Software APIs
kmac.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 
5 #ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_KMAC_H_
6 #define OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_KMAC_H_
7 
8 /**
9  * This driver is specialized to meet the needs of SPHINCS+-SHAKE.
10  */
11 
12 #include <stdint.h>
13 
15 #include "sw/device/silicon_creator/lib/error.h"
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif // __cplusplus
20 
21 /**
22  * Configure the KMAC block for KEYMGR mode of operation.
23  *
24  * In this mode, KMAC is configured to support sideload and message masking
25  * functionality.
26  *
27  * @return Error code indicating if the operation succeeded.
28  */
29 rom_error_t kmac_keymgr_configure(void);
30 
31 /**
32  * Configure the KMAC block for KMAC-256 operation with a key loaded by
33  * software.
34  *
35  * @return Error code indicating if the operation succeeded.
36  */
37 rom_error_t kmac_kmac256_sw_configure(void);
38 
39 /**
40  * Configure the KMAC block for KMAC-256 operation with a key sideloaded from
41  * the keymgr hardware block.
42  *
43  * @return Error code indicating if the operation succeeded.
44  */
45 rom_error_t kmac_kmac256_hw_configure(void);
46 
47 /**
48  * Configure the KMAC block at startup.
49  *
50  * Sets the KMAC block to use software entropy (since we have no secret inputs
51  * for SPHINCS+) and sets the mode to SHAKE-256.
52  *
53  * @return Error code indicating if the operation succeeded.
54  */
56 rom_error_t kmac_shake256_configure(void);
57 
58 /**
59  * Start a SHAKE-256 hashing operation.
60  *
61  * Must be called after `kmac_shake256_configure()`. Will block until KMAC
62  * hardware is idle.
63  *
64  * This driver supports SHAKE-256 hashing with the following pattern:
65  * - Exactly one call to `kmac_shake256_start`
66  * - Zero or more calls to `kmac_shake256_absorb`
67  * - Exactly one call to `kmac_shake256_squeeze_start`
68  * - Exactly one call to `kmac_shake256_squeeze_end`
69  *
70  * There is no need to append the `1111` padding in the SHAKE-256 specification
71  * to the input; this will happen automatically in squeeze_start().
72  *
73  * @return Error code indicating if the operation succeeded.
74  */
76 rom_error_t kmac_shake256_start(void);
77 
78 /**
79  * Absorb (more) input for a SHAKE-256 hashing operation.
80  *
81  * The caller is responsible for calling `kmac_shake256_configure()` and
82  * `kmac_shake256_start()` first. The implementation depends on specific
83  * details of the KMAC configuration (in particular the entropy setup).
84  *
85  * Blocks until the all input is written.
86  *
87  * For best performance, `in` should be 32b-aligned, although this function
88  * does handle unaligned buffers.
89  *
90  * @param in Input buffer
91  * @param inlen Length of input (bytes)
92  * @return Error code indicating if the operation succeeded.
93  */
94 void kmac_shake256_absorb(const uint8_t *in, size_t inlen);
95 
96 /**
97  * Absorb (more) input for a SHAKE-256 hashing operation.
98  *
99  * Identical to `kmac_shake256_absorb`, but accepts input in the 32b words
100  * rather than bytes and is therefore faster because it does not need to
101  * perform alignment checks.
102  *
103  * The caller is responsible for calling `kmac_shake256_configure()` and
104  * `kmac_shake256_start()` first. The implementation depends on specific
105  * details of the KMAC configuration (in particular the entropy setup).
106  *
107  * Blocks until the all input is written.
108  *
109  * @param in Input buffer
110  * @param inlen Length of input (words)
111  * @return Error code indicating if the operation succeeded.
112  */
113 void kmac_shake256_absorb_words(const uint32_t *in, size_t inlen);
114 
115 /**
116  * Begin the squeezing phase of a SHAKE-256 hashing operation.
117  *
118  * This function will move from `absorb` to `squeeze` state and append the
119  * SHAKE-256 suffix to the message. It will also initialize the internal
120  * context object.
121  *
122  * The caller is responsible for calling `kmac_shake256_configure()` and
123  * `kmac_shake256_start()` first. It is not necessary to call
124  * `kmac_shake256_absorb()` before calling this; in that case, the resulting
125  * digest will simply be the digest of an empty message.
126  *
127  * @return Error code indicating if the operation succeeded.
128  */
129 void kmac_shake256_squeeze_start(void);
130 
131 /**
132  * Squeeze output from a SHAKE-256 hashing operation, and end the operation.
133  *
134  * The caller is responsible for calling `kmac_shake256_configure` and
135  * `kmac_shake256_squeeze_start()` first.
136  *
137  * Blocks until all output is written. After ending the operation, this
138  * function does not block until KMAC is idle; errors may appear in the next
139  * call to `kmac_shake256_start`.
140  *
141  * @param out Output buffer
142  * @param outlen Desired length of output (in words)
143  * @return Error code indicating if the operation succeeded.
144  */
146 rom_error_t kmac_shake256_squeeze_end(uint32_t *out, size_t outlen);
147 
148 /**
149  * Load an unmasked software key into KMAC.
150  *
151  * @param key The key material.
152  * @param len The length of the key material in words.
153  * @return Error code indicating if the operation succeeded.
154  */
156 rom_error_t kmac_kmac256_sw_key(const uint32_t *key, size_t len);
157 
158 /**
159  * Set the KMAC prefix value.
160  *
161  * Sets the prefix to the given prefix value. The prefix
162  * must be 31 bytes or fewer.
163  *
164  * @param prefix The prefix value encoded as words.
165  * @param len The length of the prefix in bytes.
166  */
167 void kmac_kmac256_set_prefix(const void *prefix, size_t len);
168 
169 /**
170  * Start a KMAC-256 operation.
171  *
172  * @return Error code indicating if the operation succeeded.
173  */
175 inline rom_error_t kmac_kmac256_start(void) { return kmac_shake256_start(); }
176 
177 /**
178  * Absorb data into a KMAC-256.
179  *
180  * @param data Data to absorb into the sponge.
181  * @param len Length of the data.
182  */
183 inline void kmac_kmac256_absorb(const void *data, size_t len) {
184  kmac_shake256_absorb((const uint8_t *)data, len);
185 }
186 
187 /**
188  * Finalize the KMAC-256 operation.
189  *
190  * @param result Buffer to hold the result of the KMAC operation.
191  * @param rlen Length of the result buffer in words.
192  * @return Error code indicating if the operation succeeded.
193  */
195 rom_error_t kmac_kmac256_final(uint32_t *result, size_t rlen);
196 
197 #ifdef __cplusplus
198 } // extern "C"
199 #endif // __cplusplus
200 
201 #endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_KMAC_H_