From e460c4fe17743a87b9170907ec5466d7e05f92bf Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Sat, 3 Mar 2018 22:22:45 +0100 Subject: [PATCH] session: rework get_state --- firmware/fsm.c | 10 +++++-- firmware/protob/messages.options | 3 +- firmware/storage.c | 47 ++++++++++---------------------- firmware/storage.h | 3 +- vendor/trezor-common | 2 +- 5 files changed, 25 insertions(+), 40 deletions(-) diff --git a/firmware/fsm.c b/firmware/fsm.c index c4b633a..c36fb74 100644 --- a/firmware/fsm.c +++ b/firmware/fsm.c @@ -234,9 +234,14 @@ void fsm_msgInitialize(Initialize *msg) { recovery_abort(); signing_abort(); - if (msg->has_state && msg->state.size == 64) { - if (!session_compareState(msg->state.bytes)) { + if (msg && msg->has_state && msg->state.size == 64) { + uint8_t i_state[64]; + if (!session_getState(msg->state.bytes, i_state, NULL)) { session_clear(false); // do not clear PIN + } else { + if (0 != memcmp(msg->state.bytes, i_state, 64)) { + session_clear(false); // do not clear PIN + } } } else { session_clear(false); // do not clear PIN @@ -306,7 +311,6 @@ void fsm_msgGetFeatures(GetFeatures *msg) resp->has_needs_backup = true; resp->needs_backup = storage_needsBackup(); resp->has_flags = true; resp->flags = storage_getFlags(); resp->has_model = true; strlcpy(resp->model, "1", sizeof(resp->model)); - resp->has_state = true; resp->state.size = 64; session_getState(NULL, resp->state.bytes); msg_write(MessageType_MessageType_Features, resp); } diff --git a/firmware/protob/messages.options b/firmware/protob/messages.options index 88e96cb..a34b9f9 100644 --- a/firmware/protob/messages.options +++ b/firmware/protob/messages.options @@ -10,7 +10,6 @@ Features.bootloader_hash max_size:32 Features.model max_size:17 Features.fw_vendor max_size:256 Features.fw_vendor_keys max_size:32 -Features.state max_size:64 ApplySettings.language max_size:17 ApplySettings.label max_size:33 @@ -29,6 +28,8 @@ PinMatrixAck.pin max_size:10 PassphraseAck.passphrase max_size:51 PassphraseAck.state max_size:64 +PassphraseStateRequest.state max_size:64 + Entropy.entropy max_size:1024 GetPublicKey.address_n max_count:8 diff --git a/firmware/storage.c b/firmware/storage.c index ebdb01c..1fe9e9b 100644 --- a/firmware/storage.c +++ b/firmware/storage.c @@ -125,9 +125,6 @@ static bool sessionPinCached; static bool sessionPassphraseCached; static char CONFIDENTIAL sessionPassphrase[51]; -static bool sessionStateSaltSet; -static uint8_t sessionStateSalt[32]; - #define STORAGE_VERSION 9 void storage_show_error(void) @@ -270,8 +267,6 @@ void session_clear(bool clear_pin) memzero(&sessionSeed, sizeof(sessionSeed)); sessionPassphraseCached = false; memzero(&sessionPassphrase, sizeof(sessionPassphrase)); - sessionStateSaltSet = false; - memzero(&sessionStateSalt, sizeof(sessionStateSalt)); if (clear_pin) { sessionPinCached = false; } @@ -715,45 +710,31 @@ bool session_isPassphraseCached(void) return sessionPassphraseCached; } -void session_getState(const uint8_t *salt, uint8_t *state) +bool session_getState(const uint8_t *salt, uint8_t *state, const char *passphrase) { - if (!salt) { - if (!sessionStateSaltSet) { - // generate a random salt if not provided and not already cached - random_buffer(sessionStateSalt, 32); - } + if (!passphrase && !sessionPassphraseCached) { + return false; } else { - // otherwise copy provided salt to cached salt - memcpy(sessionStateSalt, salt, 32); + passphrase = sessionPassphrase; + } + if (!salt) { + // if salt is not provided fill the first half of the state with random data + random_buffer(state, 32); + } else { + // if salt is provided fill the first half of the state with salt + memcpy(state, salt, 32); } - - sessionStateSaltSet = true; - // state[0:32] = salt - memcpy(state, sessionStateSalt, 32); - // state[32:64] = HMAC(passphrase, salt || device_id) HMAC_SHA256_CTX ctx; - if (sessionPassphraseCached) { - hmac_sha256_Init(&ctx, (const uint8_t *)sessionPassphrase, strlen(sessionPassphrase)); - } else { - hmac_sha256_Init(&ctx, (const uint8_t *)"", 0); - } - hmac_sha256_Update(&ctx, sessionStateSalt, 32); + hmac_sha256_Init(&ctx, (const uint8_t *)passphrase, strlen(passphrase)); + hmac_sha256_Update(&ctx, state, 32); hmac_sha256_Update(&ctx, (const uint8_t *)storage_uuid, sizeof(storage_uuid)); hmac_sha256_Final(&ctx, state + 32); memzero(&ctx, sizeof(ctx)); -} -bool session_compareState(const uint8_t *state) -{ - if (!state) { - return false; - } - uint8_t istate[64]; - session_getState(state, istate); - return 0 == memcmp(state, istate, 64); + return true; } void session_cachePin(void) diff --git a/firmware/storage.h b/firmware/storage.h index 2c15e7e..431e830 100644 --- a/firmware/storage.h +++ b/firmware/storage.h @@ -103,8 +103,7 @@ void storage_setHomescreen(const uint8_t *data, uint32_t size); void session_cachePassphrase(const char *passphrase); bool session_isPassphraseCached(void); -void session_getState(const uint8_t *salt, uint8_t *state); -bool session_compareState(const uint8_t *state); +bool session_getState(const uint8_t *salt, uint8_t *state, const char *passphrase); void storage_setMnemonic(const char *mnemonic); bool storage_containsMnemonic(const char *mnemonic); diff --git a/vendor/trezor-common b/vendor/trezor-common index d85f7ac..0924bd6 160000 --- a/vendor/trezor-common +++ b/vendor/trezor-common @@ -1 +1 @@ -Subproject commit d85f7ac6bbcccbc83012d85fdf25635e57c5f15b +Subproject commit 0924bd6826bb63f66010e2e511356d54ea733df3