From 2799311b639d07ad460f6699149c13921f38bfa0 Mon Sep 17 00:00:00 2001 From: Vaibhav Sethia Date: Sat, 24 Aug 2024 14:22:34 +0530 Subject: [PATCH 1/9] feat(app): Add seed based wallet auth --- .../inheritance_app/inheritance_auth_wallet.c | 52 +++++++++++++------ apps/inheritance_app/inheritance_priv.h | 1 + common/cypherock-common | 2 +- src/wallet/reconstruct_wallet_flow.c | 25 +++++++++ src/wallet/reconstruct_wallet_flow.h | 4 ++ 5 files changed, 66 insertions(+), 18 deletions(-) diff --git a/apps/inheritance_app/inheritance_auth_wallet.c b/apps/inheritance_app/inheritance_auth_wallet.c index 59c72d5ac..fe1046dd1 100644 --- a/apps/inheritance_app/inheritance_auth_wallet.c +++ b/apps/inheritance_app/inheritance_auth_wallet.c @@ -118,32 +118,49 @@ static bool verify_auth_wallet_inputs() { } static bool auth_wallet_get_entropy() { - secure_data_t msgs[1] = {0}; - msgs[0].plain_data_size = WALLET_ID_SIZE; - memcpy(msgs[0].plain_data, auth->wallet_id, WALLET_ID_SIZE); - - card_error_type_e status = card_fetch_encrypt_data(auth->wallet_id, msgs, 1); - - delay_scr_init(ui_text_inheritance_wallet_authenticating, DELAY_SHORT); - - if (status != CARD_OPERATION_SUCCESS || - msgs[0].encrypted_data_size > ENTROPY_SIZE_LIMIT) { - return false; + if (!auth->is_seed_based) { + secure_data_t msgs[1] = {0}; + msgs[0].plain_data_size = WALLET_ID_SIZE; + memcpy(msgs[0].plain_data, auth->wallet_id, WALLET_ID_SIZE); + + card_error_type_e status = + card_fetch_encrypt_data(auth->wallet_id, msgs, 1); + if (status != CARD_OPERATION_SUCCESS || + msgs[0].encrypted_data_size > ENTROPY_SIZE_LIMIT) { + inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, + ERROR_DATA_FLOW_INVALID_DATA); + delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME); + return false; + } + memcpy((void *)auth->entropy, + msgs[0].encrypted_data, + msgs[0].encrypted_data_size); + auth->entropy_size = msgs[0].encrypted_data_size; + } else { + uint8_t seed[64] = {0}; + if (!reconstruct_seed_without_passphrase( + auth->wallet_id, seed, inheritance_send_error)) { + memzero(seed, sizeof(seed)); + inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, + ERROR_DATA_FLOW_INVALID_QUERY); + delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME); + return false; + } + memcpy((void *)auth->entropy, seed, 64); + auth->entropy_size = 64; + memzero(seed, sizeof(seed)); } + delay_scr_init(ui_text_inheritance_wallet_authenticating, DELAY_SHORT); set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_CARD_TAPPED); - memcpy((void *)auth->entropy, - msgs[0].encrypted_data, - msgs[0].encrypted_data_size); - auth->entropy_size = msgs[0].encrypted_data_size; - return true; } static bool auth_wallet_get_pairs() { mnemonic_to_seed((char *)auth->entropy, "", auth->private_key, NULL); ed25519_publickey(auth->private_key, auth->public_key); - + // Clear seed as soon as it is not needed + memzero((void *const)auth->entropy, sizeof(auth->entropy)); return true; } @@ -206,6 +223,7 @@ void inheritance_auth_wallet(inheritance_query_t *query) { query->auth_wallet.initiate.challenge.bytes, auth->challenge_size); auth->is_setup = query->auth_wallet.initiate.is_public_key; + auth->is_seed_based = query->auth_wallet.initiate.is_seed_based; set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_INIT); if (verify_auth_wallet_inputs() && auth_wallet_get_entropy() && diff --git a/apps/inheritance_app/inheritance_priv.h b/apps/inheritance_app/inheritance_priv.h index 1c7fa8171..c7ca48767 100644 --- a/apps/inheritance_app/inheritance_priv.h +++ b/apps/inheritance_app/inheritance_priv.h @@ -51,6 +51,7 @@ typedef struct { ed25519_public_key public_key; bool is_setup; + bool is_seed_based; auth_wallet_error_type_e status; } auth_wallet_config_t; #pragma pack(pop) diff --git a/common/cypherock-common b/common/cypherock-common index 69f7a9056..ba58231e1 160000 --- a/common/cypherock-common +++ b/common/cypherock-common @@ -1 +1 @@ -Subproject commit 69f7a9056270947b1e3ab03c911afe2eab452c2a +Subproject commit ba58231e123b1d4e0d20e4666b945ab2a2b0de71 diff --git a/src/wallet/reconstruct_wallet_flow.c b/src/wallet/reconstruct_wallet_flow.c index 72231c01c..79161c250 100644 --- a/src/wallet/reconstruct_wallet_flow.c +++ b/src/wallet/reconstruct_wallet_flow.c @@ -379,6 +379,31 @@ static const char *reconstruct_wallet(const uint8_t *wallet_id, /***************************************************************************** * GLOBAL FUNCTIONS *****************************************************************************/ +bool reconstruct_seed_without_passphrase(const uint8_t *wallet_id, + uint8_t *seed_out, + rejection_cb *reject_cb) { + if ((NULL == wallet_id) || (NULL == seed_out)) { + return false; + } + + uint8_t result = false; + + clear_wallet_data(); + mnemonic_clear(); + + const char *mnemonics = reconstruct_wallet(wallet_id, PIN_INPUT, reject_cb); + + if (NULL != mnemonics) { + mnemonic_to_seed( + mnemonics, wallet_credential_data.passphrase, seed_out, NULL); + result = true; + } + + mnemonic_clear(); + clear_wallet_data(); + return result; +} + bool reconstruct_seed(const uint8_t *wallet_id, uint8_t *seed_out, rejection_cb *reject_cb) { diff --git a/src/wallet/reconstruct_wallet_flow.h b/src/wallet/reconstruct_wallet_flow.h index e35636f9b..7fe11f712 100644 --- a/src/wallet/reconstruct_wallet_flow.h +++ b/src/wallet/reconstruct_wallet_flow.h @@ -68,4 +68,8 @@ bool reconstruct_seed(const uint8_t *wallet_id, uint8_t reconstruct_mnemonics( const uint8_t *wallet_id, char mnemonic_list[MAX_NUMBER_OF_MNEMONIC_WORDS][MAX_MNEMONIC_WORD_LENGTH]); + +bool reconstruct_seed_without_passphrase(const uint8_t *wallet_id, + uint8_t *seed_out, + rejection_cb *reject_cb); #endif /* RECONSTRUCT_SEED_FLOW_H */ From 84ce353c9dda596eeb31d474714c146a2f958859 Mon Sep 17 00:00:00 2001 From: Vaibhav Sethia Date: Mon, 26 Aug 2024 16:36:18 +0530 Subject: [PATCH 2/9] chore(app): Submodule commit --- common/cypherock-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/cypherock-common b/common/cypherock-common index ba58231e1..1a1668d96 160000 --- a/common/cypherock-common +++ b/common/cypherock-common @@ -1 +1 @@ -Subproject commit ba58231e123b1d4e0d20e4666b945ab2a2b0de71 +Subproject commit 1a1668d966e0a43da4e291d2b840c0112a9dffd4 From 38aad23179f4c04549e9fb933f4369aed283cb30 Mon Sep 17 00:00:00 2001 From: Vaibhav Sethia Date: Thu, 29 Aug 2024 01:06:22 +0530 Subject: [PATCH 3/9] fix(app): Update seed based auth flow --- .../inheritance_app/inheritance_auth_wallet.c | 192 ++++++++++++------ apps/inheritance_app/inheritance_priv.h | 24 ++- common/cypherock-common | 2 +- .../inheritance/auth_wallet.options | 4 +- 4 files changed, 152 insertions(+), 70 deletions(-) diff --git a/apps/inheritance_app/inheritance_auth_wallet.c b/apps/inheritance_app/inheritance_auth_wallet.c index fe1046dd1..145585a81 100644 --- a/apps/inheritance_app/inheritance_auth_wallet.c +++ b/apps/inheritance_app/inheritance_auth_wallet.c @@ -21,13 +21,10 @@ #include "card_fetch_data.h" #include "inheritance/core.pb.h" #include "inheritance_api.h" -#include "inheritance_main.h" #include "inheritance_priv.h" -#include "nfc.h" #include "reconstruct_wallet_flow.h" #include "status_api.h" -#include "ui_core_confirm.h" -#include "ui_screens.h" +#include "ui_delay.h" /***************************************************************************** * EXTERN VARIABLES @@ -87,6 +84,21 @@ static bool auth_wallet_get_entropy(); */ static bool auth_wallet_get_pairs(); +/** + * @brief Signs the given challenge. + * + * The function generates an Ed25519 signature for the provided challenge + * and verifies it against the public key. + * + * @return true if the signature is successfully created and verified, false + * otherwise. + */ +static bool auth_wallet_sign_challenge(const uint8_t *unsigned_txn, + const size_t unsigned_txn_size, + const ed25519_secret_key private_key, + const ed25519_public_key public_key, + ed25519_signature signature); + /** * @brief Generates and verifies a digital signature for the wallet * authentication. @@ -105,9 +117,10 @@ static bool auth_wallet_get_signature(); *****************************************************************************/ static bool verify_auth_wallet_inputs() { - if (NULL == auth->challenge || NULL == auth->wallet_id || - auth->challenge_size < CHALLENGE_SIZE_MIN || - auth->challenge_size > CHALLENGE_SIZE_MAX) { + if (auth->data.challenge_size == 0 || + auth->data.challenge_size < CHALLENGE_SIZE_MIN || + auth->data.challenge_size > CHALLENGE_SIZE_MAX || + (auth->do_wallet_based == false && auth->do_seed_based == false)) { inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, ERROR_DATA_FLOW_INVALID_QUERY); delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME); @@ -118,13 +131,30 @@ static bool verify_auth_wallet_inputs() { } static bool auth_wallet_get_entropy() { - if (!auth->is_seed_based) { + if (auth->do_seed_based) { + uint8_t seed[SIZE_SEED] = {0}; + if (!reconstruct_seed_without_passphrase( + auth->data.wallet_id, seed, inheritance_send_error)) { + memzero(seed, sizeof(seed)); + inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, + ERROR_DATA_FLOW_INVALID_QUERY); + delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME); + return false; + } + memcpy((void *)auth->seed_based_data.entropy, seed, SIZE_SEED); + auth->seed_based_data.entropy_size = SIZE_SEED; + auth->seed_based_data.has_data = true; + memzero(seed, sizeof(seed)); + // seed generation complete + set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_SEED_BASED_COMPLETED); + } + if (auth->do_wallet_based) { secure_data_t msgs[1] = {0}; msgs[0].plain_data_size = WALLET_ID_SIZE; - memcpy(msgs[0].plain_data, auth->wallet_id, WALLET_ID_SIZE); + memcpy(msgs[0].plain_data, auth->data.wallet_id, WALLET_ID_SIZE); card_error_type_e status = - card_fetch_encrypt_data(auth->wallet_id, msgs, 1); + card_fetch_encrypt_data(auth->data.wallet_id, msgs, 1); if (status != CARD_OPERATION_SUCCESS || msgs[0].encrypted_data_size > ENTROPY_SIZE_LIMIT) { inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, @@ -132,53 +162,52 @@ static bool auth_wallet_get_entropy() { delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME); return false; } - memcpy((void *)auth->entropy, + memcpy((void *)auth->wallet_based_data.entropy, msgs[0].encrypted_data, msgs[0].encrypted_data_size); - auth->entropy_size = msgs[0].encrypted_data_size; - } else { - uint8_t seed[64] = {0}; - if (!reconstruct_seed_without_passphrase( - auth->wallet_id, seed, inheritance_send_error)) { - memzero(seed, sizeof(seed)); - inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, - ERROR_DATA_FLOW_INVALID_QUERY); - delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME); - return false; - } - memcpy((void *)auth->entropy, seed, 64); - auth->entropy_size = 64; - memzero(seed, sizeof(seed)); + auth->wallet_based_data.entropy_size = msgs[0].encrypted_data_size; + auth->wallet_based_data.has_data = true; + // wallet id encryption complete + set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_WALLET_BASED_COMPLETED); } + delay_scr_init(ui_text_inheritance_wallet_authenticating, DELAY_SHORT); - set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_CARD_TAPPED); return true; } static bool auth_wallet_get_pairs() { - mnemonic_to_seed((char *)auth->entropy, "", auth->private_key, NULL); - ed25519_publickey(auth->private_key, auth->public_key); - // Clear seed as soon as it is not needed - memzero((void *const)auth->entropy, sizeof(auth->entropy)); + if (auth->seed_based_data.has_data) { + mnemonic_to_seed((char *)auth->seed_based_data.entropy, + "", + auth->seed_based_data.private_key, + NULL); + ed25519_publickey(auth->seed_based_data.private_key, + auth->seed_based_data.result.public_key); + // Clear seed as soon as it is not needed + memzero((void *const)auth->seed_based_data.entropy, + sizeof(auth->seed_based_data.entropy)); + } + if (auth->wallet_based_data.has_data) { + mnemonic_to_seed((char *)auth->wallet_based_data.entropy, + "", + auth->wallet_based_data.private_key, + NULL); + ed25519_publickey(auth->wallet_based_data.private_key, + auth->wallet_based_data.result.public_key); + } return true; } +static bool auth_wallet_sign_challenge(const uint8_t *unsigned_txn, + const size_t unsigned_txn_size, + const ed25519_secret_key private_key, + const ed25519_public_key public_key, + ed25519_signature signature) { + ed25519_sign( + unsigned_txn, unsigned_txn_size, private_key, public_key, signature); -static bool auth_wallet_get_signature() { - const size_t unsigned_txn_size = auth->challenge_size + WALLET_ID_SIZE; - uint8_t unsigned_txn[unsigned_txn_size]; - - memcpy(unsigned_txn, auth->challenge, auth->challenge_size); - memcpy(unsigned_txn + auth->challenge_size, auth->wallet_id, WALLET_ID_SIZE); - - ed25519_sign(unsigned_txn, - unsigned_txn_size, - auth->private_key, - auth->public_key, - auth->signature); - - int valid = ed25519_sign_open( - unsigned_txn, unsigned_txn_size, auth->public_key, auth->signature); + int valid = + ed25519_sign_open(unsigned_txn, unsigned_txn_size, public_key, signature); if (0 != valid) { inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, @@ -186,7 +215,34 @@ static bool auth_wallet_get_signature() { delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME); return false; } + return true; +} +static bool auth_wallet_get_signature() { + const size_t unsigned_txn_size = auth->data.challenge_size + WALLET_ID_SIZE; + uint8_t unsigned_txn[unsigned_txn_size]; + memcpy(unsigned_txn, auth->data.challenge, auth->data.challenge_size); + memcpy(unsigned_txn + auth->data.challenge_size, + auth->data.wallet_id, + WALLET_ID_SIZE); + if (auth->do_seed_based) { + if (!auth_wallet_sign_challenge(unsigned_txn, + unsigned_txn_size, + auth->seed_based_data.private_key, + auth->seed_based_data.result.public_key, + auth->seed_based_data.result.signature)) { + return false; + } + } + if (auth->do_wallet_based) { + if (!auth_wallet_sign_challenge(unsigned_txn, + unsigned_txn_size, + auth->wallet_based_data.private_key, + auth->wallet_based_data.result.public_key, + auth->wallet_based_data.result.signature)) { + return false; + } + } return true; } @@ -195,16 +251,28 @@ static bool send_result() { result.which_response = INHERITANCE_RESULT_AUTH_WALLET_TAG; result.auth_wallet.which_response = INHERITANCE_AUTH_WALLET_RESPONSE_RESULT_TAG; - memcpy(result.auth_wallet.result.signature, - auth->signature, - sizeof(ed25519_signature)); - - if (auth->is_setup) { - memcpy(result.auth_wallet.result.public_key, - auth->public_key, - sizeof(ed25519_public_key)); + if (auth->do_seed_based) { + memcpy(result.auth_wallet.result.seed_based.signature, + auth->seed_based_data.result.signature, + sizeof(ed25519_signature)); + result.auth_wallet.result.has_seed_based = true; + if (auth->with_public_key) { + memcpy(result.auth_wallet.result.seed_based.public_key, + auth->seed_based_data.result.public_key, + sizeof(ed25519_public_key)); + } + } + if (auth->do_wallet_based) { + memcpy(result.auth_wallet.result.wallet_based.signature, + auth->wallet_based_data.result.signature, + sizeof(ed25519_signature)); + result.auth_wallet.result.has_wallet_based = true; + if (auth->with_public_key) { + memcpy(result.auth_wallet.result.wallet_based.public_key, + auth->wallet_based_data.result.public_key, + sizeof(ed25519_public_key)); + } } - inheritance_send_result(&result); return true; } @@ -216,14 +284,16 @@ void inheritance_auth_wallet(inheritance_query_t *query) { auth = (auth_wallet_config_t *)cy_malloc(sizeof(auth_wallet_config_t)); memzero(auth, sizeof(auth_wallet_config_t)); - memcpy( - auth->wallet_id, query->auth_wallet.initiate.wallet_id, WALLET_ID_SIZE); - auth->challenge_size = query->auth_wallet.initiate.challenge.size; - memcpy(auth->challenge, + memcpy(auth->data.wallet_id, + query->auth_wallet.initiate.wallet_id, + WALLET_ID_SIZE); + auth->data.challenge_size = query->auth_wallet.initiate.challenge.size; + memcpy(auth->data.challenge, query->auth_wallet.initiate.challenge.bytes, - auth->challenge_size); - auth->is_setup = query->auth_wallet.initiate.is_public_key; - auth->is_seed_based = query->auth_wallet.initiate.is_seed_based; + auth->data.challenge_size); + auth->with_public_key = query->auth_wallet.initiate.with_public_key; + auth->do_seed_based = query->auth_wallet.initiate.do_seed_based; + auth->do_wallet_based = query->auth_wallet.initiate.do_wallet_based; set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_INIT); if (verify_auth_wallet_inputs() && auth_wallet_get_entropy() && diff --git a/apps/inheritance_app/inheritance_priv.h b/apps/inheritance_app/inheritance_priv.h index c7ca48767..77ff4b532 100644 --- a/apps/inheritance_app/inheritance_priv.h +++ b/apps/inheritance_app/inheritance_priv.h @@ -25,7 +25,7 @@ #define CHALLENGE_SIZE_MAX 32 #define CHALLENGE_SIZE_MIN 16 #define ENTROPY_SIZE_LIMIT 100 - +#define SIZE_SEED 64 /***************************************************************************** * PRIVATE TYPEDEFS *****************************************************************************/ @@ -38,20 +38,32 @@ typedef enum { } auth_wallet_error_type_e; #pragma pack(push, 1) +typedef struct { + ed25519_signature signature; + ed25519_public_key public_key; +} auth_wallet_result_t; + typedef struct { uint8_t wallet_id[WALLET_ID_SIZE]; uint8_t challenge[CHALLENGE_SIZE_MAX]; size_t challenge_size; +} auth_wallet_data_t; +typedef struct { const uint8_t entropy[ENTROPY_SIZE_LIMIT]; uint8_t entropy_size; ed25519_secret_key private_key; + auth_wallet_result_t result; + bool has_data; +} auth_wallet_private_t; - ed25519_signature signature; - ed25519_public_key public_key; - - bool is_setup; - bool is_seed_based; +typedef struct { + auth_wallet_data_t data; + auth_wallet_private_t wallet_based_data; + auth_wallet_private_t seed_based_data; + bool with_public_key; + bool do_seed_based; + bool do_wallet_based; auth_wallet_error_type_e status; } auth_wallet_config_t; #pragma pack(pop) diff --git a/common/cypherock-common b/common/cypherock-common index 1a1668d96..3d3dda5dd 160000 --- a/common/cypherock-common +++ b/common/cypherock-common @@ -1 +1 @@ -Subproject commit 1a1668d966e0a43da4e291d2b840c0112a9dffd4 +Subproject commit 3d3dda5ddb2e138d5894a4d9da6b9577daa396f4 diff --git a/common/proto-options/inheritance/auth_wallet.options b/common/proto-options/inheritance/auth_wallet.options index 01167653e..29a460823 100644 --- a/common/proto-options/inheritance/auth_wallet.options +++ b/common/proto-options/inheritance/auth_wallet.options @@ -1,4 +1,4 @@ inheritance.AuthWalletInitiateRequest.challenge type:FT_STATIC max_size:32 fixed_length:false inheritance.AuthWalletInitiateRequest.wallet_id type:FT_STATIC max_size:32 fixed_length:true -inheritance.AuthWalletResultResponse.public_key type:FT_STATIC max_size:32 fixed_length:true -inheritance.AuthWalletResultResponse.signature type:FT_STATIC max_size:64 fixed_length:true \ No newline at end of file +inheritance.AuthWalletSignatureAndKey.public_key type:FT_STATIC max_size:32 fixed_length:true +inheritance.AuthWalletSignatureAndKey.signature type:FT_STATIC max_size:64 fixed_length:true \ No newline at end of file From 54487c9c8743dde22f4bd3699248452eee2ae6eb Mon Sep 17 00:00:00 2001 From: Vaibhav Sethia Date: Tue, 27 Aug 2024 17:30:18 +0530 Subject: [PATCH 4/9] feat(app): Add single card tap --- .../inheritance_app/inheritance_auth_wallet.c | 14 ++++- common/flash/flash_config.h | 2 +- src/card_operations/card_fetch_encrypt_data.c | 3 ++ src/card_operations/card_operation_typedefs.h | 3 +- src/card_operations/card_pair.c | 52 +++++++++++++++++++ src/card_operations/card_pair.h | 6 +++ 6 files changed, 76 insertions(+), 4 deletions(-) diff --git a/apps/inheritance_app/inheritance_auth_wallet.c b/apps/inheritance_app/inheritance_auth_wallet.c index 95262bda9..889e16ec5 100644 --- a/apps/inheritance_app/inheritance_auth_wallet.c +++ b/apps/inheritance_app/inheritance_auth_wallet.c @@ -19,13 +19,15 @@ #include "bip39.h" #include "card_fetch_data.h" +#include "card_pair.h" #include "inheritance/core.pb.h" #include "inheritance_api.h" #include "inheritance_priv.h" #include "reconstruct_wallet_flow.h" #include "status_api.h" +#include "ui_core_confirm.h" #include "ui_delay.h" - +#include "ui_screens.h" /***************************************************************************** * EXTERN VARIABLES *****************************************************************************/ @@ -152,9 +154,17 @@ static bool auth_wallet_get_entropy() { secure_data_t msgs[1] = {0}; msgs[0].plain_data_size = WALLET_ID_SIZE; memcpy(msgs[0].plain_data, auth->data.wallet_id, WALLET_ID_SIZE); - card_error_type_e status = card_fetch_encrypt_data(auth->data.wallet_id, msgs, 1); + // Pair the card first + if (CARD_OPERATION_UNPAIRED_CARD == status) { + card_error_type_e value = + single_card_pair_operation("Pair Card", "Tap to start"); + if (value != CARD_OPERATION_SUCCESS) { + return false; + } + status = card_fetch_encrypt_data(auth->data.wallet_id, msgs, 1); + } if (status != CARD_OPERATION_SUCCESS || msgs[0].encrypted_data_size > ENTROPY_SIZE_LIMIT) { inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, diff --git a/common/flash/flash_config.h b/common/flash/flash_config.h index 88e98ff29..845e34a91 100644 --- a/common/flash/flash_config.h +++ b/common/flash/flash_config.h @@ -26,7 +26,7 @@ 32 ///< Size of IO protection key (used for encrypted comm b/w MCU and ///< ATECC608A) #define ECDSA_PUB_KEY_SIZE 33 ///< Size of ECDSA (compressed) public key -#define MAX_KEYSTORE_ENTRY 4 ///< Maximum number of keystore entries +#define MAX_KEYSTORE_ENTRY 4 + 1 ///< Maximum number of keystore entries #define FS_KEYSTORE_KEYID_LEN 4 ///< Length of key id in keystore entry #define FS_KEYSTORE_KEYPATH_LEN 8 ///< Length of key path in keystore entry #define FS_KEYSTORE_PRIVKEY_LEN \ diff --git a/src/card_operations/card_fetch_encrypt_data.c b/src/card_operations/card_fetch_encrypt_data.c index 37d85a51d..c59371622 100644 --- a/src/card_operations/card_fetch_encrypt_data.c +++ b/src/card_operations/card_fetch_encrypt_data.c @@ -128,6 +128,9 @@ card_error_type_e card_fetch_encrypt_data(uint8_t *wallet_id, #if USE_SIMULATOR == 0 memcpy(card_data.nfc_data.family_id, get_family_id(), FAMILY_ID_SIZE); result = card_initialize_applet(&card_data); + if (true == card_data.nfc_data.pairing_error) { + result = CARD_OPERATION_UNPAIRED_CARD; + } #endif if (CARD_OPERATION_SUCCESS == card_data.error_type) { diff --git a/src/card_operations/card_operation_typedefs.h b/src/card_operations/card_operation_typedefs.h index 56da849a2..8252fb8eb 100644 --- a/src/card_operations/card_operation_typedefs.h +++ b/src/card_operations/card_operation_typedefs.h @@ -46,7 +46,8 @@ typedef enum card_errors_type { can be associated to @ref card_error_status_word_e errors or PN532 errors */ - + CARD_OPERATION_UNPAIRED_CARD, /** Error indicating failed operation due to + card not being paired*/ CARD_OPERATION_DEFAULT_INVALID = 0xFF, /** Default invalid value */ } card_error_type_e; diff --git a/src/card_operations/card_pair.c b/src/card_operations/card_pair.c index 142511951..9b44fa462 100644 --- a/src/card_operations/card_pair.c +++ b/src/card_operations/card_pair.c @@ -484,6 +484,58 @@ card_error_type_e card_pair_operation(uint8_t card_number, break; } + nfc_deselect_card(); + return card_data.error_type; +} + +card_error_type_e single_card_pair_operation(char *heading, + const char *message) { + // Need to handle how assign new card its number + card_operation_data_t card_data = {0}; + card_pairing_data_t pair_data = {0}; + + if (SUCCESS != pair_card_preprocess(&pair_data)) { + return CARD_OPERATION_ABORT_OPERATION; + } + + instruction_scr_init(message, heading); + card_data.nfc_data.retries = 5; + + while (1) { + // Initialize card tap config + card_data.nfc_data.acceptable_cards = ACCEPTABLE_CARDS_ALL; + + init_and_pair_card(&card_data, &pair_data); + + if (CARD_OPERATION_SUCCESS == card_data.error_type) { + if (SW_NO_ERROR != handle_pairing_success(&card_data, &pair_data)) { + card_data.error_type = CARD_OPERATION_ABORT_OPERATION; + break; + } + + buzzer_start(BUZZER_DURATION); + // if (4 != card_number) { + // wait_for_card_removal(); + // } + // since we are pairing only one card + wait_for_card_removal(); + + break; + } + + if (CARD_OPERATION_CARD_REMOVED == card_data.error_type || + CARD_OPERATION_RETAP_BY_USER_REQUIRED == card_data.error_type) { + const char *error_msg = card_data.error_message; + if (CARD_OPERATION_SUCCESS == indicate_card_error(error_msg)) { + // Re-render the instruction screen + instruction_scr_init(message, heading); + continue; + } + } + + break; + } + nfc_deselect_card(); return card_data.error_type; } \ No newline at end of file diff --git a/src/card_operations/card_pair.h b/src/card_operations/card_pair.h index 23595fe25..d56869368 100644 --- a/src/card_operations/card_pair.h +++ b/src/card_operations/card_pair.h @@ -62,4 +62,10 @@ card_error_type_e card_pair_without_retap(uint8_t card_number, card_error_type_e card_pair_operation(uint8_t card_number, char *heading, const char *message); +// To Improvise: +// Single card pairing operation, +// Should allow single or extra card to be paired if not already, +// for any required flow +card_error_type_e single_card_pair_operation(char *heading, + const char *message); #endif \ No newline at end of file From 90ab1f3a723276861bce22268e1ecaa49ca52169 Mon Sep 17 00:00:00 2001 From: Vaibhav Sethia Date: Tue, 27 Aug 2024 23:34:26 +0530 Subject: [PATCH 5/9] fix(app): Keystore entry --- common/flash/flash_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/flash/flash_config.h b/common/flash/flash_config.h index 845e34a91..88e98ff29 100644 --- a/common/flash/flash_config.h +++ b/common/flash/flash_config.h @@ -26,7 +26,7 @@ 32 ///< Size of IO protection key (used for encrypted comm b/w MCU and ///< ATECC608A) #define ECDSA_PUB_KEY_SIZE 33 ///< Size of ECDSA (compressed) public key -#define MAX_KEYSTORE_ENTRY 4 + 1 ///< Maximum number of keystore entries +#define MAX_KEYSTORE_ENTRY 4 ///< Maximum number of keystore entries #define FS_KEYSTORE_KEYID_LEN 4 ///< Length of key id in keystore entry #define FS_KEYSTORE_KEYPATH_LEN 8 ///< Length of key path in keystore entry #define FS_KEYSTORE_PRIVKEY_LEN \ From a882a8eb53ac9dae5f82baf611654deb8fc04a3d Mon Sep 17 00:00:00 2001 From: Vaibhav Sethia Date: Thu, 29 Aug 2024 13:53:10 +0530 Subject: [PATCH 6/9] feat(app): Add compulsory pair operation --- .../inheritance_app/inheritance_auth_wallet.c | 26 +++++++++---------- src/card_operations/card_fetch_encrypt_data.c | 3 --- src/card_operations/card_operation_typedefs.h | 2 -- src/constant_texts.c | 1 + src/constant_texts.h | 1 + 5 files changed, 14 insertions(+), 19 deletions(-) diff --git a/apps/inheritance_app/inheritance_auth_wallet.c b/apps/inheritance_app/inheritance_auth_wallet.c index 889e16ec5..1f681ead4 100644 --- a/apps/inheritance_app/inheritance_auth_wallet.c +++ b/apps/inheritance_app/inheritance_auth_wallet.c @@ -20,14 +20,13 @@ #include "bip39.h" #include "card_fetch_data.h" #include "card_pair.h" +#include "core_error.h" #include "inheritance/core.pb.h" #include "inheritance_api.h" #include "inheritance_priv.h" #include "reconstruct_wallet_flow.h" #include "status_api.h" -#include "ui_core_confirm.h" #include "ui_delay.h" -#include "ui_screens.h" /***************************************************************************** * EXTERN VARIABLES *****************************************************************************/ @@ -128,7 +127,6 @@ static bool verify_auth_wallet_inputs() { delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME); return false; } - return true; } @@ -151,20 +149,20 @@ static bool auth_wallet_get_entropy() { set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_SEED_BASED_COMPLETED); } if (auth->do_wallet_based) { + // Pair the card first + card_error_type_e status = single_card_pair_operation( + (char *)ui_text_tap_the_card, ui_text_place_card_below); + if (status != CARD_OPERATION_SUCCESS) { + inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, + ERROR_DATA_FLOW_INVALID_DATA); + delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME); + return false; + } secure_data_t msgs[1] = {0}; msgs[0].plain_data_size = WALLET_ID_SIZE; memcpy(msgs[0].plain_data, auth->data.wallet_id, WALLET_ID_SIZE); - card_error_type_e status = - card_fetch_encrypt_data(auth->data.wallet_id, msgs, 1); - // Pair the card first - if (CARD_OPERATION_UNPAIRED_CARD == status) { - card_error_type_e value = - single_card_pair_operation("Pair Card", "Tap to start"); - if (value != CARD_OPERATION_SUCCESS) { - return false; - } - status = card_fetch_encrypt_data(auth->data.wallet_id, msgs, 1); - } + // fetch encrypted wallet_id + status = card_fetch_encrypt_data(auth->data.wallet_id, msgs, 1); if (status != CARD_OPERATION_SUCCESS || msgs[0].encrypted_data_size > ENTROPY_SIZE_LIMIT) { inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, diff --git a/src/card_operations/card_fetch_encrypt_data.c b/src/card_operations/card_fetch_encrypt_data.c index c59371622..37d85a51d 100644 --- a/src/card_operations/card_fetch_encrypt_data.c +++ b/src/card_operations/card_fetch_encrypt_data.c @@ -128,9 +128,6 @@ card_error_type_e card_fetch_encrypt_data(uint8_t *wallet_id, #if USE_SIMULATOR == 0 memcpy(card_data.nfc_data.family_id, get_family_id(), FAMILY_ID_SIZE); result = card_initialize_applet(&card_data); - if (true == card_data.nfc_data.pairing_error) { - result = CARD_OPERATION_UNPAIRED_CARD; - } #endif if (CARD_OPERATION_SUCCESS == card_data.error_type) { diff --git a/src/card_operations/card_operation_typedefs.h b/src/card_operations/card_operation_typedefs.h index 8252fb8eb..d0c1c6659 100644 --- a/src/card_operations/card_operation_typedefs.h +++ b/src/card_operations/card_operation_typedefs.h @@ -46,8 +46,6 @@ typedef enum card_errors_type { can be associated to @ref card_error_status_word_e errors or PN532 errors */ - CARD_OPERATION_UNPAIRED_CARD, /** Error indicating failed operation due to - card not being paired*/ CARD_OPERATION_DEFAULT_INVALID = 0xFF, /** Default invalid value */ } card_error_type_e; diff --git a/src/constant_texts.c b/src/constant_texts.c index c56b6be3f..9c6e98219 100644 --- a/src/constant_texts.c +++ b/src/constant_texts.c @@ -536,6 +536,7 @@ const char *ui_text_inheritance_wallet_auth_success = "Wallet\nauthentication\nsuccessfully"; const char *ui_text_inheritance_wallet_auth_fail = "Wallet\nauthentication\nfailed"; +const char *ui_text_tap_the_card = "Tap the card"; #ifdef ALLOW_LOG_EXPORT const char *ui_text_send_logs_prompt = "Send logs to the cySync app?"; diff --git a/src/constant_texts.h b/src/constant_texts.h index 47eabf581..09a926129 100644 --- a/src/constant_texts.h +++ b/src/constant_texts.h @@ -376,6 +376,7 @@ extern const char *ui_critical_card_health_migrate_data; extern const char *ui_text_inheritance_wallet_authenticating; extern const char *ui_text_inheritance_wallet_auth_success; extern const char *ui_text_inheritance_wallet_auth_fail; +extern const char *ui_text_tap_the_card; #ifdef ALLOW_LOG_EXPORT extern const char *ui_text_send_logs_prompt; From 54a7719fef82f4741e990777253d8ae2f5edc425 Mon Sep 17 00:00:00 2001 From: Vaibhav Sethia Date: Thu, 29 Aug 2024 15:51:32 +0530 Subject: [PATCH 7/9] feat(app): Add pairing status update --- apps/inheritance_app/inheritance_auth_wallet.c | 7 +++++-- common/cypherock-common | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/inheritance_app/inheritance_auth_wallet.c b/apps/inheritance_app/inheritance_auth_wallet.c index 1f681ead4..6af2a6b5e 100644 --- a/apps/inheritance_app/inheritance_auth_wallet.c +++ b/apps/inheritance_app/inheritance_auth_wallet.c @@ -146,7 +146,7 @@ static bool auth_wallet_get_entropy() { auth->seed_based_data.has_data = true; memzero(seed, sizeof(seed)); // seed generation complete - set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_SEED_BASED_COMPLETED); + set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_SEED_BASED_CARD_TAPPED); } if (auth->do_wallet_based) { // Pair the card first @@ -158,6 +158,8 @@ static bool auth_wallet_get_entropy() { delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME); return false; } + set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_PAIRING_CARD_TAPPED); + secure_data_t msgs[1] = {0}; msgs[0].plain_data_size = WALLET_ID_SIZE; memcpy(msgs[0].plain_data, auth->data.wallet_id, WALLET_ID_SIZE); @@ -176,7 +178,8 @@ static bool auth_wallet_get_entropy() { auth->wallet_based_data.entropy_size = msgs[0].encrypted_data_size; auth->wallet_based_data.has_data = true; // wallet id encryption complete - set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_WALLET_BASED_COMPLETED); + set_app_flow_status( + INHERITANCE_AUTH_WALLET_STATUS_WALLET_BASED_CARD_TAPPED); } delay_scr_init(ui_text_inheritance_wallet_authenticating, DELAY_SHORT); diff --git a/common/cypherock-common b/common/cypherock-common index 3d3dda5dd..cdb6c5353 160000 --- a/common/cypherock-common +++ b/common/cypherock-common @@ -1 +1 @@ -Subproject commit 3d3dda5ddb2e138d5894a4d9da6b9577daa396f4 +Subproject commit cdb6c53530369f011775525dddcc536d49503f29 From 3f5020a39be374d28942356aa4f4e850e49bd391 Mon Sep 17 00:00:00 2001 From: Vaibhav Sethia Date: Thu, 29 Aug 2024 23:18:07 +0530 Subject: [PATCH 8/9] chore: Review changes --- .../inheritance_app/inheritance_auth_wallet.c | 83 ++++++++++++++----- src/card_operations/card_pair.c | 4 - 2 files changed, 61 insertions(+), 26 deletions(-) diff --git a/apps/inheritance_app/inheritance_auth_wallet.c b/apps/inheritance_app/inheritance_auth_wallet.c index 6af2a6b5e..f0ab2ef19 100644 --- a/apps/inheritance_app/inheritance_auth_wallet.c +++ b/apps/inheritance_app/inheritance_auth_wallet.c @@ -61,8 +61,39 @@ static auth_wallet_config_t *auth = NULL; static bool verify_auth_wallet_inputs(); /** - * @brief Retrieves encrypted data (entropy) from the card based on the wallet - * ID. + * @brief Retrieves and stores seed-based entropy for authentication. + * + * Generates entropy from the seed based on the wallet ID and stores it in the + * auth structure. + * + * @return true if seed-based entropy is successfully generated and stored, + * false otherwise. + */ +static bool auth_wallet_get_seed_entropy(); + +/** + * @brief Pairs the card with the device. + * + * Initiates the card pairing process and updates the app flow status upon + * success. + * + * @return true if the card is successfully paired, false otherwise. + */ +static bool auth_wallet_pair_card(); + +/** + * @brief Retrieves and stores wallet-based entropy from the card. + * + * Fetches encrypted wallet ID data from the card to generate entropy. + * + * @return true if wallet-based entropy is successfully fetched and stored, + * false otherwise. + */ +static bool auth_wallet_get_wallet_entropy(); + +/** + * @brief Retrieves encrypted data (entropy) from the card based on the type + * requested from the host (seed based and/or wallet_id based) * * This function initializes a secure_data_t structure, fetches encrypted data * from the card, and stores the result in the auth structure. It checks if the @@ -130,15 +161,12 @@ static bool verify_auth_wallet_inputs() { return true; } -static bool auth_wallet_get_entropy() { +static bool auth_wallet_get_seed_entropy() { if (auth->do_seed_based) { uint8_t seed[SIZE_SEED] = {0}; if (!reconstruct_seed_without_passphrase( auth->data.wallet_id, seed, inheritance_send_error)) { memzero(seed, sizeof(seed)); - inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, - ERROR_DATA_FLOW_INVALID_QUERY); - delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME); return false; } memcpy((void *)auth->seed_based_data.entropy, seed, SIZE_SEED); @@ -148,28 +176,30 @@ static bool auth_wallet_get_entropy() { // seed generation complete set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_SEED_BASED_CARD_TAPPED); } - if (auth->do_wallet_based) { - // Pair the card first - card_error_type_e status = single_card_pair_operation( - (char *)ui_text_tap_the_card, ui_text_place_card_below); - if (status != CARD_OPERATION_SUCCESS) { - inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, - ERROR_DATA_FLOW_INVALID_DATA); - delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME); - return false; - } - set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_PAIRING_CARD_TAPPED); + return true; +} +static bool auth_wallet_pair_card() { + // Pair the card first + card_error_type_e status = single_card_pair_operation( + (char *)ui_text_tap_the_card, ui_text_place_card_below); + if (status != CARD_OPERATION_SUCCESS) { + return false; + } + set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_PAIRING_CARD_TAPPED); + return true; +} + +static bool auth_wallet_get_wallet_entropy() { + if (auth->do_wallet_based) { secure_data_t msgs[1] = {0}; msgs[0].plain_data_size = WALLET_ID_SIZE; memcpy(msgs[0].plain_data, auth->data.wallet_id, WALLET_ID_SIZE); // fetch encrypted wallet_id - status = card_fetch_encrypt_data(auth->data.wallet_id, msgs, 1); + card_error_type_e status = + card_fetch_encrypt_data(auth->data.wallet_id, msgs, 1); if (status != CARD_OPERATION_SUCCESS || msgs[0].encrypted_data_size > ENTROPY_SIZE_LIMIT) { - inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, - ERROR_DATA_FLOW_INVALID_DATA); - delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME); return false; } memcpy((void *)auth->wallet_based_data.entropy, @@ -181,9 +211,18 @@ static bool auth_wallet_get_entropy() { set_app_flow_status( INHERITANCE_AUTH_WALLET_STATUS_WALLET_BASED_CARD_TAPPED); } + return true; +} +static bool auth_wallet_get_entropy() { + if (!auth_wallet_get_seed_entropy() || !auth_wallet_pair_card() || + !auth_wallet_get_wallet_entropy()) { + inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, + ERROR_DATA_FLOW_INVALID_DATA); + delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME); + return false; + } delay_scr_init(ui_text_inheritance_wallet_authenticating, DELAY_SHORT); - return true; } diff --git a/src/card_operations/card_pair.c b/src/card_operations/card_pair.c index 9b44fa462..91f2b4307 100644 --- a/src/card_operations/card_pair.c +++ b/src/card_operations/card_pair.c @@ -514,10 +514,6 @@ card_error_type_e single_card_pair_operation(char *heading, } buzzer_start(BUZZER_DURATION); - // if (4 != card_number) { - // wait_for_card_removal(); - // } - // since we are pairing only one card wait_for_card_removal(); break; From 8f4a09c44a766298e6f91a9c93f6faaef94049c0 Mon Sep 17 00:00:00 2001 From: TejasvOnly Date: Fri, 30 Aug 2024 05:08:49 -0700 Subject: [PATCH 9/9] chore: Update submodule --- common/cypherock-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/cypherock-common b/common/cypherock-common index cdb6c5353..6196089ec 160000 --- a/common/cypherock-common +++ b/common/cypherock-common @@ -1 +1 @@ -Subproject commit cdb6c53530369f011775525dddcc536d49503f29 +Subproject commit 6196089ecb3d250f25ca11e8e9485681a4a4a330