From be8387afb53ca97bfb70900586272228edf8d6ea Mon Sep 17 00:00:00 2001 From: Hugo Grostabussiat Date: Sun, 5 Feb 2023 19:22:31 +0100 Subject: [PATCH] crypto: Erase key from RAM after storing into enclave When storing a new unique secret key in the secure enclave, it is temporarily stored in a stack buffer accessible by CPU1. Since it is a secret key, it should not be kept in memory as it could be leaked. This commit calls the explicit_bzero() function from the libc to ensure that the buffer containing the key is cleared. Unlike with bzero() and memset(), the compiler won't optimize away calls to explicit_bzero(). --- applications/services/crypto/crypto_cli.c | 1 + firmware/targets/f7/furi_hal/furi_hal_crypto.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/applications/services/crypto/crypto_cli.c b/applications/services/crypto/crypto_cli.c index 511a9d2a8..d91b448ec 100644 --- a/applications/services/crypto/crypto_cli.c +++ b/applications/services/crypto/crypto_cli.c @@ -276,6 +276,7 @@ void crypto_cli_store_key(Cli* cli, FuriString* args) { } } while(0); + explicit_bzero(data, sizeof(data)); furi_string_free(key_type); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_crypto.c b/firmware/targets/f7/furi_hal/furi_hal_crypto.c index e0ed3ab9b..0026636a4 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_crypto.c +++ b/firmware/targets/f7/furi_hal/furi_hal_crypto.c @@ -80,9 +80,11 @@ static bool furi_hal_crypto_generate_unique_keys(uint8_t start_slot, uint8_t end key.data = key_data; furi_hal_random_fill_buf(key_data, 32); if(!furi_hal_crypto_store_add_key(&key, &slot)) { + explicit_bzero(key_data, sizeof(key_data)); FURI_LOG_E(TAG, "Error writing key to slot %u", slot); return false; } + explicit_bzero(key_data, sizeof(key_data)); } return true; } @@ -176,6 +178,7 @@ bool furi_hal_crypto_store_add_key(FuriHalCryptoKey* key, uint8_t* slot) { memcpy(pParam.KeyData, key->data, key_data_size); SHCI_CmdStatus_t shci_state = SHCI_C2_FUS_StoreUsrKey(&pParam, slot); + explicit_bzero(&pParam, sizeof(pParam)); furi_check(furi_mutex_release(furi_hal_crypto_mutex) == FuriStatusOk); return (shci_state == SHCI_Success); }