blob: 2951fc9bdf6d13a8bbfe94fd037034f1ae54545f [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#ifndef OPENTITAN_SW_DEVICE_SCA_LIB_SIMPLE_SERIAL_H_
#define OPENTITAN_SW_DEVICE_SCA_LIB_SIMPLE_SERIAL_H_
#include <stddef.h>
#include <stdint.h>
#include "sw/device/lib/base/status.h"
#include "sw/device/lib/dif/dif_base.h"
#include "sw/device/lib/dif/dif_uart.h"
/**
* @file
* @brief Simple serial protocol for side-channel analysis.
*
* This library implements simple serial protocol version 1.1 and provides
* built-in handlers for 'v' (version) and 's' (seed PRNG) commands. Clients
* can implement additional command by registering their handlers using
* `simple_serial_register_handler()`. See https://wiki.newae.com/SimpleSerial
* for details on the protocol.
*/
/**
* Sends an error message over UART if condition evaluates to false.
*/
#define SS_CHECK(condition) \
do { \
if (!(condition)) { \
simple_serial_send_status(kSimpleSerialError); \
return; \
} \
} while (false)
/**
* Sends an error message over UART if the status represents an error.
*/
#define SS_CHECK_STATUS_OK(expr) \
do { \
status_t status_ = expr; \
if (!(status_ok(status_))) { \
unsigned char *buf = (unsigned char *)&status_.value; \
simple_serial_send_packet('z', buf, sizeof(status_.value)); \
return; \
} \
} while (false)
/**
* Sends an error message over UART if DIF does not return kDifOk.
*/
#define SS_CHECK_DIF_OK(dif_call) \
do { \
if (dif_call != kDifOk) { \
simple_serial_send_status(kSimpleSerialError); \
return; \
} \
} while (false)
/**
* Simple serial status codes.
*/
typedef enum simple_serial_result {
kSimpleSerialOk = 0,
kSimpleSerialError = 1,
} simple_serial_result_t;
/**
* Command handlers must conform to this prototype.
*/
typedef void (*simple_serial_command_handler)(const uint8_t *, size_t);
/**
* Initializes the data structures used by simple serial.
*
* This function also registers handlers for 'v' (version) and 's' (seed PRNG)
* commands.
*
* @param uart Handle to an initialized UART device.
*/
void simple_serial_init(const dif_uart_t *uart);
/**
* Registers a handler for a simple serial command.
*
* Clients cannot register handlers for 'v' (version) and 's' (seed PRNG)
* commands since these are handled by this library.
*
* @param cmd Simple serial command.
* @param handler Command handler.
*/
simple_serial_result_t simple_serial_register_handler(
uint8_t cmd, simple_serial_command_handler handler);
/**
* Waits for a simple serial packet and dispatches it to the appropriate
* handler.
*/
void simple_serial_process_packet(void);
/**
* Sends a simple serial packet over UART.
*
* @param cmd Simple serial command.
* @param data Packet payload.
* @param data_len Payload length.
*/
void simple_serial_send_packet(const uint8_t cmd, const uint8_t *data,
size_t data_len);
/**
* Sends a simple serial status packer over UART.
*
* @param res Status code.
*/
void simple_serial_send_status(uint8_t res);
/**
* Sends a buffer over UART as a hex encoded string.
*
* @param data A buffer
* @param data_len Size of the buffer.
*/
void simple_serial_print_hex(const uint8_t *data, size_t data_len);
#endif // OPENTITAN_SW_DEVICE_SCA_LIB_SIMPLE_SERIAL_H_