Software APIs
kmac.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include "sw/device/silicon_creator/lib/drivers/kmac.h"
6 
10 #include "sw/device/silicon_creator/lib/error.h"
11 
13 #include "kmac_regs.h" // Generated.
14 
15 enum {
16  /**
17  * Base address of the KMAC hardware MMIO interface.
18  */
20  /**
21  * Keccak capacity for SHAKE256.
22  *
23  * See FIPS 202, section 6.2.
24  */
25  kShake256KeccakCapacity = 2 * 256,
26  /**
27  * Keccak rate for SHAKE256 (bits).
28  *
29  * Rate is 1600 - capacity (FIPS 202, section 6.2).
30  */
31  kShake256KeccakRateBits = 1600 - kShake256KeccakCapacity,
32  /**
33  * Keccak rate for SHAKE256 (bytes).
34  */
35  kShake256KeccakRateBytes = kShake256KeccakRateBits / 8,
36  /**
37  * Keccak rate for SHAKE256 (words).
38  */
39  kShake256KeccakRateWords = kShake256KeccakRateBytes / sizeof(uint32_t),
40  /**
41  * Size of one share of the Keccak state.
42  */
43  kStateShareSize = KMAC_STATE_SIZE_BYTES / 2,
44  /**
45  * Address of first share of Keccak state.
46  */
47  kAddrStateShare0 = kBase + KMAC_STATE_REG_OFFSET,
48  /**
49  * Address of second share of Keccak state.
50  */
51  kAddrStateShare1 = kBase + KMAC_STATE_REG_OFFSET + kStateShareSize,
52 };
53 
54 // Double-check that calculated rate is smaller than one share of the state.
55 static_assert(kShake256KeccakRateWords <= kStateShareSize,
56  "assert SHAKE256 rate is <= share size");
57 
58 static const uint32_t kEntropySeed[] = {0x5d2a3764, 0x37d3ecba, 0xe1859094,
59  0xb153e3fe, 0x09596819, 0x3e85a6e8,
60  0xb6dcdaba, 0x50dc409c, 0x11e1ebd1};
61 
62 /**
63  * KMAC configuration parameters.
64  */
65 typedef struct kmac_config {
66  /**
67  * Entropy fast process mode when enabled prevents the KMAC unit consuming
68  * entropy unless it is processing a secret key. This process should not be
69  * used when resistance against side-channel attacks is required, because
70  * it may lead to leakage of the secret key in the power trace.
71  */
73  /**
74  * Message Masking with PRNG.
75  * If true, KMAC applies PRNG to the input messages to the Keccak module when
76  * KMAC mode is on.
77  */
78  bool msg_mask;
79  /**
80  * Enable KMAC sideload mode.
81  */
82  bool sideload;
83  /**
84  * Whether or not to use enable KMAC mode.
85  */
86  bool kmac_en;
87 
88  /**
89  * The algorithm: SHA3, SHAKE or cSHAKE
90  */
91  uint8_t mode;
93 
94 /**
95  * Polls the KMAC block state until the desired status bit is set.
96  *
97  * If the KMAC block registers an error, this routine exits early and returns
98  * `kErrorKmacInvalidStatus`.
99  *
100  * @param bit_index Bit within the status register to poll.
101  * @return Result of the operation.
102  */
104 static rom_error_t poll_state(bitfield_bit32_index_t bit_index) {
105  // The success condition of this function is:
106  // - The specified bit in the status register is 1, and
107  // - The error bit in KMAC's INTR_STATE register is 0.
108  //
109  // In order to make fault injection more difficult, we compute these values
110  // in a slightly convoluted way so that skipping any few instructions will
111  // not reach the success condition.
112  uint32_t status = 0;
113  rom_error_t res = launder32(kErrorOk ^ UINT32_MAX);
114  uint32_t is_error = (uint32_t)kHardenedBoolFalse;
115  do {
116  // Read the error bit.
117  uint32_t intr_state = abs_mmio_read32(kBase + KMAC_INTR_STATE_REG_OFFSET);
118  uint32_t err_bit = launder32((uint32_t)bitfield_bit32_read(
119  intr_state, KMAC_INTR_STATE_KMAC_ERR_BIT));
120  // If there is no error, (~err_bit) + 1 will be zero and `is_error` will
121  // remain `kHardenedBoolFalse`. Otherwise, ~err_bit + 1 will be
122  // UINT32_MAX and all bits will flip to produce a garbage value.
123  is_error ^= (~err_bit) + 1;
124 
125  // Read the status register.
126  status = abs_mmio_read32(kBase + KMAC_STATUS_REG_OFFSET);
127  uint32_t flag = launder32((uint32_t)bitfield_bit32_read(status, bit_index));
128  // If `flag` is 0, then `res` will be unchanged (and remain `kErrorOk ^
129  // UINT32_MAX`). If it is 1, then all bits except the LSB will flip,
130  // meaning `res = kErrorOk ^ 1`.
131  res ^= ((~flag) + 1) << 1;
132  } while (!bitfield_bit32_read(launder32(status), bit_index) &&
133  launder32(is_error) == kHardenedBoolFalse);
134 
135  // If the bit is set, this xor will set `res = kErrorOk`.
136  res ^= bitfield_bit32_read(status, bit_index);
137 
138  if (launder32(is_error) == kHardenedBoolFalse) {
140  // The only way to get here is if the desired flag is set, meaning `res =
141  // kErrorOk`.
142  return res;
143  }
144 
145  return kErrorKmacInvalidStatus;
146 }
147 
148 /**
149  * Configure kmac block using `config` parameters.
150  *
151  * @param config The kmac configuration parameters.
152  *
153  * @return Error code indicating if the operation succeeded.
154  */
155 static rom_error_t kmac_configure(kmac_config_t config) {
156  HARDENED_RETURN_IF_ERROR(poll_state(KMAC_STATUS_SHA3_IDLE_BIT));
157 
158  uint32_t entropy_period_reg = KMAC_ENTROPY_PERIOD_REG_RESVAL;
159  // Set the wait timer to the maximum count.
160  entropy_period_reg = bitfield_field32_write(
161  entropy_period_reg, KMAC_ENTROPY_PERIOD_WAIT_TIMER_FIELD,
162  KMAC_ENTROPY_PERIOD_WAIT_TIMER_MASK);
163  // Set the prescaler to the maximum number of cycles.
164  entropy_period_reg = bitfield_field32_write(
165  entropy_period_reg, KMAC_ENTROPY_PERIOD_PRESCALER_FIELD,
166  KMAC_ENTROPY_PERIOD_PRESCALER_MASK);
167  abs_mmio_write32(kBase + KMAC_ENTROPY_PERIOD_REG_OFFSET, entropy_period_reg);
168 
169  uint32_t cfg_reg = KMAC_CFG_SHADOWED_REG_RESVAL;
170  // Set `CFG.KMAC_EN` bit to 0.
171  // NOTE: If this driver is ever modified to perform an operation with
172  // KMAC_EN=true and use entropy from EDN, then the absorb() function must
173  // poll `STATUS.fifo_depth` to avoid a specific EDN-KMAC-Ibex deadlock
174  // scenario. See `absorb()` and the KMAC documentation for details.
175  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_KMAC_EN_BIT, 0);
176  // Set `CFG.KSTRENGTH` field to 256-bit strength.
177  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_KSTRENGTH_FIELD,
178  KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256);
179  // Set `CFG.MODE` field to SHAKE.
180  cfg_reg = bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_MODE_FIELD,
181  config.mode);
182  // Set `CFG.MSG_ENDIANNESS` bit to 0 (little-endian).
183  cfg_reg =
184  bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_MSG_ENDIANNESS_BIT, 0);
185  // Set `CFG.STATE_ENDIANNESS` bit to 0 (little-endian).
186  cfg_reg =
187  bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_STATE_ENDIANNESS_BIT, 0);
188 
189  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_SIDELOAD_BIT,
190  config.sideload);
191 
192  // Set `CFG.ENTROPY_MODE` field to use software entropy. SHAKE does not
193  // require any entropy, so there is no reason we should wait for entropy
194  // availability before we start hashing.
195  cfg_reg =
196  bitfield_field32_write(cfg_reg, KMAC_CFG_SHADOWED_ENTROPY_MODE_FIELD,
197  KMAC_CFG_SHADOWED_ENTROPY_MODE_VALUE_SW_MODE);
198 
199  cfg_reg =
200  bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_ENTROPY_FAST_PROCESS_BIT,
201  config.entropy_fast_process);
202 
203  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_MSG_MASK_BIT,
204  config.msg_mask);
205  cfg_reg = bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_KMAC_EN_BIT,
206  config.kmac_en);
207 
208  // Set `CFG.ENTROPY_READY` bit to 1.
209  cfg_reg =
210  bitfield_bit32_write(cfg_reg, KMAC_CFG_SHADOWED_ENTROPY_READY_BIT, 1);
211  // Set `CFG.EN_UNSUPPORTED_MODESTRENGTH` bit to 0.
212  cfg_reg = bitfield_bit32_write(
213  cfg_reg, KMAC_CFG_SHADOWED_EN_UNSUPPORTED_MODESTRENGTH_BIT, 0);
214  abs_mmio_write32_shadowed(kBase + KMAC_CFG_SHADOWED_REG_OFFSET, cfg_reg);
215 
216  // Write entropy seed register. Even though the values are
217  // irrelevant, these registers must be written for the KMAC block to consider
218  // its entropy "ready" and to begin operation.
219  abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[0]);
220  abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[1]);
221  abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[2]);
222  abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[3]);
223  abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[4]);
224  abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[5]);
225  abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[6]);
226  abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[7]);
227  abs_mmio_write32(kBase + KMAC_ENTROPY_SEED_REG_OFFSET, kEntropySeed[8]);
228 
229  return kErrorOk;
230 }
231 
232 /**
233  * Issue a command to the KMAC block.
234  *
235  * @param cmd_value Value to write to the CMD register.
236  */
237 static void issue_command(uint32_t cmd_value) {
238  uint32_t cmd_reg = bitfield_field32_write(0, KMAC_CMD_CMD_FIELD, cmd_value);
239  abs_mmio_write32(kBase + KMAC_CMD_REG_OFFSET, cmd_reg);
240 }
241 
242 rom_error_t kmac_keymgr_configure(void) {
243  return kmac_configure((kmac_config_t){
244  .entropy_fast_process = false,
245  .msg_mask = true,
246  .sideload = true,
247  .kmac_en = false,
248  .mode = KMAC_CFG_SHADOWED_MODE_VALUE_SHAKE,
249  });
250 }
251 
252 rom_error_t kmac_kmac256_sw_configure(void) {
253  kmac_kmac256_set_prefix(NULL, 0);
254  return kmac_configure((kmac_config_t){
255  .entropy_fast_process = false,
256  .msg_mask = false,
257  .sideload = false,
258  .kmac_en = true,
259  .mode = KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE,
260  });
261 }
262 
263 rom_error_t kmac_kmac256_hw_configure(void) {
264  kmac_kmac256_set_prefix(NULL, 0);
265  return kmac_configure((kmac_config_t){
266  .entropy_fast_process = false,
267  .msg_mask = false,
268  .sideload = true,
269  .kmac_en = true,
270  .mode = KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE,
271  });
272 }
273 
274 rom_error_t kmac_shake256_configure(void) {
275  return kmac_configure((kmac_config_t){
276  .entropy_fast_process = false,
277  .msg_mask = false,
278  .sideload = false,
279  .kmac_en = false,
280  .mode = KMAC_CFG_SHADOWED_MODE_VALUE_SHAKE,
281  });
282 }
283 
284 rom_error_t kmac_shake256_start(void) {
285  // Block until KMAC hardware is idle.
286  HARDENED_RETURN_IF_ERROR(poll_state(KMAC_STATUS_SHA3_IDLE_BIT));
287 
288  // Issue `CMD.START` to start the operation.
289  issue_command(KMAC_CMD_CMD_VALUE_START);
290 
291  // Block until KMAC hardware is in the `absorb` state. After `CMD.START`,
292  // KMAC should never move out of the `absorb` state until `CMD.PROCESS` is
293  // issued, so we get significant performance gains by polling only once here
294  // instead of before every `absorb`.
295  HARDENED_RETURN_IF_ERROR(poll_state(KMAC_STATUS_SHA3_ABSORB_BIT));
296 
297  return kErrorOk;
298 }
299 
300 void kmac_shake256_absorb(const uint8_t *in, size_t inlen) {
301  // This implementation does not poll `STATUS.fifo_depth` as recommended in
302  // the KMAC documentation. Normally, polling is required to prevent a
303  // deadlock scenario between Ibex, KMAC, and EDN. However, in this case it is
304  // safe to skip because `kmac_shake256_configure()` sets KMAC to use
305  // software-only entropy, and sets `kmac_en` to false (so KMAC will not
306  // produce entropy requests anyway). Since KMAC will therefore not block on
307  // EDN, it is guaranteed to keep processing message blocks. For more details,
308  // see the KMAC documentation:
309  // https://docs.opentitan.org/hw/ip/kmac/doc/#fifo-depth-and-empty-status
310 
311  // Use byte-wide writes until the input pointer is aligned.
312  // Note: writes to the KMAC message FIFO are not required to be aligned.
313  for (; inlen > 0 && misalignment32_of((uintptr_t)in); --inlen, ++in) {
314  abs_mmio_write8(kBase + KMAC_MSG_FIFO_REG_OFFSET, *in);
315  }
316 
317  // Use word writes for all full words.
318  for (; inlen >= sizeof(uint32_t);
319  inlen -= sizeof(uint32_t), in += sizeof(uint32_t)) {
320  abs_mmio_write32(kBase + KMAC_MSG_FIFO_REG_OFFSET, read_32(in));
321  }
322 
323  // Use byte-wide writes for anything left over.
324  for (; inlen > 0; --inlen, ++in) {
325  abs_mmio_write8(kBase + KMAC_MSG_FIFO_REG_OFFSET, *in);
326  }
327  HARDENED_CHECK_EQ(inlen, 0);
328 }
329 
330 void kmac_shake256_absorb_words(const uint32_t *in, size_t inlen) {
331  // This implementation does not poll `STATUS.fifo_depth` as recommended in
332  // the KMAC documentation. Normally, polling is required to prevent a
333  // deadlock scenario between Ibex, KMAC, and EDN. However, in this case it is
334  // safe to skip because `kmac_shake256_configure()` sets KMAC to use
335  // software-only entropy, and sets `kmac_en` to false (so KMAC will not
336  // produce entropy requests anyway). Since KMAC will therefore not block on
337  // EDN, it is guaranteed to keep processing message blocks. For more details,
338  // see the KMAC documentation:
339  // https://docs.opentitan.org/hw/ip/kmac/doc/#fifo-depth-and-empty-status
340 
341  for (; inlen > 0; --inlen, ++in) {
342  abs_mmio_write32(kBase + KMAC_MSG_FIFO_REG_OFFSET, *in);
343  }
344  HARDENED_CHECK_EQ(inlen, 0);
345 }
346 
347 void kmac_shake256_squeeze_start(void) {
348  // Issue `CMD.PROCESS` to move to the squeezing state.
349  issue_command(KMAC_CMD_CMD_VALUE_PROCESS);
350 }
351 
352 rom_error_t kmac_shake256_squeeze_end(uint32_t *out, size_t outlen) {
353  size_t idx = 0;
354  while (launder32(idx) < outlen) {
355  // Since we always read in increments of the SHAKE-256 rate, the index at
356  // start should always be a multiple of the rate.
357  HARDENED_CHECK_EQ(idx % kShake256KeccakRateWords, 0);
358 
359  // Poll the status register until in the 'squeeze' state.
360  HARDENED_RETURN_IF_ERROR(poll_state(KMAC_STATUS_SHA3_SQUEEZE_BIT));
361 
362  // Read words from the state registers (either `outlen` or the maximum
363  // number of words available).
364  size_t offset = 0;
365  for (; launder32(idx) < outlen && offset < kShake256KeccakRateWords;
366  ++offset) {
367  uint32_t share0 =
368  abs_mmio_read32(kAddrStateShare0 + offset * sizeof(uint32_t));
369  uint32_t share1 =
370  abs_mmio_read32(kAddrStateShare1 + offset * sizeof(uint32_t));
371  out[idx] = share0 ^ share1;
372  ++idx;
373  }
374 
375  if (offset == kShake256KeccakRateWords) {
376  // If we read all the remaining words, issue `CMD.RUN` to generate more
377  // state.
378  HARDENED_CHECK_EQ(offset, kShake256KeccakRateWords);
379  issue_command(KMAC_CMD_CMD_VALUE_RUN);
380  }
381  }
382  HARDENED_CHECK_EQ(idx, outlen);
383 
384  // Poll the status register until in the 'squeeze' state.
385  HARDENED_RETURN_IF_ERROR(poll_state(KMAC_STATUS_SHA3_SQUEEZE_BIT));
386 
387  // Issue `CMD.DONE` to finish the operation.
388  issue_command(KMAC_CMD_CMD_VALUE_DONE);
389 
390  return kErrorOk;
391 }
392 
393 #define WORD_BITS (sizeof(uint32_t) * 8)
394 #define KEY_CASE(x_) \
395  case x_ / WORD_BITS: \
396  klen = KMAC_KEY_LEN_LEN_VALUE_KEY##x_; \
397  break
398 rom_error_t kmac_kmac256_sw_key(const uint32_t *key, size_t len) {
399  uint32_t klen;
400  switch (len) {
401  KEY_CASE(128);
402  KEY_CASE(192);
403  KEY_CASE(256);
404  KEY_CASE(384);
405  KEY_CASE(512);
406  default:
407  return kErrorKmacInvalidKeySize;
408  }
409  abs_mmio_write32(kBase + KMAC_KEY_LEN_REG_OFFSET, klen);
410  for (size_t i = 0; i < KMAC_KEY_SHARE0_MULTIREG_COUNT; ++i) {
411  uint32_t value = i < len ? key[i] : 0;
412  abs_mmio_write32(
413  kBase + KMAC_KEY_SHARE0_0_REG_OFFSET + i * sizeof(uint32_t), value);
414  abs_mmio_write32(
415  kBase + KMAC_KEY_SHARE1_0_REG_OFFSET + i * sizeof(uint32_t), 0);
416  }
417  return kErrorOk;
418 }
419 
420 void kmac_kmac256_set_prefix(const void *prefix, size_t len) {
421  // The length must be less than 32 because this function encodes the prefix
422  // length as a single byte, and 32*8 == 256, which won't fit in a byte.
423  HARDENED_CHECK_LT(len, 32);
424  uint32_t regs[KMAC_PREFIX_MULTIREG_COUNT] = {
425  0x4D4B2001, // 1 32 'K' 'M'
426  0x00014341, // 'A' 'C' 1 0
427  };
428  char *r = (char *)&regs[2];
429 
430  // The prefix length is the byte immediately before where we'll store the
431  // message (the last `0` byte in the `regs` above). Set the length and
432  // then copy the prefix into the `regs` buffer.
433  r[-1] = (char)(len * 8);
434  memcpy(r, prefix, len);
435 
436  for (size_t i = 0; i < KMAC_PREFIX_MULTIREG_COUNT; ++i) {
437  abs_mmio_write32(kBase + KMAC_PREFIX_0_REG_OFFSET + i * sizeof(uint32_t),
438  regs[i]);
439  }
440 }
441 
442 rom_error_t kmac_kmac256_final(uint32_t *result, size_t rlen) {
443  // To finalize a kmac operation, we need to right-pad the bit-length of the
444  // result buffer and absorb that padded length value into the sponge.
445  uint8_t buffer[sizeof(size_t) + 1];
446  size_t val = rlen * 32;
447  size_t n = 0;
448  size_t p = sizeof(buffer) - 1;
449  while (val) {
450  buffer[--p] = val & 0xFF;
451  val >>= 8;
452  n++;
453  }
454  buffer[sizeof(buffer) - 1] = (uint8_t)n;
455  kmac_shake256_absorb(buffer + p, n + 1);
456 
457  // Now, squeeze out the result.
458  kmac_shake256_squeeze_start();
459  return kmac_shake256_squeeze_end(result, rlen);
460 }
461 
462 // Provide link locations for the inline functions in the header file.
463 extern rom_error_t kmac_kmac256_start(void);
464 extern void kmac_kmac256_absorb(const void *data, size_t len);