diff --git a/src/common/merkle.c b/src/common/merkle.c index 19205670f..ea9d7d4e2 100644 --- a/src/common/merkle.c +++ b/src/common/merkle.c @@ -24,54 +24,29 @@ #include "merkle.h" -#include "cx_ram.h" #include "debug-helpers/debug.h" #include "ledger_assert.h" -void merkle_compute_element_hash(const uint8_t *in, size_t in_len, uint8_t out[static 32]) { - cx_sha256_t hash; - cx_sha256_init(&hash); - +void merkle_compute_element_hash(const uint8_t *in, + size_t in_len, + uint8_t out[static CX_SHA256_SIZE]) { // H(0x00 | in) - crypto_hash_update_u8(&hash.header, 0x00); - crypto_hash_update(&hash.header, in, in_len); - - crypto_hash_digest(&hash.header, out, 32); + uint8_t data = 0x00; + cx_iovec_t iovec[2] = {{.iov_base = &data, .iov_len = 1}, {.iov_base = in, .iov_len = in_len}}; + cx_sha256_hash_iovec(iovec, 2, out); } -// void merkle_combine_hashes(const uint8_t left[static 32], -// const uint8_t right[static 32], -// uint8_t out[static 32]) { -// PRINT_STACK_POINTER(); - -// cx_sha256_t hash; -// cx_sha256_init(&hash); - -// // H(0x01 | left | right) -// crypto_hash_update_u8(&hash.header, 0x01); -// crypto_hash_update(&hash.header, left, 32); -// crypto_hash_update(&hash.header, right, 32); - -// crypto_hash_digest(&hash.header, out, 32); -// } - -// implementation using the cxram section, in order to save ram -void merkle_combine_hashes(const uint8_t left[static 32], - const uint8_t right[static 32], - uint8_t out[static 32]) { +void merkle_combine_hashes(const uint8_t left[static CX_SHA256_SIZE], + const uint8_t right[static CX_SHA256_SIZE], + uint8_t out[static CX_SHA256_SIZE]) { PRINT_STACK_POINTER(); - cx_sha256_init_no_throw(&G_cx.sha256); - uint8_t prefix = 0x01; - LEDGER_ASSERT(cx_sha256_update(&G_cx.sha256, &prefix, 1) == CX_OK, "It never fails"); - - LEDGER_ASSERT(cx_sha256_update(&G_cx.sha256, left, 32) == CX_OK, "It never fails"); - LEDGER_ASSERT(cx_sha256_update(&G_cx.sha256, right, 32) == CX_OK, "It never fails"); - - cx_sha256_final(&G_cx.sha256, out); - explicit_bzero(&G_cx.sha256, sizeof(cx_sha256_t)); + cx_iovec_t iovec[3] = {{.iov_base = &prefix, .iov_len = 1}, + {.iov_base = left, .iov_len = CX_SHA256_SIZE}, + {.iov_base = right, .iov_len = CX_SHA256_SIZE}}; + cx_sha256_hash_iovec(iovec, 3, out); } // TODO: make this O(log n), or possibly O(1). Currently O(log^2 n). diff --git a/src/crypto.c b/src/crypto.c index 08e053431..b5917b150 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -155,25 +155,8 @@ int bip32_CKDpub(const serialized_extended_pubkey_t *parent, return 0; } -#ifndef _NR_cx_hash_ripemd160 -/** Missing in some SDKs, we implement it using the cxram section if needed. */ -static size_t cx_hash_ripemd160(const uint8_t *in, size_t in_len, uint8_t *out, size_t out_len) { - PRINT_STACK_POINTER(); - - if (out_len < CX_RIPEMD160_SIZE) { - return 0; - } - LEDGER_ASSERT(cx_ripemd160_init_no_throw((cx_ripemd160_t *) &G_cx) == CX_OK, "It never fails"); - LEDGER_ASSERT(cx_ripemd160_update((cx_ripemd160_t *) &G_cx, in, in_len) == CX_OK, - "It never fails"); - LEDGER_ASSERT(cx_ripemd160_final((cx_ripemd160_t *) &G_cx, out) == CX_OK, "It never fails"); - explicit_bzero((cx_ripemd160_t *) &G_cx, sizeof(cx_sha256_t)); - return CX_RIPEMD160_SIZE; -} -#endif // _NR_cx_hash_ripemd160 - void crypto_ripemd160(const uint8_t *in, uint16_t inlen, uint8_t out[static 20]) { - cx_hash_ripemd160(in, inlen, out, 20); + cx_ripemd160_hash(in, inlen, out); } void crypto_hash160(const uint8_t *in, uint16_t inlen, uint8_t out[static 20]) { @@ -473,22 +456,25 @@ static int crypto_tr_lift_x(const uint8_t x[static 32], uint8_t out[static 65]) // Computes a tagged hash according to BIP-340. // If data2_len > 0, then data2 must be non-NULL and the `data` and `data2` arrays are concatenated. -// Somewhat weird signature, but this helps to optimize stack usage. -static void __attribute__((noinline)) crypto_tr_tagged_hash(const uint8_t *tag, - uint16_t tag_len, - const uint8_t *data, - uint16_t data_len, - const uint8_t *data2, - uint16_t data2_len, - uint8_t out[static 32]) { - cx_sha256_t hash_context; - cx_sha256_init(&hash_context); - - crypto_tr_tagged_hash_init(&hash_context, tag, tag_len); - - crypto_hash_update(&hash_context.header, data, data_len); - if (data2_len > 0) crypto_hash_update(&hash_context.header, data2, data2_len); - crypto_hash_digest(&hash_context.header, out, 32); +static void crypto_tr_tagged_hash(const uint8_t *tag, + uint16_t tag_len, + const uint8_t *data, + uint16_t data_len, + const uint8_t *data2, + uint16_t data2_len, + uint8_t out[static CX_SHA256_SIZE]) { + // First compute hashtag, reuse out buffer for that + cx_sha256_hash(tag, tag_len, out); + + cx_iovec_t iovec[4] = {{.iov_base = out, .iov_len = CX_SHA256_SIZE}, + {.iov_base = out, .iov_len = CX_SHA256_SIZE}, + {.iov_base = data, .iov_len = data_len}, + {.iov_base = data2, .iov_len = data2_len}}; + if (data2_len > 0) { + cx_sha256_hash_iovec(iovec, 4, out); + } else { + cx_sha256_hash_iovec(iovec, 3, out); + } } void crypto_tr_combine_taptree_hashes(const uint8_t left_h[static 32], diff --git a/src/cxram_stash.c b/src/cxram_stash.c index bd61a7aa7..1f3d819b3 100644 --- a/src/cxram_stash.c +++ b/src/cxram_stash.c @@ -3,14 +3,13 @@ #include "cxram_stash.h" #include "cx_ram.h" +#ifdef USE_CXRAM_SECTION #ifndef G_cx // The G_cx symbol is only defined in the sdk if compiled with certain libs are included. // This makes sure that the symbol exists nonetheless. union cx_u G_cx; #endif -#ifdef USE_CXRAM_SECTION - uint8_t *get_cxram_buffer() { return (uint8_t *) &G_cx; }