Skip to content

Commit

Permalink
Changed all Variable Length Arrays to a defined length
Browse files Browse the repository at this point in the history
  • Loading branch information
aido committed Nov 15, 2023
1 parent 9883d3f commit cd52f51
Show file tree
Hide file tree
Showing 14 changed files with 75 additions and 61 deletions.
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
# Change log

## [1.5.2] - 2023-11-13
## [1.5.2] - 2023-11-15
### Added
-

### Changed
- Save memory by setting the SSKR word buffer to a sensible size
- There is just enough memory available on Nano S to hold the phrases for 10 shares. Other devices can hold the full 16 shares.
- Tidy up code that sets 'Processing' screen on Nano devices
- Tidied up code that sets 'Processing' screen on Nano S devices
- Changed all Variable Length Arrays to a defined length


### Fixed
- Fix screen freezing at 'Processing' screen on Nano devices
- Fix freezing at 'Processing' screen on Nano S devices

## [1.5.1] - 2023-11-09
### Added
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ ifeq ($(GCCPATH),)
endif

CC := $(CLANGPATH)clang
CFLAGS += -O3 -Os -Wshadow -Wformat -Wno-vla -DAPPNAME=\"$(APPNAME)\"
CFLAGS += -O3 -Os -Wshadow -Wformat -DAPPNAME=\"$(APPNAME)\"
AS := $(GCCPATH)arm-none-eabi-gcc
LD := $(GCCPATH)arm-none-eabi-gcc
LDFLAGS += -O3 -Os
Expand Down
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@
# Seed Tool: A Ledger application that provides some useful seed management utilities

[![Release](https://img.shields.io/github/release/aido/app-seed-tool)](https://github.com/aido/app-seed-tool/releases)
[![License](https://img.shields.io/github/license/aido/app-seed-tool)](https://github.com/aido/app-seed-tool/blob/develop/LICENSE)

![nanos](https://img.shields.io/badge/nanos-working-green)
![nanox](https://img.shields.io/badge/nanox-working-green])
![nanosp](https://img.shields.io/badge/nanosp-working-green)
![stax](https://img.shields.io/badge/stax-in_progress-orange)
[![License](https://img.shields.io/github/license/aido/app-seed-tool)](https://github.com/aido/app-seed-tool/blob/develop/LICENSE)

[![Build app-seed-tool](https://github.com/aido/app-seed-tool/actions/workflows/ci-workflow.yml/badge.svg)](https://github.com/aido/app-seed-tool/actions/workflows/ci-workflow.yml)
[![CodeQL](https://github.com/aido/app-seed-tool/actions/workflows/codeql-workflow.yml/badge.svg)](https://github.com/aido/app-seed-tool/actions/workflows/codeql-workflow.yml)
[![Code style check](https://github.com/aido/app-seed-tool/actions/workflows/lint-workflow.yml/badge.svg)](https://github.com/aido/app-seed-tool/actions/workflows/lint-workflow.yml)
[![Ledger rule enforcer](https://github.com/aido/app-seed-tool/actions/workflows/ledger-rule-enforcer.yml/badge.svg)](https://github.com/aido/app-seed-tool/actions/workflows/ledger-rule-enforcer.yml)
[![codecov](https://codecov.io/gh/aido/app-seed-tool/branch/develop/graph/badge.svg?token=uCkGEbhGl3)](https://codecov.io/gh/aido/app-seed-tool/tree/develop)

---

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.

## Check BIP39
Expand All @@ -24,6 +27,13 @@ The application invites the user to type a [BIP-39](https://github.com/bitcoin/b
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.
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 phrases use a dictionary of exactly 256 English words with a uniform word size of 4 letters
* SSKR encodes a [CBOR] structure tagged with the data type [URTYPES], and is therefore self-describing.
* Phrases generated by SSKR can be up to 46 words in length i.e. 184 characters.
* Only two letters of each word (the first and last) are required to uniquely identify each byte value, making a minimal [ByteWords](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-012-bytewords.md) encoding as efficient as hexadecimal (2 characters per byte) and yet less error prone.
* Additionally, words can be uniquely identified by their first three letters or last three letters
* Minimizing the number of letters for each word simplifies transfer to permanent media such as stamped metal

For more information about SSKR, see [SSKR for Users](https://github.com/BlockchainCommons/crypto-commons/blob/master/Docs/sskr-users.md).

> [!NOTE]
Expand Down
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
- [ ] There is just enough memory available on Nano S to hold the phrases for 10 shares. Maybe just store SSKR Bytewords as shorter two letter minimal Bytewords rather than a 4 letter Byteword plus space for each share. Convert minimal ByteWords back to four letter Bytewords just prior to display.
- [ ] If/when the `cx_bn_gf2_n_mul()` syscall is available on Ledger Nano S change all Galois Field functionality to use syscalls.
- See [gf_syscalls](https://github.com/aido/app-seed-tool/tree/gf_syscalls) branch of repo.
- Remove all variable length arrays

### In Progress

Expand All @@ -19,6 +18,7 @@

### Done ✓

- [x] Remove all Variable Length Arrays
- [x] Save memory by setting the SSKR word buffer (G_bolos_ux_context.sskr_words_buffer) to a sensible size
- [x] Add unit tests
- [x] Add code coverage to GitHub actions
Expand Down
8 changes: 4 additions & 4 deletions src/bc-sskr/bc-shamir/interpolate.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static void hazmat_lagrange_basis(uint8_t *values, uint8_t n, const uint8_t *xc,
uint8_t xx[32 + 16];
uint8_t i;

uint32_t x_slice[8], lxi[n][8];
uint32_t x_slice[8], lxi[SHAMIR_MAX_SHARE_COUNT][8];

uint32_t numerator[8], denominator[8], temp[8];

Expand Down Expand Up @@ -124,8 +124,8 @@ int16_t interpolate(uint8_t n, // number of points to interpolate
) {
// The hazmat gf256 implementation needs the y-coordinate data
// to be in 32-byte blocks
uint8_t *y[n];
uint8_t yv[SHAMIR_MAX_SECRET_SIZE * n];
uint8_t *y[SHAMIR_MAX_SHARE_COUNT];
uint8_t yv[SHAMIR_MAX_SECRET_SIZE * SHAMIR_MAX_SHARE_COUNT];
uint8_t values[SHAMIR_MAX_SECRET_SIZE];

memzero(yv, SHAMIR_MAX_SECRET_SIZE * n);
Expand All @@ -134,7 +134,7 @@ int16_t interpolate(uint8_t n, // number of points to interpolate
memcpy(y[i], yij[i], yl);
}

uint8_t lagrange[n];
uint8_t lagrange[SHAMIR_MAX_SHARE_COUNT];
uint32_t y_slice[8], result_slice[8], temp[8];

hazmat_lagrange_basis(lagrange, n, xi, x);
Expand Down
5 changes: 5 additions & 0 deletions src/bc-sskr/bc-shamir/shamir-constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
#ifndef SHAMIR_CONSTANTS_H
#define SHAMIR_CONSTANTS_H

#if defined(TARGET_NANOS)
#define SHAMIR_MAX_SHARE_COUNT 10
#else
#define SHAMIR_MAX_SHARE_COUNT 16
#endif
#define SHAMIR_MIN_SECRET_SIZE 16
#define SHAMIR_MAX_SECRET_SIZE 32

Expand Down
8 changes: 4 additions & 4 deletions src/bc-sskr/bc-shamir/shamir.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ int16_t shamir_split_secret(uint8_t threshold,
}
return share_count;
} else {
uint8_t digest[secret_length];
uint8_t x[16];
const uint8_t *y[16];
uint8_t digest[SHAMIR_MAX_SECRET_SIZE];
uint8_t x[SHAMIR_MAX_SHARE_COUNT];
const uint8_t *y[SHAMIR_MAX_SHARE_COUNT];
uint8_t n = 0;
uint8_t *share = result;

Expand Down Expand Up @@ -120,7 +120,7 @@ int16_t shamir_recover_secret(uint8_t threshold,
return err;
}

uint8_t digest[share_length];
uint8_t digest[SHAMIR_MAX_SECRET_SIZE];
uint8_t verify[4];
uint8_t valid = 1;

Expand Down
5 changes: 2 additions & 3 deletions src/bc-sskr/bc-shamir/shamir.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@
#include <stdint.h>
#include "shamir-constants.h"

#define SHAMIR_MAX_SHARE_COUNT 16
#define SECRET_INDEX 255
#define DIGEST_INDEX 254
#define SECRET_INDEX 255
#define DIGEST_INDEX 254

/**
* creates a digest used to help valididate secret reconstruction (see SLIP-39 docs)
Expand Down
3 changes: 3 additions & 0 deletions src/bc-sskr/sskr-constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
#ifndef SSKR_CONSTANTS_H
#define SSKR_CONSTANTS_H

#include "shamir-constants.h"

#define SSKR_METADATA_LENGTH_BYTES 5
#define SSKR_MIN_STRENGTH_BYTES 16
#define SSKR_MAX_STRENGTH_BYTES 32
#define SSKR_MAX_GROUP_COUNT 1
#define SSKR_MIN_SERIALIZED_LENGTH_BYTES (SSKR_METADATA_LENGTH_BYTES + SSKR_MIN_STRENGTH_BYTES)

#define SSKR_ERROR_NOT_ENOUGH_SERIALIZED_BYTES (-1)
Expand Down
21 changes: 11 additions & 10 deletions src/bc-sskr/sskr.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ static int16_t generate_shards(uint8_t group_threshold,
return SSKR_ERROR_INVALID_GROUP_THRESHOLD;
}

uint8_t group_shares[master_secret_len * groups_len];
uint8_t group_shares[SHAMIR_MAX_SECRET_SIZE * SSKR_MAX_GROUP_COUNT];

shamir_split_secret(group_threshold,
groups_len,
Expand All @@ -178,7 +178,7 @@ static int16_t generate_shards(uint8_t group_threshold,
sskr_shard *shard;

for (uint8_t i = 0; i < groups_len; ++i, group_share += master_secret_len) {
uint8_t member_shares[master_secret_len * groups[i].count];
uint8_t member_shares[SHAMIR_MAX_SECRET_SIZE * SHAMIR_MAX_SHARE_COUNT];
shamir_split_secret(groups[i].threshold,
groups[i].count,
group_share,
Expand Down Expand Up @@ -247,7 +247,7 @@ int16_t sskr_generate(uint8_t group_threshold,
int16_t error = 0;

// allocate space for shard representations
sskr_shard shards[total_shards];
sskr_shard shards[SHAMIR_MAX_SHARE_COUNT * SSKR_MAX_GROUP_COUNT];

// generate shards
total_shards = generate_shards(group_threshold,
Expand Down Expand Up @@ -292,8 +292,8 @@ typedef struct sskr_group_struct {
uint8_t group_index;
uint8_t member_threshold;
uint8_t count;
uint8_t member_index[16];
const uint8_t *value[16];
uint8_t member_index[SHAMIR_MAX_SHARE_COUNT];
const uint8_t *value[SHAMIR_MAX_SHARE_COUNT];
} sskr_group;

/**
Expand All @@ -317,7 +317,7 @@ static int16_t combine_shards_internal(
}

uint8_t next_group = 0;
sskr_group groups[16];
sskr_group groups[SSKR_MAX_GROUP_COUNT];
uint8_t secret_len = 0;

for (uint8_t i = 0; i < shards_count; ++i) {
Expand Down Expand Up @@ -376,11 +376,12 @@ static int16_t combine_shards_internal(
// here, all of the shards are unpacked into member groups. Now we go through each
// group and recover the group secret, and then use the result to recover the
// master secret
uint8_t gx[16];
const uint8_t *gy[16];
uint8_t gx[SHAMIR_MAX_SHARE_COUNT];
const uint8_t *gy[SHAMIR_MAX_SHARE_COUNT];

// allocate enough space for the group shards and the encrypted master secret
uint8_t group_shares[secret_len * (group_threshold + 1)];
uint8_t group_shares[SSKR_MAX_STRENGTH_BYTES * (SSKR_MAX_GROUP_COUNT + 1)];

uint8_t *group_share = group_shares;

for (uint8_t i = 0; !error && i < (uint8_t) next_group; ++i) {
Expand Down Expand Up @@ -449,7 +450,7 @@ int16_t sskr_combine(const uint8_t **input_shards, // array of pointers to 10-b
return SSKR_ERROR_EMPTY_SHARD_SET;
}

sskr_shard shards[shards_count];
sskr_shard shards[SHAMIR_MAX_SHARE_COUNT * SSKR_MAX_GROUP_COUNT];

for (uint16_t i = 0; !result && i < shards_count; ++i) {
shards[i].value_len = 32;
Expand Down
12 changes: 3 additions & 9 deletions src/stax/ui_stax.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ static void on_quit(void) {
/*
* About menu
*/
static const char *const infoTypes[] = {"Version", APPNAME};
static const char *const infoTypes[] = {"Version", "Seed Tool"};
static const char *const infoContents[] = {APPVERSION, "(c) 2023 Ledger"};

static bool on_infos(uint8_t page, nbgl_pageContent_t *content) {
Expand Down Expand Up @@ -411,18 +411,12 @@ static void display_bip39_keyboard_page() {
*/

static void display_settings_page() {
char infos[] = " infos";
size_t len = sizeof(APPNAME) + sizeof(infos);
char appname_infos[len];

strlcpy(appname_infos, APPNAME, len);
strlcat(appname_infos, infos, len);
nbgl_useCaseSettings(appname_infos, 0, 1, false, display_home_page, on_infos, NULL);
nbgl_useCaseSettings("Seed Tool infos", 0, 1, false, display_home_page, on_infos, NULL);
}

static void display_home_page() {
reset_globals();
nbgl_useCaseHomeExt(APPNAME,
nbgl_useCaseHomeExt("Seed Tool",
&C_seed_stax_64px,
"This app lets you enter a\nSecret Recovery Phrase and\ntest if it matches "
"the one\npresent on this Ledger Stax",
Expand Down
4 changes: 2 additions & 2 deletions src/ux_common/onboarding_seed_bip39.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void bolos_ux_bip39_mnemonic_to_seed(unsigned char* mnemonic,
unsigned char* seed) {
// Need to keep BIP39 mnemonic in case we want to generate SSKR from it
// It will be zeroed later if not needed
unsigned char mnemonic_hash[mnemonic_length];
unsigned char mnemonic_hash[257];
memcpy(mnemonic_hash, mnemonic, mnemonic_length);
unsigned char passphrase[BIP39_MNEMONIC_LENGTH + 4];
mnemonic_length =
Expand All @@ -38,7 +38,7 @@ void bolos_ux_bip39_mnemonic_to_seed(unsigned char* mnemonic,
BIP39_PBKDF2_ROUNDS,
seed,
64);
memzero(mnemonic_hash, mnemonic_length);
memzero(mnemonic_hash, sizeof(mnemonic_hash));
PRINTF("BIP39 seed:\n %.*H\n", 64, seed);
}

Expand Down
Loading

0 comments on commit cd52f51

Please sign in to comment.