From 1ecb0f0c1c2ae6b903b0fe7f41b84590ebdad64e Mon Sep 17 00:00:00 2001 From: Andrew Kozlik Date: Thu, 15 Dec 2022 12:42:36 +0100 Subject: [PATCH] feat(legacy): Implement SLIP-0021 symmetric key derivation. --- legacy/firmware/crypto.c | 14 ++++++++++++++ legacy/firmware/crypto.h | 9 +++++++++ legacy/firmware/fsm.c | 18 ++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/legacy/firmware/crypto.c b/legacy/firmware/crypto.c index 85679bfd8..b40ba827b 100644 --- a/legacy/firmware/crypto.c +++ b/legacy/firmware/crypto.c @@ -818,3 +818,17 @@ bool change_output_to_input_script_type(OutputScriptType output_script_type, } } +void slip21_from_seed(const uint8_t *seed, int seed_len, Slip21Node *out) { + hmac_sha512((uint8_t *)"Symmetric key seed", 18, seed, seed_len, out->data); +} + +void slip21_derive_path(Slip21Node *inout, const uint8_t *label, + size_t label_len) { + HMAC_SHA512_CTX hctx = {0}; + hmac_sha512_Init(&hctx, inout->data, 32); + hmac_sha512_Update(&hctx, (uint8_t *)"\0", 1); + hmac_sha512_Update(&hctx, label, label_len); + hmac_sha512_Final(&hctx, inout->data); +} + +const uint8_t *slip21_key(const Slip21Node *node) { return &node->data[32]; } diff --git a/legacy/firmware/crypto.h b/legacy/firmware/crypto.h index 1873357ef..56f5310d9 100644 --- a/legacy/firmware/crypto.h +++ b/legacy/firmware/crypto.h @@ -41,6 +41,10 @@ #define ser_length_size(len) ((len) < 253 ? 1 : (len) < 0x10000 ? 3 : 5) +typedef struct { + uint8_t data[64]; +} Slip21Node; + uint32_t ser_length(uint32_t len, uint8_t *out); uint32_t ser_length_hash(Hasher *hasher, uint32_t len); @@ -91,4 +95,9 @@ bool is_segwit_output_script_type(OutputScriptType script_type); bool change_output_to_input_script_type(OutputScriptType output_script_type, InputScriptType *input_script_type); +void slip21_from_seed(const uint8_t *seed, int seed_len, Slip21Node *out); +void slip21_derive_path(Slip21Node *inout, const uint8_t *label, + size_t label_len); +const uint8_t *slip21_key(const Slip21Node *node); + #endif diff --git a/legacy/firmware/fsm.c b/legacy/firmware/fsm.c index 756a6a740..84e02a267 100644 --- a/legacy/firmware/fsm.c +++ b/legacy/firmware/fsm.c @@ -241,6 +241,24 @@ static HDNode *fsm_getDerivedNode(const char *curve, const uint32_t *address_n, return &node; } +static bool fsm_getSlip21Key(const char *path[], size_t path_count, + uint8_t key[32]) { + const uint8_t *seed = config_getSeed(); + if (seed == NULL) { + return false; + } + + static CONFIDENTIAL Slip21Node node; + slip21_from_seed(seed, 64, &node); + for (size_t i = 0; i < path_count; ++i) { + slip21_derive_path(&node, (uint8_t *)path[i], strlen(path[i])); + } + memcpy(key, slip21_key(&node), 32); + memzero(&node, sizeof(node)); + + return true; +} + static bool fsm_layoutAddress(const char *address, const char *desc, bool ignorecase, size_t prefixlen, const uint32_t *address_n, size_t address_n_count,