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
20#include "sw/device/lib/dif/autogen/dif_hmac_autogen.h"
21
22#ifdef __cplusplus
23extern "C" {
24#endif // __cplusplus
25
26/**
27 * Supported HMAC modes of operation.
28 */
29typedef enum dif_hmac_mode {
30 /** The HMAC mode. */
32 /** The SHA256-only mode. */
35
36/**
37 * Supported byte endienness options.
38 */
39typedef enum dif_hmac_endianness {
40 /** Big endian byte ordering. */
42 /** Little endian byte ordering. */
45
46/**
47 * HMAC key length in bits.
48 */
49typedef 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 */
61 kDifSHA256 = (1 << 1),
62 kDifSHA384 = (1 << 2),
63 kDifSHA512 = (1 << 3),
65
66/**
67 * Configuration for a single HMAC Transaction
68 */
69typedef 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 */
83typedef 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 */
148dif_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 */
212dif_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 */
227dif_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_