From 7be055337717f9a758dcf117deb86acfd35e226c Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Wed, 7 Aug 2019 16:46:21 +0200 Subject: [PATCH 01/13] Replace FIDO2 PIN storage with its hash --- fido2/ctap.c | 78 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 27 deletions(-) diff --git a/fido2/ctap.c b/fido2/ctap.c index dea0f3f..f68e474 100644 --- a/fido2/ctap.c +++ b/fido2/ctap.c @@ -29,7 +29,6 @@ uint8_t PIN_TOKEN[PIN_TOKEN_SIZE]; uint8_t KEY_AGREEMENT_PUB[64]; static uint8_t KEY_AGREEMENT_PRIV[32]; -static uint8_t PIN_CODE_HASH[32]; static int8_t PIN_BOOT_ATTEMPTS_LEFT = PIN_BOOT_ATTEMPTS; AuthenticatorState STATE; @@ -1362,7 +1361,13 @@ uint8_t ctap_update_pin_if_verified(uint8_t * pinEnc, int len, uint8_t * platfor } crypto_aes256_reset_iv(NULL); crypto_aes256_decrypt(pinHashEnc, 16); - if (memcmp(pinHashEnc, PIN_CODE_HASH, 16) != 0) + + crypto_sha256_init(); + crypto_sha256_update(pinHashEnc, 16); + crypto_sha256_update(STATE.PIN_SALT, sizeof(STATE.PIN_SALT)); + crypto_sha256_final(pinHashEnc); + + if (memcmp(pinHashEnc, STATE.PIN_CODE_HASH, 16) != 0) { ctap_reset_key_agreement(); ctap_decrement_pin_attempts(); @@ -1397,12 +1402,15 @@ uint8_t ctap_add_pin_if_verified(uint8_t * pinTokenEnc, uint8_t * platform_pubke crypto_aes256_decrypt(pinHashEnc, 16); - - if (memcmp(pinHashEnc, PIN_CODE_HASH, 16) != 0) + crypto_sha256_init(); + crypto_sha256_update(pinHashEnc, 16); + crypto_sha256_update(STATE.PIN_SALT, sizeof(STATE.PIN_SALT)); + crypto_sha256_final(pinHashEnc); + if (memcmp(pinHashEnc, STATE.PIN_CODE_HASH, 16) != 0) { printf2(TAG_ERR,"Pin does not match!\n"); printf2(TAG_ERR,"platform-pin-hash: "); dump_hex1(TAG_ERR, pinHashEnc, 16); - printf2(TAG_ERR,"authentic-pin-hash: "); dump_hex1(TAG_ERR, PIN_CODE_HASH, 16); + printf2(TAG_ERR,"authentic-pin-hash: "); dump_hex1(TAG_ERR, STATE.PIN_CODE_HASH, 16); printf2(TAG_ERR,"shared-secret: "); dump_hex1(TAG_ERR, shared_secret, 32); printf2(TAG_ERR,"platform-pubkey: "); dump_hex1(TAG_ERR, platform_pubkey, 64); printf2(TAG_ERR,"device-pubkey: "); dump_hex1(TAG_ERR, KEY_AGREEMENT_PUB, 64); @@ -1710,6 +1718,15 @@ static void ctap_state_init() STATE.rk_stored = 0; ctap_reset_rk(); + + if (ctap_generate_rng(STATE.PIN_SALT, sizeof(STATE.PIN_SALT)) != 1) { + printf2(TAG_ERR, "Error, rng failed\n"); + exit(1); + } + + printf1(TAG_STOR, "Generated PIN SALT: "); + dump_hex1(TAG_STOR, STATE.PIN_SALT, sizeof STATE.PIN_SALT); + } void ctap_init() @@ -1746,10 +1763,6 @@ void ctap_init() if (ctap_is_pin_set()) { - printf1(TAG_STOR,"pin code: \"%s\"\n", STATE.pin_code); - crypto_sha256_init(); - crypto_sha256_update(STATE.pin_code, STATE.pin_code_length); - crypto_sha256_final(PIN_CODE_HASH); printf1(TAG_STOR, "attempts_left: %d\n", STATE.remaining_tries); } else @@ -1784,34 +1797,38 @@ uint8_t ctap_is_pin_set() return STATE.is_pin_set == 1; } -uint8_t ctap_pin_matches(uint8_t * pin, int len) -{ - return memcmp(pin, STATE.pin_code, len) == 0; -} - - +/** + * Set new PIN, by updating PIN hash. Save state. + * Globals: PIN_CODE_HASH STATE + * @param pin new PIN (raw) + * @param len pin array length + */ void ctap_update_pin(uint8_t * pin, int len) { - if (len > NEW_PIN_ENC_MIN_SIZE || len < 4) + if (len >= NEW_PIN_ENC_MIN_SIZE || len < 4) { printf2(TAG_ERR, "Update pin fail length\n"); exit(1); } - memset(STATE.pin_code, 0, NEW_PIN_ENC_MIN_SIZE); - memmove(STATE.pin_code, pin, len); - STATE.pin_code_length = len; - STATE.pin_code[NEW_PIN_ENC_MIN_SIZE - 1] = 0; crypto_sha256_init(); - crypto_sha256_update(STATE.pin_code, len); - crypto_sha256_final(PIN_CODE_HASH); + crypto_sha256_update(pin, len); + uint8_t intermediateHash[32]; + crypto_sha256_final(intermediateHash); + + crypto_sha256_init(); + crypto_sha256_update(intermediateHash, 16); + memset(intermediateHash, 0, sizeof(intermediateHash)); + crypto_sha256_update(STATE.PIN_SALT, sizeof(STATE.PIN_SALT)); + crypto_sha256_final(STATE.PIN_CODE_HASH); STATE.is_pin_set = 1; authenticator_write_state(&STATE, 1); authenticator_write_state(&STATE, 0); - printf1(TAG_CTAP, "New pin set: %s\n", STATE.pin_code); + printf1(TAG_CTAP, "New pin set: %s [%d]\n", pin, len); + dump_hex1(TAG_ERR, STATE.PIN_CODE_HASH, sizeof(STATE.PIN_CODE_HASH)); } uint8_t ctap_decrement_pin_attempts() @@ -1828,9 +1845,7 @@ uint8_t ctap_decrement_pin_attempts() if (ctap_device_locked()) { - memset(PIN_TOKEN,0,sizeof(PIN_TOKEN)); - memset(PIN_CODE_HASH,0,sizeof(PIN_CODE_HASH)); - printf1(TAG_CP, "Device locked!\n"); + lock_device_permanently(); } } else @@ -1986,8 +2001,17 @@ void ctap_reset() } ctap_reset_state(); - memset(PIN_CODE_HASH,0,sizeof(PIN_CODE_HASH)); ctap_reset_key_agreement(); crypto_load_master_secret(STATE.key_space); } + +void lock_device_permanently() { + memset(PIN_TOKEN, 0, sizeof(PIN_TOKEN)); + memset(STATE.PIN_CODE_HASH, 0, sizeof(STATE.PIN_CODE_HASH)); + + printf1(TAG_CP, "Device locked!\n"); + + authenticator_write_state(&STATE, 0); + authenticator_write_state(&STATE, 1); +} From 5a448d636cb1bccf020af02b7e5557a5ea9987ce Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Wed, 7 Aug 2019 17:17:20 +0200 Subject: [PATCH 02/13] Add comments --- fido2/ctap.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fido2/ctap.c b/fido2/ctap.c index f68e474..6e3f652 100644 --- a/fido2/ctap.c +++ b/fido2/ctap.c @@ -1285,11 +1285,13 @@ uint8_t ctap_update_pin_if_verified(uint8_t * pinEnc, int len, uint8_t * platfor uint8_t hmac[32]; int ret; +// Validate incoming data packet len if (len < 64) { return CTAP1_ERR_OTHER; } +// Validate device's state if (ctap_is_pin_set()) // Check first, prevent SCA { if (ctap_device_locked()) @@ -1302,6 +1304,7 @@ uint8_t ctap_update_pin_if_verified(uint8_t * pinEnc, int len, uint8_t * platfor } } +// calculate shared_secret crypto_ecc256_shared_secret(platform_pubkey, KEY_AGREEMENT_PRIV, shared_secret); crypto_sha256_init(); @@ -1324,6 +1327,7 @@ uint8_t ctap_update_pin_if_verified(uint8_t * pinEnc, int len, uint8_t * platfor return CTAP2_ERR_PIN_AUTH_INVALID; } +// decrypt new PIN with shared secret crypto_aes256_init(shared_secret, NULL); while((len & 0xf) != 0) // round up to nearest AES block size multiple @@ -1333,7 +1337,7 @@ uint8_t ctap_update_pin_if_verified(uint8_t * pinEnc, int len, uint8_t * platfor crypto_aes256_decrypt(pinEnc, len); - +// validate new PIN (length) ret = trailing_zeros(pinEnc, NEW_PIN_ENC_MIN_SIZE - 1); ret = NEW_PIN_ENC_MIN_SIZE - ret; @@ -1349,6 +1353,8 @@ uint8_t ctap_update_pin_if_verified(uint8_t * pinEnc, int len, uint8_t * platfor dump_hex1(TAG_CP, pinEnc, ret); } +// validate device's state, decrypt and compare pinHashEnc (user provided current PIN hash) with stored PIN_CODE_HASH + if (ctap_is_pin_set()) { if (ctap_device_locked()) @@ -1383,6 +1389,7 @@ uint8_t ctap_update_pin_if_verified(uint8_t * pinEnc, int len, uint8_t * platfor } } +// set new PIN (update and store PIN_CODE_HASH) ctap_update_pin(pinEnc, ret); return 0; From 43b3e93854d336a1e9b38675a6541ae5961cac87 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Wed, 7 Aug 2019 17:18:56 +0200 Subject: [PATCH 03/13] Modify state struct --- fido2/storage.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fido2/storage.h b/fido2/storage.h index 6d49d21..6f62dd0 100644 --- a/fido2/storage.h +++ b/fido2/storage.h @@ -11,6 +11,8 @@ #define KEY_SPACE_BYTES 128 #define MAX_KEYS (1) +#define PIN_SALT_LEN (32) + #define BACKUP_MARKER 0x5A #define INITIALIZED_MARKER 0xA5 @@ -24,8 +26,8 @@ typedef struct // Pin information uint8_t is_initialized; uint8_t is_pin_set; - uint8_t pin_code[NEW_PIN_ENC_MIN_SIZE]; - int pin_code_length; + uint8_t PIN_CODE_HASH[32]; + uint8_t PIN_SALT[PIN_SALT_LEN]; int8_t remaining_tries; uint16_t rk_stored; From 6e637299e5c3efc4feb5c509c7f8e1e6667570d5 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Wed, 7 Aug 2019 17:21:07 +0200 Subject: [PATCH 04/13] Add missing declaration, and comment out wallet message --- fido2/ctap.h | 1 + fido2/extensions/wallet.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fido2/ctap.h b/fido2/ctap.h index 51a5c11..92d6b4e 100644 --- a/fido2/ctap.h +++ b/fido2/ctap.h @@ -359,5 +359,6 @@ uint16_t ctap_key_len(uint8_t index); extern uint8_t PIN_TOKEN[PIN_TOKEN_SIZE]; extern uint8_t KEY_AGREEMENT_PUB[64]; +void lock_device_permanently(); #endif diff --git a/fido2/extensions/wallet.c b/fido2/extensions/wallet.c index 537b359..e375773 100644 --- a/fido2/extensions/wallet.c +++ b/fido2/extensions/wallet.c @@ -95,7 +95,7 @@ int8_t wallet_pin(uint8_t subcmd, uint8_t * pinAuth, uint8_t * arg1, uint8_t * a if (ret != 0) return ret; - printf1(TAG_WALLET,"Success. Pin = %s\n", STATE.pin_code); +// printf1(TAG_WALLET,"Success. Pin = %s\n", STATE.pin_code); break; case CP_cmdChangePin: From bac576f3a0a761caf41f066a421a6944023d205c Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Tue, 20 Aug 2019 09:36:39 +0200 Subject: [PATCH 05/13] Make the state structure backward-compatible. Add version. --- fido2/storage.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fido2/storage.h b/fido2/storage.h index 6f62dd0..6432229 100644 --- a/fido2/storage.h +++ b/fido2/storage.h @@ -28,12 +28,14 @@ typedef struct uint8_t is_pin_set; uint8_t PIN_CODE_HASH[32]; uint8_t PIN_SALT[PIN_SALT_LEN]; + int _reserved_pin_code_length; int8_t remaining_tries; uint16_t rk_stored; uint16_t key_lens[MAX_KEYS]; uint8_t key_space[KEY_SPACE_BYTES]; + uint8_t data_version; } AuthenticatorState; From ee351421cb9a1e768c7de458edf0f8174b5ad236 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Tue, 20 Aug 2019 09:37:05 +0200 Subject: [PATCH 06/13] Add missing definition for the simulation to run --- pc/device.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pc/device.c b/pc/device.c index 2a0e166..e159e36 100644 --- a/pc/device.c +++ b/pc/device.c @@ -628,3 +628,6 @@ int device_is_nfc() { return 0; } + +void request_from_nfc(bool request_active) { +} From 6c60a37e8acec9bc72f15e33943cbfa4deed7bf2 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Tue, 20 Aug 2019 11:19:22 +0200 Subject: [PATCH 07/13] Add initial STATE migration code --- fido2/data_migration.c | 87 ++++++++++++++++++++++++++++++++++++++++++ fido2/data_migration.h | 15 ++++++++ 2 files changed, 102 insertions(+) create mode 100644 fido2/data_migration.c create mode 100644 fido2/data_migration.h diff --git a/fido2/data_migration.c b/fido2/data_migration.c new file mode 100644 index 0000000..e4cbcf1 --- /dev/null +++ b/fido2/data_migration.c @@ -0,0 +1,87 @@ +// Copyright 2019 SoloKeys Developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +#include "data_migration.h" +#include "log.h" +#include "device.h" +#include "crypto.h" + +// TODO move from macro to function/assert for better readability? +#define check(x) assert(state_prev_0xff->x == state_tmp_ptr->x); +#define check_buf(x) assert(memcmp(state_prev_0xff->x, state_tmp_ptr->x, sizeof(state_tmp_ptr->x)) == 0); + +bool migrate_from_FF_to_01(AuthenticatorState* state_previous_ptr, AuthenticatorState* state_tmp_ptr){ + // Calculate PIN hash, and replace PIN raw storage with it; add version to structure + // other ingredients do not change + if (state_tmp_ptr->data_version != 0xFF) + return false; + + static_assert(sizeof(AuthenticatorState_0xFF) <= sizeof(AuthenticatorState), "New state structure is smaller, than current one, which is not handled"); + + AuthenticatorState_0xFF* state_prev_0xff = (AuthenticatorState_0xFF *) state_previous_ptr; + + if (ctap_generate_rng(state_tmp_ptr->PIN_SALT, sizeof(state_tmp_ptr->PIN_SALT)) != 1) { + printf2(TAG_ERR, "Error, rng failed\n"); + return false; + } + if (state_prev_0xff->is_pin_set){ + crypto_sha256_init(); + crypto_sha256_update(state_prev_0xff->pin_code, state_prev_0xff->pin_code_length); + uint8_t intermediateHash[32]; + crypto_sha256_final(intermediateHash); + + crypto_sha256_init(); + crypto_sha256_update(intermediateHash, 16); + memset(intermediateHash, 0, sizeof(intermediateHash)); + crypto_sha256_update(state_tmp_ptr->PIN_SALT, sizeof(state_tmp_ptr->PIN_SALT)); + crypto_sha256_final(state_tmp_ptr->PIN_CODE_HASH); + } + + state_tmp_ptr->_reserved = 0xFF; + state_tmp_ptr->data_version = 1; + + check(is_pin_set); + check(rk_stored); + check(remaining_tries); + check_buf(key_lens); + check_buf(key_space); + + return true; +} + +void save_migrated_state(AuthenticatorState *state_tmp_ptr) { + memmove(&STATE, state_tmp_ptr, sizeof(AuthenticatorState)); + authenticator_write_state(state_tmp_ptr, 0); + authenticator_write_state(state_tmp_ptr, 1); +} + +void do_migration_if_required(AuthenticatorState* state_current){ + // Currently handles only state structures with the same size, or bigger + // FIXME rework to raw buffers with fixed size to allow state structure size decrease + if(!state_current->is_initialized) + return; + + AuthenticatorState state_tmp; + AuthenticatorState state_previous; + authenticator_read_state(&state_previous); + authenticator_read_state(&state_tmp); + if(state_current->data_version == 0xFF){ + printf2(TAG_ERR, "Running migration\n"); + bool success = migrate_from_FF_to_01(&state_previous, &state_tmp); + if (!success){ + printf2(TAG_ERR, "Failed migration from 0xFF to 1\n"); + // FIXME discuss migration failure behavior + goto return_cleanup; + } + dump_hex1(TAG_ERR, (void*)&state_tmp, sizeof(state_tmp)); + dump_hex1(TAG_ERR, (void*)&state_previous, sizeof(state_previous)); + save_migrated_state(&state_tmp); + } + return_cleanup: + memset(&state_tmp, 0, sizeof(AuthenticatorState)); + memset(&state_previous, 0, sizeof(AuthenticatorState)); +} diff --git a/fido2/data_migration.h b/fido2/data_migration.h new file mode 100644 index 0000000..ffdd9b7 --- /dev/null +++ b/fido2/data_migration.h @@ -0,0 +1,15 @@ +// Copyright 2019 SoloKeys Developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +#ifndef FIDO2_PR_DATA_MIGRATION_H +#define FIDO2_PR_DATA_MIGRATION_H + +#include "storage.h" + +void do_migration_if_required(AuthenticatorState* state_current); + +#endif //FIDO2_PR_DATA_MIGRATION_H From 816ca21f0881914a2d0ccc9bfa3cbfafd5fbd602 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Tue, 20 Aug 2019 11:20:56 +0200 Subject: [PATCH 08/13] Correct writing salted hash pinHashEnc is 16 bytes, which is too small to store sha256 result. --- fido2/ctap.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fido2/ctap.c b/fido2/ctap.c index 6e3f652..9081149 100644 --- a/fido2/ctap.c +++ b/fido2/ctap.c @@ -1368,12 +1368,13 @@ uint8_t ctap_update_pin_if_verified(uint8_t * pinEnc, int len, uint8_t * platfor crypto_aes256_reset_iv(NULL); crypto_aes256_decrypt(pinHashEnc, 16); + uint8_t pinHashEncSalted[32]; crypto_sha256_init(); crypto_sha256_update(pinHashEnc, 16); crypto_sha256_update(STATE.PIN_SALT, sizeof(STATE.PIN_SALT)); - crypto_sha256_final(pinHashEnc); + crypto_sha256_final(pinHashEncSalted); - if (memcmp(pinHashEnc, STATE.PIN_CODE_HASH, 16) != 0) + if (memcmp(pinHashEncSalted, STATE.PIN_CODE_HASH, 16) != 0) { ctap_reset_key_agreement(); ctap_decrement_pin_attempts(); @@ -1409,11 +1410,12 @@ uint8_t ctap_add_pin_if_verified(uint8_t * pinTokenEnc, uint8_t * platform_pubke crypto_aes256_decrypt(pinHashEnc, 16); + uint8_t pinHashEncSalted[32]; crypto_sha256_init(); crypto_sha256_update(pinHashEnc, 16); crypto_sha256_update(STATE.PIN_SALT, sizeof(STATE.PIN_SALT)); - crypto_sha256_final(pinHashEnc); - if (memcmp(pinHashEnc, STATE.PIN_CODE_HASH, 16) != 0) + crypto_sha256_final(pinHashEncSalted); + if (memcmp(pinHashEncSalted, STATE.PIN_CODE_HASH, 16) != 0) { printf2(TAG_ERR,"Pin does not match!\n"); printf2(TAG_ERR,"platform-pin-hash: "); dump_hex1(TAG_ERR, pinHashEnc, 16); From 8e3753e71116b331084af142010bc5f45dbcab17 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Tue, 20 Aug 2019 11:31:09 +0200 Subject: [PATCH 09/13] Add initial STATE migration code (2) --- fido2/ctap.c | 4 ++++ fido2/data_migration.c | 3 +++ fido2/storage.h | 19 ++++++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/fido2/ctap.c b/fido2/ctap.c index 9081149..29d1006 100644 --- a/fido2/ctap.c +++ b/fido2/ctap.c @@ -25,6 +25,7 @@ #include "extensions.h" #include "device.h" +#include "data_migration.h" uint8_t PIN_TOKEN[PIN_TOKEN_SIZE]; uint8_t KEY_AGREEMENT_PUB[64]; @@ -1725,6 +1726,7 @@ static void ctap_state_init() STATE.remaining_tries = PIN_LOCKOUT_ATTEMPTS; STATE.is_pin_set = 0; STATE.rk_stored = 0; + STATE.data_version = STATE_VERSION; ctap_reset_rk(); @@ -1768,6 +1770,8 @@ void ctap_init() } } + do_migration_if_required(&STATE); + crypto_load_master_secret(STATE.key_space); if (ctap_is_pin_set()) diff --git a/fido2/data_migration.c b/fido2/data_migration.c index e4cbcf1..1228bb1 100644 --- a/fido2/data_migration.c +++ b/fido2/data_migration.c @@ -81,6 +81,9 @@ void do_migration_if_required(AuthenticatorState* state_current){ dump_hex1(TAG_ERR, (void*)&state_previous, sizeof(state_previous)); save_migrated_state(&state_tmp); } + + assert(state_current->data_version == STATE_VERSION); + return_cleanup: memset(&state_tmp, 0, sizeof(AuthenticatorState)); memset(&state_previous, 0, sizeof(AuthenticatorState)); diff --git a/fido2/storage.h b/fido2/storage.h index 6432229..a014e0e 100644 --- a/fido2/storage.h +++ b/fido2/storage.h @@ -12,6 +12,7 @@ #define KEY_SPACE_BYTES 128 #define MAX_KEYS (1) #define PIN_SALT_LEN (32) +#define STATE_VERSION (1) #define BACKUP_MARKER 0x5A @@ -21,6 +22,22 @@ #define ERR_KEY_SPACE_TAKEN (-2) #define ERR_KEY_SPACE_EMPTY (-2) +typedef struct +{ + // Pin information + uint8_t is_initialized; + uint8_t is_pin_set; + uint8_t pin_code[NEW_PIN_ENC_MIN_SIZE]; + int pin_code_length; + int8_t remaining_tries; + + uint16_t rk_stored; + + uint16_t key_lens[MAX_KEYS]; + uint8_t key_space[KEY_SPACE_BYTES]; +} AuthenticatorState_0xFF; + + typedef struct { // Pin information @@ -28,7 +45,7 @@ typedef struct uint8_t is_pin_set; uint8_t PIN_CODE_HASH[32]; uint8_t PIN_SALT[PIN_SALT_LEN]; - int _reserved_pin_code_length; + int _reserved; int8_t remaining_tries; uint16_t rk_stored; From 7f82233d17dcb97110d9da4b0062c60f02d60b3d Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Tue, 20 Aug 2019 11:38:29 +0200 Subject: [PATCH 10/13] Add missing unit for firmware compilation --- targets/stm32l432/build/application.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/targets/stm32l432/build/application.mk b/targets/stm32l432/build/application.mk index 848887f..cda3519 100644 --- a/targets/stm32l432/build/application.mk +++ b/targets/stm32l432/build/application.mk @@ -10,6 +10,7 @@ SRC += $(DRIVER_LIBS) $(USB_LIB) SRC += ../../fido2/apdu.c ../../fido2/util.c ../../fido2/u2f.c ../../fido2/test_power.c SRC += ../../fido2/stubs.c ../../fido2/log.c ../../fido2/ctaphid.c ../../fido2/ctap.c SRC += ../../fido2/ctap_parse.c ../../fido2/main.c +SRC += ../../fido2/data_migration.c SRC += ../../fido2/extensions/extensions.c ../../fido2/extensions/solo.c SRC += ../../fido2/extensions/wallet.c From b452e3dfe4e92b11c5bf9b0a09960c8d47766b24 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Tue, 20 Aug 2019 11:47:14 +0200 Subject: [PATCH 11/13] Correct doc --- fido2/ctap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fido2/ctap.c b/fido2/ctap.c index 29d1006..1c1f1c7 100644 --- a/fido2/ctap.c +++ b/fido2/ctap.c @@ -1812,7 +1812,7 @@ uint8_t ctap_is_pin_set() /** * Set new PIN, by updating PIN hash. Save state. - * Globals: PIN_CODE_HASH STATE + * Globals: STATE * @param pin new PIN (raw) * @param len pin array length */ From 5a0cc0d02c81b8797360078985ad9cc6eafa7928 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Tue, 20 Aug 2019 11:57:32 +0200 Subject: [PATCH 12/13] Version used STATE data structures --- fido2/data_migration.c | 8 +++----- fido2/storage.h | 4 +++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fido2/data_migration.c b/fido2/data_migration.c index 1228bb1..d525b8c 100644 --- a/fido2/data_migration.c +++ b/fido2/data_migration.c @@ -14,15 +14,13 @@ #define check(x) assert(state_prev_0xff->x == state_tmp_ptr->x); #define check_buf(x) assert(memcmp(state_prev_0xff->x, state_tmp_ptr->x, sizeof(state_tmp_ptr->x)) == 0); -bool migrate_from_FF_to_01(AuthenticatorState* state_previous_ptr, AuthenticatorState* state_tmp_ptr){ +bool migrate_from_FF_to_01(AuthenticatorState_0xFF* state_prev_0xff, AuthenticatorState_0x01* state_tmp_ptr){ // Calculate PIN hash, and replace PIN raw storage with it; add version to structure // other ingredients do not change if (state_tmp_ptr->data_version != 0xFF) return false; - static_assert(sizeof(AuthenticatorState_0xFF) <= sizeof(AuthenticatorState), "New state structure is smaller, than current one, which is not handled"); - - AuthenticatorState_0xFF* state_prev_0xff = (AuthenticatorState_0xFF *) state_previous_ptr; + static_assert(sizeof(AuthenticatorState_0xFF) <= sizeof(AuthenticatorState_0x01), "New state structure is smaller, than current one, which is not handled"); if (ctap_generate_rng(state_tmp_ptr->PIN_SALT, sizeof(state_tmp_ptr->PIN_SALT)) != 1) { printf2(TAG_ERR, "Error, rng failed\n"); @@ -71,7 +69,7 @@ void do_migration_if_required(AuthenticatorState* state_current){ authenticator_read_state(&state_tmp); if(state_current->data_version == 0xFF){ printf2(TAG_ERR, "Running migration\n"); - bool success = migrate_from_FF_to_01(&state_previous, &state_tmp); + bool success = migrate_from_FF_to_01((AuthenticatorState_0xFF *) &state_previous, &state_tmp); if (!success){ printf2(TAG_ERR, "Failed migration from 0xFF to 1\n"); // FIXME discuss migration failure behavior diff --git a/fido2/storage.h b/fido2/storage.h index a014e0e..271e234 100644 --- a/fido2/storage.h +++ b/fido2/storage.h @@ -53,7 +53,9 @@ typedef struct uint16_t key_lens[MAX_KEYS]; uint8_t key_space[KEY_SPACE_BYTES]; uint8_t data_version; -} AuthenticatorState; +} AuthenticatorState_0x01; + +typedef AuthenticatorState_0x01 AuthenticatorState; typedef struct From a5877f518f759d7d33466816dec41d51744de69d Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Tue, 20 Aug 2019 12:42:46 +0200 Subject: [PATCH 13/13] Additional assertions and reordering --- fido2/data_migration.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fido2/data_migration.c b/fido2/data_migration.c index d525b8c..cb21e14 100644 --- a/fido2/data_migration.c +++ b/fido2/data_migration.c @@ -39,14 +39,17 @@ bool migrate_from_FF_to_01(AuthenticatorState_0xFF* state_prev_0xff, Authenticat crypto_sha256_final(state_tmp_ptr->PIN_CODE_HASH); } + assert(state_tmp_ptr->_reserved == state_prev_0xff->pin_code_length); state_tmp_ptr->_reserved = 0xFF; state_tmp_ptr->data_version = 1; + check(is_initialized); check(is_pin_set); - check(rk_stored); check(remaining_tries); + check(rk_stored); check_buf(key_lens); check_buf(key_space); + assert(state_tmp_ptr->data_version != 0xFF); return true; }