Skip to content

Commit 644a297

Browse files
committed
fixes
1 parent 8d2c015 commit 644a297

14 files changed

Lines changed: 116 additions & 155 deletions

.github/workflows/main.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ jobs:
6565
make deps
6666
- name: Run CMake
6767
run: mkdir -p build && cd build && cmake -DCMAKE_BUILD_TYPE=Debug .. && make
68-
- run: make cpp_test
6968

7069
build_ledger:
7170
needs: configure

app/src/borsh.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,17 @@ extern "C" {
3030
#define OFFSET_U32 4
3131
#define OFFSET_U64 8
3232

33-
#define DEFINE_READ_UINT(bits) \
34-
static inline parser_error_t read_u##bits(parser_context_t *ctx, uint##bits##_t *val) { \
35-
CHECK_INPUT(ctx); \
36-
CHECK_INPUT(val); \
37-
*val = *(uint##bits##_t *)(ctx->buffer.ptr + ctx->offset); \
38-
CTX_CHECK_AND_ADVANCE(ctx, OFFSET_U##bits); \
39-
return parser_ok; \
33+
#define DEFINE_READ_UINT(bits) \
34+
static parser_error_t read_u##bits(parser_context_t *ctx, uint##bits##_t *val) { \
35+
CHECK_INPUT(ctx); \
36+
CHECK_INPUT(val); \
37+
*val = *(uint##bits##_t *)(ctx->buffer.ptr + ctx->offset); \
38+
CTX_CHECK_AND_ADVANCE(ctx, OFFSET_U##bits); \
39+
return parser_ok; \
4040
}
4141

4242
DEFINE_READ_UINT(8)
43-
DEFINE_READ_UINT(16)
43+
// DEFINE_READ_UINT(16) // Removed to fix unused function warning
4444
DEFINE_READ_UINT(32)
4545
DEFINE_READ_UINT(64)
4646

app/src/crypto_helper.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* (c) 2018 - 2023 Zondax AG
2+
* (c) 2018 - 2025 Zondax AG
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,7 +28,7 @@ picohash_ctx_t ctx;
2828

2929
zxerr_t crypto_sha256_init() {
3030
#if defined(LEDGER_SPECIFIC)
31-
memset(&ctx, 0, sizeof(ctx));
31+
MEMZERO(&ctx, sizeof(ctx));
3232
cx_sha256_init_no_throw(&ctx);
3333
#else
3434
picohash_init_sha256(&ctx);

app/src/parser_impl.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* (c) 2018 - 2023 Zondax AG
2+
* (c) 2018 - 2025 Zondax AG
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -37,8 +37,10 @@ extern "C" {
3737
}
3838

3939
#define CTX_CHECK_AND_ADVANCE(CTX, SIZE) \
40-
CTX_CHECK((CTX), (SIZE)) \
41-
(CTX)->offset += (SIZE);
40+
{ \
41+
CTX_CHECK((CTX), (SIZE)) \
42+
(CTX)->offset += (SIZE); \
43+
}
4244

4345
#define MAP_ZXERR_TO_PARSER_ERR(zxerr) \
4446
((zxerr) == zxerr_ok ? parser_ok \

app/src/schema_helper.c

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@
1919
#include "borsh.h"
2020
#include "schema_reader.h"
2121
/**
22-
* @brief Find an index in the indices array.
22+
* @brief Find the position of a given index in the indices array.
2323
*
24-
* @param index The index to find.
25-
* @param indices The indices array.
26-
* @return bool True if the index is found, false otherwise.
24+
* @param index_leaf The index value to search for.
25+
* @param indices Pointer to the indices array structure.
26+
* @param index_vec Output: position of the found index in the array (if found).
27+
* @param found Output: set to true if the index is found, false otherwise.
28+
* @return parser_error_t Error code indicating success or failure.
2729
*/
28-
bool schema_find_index(uint64_t index_leaf, merkle_leaves_indices_t *indices, uint64_t *index_vec) {
30+
parser_error_t schema_find_index(uint64_t index_leaf, merkle_leaves_indices_t *indices, uint64_t *index_vec, bool *found) {
2931
CHECK_INPUT(indices);
3032
CHECK_INPUT(index_vec);
3133

@@ -36,13 +38,15 @@ bool schema_find_index(uint64_t index_leaf, merkle_leaves_indices_t *indices, ui
3638
if (index_tmp == index_leaf) {
3739
*index_vec = i;
3840
indices->indices.offset = 0;
39-
return true;
41+
*found = true;
42+
return parser_ok;
4043
}
4144
}
4245

4346
// reset offset
4447
indices->indices.offset = 0;
45-
return false;
48+
*found = false;
49+
return parser_schema_index_not_found;
4650
}
4751

4852
/**
@@ -77,30 +81,44 @@ parser_error_t schema_reset_leaf_offset(merkle_leaves_data_t *leaves) {
7781
return parser_ok;
7882
}
7983

84+
/**
85+
* @brief Get the schema type of a given index in the transaction.
86+
*
87+
* @param txObj Pointer to the transaction object.
88+
* @param index The index to get the schema type for.
89+
* @param type Output: the schema type of the index.
90+
* @return parser_error_t Error code indicating success or failure.
91+
*/
8092
parser_error_t get_schema_type(parser_tx_t *txObj, uint32_t index, uint8_t *type) {
8193
CHECK_INPUT(txObj);
8294
CHECK_INPUT(type);
8395

84-
uint64_t mem_offset = txObj->merkle_proofs.leaves.data.offset;
85-
txObj->merkle_proofs.leaves.data.offset = 0;
96+
uint64_t mem_offset = txObj->merkle_proof.leaves.data.offset;
97+
txObj->merkle_proof.leaves.data.offset = 0;
8698

8799
uint64_t index_vec = 0;
88-
if (!schema_find_index(index, &txObj->merkle_proofs.indices, &index_vec)) {
89-
return parser_schema_index_not_found;
90-
}
100+
bool found = false;
101+
CHECK_ERROR(schema_find_index(index, &txObj->merkle_proof.indices, &index_vec, &found));
91102

92-
CHECK_ERROR(schema_move_leaf_offset(&txObj->merkle_proofs.leaves, index_vec));
103+
CHECK_ERROR(schema_move_leaf_offset(&txObj->merkle_proof.leaves, index_vec));
93104

94105
uint32_t len = 0;
95-
CHECK_ERROR(read_u32(&txObj->merkle_proofs.leaves.data, &len));
106+
CHECK_ERROR(read_u32(&txObj->merkle_proof.leaves.data, &len));
96107

97-
CHECK_ERROR(read_u8(&txObj->merkle_proofs.leaves.data, type));
108+
CHECK_ERROR(read_u8(&txObj->merkle_proof.leaves.data, type));
98109

99-
txObj->merkle_proofs.leaves.data.offset = mem_offset;
110+
txObj->merkle_proof.leaves.data.offset = mem_offset;
100111

101112
return parser_ok;
102113
}
103114

115+
/**
116+
* @brief Get the root index of the unsigned transaction.
117+
*
118+
* @param txObj Pointer to the transaction object.
119+
* @param root_index Output: the root index of the unsigned transaction.
120+
* @return parser_error_t Error code indicating success or failure.
121+
*/
104122
parser_error_t schema_get_unsigned_transaction_index(parser_tx_t *txObj, uint64_t *root_index) {
105123
CHECK_INPUT(txObj);
106124

@@ -117,6 +135,12 @@ parser_error_t schema_get_unsigned_transaction_index(parser_tx_t *txObj, uint64_
117135
return parser_ok;
118136
}
119137

138+
/**
139+
* @brief Check if a link is a skip link.
140+
*
141+
* @param link Pointer to the link structure.
142+
* @return bool True if the link is a skip link, false otherwise.
143+
*/
120144
bool is_link_skip(link_t *link) {
121145
if (link->tag == LINK_IMMEDIATE && link->data.immediate.type == PRIMITIVE_SKIP) {
122146
return true;

app/src/schema_helper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ extern "C" {
2222

2323
#include "parser_common.h"
2424

25-
bool schema_find_index(uint64_t index_leaf, merkle_leaves_indices_t *indices, uint64_t *index_vec);
25+
parser_error_t schema_find_index(uint64_t index_leaf, merkle_leaves_indices_t *indices, uint64_t *index_vec, bool *found);
2626
parser_error_t schema_move_leaf_offset(merkle_leaves_data_t *leaves, uint64_t index);
2727
parser_error_t schema_reset_leaf_offset(merkle_leaves_data_t *leaves);
2828
parser_error_t get_schema_type(parser_tx_t *txObj, uint32_t index, uint8_t *type);

app/src/schema_proof.c

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* (c) 2018 - 2024 Zondax AG
2+
* (c) 2018 - 2025 Zondax AG
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -94,9 +94,11 @@ parser_error_t compute_tree_size(uint32_t num_right_siblings, uint32_t index_of_
9494
}
9595

9696
/**
97-
* @brief Compute the hash of a leaf node in the proof.
97+
* @brief Compute the hash of a leaf node at a given index in the leaves data.
9898
*
99-
* @param proof The proof structure containing the leaf node.
99+
* @param leaves Pointer to the merkle_leaves_data_t structure containing the leaves data.
100+
* @param index The index of the leaf to hash.
101+
* @param hash Output buffer for the computed hash (must be at least CX_SHA256_SIZE bytes).
100102
* @return parser_error_t Error code indicating the result of the operation.
101103
*/
102104
static parser_error_t hash_index_leaf(merkle_leaves_data_t *leaves, uint64_t index, uint8_t *hash) {
@@ -164,28 +166,32 @@ static parser_error_t get_next_lemma_hash(merkle_lemmas_t *lemmas, uint8_t *hash
164166
}
165167

166168
/**
167-
* @brief Check if there are leaves in the range.
169+
* @brief Check if there are leaves in the specified range.
168170
*
169-
* @param start The start index.
170-
* @param end The end index.
171-
* @param indices The indices array.
172-
* @return bool True if there are leaves in the range, false otherwise.
171+
* @param start The start index (inclusive).
172+
* @param end The end index (exclusive).
173+
* @param indices Pointer to the merkle_leaves_indices_t structure containing the leaf indices.
174+
* @param has_leaves Output pointer; set to true if there are leaves in the range, false otherwise.
175+
* @return parser_error_t Error code indicating the result of the operation.
173176
*/
174-
bool has_leaves(uint64_t start, uint64_t end, merkle_leaves_indices_t *indices) {
177+
static parser_error_t has_leaves(uint64_t start, uint64_t end, merkle_leaves_indices_t *indices, bool *has_leaves) {
175178
CHECK_INPUT(indices);
179+
CHECK_INPUT(has_leaves);
176180

177181
for (uint64_t i = 0; i < indices->entries; i++) {
178182
uint64_t index_tmp = 0;
179183
CHECK_ERROR(read_u64(&indices->indices, &index_tmp));
180184
if (index_tmp >= start && index_tmp < end) {
181185
indices->indices.offset = 0;
182-
return true;
186+
*has_leaves = true;
187+
return parser_ok;
183188
}
184189
}
185190

186191
// reset offset
187192
indices->indices.offset = 0;
188-
return false;
193+
*has_leaves = false;
194+
return parser_ok;
189195
}
190196

191197
/**
@@ -194,6 +200,7 @@ bool has_leaves(uint64_t start, uint64_t end, merkle_leaves_indices_t *indices)
194200
* @param proof The proof structure containing the necessary data.
195201
* @param index_start The start index.
196202
* @param index_end The end index.
203+
* @param hash Output buffer for the computed hash (must be at least CX_SHA256_SIZE bytes).
197204
* @return parser_error_t Error code indicating the result of the operation.
198205
*/
199206
static parser_error_t verify_multiproof_inner(proof_t *proof, uint64_t index_start, uint64_t index_end, uint8_t *hash) {
@@ -207,9 +214,10 @@ static parser_error_t verify_multiproof_inner(proof_t *proof, uint64_t index_sta
207214
// If this is a single node, return the hash of the node
208215
if (index_end - index_start == 1) {
209216
uint64_t index_vec = 0;
210-
if (schema_find_index(index_start, &proof->indices, &index_vec)) {
217+
bool found = false;
218+
CHECK_ERROR(schema_find_index(index_start, &proof->indices, &index_vec, &found));
219+
if (found) {
211220
CHECK_ERROR(hash_index_leaf(&proof->leaves, index_vec, hash));
212-
213221
return parser_ok;
214222
}
215223

@@ -223,8 +231,10 @@ static parser_error_t verify_multiproof_inner(proof_t *proof, uint64_t index_sta
223231
return parser_unexpected_buffer_end;
224232
}
225233

226-
bool left_has_leaves = has_leaves(index_start, mid, &proof->indices);
227-
bool right_has_leaves = has_leaves(mid, index_end, &proof->indices);
234+
bool left_has_leaves = false;
235+
bool right_has_leaves = false;
236+
CHECK_ERROR(has_leaves(index_start, mid, &proof->indices, &left_has_leaves));
237+
CHECK_ERROR(has_leaves(mid, index_end, &proof->indices, &right_has_leaves));
228238

229239
// Check left subtree
230240
CHECK_ERROR(checkStack());
@@ -253,8 +263,8 @@ static parser_error_t verify_multiproof_inner(proof_t *proof, uint64_t index_sta
253263
/**
254264
* @brief Compute the root hash for a given metadata structure.
255265
*
256-
* @param metadata The metadata structure containing the necessary data.
257-
* @param metadataDigest The output buffer for the computed metadata digest.
266+
* @param metadata Pointer to the merkle_proof_t structure containing the necessary data.
267+
* @param hash Output buffer for the computed root hash (must be at least CX_SHA256_SIZE bytes).
258268
* @return parser_error_t Error code indicating the result of the operation.
259269
*/
260270
parser_error_t get_root_hash(const merkle_proof_t *metadata, uint8_t *hash) {

app/src/schema_proof.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* (c) 2018 - 2024 Zondax AG
2+
* (c) 2018 - 2025 Zondax AG
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -35,7 +35,6 @@ typedef struct {
3535
uint64_t tree_size;
3636
} proof_t;
3737

38-
parser_error_t get_single_root_hash(const merkle_proof_t *metadata, uint8_t metadataDigest[CX_SHA256_SIZE]);
3938
parser_error_t verify_merkle_proofs(const merkle_proof_t *metadata);
4039

4140
#ifdef __cplusplus

app/src/schema_reader.c

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,7 @@ parser_error_t compute_chain_hash(parser_tx_t *txObj) {
746746
CHECK_ERROR(compute_internal_data_hash(txObj, internal_data_hash));
747747

748748
crypto_sha256_init();
749-
crypto_sha256_update(txObj->merkle_proofs.root_hash.ptr, txObj->merkle_proofs.root_hash.len);
749+
crypto_sha256_update(txObj->merkle_proof.root_hash.ptr, txObj->merkle_proof.root_hash.len);
750750
crypto_sha256_update(internal_data_hash, CX_SHA256_SIZE);
751751
crypto_sha256_update(txObj->schema.extra_metadata_hash.ptr, txObj->schema.extra_metadata_hash.len);
752752
crypto_sha256_final(computed_chain_hash);
@@ -763,49 +763,49 @@ parser_error_t schema_merkle_proofs_read(parser_context_t *ctx, parser_tx_t *txO
763763
CHECK_INPUT(txObj);
764764

765765
// read leaf data
766-
CHECK_ERROR(read_u32(ctx, &txObj->merkle_proofs.leaves.entries));
766+
CHECK_ERROR(read_u32(ctx, &txObj->merkle_proof.leaves.entries));
767767
const uint8_t *ptr_mem = ctx->buffer.ptr + ctx->offset;
768768
uint16_t offset_mem = ctx->offset;
769-
for (uint32_t i = 0; i < txObj->merkle_proofs.leaves.entries; i++) {
769+
for (uint32_t i = 0; i < txObj->merkle_proof.leaves.entries; i++) {
770770
uint32_t length = 0;
771771
CHECK_ERROR(read_u32(ctx, &length));
772772
uint8_t schema_type = 0;
773773
CHECK_ERROR(read_u8(ctx, (uint8_t *)&schema_type));
774774
CHECK_ERROR(read_schema_type(ctx, schema_type));
775775
}
776776

777-
txObj->merkle_proofs.leaves.data.buffer.ptr = ptr_mem;
778-
txObj->merkle_proofs.leaves.data.buffer.len = ctx->offset - offset_mem;
777+
txObj->merkle_proof.leaves.data.buffer.ptr = ptr_mem;
778+
txObj->merkle_proof.leaves.data.buffer.len = ctx->offset - offset_mem;
779779

780780
// read indices
781-
CHECK_ERROR(read_u32(ctx, &txObj->merkle_proofs.indices.entries));
782-
if (txObj->merkle_proofs.indices.entries != txObj->merkle_proofs.leaves.entries) {
781+
CHECK_ERROR(read_u32(ctx, &txObj->merkle_proof.indices.entries));
782+
if (txObj->merkle_proof.indices.entries != txObj->merkle_proof.leaves.entries) {
783783
return parser_schema_merkle_proofs_indices_mismatch;
784784
}
785785
const uint8_t *ptr_mem_indices = ctx->buffer.ptr + ctx->offset;
786786
uint16_t offset_mem_indices = ctx->offset;
787-
for (uint32_t i = 0; i < txObj->merkle_proofs.indices.entries; i++) {
787+
for (uint32_t i = 0; i < txObj->merkle_proof.indices.entries; i++) {
788788
uint64_t index = 0;
789789
CHECK_ERROR(read_u64(ctx, &index));
790790
}
791-
txObj->merkle_proofs.indices.indices.buffer.ptr = ptr_mem_indices;
792-
txObj->merkle_proofs.indices.indices.buffer.len = ctx->offset - offset_mem_indices;
791+
txObj->merkle_proof.indices.indices.buffer.ptr = ptr_mem_indices;
792+
txObj->merkle_proof.indices.indices.buffer.len = ctx->offset - offset_mem_indices;
793793

794794
// read lemmas
795-
CHECK_ERROR(read_u32(ctx, &txObj->merkle_proofs.lemmas.entries));
796-
txObj->merkle_proofs.lemmas.data.buffer.ptr = ctx->buffer.ptr + ctx->offset;
797-
txObj->merkle_proofs.lemmas.data.buffer.len = txObj->merkle_proofs.lemmas.entries * 32;
798-
CTX_CHECK_AND_ADVANCE(ctx, txObj->merkle_proofs.lemmas.data.buffer.len);
795+
CHECK_ERROR(read_u32(ctx, &txObj->merkle_proof.lemmas.entries));
796+
txObj->merkle_proof.lemmas.data.buffer.ptr = ctx->buffer.ptr + ctx->offset;
797+
txObj->merkle_proof.lemmas.data.buffer.len = txObj->merkle_proof.lemmas.entries * 32;
798+
CTX_CHECK_AND_ADVANCE(ctx, txObj->merkle_proof.lemmas.data.buffer.len);
799799

800800
// read tree_size
801-
CHECK_ERROR(read_u64(ctx, &txObj->merkle_proofs.tree_size));
801+
CHECK_ERROR(read_u64(ctx, &txObj->merkle_proof.tree_size));
802802

803803
// read root_hash
804-
txObj->merkle_proofs.root_hash.ptr = ctx->buffer.ptr + ctx->offset;
805-
txObj->merkle_proofs.root_hash.len = CX_SHA256_SIZE;
806-
CTX_CHECK_AND_ADVANCE(ctx, txObj->merkle_proofs.root_hash.len);
804+
txObj->merkle_proof.root_hash.ptr = ctx->buffer.ptr + ctx->offset;
805+
txObj->merkle_proof.root_hash.len = CX_SHA256_SIZE;
806+
CTX_CHECK_AND_ADVANCE(ctx, txObj->merkle_proof.root_hash.len);
807807

808-
CHECK_ERROR(verify_merkle_proofs(&txObj->merkle_proofs));
808+
CHECK_ERROR(verify_merkle_proofs(&txObj->merkle_proof));
809809

810810
return parser_ok;
811811
}

0 commit comments

Comments
 (0)