From 9a3041ba6e96c7858fdaafb35761efb8715e9250 Mon Sep 17 00:00:00 2001 From: Aido Date: Sun, 14 Jan 2024 21:20:01 +0000 Subject: [PATCH] Added a cx_crc32() function The implementation of cx_crc32_hw() on Ledger devices is buggy and produces incorrect CRC32 checks. Ledger are fixing cx_crc32_hw() on each device either through SDK or OS updates but until then cx_crc32() can be used. --- CHANGELOG.md | 4 +++- Makefile | 4 ++-- README.md | 15 +++++++++++++-- src/ux_common/onboarding_seed_sskr.c | 24 ++++++++++++++++++++++-- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e771d328..6bf654ad 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,10 @@ # Change log -## [1.5.5] - 2023-12-10 +## [1.6.0] - 2024-01-14 ### Added - Use CX_CHECK macro in compare_recovery_phrase() +- Added a `cx_crc32()` function + - The implementation of `cx_crc32_hw()` on Ledger devices is buggy and produces incorrect CRC32 checks. Ledger are fixing `cx_crc32_hw()` on each device either through SDK or OS updates but until then `cx_crc32()` can be used. ### Changed - diff --git a/Makefile b/Makefile index 58673edb..2bbcb5a9 100755 --- a/Makefile +++ b/Makefile @@ -27,8 +27,8 @@ all: default APPNAME = "Seed Tool" APPVERSION_M = 1 -APPVERSION_N = 5 -APPVERSION_P = 5 +APPVERSION_N = 6 +APPVERSION_P = 0 APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)" APP_LOAD_PARAMS = --appFlags 0x10 $(COMMON_LOAD_PARAMS) --curve secp256k1 --path "" diff --git a/README.md b/README.md index 8bf31709..722aad0a 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,22 @@ Use the utilities provided by this Ledger application to check a backed up seed or generate [Shamir's Secret Sharing (SSS)](https://en.wikipedia.org/wiki/Shamir%27s_secret_sharing) for a seed. +Not all Ledger devices are equal. The older, less capable devices do not have the capacity to provide a full range of seed utilities. The following table lists the seed utilities provided by each devices type: +
+ +||Nano S|Nano S+|Nano X|Stax| +| :--- | :---: | :---: | :---: | :---: | +|[Check BIP39](#check-bip39)|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{green}✓}$$| +|[Check Shamir's secret shares](#check-shamirs-secret-shares)|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{green}✓}$$| +|[Generate Shamir's secret sharing](#generate-shamirs-secret-sharing)|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{green}✓}$$| +|[Generate BIP85](#generate-bip85)|$${\color{red}✗}$$|$${\color{green}✓}$$|$${\color{green}✓}$$|$${\color{green}✓}$$| +
+ ## Check BIP39 The application invites the user to type a [BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) mnemonic on their Ledger device. The BIP-39 mnemonic is compared to the onboarded seed and the application notifies the user whether both seeds match or not. ## Generate Shamir's secret sharing -When the seed is validated, the user can create [Shamir's secret sharing (SSS)](https://en.wikipedia.org/wiki/Shamir%27s_secret_sharing) from the BIP-39 phrase that they provided. +If the user provided seed is valid and matches the onboarded seed, the user can create [Shamir's secret sharing (SSS)](https://en.wikipedia.org/wiki/Shamir%27s_secret_sharing) from their BIP-39 phrase. The application uses [Sharded Secret Key Reconstruction (SSKR)](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-011-sskr.md), an interoperable implementation of [Shamir's Secret Sharing (SSS)](https://en.wikipedia.org/wiki/Shamir%27s_secret_sharing). This provides a way for you to divide or 'shard' the master seed underlying a Bitcoin HD wallet into 'shares', which you can then distribute to friends, family, or fiduciaries. If you lose your seed, you can reconstruct it by collecting a sufficient number of your shares (the 'threshold'). Knowledge of fewer than the required number of parts ensures that information about the master secret is not leaked. * SSKR is round-trip compatible with BIP-39. @@ -66,7 +77,7 @@ flowchart LR 1.1 --> 1.2.1[Enter 12 Words] --> 1.3{Validate BIP39 Phrases} 1.1 --> 1.2.2[Enter 18 Words] --> 1.3 1.1 --> 1.2.3[Enter 24 Words] --> 1.3 - 1.3 --> |Valid BIP39| 1.4 + 1.3 --> |Matching BIP39| 1.4 1.3 --> |Invalid BIP39| 1.3.1[Quit] subgraph 1.4[Generate SSKR Shares] direction TB diff --git a/src/ux_common/onboarding_seed_sskr.c b/src/ux_common/onboarding_seed_sskr.c index 0544733a..3baf5cb7 100644 --- a/src/ux_common/onboarding_seed_sskr.c +++ b/src/ux_common/onboarding_seed_sskr.c @@ -8,12 +8,32 @@ #include "common_bip39.h" #include "sskr.h" +// NOTE: +// The implementation of cx_crc32_hw() on Ledger devices is buggy and produces incorrect CRC32 +// checks. Ledger are fixing cx_crc32_hw() on each device either through SDK or OS updates. +// The following function is a temporary workaround that can be removed once cx_crc32_hw() +// works on all Ledger devices + +uint32_t cx_crc32(const uint8_t *data, size_t len) { + uint32_t crc = ~0; + const uint8_t *end = data + len; + + while (data < end) { + crc ^= *data++; + for (uint8_t i = 0; i < 8; i++) { + uint32_t mask = ~((crc & 1) - 1); + crc = (crc >> 1) ^ (0xEDB88320 & mask); + } + } + return ~crc; +} + // Returns the CRC-32 checksum of the input buffer in network byte order (big endian). uint32_t cx_crc32_hw_nbo(const uint8_t *bytes, size_t len) { #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - return cx_crc32_hw(bytes, len); + return cx_crc32(bytes, len); #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - return os_swap_u32(cx_crc32_hw(bytes, len)); + return os_swap_u32(cx_crc32(bytes, len)); #else #error "What kind of system is this?" #endif