From ef02c4de5d492a5c5d562984ec65a302d093dfd0 Mon Sep 17 00:00:00 2001 From: matejcik Date: Fri, 22 Nov 2024 14:06:21 +0100 Subject: [PATCH] feat(core): introduce storage insecure mode reduces the number of PIN iterations and avoids erasing the other storage bank -- if a test ever overruns, it will probably RSOD out, but that's unlikely to happen --- core/Makefile | 2 ++ core/SConscript.firmware | 18 ++++++++++++++++++ core/SConscript.kernel | 17 +++++++++++++++++ storage/norcow.c | 4 ++++ storage/storage.c | 4 ++++ storage/storage_utils.h | 12 ++++++++++++ 6 files changed, 57 insertions(+) diff --git a/core/Makefile b/core/Makefile index 4ce16e342f..ffb8893aa5 100644 --- a/core/Makefile +++ b/core/Makefile @@ -43,6 +43,7 @@ BENCHMARK ?= 0 TREZOR_EMULATOR_DEBUGGABLE ?= 0 QUIET_MODE ?= 0 TREZOR_DISABLE_ANIMATION ?= $(if $(filter 0,$(PYOPT)),1,0) +STORAGE_INSECURE_TESTING_MODE ?= 0 # OpenOCD interface default. Alternative: ftdi/olimex-arm-usb-tiny-h OPENOCD_INTERFACE ?= stlink @@ -144,6 +145,7 @@ SCONS_VARS = \ PRODUCTION="$(PRODUCTION)" \ PYOPT="$(PYOPT)" \ QUIET_MODE="$(QUIET_MODE)" \ + STORAGE_INSECURE_TESTING_MODE="$(STORAGE_INSECURE_TESTING_MODE)" \ THP="$(THP)" \ TREZOR_DISABLE_ANIMATION="$(TREZOR_DISABLE_ANIMATION)" \ TREZOR_EMULATOR_ASAN="$(ADDRESS_SANITIZER)" \ diff --git a/core/SConscript.firmware b/core/SConscript.firmware index a3e17ee93c..bf7427ec61 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -20,6 +20,13 @@ MODEL_IDENTIFIER = models.get_model_identifier(TREZOR_MODEL) BENCHMARK = ARGUMENTS.get('BENCHMARK', '0') == '1' DISABLE_ANIMATION = ARGUMENTS.get('TREZOR_DISABLE_ANIMATION', '0') == '1' +STORAGE_INSECURE_TESTING_MODE = ARGUMENTS.get('STORAGE_INSECURE_TESTING_MODE', '0') == '1' +if STORAGE_INSECURE_TESTING_MODE and PRODUCTION: + raise RuntimeError("STORAGE_INSECURE_TESTING_MODE cannot be used in production") +if STORAGE_INSECURE_TESTING_MODE: + DISABLE_OPTIGA = True + PYOPT = "0" + if BENCHMARK and PYOPT != '0': print("BENCHMARK=1 works only with PYOPT=0.") exit(1) @@ -371,6 +378,9 @@ if THP: 'vendor/trezor-crypto/elligator2.c', ] +if STORAGE_INSECURE_TESTING_MODE: + CPPDEFINES_MOD += ['STORAGE_INSECURE_TESTING_MODE'] + ui.init_ui(TREZOR_MODEL, "firmware", CPPDEFINES_MOD, SOURCE_MOD, RUST_UI_FEATURES) SOURCE_QSTR = SOURCE_MOD + SOURCE_MICROPYTHON + SOURCE_MICROPYTHON_SPEED @@ -877,6 +887,14 @@ elif 'STM32U5G9xx' in CPPDEFINES_HAL or 'STM32U585xx' in CPPDEFINES_HAL: else: raise Exception("Unknown MCU") +if STORAGE_INSECURE_TESTING_MODE: + INSECURE_TESTING_MODE_STR = """ +######################################################### +# STORAGE_INSECURE_TESTING_MODE enabled, DO NOT USE # +######################################################### +""" + action_bin.append(INSECURE_TESTING_MODE_STR) + program_bin = env.Command( target='firmware.bin', source=program_elf, diff --git a/core/SConscript.kernel b/core/SConscript.kernel index 7b7dec48ad..e7c6d016b0 100644 --- a/core/SConscript.kernel +++ b/core/SConscript.kernel @@ -16,6 +16,13 @@ DISABLE_OPTIGA = ARGUMENTS.get('DISABLE_OPTIGA', '0') == '1' HW_REVISION = ARGUMENTS.get('HW_REVISION', None) THP = ARGUMENTS.get('THP', '0') == '1' # Trezor-Host Protocol +STORAGE_INSECURE_TESTING_MODE = ARGUMENTS.get('STORAGE_INSECURE_TESTING_MODE', '0') == '1' +if STORAGE_INSECURE_TESTING_MODE and PRODUCTION: + raise RuntimeError("STORAGE_INSECURE_TESTING_MODE cannot be used in production") +if STORAGE_INSECURE_TESTING_MODE: + DISABLE_OPTIGA = True + PYOPT = "0" + FEATURE_FLAGS = { "RDI": True, "SECP256K1_ZKP": True, # required for trezor.crypto.curve.bip340 (BIP340/Taproot) @@ -238,6 +245,8 @@ if THP: 'vendor/trezor-crypto/elligator2.c', ] +if STORAGE_INSECURE_TESTING_MODE: + CPPDEFINES_MOD += ['STORAGE_INSECURE_TESTING_MODE'] env = Environment( ENV=os.environ, @@ -414,6 +423,14 @@ action_bin=[ '$CP $TARGET ' + BINARY_NAME, ] +if STORAGE_INSECURE_TESTING_MODE: + INSECURE_TESTING_MODE_STR = """ +######################################################### +# STORAGE_INSECURE_TESTING_MODE enabled, DO NOT USE # +######################################################### +""" + action_bin.append(INSECURE_TESTING_MODE_STR) + program_bin = env.Command( target='kernel.bin', source=program_elf, diff --git a/storage/norcow.c b/storage/norcow.c index 06505bfd62..c0f6713d83 100644 --- a/storage/norcow.c +++ b/storage/norcow.c @@ -284,11 +284,15 @@ void norcow_wipe(void) { // Erase the active sector first, because it contains sensitive data. erase_sector(norcow_active_sector, sectrue); +#if STORAGE_INSECURE_TESTING_MODE && !PRODUCTION + // skip erasing inactive sectors +#else for (uint8_t i = 0; i < NORCOW_SECTOR_COUNT; i++) { if (i != norcow_active_sector) { erase_sector(i, secfalse); } } +#endif norcow_active_version = NORCOW_VERSION; norcow_write_sector = norcow_active_sector; norcow_free_offset = NORCOW_STORAGE_START; diff --git a/storage/storage.c b/storage/storage.c index b32217d5af..e3c54dadb0 100644 --- a/storage/storage.c +++ b/storage/storage.c @@ -86,8 +86,12 @@ const uint32_t V0_PIN_EMPTY = 1; // up constant storage space. #define MAX_WIPE_CODE_LEN 50 +#if STORAGE_INSECURE_TESTING_MODE && !PRODUCTION +#define PIN_ITER_COUNT 1 +#else // The total number of iterations to use in PBKDF2. #define PIN_ITER_COUNT 20000 +#endif // The minimum number of milliseconds between progress updates. #define MIN_PROGRESS_UPDATE_MS 100 diff --git a/storage/storage_utils.h b/storage/storage_utils.h index f34e8e3edf..b6e12757b7 100644 --- a/storage/storage_utils.h +++ b/storage/storage_utils.h @@ -2,3 +2,15 @@ #include uint32_t hamming_weight(uint32_t value); + +#ifndef STORAGE_INSECURE_TESTING_MODE +#define STORAGE_INSECURE_TESTING_MODE 0 +#endif + +#if STORAGE_INSECURE_TESTING_MODE +#if PRODUCTION +#error "STORAGE_INSECURE_TESTING_MODE can't be used in production" +#else +#pragma message("STORAGE IS INSECURE DO NOT USE THIS IN PRODUCTION") +#endif +#endif