Skip to content

Commit

Permalink
Merge pull request #445 from Cypherock/feat/verify-fetched-wallet/PRF…
Browse files Browse the repository at this point in the history
…-6557

feat(core): Verify fetched wallets
  • Loading branch information
amanCypherock authored Dec 20, 2023
2 parents ee796b6 + 0efecdc commit 1747f42
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 6 deletions.
86 changes: 80 additions & 6 deletions src/card_operations/card_fetch_share.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
#include "card_internal.h"
#include "card_utils.h"
#include "constant_texts.h"
#include "core_error.h"
#include "flash_api.h"
#include "nfc.h"
#include "ui_screens.h"
Expand All @@ -85,13 +86,27 @@ extern Wallet_shamir_data wallet_shamir_data;
/*****************************************************************************
* STATIC FUNCTION PROTOTYPES
*****************************************************************************/
/**
* The function `verify_fetched_wallet` compares the values of a `wallet` object
* with the values of a `flash_wallet` object and returns a boolean indicating
* whether they are equal.
*
* @param xcor The x-coordinate of the wallet share, this variable represents
* the share index fetched from the last tapped card.
*
* @return a boolean value, which indicates whether the fetched wallet matches
* the expected values.
*/
static bool verify_fetched_wallet(uint8_t xcor);

/**
* @brief Helper function that copies wallet share retrieved from X1 card onto
* the RAM
*
* @param xcor The x-coordinate of the wallet share
* @param xcor The x-coordinate of the wallet share, this variable represents
* the share index fetched from the last tapped card.
*/
static void _handle_retrieve_wallet_success(uint8_t xcor);
static bool _handle_retrieve_wallet_success(uint8_t xcor);

/*****************************************************************************
* STATIC VARIABLES
Expand All @@ -105,16 +120,66 @@ static uint8_t remaining_cards;
/*****************************************************************************
* STATIC FUNCTIONS
*****************************************************************************/
static void _handle_retrieve_wallet_success(uint8_t xcor) {
if (WALLET_IS_ARBITRARY_DATA(wallet.wallet_info))

static bool verify_fetched_wallet(uint8_t xcor) {
Flash_Wallet *flash_wallet = NULL;
bool status =
get_flash_wallet_by_name((const char *)wallet.wallet_name, &flash_wallet);

ASSERT(SUCCESS == status && NULL != flash_wallet);

bool compare_status =
(0 == memcmp(wallet.wallet_id, flash_wallet->wallet_id, WALLET_ID_SIZE));
compare_status &=
(0 == memcmp(wallet.wallet_name, flash_wallet->wallet_name, NAME_SIZE));
compare_status &= (wallet.wallet_info == flash_wallet->wallet_info);

/**
* For wallets with device share present on flash, fetched wallet nonce is
* compared with wallet nonce on flash. In case of sync wallet, the wallet
* share and encryption data is written on flash after verification. For
* verifying the wallets in this case, we compare wallet nonce fetched from
* the two cards.
*/
if (VALID_WALLET_WITHOUT_DEVICE_SHARE != flash_wallet->state) {
// Wallet nonce present on flash, so compare current wallet nonce with flash
// wallet nonce.
uint8_t wallet_nonce[NONCE_SIZE] = {0};
ASSERT(SUCCESS ==
get_flash_wallet_nonce_by_name(
(const char *)flash_wallet->wallet_name, wallet_nonce));
compare_status &=
(0 == memcmp(wallet.wallet_share_with_mac_and_nonce + BLOCK_SIZE,
wallet_nonce,
NONCE_SIZE));
} else if (0 < xcor) {
// Compare nonce from current wallet with nonce of wallet previously
// fetched.
compare_status &=
(0 == memcmp(wallet.wallet_share_with_mac_and_nonce + BLOCK_SIZE,
wallet_shamir_data.share_encryption_data[xcor - 1],
NONCE_SIZE));
}
return compare_status;
}

static bool _handle_retrieve_wallet_success(uint8_t xcor) {
if (!verify_fetched_wallet(xcor)) {
LOG_ERROR("Verification failed xxx39");
return false;
}

if (WALLET_IS_ARBITRARY_DATA(wallet.wallet_info)) {
memcpy(((uint8_t *)wallet_shamir_data.arbitrary_data_shares) +
xcor * wallet.arbitrary_data_size,
wallet.arbitrary_data_share,
wallet.arbitrary_data_size);
else
} else {
memcpy(wallet_shamir_data.mnemonic_shares[xcor],
wallet.wallet_share_with_mac_and_nonce,
BLOCK_SIZE);
}

memcpy(wallet_shamir_data.share_encryption_data[xcor],
wallet.wallet_share_with_mac_and_nonce + BLOCK_SIZE,
PADDED_NONCE_SIZE + WALLET_MAC_SIZE);
Expand All @@ -123,6 +188,8 @@ static void _handle_retrieve_wallet_success(uint8_t xcor) {
sizeof(wallet.wallet_share_with_mac_and_nonce));

wallet_shamir_data.share_x_coords[xcor] = wallet.xcor;

return true;
}

/*****************************************************************************
Expand Down Expand Up @@ -160,7 +227,14 @@ card_error_type_e card_fetch_share(const card_fetch_share_config_t *config,

if (card_data.nfc_data.status == SW_NO_ERROR) {
remaining_cards = card_data.nfc_data.acceptable_cards;
_handle_retrieve_wallet_success(config->xcor);
if (!_handle_retrieve_wallet_success(config->xcor)) {
card_data.error_type = CARD_OPERATION_VERIFICATION_FAILED;
card_data.nfc_data.status = SW_RECORD_NOT_FOUND;
mark_core_error_screen(
ui_text_wallet_verification_failed_in_reconstruction, true);
break;
}

buzzer_start(BUZZER_DURATION);

if (false == config->operation.skip_card_removal) {
Expand Down
3 changes: 3 additions & 0 deletions src/card_operations/card_operation_typedefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ typedef enum card_errors_type {
CARD_OPERATION_RETAP_BY_USER_REQUIRED, /** Errors that occur due to user
mistakes, like wrong card number or
card of wrong family tapped */
CARD_OPERATION_VERIFICATION_FAILED, /** Error occuring when wallet present on
card is different from the wallet
expected*/
CARD_OPERATION_ABORT_OPERATION, /** Error occurring due to internal handling
of NFC or card communication. These errors
can be associated to @ref
Expand Down

0 comments on commit 1747f42

Please sign in to comment.