diff --git a/CHANGELOG.md b/CHANGELOG.md index 385c4737..88ceec09 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Change log +## [1.6.2] - 2024-01-30 +### Added +- + +### Changed +- Changed some function names to be more descriptive + +### Fixed +- + ## [1.6.1] - 2024-01-27 ### Added - Added a Release Policy document @@ -12,7 +22,7 @@ ### Fixed - Fixed failing Ledger rule enforcer check - Use `cx_crc32_hw()` - - Ledger have fixed their buggy implementation of so we can start using it again + - Ledger have fixed their buggy implementation of CRC32 so we can start using it again ## [1.6.0] - 2024-01-14 ### Added diff --git a/Makefile b/Makefile index 033d73f4..38573d10 100755 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ all: default APPNAME = "Seed Tool" APPVERSION_M = 1 APPVERSION_N = 6 -APPVERSION_P = 1 +APPVERSION_P = 2 APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)" APP_LOAD_PARAMS = --appFlags 0x10 $(COMMON_LOAD_PARAMS) --curve secp256k1 --path "" diff --git a/RELEASE_POLICY.md b/RELEASE_POLICY.md index f3c84926..14a4e7f1 100755 --- a/RELEASE_POLICY.md +++ b/RELEASE_POLICY.md @@ -1,18 +1,18 @@ Release Policy ============== -Every so often a new release is tagged on the master branch and is +Every so often a new release is tagged on the develop branch and is assigned a vX.Y.Z version number, where X is incremented each time a release contains breaking changes, Y is incremented on changes such as added features, and Z is incremented if a release contains only bugfixes and other minor changes. -Releases are tagged on the master branch and will not be maintained separately. -Releases may be made if the amount commits or severity of bugs justify it, or +Releases are tagged on the develop branch and will not be maintained separately. +Releases may be made if the amount of commits or severity of bugs justify it, or in the event of security issues. The goal of a release is to provide assets such as compiled app binaries. If you -want the newest features, just use the latest commit on the master branch. +want the newest features, just use the latest commit on the develop branch. We try our best to keep it deployable at all times. Releases other than the latest release are unsupported and unmaintained. @@ -20,7 +20,7 @@ Releases other than the latest release are unsupported and unmaintained. Release procedure ----------------- -While on the master branch: +While on the develop branch: - Update the `CHANGELOG` file, adding to the previous release notes. diff --git a/src/bc-sskr/LICENSE b/src/bc-sskr/LICENSE old mode 100755 new mode 100644 diff --git a/src/bc-sskr/bc-shamir/LICENSE b/src/bc-sskr/bc-shamir/LICENSE old mode 100755 new mode 100644 diff --git a/src/bc-sskr/bc-shamir/interpolate.c b/src/bc-sskr/bc-shamir/interpolate.c index 72d73290..17762679 100644 --- a/src/bc-sskr/bc-shamir/interpolate.c +++ b/src/bc-sskr/bc-shamir/interpolate.c @@ -117,7 +117,7 @@ static void hazmat_lagrange_basis(uint8_t *values, uint8_t n, const uint8_t *xc, */ int16_t interpolate(uint8_t n, // number of points to interpolate const uint8_t *xi, // x coordinates for points (array of length n) - uint32_t yl, // length of y coordinate array + uint8_t yl, // length of y coordinate array const uint8_t **yij, // n arrays of yl bytes representing y values uint8_t x, // x coordinate to interpolate uint8_t *result // space for yl bytes of results diff --git a/src/bc-sskr/bc-shamir/interpolate.h b/src/bc-sskr/bc-shamir/interpolate.h index 1e5790e6..a10004bb 100644 --- a/src/bc-sskr/bc-shamir/interpolate.h +++ b/src/bc-sskr/bc-shamir/interpolate.h @@ -32,7 +32,7 @@ */ int16_t interpolate(uint8_t n, // number of points to interpolate const uint8_t* xi, // x coordinates for points (array of length n) - uint32_t yl, // length of y coordinate array + uint8_t yl, // length of y coordinate array const uint8_t** yij, // n arrays of yl bytes representing y values uint8_t x, // x coordinate to interpolate uint8_t* result // space for yl bytes of results diff --git a/src/bc-sskr/bc-shamir/shamir.c b/src/bc-sskr/bc-shamir/shamir.c index 95425a97..39ada1f7 100644 --- a/src/bc-sskr/bc-shamir/shamir.c +++ b/src/bc-sskr/bc-shamir/shamir.c @@ -13,26 +13,9 @@ #define memzero(...) explicit_bzero(__VA_ARGS__) -////////////////////////////////////////////////// -// hmac sha256 - -uint8_t *create_digest(const uint8_t *random_data, - uint32_t rdlen, - const uint8_t *shared_secret, - uint32_t sslen, - uint8_t *result) { - uint8_t buf[32]; - - cx_hmac_sha256(random_data, rdlen, shared_secret, sslen, buf, sizeof(buf)); - - for (uint8_t j = 0; j < 4; ++j) { - result[j] = buf[j]; - } - - return result; -} - -static int16_t validate_parameters(uint8_t threshold, uint8_t share_count, uint8_t secret_length) { +static int16_t shamir_validate_parameters(uint8_t threshold, + uint8_t share_count, + uint8_t secret_length) { if (share_count > SHAMIR_MAX_SHARE_COUNT) { return SHAMIR_ERROR_TOO_MANY_SHARES; } else if (threshold < 1 || threshold > share_count) { @@ -47,6 +30,34 @@ static int16_t validate_parameters(uint8_t threshold, uint8_t share_count, uint8 return 0; } +////////////////////////////////////////////////// +// hmac sha256 +/** + * creates a digest used to help valididate secret reconstruction (see SLIP-39 docs) + * + * returns: a pointer to the resulting 4-byte digest + * inputs: random_data: array of data to create a digest for + * rdlen: length of random_data array + * shared_secret: bytes to use as the key for the hmac when generating digest + * sslen: length of the shared secret array + * result: a pointer to a block of 4 bytes to store the resulting digest + */ +uint8_t *shamir_create_digest(const uint8_t *random_data, + uint32_t rdlen, + const uint8_t *shared_secret, + uint32_t sslen, + uint8_t *result) { + uint8_t buf[32]; + + cx_hmac_sha256(random_data, rdlen, shared_secret, sslen, buf, sizeof(buf)); + + for (uint8_t j = 0; j < 4; ++j) { + result[j] = buf[j]; + } + + return result; +} + ////////////////////////////////////////////////// // shamir sharing int16_t shamir_split_secret(uint8_t threshold, @@ -55,7 +66,7 @@ int16_t shamir_split_secret(uint8_t threshold, uint8_t secret_length, uint8_t *result, unsigned char *(*random_generator)(uint8_t *, size_t)) { - int32_t err = validate_parameters(threshold, share_count, secret_length); + int16_t err = shamir_validate_parameters(threshold, share_count, secret_length); if (err) { return err; } @@ -86,7 +97,7 @@ int16_t shamir_split_secret(uint8_t threshold, // generate secret_length - 4 bytes worth of random data random_generator(digest + 4, secret_length - 4); // put 4 bytes of digest at the top of the digest array - create_digest(digest + 4, secret_length - 4, secret, secret_length, digest); + shamir_create_digest(digest + 4, secret_length - 4, secret, secret_length, digest); x[n] = DIGEST_INDEX; y[n] = digest; n += 1; @@ -115,7 +126,7 @@ int16_t shamir_recover_secret(uint8_t threshold, const uint8_t **shares, uint8_t share_length, uint8_t *secret) { - int32_t err = validate_parameters(threshold, threshold, share_length); + int16_t err = shamir_validate_parameters(threshold, threshold, share_length); if (err) { return err; } @@ -140,7 +151,7 @@ int16_t shamir_recover_secret(uint8_t threshold, return SHAMIR_ERROR_INTERPOLATION_FAILURE; } - create_digest(digest + 4, share_length - 4, secret, share_length, verify); + shamir_create_digest(digest + 4, share_length - 4, secret, share_length, verify); for (uint8_t i = 0; i < 4; i++) { valid &= digest[i] == verify[i]; diff --git a/src/bc-sskr/bc-shamir/shamir.h b/src/bc-sskr/bc-shamir/shamir.h index 956b53a2..9073d1d1 100644 --- a/src/bc-sskr/bc-shamir/shamir.h +++ b/src/bc-sskr/bc-shamir/shamir.h @@ -14,22 +14,6 @@ #define SECRET_INDEX 255 #define DIGEST_INDEX 254 -/** - * creates a digest used to help valididate secret reconstruction (see SLIP-39 docs) - * - * returns: a pointer to the resulting 4-byte digest - * inputs: random_data: array of data to create a digest for - * rdlen: length of random_data array - * shared_secret: bytes to use as the key for the hmac when generating digest - * sslen: length of the shared secret array - * result: a pointer to a block of 4 bytes to store the resulting digest - */ -uint8_t *create_digest(const uint8_t *random_data, - uint32_t rdlen, - const uint8_t *shared_secret, - uint32_t sslen, - uint8_t *result); - ////////////////////////////////////////////////// // Shamir Secret Sharing (based on SLIP-39) diff --git a/src/bc-sskr/sskr.c b/src/bc-sskr/sskr.c index 97e45136..e10c14a1 100644 --- a/src/bc-sskr/sskr.c +++ b/src/bc-sskr/sskr.c @@ -15,7 +15,7 @@ #define memzero(...) explicit_bzero(__VA_ARGS__) -static int16_t check_secret_length(uint8_t len) { +static int16_t sskr_check_secret_length(uint8_t len) { if (len < SSKR_MIN_STRENGTH_BYTES) { return SSKR_ERROR_SECRET_TOO_SHORT; } @@ -28,9 +28,9 @@ static int16_t check_secret_length(uint8_t len) { return 0; } -static int16_t serialize_shard(const sskr_shard *shard, - uint8_t *destination, - uint16_t destination_len) { +static int16_t sskr_serialize_shard(const sskr_shard *shard, + uint8_t *destination, + uint16_t destination_len) { if (destination_len < SSKR_METADATA_LENGTH_BYTES + shard->value_len) { return SSKR_ERROR_INSUFFICIENT_SPACE; } @@ -68,7 +68,9 @@ static int16_t serialize_shard(const sskr_shard *shard, return shard->value_len + SSKR_METADATA_LENGTH_BYTES; } -static int16_t deserialize_shard(const uint8_t *source, uint16_t source_len, sskr_shard *shard) { +static int16_t sskr_deserialize_shard(const uint8_t *source, + uint16_t source_len, + sskr_shard *shard) { if (source_len < SSKR_MIN_SERIALIZED_LENGTH_BYTES) { return SSKR_ERROR_NOT_ENOUGH_SERIALIZED_BYTES; } @@ -93,7 +95,7 @@ static int16_t deserialize_shard(const uint8_t *source, uint16_t source_len, ssk shard->value_len = source_len - SSKR_METADATA_LENGTH_BYTES; memcpy(shard->value, source + SSKR_METADATA_LENGTH_BYTES, shard->value_len); - int16_t err = check_secret_length(shard->value_len); + int16_t err = sskr_check_secret_length(shard->value_len); if (err) { return err; } @@ -132,15 +134,15 @@ int16_t sskr_count_shards(uint8_t group_threshold, ////////////////////////////////////////////////// // generate shards // -static int16_t generate_shards(uint8_t group_threshold, - const sskr_group_descriptor *groups, - uint8_t groups_len, - const uint8_t *master_secret, - uint16_t master_secret_len, - sskr_shard *shards, - uint16_t shards_size, - unsigned char *(*random_generator)(uint8_t *, size_t)) { - int16_t err = check_secret_length(master_secret_len); +static int16_t sskr_generate_shards(uint8_t group_threshold, + const sskr_group_descriptor *groups, + uint8_t groups_len, + const uint8_t *master_secret, + uint16_t master_secret_len, + sskr_shard *shards, + uint16_t shards_size, + unsigned char *(*random_generator)(uint8_t *, size_t)) { + int16_t err = sskr_check_secret_length(master_secret_len); if (err) { return err; } @@ -226,7 +228,7 @@ int16_t sskr_generate(uint8_t group_threshold, uint8_t *output, uint16_t buffer_size, unsigned char *(*random_generator)(uint8_t *, size_t)) { - int16_t err = check_secret_length(master_secret_len); + int16_t err = sskr_check_secret_length(master_secret_len); if (err) { return err; } @@ -250,14 +252,14 @@ int16_t sskr_generate(uint8_t group_threshold, sskr_shard shards[SHAMIR_MAX_SHARE_COUNT * SSKR_MAX_GROUP_COUNT]; // generate shards - total_shards = generate_shards(group_threshold, - groups, - groups_len, - master_secret, - master_secret_len, - shards, - (uint16_t) total_shards, - random_generator); + total_shards = sskr_generate_shards(group_threshold, + groups, + groups_len, + master_secret, + master_secret_len, + shards, + (uint16_t) total_shards, + random_generator); if (total_shards < 0) { error = total_shards; @@ -268,7 +270,7 @@ int16_t sskr_generate(uint8_t group_threshold, uint16_t byte_count = 0; for (uint16_t i = 0; !error && i < (uint16_t) total_shards; ++i) { - int16_t bytes = serialize_shard(&shards[i], cur_output, remaining_buffer); + int16_t bytes = sskr_serialize_shard(&shards[i], cur_output, remaining_buffer); if (bytes < 0) { error = bytes; break; @@ -301,7 +303,7 @@ typedef struct sskr_group_struct { * in place, so it is for internal use only, however it provides the implementation * for both combine_shards and sskr_combine. */ -static int16_t combine_shards_internal( +static int16_t sskr_combine_shards_internal( sskr_shard *shards, // array of shard structures uint8_t shards_count, // number of shards in array uint8_t *buffer, // working space, and place to return secret @@ -455,7 +457,7 @@ int16_t sskr_combine(const uint8_t **input_shards, // array of pointers to 10-b for (uint16_t i = 0; !result && i < shards_count; ++i) { shards[i].value_len = 32; - int16_t bytes = deserialize_shard(input_shards[i], shard_len, &shards[i]); + int16_t bytes = sskr_deserialize_shard(input_shards[i], shard_len, &shards[i]); if (bytes < 0) { result = bytes; @@ -463,7 +465,7 @@ int16_t sskr_combine(const uint8_t **input_shards, // array of pointers to 10-b } if (!result) { - result = combine_shards_internal(shards, shards_count, buffer, buffer_len); + result = sskr_combine_shards_internal(shards, shards_count, buffer, buffer_len); } memzero(shards, sizeof(shards));