Software APIs
dif_hmac.h
Go to the documentation of this file.
1 // Copyright lowRISC contributors.
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>
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif // __cplusplus
20 
21 /**
22  * HMAC interrupt configuration.
23  *
24  * Enumeration used to enable, disable, test and query the HMAC interrupts.
25  * Please see the comportability specification for more information:
26  * https://docs.opentitan.org/doc/rm/comportability_specification/
27  */
28 typedef enum dif_hmac_interrupt {
29  /**
30  * HMAC is done.
31  *
32  * Associated with the `hmac.INTR_STATE.hmac_done` hardware interrupt.
33  */
35 
36  /**
37  * FIFO empty.
38  *
39  * Associated with the `hmac.INTR_STATE.fifo_empty` hardware interrupt.
40  */
42 
43  /**
44  * HMAC error occurred.
45  *
46  * Associated with the `hmac.INTR_STATE.hmac_err` hardware interrupt.
47  */
50 
51 /**
52  * Generic enable/disable enumeration.
53  *
54  * Enumeration used to enable/disable bits, flags, ...
55  */
56 typedef enum dif_hmac_enable {
57  /** Enable interrupt. */
59  /** Disable interrupt. */
62 
63 /**
64  * Supported HMAC modes of operation.
65  */
66 typedef enum dif_hmac_mode {
67  /** The HMAC mode. */
69  /** The SHA256-only mode. */
72 
73 /**
74  * Supported byte endienness options.
75  */
76 typedef enum dif_hmac_endianness {
77  /** Big endian byte ordering. */
79  /** Little endian byte ordering. */
82 
83 /**
84  * Error codes for HMAC functions that may exhibit generic failures.
85  */
86 typedef enum dif_hmac_result {
87  /** No error occurred. */
89  /** An unknown error occurred. */
91  /** An invalid argument was provided. */
94 
95 /**
96  * Error codes for HMAC FIFO operations that may fail.
97  */
98 typedef enum dif_hmac_fifo_result {
99  /** No error occurred. */
101  /** An unknown error occurred. */
103  /** An invalid argument was provided. */
105  /**
106  * The FIFO filled up before the buffer was fully consumed.
107  *
108  * Retryable. This error indicates that FIFO has filled up and will empty over
109  * time. A function that returns this error may be retried at any time, or the
110  * caller may choose to do so when the `kDifHmacInterruptFifoEmpty` interrupt
111  * is raised, provided this interrupt has been enabled via the interrupt API.
112  */
115 
116 /**
117  * Error codes for reading the HMAC digest.
118  */
120  /** No error occurred. */
122  /** An unknown error occurred. */
124  /** An invalid argument was provided. */
126  /**
127  * The HMAC operation is still in progress.
128  *
129  * Retryable. This error indicates HMAC is still processing and will finish in
130  * time. A function that returns this error may be retried at any time, or the
131  * caller may choose to do so when the `kDifHmacInterruptHmacDone` interrupt
132  * is raised, provided this interrupt has been enabled via the interrupt API.
133  *
134  * Any function that returns this error is guaranteed to have not produced
135  * any side effects.
136  */
139 
140 /**
141  * Configuration for initializing the HMAC device.
142  */
143 typedef struct dif_hmac_config {
144  /** The base address for registers in the HMAC IP. */
147 
148 /**
149  * Configuration for a single HMAC Transaction
150  */
151 typedef struct dif_hmac_transaction {
152  /** Byte endianness for writes to the FIFO. */
153  dif_hmac_endianness_t message_endianness;
154  /** Byte endianness for reads from the digest. */
155  dif_hmac_endianness_t digest_endianness;
157 
158 /**
159  * A typed representation of the HMAC digest.
160  */
161 typedef struct dif_hmac_digest { uint32_t digest[8]; } dif_hmac_digest_t;
162 
163 /**
164  * State for a particular HMAC device.
165  *
166  * Its member variables should be considered private, and are only provided so
167  * that callers can allocate it.
168  */
170 
171 /**
172  * Initializes the HMAC device described by `config`, writing internal state to
173  * `hmac_out`.
174  *
175  * This function *must* be called on a particular `mmio_region_t` before calling
176  * any other functions in this header with that `mmio_region_t`.
177  *
178  * @param config Configuration supplied for initializing a particular device.
179  * @param[out] hmac_out The location at which to write HMAC state. This location
180  * must be valid to write to.
181  * @return `kDifHmacBadArg` if `config` is null or contains illegal
182  * arguments or `hmac_out` is null, `kDifHmacOk` otherwise.
183  */
185  dif_hmac_t *hmac_out);
186 
187 /**
188  * HMAC get requested IRQ state.
189  *
190  * Get the state of the requested IRQ in `irq_type`.
191  *
192  * @param hmac HMAC state data.
193  * @param irq_type IRQ to get the state of.
194  * @param[out] state IRQ state passed back to the caller.
195  * @return `dif_hmac_result_t`.
196  */
198  dif_hmac_interrupt_t irq_type,
199  dif_hmac_enable_t *state);
200 /**
201  * HMAC clear requested IRQ state.
202  *
203  * Clear the state of the requested IRQ in `irq_type`. Primary use of this
204  * function is to de-assert the interrupt after it has been serviced.
205  *
206  * @param hmac HMAC state data.
207  * @param irq_type IRQ to be de-asserted.
208  * @return `dif_hmac_result_t`.
209  */
211  dif_hmac_interrupt_t irq_type);
212 
213 /**
214  * HMAC disable interrupts.
215  *
216  * Disable generation of all HMAC interrupts, and pass previous interrupt state
217  * in `state` back to the caller. Parameter `state` is ignored if NULL.
218  *
219  * @param hmac HMAC state data.
220  * @param[out] state IRQ state passed back to the caller.
221  * @return 'dif_hmac_result_t'.
222  */
224  uint32_t *state);
225 
226 /**
227  * HMAC restore IRQ state.
228  *
229  * Restore previous HMAC IRQ state. This function is used to restore the
230  * HMAC interrupt state prior to `dif_hmac_irqs_disable` function call.
231  *
232  * @param hmac HMAC state data.
233  * @param state IRQ state to restore.
234  * @return 'dif_hmac_result_t'.
235  */
236 dif_hmac_result_t dif_hmac_irqs_restore(const dif_hmac_t *hmac, uint32_t state);
237 
238 /**
239  * HMAC interrupt control.
240  *
241  * Enable/disable an HMAC interrupt specified in `irq_type`.
242  *
243  * @param hmac HMAC state data.
244  * @param irq_type HMAC interrupt type.
245  * @param enable enable or disable the interrupt.
246  * @return `dif_hmac_result_t`.
247  */
249  dif_hmac_interrupt_t irq_type,
250  dif_hmac_enable_t enable);
251 
252 /**
253  * HMAC interrupt force.
254  *
255  * Force interrupt specified in `irq_type`.
256  *
257  * @param hmac HMAC state data.
258  * @param irq_type HMAC interrupt type to be forced.
259  * @return `dif_hmac_result_t`.
260  */
262  dif_hmac_interrupt_t irq_type);
263 
264 /**
265  * Resets the HMAC engine and readies it to receive a new message to process an
266  * HMAC digest.
267  *
268  * This function causes the HMAC engine to start its operation. After a
269  * successful call to this function, |dif_hmac_fifo_push()| can be called to
270  * write the message for HMAC processing.
271  *
272  * This function must be called with a valid `key` that references a 32-byte,
273  * contiguous, readable region where the key may be copied from.
274  *
275  * @param hmac The HMAC device to start HMAC operation for.
276  * @param key The 256-bit HMAC key.
277  * @param config The per-transaction configuration.
278  * @return `kDifHmacBadArg` if `hmac` or `key` is null, `kDifHmacOk` otherwise.
279  */
281  const uint8_t *key,
282  const dif_hmac_transaction_t config);
283 
284 /**
285  * Resets the HMAC engine and readies it to receive a new message to process a
286  * SHA256 digest.
287  *
288  * This function causes the HMAC engine to start its operation. After a
289  * successful call to this function, |dif_hmac_fifo_push()| can be called to
290  * write the message for SHA256 processing.
291  *
292  * @param hmac The HMAC device to start SHA256 operation for.
293  * @param config The per-transaction configuration.
294  * @return `kDifHmacBadArg` if `hmac` null, `kDifHmacOk` otherwise.
295  */
297  const dif_hmac_t *hmac, const dif_hmac_transaction_t config);
298 
299 /**
300  * Attempts to send `len` bytes from the buffer pointed to by `data` to the
301  * device described by `hmac`. This function will send to the message FIFO until
302  * the FIFO fills up or `len` bytes have been sent.
303  *
304  * In the event that the FIFO fills up before `len` bytes have been sent this
305  * function will return a `kDifHmacFifoFull` error. In this case it is valid
306  * to call this function again by advancing `data` by `len` - |*bytes_sent|
307  * bytes. It may be desirable to wait for space to free up on the FIFO before
308  * issuing subsequent calls to this function, but it is not strictly
309  * necessary. The number of entries in the FIFO can be queried with
310  * `dif_hmac_fifo_count_entries()`.
311  *
312  * `data` *must* point to an allocated buffer of at least length `len`.
313  *
314  * @param hmac The HMAC device to send to.
315  * @param data A contiguous buffer to copy from.
316  * @param len The length of the buffer to copy from.
317  * @param[out] bytes_sent The number of bytes sent to the FIFO (optional).
318  * @return `kDifHmacFifoFull` if the FIFO fills up, `kDifHmacFifoBadArg` if
319  * `hmac` or `data` is null, and `kDifHmacFifoOk` otherwise.
320  */
321 dif_hmac_fifo_result_t dif_hmac_fifo_push(const dif_hmac_t *hmac,
322  const void *data, size_t len,
323  size_t *bytes_sent);
324 
325 /**
326  * Retrieves the number of entries in the HMAC FIFO. These entries may be
327  * semi-arbitrary in length; this function should not be used to calculate
328  * message length.
329  *
330  * @param hmac The HMAC device to get the FIFO depth for.
331  * @param[out] num_entries The number of entries in the FIFO.
332  * @return `kDifHmacBadArg` if `hmac` or `num_entries` is null, `kDifHmacOk`
333  * otherwise.
334  */
336  uint32_t *num_entries);
337 
338 /**
339  * Retrieves the number of bits in the loaded HMAC device.
340  * `dif_hmac_fifo_count_entries()` should be called before this function to
341  * ensure the FIFO is empty, as any bits in the FIFO are not counted in
342  * `msg_len`.
343  *
344  * @param hmac The HMAC device to get the message length for.
345  * @param[out] msg_len The number of bits in the HMAC message.
346  * @return `kDifHmacBadArg` if `hmac` or `msg_len` is null, `kDifHmacOk`
347  * otherwise.
348  */
350  uint64_t *msg_len);
351 
352 /**
353  * Attempts to run HMAC or SHA256 depending on the mode `hmac` was initialized
354  * in. Calls to this function always succeed and return without blocking. The
355  * caller can use `dif_hmac_check_state()` to check for errors and for the
356  * `DIF_HMAC_DONE` status before reading the digest with
357  * `dif_hmac_digest_read()`.
358  *
359  * @param hmac The HMAC device to initiate the run on.
360  * @return `kDifHmacBadArg` if `hmac` is null `kDifHmacOk` otherwise.
361  */
363 
364 /**
365  * Attempts to finish a transaction started with `dif_hmac_mode_*_start`, and
366  * reads the final digest in the buffer referenced by `digest`.
367  *
368  * This queries the `INTR_STATE` register to check if the HMAC is finished, and
369  * will acknowledge a `hmac_done` interrupt. If that register is not pending,
370  * then this function assumes HMAC is still processing and will return
371  * `kDifHmacErrorDigestProcessing`.
372  *
373  * Once the digest has been read, the HMAC and SHA256 datapaths are disabled,
374  * clearing the digest registers.
375  *
376  * `digest` must reference an allocated, contiguous, 32-byte buffer. This buffer
377  * shall also be 4-byte aligned. This is all consistent with the platform
378  * requirements for size and alignment requirements of `dif_hmac_digest_t`.
379  *
380  * @param hmac The HMAC device to read the digest from.
381  * @param[out] digest A contiguous 32-byte, 4-byte aligned buffer for the
382  * digest.
383  * @return `kDifHmacBadArg` if `hmac` or `digest` is null,
384  * `kDifHmacDigestProcessing` if HMAC is still processing, and
385  * `kDifHmacOk` otherwise.
386  */
387 dif_hmac_digest_result_t dif_hmac_finish(const dif_hmac_t *hmac,
388  dif_hmac_digest_t *digest);
389 
390 /**
391  * Randomizes internal secret registers on the HMAC device. This includes the
392  * key, hash value, and internal state machine. The value of `entropy` will be
393  * used to "randomize" the internal state of the HMAC device. See the HMAC IP
394  * documentation for more information: hw/ip/hmac/doc.
395  *
396  * @param hmac The HMAC device to clobber state on.
397  * @param entropy A source of randomness to write to the HMAC internal state.
398  * @return `kDifHmacBadArg` if `hmac` is null `kDifHmacOk` otherwise.
399  */
401  uint32_t entropy);
402 
403 #ifdef __cplusplus
404 } // extern "C"
405 #endif // __cplusplus
406 
407 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_HMAC_H_