@@ -34,6 +34,13 @@ enum {
3434 * CSRNG genbits buffer size in uint32_t words.
3535 */
3636 kEntropyCsrngBitsBufferNumWords = 4 ,
37+
38+ // Fast timeout for checking if hardware is ready to accept a command word
39+ kEntropyPollReadyTimeout = 100 ,
40+ // Longer timeout for waiting for a command to finish executing
41+ kEntropyPollCmdDoneTimeout = 1000000 ,
42+ // Timeout for waiting for GenBits to become valid
43+ kEntropyPollGenBitsTimeout = 131071 ,
3744};
3845
3946/**
@@ -362,10 +369,15 @@ static status_t csrng_send_app_cmd(uint32_t base_address,
362369 if ((cmd_type == kEntropyCsrngSendAppCmdTypeCsrng ) ||
363370 (cmd_type == kEntropyCsrngSendAppCmdTypeEdnSw )) {
364371 // Wait for the status register to be ready to accept the next command.
372+ uint32_t timeout = kEntropyPollReadyTimeout ;
365373 do {
366374 reg = abs_mmio_read32 (sts_reg_addr );
367375 ready = bitfield_bit32_read (reg , rdy_bit_offset );
368- } while (!ready );
376+ } while (!ready && -- timeout );
377+
378+ if (timeout == 0 ) {
379+ return OTCRYPTO_RECOV_ERR ;
380+ }
369381 }
370382
371383#define ENTROPY_CMD (m , i ) ((bitfield_field32_t){.mask = m, .index = i})
@@ -420,10 +432,15 @@ static status_t csrng_send_app_cmd(uint32_t base_address,
420432 // SW register of EDN, respectively.
421433 if (cmd_type == kEntropyCsrngSendAppCmdTypeCsrng ||
422434 cmd_type == kEntropyCsrngSendAppCmdTypeEdnSw ) {
435+ uint32_t timeout = kEntropyPollReadyTimeout ;
423436 do {
424437 reg = abs_mmio_read32 (sts_reg_addr );
425438 ready = bitfield_bit32_read (reg , reg_rdy_bit_offset );
426- } while (!ready );
439+ } while (!ready && -- timeout );
440+
441+ if (timeout == 0 ) {
442+ return OTCRYPTO_RECOV_ERR ;
443+ }
427444 }
428445 abs_mmio_write32 (cmd_reg_addr , cmd .seed_material -> data [i ]);
429446 }
@@ -433,17 +450,32 @@ static status_t csrng_send_app_cmd(uint32_t base_address,
433450 // The Generate command is complete only after all entropy bits have been
434451 // consumed. Thus poll the register that indicates if entropy bits are
435452 // available.
453+ uint32_t timeout = kEntropyPollGenBitsTimeout ;
436454 do {
437455 reg = abs_mmio_read32 (kBaseCsrng + CSRNG_GENBITS_VLD_REG_OFFSET );
438- } while (!bitfield_bit32_read (reg , CSRNG_GENBITS_VLD_GENBITS_VLD_BIT ));
456+ } while (!bitfield_bit32_read (reg , CSRNG_GENBITS_VLD_GENBITS_VLD_BIT ) &&
457+ -- timeout );
458+
459+ if (timeout == 0 ) {
460+ return OTCRYPTO_RECOV_ERR ;
461+ }
439462
440463 } else {
441464 // The non-Generate commands complete earlier, so poll the "command
442465 // request done" interrupt bit. Once it is set, the "status" bit is
443466 // updated.
467+ uint32_t timeout = (cmd .id == kEntropyDrbgOpInstantiate )
468+ ? kEntropyPollCmdDoneTimeout
469+ : kEntropyPollReadyTimeout ;
444470 do {
445471 reg = abs_mmio_read32 (kBaseCsrng + CSRNG_INTR_STATE_REG_OFFSET );
446- } while (!bitfield_bit32_read (reg , CSRNG_INTR_STATE_CS_CMD_REQ_DONE_BIT ));
472+ } while (
473+ !bitfield_bit32_read (reg , CSRNG_INTR_STATE_CS_CMD_REQ_DONE_BIT ) &&
474+ -- timeout );
475+
476+ if (timeout == 0 ) {
477+ return OTCRYPTO_RECOV_ERR ;
478+ }
447479
448480 // Check the "status" bit, which will be 0 unless there was an error.
449481 reg = abs_mmio_read32 (kBaseCsrng + CSRNG_SW_CMD_STS_REG_OFFSET );
@@ -458,9 +490,15 @@ static status_t csrng_send_app_cmd(uint32_t base_address,
458490 // entropy is consumed. Thus the acknowledgement bit shall only be polled
459491 // for non-generate commands.
460492 if (cmd .id != kEntropyDrbgOpGenerate ) {
493+ uint32_t timeout = kEntropyPollCmdDoneTimeout ;
461494 do {
462495 reg = abs_mmio_read32 (sts_reg_addr );
463- } while (!bitfield_bit32_read (reg , EDN_SW_CMD_STS_CMD_ACK_BIT ));
496+ } while (!bitfield_bit32_read (reg , EDN_SW_CMD_STS_CMD_ACK_BIT ) &&
497+ -- timeout );
498+
499+ if (timeout == 0 ) {
500+ return OTCRYPTO_RECOV_ERR ;
501+ }
464502
465503 // Check the "status" bit, which will be 0 unless there was an error.
466504 if (bitfield_field32_read (reg , CSRNG_SW_CMD_STS_CMD_STS_FIELD )) {
@@ -533,9 +571,14 @@ static void edn_stop(uint32_t edn_address) {
533571OT_WARN_UNUSED_RESULT
534572static status_t edn_ready_block (uint32_t edn_address ) {
535573 uint32_t reg ;
574+ uint32_t timeout = kEntropyPollReadyTimeout ;
536575 do {
537576 reg = abs_mmio_read32 (edn_address + EDN_SW_CMD_STS_REG_OFFSET );
538- } while (!bitfield_bit32_read (reg , EDN_SW_CMD_STS_CMD_RDY_BIT ));
577+ } while (!bitfield_bit32_read (reg , EDN_SW_CMD_STS_CMD_RDY_BIT ) && -- timeout );
578+
579+ if (timeout == 0 ) {
580+ return OTCRYPTO_RECOV_ERR ;
581+ }
539582
540583 if (bitfield_field32_read (reg , CSRNG_SW_CMD_STS_CMD_STS_FIELD )) {
541584 return OTCRYPTO_RECOV_ERR ;
@@ -965,9 +1008,16 @@ status_t entropy_csrng_generate_data_get(uint32_t *buf, size_t len,
9651008 // Block until there is more data available in the genbits buffer. CSRNG
9661009 // generates data in 128bit chunks (i.e. 4 words).
9671010 uint32_t reg ;
1011+ uint32_t timeout = kEntropyPollGenBitsTimeout ;
1012+
9681013 do {
9691014 reg = abs_mmio_read32 (kBaseCsrng + CSRNG_GENBITS_VLD_REG_OFFSET );
970- } while (!bitfield_bit32_read (reg , CSRNG_GENBITS_VLD_GENBITS_VLD_BIT ));
1015+ } while (!bitfield_bit32_read (reg , CSRNG_GENBITS_VLD_GENBITS_VLD_BIT ) &&
1016+ -- timeout );
1017+
1018+ if (timeout == 0 ) {
1019+ return OTCRYPTO_RECOV_ERR ;
1020+ }
9711021
9721022 if (fips_check != kHardenedBoolFalse &&
9731023 !bitfield_bit32_read (reg , CSRNG_GENBITS_VLD_GENBITS_FIPS_BIT )) {
0 commit comments