Software APIs
hmac.h
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 #ifndef OPENTITAN_SW_DEVICE_LIB_CRYPTO_DRIVERS_HMAC_H_
5 #define OPENTITAN_SW_DEVICE_LIB_CRYPTO_DRIVERS_HMAC_H_
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 
12 #include "sw/device/lib/crypto/impl/status.h"
13 
14 #include "hmac_regs.h"
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 enum {
21  /* Digest size for SHA-256/HMAC-256 in bits, bytes and word respectively. */
22  kHmacSha256DigestBits = 256,
23  kHmacSha256DigestBytes = kHmacSha256DigestBits / 8,
24  kHmacSha256DigestWords = kHmacSha256DigestBytes / sizeof(uint32_t),
25  /* Digest size for SHA-384/HMAC-384 in bits, bytes and word respectively. */
26  kHmacSha384DigestBits = 384,
27  kHmacSha384DigestBytes = kHmacSha384DigestBits / 8,
28  kHmacSha384DigestWords = kHmacSha384DigestBytes / sizeof(uint32_t),
29  /* Digest size for SHA-512/HMAC-512 in bits, bytes and word respectively. */
30  kHmacSha512DigestBits = 512,
31  kHmacSha512DigestBytes = kHmacSha512DigestBits / 8,
32  kHmacSha512DigestWords = kHmacSha512DigestBytes / sizeof(uint32_t),
33  /* Internal block size for SHA-256/HMAC-256 in bits, bytes and word
34  respectively. */
35  kHmacSha256BlockBits = 2 * kHmacSha256DigestBits,
36  kHmacSha256BlockBytes = kHmacSha256BlockBits / 8,
37  kHmacSha256BlockWords = kHmacSha256BlockBytes / sizeof(uint32_t),
38  /* Internal block size for SHA-384/512 and HMAC-384/512 in bits, bytes and
39  word respectively. */
40  kHmacSha512BlockBits = 2 * kHmacSha512DigestBits,
41  kHmacSha512BlockBytes = kHmacSha512BlockBits / 8,
42  kHmacSha512BlockWords = kHmacSha512BlockBytes / sizeof(uint32_t),
43  /* Maximum digest size supported by HW natively in bits, bytes and words
44  respectively. */
45  kHmacMaxDigestBits = kHmacSha512DigestBits,
46  kHmacMaxDigestBytes = kHmacMaxDigestBits / 8,
47  kHmacMaxDigestWords = kHmacMaxDigestBytes / sizeof(uint32_t),
48  /* Maximum internal block size bits, bytes and words respectively. */
49  kHmacMaxBlockBits = kHmacSha512BlockBits,
50  kHmacMaxBlockBytes = kHmacMaxBlockBits / 8,
51  kHmacMaxBlockWords = kHmacMaxBlockBytes / sizeof(uint32_t),
52 };
53 
54 /**
55  * A context struct maintained for streaming operations.
56  */
57 typedef struct hmac_ctx {
58  // A copy of `CFG` register used during resumption.
59  uint32_t cfg_reg;
60  // A copy of `KEY` to be used during start or resumption.
61  uint32_t key[kHmacMaxBlockWords];
62  // key_wordlen == 0 is used to infer that this is SHA-2 operation.
63  size_t key_wordlen;
64  // The internal (message) block size of SHA-2 for this operation.
65  size_t msg_block_bytelen;
66  size_t digest_wordlen;
67  // The following fields are saved and restored during streaming.
68  uint32_t H[kHmacMaxDigestWords];
69  uint32_t lower;
70  uint32_t upper;
71  // The following flags are used exclusively by the driver to determine whether
72  // or not the driver needs to pass the incoming requests to HMAC HWIP.
73  uint32_t hw_started;
74  uint8_t partial_block[kHmacMaxBlockBytes];
75  // The number of valid bytes in `partial_block`.
76  size_t partial_block_len;
77 } hmac_ctx_t;
78 
79 typedef enum hmac_mode {
80  // SHA2-256
81  kHmacModeSha256,
82  // SHA2-384
83  kHmacModeSha384,
84  // SHA2-512
85  kHmacModeSha512,
86  // HMAC-256
87  kHmacModeHmac256,
88  // HMAC-384
89  kHmacModeHmac384,
90  // HMAC-512
91  kHmacModeHmac512,
92 } hmac_mode_t;
93 
94 /**
95  * Initializes the context `ctx` according to given `hmac_mode` and `key`.
96  *
97  * This function does not invoke a HMAC HWIP operation, but instead prepares
98  * `ctx` with necessary data for the streaming operations to be called later:
99  *
100  * i) Prepare CFG register value (with the exception of `sha_en` bit, #23014)
101  * and store it into `ctx`. This value is repetitively loaded into HWIP during
102  * future `hmac_update` and `hmac_final` calls.
103  * ii) Copy given key and its length into `ctx` if the operation is HMAC.
104  * iii) Initialize `hw_started` flag to false which indicates whether the very
105  * first HWIP operation is executed or not. This helps decide whether start or
106  * continue operation needs to be issues to HMAC HWIP later.
107  * iv) Compute and store message block length and digest len fields to `ctx`.
108  *
109  * For SHA-2 operation, it must be that `key = NULL` and `key_wordlen = 0`.
110  * For HMAC operations, `key` must point to a key buffer that contains the
111  * processed key denoted as k0 in FIPS 198-1, Section 4. Therefore, the size of
112  * the key must match the internal block size of the underlying hash function.
113  * In other words, it means that:
114  * For HMAC-256, `key_wordlen = 64` with `key` referring to the value of k0,
115  * which consists of exactly 64 words.
116  * For HMAC-384/512, `key_wordlen = 128`, with `key` referring to the value
117  * of k0, which consists of exactly 128 words.
118  *
119  * @param[out] ctx Initialized context object for SHA2/HMAC-SHA2 operations.
120  * @param hmac_mode Specifies the mode among SHA2-256/384/512, HMAC-256/384/512.
121  * @param key Processed HMAC key.
122  * @param key_wordlen The length of HMAC key, which must match the internal
123  * block size of the underlying hash function.
124  * @return Result of the operation.
125  */
127 status_t hmac_init(hmac_ctx_t *ctx, const hmac_mode_t hmac_mode,
128  const uint32_t *key, size_t key_wordlen);
129 
130 /**
131  * Updates the state of `ctx` with given additional messsage bytes.
132  *
133  * This function first checks whether incoming byte messages together with the
134  * pending bytes `ctx->partial_block` are larger than the SHA-2/HMAC internal
135  * block size implied by `ctx`.
136  *
137  * If the available message bytes are larger than the internal block size, then
138  * the state of HWIP is restored from `ctx` and message bytes are fed into
139  * MSG_FIFO in internal block granularity. When all blocks are processed, HWIP
140  * is stopped and the state of HWIP is saved to `ctx`. The leftover message
141  * bytes that are not sufficient to be a block are stored in `ctx-partial_block`
142  * to be used in future `hmac_update` or `hmac_final` calls. Finally, the state
143  * of HWIP is cleared.
144 
145  * If the available message bytes are smaller than a single internal block,
146  * `ctx->partial_block` is appended with the incoming bytes and no HWIP
147  * operation is issued.
148  *
149  * @param ctx Context object referring to a particular SHA-2/HMAC stream.
150  * @param data Incoming message bytes to be processed into the stream.
151  * @param len size of the `data` buffer in bytes.
152  * @return Result of the operation.
153  */
155 status_t hmac_update(hmac_ctx_t *ctx, const uint8_t *data, size_t len);
156 
157 /**
158  * Finalize the SHA-2/HMAC stream and return digest/tag.
159  *
160  * This function works similar to `hmac_update`, in terms of how reamining
161  * message bytes are handled, if there are any.
162  *
163  * First, the state of HWIP is restored. Then, any remaining message byte from
164  * `ctx->partial_block` are fed to MSG_FIFO. At the end, process command is
165  * invoked at HWIP to conclude SHA-2/HMAC operation and produce the digest/tag.
166  * The result is read from HWIP into `digest` and the state of HWIP is cleared.
167  *
168  * `digest` should point to a sufficiently large buffer to accommodate
169  * the resulting digest. `digest_wordlen` must match the digest length implied
170  * by the mode used during the initialization of `ctx`, otherwise an error is
171  * returned.
172  *
173  * @param ctx Context object referring to a particular stream.
174  * @param[out] digest The digest value to be returned.
175  * @param digest_wordlen The length of the digest in words.
176  * @return Result of the operation.
177  */
179 status_t hmac_final(hmac_ctx_t *ctx, uint32_t *digest, size_t digest_wordlen);
180 
181 /**
182  * One-shot SHA-2/HMAC call.
183  *
184  * This function uses `hmac_mode` to determine whether to run SHA-2 or HMAC
185  * including the digest size. See `hmac_mode_t` for possible values.
186  *
187  * For SHA-2 operation, it must be that `key = NULL` and `key_wordlen = 0`.
188  * For HMAC operations, `key` must point to a key buffer that contains the
189  * processed key denoted as k0 in FIPS 198-1, Section 4. Therefore, the size of
190  * the key must match the internal block size of the underlying hash function.
191  * In other words, it means that:
192  * For HMAC-256, `key_wordlen = 64` with `key` referring to the value of k0,
193  * which consists of exactly 64 words.
194  * For HMAC-384/512, `key_wordlen = 128`, with `key` referring to the value
195  * of k0, which consists of exactly 128 words.
196  *
197  * `digest` should point to a sufficiently large buffer to accommodate
198  * the resulting digest. `digest_wordlen` must match the digest length implied
199  * by the mode used during the initialization of `ctx`, otherwise an error is
200  * returned.
201  *
202  * @param[out] ctx Initialized context object for SHA2/HMAC-SHA2 operations.
203  * @param hmac_mode Specifies the mode among SHA2-256/384/512, HMAC-256/384/512.
204  * @param key Processed HMAC key.
205  * @param key_wordlen The length of HMAC key, which must match the internal
206  * block size of the underlying hash function.
207  * @param[out] digest The digest value to be returned.
208  * @param digest_wordlen The length of the digest in words.
209  * @return Result of the operation.
210  */
212 status_t hmac(const hmac_mode_t hmac_mode, const uint32_t *key,
213  size_t key_wordlen, const uint8_t *data, size_t len,
214  uint32_t *digest, size_t digest_wordlen);
215 
216 #ifdef __cplusplus
217 }
218 #endif
219 
220 #endif // OPENTITAN_SW_DEVICE_LIB_CRYPTO_DRIVERS_HMAC_H_