3535#include "common/read.h"
3636#include "common/write.h"
3737
38+ #include "../boilerplate/sw.h"
3839#include "../debug-helpers/debug.h"
3940
4041#include "crypto.h"
@@ -241,26 +242,28 @@ void crypto_get_checksum(const uint8_t *in, uint16_t in_len, uint8_t out[static
241242 memmove (out , buffer , 4 );
242243}
243244
244- bool crypto_get_compressed_pubkey_at_path (const uint32_t bip32_path [],
245- uint8_t bip32_path_len ,
246- uint8_t pubkey [static 33 ],
247- uint8_t chain_code []) {
245+ cx_err_t crypto_get_compressed_pubkey_at_path (const uint32_t bip32_path [],
246+ uint8_t bip32_path_len ,
247+ uint8_t pubkey [static 33 ],
248+ uint8_t chain_code []) {
248249 uint8_t raw_public_key [65 ];
250+ cx_err_t error = CX_OK ;
249251
250- if (bip32_derive_get_pubkey_256 (CX_CURVE_256K1 ,
251- bip32_path ,
252- bip32_path_len ,
253- raw_public_key ,
254- chain_code ,
255- CX_SHA512 ) != CX_OK ) {
256- return false;
252+ error = bip32_derive_get_pubkey_256 (CX_CURVE_256K1 ,
253+ bip32_path ,
254+ bip32_path_len ,
255+ raw_public_key ,
256+ chain_code ,
257+ CX_SHA512 );
258+ if (error != CX_OK ) {
259+ return error ;
257260 }
258261
259262 if (crypto_get_compressed_pubkey (raw_public_key , pubkey ) < 0 ) {
260- return false ;
263+ return CX_INTERNAL_ERROR ;
261264 }
262265
263- return true ;
266+ return error ;
264267}
265268
266269uint32_t crypto_get_key_fingerprint (const uint8_t pub_key [static 33 ]) {
@@ -271,10 +274,14 @@ uint32_t crypto_get_key_fingerprint(const uint8_t pub_key[static 33]) {
271274}
272275
273276uint32_t crypto_get_master_key_fingerprint () {
274- uint8_t master_pub_key [33 ];
275- uint32_t bip32_path [] = {};
276- crypto_get_compressed_pubkey_at_path (bip32_path , 0 , master_pub_key , NULL );
277- return crypto_get_key_fingerprint (master_pub_key );
277+ uint8_t master_key_identifier [CX_RIPEMD160_SIZE ] = {0 };
278+
279+ int res = os_perso_get_master_key_identifier (master_key_identifier , CX_RIPEMD160_SIZE );
280+ LEDGER_ASSERT (
281+ res == CX_OK ,
282+ "Unexpected error in os_perso_get_master_key_identifier computation. Returned: %d" ,
283+ res );
284+ return read_u32_be (master_key_identifier , 0 );
278285}
279286
280287bool crypto_derive_symmetric_key (const char * label , size_t label_len , uint8_t key [static 32 ]) {
@@ -311,23 +318,26 @@ bool crypto_derive_symmetric_key(const char *label, size_t label_len, uint8_t ke
311318 return ret == CX_OK ;
312319}
313320
314- int get_extended_pubkey_at_path (const uint32_t bip32_path [],
315- uint8_t bip32_path_len ,
316- uint32_t bip32_pubkey_version ,
317- serialized_extended_pubkey_t * out_pubkey ) {
321+ cx_err_t get_extended_pubkey_at_path (const uint32_t bip32_path [],
322+ uint8_t bip32_path_len ,
323+ uint32_t bip32_pubkey_version ,
324+ serialized_extended_pubkey_t * out_pubkey ) {
318325 // find parent key's fingerprint and child number
319326 uint32_t parent_fingerprint = 0 ;
320327 uint32_t child_number = 0 ;
328+ cx_err_t error = CX_OK ;
329+
321330 if (bip32_path_len > 0 ) {
322331 // here we reuse the storage for the parent keys that we will later use
323332 // for the response, in order to save memory
324333
325334 uint8_t parent_pubkey [33 ];
326- if (!crypto_get_compressed_pubkey_at_path (bip32_path ,
327- bip32_path_len - 1 ,
328- parent_pubkey ,
329- NULL )) {
330- return -1 ;
335+ error = crypto_get_compressed_pubkey_at_path (bip32_path ,
336+ bip32_path_len - 1 ,
337+ parent_pubkey ,
338+ NULL );
339+ if (error != CX_OK ) {
340+ return error ;
331341 }
332342
333343 parent_fingerprint = crypto_get_key_fingerprint (parent_pubkey );
@@ -339,14 +349,31 @@ int get_extended_pubkey_at_path(const uint32_t bip32_path[],
339349 write_u32_be (out_pubkey -> parent_fingerprint , 0 , parent_fingerprint );
340350 write_u32_be (out_pubkey -> child_number , 0 , child_number );
341351
342- if (!crypto_get_compressed_pubkey_at_path (bip32_path ,
343- bip32_path_len ,
344- out_pubkey -> compressed_pubkey ,
345- out_pubkey -> chain_code )) {
346- return -1 ;
352+ return crypto_get_compressed_pubkey_at_path (bip32_path ,
353+ bip32_path_len ,
354+ out_pubkey -> compressed_pubkey ,
355+ out_pubkey -> chain_code );
356+ }
357+
358+ uint16_t cx_err_to_sw (cx_err_t error ) {
359+ if (error == CX_OK ) {
360+ return SW_OK ;
347361 }
348362
349- return 0 ;
363+ /* The error codes are not currently defined in the SDK */
364+ if (error == 0x4212 ) {
365+ PRINTF (
366+ "Attempt to derive a key at root level without "
367+ "HAVE_APPLICATION_FLAG_DERIVE_MASTER permission.\n" );
368+ return SW_NOT_SUPPORTED ;
369+ }
370+ if (error == 0x4215 ) {
371+ PRINTF ("Attempt to derive a key at unauthorized path.\n" );
372+ return SW_NOT_SUPPORTED ;
373+ }
374+
375+ PRINTF ("Failed getting bip32 pubkey, error = 0x%08X\n" , error );
376+ return SW_BAD_STATE ;
350377}
351378
352379int base58_encode_address (const uint8_t in [20 ], uint32_t version , char * out , size_t out_len ) {
0 commit comments