Software APIs
sha3_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 
5 #include <stddef.h>
6 
12 #include "sw/device/lib/testing/test_framework/ottf_test_config.h"
13 #include "sw/device/sca/lib/prng.h"
15 #include "sw/device/tests/penetrationtests/firmware/lib/pentest_lib.h"
16 
18 #include "kmac_regs.h"
19 
20 /**
21  * OpenTitan program for side-channel analysis of the absorb step of a KMAC128
22  * operation using a 128-bit key.
23  *
24  * This program implements the following simple serial commands:
25  * - Absorb ('p')*,
26  * - FvsR batch absorb ('b')*,
27  * - FvsR batch fixed key set ('t')*,
28  * - Version ('v')+,
29  * - Seed PRNG ('s')+,
30  * - Disable/Enable masks ('m')*
31  * Commands marked with * are implemented in this file. Those marked with + are
32  * implemented in the simple serial library. See
33  * https://wiki.newae.com/SimpleSerial for details on the protocol.
34  */
35 
36 OTTF_DEFINE_TEST_CONFIG();
37 
38 enum {
39  /**
40  * Key length in bytes.
41  */
42  kKeyLength = 16,
43  /**
44  * Message length in bytes.
45  */
46  kMessageLength = 16,
47  /**
48  * Digest length in 32-bit words.
49  */
50  kDigestLength = 8,
51  /**
52  * Number of cycles (at `kClockFreqCpuHz`) that Ibex should sleep to minimize
53  * noise during SHA3 operations. Caution: This number should be chosen to
54  * provide enough time. Otherwise, Ibex might wake up while SHA3 is still busy
55  * and disturb the capture. Currently, we use a start trigger delay of 320
56  * clock cycles and the scope captures 120 clock cycles at kClockFreqCpuHz
57  * (2400 samples). On the scope side, an offset of 320 clock cycles (6400
58  * samples) can be used to ignore the start trigger delay for the PROCESS
59  * command.
60  */
61  kIbexSha3SleepCycles = 1060,
62  /**
63  * Max number of traces per batch.
64  */
65  kNumBatchOpsMax = 128,
66 };
67 
68 /**
69  * A handle to KMAC.
70  */
71 static dif_kmac_t kmac;
72 
73 /**
74  * The KMAC config.
75  */
76 static dif_kmac_config_t config = (dif_kmac_config_t){
77  .entropy_mode = kDifKmacEntropyModeSoftware,
78  .entropy_fast_process = kDifToggleDisabled,
79  .entropy_seed = {0xb153e3fe, 0x09596819, 0x3e85a6e8, 0xb6dcdaba, 0x50dc409c,
80  0x11e1ebd1},
81  .message_big_endian = kDifToggleDisabled,
82  .output_big_endian = kDifToggleDisabled,
83  .sideload = kDifToggleDisabled,
84  .msg_mask = kDifToggleEnabled,
85 };
86 
87 /**
88  * KMAC operation state.
89  */
90 static dif_kmac_operation_state_t kmac_operation_state;
91 
92 /**
93  * SHA3 fixed message.
94  *
95  * Used for caching the fixed key in the 't' (set fixed key) command packet
96  * until it is used when handling a 'b' (batch capture) command.
97  */
98 uint8_t message_fixed[kMessageLength];
99 
100 /**
101  * Fixed-message indicator.
102  *
103  * Used in the 'b' (batch capture) command for indicating whether to use fixed
104  * or random message.
105  */
106 static bool run_fixed = false;
107 
108 /**
109  * An array of keys to be used in a batch
110  */
111 uint8_t batch_keys[kNumBatchOpsMax][kKeyLength];
112 
113 /**
114  * An array of messages to be used in a batch
115  */
116 uint8_t batch_messages[kNumBatchOpsMax][kMessageLength];
117 
118 /**
119  * Blocks until KMAC is idle.
120  */
121 static void kmac_block_until_idle(void) {
122  // TODO(#7842): Remove when `dif_kmac_get_status()` is implemented.
123  uint32_t reg;
124  do {
125  reg = mmio_region_read32(kmac.base_addr, KMAC_STATUS_REG_OFFSET);
126  } while (!bitfield_bit32_read(reg, KMAC_STATUS_SHA3_IDLE_BIT));
127 }
128 
129 /**
130  * Resets KMAC to idle state.
131  */
132 static void kmac_reset(void) {
133  // TODO(#7842): Remove when `dif_kmac_reset()` is implemented.
134  mmio_region_write32(
135  kmac.base_addr, KMAC_CMD_REG_OFFSET,
136  bitfield_field32_write(0, KMAC_CMD_CMD_FIELD, KMAC_CMD_CMD_VALUE_DONE));
137  kmac_block_until_idle();
138 }
139 
140 /**
141  * Report whether the hardware is currently idle.
142  *
143  * If the hardware is not idle then the `CFG` register is locked.
144  *
145  * @param params Hardware parameters.
146  * @returns Whether the hardware is currently idle or not.
147  */
148 static bool is_state_idle(void) {
149  uint32_t reg = mmio_region_read32(kmac.base_addr, KMAC_STATUS_REG_OFFSET);
150  return bitfield_bit32_read(reg, KMAC_STATUS_SHA3_IDLE_BIT);
151 }
152 
153 /**
154  * Calculate the rate (r) in bits from the given security level.
155  *
156  * @param security_level Security level in bits.
157  * @returns Rate in bits.
158  */
159 static uint32_t calculate_rate_bits(uint32_t security_level) {
160  // Formula for the rate in bits is:
161  //
162  // r = 1600 - c
163  //
164  // Where c is the capacity (the security level in bits multiplied by two).
165  return 1600 - 2 * security_level;
166 }
167 
168 /**
169  * Starts KMAC/SHA3 message without sending START command.
170  *
171  * Based on dif_kmac_mode_sha3_start().
172  *
173  * Unlike dif_kmac_mode_sha3_start(), this function doesn't provide the START
174  * command to the hardware.
175  */
176 static dif_result_t sha3_msg_start(dif_kmac_mode_sha3_t mode) {
177  // Set kstrength and calculate rate (r) and digest length (d) in 32-bit
178  // words.
179  uint32_t kstrength;
180  switch (mode) {
182  kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L224;
183  kmac_operation_state.offset = 0;
184  kmac_operation_state.r = calculate_rate_bits(224) / 32;
185  kmac_operation_state.d = 224 / 32;
186  break;
188  kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256;
189  kmac_operation_state.offset = 0;
190  kmac_operation_state.r = calculate_rate_bits(256) / 32;
191  kmac_operation_state.d = 256 / 32;
192  break;
194  kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L384;
195  kmac_operation_state.offset = 0;
196  kmac_operation_state.r = calculate_rate_bits(384) / 32;
197  kmac_operation_state.d = 384 / 32;
198  break;
200  kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L512;
201  kmac_operation_state.offset = 0;
202  kmac_operation_state.r = calculate_rate_bits(512) / 32;
203  kmac_operation_state.d = 512 / 32;
204  break;
205  default:
206  return kDifBadArg;
207  }
208 
209  // Hardware must be idle to start an operation.
210  if (!is_state_idle()) {
211  return kDifError;
212  }
213 
214  kmac_operation_state.squeezing = false;
215  kmac_operation_state.append_d = false;
216 
217  // Configure SHA-3 mode with the given strength.
218  uint32_t cfg_reg =
219  mmio_region_read32(kmac.base_addr, KMAC_CFG_SHADOWED_REG_OFFSET);
220  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_KSTRENGTH_FIELD,
221  kstrength);
222  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_MODE_FIELD,
223  KMAC_CFG_SHADOWED_MODE_VALUE_SHA3);
224  mmio_region_write32(kmac.base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
225  mmio_region_write32(kmac.base_addr, KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
226 
227  return kDifOk;
228 }
229 
230 /**
231  * Writes the message including its length to the message FIFO.
232  *
233  * Based on dif_kmac_absorb().
234  *
235  * Unlike dif_kmac_absorb(), this function 1) doesn't require the hardware
236  * to enter the 'absorb' state before writing the message into the message
237  * FIFO, and 2) appends the output length afterwards (normally done as
238  * part of dif_kmac_squeeze()).
239  */
240 static dif_result_t sha3_msg_write(const void *msg, size_t msg_len,
241  size_t *processed) {
242  // Set the number of bytes processed to 0.
243  if (processed != NULL) {
244  *processed = 0;
245  }
246 
247  if (msg == NULL && msg_len != 0) {
248  return kDifBadArg;
249  }
250 
251  // Check that an operation has been started.
252  if (kmac_operation_state.r == 0) {
253  return kDifError;
254  }
255 
256  // Copy the message one byte at a time.
257  // This could be sped up copying a word at a time but be careful
258  // about message endianness (e.g. only copy a word at a time when in
259  // little-endian mode).
260  for (size_t i = 0; i < msg_len; ++i) {
261  mmio_region_write8(kmac.base_addr, KMAC_MSG_FIFO_REG_OFFSET,
262  ((const uint8_t *)msg)[i]);
263  }
264 
265  if (processed != NULL) {
266  *processed = msg_len;
267  }
268  kmac_operation_state.squeezing = true;
269 
270  return kDifOk;
271 }
272 
273 /**
274  * Starts actual processing of a previously provided message.
275  *
276  * This function issues a START command directly followed by a PROCESS command.
277  */
278 static void kmac_msg_proc(void) {
279  // Issue START command.
280  uint32_t cmd_reg =
281  bitfield_field32_write(0, KMAC_CMD_CMD_FIELD, KMAC_CMD_CMD_VALUE_START);
282  mmio_region_write32(kmac.base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
283 
284  // Issue PROCESS command.
285  cmd_reg =
286  bitfield_field32_write(0, KMAC_CMD_CMD_FIELD, KMAC_CMD_CMD_VALUE_PROCESS);
287  mmio_region_write32(kmac.base_addr, KMAC_CMD_REG_OFFSET, cmd_reg);
288 }
289 
290 /**
291  * Waits until the hardware enters the 'squeeze' state.
292  *
293  * If the hardware enters the `squeeze` state, this means the output state is
294  * valid and can be read by software.
295  */
296 static void kmac_msg_done(void) {
297  // TODO(#7841, #7842): Remove when we finalize the way we capture traces.
298  uint32_t reg;
299  do {
300  reg = mmio_region_read32(kmac.base_addr, KMAC_STATUS_REG_OFFSET);
301  } while (!bitfield_bit32_read(reg, KMAC_STATUS_SHA3_SQUEEZE_BIT));
302 }
303 
304 /**
305  * Reads the digest from the hardware.
306  *
307  * Based on dif_kmac_squeeze().
308  *
309  * Unlike dif_kmac_squeeze(), this function 1) doesn't wait until the hardware
310  * enters the 'squeeze' state, 2) doesn't append the output length, 3) doesn't
311  * support the generation of more state.
312  */
313 static dif_result_t sha3_get_digest(uint32_t *out, size_t len) {
314  if (out == NULL && len != 0) {
315  return kDifBadArg;
316  }
317 
318  while (len > 0) {
319  size_t n = len;
320  size_t remaining = kmac_operation_state.r - kmac_operation_state.offset;
321  if (kmac_operation_state.d != 0 &&
322  kmac_operation_state.d < kmac_operation_state.r) {
323  remaining = kmac_operation_state.d - kmac_operation_state.offset;
324  }
325  if (n > remaining) {
326  n = remaining;
327  }
328  if (n == 0) {
329  // Normally, the hardware would now have to generate more state. But
330  // since at this point, the power measurement is already stopped, we don't
331  // support that here.
332  return kDifError;
333  }
334 
335  ptrdiff_t offset =
336  KMAC_STATE_REG_OFFSET +
337  (ptrdiff_t)kmac_operation_state.offset * (ptrdiff_t)sizeof(uint32_t);
338  for (size_t i = 0; i < n; ++i) {
339  // Read both shares from state register and combine using XOR.
340  uint32_t share0 = mmio_region_read32(kmac.base_addr, offset);
341  uint32_t share1 =
342  mmio_region_read32(kmac.base_addr, offset + kDifKmacStateShareOffset);
343  *out++ = share0 ^ share1;
344  offset += sizeof(uint32_t);
345  }
346  kmac_operation_state.offset += n;
347  len -= n;
348  }
349  return kDifOk;
350 }
351 
352 /**
353  * Initializes the KMAC peripheral.
354  *
355  * This function configures KMAC to use software entropy.
356  */
357 static void kmac_init(void) {
359  dif_kmac_init(mmio_region_from_addr(TOP_EARLGREY_KMAC_BASE_ADDR), &kmac));
360 
361  SS_CHECK_DIF_OK(dif_kmac_configure(&kmac, config));
362 
363  kmac_block_until_idle();
364 }
365 
366 /**
367  * Disables/Enables masking in the KMAC/SHA3 peripheral.
368  *
369  * This function configures KMAC/SHA3 with the appropriate mask setting.
370  */
371 static void kmac_disable_masking(const uint8_t *masks_off, size_t off_len) {
372  SS_CHECK(off_len == 1);
374  dif_kmac_init(mmio_region_from_addr(TOP_EARLGREY_KMAC_BASE_ADDR), &kmac));
375 
376  if (masks_off[0]) {
378  config.msg_mask = kDifToggleDisabled;
379  LOG_INFO("Initializing the KMAC peripheral with masking disabled.");
380  } else {
382  config.msg_mask = kDifToggleEnabled;
383  LOG_INFO("Initializing the KMAC peripheral with masking enabled.");
384  }
385  SS_CHECK_DIF_OK(dif_kmac_configure(&kmac, config));
386 
387  kmac_block_until_idle();
388  // Acknowledge the command. This is crucial to be in sync with the host.
390 }
391 
392 /**
393  * Absorbs a message without a customization string.
394  *
395  * @param msg Message.
396  * @param msg_len Message length.
397  */
398 static void sha3_serial_absorb(const uint8_t *msg, size_t msg_len) {
399  // Start a new message and write data to message FIFO.
400  SS_CHECK_DIF_OK(sha3_msg_start(kDifKmacModeSha3Len256));
401  SS_CHECK_DIF_OK(sha3_msg_write(msg, msg_len, NULL));
402 
403  // Start the SHA3 processing (this triggers the capture) and go to sleep.
404  // Using the SecCmdDelay hardware parameter, the KMAC unit is
405  // configured to start operation 40 cycles after receiving the START and PROC
406  // commands. This allows Ibex to go to sleep in order to not disturb the
407  // capture.
408  pentest_call_and_sleep(kmac_msg_proc, kIbexSha3SleepCycles, true, false);
409 }
410 
411 /**
412  * Simple serial 'p' (absorb) command handler.
413  *
414  * Absorbs the given message without a customization string,
415  * and sends the digest over UART.
416  *
417  * @param msg Message.
418  * @param msg_len Message length.
419  */
420 static void sha3_serial_single_absorb(const uint8_t *msg, size_t msg_len) {
421  SS_CHECK(msg_len == kMessageLength);
422 
423  // Start the operation.
424  sha3_serial_absorb(msg, msg_len);
425 
426  // Check KMAC has finsihed processing the message.
427  kmac_msg_done();
428 
429  // Read the digest and send it to the host for verification.
430  uint32_t out[kDigestLength];
431  SS_CHECK_DIF_OK(sha3_get_digest(out, kDigestLength));
432  simple_serial_send_packet('r', (uint8_t *)out, kDigestLength * 4);
433 
434  // Reset before the next absorb since KMAC must be idle before starting
435  // another absorb.
436  kmac_reset();
437 }
438 
439 static void sha3_serial_fixed_message_set(const uint8_t *message,
440  size_t message_len) {
441  SS_CHECK(message_len == kMessageLength);
442  memcpy(message_fixed, message, message_len);
443 }
444 
445 static void sha3_serial_batch(const uint8_t *data, size_t data_len) {
446  uint32_t num_hashes = 0;
447  uint32_t out[kDigestLength];
448  uint32_t batch_digest[kDigestLength];
449  uint8_t dummy_message[kMessageLength];
450  SS_CHECK(data_len == sizeof(num_hashes));
451  num_hashes = read_32(data);
452 
453  for (uint32_t j = 0; j < kDigestLength; ++j) {
454  batch_digest[j] = 0;
455  }
456 
457  for (uint32_t i = 0; i < num_hashes; ++i) {
458  if (run_fixed) {
459  memcpy(batch_messages[i], message_fixed, kMessageLength);
460  } else {
461  prng_rand_bytes(batch_messages[i], kMessageLength);
462  }
463  prng_rand_bytes(dummy_message, kMessageLength);
464  run_fixed = dummy_message[0] & 0x1;
465  }
466 
467  for (uint32_t i = 0; i < num_hashes; ++i) {
468  kmac_reset();
469 
470  sha3_serial_absorb(batch_messages[i], kMessageLength);
471 
472  kmac_msg_done();
473  SS_CHECK_DIF_OK(sha3_get_digest(out, kDigestLength));
474 
475  // The correctness of each batch is verified by computing and sending
476  // the batch digest. This digest is computed by XORing all outputs of
477  // the batch.
478  for (uint32_t j = 0; j < kDigestLength; ++j) {
479  batch_digest[j] ^= out[j];
480  }
481  }
482 
483  // Acknowledge the batch command. This is crucial to be in sync with the host
485  // Send the batch digest to the host for verification.
486  simple_serial_send_packet('r', (uint8_t *)batch_digest, kDigestLength * 4);
487 }
488 
489 /**
490  * Simple serial 'l' (seed lfsr) command handler.
491  *
492  * This function only supports 4-byte seeds.
493  *
494  * @param seed A buffer holding the seed.
495  */
496 static void sha3_serial_seed_lfsr(const uint8_t *seed, size_t seed_len) {
497  SS_CHECK(seed_len == sizeof(uint32_t));
498  pentest_seed_lfsr(read_32(seed), kPentestLfsrMasking);
499 }
500 
501 /**
502  * Main function.
503  *
504  * Initializes peripherals and processes simple serial packets received over
505  * UART.
506  */
507 bool test_main(void) {
508  pentest_init(kPentestTriggerSourceKmac,
509  kPentestPeripheralIoDiv4 | kPentestPeripheralKmac);
510 
511  LOG_INFO("Running sha3_serial");
512 
513  LOG_INFO("Initializing simple serial interface to capture board.");
514  simple_serial_init(pentest_get_uart());
515  simple_serial_register_handler('p', sha3_serial_single_absorb);
516  simple_serial_register_handler('b', sha3_serial_batch);
517  simple_serial_register_handler('f', sha3_serial_fixed_message_set);
518  simple_serial_register_handler('l', sha3_serial_seed_lfsr);
519  simple_serial_register_handler('m', kmac_disable_masking);
520 
521  LOG_INFO("Initializing the KMAC peripheral with masks enabled.");
522  kmac_init();
523 
524  LOG_INFO("Starting simple serial packet handling.");
525  while (true) {
527  }
528 }