22
22
#include "inheritance/core.pb.h"
23
23
#include "inheritance_api.h"
24
24
#include "inheritance_priv.h"
25
+ #include "reconstruct_wallet_flow.h"
25
26
#include "status_api.h"
26
27
#include "ui_delay.h"
27
28
@@ -83,6 +84,21 @@ static bool auth_wallet_get_entropy();
83
84
*/
84
85
static bool auth_wallet_get_pairs ();
85
86
87
+ /**
88
+ * @brief Signs the given challenge.
89
+ *
90
+ * The function generates an Ed25519 signature for the provided challenge
91
+ * and verifies it against the public key.
92
+ *
93
+ * @return true if the signature is successfully created and verified, false
94
+ * otherwise.
95
+ */
96
+ static bool auth_wallet_sign_challenge (const uint8_t * unsigned_txn ,
97
+ const size_t unsigned_txn_size ,
98
+ const ed25519_secret_key private_key ,
99
+ const ed25519_public_key public_key ,
100
+ ed25519_signature signature );
101
+
86
102
/**
87
103
* @brief Generates and verifies a digital signature for the wallet
88
104
* authentication.
@@ -101,9 +117,10 @@ static bool auth_wallet_get_signature();
101
117
*****************************************************************************/
102
118
103
119
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 ) {
120
+ if (auth -> data .challenge_size == 0 ||
121
+ auth -> data .challenge_size < CHALLENGE_SIZE_MIN ||
122
+ auth -> data .challenge_size > CHALLENGE_SIZE_MAX ||
123
+ (auth -> do_wallet_based == false && auth -> do_seed_based == false)) {
107
124
inheritance_send_error (ERROR_COMMON_ERROR_CORRUPT_DATA_TAG ,
108
125
ERROR_DATA_FLOW_INVALID_QUERY );
109
126
delay_scr_init (ui_text_inheritance_wallet_auth_fail , DELAY_TIME );
@@ -114,61 +131,119 @@ static bool verify_auth_wallet_inputs() {
114
131
}
115
132
116
133
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;
134
+ if (auth -> do_seed_based ) {
135
+ uint8_t seed [SIZE_SEED ] = {0 };
136
+ if (!reconstruct_seed_without_passphrase (
137
+ auth -> data .wallet_id , seed , inheritance_send_error )) {
138
+ memzero (seed , sizeof (seed ));
139
+ inheritance_send_error (ERROR_COMMON_ERROR_CORRUPT_DATA_TAG ,
140
+ ERROR_DATA_FLOW_INVALID_QUERY );
141
+ delay_scr_init (ui_text_inheritance_wallet_auth_fail , DELAY_TIME );
142
+ return false;
143
+ }
144
+ memcpy ((void * )auth -> seed_based_data .entropy , seed , SIZE_SEED );
145
+ auth -> seed_based_data .entropy_size = SIZE_SEED ;
146
+ auth -> seed_based_data .has_data = true;
147
+ memzero (seed , sizeof (seed ));
148
+ // seed generation complete
149
+ set_app_flow_status (INHERITANCE_AUTH_WALLET_STATUS_SEED_BASED_CARD_TAPPED );
150
+ }
151
+ if (auth -> do_wallet_based ) {
152
+ secure_data_t msgs [1 ] = {0 };
153
+ msgs [0 ].plain_data_size = WALLET_ID_SIZE ;
154
+ memcpy (msgs [0 ].plain_data , auth -> data .wallet_id , WALLET_ID_SIZE );
155
+
156
+ card_error_type_e status =
157
+ card_fetch_encrypt_data (auth -> data .wallet_id , msgs , 1 );
158
+ if (status != CARD_OPERATION_SUCCESS ||
159
+ msgs [0 ].encrypted_data_size > ENTROPY_SIZE_LIMIT ) {
160
+ inheritance_send_error (ERROR_COMMON_ERROR_CORRUPT_DATA_TAG ,
161
+ ERROR_DATA_FLOW_INVALID_DATA );
162
+ delay_scr_init (ui_text_inheritance_wallet_auth_fail , DELAY_TIME );
163
+ return false;
164
+ }
165
+ memcpy ((void * )auth -> wallet_based_data .entropy ,
166
+ msgs [0 ].encrypted_data ,
167
+ msgs [0 ].encrypted_data_size );
168
+ auth -> wallet_based_data .entropy_size = msgs [0 ].encrypted_data_size ;
169
+ auth -> wallet_based_data .has_data = true;
170
+ // wallet id encryption complete
171
+ set_app_flow_status (
172
+ INHERITANCE_AUTH_WALLET_STATUS_WALLET_BASED_CARD_TAPPED );
131
173
}
132
- set_app_flow_status (INHERITANCE_AUTH_WALLET_STATUS_CARD_TAPPED );
133
174
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 ;
175
+ delay_scr_init (ui_text_inheritance_wallet_authenticating , DELAY_SHORT );
138
176
139
177
return true;
140
178
}
141
179
142
180
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
-
181
+ if (auth -> seed_based_data .has_data ) {
182
+ mnemonic_to_seed ((char * )auth -> seed_based_data .entropy ,
183
+ "" ,
184
+ auth -> seed_based_data .private_key ,
185
+ NULL );
186
+ ed25519_publickey (auth -> seed_based_data .private_key ,
187
+ auth -> seed_based_data .result .public_key );
188
+ // Clear seed as soon as it is not needed
189
+ memzero ((void * const )auth -> seed_based_data .entropy ,
190
+ sizeof (auth -> seed_based_data .entropy ));
191
+ }
192
+ if (auth -> wallet_based_data .has_data ) {
193
+ mnemonic_to_seed ((char * )auth -> wallet_based_data .entropy ,
194
+ "" ,
195
+ auth -> wallet_based_data .private_key ,
196
+ NULL );
197
+ ed25519_publickey (auth -> wallet_based_data .private_key ,
198
+ auth -> wallet_based_data .result .public_key );
199
+ }
146
200
return true;
147
201
}
202
+ static bool auth_wallet_sign_challenge (const uint8_t * unsigned_txn ,
203
+ const size_t unsigned_txn_size ,
204
+ const ed25519_secret_key private_key ,
205
+ const ed25519_public_key public_key ,
206
+ ed25519_signature signature ) {
207
+ ed25519_sign (
208
+ unsigned_txn , unsigned_txn_size , private_key , public_key , signature );
148
209
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 );
210
+ int valid =
211
+ ed25519_sign_open (unsigned_txn , unsigned_txn_size , public_key , signature );
164
212
165
213
if (0 != valid ) {
166
214
inheritance_send_error (ERROR_COMMON_ERROR_CORRUPT_DATA_TAG ,
167
215
ERROR_DATA_FLOW_INVALID_DATA );
168
216
delay_scr_init (ui_text_inheritance_wallet_auth_fail , DELAY_TIME );
169
217
return false;
170
218
}
219
+ return true;
220
+ }
171
221
222
+ static bool auth_wallet_get_signature () {
223
+ const size_t unsigned_txn_size = auth -> data .challenge_size + WALLET_ID_SIZE ;
224
+ uint8_t unsigned_txn [unsigned_txn_size ];
225
+ memcpy (unsigned_txn , auth -> data .challenge , auth -> data .challenge_size );
226
+ memcpy (unsigned_txn + auth -> data .challenge_size ,
227
+ auth -> data .wallet_id ,
228
+ WALLET_ID_SIZE );
229
+ if (auth -> do_seed_based ) {
230
+ if (!auth_wallet_sign_challenge (unsigned_txn ,
231
+ unsigned_txn_size ,
232
+ auth -> seed_based_data .private_key ,
233
+ auth -> seed_based_data .result .public_key ,
234
+ auth -> seed_based_data .result .signature )) {
235
+ return false;
236
+ }
237
+ }
238
+ if (auth -> do_wallet_based ) {
239
+ if (!auth_wallet_sign_challenge (unsigned_txn ,
240
+ unsigned_txn_size ,
241
+ auth -> wallet_based_data .private_key ,
242
+ auth -> wallet_based_data .result .public_key ,
243
+ auth -> wallet_based_data .result .signature )) {
244
+ return false;
245
+ }
246
+ }
172
247
return true;
173
248
}
174
249
@@ -177,16 +252,28 @@ static bool send_result() {
177
252
result .which_response = INHERITANCE_RESULT_AUTH_WALLET_TAG ;
178
253
result .auth_wallet .which_response =
179
254
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 ));
255
+ if (auth -> do_seed_based ) {
256
+ memcpy (result .auth_wallet .result .seed_based .signature ,
257
+ auth -> seed_based_data .result .signature ,
258
+ sizeof (ed25519_signature ));
259
+ result .auth_wallet .result .has_seed_based = true;
260
+ if (auth -> with_public_key ) {
261
+ memcpy (result .auth_wallet .result .seed_based .public_key ,
262
+ auth -> seed_based_data .result .public_key ,
263
+ sizeof (ed25519_public_key ));
264
+ }
265
+ }
266
+ if (auth -> do_wallet_based ) {
267
+ memcpy (result .auth_wallet .result .wallet_based .signature ,
268
+ auth -> wallet_based_data .result .signature ,
269
+ sizeof (ed25519_signature ));
270
+ result .auth_wallet .result .has_wallet_based = true;
271
+ if (auth -> with_public_key ) {
272
+ memcpy (result .auth_wallet .result .wallet_based .public_key ,
273
+ auth -> wallet_based_data .result .public_key ,
274
+ sizeof (ed25519_public_key ));
275
+ }
188
276
}
189
-
190
277
inheritance_send_result (& result );
191
278
return true;
192
279
}
@@ -199,13 +286,16 @@ void inheritance_auth_wallet(inheritance_query_t *query) {
199
286
ASSERT (auth != NULL );
200
287
memzero (auth , sizeof (auth_wallet_config_t ));
201
288
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 ,
289
+ memcpy (auth -> data .wallet_id ,
290
+ query -> auth_wallet .initiate .wallet_id ,
291
+ WALLET_ID_SIZE );
292
+ auth -> data .challenge_size = query -> auth_wallet .initiate .challenge .size ;
293
+ memcpy (auth -> data .challenge ,
206
294
query -> auth_wallet .initiate .challenge .bytes ,
207
- auth -> challenge_size );
208
- auth -> is_setup = query -> auth_wallet .initiate .is_public_key ;
295
+ auth -> data .challenge_size );
296
+ auth -> with_public_key = query -> auth_wallet .initiate .with_public_key ;
297
+ auth -> do_seed_based = query -> auth_wallet .initiate .do_seed_based ;
298
+ auth -> do_wallet_based = query -> auth_wallet .initiate .do_wallet_based ;
209
299
210
300
set_app_flow_status (INHERITANCE_AUTH_WALLET_STATUS_INIT );
211
301
if (verify_auth_wallet_inputs () && auth_wallet_get_entropy () &&
0 commit comments