Software APIs
kmac.c
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 #include "sw/device/lib/crypto/drivers/kmac.h"
6 
10 #include "sw/device/lib/crypto/drivers/entropy.h"
11 #include "sw/device/lib/crypto/impl/status.h"
12 
14 #include "kmac_regs.h" // Generated.
15 
16 // Module ID for status codes.
17 #define MODULE_ID MAKE_MODULE_ID('d', 'k', 'c')
18 
19 /**
20  * Security strength values.
21  *
22  * These values corresponds to the half of the capacity of Keccak permutation.
23  */
24 typedef enum kmac_security_str {
25  kKmacSecurityStrength128 = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L128,
26  kKmacSecurityStrength224 = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L224,
27  kKmacSecurityStrength256 = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256,
28  kKmacSecurityStrength384 = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L384,
29  kKmacSecurityStrength512 = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L512,
30 } kmac_security_str_t;
31 
32 /**
33  * List of supported KMAC modes.
34  *
35  * Each `kmac_operation_t` enumeration constant is a bitfield with the
36  * following layout:
37  * - Bit 0: kmac_en (Whether to enable KMAC datapath).
38  * - Bit 1-2: Keccak hashing mode (e.g. SHA, SHAKE, or cSHAKE).
39  */
40 typedef enum kmac_operation {
41  kKmacOperationSHA3 = KMAC_CFG_SHADOWED_MODE_VALUE_SHA3 << 1 | 0,
42  kKmacOperationSHAKE = KMAC_CFG_SHADOWED_MODE_VALUE_SHAKE << 1 | 0,
43  kKmacOperationCSHAKE = KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE << 1 | 0,
44  kKmacOperationKMAC = KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE << 1 | 1,
45 } kmac_operation_t;
46 
47 /**
48  * List of supported KMAC key sizes.
49  */
50 typedef enum kmac_key_length {
51  kKmacKeyLength128 = KMAC_KEY_LEN_LEN_VALUE_KEY128,
52  kKmacKeyLength192 = KMAC_KEY_LEN_LEN_VALUE_KEY192,
53  kKmacKeyLength256 = KMAC_KEY_LEN_LEN_VALUE_KEY256,
54  kKmacKeyLength384 = KMAC_KEY_LEN_LEN_VALUE_KEY384,
55  kKmacKeyLength512 = KMAC_KEY_LEN_LEN_VALUE_KEY512,
56 } kmac_key_len_t;
57 
58 enum {
59  kKmacPrefixRegCount = 4 * KMAC_PREFIX_MULTIREG_COUNT,
60  kKmacBaseAddr = TOP_EARLGREY_KMAC_BASE_ADDR,
61  kKmacCfgAddr = kKmacBaseAddr + KMAC_CFG_SHADOWED_REG_OFFSET,
62  kKmacKeyShare0Addr = kKmacBaseAddr + KMAC_KEY_SHARE0_0_REG_OFFSET,
63  kKmacKeyShare1Addr = kKmacBaseAddr + KMAC_KEY_SHARE1_0_REG_OFFSET,
64  kKmacStateShareSize = KMAC_STATE_SIZE_BYTES / 2,
65  kKmacStateShare0Addr = kKmacBaseAddr + KMAC_STATE_REG_OFFSET,
66  kKmacStateShare1Addr =
67  kKmacBaseAddr + KMAC_STATE_REG_OFFSET + kKmacStateShareSize,
68 };
69 
70 // "KMAC" string in little endian
71 static const uint8_t kKmacFuncNameKMAC[] = {0x4b, 0x4d, 0x41, 0x43};
72 
73 // We need 5 bytes at most for encoding the length of cust_str and func_name.
74 // That leaves 39 bytes for the string. We simply truncate it to 36 bytes.
75 OT_ASSERT_ENUM_VALUE(kKmacPrefixMaxSize, 4 * KMAC_PREFIX_MULTIREG_COUNT - 8);
76 OT_ASSERT_ENUM_VALUE(kKmacCustStrMaxSize, kKmacPrefixMaxSize - 4);
77 
78 static const uint32_t prefix_offsets[] = {
79  KMAC_PREFIX_0_REG_OFFSET, KMAC_PREFIX_1_REG_OFFSET,
80  KMAC_PREFIX_2_REG_OFFSET, KMAC_PREFIX_3_REG_OFFSET,
81  KMAC_PREFIX_4_REG_OFFSET, KMAC_PREFIX_5_REG_OFFSET,
82  KMAC_PREFIX_6_REG_OFFSET, KMAC_PREFIX_7_REG_OFFSET,
83  KMAC_PREFIX_8_REG_OFFSET, KMAC_PREFIX_9_REG_OFFSET,
84  KMAC_PREFIX_10_REG_OFFSET,
85 };
86 
87 // Check that KEY_SHARE registers form a continuous address space
88 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_1_REG_OFFSET,
89  KMAC_KEY_SHARE0_0_REG_OFFSET + 4);
90 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_2_REG_OFFSET,
91  KMAC_KEY_SHARE0_1_REG_OFFSET + 4);
92 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_3_REG_OFFSET,
93  KMAC_KEY_SHARE0_2_REG_OFFSET + 4);
94 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_4_REG_OFFSET,
95  KMAC_KEY_SHARE0_3_REG_OFFSET + 4);
96 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_5_REG_OFFSET,
97  KMAC_KEY_SHARE0_4_REG_OFFSET + 4);
98 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_6_REG_OFFSET,
99  KMAC_KEY_SHARE0_5_REG_OFFSET + 4);
100 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_7_REG_OFFSET,
101  KMAC_KEY_SHARE0_6_REG_OFFSET + 4);
102 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_8_REG_OFFSET,
103  KMAC_KEY_SHARE0_7_REG_OFFSET + 4);
104 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_9_REG_OFFSET,
105  KMAC_KEY_SHARE0_8_REG_OFFSET + 4);
106 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_10_REG_OFFSET,
107  KMAC_KEY_SHARE0_9_REG_OFFSET + 4);
108 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_11_REG_OFFSET,
109  KMAC_KEY_SHARE0_10_REG_OFFSET + 4);
110 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_12_REG_OFFSET,
111  KMAC_KEY_SHARE0_11_REG_OFFSET + 4);
112 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_13_REG_OFFSET,
113  KMAC_KEY_SHARE0_12_REG_OFFSET + 4);
114 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_14_REG_OFFSET,
115  KMAC_KEY_SHARE0_13_REG_OFFSET + 4);
116 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE0_15_REG_OFFSET,
117  KMAC_KEY_SHARE0_14_REG_OFFSET + 4);
118 
119 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_1_REG_OFFSET,
120  KMAC_KEY_SHARE1_0_REG_OFFSET + 4);
121 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_2_REG_OFFSET,
122  KMAC_KEY_SHARE1_1_REG_OFFSET + 4);
123 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_3_REG_OFFSET,
124  KMAC_KEY_SHARE1_2_REG_OFFSET + 4);
125 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_4_REG_OFFSET,
126  KMAC_KEY_SHARE1_3_REG_OFFSET + 4);
127 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_5_REG_OFFSET,
128  KMAC_KEY_SHARE1_4_REG_OFFSET + 4);
129 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_6_REG_OFFSET,
130  KMAC_KEY_SHARE1_5_REG_OFFSET + 4);
131 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_7_REG_OFFSET,
132  KMAC_KEY_SHARE1_6_REG_OFFSET + 4);
133 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_8_REG_OFFSET,
134  KMAC_KEY_SHARE1_7_REG_OFFSET + 4);
135 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_9_REG_OFFSET,
136  KMAC_KEY_SHARE1_8_REG_OFFSET + 4);
137 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_10_REG_OFFSET,
138  KMAC_KEY_SHARE1_9_REG_OFFSET + 4);
139 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_11_REG_OFFSET,
140  KMAC_KEY_SHARE1_10_REG_OFFSET + 4);
141 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_12_REG_OFFSET,
142  KMAC_KEY_SHARE1_11_REG_OFFSET + 4);
143 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_13_REG_OFFSET,
144  KMAC_KEY_SHARE1_12_REG_OFFSET + 4);
145 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_14_REG_OFFSET,
146  KMAC_KEY_SHARE1_13_REG_OFFSET + 4);
147 OT_ASSERT_ENUM_VALUE(KMAC_KEY_SHARE1_15_REG_OFFSET,
148  KMAC_KEY_SHARE1_14_REG_OFFSET + 4);
149 
150 OT_ASSERT_ENUM_VALUE(ARRAYSIZE(prefix_offsets), KMAC_PREFIX_MULTIREG_COUNT);
151 
152 // Ensure each PREFIX register is 4 bytes
153 OT_ASSERT_ENUM_VALUE(32, KMAC_PREFIX_PREFIX_FIELD_WIDTH);
154 
155 /**
156  * Return the rate (in bytes) for given security strength.
157  *
158  * The caller must ensure that `keccak_rate` is not a NULL pointer. This is not
159  * checked within this function.
160  *
161  * @param security_str Security strength.
162  * @param keccak_rate The keccak rate in 32-bit words.
163  * @return Error code.
164  */
166 static status_t kmac_get_keccak_rate_words(kmac_security_str_t security_str,
167  size_t *keccak_rate) {
168  // Since Keccak state is 1600 bits, rate is calculated with
169  // rate = (1600 - 2*x) where x is the security strength (i.e. half the
170  // capacity).
171  switch (security_str) {
172  case kKmacSecurityStrength128:
173  *keccak_rate = (1600 - 2 * 128) / 32;
174  break;
175  case kKmacSecurityStrength224:
176  *keccak_rate = (1600 - 2 * 224) / 32;
177  break;
178  case kKmacSecurityStrength256:
179  *keccak_rate = (1600 - 2 * 256) / 32;
180  break;
181  case kKmacSecurityStrength384:
182  *keccak_rate = (1600 - 2 * 384) / 32;
183  break;
184  case kKmacSecurityStrength512:
185  *keccak_rate = (1600 - 2 * 512) / 32;
186  break;
187  default:
188  return OTCRYPTO_BAD_ARGS;
189  }
190  return OTCRYPTO_OK;
191 }
192 
193 /**
194  * Return the matching enum of `kmac_key_len_t` for given key length.
195  *
196  * `key_len_enum` must not be NULL pointer.
197  *
198  * @param key_len The size of the key in bytes.
199  * @param key_len_enum The corresponding enum value to be returned.
200  * @return Error code.
201  */
203 static status_t kmac_get_key_len_bytes(size_t key_len,
204  kmac_key_len_t *key_len_enum) {
205  switch (key_len) {
206  case 128 / 8:
207  *key_len_enum = kKmacKeyLength128;
208  break;
209  case 192 / 8:
210  *key_len_enum = kKmacKeyLength192;
211  break;
212  case 256 / 8:
213  *key_len_enum = kKmacKeyLength256;
214  break;
215  case 384 / 8:
216  *key_len_enum = kKmacKeyLength384;
217  break;
218  case 512 / 8:
219  *key_len_enum = kKmacKeyLength512;
220  break;
221  default:
222  return OTCRYPTO_BAD_ARGS;
223  }
224  return OTCRYPTO_OK;
225 }
226 
227 status_t kmac_key_length_check(size_t key_len) {
228  kmac_key_len_t key_len_enum;
229  // Run the conversion to the key length enum, but we only care about the
230  // error code.
231  return kmac_get_key_len_bytes(key_len, &key_len_enum);
232 }
233 
234 status_t kmac_hwip_default_configure(void) {
235  // Ensure that the entropy complex is initialized.
236  HARDENED_TRY(entropy_complex_check());
237 
238  uint32_t status_reg = abs_mmio_read32(kKmacBaseAddr + KMAC_STATUS_REG_OFFSET);
239 
240  // Check that core is not in fault state
241  if (bitfield_bit32_read(status_reg, KMAC_STATUS_ALERT_FATAL_FAULT_BIT)) {
242  return OTCRYPTO_FATAL_ERR;
243  }
244  if (bitfield_bit32_read(status_reg,
245  KMAC_STATUS_ALERT_RECOV_CTRL_UPDATE_ERR_BIT)) {
246  return OTCRYPTO_RECOV_ERR;
247  }
248  // Check that core is not busy
249  if (!bitfield_bit32_read(status_reg, KMAC_STATUS_SHA3_IDLE_BIT)) {
250  return OTCRYPTO_RECOV_ERR;
251  }
252 
253  // Check that there is no err pending in intr state
254  uint32_t intr_state =
255  abs_mmio_read32(kKmacBaseAddr + KMAC_INTR_STATE_REG_OFFSET);
256  if (bitfield_bit32_read(intr_state, KMAC_INTR_STATE_KMAC_ERR_BIT)) {
257  return OTCRYPTO_RECOV_ERR;
258  }
259 
260  // Check CFG.regwen
261  uint32_t cfg_regwen =
262  abs_mmio_read32(kKmacBaseAddr + KMAC_CFG_REGWEN_REG_OFFSET);
263  if (!bitfield_bit32_read(cfg_regwen, KMAC_CFG_REGWEN_EN_BIT)) {
264  return OTCRYPTO_RECOV_ERR;
265  }
266 
267  // Keep err interrupt disabled
268  uint32_t intr_reg = KMAC_INTR_ENABLE_REG_RESVAL;
269  intr_reg = bitfield_bit32_write(intr_reg, KMAC_INTR_ENABLE_KMAC_ERR_BIT, 0);
270  abs_mmio_write32(kKmacBaseAddr + KMAC_INTR_ENABLE_REG_OFFSET, intr_reg);
271 
272  // Configure max for entropy period (use UINT32_MAX and let bitfield clamp
273  // them to their bitfield)
274  uint32_t entropy_period = KMAC_ENTROPY_PERIOD_REG_RESVAL;
275  entropy_period = bitfield_field32_write(
276  entropy_period, KMAC_ENTROPY_PERIOD_PRESCALER_FIELD, UINT32_MAX);
277  entropy_period = bitfield_field32_write(
278  entropy_period, KMAC_ENTROPY_PERIOD_WAIT_TIMER_FIELD, UINT32_MAX);
279  abs_mmio_write32(kKmacBaseAddr + KMAC_ENTROPY_PERIOD_REG_OFFSET,
280  entropy_period);
281 
282  // Configure max for hash threshold (use UINT32_MAX and let bitfield clamp
283  // them to their bitfield)
284  uint32_t entropy_hash_threshold =
285  KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_REG_RESVAL;
286  entropy_hash_threshold = bitfield_field32_write(
287  entropy_hash_threshold,
288  KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_THRESHOLD_FIELD, UINT32_MAX);
289  abs_mmio_write32(
290  kKmacBaseAddr + KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_REG_OFFSET,
291  entropy_hash_threshold);
292 
293  // Configure CFG
294  uint32_t cfg_reg = KMAC_CFG_SHADOWED_REG_RESVAL;
295  // Little_endian
296  cfg_reg =
297  bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_MSG_ENDIANNESS_BIT, 0);
298  cfg_reg =
299  bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_STATE_ENDIANNESS_BIT, 0);
300 
301  // Sideload: off, default key comes from SW
302  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_SIDELOAD_BIT, 0);
303 
304  // Entropy mode: EDN
305  cfg_reg =
306  bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_ENTROPY_MODE_FIELD,
307  KMAC_CFG_SHADOWED_ENTROPY_MODE_VALUE_EDN_MODE);
308 
309  // Use quality randomness for message blocks too
310  cfg_reg = bitfield_bit32_write(cfg_reg,
311  KMAC_CFG_SHADOWED_ENTROPY_FAST_PROCESS_BIT, 1);
312  // Do not remask message blocks
313  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_MSG_MASK_BIT, 0);
314 
315  // Mark entropy source as ready
316  cfg_reg =
317  bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_ENTROPY_READY_BIT, 1);
318  // Unsupported modes: disabled
319  cfg_reg = bitfield_bit32_write(
320  cfg_reg, KMAC_CFG_SHADOWED_EN_UNSUPPORTED_MODESTRENGTH_BIT, 0);
321 
322  abs_mmio_write32_shadowed(kKmacBaseAddr + KMAC_CFG_SHADOWED_REG_OFFSET,
323  cfg_reg);
324 
325  return OTCRYPTO_OK;
326 }
327 
328 /**
329  * Wait until given status bit is set.
330  *
331  * Loops until the `bit_position` of status register reaches the value
332  * `bit_value`.
333  * @param bit_position The bit position in the status register.
334  * @param bit_value Whether it should wait for 0 or 1.
335  * @return Error status.
336  */
338 static status_t wait_status_bit(uint32_t bit_position, bool bit_value) {
339  if (bit_position > 31) {
340  return OTCRYPTO_BAD_ARGS;
341  }
342 
343  while (true) {
344  uint32_t reg = abs_mmio_read32(kKmacBaseAddr + KMAC_STATUS_REG_OFFSET);
345  if (bitfield_bit32_read(reg, KMAC_STATUS_ALERT_FATAL_FAULT_BIT)) {
346  return OTCRYPTO_FATAL_ERR;
347  }
348  if (bitfield_bit32_read(reg, KMAC_STATUS_ALERT_RECOV_CTRL_UPDATE_ERR_BIT)) {
349  return OTCRYPTO_RECOV_ERR;
350  }
351  if (bitfield_bit32_read(reg, bit_position) == bit_value) {
352  return OTCRYPTO_OK;
353  }
354  }
355 }
356 
357 /**
358  * Encode a given integer as byte array and return its size along with it.
359  *
360  * This is a common procedure that can be used to implement both `left_encode`
361  * and `right_encode` functions defined in NIST SP 800-185. Given an integer
362  * `value` it returns its encoding as a byte array in `encoding_buf`. Meanwhile,
363  * `encoding_header` keeps the size of `encoding_buf`. Later the two can be
364  * combined as below:
365  *
366  * left_encode(`value`) = `encoding_header` || `encoding_buf`
367  * right_encode(`value`) = `encoding_buf` || `encoding_header`
368  *
369  * The caller must ensure that `encoding_buf` and `encoding_header` are not
370  * NULL pointers. This is not checked within this function.
371  *
372  * The maximum `value` that can be encoded is restricted to the maximum value
373  * that can be stored with `size_t` type.
374  *
375  * @param value Integer to be encoded.
376  * @param[out] encoding_buf The output byte array representing `value`.
377  * @param[out] encoding_header The number of bytes written to `encoded_value`.
378  * @return Error code.
379  */
381 static status_t little_endian_encode(size_t value, uint8_t *encoding_buf,
382  uint8_t *encoding_header) {
383  uint8_t len = 0;
384  uint8_t reverse_buf[sizeof(size_t)];
385  do {
386  reverse_buf[len] = value & UINT8_MAX;
387  value >>= 8;
388  len++;
389  } while (value > 0);
390  *encoding_header = len;
391 
392  for (size_t idx = 0; idx < len; idx++) {
393  encoding_buf[idx] = reverse_buf[len - 1 - idx];
394  }
395 
396  return OTCRYPTO_OK;
397 }
398 
399 /**
400  * Set prefix registers.
401  *
402  * This function directly writes to PREFIX registers of KMAC HWIP.
403  * The combined size of customization string and the function name
404  * must not exceed `kKmacPrefixMaxSize`.
405  *
406  * @param func_name Function name input in cSHAKE.
407  * @param cust_str Customization string input in cSHAKE.
408  * @return Error code.
409  */
411 static status_t kmac_set_prefix_regs(const unsigned char *func_name,
412  size_t func_name_len,
413  const unsigned char *cust_str,
414  size_t cust_str_len) {
415  // Initialize with 0 so that the last untouched bytes are set as 0x0
416  uint32_t prefix_buffer[kKmacPrefixRegCount] = {0x0};
417  unsigned char *prefix_buf_ptr = (unsigned char *)prefix_buffer;
418 
419  if (func_name_len + cust_str_len > kKmacPrefixMaxSize) {
420  return OTCRYPTO_BAD_ARGS;
421  }
422 
423  // left_encode(`func_name_len_bits`) below
424  uint8_t bytes_written = 0;
425  HARDENED_TRY(little_endian_encode(func_name_len << 3, prefix_buf_ptr + 1,
426  &bytes_written));
427  prefix_buf_ptr[0] = bytes_written;
428  prefix_buf_ptr += bytes_written + 1;
429 
430  // copy `func_name`
431  memcpy(prefix_buf_ptr, func_name, func_name_len);
432  prefix_buf_ptr += func_name_len;
433 
434  // left_encode(`cust_str_len_bits`) below
435  HARDENED_TRY(little_endian_encode(cust_str_len << 3, prefix_buf_ptr + 1,
436  &bytes_written));
437  prefix_buf_ptr[0] = bytes_written;
438  prefix_buf_ptr += bytes_written + 1;
439 
440  // copy `cust_str`
441  memcpy(prefix_buf_ptr, cust_str, cust_str_len);
442 
443  // Copy from `prefix_buffer` to PREFIX_REGS
444  for (size_t i = 0; i < KMAC_PREFIX_MULTIREG_COUNT; i++) {
445  abs_mmio_write32(kKmacBaseAddr + prefix_offsets[i], prefix_buffer[i]);
446  }
447 
448  return OTCRYPTO_OK;
449 }
450 
451 /**
452  * Initializes the KMAC configuration.
453  *
454  * In particular, this function sets the CFG register of KMAC for given
455  * `operation_type`. The struct type kmac_operation_t is defined in a way that
456  * each field inherently implies a fixed security strength (i.e. half of Keccak
457  * capacity). For instance, if we want to run SHA-3 with 224-bit digest size,
458  * then `operation_type` = kSHA3_224.
459  *
460  * `hw_backed` must be either `kHardenedBoolFalse` or `kHardenedBoolTrue`. For
461  * other values, this function returns an error.
462  * For KMAC operations, if `hw_backed = kHardenedBoolTrue` the sideloaded key
463  * coming from Keymgr is used. If `hw_backed = kHardenedBoolFalse`, the key
464  * configured by SW is used.
465  *
466  * For non-KMAC operations, the value of `hw_backed` can be either of
467  * `kHardenedBoolFalse` or `kHardenedBoolTrue`. It is recommended to set it to
468  * `kHardenedBoolFalse` for consistency.
469  *
470  * @param operation The chosen operation, see kmac_operation_t struct.
471  * @param security_str Security strength for KMAC (128 or 256).
472  * @param hw_backed Whether the key comes from the sideload port.
473  * @return Error code.
474  */
476 static status_t kmac_init(kmac_operation_t operation,
477  kmac_security_str_t security_str,
478  hardened_bool_t hw_backed) {
479  HARDENED_TRY(wait_status_bit(KMAC_STATUS_SHA3_IDLE_BIT, 1));
480 
481  // If the operation is KMAC, ensure that the entropy complex has been
482  // initialized for masking.
483  if (operation == kKmacOperationKMAC) {
484  HARDENED_TRY(entropy_complex_check());
485  }
486 
487  // We need to preserve some bits of CFG register, such as:
488  // entropy_mode, entropy_ready etc. On the other hand, some bits
489  // need to be reset for each invocation.
490  uint32_t cfg_reg =
491  abs_mmio_read32(kKmacBaseAddr + KMAC_CFG_SHADOWED_REG_OFFSET);
492 
493  // Make sure kmac_en and sideload bits of CFG are reset at each invocation
494  // These bits should be set to 1 only if needed by the rest of the code
495  // in this function.
496  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_KMAC_EN_BIT, 0);
497  if (hw_backed == kHardenedBoolTrue) {
498  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_SIDELOAD_BIT, 1);
499  } else if (hw_backed == kHardenedBoolFalse) {
500  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_SIDELOAD_BIT, 0);
501  } else {
502  return OTCRYPTO_BAD_ARGS;
503  };
504 
505  // operation bit fields: Bit 0: `kmac_en`, Bit 1-2: `mode`
506  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_KMAC_EN_BIT,
507  operation & 1);
508  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_MODE_FIELD,
509  operation >> 1);
510 
511  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_KSTRENGTH_FIELD,
512  security_str);
513  abs_mmio_write32_shadowed(kKmacBaseAddr + KMAC_CFG_SHADOWED_REG_OFFSET,
514  cfg_reg);
515 
516  return OTCRYPTO_OK;
517 }
518 
519 /**
520  * Configure the prefix registers with customization string.
521  *
522  * For KMAC, this function ignores `func_name` and uses "KMAC" instead.
523  *
524  * The caller must ensure that `func_name` and `cust_str` have properly
525  * allocated `data` fields whose length matches their `len` fields.
526  *
527  * In total `func_name` and `cust_str` can be at most `kKmacPrefixMaxSize`
528  * bytes.
529  *
530  * @param operation The KMAC or cSHAKE operation.
531  * @param func_name The function name, used for cSHAKE.
532  * @param func_name_len Length of the function name in bytes.
533  * @param cust_str The customization string (both for cSHAKE and KMAC).
534  * @param cust_str_len Length of the customization string in bytes.
535  * @return Error code.
536  */
538 static status_t kmac_write_prefix_block(kmac_operation_t operation,
539  const unsigned char *func_name,
540  size_t func_name_len,
541  const unsigned char *cust_str,
542  size_t cust_str_len) {
543  if (operation == kKmacOperationCSHAKE) {
544  return kmac_set_prefix_regs(func_name, func_name_len, cust_str,
545  cust_str_len);
546  } else if (operation == kKmacOperationKMAC) {
547  return kmac_set_prefix_regs(kKmacFuncNameKMAC, sizeof(kKmacFuncNameKMAC),
548  cust_str, cust_str_len);
549  }
550  return OTCRYPTO_BAD_ARGS;
551 }
552 
553 /**
554  * Update the key registers with given key shares.
555  *
556  * The caller must ensure that `key` struct is properly populated (no NULL
557  * pointers and matching `len`).
558  *
559  * The accepted `key->len` values are {128 / 8, 192 / 8, 256 / 8, 384 / 8,
560  * 512 / 8}, otherwise an error will be returned.
561  *
562  * @param key The input key passed as a struct.
563  * @return Error code.
564  */
566 static status_t kmac_write_key_block(kmac_blinded_key_t *key) {
567  kmac_key_len_t key_len_enum;
568  HARDENED_TRY(kmac_get_key_len_bytes(key->len, &key_len_enum));
569 
570  uint32_t key_len_reg = bitfield_field32_write(
571  KMAC_KEY_LEN_REG_RESVAL, KMAC_KEY_LEN_LEN_FIELD, key_len_enum);
572  abs_mmio_write32(kKmacBaseAddr + KMAC_KEY_LEN_REG_OFFSET, key_len_reg);
573 
574  for (size_t i = 0; i < key->len; i += 4) {
575  abs_mmio_write32(kKmacKeyShare0Addr + i, key->share0[i / 4]);
576  abs_mmio_write32(kKmacKeyShare1Addr + i, key->share1[i / 4]);
577  }
578 
579  return OTCRYPTO_OK;
580 }
581 
582 /**
583  * Common routine for feeding message blocks during SHA/SHAKE/cSHAKE/KMAC.
584  *
585  * Before running this, the operation type must be configured with kmac_init.
586  * Then, we can use this function to feed various bytes of data to the KMAC
587  * core. Note that this is a one-shot implementation, and it does not support
588  * streaming mode.
589  *
590  * This routine does not check input parameters for consistency. For instance,
591  * one can invoke SHA-3_224 with digest_len=32, which will produce 256 bits of
592  * digest. The caller is responsible for ensuring that the digest length and
593  * mode are consistent.
594  *
595  * The caller must ensure that `message_len` bytes (rounded up to the next 32b
596  * word) are allocated at the location pointed to by `message`, and similarly
597  * that `digest_len_words` 32-bit words are allocated at the location pointed
598  * to by `digest`. If `masked_digest` is set, then `digest` must contain 2x
599  * `digest_len_words` to fit both shares.
600  *
601  * @param operation The operation type.
602  * @param message Input message string.
603  * @param message_len Message length in bytes.
604  * @param digest The struct to which the result will be written.
605  * @param digest_len_words Requested digest length in 32-bit words.
606  * @param masked_digest Whether to return the digest in two shares.
607  * @return Error code.
608  */
610 static status_t kmac_process_msg_blocks(kmac_operation_t operation,
611  const uint8_t *message,
612  size_t message_len, uint32_t *digest,
613  size_t digest_len_words,
614  hardened_bool_t masked_digest) {
615  // Block until KMAC is idle.
616  HARDENED_TRY(wait_status_bit(KMAC_STATUS_SHA3_IDLE_BIT, 1));
617 
618  // Issue the start command, so that messages written to MSG_FIFO are forwarded
619  // to Keccak
620  uint32_t cmd_reg = KMAC_CMD_REG_RESVAL;
621  cmd_reg = bitfield_field32_write(cmd_reg, KMAC_CMD_CMD_FIELD,
622  KMAC_CMD_CMD_VALUE_START);
623  abs_mmio_write32(kKmacBaseAddr + KMAC_CMD_REG_OFFSET, cmd_reg);
624  HARDENED_TRY(wait_status_bit(KMAC_STATUS_SHA3_ABSORB_BIT, 1));
625 
626  // Begin by writing a one byte at a time until the data is aligned.
627  size_t i = 0;
628  for (; misalignment32_of((uintptr_t)(&message[i])) > 0 && i < message_len;
629  i++) {
630  HARDENED_TRY(wait_status_bit(KMAC_STATUS_FIFO_FULL_BIT, 0));
631  abs_mmio_write8(kKmacBaseAddr + KMAC_MSG_FIFO_REG_OFFSET, message[i]);
632  }
633 
634  // Write one word at a time as long as there is a full word available.
635  for (; i + sizeof(uint32_t) <= message_len; i += sizeof(uint32_t)) {
636  HARDENED_TRY(wait_status_bit(KMAC_STATUS_FIFO_FULL_BIT, 0));
637  uint32_t next_word = read_32(&message[i]);
638  abs_mmio_write32(kKmacBaseAddr + KMAC_MSG_FIFO_REG_OFFSET, next_word);
639  }
640 
641  // For the last few bytes, we need to write one byte at a time again.
642  for (; i < message_len; i++) {
643  HARDENED_TRY(wait_status_bit(KMAC_STATUS_FIFO_FULL_BIT, 0));
644  abs_mmio_write8(kKmacBaseAddr + KMAC_MSG_FIFO_REG_OFFSET, message[i]);
645  }
646 
647  // If operation=KMAC, then we need to write `right_encode(digest->len)`
648  if (operation == kKmacOperationKMAC) {
649  uint32_t digest_len_bits = 8 * sizeof(uint32_t) * digest_len_words;
650  if (digest_len_bits / (8 * sizeof(uint32_t)) != digest_len_words) {
651  return OTCRYPTO_BAD_ARGS;
652  }
653 
654  // right_encode(`digest_len_bit`) below
655  // According to NIST SP 800-185, the maximum integer that can be encoded
656  // with `right_encode` is the value represented with 255 bytes. However,
657  // this driver supports only up to `digest_len_bits` that can be represented
658  // with `size_t`.
659  uint8_t buf[sizeof(size_t) + 1] = {0};
660  uint8_t bytes_written;
661  HARDENED_TRY(little_endian_encode(digest_len_bits, buf, &bytes_written));
662  buf[bytes_written] = bytes_written;
663  uint8_t *fifo_dst = (uint8_t *)(kKmacBaseAddr + KMAC_MSG_FIFO_REG_OFFSET);
664  memcpy(fifo_dst, buf, bytes_written + 1);
665  }
666 
667  // Issue the process command, so that squeezing phase can start
668  cmd_reg = KMAC_CMD_REG_RESVAL;
669  cmd_reg = bitfield_field32_write(cmd_reg, KMAC_CMD_CMD_FIELD,
670  KMAC_CMD_CMD_VALUE_PROCESS);
671  abs_mmio_write32(kKmacBaseAddr + KMAC_CMD_REG_OFFSET, cmd_reg);
672 
673  // Wait until squeezing is done
674  HARDENED_TRY(wait_status_bit(KMAC_STATUS_SHA3_SQUEEZE_BIT, 1));
675 
676  uint32_t cfg_reg =
677  abs_mmio_read32(kKmacBaseAddr + KMAC_CFG_SHADOWED_REG_OFFSET);
678  uint32_t keccak_str =
679  bitfield_field32_read(cfg_reg, KMAC_CFG_SHADOWED_KSTRENGTH_FIELD);
680  size_t keccak_rate_words;
681  HARDENED_TRY(kmac_get_keccak_rate_words(keccak_str, &keccak_rate_words));
682 
683  // Finally, we can read the two shares of digest and XOR them.
684  size_t idx = 0;
685 
686  while (launder32(idx) < digest_len_words) {
687  // Since we always read in increments of the Keccak rate, the index at
688  // start should always be a multiple of the rate.
689  HARDENED_CHECK_EQ(idx % keccak_rate_words, 0);
690 
691  // Poll the status register until in the 'squeeze' state.
692  HARDENED_TRY(wait_status_bit(KMAC_STATUS_SHA3_SQUEEZE_BIT, 1));
693 
694  // Read words from the state registers (either `digest_len_words` or the
695  // maximum number of words available).
696  size_t offset = 0;
697  if (launder32(masked_digest) == kHardenedBoolTrue) {
698  HARDENED_CHECK_EQ(masked_digest, kHardenedBoolTrue);
699  // Read the digest into each share in turn. Do this in separate loops so
700  // corresponding shares aren't handled close together.
701  for (offset = 0; launder32(idx + offset) < digest_len_words &&
702  offset < keccak_rate_words;
703  offset++) {
704  digest[idx + offset] =
705  abs_mmio_read32(kKmacStateShare0Addr + offset * sizeof(uint32_t));
706  }
707  for (offset = 0; launder32(idx + offset) < digest_len_words &&
708  offset < keccak_rate_words;
709  offset++) {
710  digest[idx + offset + digest_len_words] =
711  abs_mmio_read32(kKmacStateShare1Addr + offset * sizeof(uint32_t));
712  }
713  idx += offset;
714  } else {
715  // Skip right to the hardened check here instead of returning
716  // `OTCRYPTO_BAD_ARGS` if the value is not `kHardenedBoolFalse`; this
717  // value always comes from within the cryptolib, so we expect it to be
718  // valid and should be suspicious if it's not.
719  HARDENED_CHECK_EQ(masked_digest, kHardenedBoolFalse);
720  // Unmask the digest as we read it.
721  for (; launder32(idx) < digest_len_words && offset < keccak_rate_words;
722  offset++) {
723  digest[idx] =
724  abs_mmio_read32(kKmacStateShare0Addr + offset * sizeof(uint32_t));
725  digest[idx] ^=
726  abs_mmio_read32(kKmacStateShare1Addr + offset * sizeof(uint32_t));
727  idx++;
728  }
729  }
730 
731  // If we read all the remaining words and still need more digest, issue
732  // `CMD.RUN` to generate more state.
733  if (launder32(offset) == keccak_rate_words && idx < digest_len_words) {
734  HARDENED_CHECK_EQ(offset, keccak_rate_words);
735  cmd_reg = KMAC_CMD_REG_RESVAL;
736  cmd_reg = bitfield_field32_write(cmd_reg, KMAC_CMD_CMD_FIELD,
737  KMAC_CMD_CMD_VALUE_RUN);
738  abs_mmio_write32(kKmacBaseAddr + KMAC_CMD_REG_OFFSET, cmd_reg);
739  }
740  }
741  HARDENED_CHECK_EQ(idx, digest_len_words);
742 
743  // Poll the status register until in the 'squeeze' state.
744  HARDENED_TRY(wait_status_bit(KMAC_STATUS_SHA3_SQUEEZE_BIT, 1));
745 
746  // Release the KMAC core, so that it goes back to idle mode
747  cmd_reg = KMAC_CMD_REG_RESVAL;
748  cmd_reg = bitfield_field32_write(cmd_reg, KMAC_CMD_CMD_FIELD,
749  KMAC_CMD_CMD_VALUE_DONE);
750  abs_mmio_write32(kKmacBaseAddr + KMAC_CMD_REG_OFFSET, cmd_reg);
751 
752  return OTCRYPTO_OK;
753 }
754 
755 status_t kmac_sha3_224(const uint8_t *message, size_t message_len,
756  uint32_t *digest) {
757  HARDENED_TRY(kmac_init(kKmacOperationSHA3, kKmacSecurityStrength224,
758  /*hw_backed=*/kHardenedBoolFalse));
759 
760  size_t digest_len_words = kSha3_224DigestWords;
761  return kmac_process_msg_blocks(kKmacOperationSHA3, message, message_len,
762  digest, digest_len_words,
763  /*masked_digest=*/kHardenedBoolFalse);
764 }
765 
766 status_t kmac_sha3_256(const uint8_t *message, size_t message_len,
767  uint32_t *digest) {
768  HARDENED_TRY(kmac_init(kKmacOperationSHA3, kKmacSecurityStrength256,
769  /*hw_backed=*/kHardenedBoolFalse));
770 
771  size_t digest_len_words = kSha3_256DigestWords;
772  return kmac_process_msg_blocks(kKmacOperationSHA3, message, message_len,
773  digest, digest_len_words,
774  /*masked_digest=*/kHardenedBoolFalse);
775 }
776 
777 status_t kmac_sha3_384(const uint8_t *message, size_t message_len,
778  uint32_t *digest) {
779  HARDENED_TRY(kmac_init(kKmacOperationSHA3, kKmacSecurityStrength384,
780  /*hw_backed=*/kHardenedBoolFalse));
781 
782  size_t digest_len_words = kSha3_384DigestWords;
783  return kmac_process_msg_blocks(kKmacOperationSHA3, message, message_len,
784  digest, digest_len_words,
785  /*masked_digest=*/kHardenedBoolFalse);
786 }
787 
788 status_t kmac_sha3_512(const uint8_t *message, size_t message_len,
789  uint32_t *digest) {
790  HARDENED_TRY(kmac_init(kKmacOperationSHA3, kKmacSecurityStrength512,
791  /*hw_backed=*/kHardenedBoolFalse));
792 
793  size_t digest_len_words = kSha3_512DigestWords;
794  return kmac_process_msg_blocks(kKmacOperationSHA3, message, message_len,
795  digest, digest_len_words,
796  /*masked_digest=*/kHardenedBoolFalse);
797 }
798 
799 status_t kmac_shake_128(const uint8_t *message, size_t message_len,
800  uint32_t *digest, size_t digest_len) {
801  HARDENED_TRY(kmac_init(kKmacOperationSHAKE, kKmacSecurityStrength128,
802  /*hw_backed=*/kHardenedBoolFalse));
803 
804  return kmac_process_msg_blocks(kKmacOperationSHAKE, message, message_len,
805  digest, digest_len,
806  /*masked_digest=*/kHardenedBoolFalse);
807 }
808 
809 status_t kmac_shake_256(const uint8_t *message, size_t message_len,
810  uint32_t *digest, size_t digest_len) {
811  HARDENED_TRY(kmac_init(kKmacOperationSHAKE, kKmacSecurityStrength256,
812  /*hw_backed=*/kHardenedBoolFalse));
813 
814  return kmac_process_msg_blocks(kKmacOperationSHAKE, message, message_len,
815  digest, digest_len,
816  /*masked_digest=*/kHardenedBoolFalse);
817 }
818 
819 status_t kmac_cshake_128(const uint8_t *message, size_t message_len,
820  const unsigned char *func_name, size_t func_name_len,
821  const unsigned char *cust_str, size_t cust_str_len,
822  uint32_t *digest, size_t digest_len) {
823  HARDENED_TRY(kmac_init(kKmacOperationCSHAKE, kKmacSecurityStrength128,
824  /*hw_backed=*/kHardenedBoolFalse));
825 
826  HARDENED_TRY(kmac_write_prefix_block(kKmacOperationCSHAKE, func_name,
827  func_name_len, cust_str, cust_str_len));
828 
829  return kmac_process_msg_blocks(kKmacOperationCSHAKE, message, message_len,
830  digest, digest_len,
831  /*masked_digest=*/kHardenedBoolFalse);
832 }
833 
834 status_t kmac_cshake_256(const uint8_t *message, size_t message_len,
835  const unsigned char *func_name, size_t func_name_len,
836  const unsigned char *cust_str, size_t cust_str_len,
837  uint32_t *digest, size_t digest_len) {
838  HARDENED_TRY(kmac_init(kKmacOperationCSHAKE, kKmacSecurityStrength256,
839  /*hw_backed=*/kHardenedBoolFalse));
840 
841  HARDENED_TRY(kmac_write_prefix_block(kKmacOperationCSHAKE, func_name,
842  func_name_len, cust_str, cust_str_len));
843 
844  return kmac_process_msg_blocks(kKmacOperationCSHAKE, message, message_len,
845  digest, digest_len,
846  /*masked_digest=*/kHardenedBoolFalse);
847 }
848 
849 status_t kmac_kmac_128(kmac_blinded_key_t *key, hardened_bool_t masked_digest,
850  const uint8_t *message, size_t message_len,
851  const unsigned char *cust_str, size_t cust_str_len,
852  uint32_t *digest, size_t digest_len) {
853  HARDENED_TRY(
854  kmac_init(kKmacOperationKMAC, kKmacSecurityStrength128, key->hw_backed));
855 
856  if (key->hw_backed == kHardenedBoolTrue) {
857  if (key->share0 != NULL || key->share1 != NULL ||
858  key->len != kKmacSideloadKeyLength / 8) {
859  return OTCRYPTO_BAD_ARGS;
860  }
861  } else if (key->hw_backed == kHardenedBoolFalse) {
862  if (key->share0 == NULL || key->share1 == NULL) {
863  return OTCRYPTO_BAD_ARGS;
864  }
865  HARDENED_TRY(kmac_write_key_block(key));
866  } else {
867  return OTCRYPTO_BAD_ARGS;
868  }
869 
870  HARDENED_TRY(kmac_write_prefix_block(kKmacOperationKMAC, /*func_name=*/NULL,
871  /*func_name_len=*/0, cust_str,
872  cust_str_len));
873 
874  return kmac_process_msg_blocks(kKmacOperationKMAC, message, message_len,
875  digest, digest_len, masked_digest);
876 }
877 
878 status_t kmac_kmac_256(kmac_blinded_key_t *key, hardened_bool_t masked_digest,
879  const uint8_t *message, size_t message_len,
880  const unsigned char *cust_str, size_t cust_str_len,
881  uint32_t *digest, size_t digest_len) {
882  HARDENED_TRY(
883  kmac_init(kKmacOperationKMAC, kKmacSecurityStrength256, key->hw_backed));
884 
885  if (key->hw_backed == kHardenedBoolTrue) {
886  if (key->share0 != NULL || key->share1 != NULL ||
887  key->len != kKmacSideloadKeyLength / 8) {
888  return OTCRYPTO_BAD_ARGS;
889  }
890  } else if (key->hw_backed == kHardenedBoolFalse) {
891  if (key->share0 == NULL || key->share1 == NULL) {
892  return OTCRYPTO_BAD_ARGS;
893  }
894  HARDENED_TRY(kmac_write_key_block(key));
895  } else {
896  return OTCRYPTO_BAD_ARGS;
897  }
898 
899  HARDENED_TRY(kmac_write_prefix_block(kKmacOperationKMAC, /*func_name=*/NULL,
900  /*func_name_len=*/0, cust_str,
901  cust_str_len));
902 
903  return kmac_process_msg_blocks(kKmacOperationKMAC, message, message_len,
904  digest, digest_len, masked_digest);
905 }