Software APIs
simple_serial.h
Go to the documentation of this file.
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #ifndef OPENTITAN_SW_DEVICE_SCA_LIB_SIMPLE_SERIAL_H_
6 #define OPENTITAN_SW_DEVICE_SCA_LIB_SIMPLE_SERIAL_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include "sw/device/lib/base/status.h"
14 
15 /**
16  * @file
17  * @brief Simple serial protocol for side-channel analysis.
18  *
19  * This library implements simple serial protocol version 1.1 and provides
20  * built-in handlers for 'v' (version) and 's' (seed PRNG) commands. Clients
21  * can implement additional command by registering their handlers using
22  * `simple_serial_register_handler()`. See https://wiki.newae.com/SimpleSerial
23  * for details on the protocol.
24  */
25 
26 /**
27  * Sends an error message over UART if condition evaluates to false.
28  */
29 #define SS_CHECK(condition) \
30  do { \
31  if (!(condition)) { \
32  simple_serial_send_status(kSimpleSerialError); \
33  return; \
34  } \
35  } while (false)
36 
37 /**
38  * Sends an error message over UART if the status represents an error.
39  */
40 #define SS_CHECK_STATUS_OK(expr) \
41  do { \
42  status_t status_ = expr; \
43  if (!(status_ok(status_))) { \
44  unsigned char *buf = (unsigned char *)&status_.value; \
45  simple_serial_send_packet('z', buf, sizeof(status_.value)); \
46  return; \
47  } \
48  } while (false)
49 
50 /**
51  * Sends an error message over UART if DIF does not return kDifOk.
52  */
53 #define SS_CHECK_DIF_OK(dif_call) \
54  do { \
55  if (dif_call != kDifOk) { \
56  simple_serial_send_status(kSimpleSerialError); \
57  return; \
58  } \
59  } while (false)
60 
61 /**
62  * Simple serial status codes.
63  */
64 typedef enum simple_serial_result {
65  kSimpleSerialOk = 0,
66  kSimpleSerialError = 1,
68 
69 /**
70  * Command handlers must conform to this prototype.
71  */
72 typedef void (*simple_serial_command_handler)(const uint8_t *, size_t);
73 
74 /**
75  * Initializes the data structures used by simple serial.
76  *
77  * This function also registers handlers for 'v' (version) and 's' (seed PRNG)
78  * commands.
79  *
80  * @param uart Handle to an initialized UART device.
81  */
82 void simple_serial_init(const dif_uart_t *uart);
83 
84 /**
85  * Registers a handler for a simple serial command.
86  *
87  * Clients cannot register handlers for 'v' (version) and 's' (seed PRNG)
88  * commands since these are handled by this library.
89  *
90  * @param cmd Simple serial command.
91  * @param handler Command handler.
92  */
94  uint8_t cmd, simple_serial_command_handler handler);
95 
96 /**
97  * Waits for a simple serial packet and dispatches it to the appropriate
98  * handler.
99  */
101 
102 /**
103  * Sends a simple serial packet over UART.
104  *
105  * @param cmd Simple serial command.
106  * @param data Packet payload.
107  * @param data_len Payload length.
108  */
109 void simple_serial_send_packet(const uint8_t cmd, const uint8_t *data,
110  size_t data_len);
111 
112 /**
113  * Sends a simple serial status packer over UART.
114  *
115  * @param res Status code.
116  */
117 void simple_serial_send_status(uint8_t res);
118 
119 /**
120  * Sends a buffer over UART as a hex encoded string.
121  *
122  * @param data A buffer
123  * @param data_len Size of the buffer.
124  */
125 void simple_serial_print_hex(const uint8_t *data, size_t data_len);
126 
127 #endif // OPENTITAN_SW_DEVICE_SCA_LIB_SIMPLE_SERIAL_H_