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  uint32_t *capacity) {
677  if (kmac == NULL || operation_state == NULL || (out == NULL && len != 0)) {
678  return kDifBadArg;
679  }
680 
681  // Set `processed` to 0 so we can return early without setting it again.
682  if (processed != NULL) {
683  *processed = 0;
684  }
685 
686  const mmio_region_t base = kmac->base_addr;
687 
688  // Move into squeezing state (if not already in it).
689  // Do this even if the length requested is 0 or too big.
690  if (!operation_state->squeezing) {
691  if (operation_state->append_d) {
692  // The KMAC operation requires that the output length (d) in bits be right
693  // encoded and appended to the end of the message.
694  // Note: kDifKmacMaxOutputLenWords could be reduced to make this code
695  // simpler. For example, a maximum of `(UINT16_MAX - 32) / 32` (just under
696  // 8 KiB) would mean that d is guaranteed to be less than 0xFFFF.
697  uint32_t d = operation_state->d * 32;
698  int len = 1 + (d > 0xFF) + (d > 0xFFFF) + (d > 0xFFFFFF);
699  int shift = (len - 1) * 8;
700  while (shift >= 8) {
701  mmio_region_write8(base, KMAC_MSG_FIFO_REG_OFFSET,
702  (uint8_t)(d >> shift));
703  shift -= 8;
704  }
705  mmio_region_write8(base, KMAC_MSG_FIFO_REG_OFFSET, (uint8_t)d);
706  mmio_region_write8(base, KMAC_MSG_FIFO_REG_OFFSET, (uint8_t)len);
707  }
708  operation_state->squeezing = true;
709 
710  // Issue squeeze command.
711  uint32_t cmd_reg = bitfield_field32_write(0, KMAC_CMD_CMD_FIELD,
712  KMAC_CMD_CMD_VALUE_PROCESS);
713  mmio_region_write32(base, KMAC_CMD_REG_OFFSET, cmd_reg);
714  }
715 
716  // If the operation has a fixed length output then the total number of bytes
717  // requested must not exceed that length.
718  if (operation_state->d != 0 &&
719  len > (operation_state->d - operation_state->offset)) {
720  return kDifError;
721  }
722 
723  if (len == 0) {
724  return kDifOk;
725  }
726 
727  while (len > 0) {
728  size_t n = len;
729  size_t remaining = operation_state->r - operation_state->offset;
730  if (operation_state->d != 0 && operation_state->d < operation_state->r) {
731  remaining = operation_state->d - operation_state->offset;
732  }
733  if (n > remaining) {
734  n = remaining;
735  }
736  if (n == 0) {
737  // Reduce the digest length to reflect consumed output state.
738  if (operation_state->d != 0) {
739  if (operation_state->d <= operation_state->r) {
740  return kDifError;
741  }
742  operation_state->d -= operation_state->r;
743  }
744 
745  // Issue run command to generate more state.
746  uint32_t cmd_reg =
747  bitfield_field32_write(0, KMAC_CMD_CMD_FIELD, KMAC_CMD_CMD_VALUE_RUN);
748  mmio_region_write32(base, KMAC_CMD_REG_OFFSET, cmd_reg);
749  operation_state->offset = 0;
750  continue;
751  }
752 
753  // Poll the status register until in the 'squeeze' state.
755  dif_kmac_poll_status(kmac, KMAC_STATUS_SHA3_SQUEEZE_BIT));
756 
757  ptrdiff_t offset =
758  KMAC_STATE_REG_OFFSET +
759  (ptrdiff_t)operation_state->offset * (ptrdiff_t)sizeof(uint32_t);
760  for (size_t i = 0; i < n; ++i) {
761  // Read both shares from state register and combine using XOR.
762  uint32_t share0 = mmio_region_read32(base, offset);
763  uint32_t share1 =
764  mmio_region_read32(base, offset + kDifKmacStateShareOffset);
765  *out++ = share0 ^ share1;
766  offset += sizeof(uint32_t);
767  }
768  operation_state->offset += n;
769  len -= n;
770  if (processed != NULL) {
771  *processed += n;
772  }
773  // Read also the capacity of the state, if non-NULL buffer is given.
774  // This is only useful for testing that capacity is not leaked during
775  // sideloaded KMAC operations.
776  if (capacity != NULL) {
777  ptrdiff_t capacity_offset =
778  KMAC_STATE_REG_OFFSET +
779  (ptrdiff_t)operation_state->r * (ptrdiff_t)sizeof(uint32_t);
780  for (int i = 0; i < kDifKmacStateWords - operation_state->r; ++i) {
781  uint32_t share0 = mmio_region_read32(base, capacity_offset);
782  uint32_t share1 = mmio_region_read32(
783  base, capacity_offset + kDifKmacStateShareOffset);
784  *capacity++ = share0 ^ share1;
785  capacity_offset += sizeof(uint32_t);
786  }
787  }
788  }
789  return kDifOk;
790 }
791 
793  dif_kmac_operation_state_t *operation_state) {
794  if (kmac == NULL || operation_state == NULL) {
795  return kDifBadArg;
796  }
797 
798  // The hardware should (must?) complete squeeze operation before the DONE
799  // command is issued.
800  if (!operation_state->squeezing) {
801  return kDifError;
802  }
803  while (true) {
804  if (is_state_squeeze(kmac)) {
805  break;
806  }
807  // TODO(#6248): check for error.
808  }
809 
810  // Issue done command.
811  uint32_t cmd_reg =
812  bitfield_field32_write(0, KMAC_CMD_CMD_FIELD, KMAC_CMD_CMD_VALUE_DONE);
813  mmio_region_write32(kmac->base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
814 
815  // Reset operation state.
816  operation_state->squeezing = false;
817  operation_state->append_d = false;
818  operation_state->offset = 0;
819  operation_state->r = 0;
820  operation_state->d = 0;
821 
822  return kDifOk;
823 }
824 
826  bool *is_locked) {
827  if (kmac == NULL || is_locked == NULL) {
828  return kDifBadArg;
829  }
830 
831  uint32_t reg =
832  mmio_region_read32(kmac->base_addr, KMAC_CFG_REGWEN_REG_OFFSET);
833  *is_locked = !bitfield_bit32_read(reg, KMAC_CFG_REGWEN_EN_BIT);
834  return kDifOk;
835 }
836 
838  dif_kmac_status_t *kmac_status) {
839  if (kmac == NULL || kmac_status == NULL) {
840  return kDifBadArg;
841  }
842 
843  uint32_t reg = mmio_region_read32(kmac->base_addr, KMAC_STATUS_REG_OFFSET);
844 
845  kmac_status->sha3_state = bitfield_field32_read(
846  reg,
847  (bitfield_field32_t){.mask = 0x07, .index = KMAC_STATUS_SHA3_IDLE_BIT});
848 
849  kmac_status->fifo_depth =
850  bitfield_field32_read(reg, KMAC_STATUS_FIFO_DEPTH_FIELD);
851 
852  kmac_status->fifo_state = bitfield_field32_read(
853  reg,
854  (bitfield_field32_t){.mask = 0x03, .index = KMAC_STATUS_FIFO_EMPTY_BIT});
855 
856  kmac_status->faults = bitfield_field32_read(
857  reg, (bitfield_field32_t){.mask = 0x03,
858  .index = KMAC_STATUS_ALERT_FATAL_FAULT_BIT});
859 
860  return kDifOk;
861 }
862 
864  uint32_t *hash_ctr) {
865  if (kmac == NULL || hash_ctr == NULL) {
866  return kDifBadArg;
867  }
868 
869  uint32_t reg = mmio_region_read32(kmac->base_addr,
870  KMAC_ENTROPY_REFRESH_HASH_CNT_REG_OFFSET);
871 
872  *hash_ctr =
873  bitfield_field32_read(reg, KMAC_ENTROPY_REFRESH_HASH_CNT_HASH_CNT_FIELD);
874 
875  return kDifOk;
876 }
877 
879  uint32_t *info) {
880  if (kmac == NULL || error == NULL || info == NULL) {
881  return kDifBadArg;
882  }
883 
884  uint32_t reg = mmio_region_read32(kmac->base_addr, KMAC_ERR_CODE_REG_OFFSET);
885  *info = reg & 0xFFFFFF;
886  *error = (reg >> 24) & 0xFF;
887  return kDifOk;
888 }
889 
891  dif_kmac_operation_state_t *operation_state) {
892  if (kmac == NULL || operation_state == NULL) {
893  return kDifBadArg;
894  }
895  operation_state->d = 0;
896  operation_state->r = 0;
897  operation_state->offset = 0;
898  operation_state->squeezing = false;
900  return kDifOk;
901 }
902 
904  if (kmac == NULL) {
905  return kDifBadArg;
906  }
907  uint32_t reg = 0;
908  reg = bitfield_bit32_write(reg, KMAC_CMD_ERR_PROCESSED_BIT, 1);
909  mmio_region_write32(kmac->base_addr, KMAC_CMD_REG_OFFSET, reg);
910  return kDifOk;
911 }