@@ -89,6 +89,10 @@ typedef struct kmac_config {
8989 * The algorithm: SHA3, SHAKE or cSHAKE
9090 */
9191 uint8_t mode ;
92+ /**
93+ * Hashing strength: L128, L224, L256, L384 or L512
94+ */
95+ uint8_t kstrength ;
9296} kmac_config_t ;
9397
9498/**
@@ -173,9 +177,9 @@ static rom_error_t kmac_configure(kmac_config_t config) {
173177 // poll `STATUS.fifo_depth` to avoid a specific EDN-KMAC-Ibex deadlock
174178 // scenario. See `absorb()` and the KMAC documentation for details.
175179 cfg_reg = bitfield_bit32_write (cfg_reg , KMAC_CFG_SHADOWED_KMAC_EN_BIT , 0 );
176- // Set `CFG.KSTRENGTH` field to 256-bit strength .
180+ // Set `CFG.KSTRENGTH` field.
177181 cfg_reg = bitfield_field32_write (cfg_reg , KMAC_CFG_SHADOWED_KSTRENGTH_FIELD ,
178- KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256 );
182+ config . kstrength );
179183 // Set `CFG.MODE` field to SHAKE.
180184 cfg_reg = bitfield_field32_write (cfg_reg , KMAC_CFG_SHADOWED_MODE_FIELD ,
181185 config .mode );
@@ -246,6 +250,7 @@ rom_error_t kmac_keymgr_configure(void) {
246250 .sideload = true,
247251 .kmac_en = false,
248252 .mode = KMAC_CFG_SHADOWED_MODE_VALUE_SHAKE ,
253+ .kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256 ,
249254 });
250255}
251256
@@ -257,6 +262,7 @@ rom_error_t kmac_kmac256_sw_configure(void) {
257262 .sideload = false,
258263 .kmac_en = true,
259264 .mode = KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE ,
265+ .kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256 ,
260266 });
261267}
262268
@@ -268,6 +274,18 @@ rom_error_t kmac_kmac256_hw_configure(void) {
268274 .sideload = true,
269275 .kmac_en = true,
270276 .mode = KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE ,
277+ .kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256 ,
278+ });
279+ }
280+
281+ rom_error_t kmac_shake128_configure (void ) {
282+ return kmac_configure ((kmac_config_t ){
283+ .entropy_fast_process = false,
284+ .msg_mask = false,
285+ .sideload = false,
286+ .kmac_en = false,
287+ .mode = KMAC_CFG_SHADOWED_MODE_VALUE_SHAKE ,
288+ .kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L128 ,
271289 });
272290}
273291
@@ -278,6 +296,7 @@ rom_error_t kmac_shake256_configure(void) {
278296 .sideload = false,
279297 .kmac_en = false,
280298 .mode = KMAC_CFG_SHADOWED_MODE_VALUE_SHAKE ,
299+ .kstrength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256 ,
281300 });
282301}
283302
@@ -350,20 +369,26 @@ void kmac_shake256_squeeze_start(void) {
350369}
351370
352371rom_error_t kmac_shake256_squeeze_end (uint32_t * out , size_t outlen ) {
372+ HARDENED_RETURN_IF_ERROR (
373+ kmac_squeeze_words (out , outlen , kShake256KeccakRateWords ));
374+ return kmac_done ();
375+ }
376+
377+ rom_error_t kmac_squeeze_words (uint32_t * out , size_t out_words ,
378+ size_t rate_words ) {
353379 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 );
380+ while (launder32 (idx ) < out_words ) {
381+ // Since we always read in increments of the rate, the index at the start
382+ // of each squeeze cycle must be a multiple of the rate.
383+ HARDENED_CHECK_EQ (idx % rate_words , 0 );
358384
359385 // Poll the status register until in the 'squeeze' state.
360386 HARDENED_RETURN_IF_ERROR (poll_state (KMAC_STATUS_SHA3_SQUEEZE_BIT ));
361387
362388 // Read words from the state registers (either `outlen` or the maximum
363389 // number of words available).
364390 size_t offset = 0 ;
365- for (; launder32 (idx ) < outlen && offset < kShake256KeccakRateWords ;
366- ++ offset ) {
391+ for (; launder32 (idx ) < out_words && offset < rate_words ; ++ offset ) {
367392 uint32_t share0 =
368393 abs_mmio_read32 (kAddrStateShare0 + offset * sizeof (uint32_t ));
369394 uint32_t share1 =
@@ -372,15 +397,18 @@ rom_error_t kmac_shake256_squeeze_end(uint32_t *out, size_t outlen) {
372397 ++ idx ;
373398 }
374399
375- if (launder32 (offset ) == kShake256KeccakRateWords ) {
400+ if (launder32 (offset ) == rate_words ) {
376401 // If we read all the remaining words, issue `CMD.RUN` to generate more
377402 // state.
378- HARDENED_CHECK_EQ (offset , kShake256KeccakRateWords );
403+ HARDENED_CHECK_EQ (offset , rate_words );
379404 issue_command (KMAC_CMD_CMD_VALUE_RUN );
380405 }
381406 }
382- HARDENED_CHECK_EQ (idx , outlen );
407+ HARDENED_CHECK_EQ (idx , out_words );
408+ return kErrorOk ;
409+ }
383410
411+ rom_error_t kmac_done (void ) {
384412 // Poll the status register until in the 'squeeze' state.
385413 HARDENED_RETURN_IF_ERROR (poll_state (KMAC_STATUS_SHA3_SQUEEZE_BIT ));
386414
@@ -390,6 +418,13 @@ rom_error_t kmac_shake256_squeeze_end(uint32_t *out, size_t outlen) {
390418 return kErrorOk ;
391419}
392420
421+ bool kmac_is_squeezing (void ) {
422+ uint32_t status = abs_mmio_read32 (kBase + KMAC_STATUS_REG_OFFSET );
423+ bool sha3_idle = bitfield_bit32_read (status , KMAC_STATUS_SHA3_IDLE_BIT );
424+ bool sha3_absorb = bitfield_bit32_read (status , KMAC_STATUS_SHA3_ABSORB_BIT );
425+ return !sha3_idle && !sha3_absorb ;
426+ }
427+
393428#define WORD_BITS (sizeof(uint32_t) * 8)
394429#define KEY_CASE (x_ ) \
395430 case x_ / WORD_BITS: \
0 commit comments