From aa54b60d6f29a21c23d5c705e3f29556df77fb55 Mon Sep 17 00:00:00 2001 From: Pascal Nasahl Date: Thu, 17 Jul 2025 14:58:14 +0200 Subject: [PATCH 1/2] [crypto] Add OTBN DMEM wipes to RSA code Always wipe the DMEM once the OTBN execution has been finished. Signed-off-by: Pascal Nasahl --- sw/device/lib/crypto/impl/rsa/rsa_3072_verify.c | 6 ++++-- sw/device/lib/crypto/impl/rsa/rsa_keygen.c | 4 +--- sw/device/lib/crypto/impl/rsa/rsa_modexp.c | 4 ++++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/sw/device/lib/crypto/impl/rsa/rsa_3072_verify.c b/sw/device/lib/crypto/impl/rsa/rsa_3072_verify.c index 86c5a191bd3bd..43e616f249233 100644 --- a/sw/device/lib/crypto/impl/rsa/rsa_3072_verify.c +++ b/sw/device/lib/crypto/impl/rsa/rsa_3072_verify.c @@ -146,7 +146,8 @@ status_t rsa_3072_compute_constants(const rsa_3072_public_key_t *public_key, HARDENED_TRY( otbn_dmem_read(kOtbnWideWordNumWords, kOtbnVarRsaM0Inv, result->m0_inv)); - return OTCRYPTO_OK; + // Wipe DMEM. + return otbn_dmem_sec_wipe(); } status_t rsa_3072_verify_start(const rsa_3072_int_t *signature, @@ -212,7 +213,8 @@ status_t rsa_3072_verify_finalize(const rsa_3072_int_t *message, } } - return OTCRYPTO_OK; + // Wipe DMEM. + return otbn_dmem_sec_wipe(); } status_t rsa_3072_verify(const rsa_3072_int_t *signature, diff --git a/sw/device/lib/crypto/impl/rsa/rsa_keygen.c b/sw/device/lib/crypto/impl/rsa/rsa_keygen.c index 76d34d31f6c1c..3ea4379334e27 100644 --- a/sw/device/lib/crypto/impl/rsa/rsa_keygen.c +++ b/sw/device/lib/crypto/impl/rsa/rsa_keygen.c @@ -99,9 +99,7 @@ static status_t keygen_finalize(uint32_t exp_mode, size_t num_words, HARDENED_TRY(otbn_dmem_read(num_words, kOtbnVarRsaD, d)); // Wipe DMEM. - HARDENED_TRY(otbn_dmem_sec_wipe()); - - return OTCRYPTO_OK; + return otbn_dmem_sec_wipe(); } status_t rsa_keygen_2048_start(void) { diff --git a/sw/device/lib/crypto/impl/rsa/rsa_modexp.c b/sw/device/lib/crypto/impl/rsa/rsa_modexp.c index dc371505bc497..25f4dce5adacc 100644 --- a/sw/device/lib/crypto/impl/rsa/rsa_modexp.c +++ b/sw/device/lib/crypto/impl/rsa/rsa_modexp.c @@ -72,6 +72,8 @@ status_t rsa_modexp_wait(size_t *num_words) { } else if (mode == kMode4096Modexp || mode == kMode4096ModexpF4) { *num_words = kRsa4096NumWords; } else { + // Wipe DMEM. + HARDENED_TRY(otbn_dmem_sec_wipe()); // Unrecognized mode. return OTCRYPTO_FATAL_ERR; } @@ -96,6 +98,8 @@ static status_t rsa_modexp_finalize(const size_t num_words, uint32_t *result) { // Check that the inferred result size matches expectations. if (num_words != num_words_inferred) { + // Wipe DMEM. + HARDENED_TRY(otbn_dmem_sec_wipe()); return OTCRYPTO_FATAL_ERR; } From b3ee06b8a588c72034c061088fb08ef4033d6805 Mon Sep 17 00:00:00 2001 From: Pascal Nasahl Date: Thu, 17 Jul 2025 15:55:25 +0200 Subject: [PATCH 2/2] [crypto] Wipe DMEM also in error cases When an error occurs, HARDENED_TRY() immediately returns. As we also want to wipe the OTBN DMEM when an error happens, this commit adds HARDENED_TRY_WIPE_DMEM() which wipes DMEM on an error before returning. Signed-off-by: Pascal Nasahl --- sw/device/lib/crypto/drivers/otbn.h | 21 ++++++++ sw/device/lib/crypto/impl/ecc/p256.c | 50 +++++++++++-------- sw/device/lib/crypto/impl/ecc/p384.c | 50 +++++++++++-------- .../lib/crypto/impl/rsa/rsa_3072_verify.c | 11 ++-- sw/device/lib/crypto/impl/rsa/rsa_keygen.c | 9 ++-- sw/device/lib/crypto/impl/rsa/rsa_modexp.c | 8 +-- sw/device/lib/crypto/impl/sha2/sha256.c | 4 +- sw/device/lib/crypto/impl/sha2/sha512.c | 7 +-- 8 files changed, 102 insertions(+), 58 deletions(-) diff --git a/sw/device/lib/crypto/drivers/otbn.h b/sw/device/lib/crypto/drivers/otbn.h index d9053a9f8accf..96e70f67e5103 100644 --- a/sw/device/lib/crypto/drivers/otbn.h +++ b/sw/device/lib/crypto/drivers/otbn.h @@ -15,6 +15,27 @@ extern "C" { #endif +/** + * Hardened version of the `TRY` macro that wipes DMEM() on an error. + * + * Returns an error if either expr_ represents an error, or if the OK code does + * not match the expected hardened value. + * + * @param expr_ An expression that evaluates to a `status_t`. + * @return The enclosed OK value. + */ +#define HARDENED_TRY_WIPE_DMEM(expr_) \ + do { \ + status_t status_ = expr_; \ + if (launder32(OT_UNSIGNED(status_.value)) != kHardenedBoolTrue) { \ + otbn_dmem_sec_wipe(); \ + return (status_t){ \ + .value = (int32_t)(OT_UNSIGNED(status_.value) | 0x80000000)}; \ + } \ + HARDENED_CHECK_EQ(status_.value, kHardenedBoolTrue); \ + status_.value; \ + } while (false) + /** * Constants related to OTBN wide words */ diff --git a/sw/device/lib/crypto/impl/ecc/p256.c b/sw/device/lib/crypto/impl/ecc/p256.c index 190d8697eb089..799cdee0e7d2c 100644 --- a/sw/device/lib/crypto/impl/ecc/p256.c +++ b/sw/device/lib/crypto/impl/ecc/p256.c @@ -123,17 +123,19 @@ status_t p256_sideload_keygen_start(void) { status_t p256_keygen_finalize(p256_masked_scalar_t *private_key, p256_point_t *public_key) { // Spin here waiting for OTBN to complete. - HARDENED_TRY(otbn_busy_wait_for_done()); + HARDENED_TRY_WIPE_DMEM(otbn_busy_wait_for_done()); // Read the masked private key from OTBN dmem. - HARDENED_TRY(otbn_dmem_read(kP256MaskedScalarShareWords, kOtbnVarD0, - private_key->share0)); - HARDENED_TRY(otbn_dmem_read(kP256MaskedScalarShareWords, kOtbnVarD1, - private_key->share1)); + HARDENED_TRY_WIPE_DMEM(otbn_dmem_read(kP256MaskedScalarShareWords, kOtbnVarD0, + private_key->share0)); + HARDENED_TRY_WIPE_DMEM(otbn_dmem_read(kP256MaskedScalarShareWords, kOtbnVarD1, + private_key->share1)); // Read the public key from OTBN dmem. - HARDENED_TRY(otbn_dmem_read(kP256CoordWords, kOtbnVarX, public_key->x)); - HARDENED_TRY(otbn_dmem_read(kP256CoordWords, kOtbnVarY, public_key->y)); + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(kP256CoordWords, kOtbnVarX, public_key->x)); + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(kP256CoordWords, kOtbnVarY, public_key->y)); // Wipe DMEM. return otbn_dmem_sec_wipe(); @@ -141,11 +143,13 @@ status_t p256_keygen_finalize(p256_masked_scalar_t *private_key, status_t p256_sideload_keygen_finalize(p256_point_t *public_key) { // Spin here waiting for OTBN to complete. - HARDENED_TRY(otbn_busy_wait_for_done()); + HARDENED_TRY_WIPE_DMEM(otbn_busy_wait_for_done()); // Read the public key from OTBN dmem. - HARDENED_TRY(otbn_dmem_read(kP256CoordWords, kOtbnVarX, public_key->x)); - HARDENED_TRY(otbn_dmem_read(kP256CoordWords, kOtbnVarY, public_key->y)); + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(kP256CoordWords, kOtbnVarX, public_key->x)); + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(kP256CoordWords, kOtbnVarY, public_key->y)); // Wipe DMEM. return otbn_dmem_sec_wipe(); @@ -212,13 +216,15 @@ status_t p256_ecdsa_sideload_sign_start( status_t p256_ecdsa_sign_finalize(p256_ecdsa_signature_t *result) { // Spin here waiting for OTBN to complete. - HARDENED_TRY(otbn_busy_wait_for_done()); + HARDENED_TRY_WIPE_DMEM(otbn_busy_wait_for_done()); // Read signature R out of OTBN dmem. - HARDENED_TRY(otbn_dmem_read(kP256ScalarWords, kOtbnVarR, result->r)); + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(kP256ScalarWords, kOtbnVarR, result->r)); // Read signature S out of OTBN dmem. - HARDENED_TRY(otbn_dmem_read(kP256ScalarWords, kOtbnVarS, result->s)); + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(kP256ScalarWords, kOtbnVarS, result->s)); // Wipe DMEM. return otbn_dmem_sec_wipe(); @@ -256,20 +262,21 @@ status_t p256_ecdsa_verify_start(const p256_ecdsa_signature_t *signature, status_t p256_ecdsa_verify_finalize(const p256_ecdsa_signature_t *signature, hardened_bool_t *result) { // Spin here waiting for OTBN to complete. - HARDENED_TRY(otbn_busy_wait_for_done()); + HARDENED_TRY_WIPE_DMEM(otbn_busy_wait_for_done()); // Read the status code out of DMEM (false if basic checks on the validity of // the signature and public key failed). uint32_t ok; - HARDENED_TRY(otbn_dmem_read(1, kOtbnVarOk, &ok)); + HARDENED_TRY_WIPE_DMEM(otbn_dmem_read(1, kOtbnVarOk, &ok)); if (launder32(ok) != kHardenedBoolTrue) { + HARDENED_TRY(otbn_dmem_sec_wipe()); return OTCRYPTO_BAD_ARGS; } HARDENED_CHECK_EQ(ok, kHardenedBoolTrue); // Read x_r (recovered R) out of OTBN dmem. uint32_t x_r[kP256ScalarWords]; - HARDENED_TRY(otbn_dmem_read(kP256ScalarWords, kOtbnVarXr, x_r)); + HARDENED_TRY_WIPE_DMEM(otbn_dmem_read(kP256ScalarWords, kOtbnVarXr, x_r)); *result = hardened_memeq(x_r, signature->r, kP256ScalarWords); @@ -301,19 +308,22 @@ status_t p256_ecdh_start(const p256_masked_scalar_t *private_key, status_t p256_ecdh_finalize(p256_ecdh_shared_key_t *shared_key) { // Spin here waiting for OTBN to complete. - HARDENED_TRY(otbn_busy_wait_for_done()); + HARDENED_TRY_WIPE_DMEM(otbn_busy_wait_for_done()); // Read the code indicating if the public key is valid. uint32_t ok; - HARDENED_TRY(otbn_dmem_read(1, kOtbnVarOk, &ok)); + HARDENED_TRY_WIPE_DMEM(otbn_dmem_read(1, kOtbnVarOk, &ok)); if (launder32(ok) != kHardenedBoolTrue) { + HARDENED_TRY(otbn_dmem_sec_wipe()); return OTCRYPTO_BAD_ARGS; } HARDENED_CHECK_EQ(ok, kHardenedBoolTrue); // Read the shares of the key from OTBN dmem (at vars x and y). - HARDENED_TRY(otbn_dmem_read(kP256CoordWords, kOtbnVarX, shared_key->share0)); - HARDENED_TRY(otbn_dmem_read(kP256CoordWords, kOtbnVarY, shared_key->share1)); + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(kP256CoordWords, kOtbnVarX, shared_key->share0)); + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(kP256CoordWords, kOtbnVarY, shared_key->share1)); // Wipe DMEM. return otbn_dmem_sec_wipe(); diff --git a/sw/device/lib/crypto/impl/ecc/p384.c b/sw/device/lib/crypto/impl/ecc/p384.c index d8e0be547eddb..660bad7f004f4 100644 --- a/sw/device/lib/crypto/impl/ecc/p384.c +++ b/sw/device/lib/crypto/impl/ecc/p384.c @@ -164,17 +164,19 @@ status_t p384_keygen_start(void) { status_t p384_keygen_finalize(p384_masked_scalar_t *private_key, p384_point_t *public_key) { // Spin here waiting for OTBN to complete. - HARDENED_TRY(otbn_busy_wait_for_done()); + HARDENED_TRY_WIPE_DMEM(otbn_busy_wait_for_done()); // Read the masked private key from OTBN dmem. - HARDENED_TRY(otbn_dmem_read(kP384MaskedScalarShareWords, kOtbnVarD0, - private_key->share0)); - HARDENED_TRY(otbn_dmem_read(kP384MaskedScalarShareWords, kOtbnVarD1, - private_key->share1)); + HARDENED_TRY_WIPE_DMEM(otbn_dmem_read(kP384MaskedScalarShareWords, kOtbnVarD0, + private_key->share0)); + HARDENED_TRY_WIPE_DMEM(otbn_dmem_read(kP384MaskedScalarShareWords, kOtbnVarD1, + private_key->share1)); // Read the public key from OTBN dmem. - HARDENED_TRY(otbn_dmem_read(kP384CoordWords, kOtbnVarX, public_key->x)); - HARDENED_TRY(otbn_dmem_read(kP384CoordWords, kOtbnVarY, public_key->y)); + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(kP384CoordWords, kOtbnVarX, public_key->x)); + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(kP384CoordWords, kOtbnVarY, public_key->y)); // Wipe DMEM. return otbn_dmem_sec_wipe(); @@ -194,11 +196,13 @@ status_t p384_sideload_keygen_start(void) { status_t p384_sideload_keygen_finalize(p384_point_t *public_key) { // Spin here waiting for OTBN to complete. - HARDENED_TRY(otbn_busy_wait_for_done()); + HARDENED_TRY_WIPE_DMEM(otbn_busy_wait_for_done()); // Read the public key from OTBN dmem. - HARDENED_TRY(otbn_dmem_read(kP384CoordWords, kOtbnVarX, public_key->x)); - HARDENED_TRY(otbn_dmem_read(kP384CoordWords, kOtbnVarY, public_key->y)); + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(kP384CoordWords, kOtbnVarX, public_key->x)); + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(kP384CoordWords, kOtbnVarY, public_key->y)); // Wipe DMEM. return otbn_dmem_sec_wipe(); @@ -241,13 +245,15 @@ status_t p384_ecdsa_sideload_sign_start( status_t p384_ecdsa_sign_finalize(p384_ecdsa_signature_t *result) { // Spin here waiting for OTBN to complete. - HARDENED_TRY(otbn_busy_wait_for_done()); + HARDENED_TRY_WIPE_DMEM(otbn_busy_wait_for_done()); // Read signature R out of OTBN dmem. - HARDENED_TRY(otbn_dmem_read(kP384ScalarWords, kOtbnVarR, result->r)); + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(kP384ScalarWords, kOtbnVarR, result->r)); // Read signature S out of OTBN dmem. - HARDENED_TRY(otbn_dmem_read(kP384ScalarWords, kOtbnVarS, result->s)); + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(kP384ScalarWords, kOtbnVarS, result->s)); // Wipe DMEM. return otbn_dmem_sec_wipe(); @@ -282,20 +288,21 @@ status_t p384_ecdsa_verify_start(const p384_ecdsa_signature_t *signature, status_t p384_ecdsa_verify_finalize(const p384_ecdsa_signature_t *signature, hardened_bool_t *result) { // Spin here waiting for OTBN to complete. - HARDENED_TRY(otbn_busy_wait_for_done()); + HARDENED_TRY_WIPE_DMEM(otbn_busy_wait_for_done()); // Read the status code out of DMEM (false if basic checks on the validity of // the signature and public key failed). uint32_t ok; - HARDENED_TRY(otbn_dmem_read(1, kOtbnVarOk, &ok)); + HARDENED_TRY_WIPE_DMEM(otbn_dmem_read(1, kOtbnVarOk, &ok)); if (launder32(ok) != kHardenedBoolTrue) { + HARDENED_TRY(otbn_dmem_sec_wipe()); return OTCRYPTO_BAD_ARGS; } HARDENED_CHECK_EQ(ok, kHardenedBoolTrue); // Read x_r (recovered R) out of OTBN dmem. uint32_t x_r[kP384ScalarWords]; - HARDENED_TRY(otbn_dmem_read(kP384ScalarWords, kOtbnVarXr, x_r)); + HARDENED_TRY_WIPE_DMEM(otbn_dmem_read(kP384ScalarWords, kOtbnVarXr, x_r)); *result = hardened_memeq(x_r, signature->r, kP384ScalarWords); @@ -324,20 +331,23 @@ status_t p384_ecdh_start(const p384_masked_scalar_t *private_key, status_t p384_ecdh_finalize(p384_ecdh_shared_key_t *shared_key) { // Spin here waiting for OTBN to complete. - HARDENED_TRY(otbn_busy_wait_for_done()); + HARDENED_TRY_WIPE_DMEM(otbn_busy_wait_for_done()); // Read the status code out of DMEM (false if basic checks on the validity of // the signature and public key failed). uint32_t ok; - HARDENED_TRY(otbn_dmem_read(1, kOtbnVarOk, &ok)); + HARDENED_TRY_WIPE_DMEM(otbn_dmem_read(1, kOtbnVarOk, &ok)); if (launder32(ok) != kHardenedBoolTrue) { + HARDENED_TRY(otbn_dmem_sec_wipe()); return OTCRYPTO_BAD_ARGS; } HARDENED_CHECK_EQ(ok, kHardenedBoolTrue); // Read the shares of the key from OTBN dmem (at vars x and y). - HARDENED_TRY(otbn_dmem_read(kP384CoordWords, kOtbnVarX, shared_key->share0)); - HARDENED_TRY(otbn_dmem_read(kP384CoordWords, kOtbnVarY, shared_key->share1)); + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(kP384CoordWords, kOtbnVarX, shared_key->share0)); + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(kP384CoordWords, kOtbnVarY, shared_key->share1)); // Wipe DMEM. return otbn_dmem_sec_wipe(); diff --git a/sw/device/lib/crypto/impl/rsa/rsa_3072_verify.c b/sw/device/lib/crypto/impl/rsa/rsa_3072_verify.c index 43e616f249233..d26423ac701d4 100644 --- a/sw/device/lib/crypto/impl/rsa/rsa_3072_verify.c +++ b/sw/device/lib/crypto/impl/rsa/rsa_3072_verify.c @@ -137,13 +137,14 @@ status_t rsa_3072_compute_constants(const rsa_3072_public_key_t *public_key, HARDENED_TRY(otbn_execute()); // Spin here waiting for OTBN to complete. - HARDENED_TRY(otbn_busy_wait_for_done()); + HARDENED_TRY_WIPE_DMEM(otbn_busy_wait_for_done()); // Read constant rr out of DMEM. - HARDENED_TRY(read_rsa_3072_int_from_otbn(kOtbnVarRsaRR, &result->rr)); + HARDENED_TRY_WIPE_DMEM( + read_rsa_3072_int_from_otbn(kOtbnVarRsaRR, &result->rr)); // Read constant m0_inv out of DMEM. - HARDENED_TRY( + HARDENED_TRY_WIPE_DMEM( otbn_dmem_read(kOtbnWideWordNumWords, kOtbnVarRsaM0Inv, result->m0_inv)); // Wipe DMEM. @@ -197,11 +198,11 @@ status_t rsa_3072_verify_finalize(const rsa_3072_int_t *message, *result = kHardenedBoolFalse; // Spin here waiting for OTBN to complete. - HARDENED_TRY(otbn_busy_wait_for_done()); + HARDENED_TRY_WIPE_DMEM(otbn_busy_wait_for_done()); // Read recovered message out of OTBN dmem. rsa_3072_int_t recoveredMessage; - HARDENED_TRY( + HARDENED_TRY_WIPE_DMEM( read_rsa_3072_int_from_otbn(kOtbnVarRsaOutBuf, &recoveredMessage)); // TODO: harden this memory comparison diff --git a/sw/device/lib/crypto/impl/rsa/rsa_keygen.c b/sw/device/lib/crypto/impl/rsa/rsa_keygen.c index 3ea4379334e27..8f1d3f89f5901 100644 --- a/sw/device/lib/crypto/impl/rsa/rsa_keygen.c +++ b/sw/device/lib/crypto/impl/rsa/rsa_keygen.c @@ -83,20 +83,21 @@ static status_t keygen_start(uint32_t mode) { static status_t keygen_finalize(uint32_t exp_mode, size_t num_words, uint32_t *n, uint32_t *d) { // Spin here waiting for OTBN to complete. - HARDENED_TRY(otbn_busy_wait_for_done()); + HARDENED_TRY_WIPE_DMEM(otbn_busy_wait_for_done()); // Read the mode from OTBN dmem and panic if it's not as expected. uint32_t act_mode = 0; - HARDENED_TRY(otbn_dmem_read(1, kOtbnVarRsaMode, &act_mode)); + HARDENED_TRY_WIPE_DMEM(otbn_dmem_read(1, kOtbnVarRsaMode, &act_mode)); if (act_mode != exp_mode) { + HARDENED_TRY(otbn_dmem_sec_wipe()); return OTCRYPTO_FATAL_ERR; } // Read the public modulus (n) from OTBN dmem. - HARDENED_TRY(otbn_dmem_read(num_words, kOtbnVarRsaN, n)); + HARDENED_TRY_WIPE_DMEM(otbn_dmem_read(num_words, kOtbnVarRsaN, n)); // Read the private exponent (d) from OTBN dmem. - HARDENED_TRY(otbn_dmem_read(num_words, kOtbnVarRsaD, d)); + HARDENED_TRY_WIPE_DMEM(otbn_dmem_read(num_words, kOtbnVarRsaD, d)); // Wipe DMEM. return otbn_dmem_sec_wipe(); diff --git a/sw/device/lib/crypto/impl/rsa/rsa_modexp.c b/sw/device/lib/crypto/impl/rsa/rsa_modexp.c index 25f4dce5adacc..c952646e05c87 100644 --- a/sw/device/lib/crypto/impl/rsa/rsa_modexp.c +++ b/sw/device/lib/crypto/impl/rsa/rsa_modexp.c @@ -58,11 +58,11 @@ enum { status_t rsa_modexp_wait(size_t *num_words) { // Spin here waiting for OTBN to complete. - HARDENED_TRY(otbn_busy_wait_for_done()); + HARDENED_TRY_WIPE_DMEM(otbn_busy_wait_for_done()); // Read the application mode. uint32_t mode; - HARDENED_TRY(otbn_dmem_read(1, kOtbnVarRsaMode, &mode)); + HARDENED_TRY_WIPE_DMEM(otbn_dmem_read(1, kOtbnVarRsaMode, &mode)); *num_words = 0; if (mode == kMode2048Modexp || mode == kMode2048ModexpF4) { @@ -94,7 +94,7 @@ status_t rsa_modexp_wait(size_t *num_words) { static status_t rsa_modexp_finalize(const size_t num_words, uint32_t *result) { // Wait for OTBN to complete and get the result size. size_t num_words_inferred; - HARDENED_TRY(rsa_modexp_wait(&num_words_inferred)); + HARDENED_TRY_WIPE_DMEM(rsa_modexp_wait(&num_words_inferred)); // Check that the inferred result size matches expectations. if (num_words != num_words_inferred) { @@ -104,7 +104,7 @@ static status_t rsa_modexp_finalize(const size_t num_words, uint32_t *result) { } // Read the result. - HARDENED_TRY(otbn_dmem_read(num_words, kOtbnVarRsaInOut, result)); + HARDENED_TRY_WIPE_DMEM(otbn_dmem_read(num_words, kOtbnVarRsaInOut, result)); // Wipe DMEM. return otbn_dmem_sec_wipe(); diff --git a/sw/device/lib/crypto/impl/sha2/sha256.c b/sw/device/lib/crypto/impl/sha2/sha256.c index 9ace990dcb2db..3cb0f68b59c55 100644 --- a/sw/device/lib/crypto/impl/sha2/sha256.c +++ b/sw/device/lib/crypto/impl/sha2/sha256.c @@ -87,7 +87,7 @@ static status_t process_message_buffer(sha256_otbn_ctx_t *ctx) { // Run the OTBN program. HARDENED_TRY(otbn_execute()); - HARDENED_TRY(otbn_busy_wait_for_done()); + HARDENED_TRY_WIPE_DMEM(otbn_busy_wait_for_done()); // Reset the message buffer counter. ctx->num_blocks = 0; @@ -245,7 +245,7 @@ static status_t process_message(sha256_state_t *state, const uint8_t *msg, } // Read the final state from OTBN dmem. - HARDENED_TRY( + HARDENED_TRY_WIPE_DMEM( otbn_dmem_read(kSha256StateWords, kOtbnVarSha256State, new_state.H)); // Clear OTBN's memory. diff --git a/sw/device/lib/crypto/impl/sha2/sha512.c b/sw/device/lib/crypto/impl/sha2/sha512.c index d0154dd8e59bb..5d76fed0b37b9 100644 --- a/sw/device/lib/crypto/impl/sha2/sha512.c +++ b/sw/device/lib/crypto/impl/sha2/sha512.c @@ -135,7 +135,7 @@ static status_t process_message_buffer(sha512_otbn_ctx_t *ctx) { // Run the OTBN program. HARDENED_TRY(otbn_execute()); - HARDENED_TRY(otbn_busy_wait_for_done()); + HARDENED_TRY_WIPE_DMEM(otbn_busy_wait_for_done()); // Reset the message buffer counter. ctx->num_blocks = 0; @@ -307,8 +307,9 @@ static status_t process_message(sha512_state_t *state, const uint8_t *msg, // boundaries. otbn_addr_t state_read_addr = kOtbnVarSha512State; for (size_t i = 0; i + 1 < kSha512StateWords; i += 2) { - HARDENED_TRY(otbn_dmem_read(1, state_read_addr, &new_state.H[i + 1])); - HARDENED_TRY( + HARDENED_TRY_WIPE_DMEM( + otbn_dmem_read(1, state_read_addr, &new_state.H[i + 1])); + HARDENED_TRY_WIPE_DMEM( otbn_dmem_read(1, state_read_addr + sizeof(uint32_t), &new_state.H[i])); state_read_addr += kOtbnWideWordNumBytes; }