Software APIs
kmac_serial.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 
10 #include "sw/device/lib/testing/test_framework/ottf_test_config.h"
11 #include "sw/device/sca/lib/prng.h"
13 #include "sw/device/tests/penetrationtests/firmware/lib/pentest_lib.h"
14 
16 #include "kmac_regs.h"
17 
18 /**
19  * OpenTitan program for side-channel analysis of the absorb step of a KMAC128
20  * operation using a 128-bit key.
21  *
22  * This program implements the following simple serial commands:
23  * - Set key ('k')*,
24  * - Absorb ('p')*,
25  * - FvsR batch absorb ('b')*,
26  * - FvsR batch fixed key set ('t')*,
27  * - Version ('v')+,
28  * - Seed PRNG ('s')+,
29  * Commands marked with * are implemented in this file. Those marked with + are
30  * implemented in the simple serial library. See
31  * https://wiki.newae.com/SimpleSerial for details on the protocol.
32  */
33 
34 OTTF_DEFINE_TEST_CONFIG();
35 
36 enum {
37  /**
38  * Key length in bytes.
39  */
40  kKeyLength = 16,
41  /**
42  * Message length in bytes.
43  */
44  kMessageLength = 16,
45  /**
46  * Digest length in 32-bit words.
47  */
48  kDigestLength = 8,
49  /**
50  * Number of cycles (at `kClockFreqCpuHz`) that Ibex should sleep to minimize
51  * noise during SHA3 operations. Caution: This number should be chosen to
52  * provide enough time. Otherwise, Ibex might wake up while SHA3 is still busy
53  * and disturb the capture. Currently, we use a start trigger delay of 320
54  * clock cycles and the scope captures 160 clock cycles at kClockFreqCpuHz
55  * (3200 samples). On the scope side, an offset of 395 clock cycles (7900
56  * samples) is used to ignore 1) the start trigger delay for the PROCESS
57  * command, and 2) the absorb phase for the fixed prefix.
58  */
59  kIbexSha3SleepCycles = 1180,
60  /**
61  * Max number of traces per batch.
62  */
63  kNumBatchOpsMax = 128,
64 };
65 
66 /**
67  * A handle to KMAC.
68  */
69 static dif_kmac_t kmac;
70 
71 /**
72  * KMAC operation state.
73  */
74 static dif_kmac_operation_state_t kmac_operation_state;
75 
76 /**
77  * KMAC key.
78  *
79  * Used for caching the key in the 'k' (set key) command packet until it is used
80  * when handling a 'p' (absorb) command.
81  */
82 static dif_kmac_key_t kmac_key;
83 
84 /**
85  * KMAC fixed key.
86  *
87  * Used for caching the fixed key in the 't' (set fixed key) command packet
88  * until it is used when handling a 'b' (batch capture) command.
89  */
90 uint8_t key_fixed[kKeyLength];
91 
92 /**
93  * Fixed-key indicator.
94  *
95  * Used in the 'b' (batch capture) command for indicating whether to use fixed
96  * or random key.
97  */
98 static bool run_fixed = false;
99 
100 /**
101  * An array of keys to be used in a batch
102  */
103 uint8_t batch_keys[kNumBatchOpsMax][kKeyLength];
104 
105 /**
106  * An array of messages to be used in a batch
107  */
108 uint8_t batch_messages[kNumBatchOpsMax][kMessageLength];
109 
110 /**
111  * Blocks until KMAC is idle.
112  */
113 static void kmac_block_until_idle(void) {
114  // TODO(#7842): Remove when `dif_kmac_get_status()` is implemented.
115  uint32_t reg;
116  do {
117  reg = mmio_region_read32(kmac.base_addr, KMAC_STATUS_REG_OFFSET);
118  } while (!bitfield_bit32_read(reg, KMAC_STATUS_SHA3_IDLE_BIT));
119 }
120 
121 /**
122  * Resets KMAC to idle state.
123  */
124 static void kmac_reset(void) {
125  // TODO(#7842): Remove when `dif_kmac_reset()` is implemented.
126  mmio_region_write32(
127  kmac.base_addr, KMAC_CMD_REG_OFFSET,
128  bitfield_field32_write(0, KMAC_CMD_CMD_FIELD, KMAC_CMD_CMD_VALUE_DONE));
129  kmac_block_until_idle();
130 }
131 
132 /**
133  * Report whether the hardware is currently idle.
134  *
135  * If the hardware is not idle then the `CFG` register is locked.
136  *
137  * @param params Hardware parameters.
138  * @returns Whether the hardware is currently idle or not.
139  */
140 static bool is_state_idle(void) {
141  uint32_t reg = mmio_region_read32(kmac.base_addr, KMAC_STATUS_REG_OFFSET);
142  return bitfield_bit32_read(reg, KMAC_STATUS_SHA3_IDLE_BIT);
143 }
144 
145 /**
146  * Calculate the rate (r) in bits from the given security level.
147  *
148  * @param security_level Security level in bits.
149  * @returns Rate in bits.
150  */
151 static uint32_t calculate_rate_bits(uint32_t security_level) {
152  // Formula for the rate in bits is:
153  //
154  // r = 1600 - c
155  //
156  // Where c is the capacity (the security level in bits multiplied by two).
157  return 1600 - 2 * security_level;
158 }
159 
160 /**
161  * Starts KMAC message without sending START command.
162  *
163  * Based on dif_kmac_mode_kmac_start().
164  *
165  * Unlike dif_kmac_mode_kmac_start(), this function doesn't provide the START
166  * command to the hardware, i.e., just the key is provided and the initial setup
167  * for starting a new message is performed.
168  */
169 static dif_result_t kmac_msg_start(dif_kmac_mode_kmac_t mode, size_t l,
170  const dif_kmac_key_t *k,
172  if (k == NULL || l > kDifKmacMaxOutputLenWords) {
173  return kDifBadArg;
174  }
175 
176  // Set key strength and calculate rate (r).
177  uint32_t kstrength;
178  switch (mode) {
180  kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L128;
181  kmac_operation_state.r = calculate_rate_bits(128) / 32;
182  break;
184  kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256;
185  kmac_operation_state.r = calculate_rate_bits(256) / 32;
186  break;
187  default:
188  return kDifBadArg;
189  }
190  kmac_operation_state.offset = 0;
191  kmac_operation_state.d = l;
192  kmac_operation_state.append_d = true;
193 
194  uint32_t key_len;
195  switch (k->length) {
196  case kDifKmacKeyLen128:
197  key_len = KMAC_KEY_LEN_LEN_VALUE_KEY128;
198  break;
199  case kDifKmacKeyLen192:
200  key_len = KMAC_KEY_LEN_LEN_VALUE_KEY192;
201  break;
202  case kDifKmacKeyLen256:
203  key_len = KMAC_KEY_LEN_LEN_VALUE_KEY256;
204  break;
205  case kDifKmacKeyLen384:
206  key_len = KMAC_KEY_LEN_LEN_VALUE_KEY384;
207  break;
208  case kDifKmacKeyLen512:
209  key_len = KMAC_KEY_LEN_LEN_VALUE_KEY512;
210  break;
211  default:
212  return kDifBadArg;
213  }
214 
215  // Hardware must be idle to start an operation.
216  if (!is_state_idle()) {
217  return kDifError;
218  }
219 
220  // Set key length and shares.
221  // Uniform sharing is achieved by XORing a random number into both shares.
222  mmio_region_write32(kmac.base_addr, KMAC_KEY_LEN_REG_OFFSET, key_len);
223  for (int i = 0; i < ARRAYSIZE(k->share0); ++i) {
224  // Run LFSR for 32 steps to ensure that all state bits are updated.
225  const uint32_t a = pentest_next_lfsr(32, kPentestLfsrMasking);
226  mmio_region_write32(kmac.base_addr,
227  KMAC_KEY_SHARE0_0_REG_OFFSET +
228  (ptrdiff_t)i * (ptrdiff_t)sizeof(uint32_t),
229  k->share0[i] ^ a);
230  mmio_region_write32(kmac.base_addr,
231  KMAC_KEY_SHARE1_0_REG_OFFSET +
232  (ptrdiff_t)i * (ptrdiff_t)sizeof(uint32_t),
233  k->share1[i] ^ a);
234  }
235 
236  // Configure cSHAKE mode with the given strength and enable KMAC mode.
237  uint32_t cfg_reg =
238  mmio_region_read32(kmac.base_addr, KMAC_CFG_SHADOWED_REG_OFFSET);
239  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_KMAC_EN_BIT, true);
240  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_KSTRENGTH_FIELD,
241  kstrength);
242  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_MODE_FIELD,
243  KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE);
244  mmio_region_write32(kmac.base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
245  mmio_region_write32(kmac.base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
246 
247  // Initialize prefix registers with function name ("KMAC") and empty
248  // customization string. The empty customization string will be overwritten if
249  // a non-empty string is provided.
250  uint32_t prefix_regs[11] = {
251  0x4D4B2001, // 1 32 'K' 'M'
252  0x00014341, // 'A' 'C' 1 0
253  };
254 
255  // Encoded customization string (s) must be at least 3 bytes long if it is not
256  // the empty string.
257  if (s != NULL && s->length >= 3) {
258  // First two bytes overwrite the pre-encoded empty customization string.
259  prefix_regs[1] &= 0xFFFF;
260  prefix_regs[1] |= (uint32_t)((uint8_t)s->buffer[0]) << 16;
261  prefix_regs[1] |= (uint32_t)((uint8_t)s->buffer[1]) << 24;
262  memcpy(&prefix_regs[2], &s->buffer[2], s->length - 2);
263  }
264 
265  // Write PREFIX register values.
266  const mmio_region_t base = kmac.base_addr;
267  mmio_region_write32(base, KMAC_PREFIX_0_REG_OFFSET, prefix_regs[0]);
268  mmio_region_write32(base, KMAC_PREFIX_1_REG_OFFSET, prefix_regs[1]);
269  mmio_region_write32(base, KMAC_PREFIX_2_REG_OFFSET, prefix_regs[2]);
270  mmio_region_write32(base, KMAC_PREFIX_3_REG_OFFSET, prefix_regs[3]);
271  mmio_region_write32(base, KMAC_PREFIX_4_REG_OFFSET, prefix_regs[4]);
272  mmio_region_write32(base, KMAC_PREFIX_5_REG_OFFSET, prefix_regs[5]);
273  mmio_region_write32(base, KMAC_PREFIX_6_REG_OFFSET, prefix_regs[6]);
274  mmio_region_write32(base, KMAC_PREFIX_7_REG_OFFSET, prefix_regs[7]);
275  mmio_region_write32(base, KMAC_PREFIX_8_REG_OFFSET, prefix_regs[8]);
276  mmio_region_write32(base, KMAC_PREFIX_9_REG_OFFSET, prefix_regs[9]);
277  mmio_region_write32(base, KMAC_PREFIX_10_REG_OFFSET, prefix_regs[10]);
278 
279  return kDifOk;
280 }
281 
282 /**
283  * Writes the message including its length to the message FIFO.
284  *
285  * Based on dif_kmac_absorb().
286  *
287  * Unlike dif_kmac_absorb(), this function 1) doesn't require the hardware
288  * to enter the 'absorb' state before writing the message into the message
289  * FIFO, and 2) appends the output length afterwards (normally done as
290  * part of dif_kmac_squeeze()).
291  */
292 static dif_result_t kmac_msg_write(const void *msg, size_t msg_len,
293  size_t *processed) {
294  // Set the number of bytes processed to 0.
295  if (processed != NULL) {
296  *processed = 0;
297  }
298 
299  if (msg == NULL && msg_len != 0) {
300  return kDifBadArg;
301  }
302 
303  // Check that an operation has been started.
304  if (kmac_operation_state.r == 0) {
305  return kDifError;
306  }
307 
308  // Copy the message one byte at a time.
309  // This could be sped up copying a word at a time but be careful
310  // about message endianness (e.g. only copy a word at a time when in
311  // little-endian mode).
312  for (size_t i = 0; i < msg_len; ++i) {
313  mmio_region_write8(kmac.base_addr, KMAC_MSG_FIFO_REG_OFFSET,
314  ((const uint8_t *)msg)[i]);
315  }
316 
317  if (processed != NULL) {
318  *processed = msg_len;
319  }
320 
321  // The KMAC operation requires that the output length (d) in bits be right
322  // encoded and appended to the end of the message.
323  // Note: kDifKmacMaxOutputLenWords could be reduced to make this code
324  // simpler. For example, a maximum of `(UINT16_MAX - 32) / 32` (just under
325  // 8 KiB) would mean that d is guaranteed to be less than 0xFFFF.
326  uint32_t d = kmac_operation_state.d * 32;
327  int out_len = 1 + (d > 0xFF) + (d > 0xFFFF) + (d > 0xFFFFFF);
328  int shift = (out_len - 1) * 8;
329  while (shift >= 8) {
330  mmio_region_write8(kmac.base_addr, KMAC_MSG_FIFO_REG_OFFSET,
331  (uint8_t)(d >> shift));
332  shift -= 8;
333  }
334  mmio_region_write8(kmac.base_addr, KMAC_MSG_FIFO_REG_OFFSET, (uint8_t)d);
335  mmio_region_write8(kmac.base_addr, KMAC_MSG_FIFO_REG_OFFSET,
336  (uint8_t)out_len);
337  kmac_operation_state.squeezing = true;
338 
339  return kDifOk;
340 }
341 
342 /**
343  * Starts actual processing of a previously provided message.
344  *
345  * This function issues a START command directly followed by a PROCESS command.
346  */
347 static void kmac_msg_proc(void) {
348  // Issue START command.
349  uint32_t cmd_reg =
350  bitfield_field32_write(0, KMAC_CMD_CMD_FIELD, KMAC_CMD_CMD_VALUE_START);
351  mmio_region_write32(kmac.base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
352 
353  // Issue PROCESS command.
354  cmd_reg =
355  bitfield_field32_write(0, KMAC_CMD_CMD_FIELD, KMAC_CMD_CMD_VALUE_PROCESS);
356  mmio_region_write32(kmac.base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
357 }
358 
359 /**
360  * Waits until the hardware enters the 'squeeze' state.
361  *
362  * If the hardware enters the `squeeze` state, this means the output state is
363  * valid and can be read by software.
364  */
365 static void kmac_msg_done(void) {
366  // TODO(#7841, #7842): Remove when we finalize the way we capture traces.
367  uint32_t reg;
368  do {
369  reg = mmio_region_read32(kmac.base_addr, KMAC_STATUS_REG_OFFSET);
370  } while (!bitfield_bit32_read(reg, KMAC_STATUS_SHA3_SQUEEZE_BIT));
371 }
372 
373 /**
374  * Reads the digest from the hardware.
375  *
376  * Based on dif_kmac_squeeze().
377  *
378  * Unlike dif_kmac_squeeze(), this function 1) doesn't wait until the hardware
379  * enters the 'squeeze' state, 2) doesn't append the output length, 3) doesn't
380  * support the generation of more state.
381  */
382 static dif_result_t kmac_get_digest(uint32_t *out, size_t len) {
383  if (out == NULL && len != 0) {
384  return kDifBadArg;
385  }
386 
387  while (len > 0) {
388  size_t n = len;
389  size_t remaining = kmac_operation_state.r - kmac_operation_state.offset;
390  if (kmac_operation_state.d != 0 &&
391  kmac_operation_state.d < kmac_operation_state.r) {
392  remaining = kmac_operation_state.d - kmac_operation_state.offset;
393  }
394  if (n > remaining) {
395  n = remaining;
396  }
397  if (n == 0) {
398  // Normally, the hardware would now have to generate more state. But
399  // since at this point, the power measurement is already stopped, we don't
400  // support that here.
401  return kDifError;
402  }
403 
404  ptrdiff_t offset =
405  KMAC_STATE_REG_OFFSET +
406  (ptrdiff_t)kmac_operation_state.offset * (ptrdiff_t)sizeof(uint32_t);
407  for (size_t i = 0; i < n; ++i) {
408  // Read both shares from state register and combine using XOR.
409  uint32_t share0 = mmio_region_read32(kmac.base_addr, offset);
410  uint32_t share1 =
411  mmio_region_read32(kmac.base_addr, offset + kDifKmacStateShareOffset);
412  *out++ = share0 ^ share1;
413  offset += sizeof(uint32_t);
414  }
415  kmac_operation_state.offset += n;
416  len -= n;
417  }
418  return kDifOk;
419 }
420 
421 /**
422  * Initializes the KMAC peripheral.
423  *
424  * This function configures KMAC to use software entropy.
425  */
426 static void kmac_init(void) {
428  dif_kmac_init(mmio_region_from_addr(TOP_EARLGREY_KMAC_BASE_ADDR), &kmac));
429 
431  .entropy_mode = kDifKmacEntropyModeSoftware,
432  .entropy_fast_process = kDifToggleDisabled,
433  .entropy_seed = {0xb153e3fe, 0x09596819, 0x3e85a6e8, 0xb6dcdaba,
434  0x50dc409c, 0x11e1ebd1},
435  .message_big_endian = kDifToggleDisabled,
436  .output_big_endian = kDifToggleDisabled,
437  .sideload = kDifToggleDisabled,
438  .msg_mask = kDifToggleEnabled,
439  };
440  SS_CHECK_DIF_OK(dif_kmac_configure(&kmac, config));
441 
442  kmac_block_until_idle();
443 }
444 
445 /**
446  * Simple serial 'k' (set key) command handler.
447  *
448  * This function simply caches the provided key in the static `kmac_key`
449  * variable so that it can be used in subsequent operations. This function does
450  * not use key shares to simplify side-channel analysis. The key must be
451  * `kKeyLength` bytes long.
452  *
453  * @param key Key. Must be `kKeyLength` bytes long.
454  * @param key_len Key length. Must be equal to `kKeyLength`.
455  * @return Result of the operation.
456  */
457 static void sha3_serial_set_key(const uint8_t *key, size_t key_len) {
458  SS_CHECK(key_len == kKeyLength);
459 
460  kmac_key = (dif_kmac_key_t){
461  .length = kDifKmacKeyLen128,
462  };
463  memcpy(kmac_key.share0, key, kKeyLength);
464 }
465 
466 /**
467  * Absorbs a message using KMAC128 without a customization string.
468  *
469  * @param msg Message.
470  * @param msg_len Message length.
471  */
472 static void sha3_serial_absorb(const uint8_t *msg, size_t msg_len) {
473  // Start a new message and write data to message FIFO.
475  kmac_msg_start(kDifKmacModeKmacLen128, kDigestLength, &kmac_key, NULL));
476  SS_CHECK_DIF_OK(kmac_msg_write(msg, msg_len, NULL));
477 
478  // Start the SHA3 processing (this triggers the capture) and go to sleep.
479  // Using the SecCmdDelay hardware parameter, the KMAC unit is
480  // configured to start operation 40 cycles after receiving the START and PROC
481  // commands. This allows Ibex to go to sleep in order to not disturb the
482  // capture.
483  pentest_call_and_sleep(kmac_msg_proc, kIbexSha3SleepCycles, false, false);
484 }
485 
486 /**
487  * Simple serial 'p' (absorb) command handler.
488  *
489  * Absorbs the given message using KMAC128 without a customization string,
490  * and sends the digest over UART. This function also handles the trigger
491  * signal.
492  *
493  * @param msg Message.
494  * @param msg_len Message length.
495  */
496 static void sha3_serial_single_absorb(const uint8_t *msg, size_t msg_len) {
497  SS_CHECK(msg_len == kMessageLength);
498 
499  // Ungate the capture trigger signal and then start the operation.
500  pentest_set_trigger_high();
501  sha3_serial_absorb(msg, msg_len);
502  pentest_set_trigger_low();
503 
504  // Check KMAC has finsihed processing the message.
505  kmac_msg_done();
506 
507  // Read the digest and send it to the host for verification.
508  uint32_t out[kDigestLength];
509  SS_CHECK_DIF_OK(kmac_get_digest(out, kDigestLength));
510  simple_serial_send_packet('r', (uint8_t *)out, kDigestLength * 4);
511 
512  // Reset before the next absorb since KMAC must be idle before starting
513  // another absorb.
514  kmac_reset();
515 }
516 
517 static void sha3_serial_fixed_key_set(const uint8_t *key, size_t key_len) {
518  SS_CHECK(key_len == kKeyLength);
519  memcpy(key_fixed, key, key_len);
520 }
521 
522 static void sha3_serial_batch(const uint8_t *data, size_t data_len) {
523  uint32_t num_encryptions = 0;
524  uint32_t out[kDigestLength];
525  uint32_t batch_digest[kDigestLength];
526  SS_CHECK(data_len == sizeof(num_encryptions));
527  num_encryptions = read_32(data);
528 
529  for (uint32_t j = 0; j < kDigestLength; ++j) {
530  batch_digest[j] = 0;
531  }
532 
533  for (uint32_t i = 0; i < num_encryptions; ++i) {
534  if (run_fixed) {
535  memcpy(batch_keys[i], key_fixed, kKeyLength);
536  } else {
537  prng_rand_bytes(batch_keys[i], kKeyLength);
538  }
539  prng_rand_bytes(batch_messages[i], kMessageLength);
540  run_fixed = batch_messages[i][0] & 0x1;
541  }
542 
543  for (uint32_t i = 0; i < num_encryptions; ++i) {
544  kmac_reset();
545  memcpy(kmac_key.share0, batch_keys[i], kKeyLength);
546 
547  pentest_set_trigger_high();
548  sha3_serial_absorb(batch_messages[i], kMessageLength);
549  pentest_set_trigger_low();
550 
551  kmac_msg_done();
552  SS_CHECK_DIF_OK(kmac_get_digest(out, kDigestLength));
553 
554  // The correctness of each batch is verified by computing and sending
555  // the batch digest. This digest is computed by XORing all outputs of
556  // the batch.
557  for (uint32_t j = 0; j < kDigestLength; ++j) {
558  batch_digest[j] ^= out[j];
559  }
560  }
561  // Send the batch digest to the host for verification.
562  simple_serial_send_packet('r', (uint8_t *)batch_digest, kDigestLength * 4);
563 }
564 
565 /**
566  * Simple serial 'l' (seed lfsr) command handler.
567  *
568  * This function only supports 4-byte seeds.
569  *
570  * @param seed A buffer holding the seed.
571  */
572 static void sha3_serial_seed_lfsr(const uint8_t *seed, size_t seed_len) {
573  SS_CHECK(seed_len == sizeof(uint32_t));
574  pentest_seed_lfsr(read_32(seed), kPentestLfsrMasking);
575 }
576 
577 /**
578  * Main function.
579  *
580  * Initializes peripherals and processes simple serial packets received over
581  * UART.
582  */
583 bool test_main(void) {
584  pentest_init(kPentestTriggerSourceKmac,
585  kPentestPeripheralIoDiv4 | kPentestPeripheralKmac);
586 
587  LOG_INFO("Running kmac_serial");
588 
589  LOG_INFO("Initializing simple serial interface to capture board.");
590  simple_serial_init(pentest_get_uart());
591  simple_serial_register_handler('k', sha3_serial_set_key);
592  simple_serial_register_handler('p', sha3_serial_single_absorb);
593  simple_serial_register_handler('b', sha3_serial_batch);
594  simple_serial_register_handler('f', sha3_serial_fixed_key_set);
595  simple_serial_register_handler('l', sha3_serial_seed_lfsr);
596 
597  LOG_INFO("Initializing the KMAC peripheral.");
598  kmac_init();
599 
600  LOG_INFO("Starting simple serial packet handling.");
601  while (true) {
603  }
604 }