Skip to content

Commit 302e0e2

Browse files
authored
Merge branch 'feat/inheritance/base' into feat/inheritance/encryption
2 parents 06c3efc + 06e1459 commit 302e0e2

File tree

9 files changed

+303
-7
lines changed

9 files changed

+303
-7
lines changed
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
/**
2+
* @file inheritance_auth_wallet.c
3+
* @author Cypherock X1 Team
4+
* @brief
5+
* @details
6+
7+
* @copyright Copyright (c) 2023 HODL TECH PTE LTD
8+
* <br/> You may obtain a copy of license at <a href="https://mitcc.org/"
9+
* target=_blank>https://mitcc.org/</a>
10+
*
11+
*/
12+
13+
/*****************************************************************************
14+
* INCLUDES
15+
*****************************************************************************/
16+
17+
#include <stdbool.h>
18+
#include <stdint.h>
19+
20+
#include "bip39.h"
21+
#include "card_fetch_data.h"
22+
#include "inheritance/core.pb.h"
23+
#include "inheritance_api.h"
24+
#include "inheritance_priv.h"
25+
#include "status_api.h"
26+
#include "ui_delay.h"
27+
28+
/*****************************************************************************
29+
* EXTERN VARIABLES
30+
*****************************************************************************/
31+
32+
/*****************************************************************************
33+
* PRIVATE MACROS AND DEFINES
34+
*****************************************************************************/
35+
36+
/*****************************************************************************
37+
* STATIC VARIABLES
38+
*****************************************************************************/
39+
static auth_wallet_config_t *auth = NULL;
40+
41+
/*****************************************************************************
42+
* GLOBAL VARIABLES
43+
*****************************************************************************/
44+
45+
/*****************************************************************************
46+
* STATIC FUNCTION PROTOTYPES
47+
*****************************************************************************/
48+
49+
/**
50+
* @brief Verifies the integrity and validity of the wallet authentication
51+
* inputs.
52+
*
53+
* This static function checks if the challenge, wallet ID, and challenge size
54+
* are non-zero and within the expected range. It ensures the authentication
55+
* inputs are valid.
56+
*
57+
* @return true Always returns true if all assertions pass.
58+
*/
59+
static bool verify_auth_wallet_inputs();
60+
61+
/**
62+
* @brief Retrieves encrypted data (entropy) from the card based on the wallet
63+
* ID.
64+
*
65+
* This function initializes a secure_data_t structure, fetches encrypted data
66+
* from the card, and stores the result in the auth structure. It checks if the
67+
* operation was successful and if the encrypted data size is within the allowed
68+
* limit.
69+
*
70+
* @return true If the entropy was successfully fetched and stored.
71+
* @return false If there was an error in fetching the encrypted data or if the
72+
* data size exceeds the limit.
73+
*/
74+
static bool auth_wallet_get_entropy();
75+
76+
/**
77+
* @brief Generates the public and private key pairs based on the entropy.
78+
*
79+
* This function derives a seed from the entropy and generates an Ed25519 key
80+
* pair (private and public keys). It stores the keys in the auth structure.
81+
*
82+
* @return true Always returns true.
83+
*/
84+
static bool auth_wallet_get_pairs();
85+
86+
/**
87+
* @brief Generates and verifies a digital signature for the wallet
88+
* authentication.
89+
*
90+
* This function creates an unsigned transaction by concatenating the challenge
91+
* and wallet ID. It then signs the transaction using the private key and
92+
* verifies the signature using the public key.
93+
*
94+
* @return true If the signature was successfully generated and verified.
95+
* @return false If the signature verification failed.
96+
*/
97+
static bool auth_wallet_get_signature();
98+
99+
/*****************************************************************************
100+
* STATIC FUNCTIONS
101+
*****************************************************************************/
102+
103+
static bool verify_auth_wallet_inputs() {
104+
if (NULL == auth->challenge || NULL == auth->wallet_id ||
105+
auth->challenge_size < CHALLENGE_SIZE_MIN ||
106+
auth->challenge_size > CHALLENGE_SIZE_MAX) {
107+
inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG,
108+
ERROR_DATA_FLOW_INVALID_QUERY);
109+
delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME);
110+
return false;
111+
}
112+
113+
return true;
114+
}
115+
116+
static bool auth_wallet_get_entropy() {
117+
secure_data_t msgs[1] = {0};
118+
msgs[0].plain_data_size = WALLET_ID_SIZE;
119+
memcpy(msgs[0].plain_data, auth->wallet_id, WALLET_ID_SIZE);
120+
121+
card_error_type_e status = card_fetch_encrypt_data(auth->wallet_id, msgs, 1);
122+
123+
delay_scr_init(ui_text_inheritance_wallet_authenticating, DELAY_SHORT);
124+
125+
if (status != CARD_OPERATION_SUCCESS ||
126+
msgs[0].encrypted_data_size > ENTROPY_SIZE_LIMIT) {
127+
inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG,
128+
ERROR_DATA_FLOW_INVALID_QUERY);
129+
delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME);
130+
return false;
131+
}
132+
set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_CARD_TAPPED);
133+
134+
memcpy((void *)auth->entropy,
135+
msgs[0].encrypted_data,
136+
msgs[0].encrypted_data_size);
137+
auth->entropy_size = msgs[0].encrypted_data_size;
138+
139+
return true;
140+
}
141+
142+
static bool auth_wallet_get_pairs() {
143+
mnemonic_to_seed((char *)auth->entropy, "", auth->private_key, NULL);
144+
ed25519_publickey(auth->private_key, auth->public_key);
145+
146+
return true;
147+
}
148+
149+
static bool auth_wallet_get_signature() {
150+
const size_t unsigned_txn_size = auth->challenge_size + WALLET_ID_SIZE;
151+
uint8_t unsigned_txn[unsigned_txn_size];
152+
153+
memcpy(unsigned_txn, auth->challenge, auth->challenge_size);
154+
memcpy(unsigned_txn + auth->challenge_size, auth->wallet_id, WALLET_ID_SIZE);
155+
156+
ed25519_sign(unsigned_txn,
157+
unsigned_txn_size,
158+
auth->private_key,
159+
auth->public_key,
160+
auth->signature);
161+
162+
int valid = ed25519_sign_open(
163+
unsigned_txn, unsigned_txn_size, auth->public_key, auth->signature);
164+
165+
if (0 != valid) {
166+
inheritance_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG,
167+
ERROR_DATA_FLOW_INVALID_DATA);
168+
delay_scr_init(ui_text_inheritance_wallet_auth_fail, DELAY_TIME);
169+
return false;
170+
}
171+
172+
return true;
173+
}
174+
175+
static bool send_result() {
176+
inheritance_result_t result = INHERITANCE_RESULT_INIT_ZERO;
177+
result.which_response = INHERITANCE_RESULT_AUTH_WALLET_TAG;
178+
result.auth_wallet.which_response =
179+
INHERITANCE_AUTH_WALLET_RESPONSE_RESULT_TAG;
180+
memcpy(result.auth_wallet.result.signature,
181+
auth->signature,
182+
sizeof(ed25519_signature));
183+
184+
if (auth->is_setup) {
185+
memcpy(result.auth_wallet.result.public_key,
186+
auth->public_key,
187+
sizeof(ed25519_public_key));
188+
}
189+
190+
inheritance_send_result(&result);
191+
return true;
192+
}
193+
/*****************************************************************************
194+
* GLOBAL FUNCTIONS
195+
*****************************************************************************/
196+
197+
void inheritance_auth_wallet(inheritance_query_t *query) {
198+
auth = (auth_wallet_config_t *)malloc(sizeof(auth_wallet_config_t));
199+
ASSERT(auth != NULL);
200+
memzero(auth, sizeof(auth_wallet_config_t));
201+
202+
memcpy(
203+
auth->wallet_id, query->auth_wallet.initiate.wallet_id, WALLET_ID_SIZE);
204+
auth->challenge_size = query->auth_wallet.initiate.challenge.size;
205+
memcpy(auth->challenge,
206+
query->auth_wallet.initiate.challenge.bytes,
207+
auth->challenge_size);
208+
auth->is_setup = query->auth_wallet.initiate.is_public_key;
209+
210+
set_app_flow_status(INHERITANCE_AUTH_WALLET_STATUS_INIT);
211+
if (verify_auth_wallet_inputs() && auth_wallet_get_entropy() &&
212+
auth_wallet_get_pairs() && auth_wallet_get_signature() && send_result()) {
213+
delay_scr_init(ui_text_inheritance_wallet_auth_success, DELAY_TIME);
214+
}
215+
216+
memzero(auth, sizeof(auth_wallet_config_t));
217+
free(auth);
218+
auth = NULL;
219+
}

apps/inheritance_app/inheritance_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ void inheritance_main(usb_event_t usb_evt, const void *app_config) {
126126

127127
switch ((uint8_t)query.which_request) {
128128
case INHERITANCE_QUERY_AUTH_WALLET_TAG: {
129-
// TODO: Add auth wallet functionality
129+
inheritance_auth_wallet(&query);
130130
break;
131131
}
132132
case INHERITANCE_QUERY_ENCRYPT_TAG: {

apps/inheritance_app/inheritance_main.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
*****************************************************************************/
2020

2121
#include "app_registry.h"
22-
#include "events.h"
23-
#include "inheritance_context.h"
2422
/*****************************************************************************
2523
* MACROS AND DEFINES
2624
*****************************************************************************/

apps/inheritance_app/inheritance_priv.h

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,54 @@
1313
/*****************************************************************************
1414
* INCLUDES
1515
*****************************************************************************/
16-
#include <inheritance/core.pb.h>
1716
#include <stdint.h>
1817

1918
#include "card_fetch_data.h"
2019
#include "inheritance_context.h"
2120
#include "ui_input_text.h"
21+
#include "ed25519.h"
22+
#include "inheritance/core.pb.h"
23+
#include "wallet.h"
2224

2325
/*****************************************************************************
24-
* TYPEDEFS
26+
* PRIVATE MACROS AND DEFINES
27+
*****************************************************************************/
28+
#define CHALLENGE_SIZE_MAX 32
29+
#define CHALLENGE_SIZE_MIN 16
30+
#define ENTROPY_SIZE_LIMIT 100
31+
32+
/*****************************************************************************
33+
* PRIVATE TYPEDEFS
2534
*****************************************************************************/
35+
typedef enum {
36+
AUTH_WALLET_OK = 0,
37+
AUTH_WALLET_TYPE_INVALID, // TODO: In inheriance app - Show error message
38+
// on ui that which assert is wrong
39+
AUTH_WALLET_INPUTS_INVALID, // TODO: In inheritance app - Add in wallet id
40+
// comparison, show error message on ui
41+
} auth_wallet_error_type_e;
42+
43+
#pragma pack(push, 1)
44+
typedef struct {
45+
uint8_t wallet_id[WALLET_ID_SIZE];
46+
uint8_t challenge[CHALLENGE_SIZE_MAX];
47+
size_t challenge_size;
2648

49+
const uint8_t entropy[ENTROPY_SIZE_LIMIT];
50+
uint8_t entropy_size;
51+
ed25519_secret_key private_key;
52+
53+
ed25519_signature signature;
54+
ed25519_public_key public_key;
55+
56+
bool is_setup;
57+
auth_wallet_error_type_e status;
58+
} auth_wallet_config_t;
59+
#pragma pack(pop)
60+
61+
/*****************************************************************************
62+
* TYPEDEFS
63+
*****************************************************************************/
2764
typedef struct {
2865
secure_data_t data[INHERITANCE_MESSAGES_MAX_COUNT];
2966
uint8_t data_count;
@@ -33,6 +70,20 @@ typedef struct {
3370
uint16_t packet_size;
3471
} inheritance_encryption_context_t;
3572

73+
/*****************************************************************************
74+
* EXPORTED VARIABLES
75+
*****************************************************************************/
76+
77+
/*****************************************************************************
78+
* GLOBAL FUNCTION PROTOTYPES
79+
*****************************************************************************/
80+
81+
/**
82+
* @brief Entry point to auth wallet flow
83+
*
84+
*/
85+
void inheritance_auth_wallet(inheritance_query_t *query);
86+
3687
/**
3788
* @brief Handler for inheritance messages encrytion flow.
3889
* @details The expected request type is INHERITANCE_QUERY_ENCRYPT_TAG.
@@ -42,4 +93,5 @@ typedef struct {
4293
* @param query Reference to the decoded query struct from the host app
4394
*/
4495
void inheritance_encrypt_data(inheritance_query_t *query);
96+
4597
#endif /* INHERITANCE_PRIV_H */

common/interfaces/card_interface/nfc.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,7 @@ ISO7816 nfc_encrypt_data(const uint8_t name[NAME_SIZE],
548548
ASSERT(plain_data_size != 0);
549549
ASSERT(encrypted_data != NULL);
550550

551+
#if USE_SIMULATOR == 0
551552
ISO7816 status_word = CLA_ISO7816;
552553
uint8_t send_apdu[600] = {0}, *recv_apdu = send_apdu;
553554
uint16_t send_len = 0, recv_len = 236;
@@ -579,9 +580,15 @@ ISO7816 nfc_encrypt_data(const uint8_t name[NAME_SIZE],
579580
memcpy(encrypted_data, recv_apdu + 3, recv_len - 5);
580581
}
581582
}
582-
583583
memzero(recv_apdu, sizeof(send_apdu));
584584
return status_word;
585+
#else
586+
// TODO: Standardize simulator/test wallet info
587+
memcpy(name, "FIRST", 5);
588+
memcpy(encrypted_data, name, 1);
589+
memcpy(encrypted_data + 1, plain_data, plain_data_size);
590+
*encrypted_data_size = 1 + plain_data_size;
591+
#endif
585592
}
586593

587594
ISO7816 nfc_decrypt_data(const uint8_t name[NAME_SIZE],
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
inheritance.AuthWalletInitiateRequest.challenge type:FT_STATIC max_size:32 fixed_length:false
2+
inheritance.AuthWalletInitiateRequest.wallet_id type:FT_STATIC max_size:32 fixed_length:true
3+
inheritance.AuthWalletResultResponse.public_key type:FT_STATIC max_size:32 fixed_length:true
4+
inheritance.AuthWalletResultResponse.signature type:FT_STATIC max_size:64 fixed_length:true

src/card_operations/card_fetch_data.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
/*****************************************************************************
1212
* INCLUDES
1313
*****************************************************************************/
14-
#include <assert.h>
1514

15+
#include <assert.h>
1616
#include "card_operation_typedefs.h"
1717
#include "stdbool.h"
1818
#include "stdint.h"

src/constant_texts.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,16 @@ const char *ui_text_unreliable_cards =
527527
const char *ui_critical_card_health_migrate_data =
528528
"Card health is critical! Migrate to new set of cards";
529529

530+
// App specific
531+
532+
// Inheritance
533+
const char *ui_text_inheritance_wallet_authenticating =
534+
"Wallet\nauthenticating...";
535+
const char *ui_text_inheritance_wallet_auth_success =
536+
"Wallet\nauthentication\nsuccessfully";
537+
const char *ui_text_inheritance_wallet_auth_fail =
538+
"Wallet\nauthentication\nfailed";
539+
530540
const char *ui_text_inheritance_flow_confirmation =
531541
"Proceed to encrypt data for %s?";
532542

src/constant_texts.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,12 @@ extern const char *ui_text_nfc_hardware_fault_detected;
370370
extern const char *ui_text_unreliable_cards;
371371
extern const char *ui_critical_card_health_migrate_data;
372372

373+
// App specific
374+
375+
// Inheritance
376+
extern const char *ui_text_inheritance_wallet_authenticating;
377+
extern const char *ui_text_inheritance_wallet_auth_success;
378+
extern const char *ui_text_inheritance_wallet_auth_fail;
373379
extern const char *ui_text_inheritance_flow_confirmation;
374380

375381
#ifdef ALLOW_LOG_EXPORT

0 commit comments

Comments
 (0)