Software APIs
dif_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 
6 
7 #include <assert.h>
8 
12 
13 #include "kmac_regs.h" // Generated.
14 
15 enum {
16  /**
17  * The maximum amount of usable bits in the output state.
18  *
19  * This constant may be assumed to be a multiple of 32.
20  *
21  * The actual number of usable bits may be lower than the value defined
22  * depending on the mode in use. The intent is that this constant is useful
23  * for sizing fixed length buffers.
24  *
25  * Formula for the rate in bits is:
26  *
27  * r = 1600 - c
28  *
29  * Where c is the capacity (the security level in bits multiplied by two).
30  *
31  * The lowest security level is 128 (e.g. SHAKE128).
32  */
33  kDifKmacMaximumBitRate = 1600 - (2 * 128),
34 };
35 
37  const char *data, size_t len, dif_kmac_customization_string_t *out) {
38  if ((data == NULL && len != 0) || out == NULL) {
39  return kDifBadArg;
40  }
41 
43  return kDifBadArg;
44  }
45 
46  static_assert(kDifKmacMaxCustomizationStringLen <= UINT16_MAX / 8,
47  "length requires more than 3 bytes to left encode");
48  static_assert(ARRAYSIZE(out->buffer) >= kDifKmacMaxCustomizationStringLen + 3,
49  "buffer is not large enough");
50 
51  // Left encode length in bits.
52  uint16_t bits = ((uint16_t)len) * 8;
53  char *buffer = out->buffer;
54  if (bits <= UINT8_MAX) {
55  out->length = len + 2;
56  *buffer++ = 1;
57  *buffer++ = (char)bits;
58  } else {
59  out->length = len + 3;
60  *buffer++ = 2;
61  // Most significant byte is first (i.e. big-endian).
62  *buffer++ = (char)(bits >> 8);
63  *buffer++ = (char)bits;
64  }
65 
66  memcpy(buffer, data, len);
67 
68  return kDifOk;
69 }
70 
71 dif_result_t dif_kmac_function_name_init(const char *data, size_t len,
73  if ((data == NULL && len != 0) || out == NULL) {
74  return kDifBadArg;
75  }
76 
77  if (len > kDifKmacMaxFunctionNameLen) {
78  return kDifBadArg;
79  }
80 
81  static_assert(kDifKmacMaxFunctionNameLen <= UINT8_MAX / 8,
82  "length requires more than 2 bytes to left encode");
83  static_assert(ARRAYSIZE(out->buffer) >= kDifKmacMaxFunctionNameLen + 2,
84  "buffer is not large enough");
85 
86  // Length of the data to be stored into buffer.
87  out->length = len + 2;
88 
89  // Left encode length in bits.
90  out->buffer[0] = 1;
91  out->buffer[1] = (char)(len * 8);
92 
93  memcpy(&out->buffer[2], data, len);
94 
95  return kDifOk;
96 }
97 
98 /**
99  * Report whether the hardware is currently idle.
100  *
101  * If the hardware is not idle then the `CFG` register is locked.
102  *
103  * @param kmac Handle.
104  * @returns Whether the hardware is currently idle or not.
105  */
106 static bool is_state_idle(const dif_kmac_t *kmac) {
107  uint32_t reg = mmio_region_read32(kmac->base_addr, KMAC_STATUS_REG_OFFSET);
108  return bitfield_bit32_read(reg, KMAC_STATUS_SHA3_IDLE_BIT);
109 }
110 
111 /**
112  * Report whether the hardware is currently in the absorb state and accepting
113  * writes to the message FIFO.
114  *
115  * Note that writes to the message FIFO may still block if it is full.
116  *
117  * @param kmac Handle.
118  * @returns Whether the hardware is currently absorbing or not.
119  */
120 static bool is_state_absorb(const dif_kmac_t *kmac) {
121  uint32_t reg = mmio_region_read32(kmac->base_addr, KMAC_STATUS_REG_OFFSET);
122  return bitfield_bit32_read(reg, KMAC_STATUS_SHA3_ABSORB_BIT);
123 }
124 
125 /**
126  * Report whether the hardware is currently in the squeeze state which means
127  * that the output state is valid and may be read by software.
128  *
129  * @param kmac Handle.
130  * @returns Whether the hardware is currently in the squeeze state or not.
131  */
132 static bool is_state_squeeze(const dif_kmac_t *kmac) {
133  uint32_t reg = mmio_region_read32(kmac->base_addr, KMAC_STATUS_REG_OFFSET);
134  return bitfield_bit32_read(reg, KMAC_STATUS_SHA3_SQUEEZE_BIT);
135 }
136 
138  if (kmac == NULL) {
139  return kDifBadArg;
140  }
141  uint32_t reg =
142  mmio_region_read32(kmac->base_addr, KMAC_INTR_STATE_REG_OFFSET);
143  *error = bitfield_bit32_read(reg, KMAC_INTR_STATE_KMAC_ERR_BIT);
144  return kDifOk;
145 }
146 
148  if (kmac == NULL) {
149  return kDifBadArg;
150  }
151  uint32_t reg = 0;
152  reg = bitfield_bit32_write(reg, KMAC_INTR_STATE_KMAC_ERR_BIT, true);
153  mmio_region_write32(kmac->base_addr, KMAC_INTR_STATE_REG_OFFSET, reg);
154  return kDifOk;
155 }
156 
157 dif_result_t dif_kmac_poll_status(const dif_kmac_t *kmac, uint32_t flag) {
158  while (true) {
159  uint32_t reg = mmio_region_read32(kmac->base_addr, KMAC_STATUS_REG_OFFSET);
160  if (bitfield_bit32_read(reg, flag)) {
161  break;
162  }
163  bool error;
165  if (error) {
166  return kDifError;
167  }
168  }
169  return kDifOk;
170 }
171 
173  if (kmac == NULL) {
174  return kDifBadArg;
175  }
176 
177  // Entropy mode.
178  uint32_t entropy_mode_value;
179  bool entropy_ready = false;
180  switch (config.entropy_mode) {
181  case kDifKmacEntropyModeIdle:
182  entropy_mode_value = KMAC_CFG_SHADOWED_ENTROPY_MODE_VALUE_IDLE_MODE;
183  break;
184  case kDifKmacEntropyModeEdn:
185  entropy_mode_value = KMAC_CFG_SHADOWED_ENTROPY_MODE_VALUE_EDN_MODE;
186  entropy_ready = true;
187  break;
188  case kDifKmacEntropyModeSoftware:
189  entropy_mode_value = KMAC_CFG_SHADOWED_ENTROPY_MODE_VALUE_SW_MODE;
190  entropy_ready = true;
191  break;
192  default:
193  return kDifBadArg;
194  }
195 
196  // Check that the hardware is in an idle state.
197  if (!is_state_idle(kmac)) {
198  return kDifLocked;
199  }
200 
201  // Write entropy period register.
202  uint32_t entropy_period_reg = 0;
203  entropy_period_reg = bitfield_field32_write(
204  entropy_period_reg, KMAC_ENTROPY_PERIOD_WAIT_TIMER_FIELD,
205  config.entropy_wait_timer);
206  entropy_period_reg = bitfield_field32_write(
207  entropy_period_reg, KMAC_ENTROPY_PERIOD_PRESCALER_FIELD,
208  config.entropy_prescaler);
209 
210  mmio_region_write32(kmac->base_addr, KMAC_ENTROPY_PERIOD_REG_OFFSET,
211  entropy_period_reg);
212 
213  // Write threshold register.
214  uint32_t entropy_threshold_reg =
215  KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_REG_RESVAL;
216  entropy_threshold_reg = bitfield_field32_write(
217  entropy_threshold_reg,
218  KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_THRESHOLD_FIELD,
219  config.entropy_hash_threshold);
220 
221  mmio_region_write32_shadowed(
222  kmac->base_addr, KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_REG_OFFSET,
223  entropy_threshold_reg);
224 
225  // Write configuration register.
226  uint32_t cfg_reg = 0;
227  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_MSG_ENDIANNESS_BIT,
228  config.message_big_endian);
229  cfg_reg =
230  bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_STATE_ENDIANNESS_BIT,
231  config.output_big_endian);
232  cfg_reg = bitfield_field32_write(
233  cfg_reg, KMAC_CFG_SHADOWED_ENTROPY_MODE_FIELD, entropy_mode_value);
234  cfg_reg =
235  bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_ENTROPY_FAST_PROCESS_BIT,
236  config.entropy_fast_process);
237  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_SIDELOAD_BIT,
238  config.sideload);
239  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_ENTROPY_READY_BIT,
240  entropy_ready);
241 
242  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_MSG_MASK_BIT,
243  config.msg_mask);
244 
245  mmio_region_write32_shadowed(kmac->base_addr, KMAC_CFG_SHADOWED_REG_OFFSET,
246  cfg_reg);
247 
248  // Write entropy seed registers.
249  for (int i = 0; i < kDifKmacEntropySeedWords; ++i) {
250  mmio_region_write32(kmac->base_addr, KMAC_ENTROPY_SEED_REG_OFFSET,
251  config.entropy_seed[i]);
252  }
253 
254  return kDifOk;
255 }
256 
257 /**
258  * Calculate the rate (r) in bits from the given security level.
259  *
260  * @param security_level Security level in bits.
261  * @returns Rate in bits.
262  */
263 static uint32_t calculate_rate_bits(uint32_t security_level) {
264  // Formula for the rate in bits is:
265  //
266  // r = 1600 - c
267  //
268  // Where c is the capacity (the security level in bits multiplied by two).
269  return 1600 - 2 * security_level;
270 }
271 
273  const dif_kmac_t *kmac, dif_kmac_operation_state_t *operation_state,
274  dif_kmac_mode_sha3_t mode) {
275  if (kmac == NULL || operation_state == NULL) {
276  return kDifBadArg;
277  }
278 
279  // Set key strength and calculate rate (r) and digest length (d) in 32-bit
280  // words.
281  uint32_t kstrength;
282  switch (mode) {
284  kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L224;
285  operation_state->offset = 0;
286  operation_state->r = calculate_rate_bits(224) / 32;
287  operation_state->d = 224 / 32;
288  break;
290  kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256;
291  operation_state->offset = 0;
292  operation_state->r = calculate_rate_bits(256) / 32;
293  operation_state->d = 256 / 32;
294  break;
296  kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L384;
297  operation_state->offset = 0;
298  operation_state->r = calculate_rate_bits(384) / 32;
299  operation_state->d = 384 / 32;
300  break;
302  kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L512;
303  operation_state->offset = 0;
304  operation_state->r = calculate_rate_bits(512) / 32;
305  operation_state->d = 512 / 32;
306  break;
307  default:
308  return kDifBadArg;
309  }
310 
311  // Hardware must be idle to start an operation.
312  if (!is_state_idle(kmac)) {
313  return kDifError;
314  }
315 
316  operation_state->squeezing = false;
317  operation_state->append_d = false;
318 
319  // Configure SHA-3 mode with the given strength.
320  uint32_t cfg_reg =
321  mmio_region_read32(kmac->base_addr, KMAC_CFG_SHADOWED_REG_OFFSET);
322  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_KSTRENGTH_FIELD,
323  kstrength);
324  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_MODE_FIELD,
325  KMAC_CFG_SHADOWED_MODE_VALUE_SHA3);
326  mmio_region_write32(kmac->base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
327  mmio_region_write32(kmac->base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
328 
329  // Issue start command.
330  uint32_t cmd_reg =
331  bitfield_field32_write(0, KMAC_CMD_CMD_FIELD, KMAC_CMD_CMD_VALUE_START);
332  mmio_region_write32(kmac->base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
333 
334  // Poll until the status register is in the 'absorb' state.
335  return dif_kmac_poll_status(kmac, KMAC_STATUS_SHA3_ABSORB_BIT);
336 }
337 
339  const dif_kmac_t *kmac, dif_kmac_operation_state_t *operation_state,
340  dif_kmac_mode_shake_t mode) {
341  if (kmac == NULL || operation_state == NULL) {
342  return kDifBadArg;
343  }
344 
345  // Set key strength and calculate rate (r).
346  uint32_t kstrength;
347  switch (mode) {
349  kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L128;
350  operation_state->r = calculate_rate_bits(128) / 32;
351  break;
353  kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256;
354  operation_state->r = calculate_rate_bits(256) / 32;
355  break;
356  default:
357  return kDifBadArg;
358  }
359 
360  // Hardware must be idle to start an operation.
361  if (!is_state_idle(kmac)) {
362  return kDifError;
363  }
364  operation_state->squeezing = false;
365  operation_state->append_d = false;
366  operation_state->d = 0; // Zero indicates variable digest length.
367  operation_state->offset = 0;
368 
369  // Configure SHAKE mode with the given strength.
370  uint32_t cfg_reg =
371  mmio_region_read32(kmac->base_addr, KMAC_CFG_SHADOWED_REG_OFFSET);
372  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_KSTRENGTH_FIELD,
373  kstrength);
374  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_MODE_FIELD,
375  KMAC_CFG_SHADOWED_MODE_VALUE_SHAKE);
376  mmio_region_write32(kmac->base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
377  mmio_region_write32(kmac->base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
378 
379  // Issue start command.
380  uint32_t cmd_reg =
381  bitfield_field32_write(0, KMAC_CMD_CMD_FIELD, KMAC_CMD_CMD_VALUE_START);
382  mmio_region_write32(kmac->base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
383 
384  return dif_kmac_poll_status(kmac, KMAC_STATUS_SHA3_ABSORB_BIT);
385 }
386 
388  const dif_kmac_t *kmac, dif_kmac_operation_state_t *operation_state,
391  if (kmac == NULL || operation_state == NULL) {
392  return kDifBadArg;
393  }
394 
395  // Use SHAKE if both N and S are empty strings.
396  bool n_is_empty = n == NULL || (n->buffer[0] == 1 && n->buffer[1] == 0);
397  bool s_is_empty = s == NULL || (s->buffer[0] == 1 && s->buffer[1] == 0);
398  if (n_is_empty && s_is_empty) {
399  switch (mode) {
401  return dif_kmac_mode_shake_start(kmac, operation_state,
404  return dif_kmac_mode_shake_start(kmac, operation_state,
406  default:
407  return kDifBadArg;
408  }
409  }
410 
411  // Set key strength and calculate rate (r).
412  uint32_t kstrength;
413  switch (mode) {
415  kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L128;
416  operation_state->r = calculate_rate_bits(128) / 32;
417  break;
419  kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256;
420  operation_state->r = calculate_rate_bits(256) / 32;
421  break;
422  default:
423  return kDifBadArg;
424  }
425 
426  // Hardware must be idle to start an operation.
427  if (!is_state_idle(kmac)) {
428  return kDifError;
429  }
430  operation_state->squeezing = false;
431  operation_state->append_d = false;
432  operation_state->d = 0; // Zero indicates variable digest length.
433  operation_state->offset = 0;
434 
435  // Configure cSHAKE mode with the given strength.
436  uint32_t cfg_reg =
437  mmio_region_read32(kmac->base_addr, KMAC_CFG_SHADOWED_REG_OFFSET);
438  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_KSTRENGTH_FIELD,
439  kstrength);
440  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_MODE_FIELD,
441  KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE);
442  mmio_region_write32(kmac->base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
443  mmio_region_write32(kmac->base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
444 
445  // Calculate PREFIX register values.
446  uint32_t prefix_regs[11] = {0};
447  uint8_t *prefix_data = (uint8_t *)prefix_regs;
448  if (n == NULL || n->length < 3) {
449  // Append left encoded empty string.
450  prefix_data[0] = 1;
451  prefix_data[1] = 0;
452  prefix_data += 2;
453  } else {
454  memcpy(prefix_data, n->buffer, n->length);
455  prefix_data += n->length;
456  }
457  if (s == NULL || s->length == 0) {
458  // Append left encoded empty string.
459  prefix_data[0] = 1;
460  prefix_data[1] = 0;
461  } else {
462  memcpy(prefix_data, s->buffer, s->length);
463  }
464 
465  // Write PREFIX register values.
466  const mmio_region_t base = kmac->base_addr;
467  mmio_region_write32(base, KMAC_PREFIX_0_REG_OFFSET, prefix_regs[0]);
468  mmio_region_write32(base, KMAC_PREFIX_1_REG_OFFSET, prefix_regs[1]);
469  mmio_region_write32(base, KMAC_PREFIX_2_REG_OFFSET, prefix_regs[2]);
470  mmio_region_write32(base, KMAC_PREFIX_3_REG_OFFSET, prefix_regs[3]);
471  mmio_region_write32(base, KMAC_PREFIX_4_REG_OFFSET, prefix_regs[4]);
472  mmio_region_write32(base, KMAC_PREFIX_5_REG_OFFSET, prefix_regs[5]);
473  mmio_region_write32(base, KMAC_PREFIX_6_REG_OFFSET, prefix_regs[6]);
474  mmio_region_write32(base, KMAC_PREFIX_7_REG_OFFSET, prefix_regs[7]);
475  mmio_region_write32(base, KMAC_PREFIX_8_REG_OFFSET, prefix_regs[8]);
476  mmio_region_write32(base, KMAC_PREFIX_9_REG_OFFSET, prefix_regs[9]);
477  mmio_region_write32(base, KMAC_PREFIX_10_REG_OFFSET, prefix_regs[10]);
478 
479  // Issue start command.
480  uint32_t cmd_reg =
481  bitfield_field32_write(0, KMAC_CMD_CMD_FIELD, KMAC_CMD_CMD_VALUE_START);
482  mmio_region_write32(kmac->base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
483 
484  return dif_kmac_poll_status(kmac, KMAC_STATUS_SHA3_ABSORB_BIT);
485 }
486 
488  const dif_kmac_t *kmac, dif_kmac_operation_state_t *operation_state,
489  dif_kmac_mode_kmac_t mode, size_t l, const dif_kmac_key_t *k,
491  if (kmac == NULL || operation_state == NULL || k == NULL ||
493  return kDifBadArg;
494  }
495 
496  // Set key strength and calculate rate (r).
497  uint32_t kstrength;
498  switch (mode) {
500  kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L128;
501  operation_state->r = calculate_rate_bits(128) / 32;
502  break;
504  kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256;
505  operation_state->r = calculate_rate_bits(256) / 32;
506  break;
507  default:
508  return kDifBadArg;
509  }
510  operation_state->squeezing = false;
511  operation_state->offset = 0;
512  operation_state->d = l;
513  operation_state->append_d = true;
514 
515  uint32_t key_len;
516  switch (k->length) {
517  case kDifKmacKeyLen128:
518  key_len = KMAC_KEY_LEN_LEN_VALUE_KEY128;
519  break;
520  case kDifKmacKeyLen192:
521  key_len = KMAC_KEY_LEN_LEN_VALUE_KEY192;
522  break;
523  case kDifKmacKeyLen256:
524  key_len = KMAC_KEY_LEN_LEN_VALUE_KEY256;
525  break;
526  case kDifKmacKeyLen384:
527  key_len = KMAC_KEY_LEN_LEN_VALUE_KEY384;
528  break;
529  case kDifKmacKeyLen512:
530  key_len = KMAC_KEY_LEN_LEN_VALUE_KEY512;
531  break;
532  default:
533  return kDifBadArg;
534  }
535 
536  // Hardware must be idle to start an operation.
537  if (!is_state_idle(kmac)) {
538  return kDifError;
539  }
540  // Set key length and shares.
541  mmio_region_write32(kmac->base_addr, KMAC_KEY_LEN_REG_OFFSET, key_len);
542  for (int i = 0; i < ARRAYSIZE(k->share0); ++i) {
543  mmio_region_write32(kmac->base_addr,
544  KMAC_KEY_SHARE0_0_REG_OFFSET +
545  (ptrdiff_t)i * (ptrdiff_t)sizeof(uint32_t),
546  k->share0[i]);
547  mmio_region_write32(kmac->base_addr,
548  KMAC_KEY_SHARE1_0_REG_OFFSET +
549  (ptrdiff_t)i * (ptrdiff_t)sizeof(uint32_t),
550  k->share1[i]);
551  }
552 
553  // Configure cSHAKE mode with the given strength and enable KMAC mode.
554  uint32_t cfg_reg =
555  mmio_region_read32(kmac->base_addr, KMAC_CFG_SHADOWED_REG_OFFSET);
556  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_KMAC_EN_BIT, true);
557  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_KSTRENGTH_FIELD,
558  kstrength);
559  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_MODE_FIELD,
560  KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE);
561  mmio_region_write32(kmac->base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
562  mmio_region_write32(kmac->base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
563 
564  // Initialize prefix registers with function name ("KMAC") and empty
565  // customization string. The empty customization string will be overwritten if
566  // a non-empty string is provided.
567  uint32_t prefix_regs[11] = {
568  0x4D4B2001, // 1 32 'K' 'M'
569  0x00014341, // 'A' 'C' 1 0
570  };
571 
572  // Encoded customization string (s) must be at least 3 bytes long if it is not
573  // the empty string.
574  if (s != NULL && s->length >= 3) {
575  // First two bytes overwrite the pre-encoded empty customization string.
576  prefix_regs[1] &= 0xFFFF;
577  prefix_regs[1] |= (uint32_t)((uint8_t)s->buffer[0]) << 16;
578  prefix_regs[1] |= (uint32_t)((uint8_t)s->buffer[1]) << 24;
579  memcpy(&prefix_regs[2], &s->buffer[2], s->length - 2);
580  }
581 
582  // Write PREFIX register values.
583  const mmio_region_t base = kmac->base_addr;
584  mmio_region_write32(base, KMAC_PREFIX_0_REG_OFFSET, prefix_regs[0]);
585  mmio_region_write32(base, KMAC_PREFIX_1_REG_OFFSET, prefix_regs[1]);
586  mmio_region_write32(base, KMAC_PREFIX_2_REG_OFFSET, prefix_regs[2]);
587  mmio_region_write32(base, KMAC_PREFIX_3_REG_OFFSET, prefix_regs[3]);
588  mmio_region_write32(base, KMAC_PREFIX_4_REG_OFFSET, prefix_regs[4]);
589  mmio_region_write32(base, KMAC_PREFIX_5_REG_OFFSET, prefix_regs[5]);
590  mmio_region_write32(base, KMAC_PREFIX_6_REG_OFFSET, prefix_regs[6]);
591  mmio_region_write32(base, KMAC_PREFIX_7_REG_OFFSET, prefix_regs[7]);
592  mmio_region_write32(base, KMAC_PREFIX_8_REG_OFFSET, prefix_regs[8]);
593  mmio_region_write32(base, KMAC_PREFIX_9_REG_OFFSET, prefix_regs[9]);
594  mmio_region_write32(base, KMAC_PREFIX_10_REG_OFFSET, prefix_regs[10]);
595 
596  // Issue start command.
597  uint32_t cmd_reg =
598  bitfield_field32_write(0, KMAC_CMD_CMD_FIELD, KMAC_CMD_CMD_VALUE_START);
599  mmio_region_write32(kmac->base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
600 
601  return dif_kmac_poll_status(kmac, KMAC_STATUS_SHA3_ABSORB_BIT);
602 }
603 
604 static void msg_fifo_write(const dif_kmac_t *kmac, const unsigned char *data,
605  size_t len) {
606  // Copy message using aligned word sized loads and stores where possible to
607  // improve performance. Note: the parts of the message copied a byte at a time
608  // will not be byte swapped in big-endian mode.
609  for (; len != 0 && ((uintptr_t)data) % sizeof(uint32_t); --len) {
610  mmio_region_write8(kmac->base_addr, KMAC_MSG_FIFO_REG_OFFSET, *data++);
611  }
612  for (; len >= sizeof(uint32_t); len -= sizeof(uint32_t)) {
613  mmio_region_write32(kmac->base_addr, KMAC_MSG_FIFO_REG_OFFSET,
614  read_32(data));
615  data += sizeof(uint32_t);
616  }
617  for (; len != 0; --len) {
618  mmio_region_write8(kmac->base_addr, KMAC_MSG_FIFO_REG_OFFSET, *data++);
619  }
620 }
621 
623  dif_kmac_operation_state_t *operation_state,
624  const void *msg, size_t len, size_t *processed) {
625  // Set the number of bytes processed to 0.
626  if (processed != NULL) {
627  *processed = 0;
628  }
629 
630  if (kmac == NULL || operation_state == NULL || (msg == NULL && len != 0)) {
631  return kDifBadArg;
632  }
633 
634  // Check that an operation has been started.
635  if (operation_state->r == 0) {
636  return kDifError;
637  }
638 
639  // Poll until the status register is in the 'absorb' state.
640  if (!is_state_absorb(kmac)) {
641  return kDifError;
642  }
643 
644  // Copy message using aligned word sized loads and stores where possible to
645  // improve performance. Note: the parts of the message copied a byte at a time
646  // will not be byte swapped in big-endian mode.
647  const unsigned char *data = (const unsigned char *)msg;
649  while (len > 0) {
650  // Read the status register.
652 
653  // Calculate the remaining space in the message FIFO based on the
654  // `FIFO_DEPTH` status field.
655  size_t free_entries = (KMAC_PARAM_NUM_ENTRIES_MSG_FIFO - status.fifo_depth);
656  size_t max_len = free_entries * KMAC_PARAM_NUM_BYTES_MSG_FIFO_ENTRY;
657  size_t write_len = (len < max_len) ? len : max_len;
658  msg_fifo_write(kmac, data, write_len);
659  data += write_len;
660  len -= write_len;
661 
662  // If `processed` is non-null, do not continue after the first iteration;
663  // return the number of bytes written and `kDifKmacIncomplete`.
664  if (processed != NULL) {
665  *processed = write_len;
666  break;
667  }
668  }
669 
670  return kDifOk;
671 }
672 
674  dif_kmac_operation_state_t *operation_state,
675  uint32_t *out, size_t len, size_t *processed) {
676  if (kmac == NULL || operation_state == NULL || (out == NULL && len != 0)) {
677  return kDifBadArg;
678  }
679 
680  // Set `processed` to 0 so we can return early without setting it again.
681  if (processed != NULL) {
682  *processed = 0;
683  }
684 
685  const mmio_region_t base = kmac->base_addr;
686 
687  // Move into squeezing state (if not already in it).
688  // Do this even if the length requested is 0 or too big.
689  if (!operation_state->squeezing) {
690  if (operation_state->append_d) {
691  // The KMAC operation requires that the output length (d) in bits be right
692  // encoded and appended to the end of the message.
693  // Note: kDifKmacMaxOutputLenWords could be reduced to make this code
694  // simpler. For example, a maximum of `(UINT16_MAX - 32) / 32` (just under
695  // 8 KiB) would mean that d is guaranteed to be less than 0xFFFF.
696  uint32_t d = operation_state->d * 32;
697  int len = 1 + (d > 0xFF) + (d > 0xFFFF) + (d > 0xFFFFFF);
698  int shift = (len - 1) * 8;
699  while (shift >= 8) {
700  mmio_region_write8(base, KMAC_MSG_FIFO_REG_OFFSET,
701  (uint8_t)(d >> shift));
702  shift -= 8;
703  }
704  mmio_region_write8(base, KMAC_MSG_FIFO_REG_OFFSET, (uint8_t)d);
705  mmio_region_write8(base, KMAC_MSG_FIFO_REG_OFFSET, (uint8_t)len);
706  }
707  operation_state->squeezing = true;
708 
709  // Issue squeeze command.
710  uint32_t cmd_reg = bitfield_field32_write(0, KMAC_CMD_CMD_FIELD,
711  KMAC_CMD_CMD_VALUE_PROCESS);
712  mmio_region_write32(base, KMAC_CMD_REG_OFFSET, cmd_reg);
713  }
714 
715  // If the operation has a fixed length output then the total number of bytes
716  // requested must not exceed that length.
717  if (operation_state->d != 0 &&
718  len > (operation_state->d - operation_state->offset)) {
719  return kDifError;
720  }
721 
722  if (len == 0) {
723  return kDifOk;
724  }
725 
726  while (len > 0) {
727  size_t n = len;
728  size_t remaining = operation_state->r - operation_state->offset;
729  if (operation_state->d != 0 && operation_state->d < operation_state->r) {
730  remaining = operation_state->d - operation_state->offset;
731  }
732  if (n > remaining) {
733  n = remaining;
734  }
735  if (n == 0) {
736  // Reduce the digest length to reflect consumed output state.
737  if (operation_state->d != 0) {
738  if (operation_state->d <= operation_state->r) {
739  return kDifError;
740  }
741  operation_state->d -= operation_state->r;
742  }
743 
744  // Issue run command to generate more state.
745  uint32_t cmd_reg =
746  bitfield_field32_write(0, KMAC_CMD_CMD_FIELD, KMAC_CMD_CMD_VALUE_RUN);
747  mmio_region_write32(base, KMAC_CMD_REG_OFFSET, cmd_reg);
748  operation_state->offset = 0;
749  continue;
750  }
751 
752  // Poll the status register until in the 'squeeze' state.
754  dif_kmac_poll_status(kmac, KMAC_STATUS_SHA3_SQUEEZE_BIT));
755 
756  ptrdiff_t offset =
757  KMAC_STATE_REG_OFFSET +
758  (ptrdiff_t)operation_state->offset * (ptrdiff_t)sizeof(uint32_t);
759  for (size_t i = 0; i < n; ++i) {
760  // Read both shares from state register and combine using XOR.
761  uint32_t share0 = mmio_region_read32(base, offset);
762  uint32_t share1 =
763  mmio_region_read32(base, offset + kDifKmacStateShareOffset);
764  *out++ = share0 ^ share1;
765  offset += sizeof(uint32_t);
766  }
767  operation_state->offset += n;
768  len -= n;
769  if (processed != NULL) {
770  *processed += n;
771  }
772  }
773  return kDifOk;
774 }
775 
777  dif_kmac_operation_state_t *operation_state) {
778  if (kmac == NULL || operation_state == NULL) {
779  return kDifBadArg;
780  }
781 
782  // The hardware should (must?) complete squeeze operation before the DONE
783  // command is issued.
784  if (!operation_state->squeezing) {
785  return kDifError;
786  }
787  while (true) {
788  if (is_state_squeeze(kmac)) {
789  break;
790  }
791  // TODO(#6248): check for error.
792  }
793 
794  // Issue done command.
795  uint32_t cmd_reg =
796  bitfield_field32_write(0, KMAC_CMD_CMD_FIELD, KMAC_CMD_CMD_VALUE_DONE);
797  mmio_region_write32(kmac->base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
798 
799  // Reset operation state.
800  operation_state->squeezing = false;
801  operation_state->append_d = false;
802  operation_state->offset = 0;
803  operation_state->r = 0;
804  operation_state->d = 0;
805 
806  return kDifOk;
807 }
808 
810  bool *is_locked) {
811  if (kmac == NULL || is_locked == NULL) {
812  return kDifBadArg;
813  }
814 
815  uint32_t reg =
816  mmio_region_read32(kmac->base_addr, KMAC_CFG_REGWEN_REG_OFFSET);
817  *is_locked = !bitfield_bit32_read(reg, KMAC_CFG_REGWEN_EN_BIT);
818  return kDifOk;
819 }
820 
822  dif_kmac_status_t *kmac_status) {
823  if (kmac == NULL || kmac_status == NULL) {
824  return kDifBadArg;
825  }
826 
827  uint32_t reg = mmio_region_read32(kmac->base_addr, KMAC_STATUS_REG_OFFSET);
828 
829  kmac_status->sha3_state = bitfield_field32_read(
830  reg,
831  (bitfield_field32_t){.mask = 0x07, .index = KMAC_STATUS_SHA3_IDLE_BIT});
832 
833  kmac_status->fifo_depth =
834  bitfield_field32_read(reg, KMAC_STATUS_FIFO_DEPTH_FIELD);
835 
836  kmac_status->fifo_state = bitfield_field32_read(
837  reg,
838  (bitfield_field32_t){.mask = 0x03, .index = KMAC_STATUS_FIFO_EMPTY_BIT});
839 
840  kmac_status->faults = bitfield_field32_read(
841  reg, (bitfield_field32_t){.mask = 0x03,
842  .index = KMAC_STATUS_ALERT_FATAL_FAULT_BIT});
843 
844  return kDifOk;
845 }
846 
848  uint32_t *hash_ctr) {
849  if (kmac == NULL || hash_ctr == NULL) {
850  return kDifBadArg;
851  }
852 
853  uint32_t reg = mmio_region_read32(kmac->base_addr,
854  KMAC_ENTROPY_REFRESH_HASH_CNT_REG_OFFSET);
855 
856  *hash_ctr =
857  bitfield_field32_read(reg, KMAC_ENTROPY_REFRESH_HASH_CNT_HASH_CNT_FIELD);
858 
859  return kDifOk;
860 }
861 
863  uint32_t *info) {
864  if (kmac == NULL || error == NULL || info == NULL) {
865  return kDifBadArg;
866  }
867 
868  uint32_t reg = mmio_region_read32(kmac->base_addr, KMAC_ERR_CODE_REG_OFFSET);
869  *info = reg & 0xFFFFFF;
870  *error = (reg >> 24) & 0xFF;
871  return kDifOk;
872 }
873 
875  dif_kmac_operation_state_t *operation_state) {
876  if (kmac == NULL || operation_state == NULL) {
877  return kDifBadArg;
878  }
879  operation_state->d = 0;
880  operation_state->r = 0;
881  operation_state->offset = 0;
882  operation_state->squeezing = false;
884  return kDifOk;
885 }
886 
888  if (kmac == NULL) {
889  return kDifBadArg;
890  }
891  uint32_t reg = 0;
892  reg = bitfield_bit32_write(reg, KMAC_CMD_ERR_PROCESSED_BIT, 1);
893  mmio_region_write32(kmac->base_addr, KMAC_CMD_REG_OFFSET, reg);
894  return kDifOk;
895 }