From 906222e2222315c72b24beeec7551e9ef57001a1 Mon Sep 17 00:00:00 2001 From: neithanmo Date: Fri, 18 Oct 2024 02:21:55 -0600 Subject: [PATCH] Use proper error types and silence unused warnings Define a common field type to be used in other parts of the parser Fix unused warning Add spend action and helper types definitions Add decode function for spend plans add spend error --- app/src/apdu_handler.c | 4 +-- app/src/c_api/rust.c | 19 ++++++----- app/src/common/parser_common.h | 2 ++ app/src/parser_pb_utils.c | 54 +++++++++++++++++++++++++++++++ app/src/parser_pb_utils.h | 54 +++++++++++++++++++++++++++++++ app/src/parser_txdef.h | 40 +++++++++++++++++++++-- app/src/spend_plan.c | 59 ++++++++++++++++++++++++++++++++++ app/src/spend_plan.h | 42 ++++++++++++++++++++++++ 8 files changed, 262 insertions(+), 12 deletions(-) create mode 100644 app/src/parser_pb_utils.c create mode 100644 app/src/parser_pb_utils.h create mode 100644 app/src/spend_plan.c create mode 100644 app/src/spend_plan.h diff --git a/app/src/apdu_handler.c b/app/src/apdu_handler.c index a3ae0c78..a68d39e4 100644 --- a/app/src/apdu_handler.c +++ b/app/src/apdu_handler.c @@ -174,8 +174,8 @@ __Z_INLINE void handleSign(volatile uint32_t *flags, volatile uint32_t *tx, uint THROW(APDU_CODE_OK); } - const char *error_msg = tx_parse(); - // CHECK_APP_CANARY() + __Z_UNUSED const char *error_msg = tx_parse(); + CHECK_APP_CANARY() // if (error_msg != NULL) { // const int error_msg_length = strnlen(error_msg, sizeof(G_io_apdu_buffer)); // memcpy(G_io_apdu_buffer, error_msg, error_msg_length); diff --git a/app/src/c_api/rust.c b/app/src/c_api/rust.c index 77889250..a6a0f973 100644 --- a/app/src/c_api/rust.c +++ b/app/src/c_api/rust.c @@ -2,22 +2,25 @@ #include #include "crypto.h" +#include "zxmacros.h" zxerr_t crypto_extractSpendingKeyBytes(uint8_t *key_bytes, uint32_t key_bytes_len); // Function to compute BLAKE2b hash with personalization -int8_t blake2b_hash_with_personalization(const uint8_t *input, size_t input_len, uint8_t *output, size_t output_len, +zxerr_t blake2b_hash_with_personalization(const uint8_t *input, size_t input_len, uint8_t *output, size_t output_len, const uint8_t *label, size_t label_len) { cx_blake2b_t hash_context; - unsigned char *salt = NULL; - unsigned int salt_len = 0; + // unsigned char *salt = NULL; + // unsigned int salt_len = 0; + + zxerr_t error = zxerr_invalid_crypto_settings; // no salt - if (cx_blake2b_init2_no_throw(&hash_context, output_len * 8, NULL, 0, label, label_len) != CX_OK) { - return -1; - } - cx_hash(&hash_context.header, CX_LAST, input, input_len, output, output_len); + CATCH_CXERROR(cx_blake2b_init2_no_throw(&hash_context, output_len * 8, NULL, 0, (uint8_t *)label, label_len)); + + CATCH_CXERROR(cx_hash_no_throw(&hash_context.header, CX_LAST, input, input_len, output, output_len)); - return 0; +catch_cx_error: + return error; } diff --git a/app/src/common/parser_common.h b/app/src/common/parser_common.h index fd13ad8c..2f5ef533 100644 --- a/app/src/common/parser_common.h +++ b/app/src/common/parser_common.h @@ -31,6 +31,7 @@ extern "C" { if (__err != parser_ok) return __err; \ } + // Convert bytes to uint32_t, // assume data is in BE format #define U32_BE(buffer, number) \ @@ -64,6 +65,7 @@ typedef enum { paser_unknown_transaction, parser_detection_data_overflow, parser_actions_overflow, + parser_spend_plan_error, } parser_error_t; typedef struct { diff --git a/app/src/parser_pb_utils.c b/app/src/parser_pb_utils.c new file mode 100644 index 00000000..9f48bd1a --- /dev/null +++ b/app/src/parser_pb_utils.c @@ -0,0 +1,54 @@ +/******************************************************************************* + * (c) 2018 - 2023 Zondax AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ********************************************************************************/ + +#include "parser_impl.h" + +#include "parser_interface.h" +#include "zxformat.h" +#include "parser_pb_utils.h" + + +bool decode_fixed_field(pb_istream_t *stream, const pb_field_t *field, void **arg) +{ + if (stream->bytes_left == 0 || arg == NULL) + return false; + + fixed_size_field_t *decode_arg = (fixed_size_field_t *)*arg; + if (decode_arg == NULL || decode_arg->bytes == NULL) { + return false; + } + + if (decode_arg->check_size && stream->bytes_left != decode_arg->expected_size) { + return false; + } + + const uint8_t *first_byte = stream->state; + uint16_t data_size = stream->bytes_left; + + decode_arg->bytes->ptr = first_byte; + decode_arg->bytes->len = data_size; + + return true; +} + +void setup_decode_fixed_field(pb_callback_t *callback, fixed_size_field_t *arg, Bytes_t *bytes, uint16_t expected_size, bool check_size) { + arg->bytes = bytes; + arg->expected_size = expected_size; + arg->check_size = check_size; + callback->funcs.decode = &decode_fixed_field; + callback->arg = arg; +} + diff --git a/app/src/parser_pb_utils.h b/app/src/parser_pb_utils.h new file mode 100644 index 00000000..01d678c1 --- /dev/null +++ b/app/src/parser_pb_utils.h @@ -0,0 +1,54 @@ +/******************************************************************************* + * (c) 2018 - 2023 Zondax AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ********************************************************************************/ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include +#include + +#include "parser_common.h" +#include "parser_txdef.h" +#include "zxtypes.h" + +#include "pb_common.h" +#include "pb_decode.h" +#include "protobuf/penumbra/core/transaction/v1/transaction.pb.h" + +typedef struct { + Bytes_t *bytes; + uint16_t expected_size; + bool check_size; +} fixed_size_field_t; + +// Callback to parse binding fields in spend plans. all those fields are just +// 32-bytes data array that later in rust can be converted into +// Fq, Fr types +bool decode_fixed_field(pb_istream_t *stream, const pb_field_t *field, void **arg); + +void setup_decode_fixed_field(pb_callback_t *callback, fixed_size_field_t *arg, Bytes_t *bytes, uint16_t expected_size, bool check_size); + + +#ifdef __cplusplus +} +#endif + + diff --git a/app/src/parser_txdef.h b/app/src/parser_txdef.h index 82475df1..5d570e7b 100644 --- a/app/src/parser_txdef.h +++ b/app/src/parser_txdef.h @@ -31,20 +31,56 @@ extern "C" { #define DETECTION_DATA_QTY 16 #define ACTIONS_QTY 16 +#define ASSET_ID_LEN 32 +#define RSEED_LEN 32 + typedef struct { const uint8_t *ptr; uint16_t len; } Bytes_t; typedef struct { - Bytes_t parameters; -} transaction_parameters_t; + uint64_t lo; + uint64_t hi; +} amount_t; + +typedef struct { + Bytes_t inner; +} asset_id_t; + +typedef struct { + amount_t amount; + asset_id_t asset_id; +} value_t; typedef struct { Bytes_t inner; + // Field bellow is a sort of optional + // and is a shortcut for the case address is already + // bech32m encoded Bytes_t alt_bech32m; } address_plan_t; +typedef struct { + value_t value; + Bytes_t rseed; + address_plan_t address; +} note_t; + +typedef struct { + note_t note; + uint64_t position; + Bytes_t randomizer; + Bytes_t value_blinding; + Bytes_t proof_blinding_r; + Bytes_t proof_blinding_s; +} spend_plan_t; + + +typedef struct { + Bytes_t parameters; +} transaction_parameters_t; + typedef struct { address_plan_t return_address; Bytes_t text; diff --git a/app/src/spend_plan.c b/app/src/spend_plan.c new file mode 100644 index 00000000..8bc78b7d --- /dev/null +++ b/app/src/spend_plan.c @@ -0,0 +1,59 @@ +/******************************************************************************* + * (c) 2018 - 2023 Zondax AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ********************************************************************************/ + +#include "parser_impl.h" +#include "parser_interface.h" +#include "pb_common.h" +#include "pb_decode.h" +#include "protobuf/penumbra/core/transaction/v1/transaction.pb.h" + +#include "parser_interface.h" +#include "zxformat.h" +#include "parser_pb_utils.h" + +parser_error_t decode_spend_plan(const Bytes_t *data, spend_plan_t *output) { + penumbra_core_component_shielded_pool_v1_SpendPlan spend_plan = penumbra_core_component_shielded_pool_v1_SpendPlan_init_default; + + pb_istream_t spend_stream = pb_istream_from_buffer(data->ptr, data->len); + CHECK_APP_CANARY() + + + // Set up fixed size fields + fixed_size_field_t randomizer_arg, value_blinding_arg, proof_blinding_r_arg, proof_blinding_s_arg; + + setup_decode_fixed_field(&spend_plan.randomizer, &randomizer_arg, &output->randomizer, 32, true); + setup_decode_fixed_field(&spend_plan.value_blinding, &value_blinding_arg, &output->value_blinding, 32, true); + setup_decode_fixed_field(&spend_plan.proof_blinding_r, &proof_blinding_r_arg, &output->proof_blinding_r, 32, true); + setup_decode_fixed_field(&spend_plan.proof_blinding_s, &proof_blinding_s_arg, &output->proof_blinding_s, 32, true); + setup_decode_fixed_field(&spend_plan.proof_blinding_s, &proof_blinding_s_arg, &output->proof_blinding_s, 32, true); + + // asset_id in Note + fixed_size_field_t asset_id_arg; + setup_decode_fixed_field(&spend_plan.note.value.asset_id.inner, &asset_id_arg, &output->note.value.asset_id.inner, ASSET_ID_LEN, true); + // rseed in Note + fixed_size_field_t rseed_arg; + setup_decode_fixed_field(&spend_plan.note.rseed, &rseed_arg, &output->note.rseed, RSEED_LEN, true); + + if (!pb_decode(&spend_stream, penumbra_core_component_shielded_pool_v1_SpendPlan_fields, &spend_plan)) { + return parser_spend_plan_error; + } + + output->note.value.amount.lo = spend_plan.note.value.amount.lo; + output->note.value.amount.hi = spend_plan.note.value.amount.hi; + output->position = spend_plan.position; + + return parser_ok; +} diff --git a/app/src/spend_plan.h b/app/src/spend_plan.h new file mode 100644 index 00000000..18b500c8 --- /dev/null +++ b/app/src/spend_plan.h @@ -0,0 +1,42 @@ +/******************************************************************************* + * (c) 2018 - 2023 Zondax AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ********************************************************************************/ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include +#include + +#include "parser_common.h" +#include "parser_txdef.h" +#include "zxtypes.h" + +#include "pb_common.h" +#include "pb_decode.h" +#include "protobuf/penumbra/core/transaction/v1/transaction.pb.h" + +parser_error_t decode_spend_plan(const Bytes_t *input, spend_plan_t *spend_plan); + + +#ifdef __cplusplus +} +#endif +