Software APIs
dif_hmac.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_LIB_DIF_DIF_HMAC_H_
6 #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_HMAC_H_
7 
8 /**
9  * @file
10  * @brief <a href="/hw/ip/hmac/doc/">HMAC</a> Device Interface Functions
11  */
12 
13 #include <stddef.h>
14 #include <stdint.h>
15 
19 
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif // __cplusplus
25 
26 /**
27  * Supported HMAC modes of operation.
28  */
29 typedef enum dif_hmac_mode {
30  /** The HMAC mode. */
32  /** The SHA256-only mode. */
35 
36 /**
37  * Supported byte endienness options.
38  */
39 typedef enum dif_hmac_endianness {
40  /** Big endian byte ordering. */
42  /** Little endian byte ordering. */
45 
46 /**
47  * HMAC key length in bits.
48  */
49 typedef enum dif_hmac_key_length {
50  kDifHMACKey128 = 1,
51  kDifHMACKey256 = (1 << 1),
52  kDifHMACKey384 = (1 << 2),
53  kDifHMACKey512 = (1 << 3),
54  kDifHMACKey1024 = (1 << 4),
56 
57 /**
58  * SHA-2 digest size
59  */
60 typedef enum dif_sha2_digest_size {
61  kDifSHA256 = (1 << 1),
62  kDifSHA384 = (1 << 2),
63  kDifSHA512 = (1 << 3),
65 
66 /**
67  * Configuration for a single HMAC Transaction
68  */
69 typedef struct dif_hmac_transaction {
70  /** Byte endianness for writes to the FIFO. */
72  /** Byte endianness for reads from the digest. */
74  /** SHA-2 digest size. */
76  /** HMAC key length. */
79 
80 /**
81  * A typed representation of the HMAC digest.
82  */
83 typedef struct dif_hmac_digest {
84  uint32_t digest[8];
86 
87 /**
88  * Resets the HMAC engine and readies it to receive a new message to process an
89  * HMAC digest.
90  *
91  * This function causes the HMAC engine to start its operation. After a
92  * successful call to this function, |dif_hmac_fifo_push()| can be called to
93  * write the message for HMAC processing.
94  *
95  * This function should be called with a valid `key` that references a 32-byte,
96  * contiguous, readable region where the key may be copied from. Passing a
97  * `NULL` `key` reference will skip loading of the key. This is only expected to
98  * be used to test scenarios where the key is not loaded.
99  *
100  * @param hmac The HMAC device to start HMAC operation for.
101  * @param key The 256-bit HMAC key.
102  * @param config The per-transaction configuration.
103  * @return The result of the operation.
104  */
107  const uint8_t *key,
108  const dif_hmac_transaction_t config);
109 
110 /**
111  * Resets the HMAC engine and readies it to receive a new message to process a
112  * SHA256 digest.
113  *
114  * This function causes the HMAC engine to start its operation. After a
115  * successful call to this function, |dif_hmac_fifo_push()| can be called to
116  * write the message for SHA256 processing.
117  *
118  * @param hmac The HMAC device to start SHA256 operation for.
119  * @param config The per-transaction configuration.
120  * @return The result of the operation.
121  */
124  const dif_hmac_transaction_t config);
125 
126 /**
127  * Attempts to send `len` bytes from the buffer pointed to by `data` to the
128  * device described by `hmac`. This function will send to the message FIFO until
129  * the FIFO fills up or `len` bytes have been sent.
130  *
131  * In the event that the FIFO fills up before `len` bytes have been sent this
132  * function will return a `kDifHmacFifoFull` error. In this case it is valid
133  * to call this function again by advancing `data` by `len` - |*bytes_sent|
134  * bytes. It may be desirable to wait for space to free up on the FIFO before
135  * issuing subsequent calls to this function, but it is not strictly
136  * necessary. The number of entries in the FIFO can be queried with
137  * `dif_hmac_fifo_count_entries()`.
138  *
139  * `data` *must* point to an allocated buffer of at least length `len`.
140  *
141  * @param hmac The HMAC device to send to.
142  * @param data A contiguous buffer to copy from.
143  * @param len The length of the buffer to copy from.
144  * @param[out] bytes_sent The number of bytes sent to the FIFO (optional).
145  * @return The result of the operation.
146  */
148 dif_result_t dif_hmac_fifo_push(const dif_hmac_t *hmac, const void *data,
149  size_t len, size_t *bytes_sent);
150 
151 /**
152  * Retrieves the number of entries in the HMAC FIFO. These entries may be
153  * semi-arbitrary in length; this function should not be used to calculate
154  * message length.
155  *
156  * @param hmac The HMAC device to get the FIFO depth for.
157  * @param[out] num_entries The number of entries in the FIFO.
158  * @return The result of the operation.
159  */
162  uint32_t *num_entries);
163 
164 /**
165  * Retrieves the number of bits in the loaded HMAC device.
166  * `dif_hmac_fifo_count_entries()` should be called before this function to
167  * ensure the FIFO is empty, as any bits in the FIFO are not counted in
168  * `msg_len`.
169  *
170  * @param hmac The HMAC device to get the message length for.
171  * @param[out] msg_len The number of bits in the HMAC message.
172  * @return The result of the operation.
173  */
176  uint64_t *msg_len);
177 
178 /**
179  * Attempts to run HMAC or SHA256 depending on the mode `hmac` was initialized
180  * in. Calls to this function always succeed and return without blocking. The
181  * caller can use `dif_hmac_check_state()` to check for errors and for the
182  * `DIF_HMAC_DONE` status before reading the digest with
183  * `dif_hmac_digest_read()`.
184  *
185  * @param hmac The HMAC device to initiate the run on.
186  * @return The result of the operation.
187  */
190 
191 /**
192  * Attempts to finish a transaction started with `dif_hmac_mode_*_start`, and
193  * reads the final digest in the buffer referenced by `digest`.
194  *
195  * This queries the `INTR_STATE` register to check if the HMAC is finished, and
196  * will acknowledge a `hmac_done` interrupt. If that register is not pending,
197  * then this function assumes HMAC is still processing and will return
198  * `kDifHmacErrorDigestProcessing`.
199  *
200  * `digest` must reference an allocated, contiguous, 32-byte buffer. This buffer
201  * shall also be 4-byte aligned. This is all consistent with the platform
202  * requirements for size and alignment requirements of `dif_hmac_digest_t`.
203  *
204  * @param hmac The HMAC device to read the digest from.
205  * @param disable_after_done If true, the HMAC and SHA256 datapaths will be
206  * disabled after the digest is read, clearing the digest registers.
207  * @param[out] digest A contiguous 32-byte, 4-byte aligned buffer for the
208  * digest.
209  * @return The result of the operation.
210  */
212 dif_result_t dif_hmac_finish(const dif_hmac_t *hmac, bool disable_after_done,
213  dif_hmac_digest_t *digest);
214 
215 /**
216  * Randomizes internal secret registers on the HMAC device. This includes the
217  * key, hash value, and internal state machine. The value of `entropy` will be
218  * used to "randomize" the internal state of the HMAC device. See the HMAC IP
219  * documentation for more information: hw/ip/hmac/doc.
220  *
221  * @param hmac The HMAC device to clobber state on.
222  * @param entropy A source of randomness to write to the HMAC internal state.
223  * @param[out] digest The resulting digest from the wipe operation.
224  * @return The result of the operation.
225  */
227 dif_result_t dif_hmac_wipe_secret(const dif_hmac_t *hmac, uint32_t entropy,
228  dif_hmac_digest_t *digest);
229 
230 #ifdef __cplusplus
231 } // extern "C"
232 #endif // __cplusplus
233 
234 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_HMAC_H_