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="/book/hw/ip/hmac/">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. */
78 /** Use the sideload key from the key manager. */
81
82/**
83 * A typed representation of the HMAC digest.
84 */
85typedef struct dif_hmac_digest {
86 uint32_t digest[8];
88
89/**
90 * Resets the HMAC engine and readies it to receive a new message to process an
91 * HMAC digest.
92 *
93 * This function causes the HMAC engine to start its operation. After a
94 * successful call to this function, |dif_hmac_fifo_push()| can be called to
95 * write the message for HMAC processing.
96 *
97 * This function should be called with a valid `key` that references a 32-byte,
98 * contiguous, readable region where the key may be copied from. Passing a
99 * `NULL` `key` reference will skip loading of the key. This is only expected to
100 * be used to test scenarios where the key is not loaded.
101 *
102 * @param hmac The HMAC device to start HMAC operation for.
103 * @param key The 256-bit HMAC key. Ignored if `config.sideload` is set.
104 * @param config The per-transaction configuration.
105 * @return The result of the operation.
106 */
109 const uint8_t *key,
110 const dif_hmac_transaction_t config);
111
112/**
113 * Resets the HMAC engine and readies it to receive a new message to process a
114 * SHA256 digest.
115 *
116 * This function causes the HMAC engine to start its operation. After a
117 * successful call to this function, |dif_hmac_fifo_push()| can be called to
118 * write the message for SHA256 processing.
119 *
120 * @param hmac The HMAC device to start SHA256 operation for.
121 * @param config The per-transaction configuration.
122 * @return The result of the operation.
123 */
126 const dif_hmac_transaction_t config);
127
128/**
129 * Attempts to send `len` bytes from the buffer pointed to by `data` to the
130 * device described by `hmac`. This function will send to the message FIFO until
131 * the FIFO fills up or `len` bytes have been sent.
132 *
133 * In the event that the FIFO fills up before `len` bytes have been sent this
134 * function will return a `kDifHmacFifoFull` error. In this case it is valid
135 * to call this function again by advancing `data` by `len` - |*bytes_sent|
136 * bytes. It may be desirable to wait for space to free up on the FIFO before
137 * issuing subsequent calls to this function, but it is not strictly
138 * necessary. The number of entries in the FIFO can be queried with
139 * `dif_hmac_fifo_count_entries()`.
140 *
141 * `data` *must* point to an allocated buffer of at least length `len`.
142 *
143 * @param hmac The HMAC device to send to.
144 * @param data A contiguous buffer to copy from.
145 * @param len The length of the buffer to copy from.
146 * @param[out] bytes_sent The number of bytes sent to the FIFO (optional).
147 * @return The result of the operation.
148 */
150dif_result_t dif_hmac_fifo_push(const dif_hmac_t *hmac, const void *data,
151 size_t len, size_t *bytes_sent);
152
153/**
154 * Retrieves the number of entries in the HMAC FIFO. These entries may be
155 * semi-arbitrary in length; this function should not be used to calculate
156 * message length.
157 *
158 * @param hmac The HMAC device to get the FIFO depth for.
159 * @param[out] num_entries The number of entries in the FIFO.
160 * @return The result of the operation.
161 */
164 uint32_t *num_entries);
165
166/**
167 * Retrieves the number of bits in the loaded HMAC device.
168 * `dif_hmac_fifo_count_entries()` should be called before this function to
169 * ensure the FIFO is empty, as any bits in the FIFO are not counted in
170 * `msg_len`.
171 *
172 * @param hmac The HMAC device to get the message length for.
173 * @param[out] msg_len The number of bits in the HMAC message.
174 * @return The result of the operation.
175 */
178 uint64_t *msg_len);
179
180/**
181 * Attempts to run HMAC or SHA256 depending on the mode `hmac` was initialized
182 * in. Calls to this function always succeed and return without blocking. The
183 * caller can use `dif_hmac_check_state()` to check for errors and for the
184 * `DIF_HMAC_DONE` status before reading the digest with
185 * `dif_hmac_digest_read()`.
186 *
187 * @param hmac The HMAC device to initiate the run on.
188 * @return The result of the operation.
189 */
192
193/**
194 * Attempts to finish a transaction started with `dif_hmac_mode_*_start`, and
195 * reads the final digest in the buffer referenced by `digest`.
196 *
197 * This queries the `INTR_STATE` register to check if the HMAC is finished, and
198 * will acknowledge a `hmac_done` interrupt. If that register is not pending,
199 * then this function assumes HMAC is still processing and will return
200 * `kDifHmacErrorDigestProcessing`.
201 *
202 * `digest` must reference an allocated, contiguous, 32-byte buffer. This buffer
203 * shall also be 4-byte aligned. This is all consistent with the platform
204 * requirements for size and alignment requirements of `dif_hmac_digest_t`.
205 *
206 * @param hmac The HMAC device to read the digest from.
207 * @param disable_after_done If true, the HMAC and SHA256 datapaths will be
208 * disabled after the digest is read, clearing the digest registers.
209 * @param[out] digest A contiguous 32-byte, 4-byte aligned buffer for the
210 * digest.
211 * @return The result of the operation.
212 */
214dif_result_t dif_hmac_finish(const dif_hmac_t *hmac, bool disable_after_done,
215 dif_hmac_digest_t *digest);
216
217/**
218 * Randomizes internal secret registers on the HMAC device. This includes the
219 * key, hash value, and internal state machine. The value of `entropy` will be
220 * used to "randomize" the internal state of the HMAC device. See the HMAC IP
221 * documentation for more information: hw/ip/hmac/doc.
222 *
223 * @param hmac The HMAC device to clobber state on.
224 * @param entropy A source of randomness to write to the HMAC internal state.
225 * @param[out] digest The resulting digest from the wipe operation.
226 * @return The result of the operation.
227 */
229dif_result_t dif_hmac_wipe_secret(const dif_hmac_t *hmac, uint32_t entropy,
230 dif_hmac_digest_t *digest);
231
232#ifdef __cplusplus
233} // extern "C"
234#endif // __cplusplus
235
236#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_HMAC_H_