diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index db97ec7..09fd099 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -31,7 +31,7 @@ jobs: lcov --directory . -b "$(realpath build/)" --capture --initial -o coverage.base && \ lcov --rc lcov_branch_coverage=1 --directory . -b "$(realpath build/)" --capture -o coverage.capture && \ lcov --directory . -b "$(realpath build/)" --add-tracefile coverage.base --add-tracefile coverage.capture -o coverage.info && \ - lcov --directory . -b "$(realpath build/)" --remove coverage.info '*/unit-tests/*,*/import/*' -o coverage.info && \ + lcov --directory . -b "$(realpath build/)" --remove coverage.info '*/unit-tests/*' --remove coverage.info 'lib_standard_app' --remove coverage.info '*/src/import/*' -o coverage.info && \ genhtml coverage.info -o coverage - uses: actions/upload-artifact@v3 diff --git a/.vscode/settings.json b/.vscode/settings.json index a62eb6b..4bbe9e2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,7 @@ { "files.associations": { - "*.h": "c" + "*.h": "c", + "system_error": "c" }, "C_Cpp.clang_format_path": "/usr/bin/clang-format", "editor.formatOnSave": false, diff --git a/Makefile b/Makefile index 195e96a..675a1d9 100644 --- a/Makefile +++ b/Makefile @@ -1,112 +1,116 @@ +# **************************************************************************** +# Ledger App Boilerplate +# (c) 2023 Ledger SAS. +# +# 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. +# **************************************************************************** + ifeq ($(BOLOS_SDK),) $(error Environment variable BOLOS_SDK is not set) endif include $(BOLOS_SDK)/Makefile.defines -APP_LOAD_PARAMS = --curve secp256k1 -ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOX TARGET_STAX)) -APP_LOAD_PARAMS += --appFlags 0x200 # APPLICATION_FLAG_BOLOS_SETTINGS -else -APP_LOAD_PARAMS += --appFlags 0x000 -endif -APP_LOAD_PARAMS += --path "44'/111111'" -APP_LOAD_PARAMS += $(COMMON_LOAD_PARAMS) +######################################## +# Mandatory configuration # +######################################## +# Application name +APPNAME = "Kaspa" -APPNAME = "Kaspa" +# Application version APPVERSION_M = 1 APPVERSION_N = 0 APPVERSION_P = 0 -APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)" +APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)" ifeq ($(TARGET_NAME),TARGET_NANOS) DEFINES += MAX_INPUT_COUNT=15 - ICONNAME=icons/nanos_kaspa_logo.gif else ifeq ($(TARGET_NAME),TARGET_STAX) DEFINES += MAX_INPUT_COUNT=128 - ICONNAME=icons/stax_kaspa_logo_32px.gif else DEFINES += MAX_INPUT_COUNT=128 - ICONNAME=icons/nanox_kaspa_logo.gif endif -DEFINES += $(DEFINES_LIB) -DEFINES += APPNAME=\"$(APPNAME)\" -DEFINES += APPVERSION=\"$(APPVERSION)\" -DEFINES += MAJOR_VERSION=$(APPVERSION_M) MINOR_VERSION=$(APPVERSION_N) PATCH_VERSION=$(APPVERSION_P) -DEFINES += OS_IO_SEPROXYHAL -DEFINES += HAVE_SPRINTF HAVE_SNPRINTF_FORMAT_U -DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=6 IO_HID_EP_LENGTH=64 HAVE_USB_APDU -DEFINES += USB_SEGMENT_SIZE=64 -DEFINES += BLE_SEGMENT_SIZE=32 -DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=0 WEBUSB_URL="" -DEFINES += UNUSED\(x\)=\(void\)x - -ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOX TARGET_STAX)) - DEFINES += HAVE_BLE BLE_COMMAND_TIMEOUT_MS=2000 HAVE_BLE_APDU -endif - -ifeq ($(TARGET_NAME),TARGET_NANOS) - DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128 -else - DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300 -endif - -ifeq ($(TARGET_NAME),TARGET_STAX) - DEFINES += NBGL_QRCODE -else - DEFINES += HAVE_BAGL HAVE_UX_FLOW - ifneq ($(TARGET_NAME),TARGET_NANOS) - DEFINES += HAVE_GLO096 - DEFINES += BAGL_WIDTH=128 BAGL_HEIGHT=64 - DEFINES += HAVE_BAGL_ELLIPSIS # long label truncation feature - DEFINES += HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX - DEFINES += HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX - DEFINES += HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX - endif -endif - -DEBUG ?= 0 -ifneq ($(DEBUG),0) - DEFINES += HAVE_DEBUG_APDU - DEFINES += HAVE_PRINTF - ifeq ($(TARGET_NAME),TARGET_NANOS) - DEFINES += PRINTF=screen_printf - else - DEFINES += PRINTF=mcu_usb_printf - endif -else - DEFINES += PRINTF\(...\)= -endif - -CC := $(CLANGPATH)clang -AS := $(GCCPATH)arm-none-eabi-gcc -LD := $(GCCPATH)arm-none-eabi-gcc -LDLIBS += -lm -lgcc -lc - -include $(BOLOS_SDK)/Makefile.glyphs - +# Application source files APP_SOURCE_PATH += src -SDK_SOURCE_PATH += lib_stusb lib_stusb_impl - -ifneq ($(TARGET_NAME),TARGET_STAX) -SDK_SOURCE_PATH += lib_ux -endif - -ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOX TARGET_STAX)) - SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl -endif - -load: all - python3 -m ledgerblue.loadApp $(APP_LOAD_PARAMS) - -load-offline: all - python3 -m ledgerblue.loadApp $(APP_LOAD_PARAMS) --offline - -delete: - python3 -m ledgerblue.deleteApp $(COMMON_DELETE_PARAMS) - -include $(BOLOS_SDK)/Makefile.rules -listvariants: - @echo VARIANTS COIN KAS +# Application icons following guidelines: +# https://developers.ledger.com/docs/embedded-app/design-requirements/#device-icon +ICON_NANOS = icons/nanos_kaspa_logo.gif +ICON_NANOX = icons/nanox_kaspa_logo.gif +ICON_NANOSP = icons/nanox_kaspa_logo.gif +ICON_STAX = icons/stax_kaspa_logo_32px.gif + +# Application allowed derivation curves. +# Possibles curves are: secp256k1, secp256r1, ed25519 and bls12381g1 +# If your app needs it, you can specify multiple curves by using: +# `CURVE_APP_LOAD_PARAMS = ` +CURVE_APP_LOAD_PARAMS = secp256k1 + +# Application allowed derivation paths. +# You should request a specific path for your app. +# This serve as an isolation mechanism. +# Most application will have to request a path according to the BIP-0044 +# and SLIP-0044 standards. +# If your app needs it, you can specify multiple path by using: +# `PATH_APP_LOAD_PARAMS = "44'/1'" "45'/1'"` +PATH_APP_LOAD_PARAMS = "44'/111111'" # purpose=coin(44) / coin_type=Testnet(1) + +# Setting to allow building variant applications +# - is the name of the parameter which should be set +# to specify the variant that should be build. +# - a list of variant that can be build using this app code. +# * It must at least contains one value. +# * Values can be the app ticker or anything else but should be unique. +VARIANT_PARAM = COIN +VARIANT_VALUES = KAS + +# Enabling DEBUG flag will enable PRINTF and disable optimizations +#DEBUG = 1 + +######################################## +# Application custom permissions # +######################################## +# See SDK `include/appflags.h` for the purpose of each permission +#HAVE_APPLICATION_FLAG_DERIVE_MASTER = 1 +#HAVE_APPLICATION_FLAG_GLOBAL_PIN = 1 +#HAVE_APPLICATION_FLAG_BOLOS_SETTINGS = 1 +#HAVE_APPLICATION_FLAG_LIBRARY = 1 + +######################################## +# Application communication interfaces # +######################################## +ENABLE_BLUETOOTH = 1 +#ENABLE_NFC = 1 + +######################################## +# NBGL custom features # +######################################## +ENABLE_NBGL_QRCODE = 1 +#ENABLE_NBGL_KEYBOARD = 1 +#ENABLE_NBGL_KEYPAD = 1 + +######################################## +# Features disablers # +######################################## +# These advanced settings allow to disable some feature that are by +# default enabled in the SDK `Makefile.standard_app`. +#DISABLE_STANDARD_APP_FILES = 1 +#DISABLE_DEFAULT_IO_SEPROXY_BUFFER_SIZE = 1 # To allow custom size declaration +#DISABLE_STANDARD_APP_DEFINES = 1 # Will set all the following disablers +#DISABLE_STANDARD_SNPRINTF = 1 +#DISABLE_STANDARD_USB = 1 +#DISABLE_STANDARD_WEBUSB = 1 +#DISABLE_STANDARD_BAGL_UX_FLOW = 1 + +include $(BOLOS_SDK)/Makefile.standard_app \ No newline at end of file diff --git a/fuzzing/fuzz_tx_parser.cc b/fuzzing/fuzz_tx_parser.cc index 8580f59..04fa0b1 100644 --- a/fuzzing/fuzz_tx_parser.cc +++ b/fuzzing/fuzz_tx_parser.cc @@ -27,7 +27,7 @@ #include extern "C" { -#include "common/buffer.h" +#include "buffer.h" #include "common/format.h" #include "transaction/deserialize.h" #include "transaction/types.h" diff --git a/fuzzing/fuzz_txin_parser.cc b/fuzzing/fuzz_txin_parser.cc index b299999..cfdb234 100644 --- a/fuzzing/fuzz_txin_parser.cc +++ b/fuzzing/fuzz_txin_parser.cc @@ -27,7 +27,7 @@ #include extern "C" { -#include "common/buffer.h" +#include "buffer.h" #include "common/format.h" #include "transaction/deserialize.h" #include "transaction/types.h" diff --git a/fuzzing/fuzz_txout_parser.cc b/fuzzing/fuzz_txout_parser.cc index 7ca28d7..9b70ea3 100644 --- a/fuzzing/fuzz_txout_parser.cc +++ b/fuzzing/fuzz_txout_parser.cc @@ -27,7 +27,7 @@ #include extern "C" { -#include "common/buffer.h" +#include "buffer.h" #include "common/format.h" #include "transaction/deserialize.h" #include "transaction/types.h" diff --git a/src/apdu/dispatcher.c b/src/apdu/dispatcher.c index 5eb722f..771049f 100644 --- a/src/apdu/dispatcher.c +++ b/src/apdu/dispatcher.c @@ -28,9 +28,9 @@ #include "../constants.h" #include "../globals.h" #include "../types.h" -#include "../io.h" +#include "io.h" #include "../sw.h" -#include "../common/buffer.h" +#include "buffer.h" #include "../handler/get_version.h" #include "../handler/get_app_name.h" #include "../handler/get_public_key.h" diff --git a/src/app_main.c b/src/app_main.c new file mode 100644 index 0000000..07fb70f --- /dev/null +++ b/src/app_main.c @@ -0,0 +1,85 @@ +/***************************************************************************** + * MIT License + * + * Copyright (c) 2023 coderofstuff + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ +#include // uint*_t +#include // memset, explicit_bzero + +#include "os.h" +#include "ux.h" + +#include "types.h" +#include "globals.h" +#include "io.h" +#include "sw.h" +#include "ui/menu.h" +#include "apdu/parser.h" +#include "apdu/dispatcher.h" + +global_ctx_t G_context; + +/** + * Handle APDU command received and send back APDU response using handlers. + */ +void app_main() { + // Length of APDU command received in G_io_apdu_buffer + int input_len = 0; + // Structured APDU command + command_t cmd; + + io_init(); + + ui_menu_main(); + + // Reset context + explicit_bzero(&G_context, sizeof(G_context)); + + for (;;) { + // Receive command bytes in G_io_apdu_buffer + if ((input_len = io_recv_command()) < 0) { + PRINTF("=> io_recv_command failure\n"); + return; + } + + // Parse APDU command from G_io_apdu_buffer + if (!apdu_parser(&cmd, G_io_apdu_buffer, input_len)) { + PRINTF("=> /!\\ BAD LENGTH: %.*H\n", input_len, G_io_apdu_buffer); + io_send_sw(SW_WRONG_DATA_LENGTH); + continue; + } + + PRINTF("=> CLA=%02X | INS=%02X | P1=%02X | P2=%02X | Lc=%02X | CData=%.*H\n", + cmd.cla, + cmd.ins, + cmd.p1, + cmd.p2, + cmd.lc, + cmd.lc, + cmd.data); + + // Dispatch structured APDU command to handler + if (apdu_dispatcher(&cmd) < 0) { + PRINTF("=> apdu_dispatcher failure\n"); + return; + } + } +} \ No newline at end of file diff --git a/src/common/buffer.c b/src/common/buffer.c deleted file mode 100644 index 5c49ffd..0000000 --- a/src/common/buffer.c +++ /dev/null @@ -1,158 +0,0 @@ -/***************************************************************************** - * MIT License - * - * Copyright (c) 2023 coderofstuff - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#include // uint*_t -#include // size_t -#include // bool -#include // memmove - -#include "buffer.h" -#include "read.h" -#include "bip32.h" - -bool buffer_can_read(const buffer_t *buffer, size_t n) { - return buffer->size - buffer->offset >= n; -} - -bool buffer_seek_set(buffer_t *buffer, size_t offset) { - if (offset > buffer->size) { - return false; - } - - buffer->offset = offset; - - return true; -} - -bool buffer_seek_cur(buffer_t *buffer, size_t offset) { - if (buffer->offset + offset < buffer->offset || // overflow - buffer->offset + offset > buffer->size) { // exceed buffer size - return false; - } - - buffer->offset += offset; - - return true; -} - -bool buffer_seek_end(buffer_t *buffer, size_t offset) { - if (offset > buffer->size) { - return false; - } - - buffer->offset = buffer->size - offset; - - return true; -} - -bool buffer_read_u8(buffer_t *buffer, uint8_t *value) { - if (!buffer_can_read(buffer, 1)) { - *value = 0; - - return false; - } - - *value = buffer->ptr[buffer->offset]; - buffer_seek_cur(buffer, 1); - - return true; -} - -bool buffer_read_u16(buffer_t *buffer, uint16_t *value, endianness_t endianness) { - if (!buffer_can_read(buffer, 2)) { - *value = 0; - - return false; - } - - *value = ((endianness == BE) ? read_u16_be(buffer->ptr, buffer->offset) - : read_u16_le(buffer->ptr, buffer->offset)); - - buffer_seek_cur(buffer, 2); - - return true; -} - -bool buffer_read_u32(buffer_t *buffer, uint32_t *value, endianness_t endianness) { - if (!buffer_can_read(buffer, 4)) { - *value = 0; - - return false; - } - - *value = ((endianness == BE) ? read_u32_be(buffer->ptr, buffer->offset) - : read_u32_le(buffer->ptr, buffer->offset)); - - buffer_seek_cur(buffer, 4); - - return true; -} - -bool buffer_read_u64(buffer_t *buffer, uint64_t *value, endianness_t endianness) { - if (!buffer_can_read(buffer, 8)) { - *value = 0; - - return false; - } - - *value = ((endianness == BE) ? read_u64_be(buffer->ptr, buffer->offset) - : read_u64_le(buffer->ptr, buffer->offset)); - - buffer_seek_cur(buffer, 8); - - return true; -} - -bool buffer_read_bip32_path(buffer_t *buffer, uint32_t *out, size_t out_len) { - if (!bip32_path_read(buffer->ptr + buffer->offset, - buffer->size - buffer->offset, - out, - out_len)) { - return false; - } - - buffer_seek_cur(buffer, sizeof(*out) * out_len); - - return true; -} - -bool buffer_copy(const buffer_t *buffer, uint8_t *out, size_t out_len) { - if (buffer->size - buffer->offset > out_len) { - return false; - } - - memmove(out, buffer->ptr + buffer->offset, buffer->size - buffer->offset); - - return true; -} - -bool buffer_move(buffer_t *buffer, uint8_t *out, size_t out_len) { - if (!buffer_copy(buffer, out, out_len)) { - return false; - } - - buffer_seek_cur(buffer, out_len); - - return true; -} diff --git a/src/common/buffer.h b/src/common/buffer.h deleted file mode 100644 index 7ff4f3a..0000000 --- a/src/common/buffer.h +++ /dev/null @@ -1,200 +0,0 @@ -/***************************************************************************** - * MIT License - * - * Copyright (c) 2023 coderofstuff - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#pragma once - -#include // uint*_t -#include // size_t -#include // bool - -/** - * Enumeration for endianness. - */ -typedef enum { - BE, /// Big Endian - LE /// Little Endian -} endianness_t; - -/** - * Struct for buffer with size and offset. - */ -typedef struct { - const uint8_t *ptr; /// Pointer to byte buffer - size_t size; /// Size of byte buffer - size_t offset; /// Offset in byte buffer -} buffer_t; - -/** - * Tell whether buffer can read bytes or not. - * - * @param[in] buffer - * Pointer to input buffer struct. - * @param[in] n - * Number of bytes to read in buffer. - * - * @return true if success, false otherwise. - * - */ -bool buffer_can_read(const buffer_t *buffer, size_t n); - -/** - * Seek the buffer to specific offset. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[in] offset - * Specific offset to seek. - * - * @return true if success, false otherwise. - * - */ -bool buffer_seek_set(buffer_t *buffer, size_t offset); - -/** - * Seek buffer relatively to current offset. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[in] offset - * Offset to seek relatively to `buffer->offset`. - * - * @return true if success, false otherwise. - * - */ -bool buffer_seek_cur(buffer_t *buffer, size_t offset); - -/** - * Seek the buffer relatively to the end. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[in] offset - * Offset to seek relatively to `buffer->size`. - * - * @return true if success, false otherwise. - * - */ -bool buffer_seek_end(buffer_t *buffer, size_t offset); - -/** - * Read 1 byte from buffer into uint8_t. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[out] value - * Pointer to 8-bit unsigned integer read from buffer. - * - * @return true if success, false otherwise. - * - */ -bool buffer_read_u8(buffer_t *buffer, uint8_t *value); - -/** - * Read 2 bytes from buffer into uint16_t. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[out] value - * Pointer to 16-bit unsigned integer read from buffer. - * @param[in] endianness - * Either BE (Big Endian) or LE (Little Endian). - * - * @return true if success, false otherwise. - * - */ -bool buffer_read_u16(buffer_t *buffer, uint16_t *value, endianness_t endianness); - -/** - * Read 4 bytes from buffer into uint32_t. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[out] value - * Pointer to 32-bit unsigned integer read from buffer. - * @param[in] endianness - * Either BE (Big Endian) or LE (Little Endian). - * - * @return true if success, false otherwise. - * - */ -bool buffer_read_u32(buffer_t *buffer, uint32_t *value, endianness_t endianness); - -/** - * Read 8 bytes from buffer into uint64_t. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[out] value - * Pointer to 64-bit unsigned integer read from buffer. - * @param[in] endianness - * Either BE (Big Endian) or LE (Little Endian). - * - * @return true if success, false otherwise. - * - */ -bool buffer_read_u64(buffer_t *buffer, uint64_t *value, endianness_t endianness); - -/** - * Read BIP32 path from buffer. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[out] out - * Pointer to output 32-bit integer buffer. - * @param[in] out_len - * Number of BIP32 paths read in the output buffer. - * - * @return true if success, false otherwise. - * - */ -bool buffer_read_bip32_path(buffer_t *buffer, uint32_t *out, size_t out_len); - -/** - * Copy bytes from buffer without moving offset. - * - * @param[in] buffer - * Pointer to input buffer struct. - * @param[out] out - * Pointer to output byte buffer. - * @param[in] out_len - * Length of output byte buffer. - * - * @return true if success, false otherwise. - * - */ -bool buffer_copy(const buffer_t *buffer, uint8_t *out, size_t out_len); - -/** - * Move bytes from buffer. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[out] out - * Pointer to output byte buffer. - * @param[in] out_len - * Length of output byte buffer. - * - * @return true if success, false otherwise. - * - */ -bool buffer_move(buffer_t *buffer, uint8_t *out, size_t out_len); diff --git a/src/common/format.c b/src/common/format.c index 1db8c83..d614b61 100644 --- a/src/common/format.c +++ b/src/common/format.c @@ -103,7 +103,7 @@ bool format_u64(char *out, size_t outLen, uint64_t in) { return true; } -bool format_fpu64(char *dst, size_t dst_len, const uint64_t value, uint8_t decimals) { +bool format_fpu64_trimmed(char *dst, size_t dst_len, const uint64_t value, uint8_t decimals) { char buffer[21] = {0}; if (!format_u64(buffer, sizeof(buffer), value)) { diff --git a/src/common/format.h b/src/common/format.h index b1a0506..1c8d486 100644 --- a/src/common/format.h +++ b/src/common/format.h @@ -72,7 +72,7 @@ bool format_u64(char *dst, size_t dst_len, uint64_t value); * @return true if success, false otherwise. * */ -bool format_fpu64(char *dst, size_t dst_len, const uint64_t value, uint8_t decimals); +bool format_fpu64_trimmed(char *dst, size_t dst_len, const uint64_t value, uint8_t decimals); /** * Format byte buffer to uppercase hexadecimal string. diff --git a/src/common/read.c b/src/common/read.c deleted file mode 100644 index bd0c7cc..0000000 --- a/src/common/read.c +++ /dev/null @@ -1,72 +0,0 @@ -/***************************************************************************** - * MIT License - * - * Copyright (c) 2023 coderofstuff - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ - -#include // uint*_t -#include // size_t - -uint16_t read_u16_be(const uint8_t *ptr, size_t offset) { - return (uint16_t) ptr[offset + 0] << 8 | // - (uint16_t) ptr[offset + 1] << 0; -} - -uint32_t read_u32_be(const uint8_t *ptr, size_t offset) { - return (uint32_t) ptr[offset + 0] << 24 | // - (uint32_t) ptr[offset + 1] << 16 | // - (uint32_t) ptr[offset + 2] << 8 | // - (uint32_t) ptr[offset + 3] << 0; -} - -uint64_t read_u64_be(const uint8_t *ptr, size_t offset) { - return (uint64_t) ptr[offset + 0] << 56 | // - (uint64_t) ptr[offset + 1] << 48 | // - (uint64_t) ptr[offset + 2] << 40 | // - (uint64_t) ptr[offset + 3] << 32 | // - (uint64_t) ptr[offset + 4] << 24 | // - (uint64_t) ptr[offset + 5] << 16 | // - (uint64_t) ptr[offset + 6] << 8 | // - (uint64_t) ptr[offset + 7] << 0; -} - -uint16_t read_u16_le(const uint8_t *ptr, size_t offset) { - return (uint16_t) ptr[offset + 0] << 0 | // - (uint16_t) ptr[offset + 1] << 8; -} - -uint32_t read_u32_le(const uint8_t *ptr, size_t offset) { - return (uint32_t) ptr[offset + 0] << 0 | // - (uint32_t) ptr[offset + 1] << 8 | // - (uint32_t) ptr[offset + 2] << 16 | // - (uint32_t) ptr[offset + 3] << 24; -} - -uint64_t read_u64_le(const uint8_t *ptr, size_t offset) { - return (uint64_t) ptr[offset + 0] << 0 | // - (uint64_t) ptr[offset + 1] << 8 | // - (uint64_t) ptr[offset + 2] << 16 | // - (uint64_t) ptr[offset + 3] << 24 | // - (uint64_t) ptr[offset + 4] << 32 | // - (uint64_t) ptr[offset + 5] << 40 | // - (uint64_t) ptr[offset + 6] << 48 | // - (uint64_t) ptr[offset + 7] << 56; -} diff --git a/src/common/read.h b/src/common/read.h deleted file mode 100644 index 335a571..0000000 --- a/src/common/read.h +++ /dev/null @@ -1,105 +0,0 @@ -/***************************************************************************** - * MIT License - * - * Copyright (c) 2023 coderofstuff - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#pragma once - -#include // uint*_t -#include // size_t - -/** - * Read 2 bytes as Big Endian from byte buffer. - * - * @param[in] ptr - * Pointer to byte buffer. - * @param[in] offset - * Offset in the byte buffer. - * - * @return 2 bytes value read from buffer. - * - */ -uint16_t read_u16_be(const uint8_t *ptr, size_t offset); - -/** - * Read 4 bytes as Big Endian from byte buffer. - * - * @param[in] ptr - * Pointer to byte buffer. - * @param[in] offset - * Offset in the byte buffer. - * - * @return 4 bytes value read from buffer. - * - */ -uint32_t read_u32_be(const uint8_t *ptr, size_t offset); - -/** - * Read 8 bytes as Big Endian from byte buffer. - * - * @param[in] ptr - * Pointer to byte buffer. - * @param[in] offset - * Offset in the byte buffer. - * - * @return 8 bytes value read from buffer. - * - */ -uint64_t read_u64_be(const uint8_t *ptr, size_t offset); - -/** - * Read 2 bytes as Little Endian from byte buffer. - * - * @param[in] ptr - * Pointer to byte buffer. - * @param[in] offset - * Offset in the byte buffer. - * - * @return 2 bytes value read from buffer. - * - */ -uint16_t read_u16_le(const uint8_t *ptr, size_t offset); - -/** - * Read 4 bytes as Little Endian from byte buffer. - * - * @param[in] ptr - * Pointer to byte buffer. - * @param[in] offset - * Offset in the byte buffer. - * - * @return 4 bytes value read from buffer. - * - */ -uint32_t read_u32_le(const uint8_t *ptr, size_t offset); - -/** - * Read 8 bytes as Little Endian from byte buffer. - * - * @param[in] ptr - * Pointer to byte buffer. - * @param[in] offset - * Offset in the byte buffer. - * - * @return 8 bytes value read from buffer. - * - */ -uint64_t read_u64_le(const uint8_t *ptr, size_t offset); diff --git a/src/crypto.c b/src/crypto.c index ca60bb5..ab22a19 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -25,86 +25,39 @@ #include // memset, explicit_bzero #include // bool +#include "crypto_helpers.h" #include "crypto.h" #include "globals.h" #include "sighash.h" -int crypto_derive_private_key(cx_ecfp_private_key_t *private_key, - uint8_t chain_code[static 32], - const uint32_t *bip32_path, - uint8_t bip32_path_len) { - uint8_t raw_private_key[32] = {0}; - int error = 0; - - BEGIN_TRY { - TRY { - // derive the seed with bip32_path - os_perso_derive_node_bip32(CX_CURVE_256K1, - bip32_path, - bip32_path_len, - raw_private_key, - chain_code); - // new private_key from raw - cx_ecfp_init_private_key(CX_CURVE_256K1, - raw_private_key, - sizeof(raw_private_key), - private_key); - } - CATCH_OTHER(e) { - error = e; - } - FINALLY { - explicit_bzero(&raw_private_key, sizeof(raw_private_key)); - } - } - END_TRY; - - return error; -} - -void crypto_init_public_key(cx_ecfp_private_key_t *private_key, - cx_ecfp_public_key_t *public_key, - uint8_t raw_public_key[static 64]) { - // generate corresponding public key - cx_ecfp_generate_pair(CX_CURVE_256K1, public_key, private_key, 1); - - memmove(raw_public_key, public_key->W + 1, 64); -} - bool crypto_validate_public_key(const uint32_t *bip32_path, uint8_t bip32_path_len, uint8_t compressed_public_key[static 32]) { - cx_ecfp_private_key_t private_key = {0}; - cx_ecfp_public_key_t public_key = {0}; + uint8_t raw_pubkey[65] = {0}; uint8_t chain_code[32] = {0}; - int error = crypto_derive_private_key(&private_key, chain_code, bip32_path, bip32_path_len); - if (error != 0) { - return false; - } + int error = bip32_derive_get_pubkey_256(CX_CURVE_256K1, + bip32_path, + bip32_path_len, + raw_pubkey, + chain_code, + CX_SHA512); - BEGIN_TRY { - TRY { - cx_ecfp_generate_pair(CX_CURVE_256K1, &public_key, &private_key, 1); - } - } - FINALLY { - explicit_bzero(&private_key, sizeof(private_key)); + if (error != CX_OK) { + return false; } - END_TRY; - PRINTF("==> Generated Data: %.*H\n", 32, public_key.W + 1); + PRINTF("==> Generated Data: %.*H\n", 32, raw_pubkey + 1); PRINTF("==> Passed Data : %.*H\n", 32, compressed_public_key); - return memcmp(public_key.W + 1, compressed_public_key, 32) == 0; + return memcmp(raw_pubkey + 1, compressed_public_key, 32) == 0; } int crypto_sign_message(void) { cx_ecfp_private_key_t private_key = {0}; cx_ecfp_public_key_t public_key = {0}; uint8_t chain_code[32] = {0}; - uint32_t info = 0; transaction_input_t *txin = &G_context.tx_info.transaction.tx_inputs[G_context.tx_info.signing_input_index]; @@ -118,12 +71,12 @@ int crypto_sign_message(void) { G_context.bip32_path_len = 5; - // derive private key according to BIP32 path - int error = crypto_derive_private_key(&private_key, - chain_code, - G_context.bip32_path, - G_context.bip32_path_len); - if (error != 0) { + int error = bip32_derive_init_privkey_256(CX_CURVE_256K1, + G_context.bip32_path, + G_context.bip32_path_len, + &private_key, + chain_code); + if (error != CX_OK) { return error; } @@ -133,23 +86,27 @@ int crypto_sign_message(void) { memset(G_context.tx_info.sighash, 0, sizeof(G_context.tx_info.sighash)); memset(G_context.tx_info.signature, 0, sizeof(G_context.tx_info.signature)); - cx_ecfp_generate_pair(CX_CURVE_256K1, &public_key, &private_key, 1); + error = cx_ecfp_generate_pair_no_throw(CX_CURVE_256K1, &public_key, &private_key, 1); + if (error != CX_OK) { + return error; + } + calc_sighash(&G_context.tx_info.transaction, txin, public_key.W + 1, G_context.tx_info.sighash); - cx_ecschnorr_sign(&private_key, - CX_ECSCHNORR_BIP0340 | CX_RND_TRNG, - CX_SHA256, - G_context.tx_info.sighash, - sizeof(G_context.tx_info.sighash), - G_context.tx_info.signature, - sizeof(G_context.tx_info.signature), - &info); - PRINTF("Signature: %.*H\n", 64, G_context.tx_info.signature); - } - CATCH_OTHER(e) { - error = e; + + size_t sig_len = sizeof(G_context.tx_info.signature); + error = cx_ecschnorr_sign_no_throw(&private_key, + CX_ECSCHNORR_BIP0340 | CX_RND_TRNG, + CX_SHA256, + G_context.tx_info.sighash, + sizeof(G_context.tx_info.sighash), + G_context.tx_info.signature, + &sig_len); + if (error != CX_OK) { + PRINTF("Signature: %.*H\n", 64, G_context.tx_info.signature); + } } FINALLY { explicit_bzero(&public_key, sizeof(public_key)); diff --git a/src/crypto.h b/src/crypto.h index 4d5daee..ff05f0a 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -26,46 +26,8 @@ #include // uint*_t -#include "os.h" #include "cx.h" -/** - * Derive private key given BIP32 path. - * - * @param[out] private_key - * Pointer to private key. - * @param[out] chain_code - * Pointer to 32 bytes array for chain code. - * @param[in] bip32_path - * Pointer to buffer with BIP32 path. - * @param[in] bip32_path_len - * Number of path in BIP32 path. - * - * @return 0 on success, error number otherwise. - * - */ -int crypto_derive_private_key(cx_ecfp_private_key_t *private_key, - uint8_t chain_code[static 32], - const uint32_t *bip32_path, - uint8_t bip32_path_len); - -/** - * Initialize public key given private key. - * - * @param[in] private_key - * Pointer to private key. - * @param[out] public_key - * Pointer to public key. - * @param[out] raw_public_key - * Pointer to raw public key. - * - * @throw INVALID_PARAMETER - * - */ -void crypto_init_public_key(cx_ecfp_private_key_t *private_key, - cx_ecfp_public_key_t *public_key, - uint8_t raw_public_key[static 64]); - /** * Sign message hash in global context. * diff --git a/src/handler/debug.c b/src/handler/debug.c index 7cfba0a..c89942f 100644 --- a/src/handler/debug.c +++ b/src/handler/debug.c @@ -40,7 +40,7 @@ static int helper_send_response_sig(uint8_t* signature) { memmove(resp + offset, signature, 64); offset += 64; - return io_send_response(&(const buffer_t){.ptr = resp, .size = offset, .offset = 0}, SW_OK); + return io_send_response_pointer(resp, offset, SW_OK); } // Test cases from https://github.com/bitcoin/bips/blob/master/bip-0340/test-vectors.csv static void debug_test_case_1(uint8_t* signature) { diff --git a/src/handler/get_app_name.c b/src/handler/get_app_name.c index 1fae660..7c7696a 100644 --- a/src/handler/get_app_name.c +++ b/src/handler/get_app_name.c @@ -26,15 +26,13 @@ #include "get_app_name.h" #include "../constants.h" #include "../globals.h" -#include "../io.h" +#include "io.h" #include "../sw.h" #include "../types.h" -#include "common/buffer.h" +#include "buffer.h" int handler_get_app_name() { _Static_assert(APPNAME_LEN < MAX_APPNAME_LEN, "APPNAME must be at most 64 characters!"); - buffer_t rdata = {.ptr = (uint8_t *) PIC(APPNAME), .size = APPNAME_LEN, .offset = 0}; - - return io_send_response(&rdata, SW_OK); + return io_send_response_pointer((uint8_t *) PIC(APPNAME), APPNAME_LEN, SW_OK); } diff --git a/src/handler/get_public_key.c b/src/handler/get_public_key.c index 388cbca..fd574eb 100644 --- a/src/handler/get_public_key.c +++ b/src/handler/get_public_key.c @@ -27,15 +27,15 @@ #include // memset, explicit_bzero #include "os.h" -#include "cx.h" +#include "crypto_helpers.h" #include "get_public_key.h" #include "../globals.h" #include "../types.h" -#include "../io.h" +#include "io.h" #include "../sw.h" #include "../crypto.h" -#include "../common/buffer.h" +#include "buffer.h" #include "../ui/display.h" #include "../helper/send_response.h" @@ -44,8 +44,7 @@ int handler_get_public_key(buffer_t *cdata, bool display) { G_context.req_type = CONFIRM_ADDRESS; G_context.state = STATE_NONE; - cx_ecfp_private_key_t private_key = {0}; - cx_ecfp_public_key_t public_key = {0}; + uint8_t raw_pubkey[65] = {0}; if (!buffer_read_u8(cdata, &G_context.bip32_path_len) || !buffer_read_bip32_path(cdata, G_context.bip32_path, (size_t) G_context.bip32_path_len)) { @@ -69,18 +68,18 @@ int handler_get_public_key(buffer_t *cdata, bool display) { return io_send_sw(SW_WRONG_BIP32_TYPE); } - // derive private key according to BIP32 path - int error = crypto_derive_private_key(&private_key, - G_context.pk_info.chain_code, - G_context.bip32_path, - G_context.bip32_path_len); - if (error != 0) { + int error = bip32_derive_get_pubkey_256(CX_CURVE_256K1, + G_context.bip32_path, + G_context.bip32_path_len, + raw_pubkey, + G_context.pk_info.chain_code, + CX_SHA512); + + if (error != CX_OK) { return io_send_sw(error); } - // generate corresponding public key - crypto_init_public_key(&private_key, &public_key, G_context.pk_info.raw_public_key); - // reset private key - explicit_bzero(&private_key, sizeof(private_key)); + + memmove(G_context.pk_info.raw_public_key, raw_pubkey + 1, 64); if (display) { return ui_display_address(); diff --git a/src/handler/get_public_key.h b/src/handler/get_public_key.h index 16c7a67..3db59d7 100644 --- a/src/handler/get_public_key.h +++ b/src/handler/get_public_key.h @@ -28,7 +28,7 @@ #include // uint*_t #include "../types.h" -#include "../common/buffer.h" +#include "buffer.h" /** * Handler for GET_PUBLIC_KEY command. If successfully parse BIP32 path, diff --git a/src/handler/get_version.c b/src/handler/get_version.c index 0ebd56e..f516582 100644 --- a/src/handler/get_version.c +++ b/src/handler/get_version.c @@ -28,10 +28,10 @@ #include "get_version.h" #include "../globals.h" #include "../constants.h" -#include "../io.h" +#include "io.h" #include "../sw.h" #include "../types.h" -#include "common/buffer.h" +#include "buffer.h" int handler_get_version() { _Static_assert(APPVERSION_LEN == 3, "Length of (MAJOR || MINOR || PATCH) must be 3!"); @@ -42,11 +42,9 @@ int handler_get_version() { _Static_assert(PATCH_VERSION >= 0 && PATCH_VERSION <= UINT8_MAX, "PATCH version must be between 0 and 255!"); - return io_send_response( - &(const buffer_t){.ptr = (uint8_t[APPVERSION_LEN]){(uint8_t) MAJOR_VERSION, - (uint8_t) MINOR_VERSION, - (uint8_t) PATCH_VERSION}, - .size = APPVERSION_LEN, - .offset = 0}, - SW_OK); + return io_send_response_pointer((uint8_t[APPVERSION_LEN]){(uint8_t) MAJOR_VERSION, + (uint8_t) MINOR_VERSION, + (uint8_t) PATCH_VERSION}, + APPVERSION_LEN, + SW_OK); } diff --git a/src/handler/sign_tx.c b/src/handler/sign_tx.c index 78f754e..7956cbc 100644 --- a/src/handler/sign_tx.c +++ b/src/handler/sign_tx.c @@ -36,7 +36,7 @@ #include "../globals.h" #include "../crypto.h" #include "../ui/display.h" -#include "../common/buffer.h" +#include "buffer.h" #include "../transaction/types.h" #include "../transaction/deserialize.h" #include "../transaction/tx_validate.h" diff --git a/src/handler/sign_tx.h b/src/handler/sign_tx.h index cda5935..6730899 100644 --- a/src/handler/sign_tx.h +++ b/src/handler/sign_tx.h @@ -26,7 +26,7 @@ #include // uint*_t #include // bool -#include "../common/buffer.h" +#include "buffer.h" /** * Handler for SIGN_TX command. If successfully parse BIP32 path diff --git a/src/helper/send_reponse.c b/src/helper/send_reponse.c index b9971a2..2d8ba24 100644 --- a/src/helper/send_reponse.c +++ b/src/helper/send_reponse.c @@ -29,7 +29,7 @@ #include "../constants.h" #include "../globals.h" #include "../sw.h" -#include "common/buffer.h" +#include "buffer.h" int helper_send_response_pubkey() { uint8_t resp[1 + 1 + PUBKEY_LEN + 1 + CHAINCODE_LEN] = {0}; @@ -43,7 +43,7 @@ int helper_send_response_pubkey() { memmove(resp + offset, G_context.pk_info.chain_code, CHAINCODE_LEN); offset += CHAINCODE_LEN; - return io_send_response(&(const buffer_t){.ptr = resp, .size = offset, .offset = 0}, SW_OK); + return io_send_response_pointer(resp, offset, SW_OK); } int helper_send_response_sig() { @@ -66,5 +66,5 @@ int helper_send_response_sig() { memmove(resp + offset, G_context.tx_info.sighash, sizeof(G_context.tx_info.sighash)); offset += sizeof(G_context.tx_info.sighash); - return io_send_response(&(const buffer_t){.ptr = resp, .size = offset, .offset = 0}, SW_OK); + return io_send_response_pointer(resp, offset, SW_OK); } diff --git a/src/io.c b/src/io.c deleted file mode 100755 index e1f7705..0000000 --- a/src/io.c +++ /dev/null @@ -1,190 +0,0 @@ -/***************************************************************************** - * MIT License - * - * Copyright (c) 2023 coderofstuff - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#include -#include - -#include "os.h" -#include "ux.h" - -#ifdef HAVE_NBGL -#include "nbgl_touch.h" -#include "nbgl_page.h" -#endif // HAVE_NBGL - -#include "io.h" -#include "globals.h" -#include "sw.h" -#include "common/buffer.h" -#include "common/write.h" - -#ifdef HAVE_BAGL -void io_seproxyhal_display(const bagl_element_t *element) { - io_seproxyhal_display_default(element); -} -#endif // HAVE_BAGL - -uint8_t io_event(uint8_t channel) { - (void) channel; - - switch (G_io_seproxyhal_spi_buffer[0]) { - case SEPROXYHAL_TAG_BUTTON_PUSH_EVENT: -#ifdef HAVE_BAGL - UX_BUTTON_PUSH_EVENT(G_io_seproxyhal_spi_buffer); -#endif // HAVE_BAGL - break; - case SEPROXYHAL_TAG_STATUS_EVENT: - if (G_io_apdu_media == IO_APDU_MEDIA_USB_HID && // - !(U4BE(G_io_seproxyhal_spi_buffer, 3) & // - SEPROXYHAL_TAG_STATUS_EVENT_FLAG_USB_POWERED)) { - THROW(EXCEPTION_IO_RESET); - } - __attribute__((fallthrough)); - case SEPROXYHAL_TAG_DISPLAY_PROCESSED_EVENT: -#ifdef HAVE_BAGL - UX_DISPLAYED_EVENT({}); -#endif // HAVE_BAGL -#ifdef HAVE_NBGL - UX_DEFAULT_EVENT(); -#endif // HAVE_NBGL - break; -#ifdef HAVE_NBGL - case SEPROXYHAL_TAG_FINGER_EVENT: - UX_FINGER_EVENT(G_io_seproxyhal_spi_buffer); - break; -#endif // HAVE_NBGL - case SEPROXYHAL_TAG_TICKER_EVENT: - UX_TICKER_EVENT(G_io_seproxyhal_spi_buffer, {}); - break; - default: - UX_DEFAULT_EVENT(); - break; - } - - if (!io_seproxyhal_spi_is_status_sent()) { - io_seproxyhal_general_status(); - } - - return 1; -} - -uint16_t io_exchange_al(uint8_t channel, uint16_t tx_len) { - switch (channel & ~(IO_FLAGS)) { - case CHANNEL_KEYBOARD: - break; - case CHANNEL_SPI: - if (tx_len) { - io_seproxyhal_spi_send(G_io_apdu_buffer, tx_len); - - if (channel & IO_RESET_AFTER_REPLIED) { - halt(); - } - - return 0; - } else { - return io_seproxyhal_spi_recv(G_io_apdu_buffer, sizeof(G_io_apdu_buffer), 0); - } - default: - THROW(INVALID_PARAMETER); - } - - return 0; -} - -/** - * Variable containing the length of the APDU response to send back. - */ -static uint32_t G_output_len = 0; - -/** - * IO state (READY, RECEIVING, WAITING). - */ -static io_state_e G_io_state = READY; - -void io_init() { - // Reset length of APDU response - G_output_len = 0; - G_io_state = READY; -} - -int io_recv_command() { - int ret = -1; - - switch (G_io_state) { - case READY: - G_io_state = RECEIVED; - ret = io_exchange(CHANNEL_APDU, G_output_len); - break; - case RECEIVED: - G_io_state = WAITING; - ret = io_exchange(CHANNEL_APDU | IO_ASYNCH_REPLY, G_output_len); - G_io_state = RECEIVED; - break; - case WAITING: - G_io_state = READY; - ret = -1; - break; - } - - return ret; -} - -int io_send_response(const buffer_t *rdata, uint16_t sw) { - int ret = -1; - - if (rdata != NULL) { - if (rdata->size - rdata->offset > IO_APDU_BUFFER_SIZE - 2 || // - !buffer_copy(rdata, G_io_apdu_buffer, sizeof(G_io_apdu_buffer))) { - return io_send_sw(SW_WRONG_RESPONSE_LENGTH); - } - G_output_len = rdata->size - rdata->offset; - PRINTF("<= SW=%04X | RData=%.*H\n", sw, rdata->size, rdata->ptr); - } else { - G_output_len = 0; - PRINTF("<= SW=%04X | RData=\n", sw); - } - - write_u16_be(G_io_apdu_buffer, G_output_len, sw); - G_output_len += 2; - - switch (G_io_state) { - case READY: - ret = -1; - break; - case RECEIVED: - G_io_state = READY; - ret = 0; - break; - case WAITING: - ret = io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, G_output_len); - G_output_len = 0; - G_io_state = READY; - break; - } - - return ret; -} - -int io_send_sw(uint16_t sw) { - return io_send_response(NULL, sw); -} diff --git a/src/io.h b/src/io.h deleted file mode 100644 index 2c382ca..0000000 --- a/src/io.h +++ /dev/null @@ -1,88 +0,0 @@ -/***************************************************************************** - * MIT License - * - * Copyright (c) 2023 coderofstuff - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#pragma once - -#include - -#include "ux.h" -#include "os_io_seproxyhal.h" - -#include "types.h" -#include "common/buffer.h" - -#ifdef HAVE_BAGL -void io_seproxyhal_display(const bagl_element_t *element); -#endif // HAVE_BAGL - -/** - * IO callback called when an interrupt based channel has received - * data to be processed. - * - * @return 1 if success, 0 otherwise. - * - */ -uint8_t io_event(uint8_t channel); - -uint16_t io_exchange_al(uint8_t channel, uint16_t tx_len); - -/** - * Initialize the APDU I/O state. - * - * This function must be called before calling any other I/O function. - */ -void io_init(void); - -/** - * Receive APDU command in G_io_apdu_buffer. - * - * @return zero or positive integer if success, -1 otherwise. - * - */ -int io_recv_command(void); - -/** - * Send APDU response (response data + status word) by filling - * G_io_apdu_buffer. - * - * @param[in] rdata - * Buffer with APDU response data. - * @param[in] sw - * Status word of APDU response. - * - * @return zero or positive integer if success, -1 otherwise. - * - */ -int io_send_response(const buffer_t *rdata, uint16_t sw); - -/** - * Send APDU response (only status word) by filling - * G_io_apdu_buffer. - * - * @param[in] sw - * Status word of APDU response. - * - * @return zero or positive integer if success, -1 otherwise. - * - */ -int io_send_sw(uint16_t sw); diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 00e1ec3..0000000 --- a/src/main.c +++ /dev/null @@ -1,166 +0,0 @@ -/***************************************************************************** - * MIT License - * - * Copyright (c) 2023 coderofstuff - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#include // uint*_t -#include // memset, explicit_bzero - -#include "os.h" -#include "ux.h" - -#include "types.h" -#include "globals.h" -#include "io.h" -#include "sw.h" -#include "ui/menu.h" -#include "apdu/parser.h" -#include "apdu/dispatcher.h" - -uint8_t G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B]; -ux_state_t G_ux; -bolos_ux_params_t G_ux_params; -global_ctx_t G_context; - -/** - * Handle APDU command received and send back APDU response using handlers. - */ -void app_main() { - // Length of APDU command received in G_io_apdu_buffer - int input_len = 0; - // Structured APDU command - command_t cmd; - - io_init(); - - // Reset context - explicit_bzero(&G_context, sizeof(G_context)); - - for (;;) { - BEGIN_TRY { - TRY { - // Reset structured APDU command - memset(&cmd, 0, sizeof(cmd)); - - // Receive command bytes in G_io_apdu_buffer - if ((input_len = io_recv_command()) < 0) { - CLOSE_TRY; - return; - } - - // Parse APDU command from G_io_apdu_buffer - if (!apdu_parser(&cmd, G_io_apdu_buffer, input_len)) { - PRINTF("=> /!\\ BAD LENGTH: %.*H\n", input_len, G_io_apdu_buffer); - io_send_sw(SW_WRONG_DATA_LENGTH); - CLOSE_TRY; - continue; - } - - PRINTF("=> CLA=%02X | INS=%02X | P1=%02X | P2=%02X | Lc=%02X | CData=%.*H\n", - cmd.cla, - cmd.ins, - cmd.p1, - cmd.p2, - cmd.lc, - cmd.lc, - cmd.data); - - // Dispatch structured APDU command to handler - if (apdu_dispatcher(&cmd) < 0) { - CLOSE_TRY; - return; - } - } - CATCH(EXCEPTION_IO_RESET) { - THROW(EXCEPTION_IO_RESET); - } - CATCH_OTHER(e) { - io_send_sw(e); - } - FINALLY { - } - END_TRY; - } - } -} - -/** - * Exit the application and go back to the dashboard. - */ -void app_exit() { - BEGIN_TRY_L(exit) { - TRY_L(exit) { - os_sched_exit(-1); - } - FINALLY_L(exit) { - } - } - END_TRY_L(exit); -} - -/** - * Main loop to setup USB, Bluetooth, UI and launch app_main(). - */ -__attribute__((section(".boot"))) int main() { - __asm volatile("cpsie i"); - - os_boot(); - - for (;;) { - // Initialize the UX system - UX_INIT(); - - BEGIN_TRY { - TRY { - io_seproxyhal_init(); - -#ifdef HAVE_BLE - G_io_app.plane_mode = os_setting_get(OS_SETTING_PLANEMODE, NULL, 0); -#endif // HAVE_BLE - USB_power(0); - USB_power(1); - - ui_menu_main(); - -#ifdef HAVE_BLE - BLE_power(0, NULL); - BLE_power(1, NULL); -#endif // HAVE_BLE - app_main(); - } - CATCH(EXCEPTION_IO_RESET) { - CLOSE_TRY; - continue; - } - CATCH_ALL { - CLOSE_TRY; - break; - } - FINALLY { - } - } - END_TRY; - } - - app_exit(); - - return 0; -} diff --git a/src/sighash.c b/src/sighash.c index f7153d3..47124ac 100644 --- a/src/sighash.c +++ b/src/sighash.c @@ -29,8 +29,8 @@ #include "./import/blake2b.h" #include "./transaction/types.h" -#include "./common/buffer.h" -#include "./common/write.h" +#include "buffer.h" +#include "write.h" #include "globals.h" #include "./constants.h" diff --git a/src/transaction/deserialize.c b/src/transaction/deserialize.c index 8c8303b..8451f33 100644 --- a/src/transaction/deserialize.c +++ b/src/transaction/deserialize.c @@ -25,7 +25,7 @@ #include "deserialize.h" #include "utils.h" #include "types.h" -#include "../common/buffer.h" +#include "buffer.h" parser_status_e transaction_output_deserialize(buffer_t *buf, transaction_output_t *txout) { // 8 bytes diff --git a/src/transaction/deserialize.h b/src/transaction/deserialize.h index 6fe8f4b..731708d 100644 --- a/src/transaction/deserialize.h +++ b/src/transaction/deserialize.h @@ -24,7 +24,7 @@ #pragma once #include "types.h" -#include "../common/buffer.h" +#include "buffer.h" /** * Deserialize raw transaction in structure. diff --git a/src/transaction/serialize.c b/src/transaction/serialize.c index 7d414f0..7cdc35e 100644 --- a/src/transaction/serialize.c +++ b/src/transaction/serialize.c @@ -27,7 +27,7 @@ #include // memmove #include "serialize.h" -#include "../common/write.h" +#include "write.h" int transaction_serialize(const transaction_t *tx, uint32_t *path, uint8_t *out, size_t out_len) { size_t offset = 0; diff --git a/src/types.h b/src/types.h index 245e128..6b42725 100644 --- a/src/types.h +++ b/src/types.h @@ -28,16 +28,7 @@ #include "constants.h" #include "transaction/types.h" -#include "common/bip32.h" - -/** - * Enumeration for the status of IO. - */ -typedef enum { - READY, /// ready for new event - RECEIVED, /// data received - WAITING /// waiting -} io_state_e; +#include "bip32.h" /** * Enumeration with expected INS of APDU commands. diff --git a/src/ui/bagl_display.c b/src/ui/bagl_display.c index cedd7a0..d0ef16d 100644 --- a/src/ui/bagl_display.c +++ b/src/ui/bagl_display.c @@ -36,14 +36,14 @@ #include "display.h" #include "constants.h" #include "../globals.h" -#include "../io.h" +#include "io.h" #include "../sw.h" #include "../address.h" #include "action/validate.h" #include "../types.h" #include "../transaction/types.h" #include "../transaction/utils.h" -#include "../common/bip32.h" +#include "bip32.h" #include "../common/format.h" #include "../menu.h" @@ -184,10 +184,10 @@ int ui_display_transaction() { memset(g_amount, 0, sizeof(g_amount)); char amount[30] = {0}; - if (!format_fpu64(amount, - sizeof(amount), - G_context.tx_info.transaction.tx_outputs[0].value, - EXPONENT_SMALLEST_UNIT)) { + if (!format_fpu64_trimmed(amount, + sizeof(amount), + G_context.tx_info.transaction.tx_outputs[0].value, + EXPONENT_SMALLEST_UNIT)) { return io_send_sw(SW_DISPLAY_AMOUNT_FAIL); } snprintf(g_amount, sizeof(g_amount), "KAS %.*s", sizeof(amount), amount); @@ -195,13 +195,13 @@ int ui_display_transaction() { memset(g_fees, 0, sizeof(g_fees)); char fees[30] = {0}; - if (!format_fpu64(fees, - sizeof(fees), - calc_fees(G_context.tx_info.transaction.tx_inputs, - G_context.tx_info.transaction.tx_input_len, - G_context.tx_info.transaction.tx_outputs, - G_context.tx_info.transaction.tx_output_len), - EXPONENT_SMALLEST_UNIT)) { + if (!format_fpu64_trimmed(fees, + sizeof(fees), + calc_fees(G_context.tx_info.transaction.tx_inputs, + G_context.tx_info.transaction.tx_input_len, + G_context.tx_info.transaction.tx_outputs, + G_context.tx_info.transaction.tx_output_len), + EXPONENT_SMALLEST_UNIT)) { return io_send_sw(SW_DISPLAY_AMOUNT_FAIL); } snprintf(g_fees, sizeof(g_fees), "KAS %.*s", sizeof(fees), fees); diff --git a/src/ui/nbgl_display_address.c b/src/ui/nbgl_display_address.c index a406eb0..112bb8f 100644 --- a/src/ui/nbgl_display_address.c +++ b/src/ui/nbgl_display_address.c @@ -36,13 +36,13 @@ #include "display.h" #include "constants.h" #include "../globals.h" -#include "../io.h" +#include "io.h" #include "../sw.h" #include "../address.h" #include "action/validate.h" #include "../types.h" #include "../transaction/types.h" -#include "../common/bip32.h" +#include "bip32.h" #include "../common/format.h" #include "../menu.h" diff --git a/src/ui/nbgl_display_transaction.c b/src/ui/nbgl_display_transaction.c index a30f1f5..103626e 100755 --- a/src/ui/nbgl_display_transaction.c +++ b/src/ui/nbgl_display_transaction.c @@ -37,13 +37,13 @@ #include "display.h" #include "constants.h" #include "../globals.h" -#include "../io.h" +#include "io.h" #include "../sw.h" #include "../address.h" #include "action/validate.h" #include "../transaction/types.h" #include "../transaction/utils.h" -#include "../common/bip32.h" +#include "bip32.h" #include "../common/format.h" #include "../menu.h" @@ -115,10 +115,10 @@ int ui_display_transaction() { // Format amount and address to g_amount and g_address buffers memset(g_amount, 0, sizeof(g_amount)); char amount[30] = {0}; - if (!format_fpu64(amount, - sizeof(amount), - G_context.tx_info.transaction.tx_outputs[0].value, - EXPONENT_SMALLEST_UNIT)) { + if (!format_fpu64_trimmed(amount, + sizeof(amount), + G_context.tx_info.transaction.tx_outputs[0].value, + EXPONENT_SMALLEST_UNIT)) { return io_send_sw(SW_DISPLAY_AMOUNT_FAIL); } snprintf(g_amount, sizeof(g_amount), "KAS %.*s", sizeof(amount), amount); diff --git a/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00000.png b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00000.png new file mode 100644 index 0000000..8842989 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00000.png differ diff --git a/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00001.png b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00001.png new file mode 100644 index 0000000..5a709a6 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00001.png differ diff --git a/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00002.png b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00002.png new file mode 100644 index 0000000..2c99888 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00002.png differ diff --git a/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00003.png b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00003.png new file mode 100644 index 0000000..281b090 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00003.png differ diff --git a/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00004.png b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00004.png new file mode 100644 index 0000000..8a26e9a Binary files /dev/null and b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00004.png differ diff --git a/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00005.png b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00005.png new file mode 100644 index 0000000..2f595a3 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00005.png differ diff --git a/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00006.png b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00006.png new file mode 100644 index 0000000..1267831 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00006.png differ diff --git a/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00007.png b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00007.png new file mode 100644 index 0000000..66c411c Binary files /dev/null and b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00007.png differ diff --git a/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00008.png b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00008.png new file mode 100644 index 0000000..9ab6248 Binary files /dev/null and b/tests/snapshots/nanos/test_sign_tx_simple_ecdsa/00008.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00000.png b/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00000.png new file mode 100644 index 0000000..df51419 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00000.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00001.png b/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00001.png new file mode 100644 index 0000000..f7a5d5a Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00001.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00002.png b/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00002.png new file mode 100644 index 0000000..8c13c47 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00002.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00003.png b/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00003.png new file mode 100644 index 0000000..596ee5f Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00003.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00004.png b/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00004.png new file mode 100644 index 0000000..848a5ce Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00004.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00005.png b/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00005.png new file mode 100644 index 0000000..53ae651 Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00005.png differ diff --git a/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00006.png b/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00006.png new file mode 100644 index 0000000..63b43ce Binary files /dev/null and b/tests/snapshots/nanosp/test_sign_tx_simple_ecdsa/00006.png differ diff --git a/tests/snapshots/nanox/test_app_mainmenu/00000.png b/tests/snapshots/nanox/test_app_mainmenu/00000.png index 63b43ce..8ce05d9 100644 Binary files a/tests/snapshots/nanox/test_app_mainmenu/00000.png and b/tests/snapshots/nanox/test_app_mainmenu/00000.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_confirm_accepted/00002.png b/tests/snapshots/nanox/test_get_public_key_confirm_accepted/00002.png index f6fbd41..9145051 100644 Binary files a/tests/snapshots/nanox/test_get_public_key_confirm_accepted/00002.png and b/tests/snapshots/nanox/test_get_public_key_confirm_accepted/00002.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_confirm_accepted/00003.png b/tests/snapshots/nanox/test_get_public_key_confirm_accepted/00003.png index 1da459c..88d6041 100644 Binary files a/tests/snapshots/nanox/test_get_public_key_confirm_accepted/00003.png and b/tests/snapshots/nanox/test_get_public_key_confirm_accepted/00003.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_confirm_accepted/00005.png b/tests/snapshots/nanox/test_get_public_key_confirm_accepted/00005.png index 63b43ce..8ce05d9 100644 Binary files a/tests/snapshots/nanox/test_get_public_key_confirm_accepted/00005.png and b/tests/snapshots/nanox/test_get_public_key_confirm_accepted/00005.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_confirm_refused/00002.png b/tests/snapshots/nanox/test_get_public_key_confirm_refused/00002.png index f6fbd41..9145051 100644 Binary files a/tests/snapshots/nanox/test_get_public_key_confirm_refused/00002.png and b/tests/snapshots/nanox/test_get_public_key_confirm_refused/00002.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_confirm_refused/00003.png b/tests/snapshots/nanox/test_get_public_key_confirm_refused/00003.png index 1da459c..88d6041 100644 Binary files a/tests/snapshots/nanox/test_get_public_key_confirm_refused/00003.png and b/tests/snapshots/nanox/test_get_public_key_confirm_refused/00003.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_confirm_refused/00005.png b/tests/snapshots/nanox/test_get_public_key_confirm_refused/00005.png index c922246..e90cd9d 100644 Binary files a/tests/snapshots/nanox/test_get_public_key_confirm_refused/00005.png and b/tests/snapshots/nanox/test_get_public_key_confirm_refused/00005.png differ diff --git a/tests/snapshots/nanox/test_get_public_key_confirm_refused/00006.png b/tests/snapshots/nanox/test_get_public_key_confirm_refused/00006.png index 63b43ce..8ce05d9 100644 Binary files a/tests/snapshots/nanox/test_get_public_key_confirm_refused/00006.png and b/tests/snapshots/nanox/test_get_public_key_confirm_refused/00006.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_max/00001.png b/tests/snapshots/nanox/test_sign_tx_max/00001.png index 94b99d5..ff1d02e 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_max/00001.png and b/tests/snapshots/nanox/test_sign_tx_max/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_max/00002.png b/tests/snapshots/nanox/test_sign_tx_max/00002.png index c49815e..f32599b 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_max/00002.png and b/tests/snapshots/nanox/test_sign_tx_max/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_max/00006.png b/tests/snapshots/nanox/test_sign_tx_max/00006.png index 63b43ce..8ce05d9 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_max/00006.png and b/tests/snapshots/nanox/test_sign_tx_max/00006.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_p2sh/00001.png b/tests/snapshots/nanox/test_sign_tx_p2sh/00001.png index 52c8036..c08ef70 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_p2sh/00001.png and b/tests/snapshots/nanox/test_sign_tx_p2sh/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_p2sh/00002.png b/tests/snapshots/nanox/test_sign_tx_p2sh/00002.png index 17aa5fd..294633e 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_p2sh/00002.png and b/tests/snapshots/nanox/test_sign_tx_p2sh/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_p2sh/00006.png b/tests/snapshots/nanox/test_sign_tx_p2sh/00006.png index 63b43ce..8ce05d9 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_p2sh/00006.png and b/tests/snapshots/nanox/test_sign_tx_p2sh/00006.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_refused/00001.png b/tests/snapshots/nanox/test_sign_tx_refused/00001.png index 94b99d5..ff1d02e 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_refused/00001.png and b/tests/snapshots/nanox/test_sign_tx_refused/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_refused/00002.png b/tests/snapshots/nanox/test_sign_tx_refused/00002.png index c49815e..f32599b 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_refused/00002.png and b/tests/snapshots/nanox/test_sign_tx_refused/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_refused/00006.png b/tests/snapshots/nanox/test_sign_tx_refused/00006.png index c922246..e90cd9d 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_refused/00006.png and b/tests/snapshots/nanox/test_sign_tx_refused/00006.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_refused/00007.png b/tests/snapshots/nanox/test_sign_tx_refused/00007.png index 63b43ce..8ce05d9 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_refused/00007.png and b/tests/snapshots/nanox/test_sign_tx_refused/00007.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple/00001.png b/tests/snapshots/nanox/test_sign_tx_simple/00001.png index 94b99d5..ff1d02e 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_simple/00001.png and b/tests/snapshots/nanox/test_sign_tx_simple/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple/00002.png b/tests/snapshots/nanox/test_sign_tx_simple/00002.png index c49815e..f32599b 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_simple/00002.png and b/tests/snapshots/nanox/test_sign_tx_simple/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple/00006.png b/tests/snapshots/nanox/test_sign_tx_simple/00006.png index 63b43ce..8ce05d9 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_simple/00006.png and b/tests/snapshots/nanox/test_sign_tx_simple/00006.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple_change_idx1/00001.png b/tests/snapshots/nanox/test_sign_tx_simple_change_idx1/00001.png index 81ff98e..bf75c98 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_simple_change_idx1/00001.png and b/tests/snapshots/nanox/test_sign_tx_simple_change_idx1/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple_change_idx1/00002.png b/tests/snapshots/nanox/test_sign_tx_simple_change_idx1/00002.png index ef35add..6b4439e 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_simple_change_idx1/00002.png and b/tests/snapshots/nanox/test_sign_tx_simple_change_idx1/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple_change_idx1/00006.png b/tests/snapshots/nanox/test_sign_tx_simple_change_idx1/00006.png index 63b43ce..8ce05d9 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_simple_change_idx1/00006.png and b/tests/snapshots/nanox/test_sign_tx_simple_change_idx1/00006.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00000.png b/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00000.png new file mode 100644 index 0000000..df51419 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00000.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00001.png b/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00001.png new file mode 100644 index 0000000..fe57e7f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00002.png b/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00002.png new file mode 100644 index 0000000..909f2d7 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00003.png b/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00003.png new file mode 100644 index 0000000..596ee5f Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00003.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00004.png b/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00004.png new file mode 100644 index 0000000..848a5ce Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00004.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00005.png b/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00005.png new file mode 100644 index 0000000..53ae651 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00005.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00006.png b/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00006.png new file mode 100644 index 0000000..8ce05d9 Binary files /dev/null and b/tests/snapshots/nanox/test_sign_tx_simple_ecdsa/00006.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple_sendint/00001.png b/tests/snapshots/nanox/test_sign_tx_simple_sendint/00001.png index 94b99d5..ff1d02e 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_simple_sendint/00001.png and b/tests/snapshots/nanox/test_sign_tx_simple_sendint/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple_sendint/00002.png b/tests/snapshots/nanox/test_sign_tx_simple_sendint/00002.png index c49815e..f32599b 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_simple_sendint/00002.png and b/tests/snapshots/nanox/test_sign_tx_simple_sendint/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple_sendint/00006.png b/tests/snapshots/nanox/test_sign_tx_simple_sendint/00006.png index 63b43ce..8ce05d9 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_simple_sendint/00006.png and b/tests/snapshots/nanox/test_sign_tx_simple_sendint/00006.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple_sendmaxu64/00001.png b/tests/snapshots/nanox/test_sign_tx_simple_sendmaxu64/00001.png index 94b99d5..ff1d02e 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_simple_sendmaxu64/00001.png and b/tests/snapshots/nanox/test_sign_tx_simple_sendmaxu64/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple_sendmaxu64/00002.png b/tests/snapshots/nanox/test_sign_tx_simple_sendmaxu64/00002.png index c49815e..f32599b 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_simple_sendmaxu64/00002.png and b/tests/snapshots/nanox/test_sign_tx_simple_sendmaxu64/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_simple_sendmaxu64/00006.png b/tests/snapshots/nanox/test_sign_tx_simple_sendmaxu64/00006.png index 63b43ce..8ce05d9 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_simple_sendmaxu64/00006.png and b/tests/snapshots/nanox/test_sign_tx_simple_sendmaxu64/00006.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_change/00001.png b/tests/snapshots/nanox/test_sign_tx_with_change/00001.png index 94b99d5..ff1d02e 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_with_change/00001.png and b/tests/snapshots/nanox/test_sign_tx_with_change/00001.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_change/00002.png b/tests/snapshots/nanox/test_sign_tx_with_change/00002.png index c49815e..f32599b 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_with_change/00002.png and b/tests/snapshots/nanox/test_sign_tx_with_change/00002.png differ diff --git a/tests/snapshots/nanox/test_sign_tx_with_change/00006.png b/tests/snapshots/nanox/test_sign_tx_with_change/00006.png index 63b43ce..8ce05d9 100644 Binary files a/tests/snapshots/nanox/test_sign_tx_with_change/00006.png and b/tests/snapshots/nanox/test_sign_tx_with_change/00006.png differ diff --git a/tests/snapshots/stax/test_app_mainmenu/00000.png b/tests/snapshots/stax/test_app_mainmenu/00000.png index e05fba6..ad6b72e 100644 Binary files a/tests/snapshots/stax/test_app_mainmenu/00000.png and b/tests/snapshots/stax/test_app_mainmenu/00000.png differ diff --git a/tests/snapshots/stax/test_app_mainmenu/00001.png b/tests/snapshots/stax/test_app_mainmenu/00001.png index 67cbbc0..2d6324e 100644 Binary files a/tests/snapshots/stax/test_app_mainmenu/00001.png and b/tests/snapshots/stax/test_app_mainmenu/00001.png differ diff --git a/tests/snapshots/stax/test_app_mainmenu/00002.png b/tests/snapshots/stax/test_app_mainmenu/00002.png index e05fba6..ad6b72e 100644 Binary files a/tests/snapshots/stax/test_app_mainmenu/00002.png and b/tests/snapshots/stax/test_app_mainmenu/00002.png differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_accepted/00000.png b/tests/snapshots/stax/test_get_public_key_confirm_accepted/00000.png index a66705e..b47b2de 100644 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_accepted/00000.png and b/tests/snapshots/stax/test_get_public_key_confirm_accepted/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_accepted/00001.png b/tests/snapshots/stax/test_get_public_key_confirm_accepted/00001.png index b30b100..572e2bd 100644 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_accepted/00001.png and b/tests/snapshots/stax/test_get_public_key_confirm_accepted/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_accepted/00002.png b/tests/snapshots/stax/test_get_public_key_confirm_accepted/00002.png index 0d36f12..e18f4d5 100644 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_accepted/00002.png and b/tests/snapshots/stax/test_get_public_key_confirm_accepted/00002.png differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_accepted/00003.png b/tests/snapshots/stax/test_get_public_key_confirm_accepted/00003.png index b30b100..572e2bd 100644 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_accepted/00003.png and b/tests/snapshots/stax/test_get_public_key_confirm_accepted/00003.png differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_accepted/00004.png b/tests/snapshots/stax/test_get_public_key_confirm_accepted/00004.png index d63f2a1..7831008 100644 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_accepted/00004.png and b/tests/snapshots/stax/test_get_public_key_confirm_accepted/00004.png differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_accepted/00005.png b/tests/snapshots/stax/test_get_public_key_confirm_accepted/00005.png index 96678cb..f59899e 100644 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_accepted/00005.png and b/tests/snapshots/stax/test_get_public_key_confirm_accepted/00005.png differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_accepted/00006.png b/tests/snapshots/stax/test_get_public_key_confirm_accepted/00006.png index e05fba6..ad6b72e 100644 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_accepted/00006.png and b/tests/snapshots/stax/test_get_public_key_confirm_accepted/00006.png differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_refused/part0/00000.png b/tests/snapshots/stax/test_get_public_key_confirm_refused/part0/00000.png index a66705e..b47b2de 100644 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_refused/part0/00000.png and b/tests/snapshots/stax/test_get_public_key_confirm_refused/part0/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_refused/part0/00001.png b/tests/snapshots/stax/test_get_public_key_confirm_refused/part0/00001.png index 762a009..b0eba3f 100644 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_refused/part0/00001.png and b/tests/snapshots/stax/test_get_public_key_confirm_refused/part0/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_refused/part0/00002.png b/tests/snapshots/stax/test_get_public_key_confirm_refused/part0/00002.png index e05fba6..ad6b72e 100644 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_refused/part0/00002.png and b/tests/snapshots/stax/test_get_public_key_confirm_refused/part0/00002.png differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_refused/part1/00000.png b/tests/snapshots/stax/test_get_public_key_confirm_refused/part1/00000.png index a66705e..b47b2de 100644 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_refused/part1/00000.png and b/tests/snapshots/stax/test_get_public_key_confirm_refused/part1/00000.png differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_refused/part1/00001.png b/tests/snapshots/stax/test_get_public_key_confirm_refused/part1/00001.png index b30b100..572e2bd 100644 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_refused/part1/00001.png and b/tests/snapshots/stax/test_get_public_key_confirm_refused/part1/00001.png differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_refused/part1/00002.png b/tests/snapshots/stax/test_get_public_key_confirm_refused/part1/00002.png index 762a009..b0eba3f 100644 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_refused/part1/00002.png and b/tests/snapshots/stax/test_get_public_key_confirm_refused/part1/00002.png differ diff --git a/tests/snapshots/stax/test_get_public_key_confirm_refused/part1/00003.png b/tests/snapshots/stax/test_get_public_key_confirm_refused/part1/00003.png index e05fba6..ad6b72e 100644 Binary files a/tests/snapshots/stax/test_get_public_key_confirm_refused/part1/00003.png and b/tests/snapshots/stax/test_get_public_key_confirm_refused/part1/00003.png differ diff --git a/tests/snapshots/stax/test_sign_tx_max/00000.png b/tests/snapshots/stax/test_sign_tx_max/00000.png index 13de05b..1b50145 100644 Binary files a/tests/snapshots/stax/test_sign_tx_max/00000.png and b/tests/snapshots/stax/test_sign_tx_max/00000.png differ diff --git a/tests/snapshots/stax/test_sign_tx_max/00001.png b/tests/snapshots/stax/test_sign_tx_max/00001.png index 4da4b74..8d5001c 100644 Binary files a/tests/snapshots/stax/test_sign_tx_max/00001.png and b/tests/snapshots/stax/test_sign_tx_max/00001.png differ diff --git a/tests/snapshots/stax/test_sign_tx_max/00002.png b/tests/snapshots/stax/test_sign_tx_max/00002.png index e78ce5f..3c651ba 100644 Binary files a/tests/snapshots/stax/test_sign_tx_max/00002.png and b/tests/snapshots/stax/test_sign_tx_max/00002.png differ diff --git a/tests/snapshots/stax/test_sign_tx_max/00003.png b/tests/snapshots/stax/test_sign_tx_max/00003.png index 7a05bf7..cd2f527 100644 Binary files a/tests/snapshots/stax/test_sign_tx_max/00003.png and b/tests/snapshots/stax/test_sign_tx_max/00003.png differ diff --git a/tests/snapshots/stax/test_sign_tx_max/00004.png b/tests/snapshots/stax/test_sign_tx_max/00004.png index e05fba6..ad6b72e 100644 Binary files a/tests/snapshots/stax/test_sign_tx_max/00004.png and b/tests/snapshots/stax/test_sign_tx_max/00004.png differ diff --git a/tests/snapshots/stax/test_sign_tx_p2sh/00000.png b/tests/snapshots/stax/test_sign_tx_p2sh/00000.png index 13de05b..1b50145 100644 Binary files a/tests/snapshots/stax/test_sign_tx_p2sh/00000.png and b/tests/snapshots/stax/test_sign_tx_p2sh/00000.png differ diff --git a/tests/snapshots/stax/test_sign_tx_p2sh/00001.png b/tests/snapshots/stax/test_sign_tx_p2sh/00001.png index dd3466a..60b0998 100644 Binary files a/tests/snapshots/stax/test_sign_tx_p2sh/00001.png and b/tests/snapshots/stax/test_sign_tx_p2sh/00001.png differ diff --git a/tests/snapshots/stax/test_sign_tx_p2sh/00002.png b/tests/snapshots/stax/test_sign_tx_p2sh/00002.png index e78ce5f..3c651ba 100644 Binary files a/tests/snapshots/stax/test_sign_tx_p2sh/00002.png and b/tests/snapshots/stax/test_sign_tx_p2sh/00002.png differ diff --git a/tests/snapshots/stax/test_sign_tx_p2sh/00003.png b/tests/snapshots/stax/test_sign_tx_p2sh/00003.png index 7a05bf7..cd2f527 100644 Binary files a/tests/snapshots/stax/test_sign_tx_p2sh/00003.png and b/tests/snapshots/stax/test_sign_tx_p2sh/00003.png differ diff --git a/tests/snapshots/stax/test_sign_tx_p2sh/00004.png b/tests/snapshots/stax/test_sign_tx_p2sh/00004.png index e05fba6..ad6b72e 100644 Binary files a/tests/snapshots/stax/test_sign_tx_p2sh/00004.png and b/tests/snapshots/stax/test_sign_tx_p2sh/00004.png differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/part0/00000.png b/tests/snapshots/stax/test_sign_tx_refused/part0/00000.png index 13de05b..1b50145 100644 Binary files a/tests/snapshots/stax/test_sign_tx_refused/part0/00000.png and b/tests/snapshots/stax/test_sign_tx_refused/part0/00000.png differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/part0/00001.png b/tests/snapshots/stax/test_sign_tx_refused/part0/00001.png index be76a06..babad98 100644 Binary files a/tests/snapshots/stax/test_sign_tx_refused/part0/00001.png and b/tests/snapshots/stax/test_sign_tx_refused/part0/00001.png differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/part0/00002.png b/tests/snapshots/stax/test_sign_tx_refused/part0/00002.png index 3c48ddd..cebc8be 100644 Binary files a/tests/snapshots/stax/test_sign_tx_refused/part0/00002.png and b/tests/snapshots/stax/test_sign_tx_refused/part0/00002.png differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/part0/00003.png b/tests/snapshots/stax/test_sign_tx_refused/part0/00003.png index e05fba6..ad6b72e 100644 Binary files a/tests/snapshots/stax/test_sign_tx_refused/part0/00003.png and b/tests/snapshots/stax/test_sign_tx_refused/part0/00003.png differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/part1/00000.png b/tests/snapshots/stax/test_sign_tx_refused/part1/00000.png index 13de05b..1b50145 100644 Binary files a/tests/snapshots/stax/test_sign_tx_refused/part1/00000.png and b/tests/snapshots/stax/test_sign_tx_refused/part1/00000.png differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/part1/00001.png b/tests/snapshots/stax/test_sign_tx_refused/part1/00001.png index 50d82af..8c2dda9 100644 Binary files a/tests/snapshots/stax/test_sign_tx_refused/part1/00001.png and b/tests/snapshots/stax/test_sign_tx_refused/part1/00001.png differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/part1/00002.png b/tests/snapshots/stax/test_sign_tx_refused/part1/00002.png index be76a06..babad98 100644 Binary files a/tests/snapshots/stax/test_sign_tx_refused/part1/00002.png and b/tests/snapshots/stax/test_sign_tx_refused/part1/00002.png differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/part1/00003.png b/tests/snapshots/stax/test_sign_tx_refused/part1/00003.png index 3c48ddd..cebc8be 100644 Binary files a/tests/snapshots/stax/test_sign_tx_refused/part1/00003.png and b/tests/snapshots/stax/test_sign_tx_refused/part1/00003.png differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/part1/00004.png b/tests/snapshots/stax/test_sign_tx_refused/part1/00004.png index e05fba6..ad6b72e 100644 Binary files a/tests/snapshots/stax/test_sign_tx_refused/part1/00004.png and b/tests/snapshots/stax/test_sign_tx_refused/part1/00004.png differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/part2/00000.png b/tests/snapshots/stax/test_sign_tx_refused/part2/00000.png index 13de05b..1b50145 100644 Binary files a/tests/snapshots/stax/test_sign_tx_refused/part2/00000.png and b/tests/snapshots/stax/test_sign_tx_refused/part2/00000.png differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/part2/00001.png b/tests/snapshots/stax/test_sign_tx_refused/part2/00001.png index 50d82af..8c2dda9 100644 Binary files a/tests/snapshots/stax/test_sign_tx_refused/part2/00001.png and b/tests/snapshots/stax/test_sign_tx_refused/part2/00001.png differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/part2/00002.png b/tests/snapshots/stax/test_sign_tx_refused/part2/00002.png index e78ce5f..3c651ba 100644 Binary files a/tests/snapshots/stax/test_sign_tx_refused/part2/00002.png and b/tests/snapshots/stax/test_sign_tx_refused/part2/00002.png differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/part2/00003.png b/tests/snapshots/stax/test_sign_tx_refused/part2/00003.png index be76a06..babad98 100644 Binary files a/tests/snapshots/stax/test_sign_tx_refused/part2/00003.png and b/tests/snapshots/stax/test_sign_tx_refused/part2/00003.png differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/part2/00004.png b/tests/snapshots/stax/test_sign_tx_refused/part2/00004.png index 3c48ddd..cebc8be 100644 Binary files a/tests/snapshots/stax/test_sign_tx_refused/part2/00004.png and b/tests/snapshots/stax/test_sign_tx_refused/part2/00004.png differ diff --git a/tests/snapshots/stax/test_sign_tx_refused/part2/00005.png b/tests/snapshots/stax/test_sign_tx_refused/part2/00005.png index e05fba6..ad6b72e 100644 Binary files a/tests/snapshots/stax/test_sign_tx_refused/part2/00005.png and b/tests/snapshots/stax/test_sign_tx_refused/part2/00005.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple/00000.png b/tests/snapshots/stax/test_sign_tx_simple/00000.png index 13de05b..1b50145 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple/00000.png and b/tests/snapshots/stax/test_sign_tx_simple/00000.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple/00001.png b/tests/snapshots/stax/test_sign_tx_simple/00001.png index 50d82af..8c2dda9 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple/00001.png and b/tests/snapshots/stax/test_sign_tx_simple/00001.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple/00002.png b/tests/snapshots/stax/test_sign_tx_simple/00002.png index e78ce5f..3c651ba 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple/00002.png and b/tests/snapshots/stax/test_sign_tx_simple/00002.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple/00003.png b/tests/snapshots/stax/test_sign_tx_simple/00003.png index 7a05bf7..cd2f527 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple/00003.png and b/tests/snapshots/stax/test_sign_tx_simple/00003.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple/00004.png b/tests/snapshots/stax/test_sign_tx_simple/00004.png index e05fba6..ad6b72e 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple/00004.png and b/tests/snapshots/stax/test_sign_tx_simple/00004.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00000.png b/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00000.png index 13de05b..1b50145 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00000.png and b/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00000.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00001.png b/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00001.png index ce109b7..b6c02f1 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00001.png and b/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00001.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00002.png b/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00002.png index e78ce5f..3c651ba 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00002.png and b/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00002.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00003.png b/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00003.png index 7a05bf7..cd2f527 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00003.png and b/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00003.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00004.png b/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00004.png index e05fba6..ad6b72e 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00004.png and b/tests/snapshots/stax/test_sign_tx_simple_change_idx1/00004.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_ecdsa/00000.png b/tests/snapshots/stax/test_sign_tx_simple_ecdsa/00000.png new file mode 100644 index 0000000..1b50145 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_simple_ecdsa/00000.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_ecdsa/00001.png b/tests/snapshots/stax/test_sign_tx_simple_ecdsa/00001.png new file mode 100644 index 0000000..7cb1f61 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_simple_ecdsa/00001.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_ecdsa/00002.png b/tests/snapshots/stax/test_sign_tx_simple_ecdsa/00002.png new file mode 100644 index 0000000..3c651ba Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_simple_ecdsa/00002.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_ecdsa/00003.png b/tests/snapshots/stax/test_sign_tx_simple_ecdsa/00003.png new file mode 100644 index 0000000..cd2f527 Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_simple_ecdsa/00003.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_ecdsa/00004.png b/tests/snapshots/stax/test_sign_tx_simple_ecdsa/00004.png new file mode 100644 index 0000000..ad6b72e Binary files /dev/null and b/tests/snapshots/stax/test_sign_tx_simple_ecdsa/00004.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_sendint/00000.png b/tests/snapshots/stax/test_sign_tx_simple_sendint/00000.png index 13de05b..1b50145 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple_sendint/00000.png and b/tests/snapshots/stax/test_sign_tx_simple_sendint/00000.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_sendint/00001.png b/tests/snapshots/stax/test_sign_tx_simple_sendint/00001.png index 67d5cdd..1e78a16 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple_sendint/00001.png and b/tests/snapshots/stax/test_sign_tx_simple_sendint/00001.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_sendint/00002.png b/tests/snapshots/stax/test_sign_tx_simple_sendint/00002.png index e78ce5f..3c651ba 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple_sendint/00002.png and b/tests/snapshots/stax/test_sign_tx_simple_sendint/00002.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_sendint/00003.png b/tests/snapshots/stax/test_sign_tx_simple_sendint/00003.png index 7a05bf7..cd2f527 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple_sendint/00003.png and b/tests/snapshots/stax/test_sign_tx_simple_sendint/00003.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_sendint/00004.png b/tests/snapshots/stax/test_sign_tx_simple_sendint/00004.png index e05fba6..ad6b72e 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple_sendint/00004.png and b/tests/snapshots/stax/test_sign_tx_simple_sendint/00004.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00000.png b/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00000.png index 13de05b..1b50145 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00000.png and b/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00000.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00001.png b/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00001.png index 405a5b8..2be07d9 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00001.png and b/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00001.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00002.png b/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00002.png index e78ce5f..3c651ba 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00002.png and b/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00002.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00003.png b/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00003.png index 7a05bf7..cd2f527 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00003.png and b/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00003.png differ diff --git a/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00004.png b/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00004.png index e05fba6..ad6b72e 100644 Binary files a/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00004.png and b/tests/snapshots/stax/test_sign_tx_simple_sendmaxu64/00004.png differ diff --git a/tests/snapshots/stax/test_sign_tx_with_change/00000.png b/tests/snapshots/stax/test_sign_tx_with_change/00000.png index 13de05b..1b50145 100644 Binary files a/tests/snapshots/stax/test_sign_tx_with_change/00000.png and b/tests/snapshots/stax/test_sign_tx_with_change/00000.png differ diff --git a/tests/snapshots/stax/test_sign_tx_with_change/00001.png b/tests/snapshots/stax/test_sign_tx_with_change/00001.png index 751c238..2f1cb10 100644 Binary files a/tests/snapshots/stax/test_sign_tx_with_change/00001.png and b/tests/snapshots/stax/test_sign_tx_with_change/00001.png differ diff --git a/tests/snapshots/stax/test_sign_tx_with_change/00002.png b/tests/snapshots/stax/test_sign_tx_with_change/00002.png index e78ce5f..3c651ba 100644 Binary files a/tests/snapshots/stax/test_sign_tx_with_change/00002.png and b/tests/snapshots/stax/test_sign_tx_with_change/00002.png differ diff --git a/tests/snapshots/stax/test_sign_tx_with_change/00003.png b/tests/snapshots/stax/test_sign_tx_with_change/00003.png index 7a05bf7..cd2f527 100644 Binary files a/tests/snapshots/stax/test_sign_tx_with_change/00003.png and b/tests/snapshots/stax/test_sign_tx_with_change/00003.png differ diff --git a/tests/snapshots/stax/test_sign_tx_with_change/00004.png b/tests/snapshots/stax/test_sign_tx_with_change/00004.png index e05fba6..ad6b72e 100644 Binary files a/tests/snapshots/stax/test_sign_tx_with_change/00004.png and b/tests/snapshots/stax/test_sign_tx_with_change/00004.png differ diff --git a/tests/test_sign_cmd.py b/tests/test_sign_cmd.py index 9a09cba..0c7dd6d 100644 --- a/tests/test_sign_cmd.py +++ b/tests/test_sign_cmd.py @@ -66,6 +66,63 @@ def test_sign_tx_simple(firmware, backend, navigator, test_name): assert transaction.get_sighash(0) == sighash assert check_signature_validity(public_key, der_sig, sighash, transaction) +def test_sign_tx_simple_ecdsa(firmware, backend, navigator, test_name): + # Use the app interface instead of raw interface + client = KaspaCommandSender(backend) + # The path used for this entire test + path: str = "m/44'/111111'/0'/0/0" + + # First we need to get the public key of the device in order to build the transaction + rapdu = client.get_public_key(path=path) + _, public_key, _, _ = unpack_get_public_key_response(rapdu.data) + + # Create the transaction that will be sent to the device for signing + transaction = Transaction( + version=0, + inputs=[ + TransactionInput( + value=1100000, + tx_id="40b022362f1a303518e2b49f86f87a317c87b514ca0f3d08ad2e7cf49d08cc70", + address_type=0, + address_index=0, + index=0, + public_key=public_key[1:33] + ) + ], + outputs=[ + TransactionOutput( + value=1090000, + script_public_key="2102dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659ab" + ) + ] + ) + + # Send the sign device instruction. + # As it requires on-screen validation, the function is asynchronous. + # It will yield the result when the navigation is done + with client.sign_tx(transaction=transaction): + # Validate the on-screen request by performing the navigation appropriate for this device + if firmware.device.startswith("nano"): + navigator.navigate_until_text_and_compare(NavInsID.RIGHT_CLICK, + [NavInsID.BOTH_CLICK], + "Approve", + ROOT_SCREENSHOT_PATH, + test_name) + else: + navigator.navigate_until_text_and_compare(NavInsID.USE_CASE_REVIEW_TAP, + [NavInsID.USE_CASE_REVIEW_CONFIRM, + NavInsID.USE_CASE_STATUS_DISMISS], + "Hold to sign", + ROOT_SCREENSHOT_PATH, + test_name) + + # The device as yielded the result, parse it and ensure that the signature is correct + response = client.get_async_response().data + _, _, _, der_sig, _, sighash = unpack_sign_tx_response(response) + assert transaction.get_sighash(0) == sighash + assert check_signature_validity(public_key, der_sig, sighash, transaction) + + def test_sign_tx_p2sh(firmware, backend, navigator, test_name): # Use the app interface instead of raw interface client = KaspaCommandSender(backend) diff --git a/unit-tests/CMakeLists.txt b/unit-tests/CMakeLists.txt index 9c170f8..9299687 100644 --- a/unit-tests/CMakeLists.txt +++ b/unit-tests/CMakeLists.txt @@ -41,14 +41,12 @@ include_directories(mock_includes) # include_directories(/opt/nanos-secure-sdk/include/) include_directories(/opt/ledger-secure-sdk/include/) include_directories(/opt/ledger-secure-sdk/lib_cxng/include) +include_directories(/opt/ledger-secure-sdk/lib_standard_app/) add_executable(test_address test_address.c) -add_executable(test_bip32 test_bip32.c) -add_executable(test_buffer test_buffer.c) add_executable(test_format test_format.c) add_executable(test_sighash test_sighash.c) -add_executable(test_write test_write.c) add_executable(test_apdu_parser test_apdu_parser.c) add_executable(test_tx_parser test_tx_parser.c) add_executable(test_tx_utils test_tx_utils.c) @@ -56,28 +54,27 @@ add_executable(test_tx_utils test_tx_utils.c) add_library(address SHARED ../src/address.c) add_library(blake2b SHARED ../src/import/blake2b.c) add_library(cashaddr SHARED ../src/import/cashaddr.c) -add_library(bip32 SHARED ../src/common/bip32.c) -add_library(buffer SHARED ../src/common/buffer.c) -add_library(read SHARED ../src/common/read.c) +add_library(bip32 SHARED /opt/ledger-secure-sdk/lib_standard_app/bip32.c) +add_library(buffer SHARED /opt/ledger-secure-sdk/lib_standard_app/buffer.c) +add_library(read SHARED /opt/ledger-secure-sdk/lib_standard_app/read.c) add_library(sighash SHARED ../src/sighash.c) -add_library(write SHARED ../src/common/write.c) +add_library(write SHARED /opt/ledger-secure-sdk/lib_standard_app/write.c) add_library(format SHARED ../src/common/format.c) add_library(apdu_parser SHARED ../src/apdu/parser.c) add_library(transaction_deserialize ../src/transaction/deserialize.c) add_library(transaction_serialize ../src/transaction/serialize.c) add_library(transaction_utils ../src/transaction/utils.c) +add_library(varint SHARED /opt/ledger-secure-sdk/lib_standard_app/varint.c) target_link_libraries(test_address PUBLIC cmocka gcov address cashaddr) -target_link_libraries(test_bip32 PUBLIC cmocka gcov bip32 read) -target_link_libraries(test_buffer PUBLIC cmocka gcov buffer bip32 write read) target_link_libraries(test_format PUBLIC cmocka gcov format) target_link_libraries(test_sighash PUBLIC cmocka gcov sighash blake2b write) -target_link_libraries(test_write PUBLIC cmocka gcov write) target_link_libraries(test_apdu_parser PUBLIC cmocka gcov apdu_parser) target_link_libraries(test_tx_parser PUBLIC transaction_deserialize transaction_serialize buffer + varint bip32 cmocka gcov @@ -92,11 +89,8 @@ target_link_libraries(test_tx_utils PUBLIC cashaddr) add_test(test_address test_address) -add_test(test_bip32 test_bip32) -add_test(test_buffer test_buffer) add_test(test_format test_format) add_test(test_sighash test_sighash) -add_test(test_write test_write) add_test(test_apdu_parser test_apdu_parser) add_test(test_tx_parser test_tx_parser) add_test(test_tx_utils test_tx_utils) diff --git a/unit-tests/gen_coverage.sh b/unit-tests/gen_coverage.sh index 9cf0594..c956343 100755 --- a/unit-tests/gen_coverage.sh +++ b/unit-tests/gen_coverage.sh @@ -8,7 +8,7 @@ BUILD_DIRECTORY=$(realpath build/) lcov --directory . -b "${BUILD_DIRECTORY}" --capture --initial -o coverage.base && lcov --rc lcov_branch_coverage=1 --directory . -b "${BUILD_DIRECTORY}" --capture -o coverage.capture && lcov --directory . -b "${BUILD_DIRECTORY}" --add-tracefile coverage.base --add-tracefile coverage.capture -o coverage.info && -lcov --directory . -b "${BUILD_DIRECTORY}" --remove coverage.info '*/unit-tests/*,*/src/import/*' -o coverage.info && +lcov --directory . -b "${BUILD_DIRECTORY}" --remove coverage.info '*/unit-tests/*' --remove coverage.info 'lib_standard_app' --remove coverage.info '*/src/import/*' -o coverage.info && echo "Generated 'coverage.info'." && genhtml coverage.info -o coverage diff --git a/unit-tests/test_bip32.c b/unit-tests/test_bip32.c deleted file mode 100644 index 4610c58..0000000 --- a/unit-tests/test_bip32.c +++ /dev/null @@ -1,132 +0,0 @@ -/***************************************************************************** - * MIT License - * - * Copyright (c) 2023 coderofstuff - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#include -#include -#include -#include -#include - -#include - -#include "common/bip32.h" - -static void test_bip32_format(void **state) { - (void) state; - - char output[30]; - bool b = false; - - b = bip32_path_format((const uint32_t[5]){0x8000002C, 0x80000000, 0x80000000, 0, 0}, - 5, - output, - sizeof(output)); - assert_true(b); - assert_string_equal(output, "44'/0'/0'/0/0"); - - b = bip32_path_format((const uint32_t[5]){0x8000002C, 0x80000001, 0x80000000, 0, 0}, - 5, - output, - sizeof(output)); - assert_true(b); - assert_string_equal(output, "44'/1'/0'/0/0"); - - b = bip32_path_format((const uint32_t[5]){0x8000002C, 0x8001b207, 0x80000000, 0, 0}, - 5, - output, - sizeof(output)); - assert_true(b); - // Hex APDU: e005010015058000002c8001b207800000000000000000000000 - assert_string_equal(output, "44'/111111'/0'/0/0"); -} - -static void test_bad_bip32_format(void **state) { - (void) state; - - char output[30]; - bool b = true; - - // More than MAX_BIP32_PATH (=10) - b = bip32_path_format( - (const uint32_t[11]){0x8000002C, 0x80000000, 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0}, - 11, - output, - sizeof(output)); - assert_false(b); - - // No BIP32 path (=0) - b = bip32_path_format(NULL, 0, output, sizeof(output)); - assert_false(b); -} - -static void test_bip32_read(void **state) { - (void) state; - - // clang-format off - uint8_t input[20] = { - 0x80, 0x00, 0x00, 0x2C, - 0x80, 0x00, 0x00, 0x01, - 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - uint32_t expected[5] = {0x8000002C, 0x80000001, 0x80000000, 0, 0}; - uint32_t output[5] = {0}; - bool b = false; - - b = bip32_path_read(input, sizeof(input), output, 5); - assert_true(b); - assert_memory_equal(output, expected, 5); -} - -static void test_bad_bip32_read(void **state) { - (void) state; - - // clang-format off - uint8_t input[20] = { - 0x80, 0x00, 0x00, 0x2C, - 0x80, 0x00, 0x00, 0x01, - 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - uint32_t output[10] = {0}; - - // buffer too small (5 BIP32 paths instead of 10) - assert_false(bip32_path_read(input, sizeof(input), output, 10)); - - // No BIP32 path - assert_false(bip32_path_read(input, sizeof(input), output, 0)); - - // More than MAX_BIP32_PATH (=10) - assert_false(bip32_path_read(input, sizeof(input), output, 20)); -} - -int main() { - const struct CMUnitTest tests[] = {cmocka_unit_test(test_bip32_format), - cmocka_unit_test(test_bad_bip32_format), - cmocka_unit_test(test_bip32_read), - cmocka_unit_test(test_bad_bip32_read)}; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/unit-tests/test_buffer.c b/unit-tests/test_buffer.c deleted file mode 100644 index c75034e..0000000 --- a/unit-tests/test_buffer.c +++ /dev/null @@ -1,158 +0,0 @@ -/***************************************************************************** - * MIT License - * - * Copyright (c) 2023 coderofstuff - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#include -#include -#include -#include -#include - -#include - -#include "common/buffer.h" - -static void test_buffer_can_read(void **state) { - (void) state; - - uint8_t temp[20] = {0}; - buffer_t buf = {.ptr = temp, .size = sizeof(temp), .offset = 0}; - - assert_true(buffer_can_read(&buf, 20)); - - assert_true(buffer_seek_cur(&buf, 20)); - assert_false(buffer_can_read(&buf, 1)); -} - -static void test_buffer_seek(void **state) { - (void) state; - - uint8_t temp[20] = {0}; - buffer_t buf = {.ptr = temp, .size = sizeof(temp), .offset = 0}; - - assert_true(buffer_can_read(&buf, 20)); - - assert_true(buffer_seek_cur(&buf, 20)); // seek at offset 20 - assert_false(buffer_can_read(&buf, 1)); // can't read 1 byte - assert_false(buffer_seek_cur(&buf, 1)); // can't move at offset 21 - - assert_true(buffer_seek_end(&buf, 19)); - assert_int_equal(buf.offset, 1); - assert_false(buffer_seek_end(&buf, 21)); // can't seek at offset -1 - - assert_true(buffer_seek_set(&buf, 10)); - assert_int_equal(buf.offset, 10); - assert_false(buffer_seek_set(&buf, 21)); // can't seek at offset 21 -} - -static void test_buffer_read(void **state) { - (void) state; - - // clang-format off - uint8_t temp[15] = { - 0xFF, - 0x01, 0x02, - 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E - }; - buffer_t buf = {.ptr = temp, .size = sizeof(temp), .offset = 0}; - - uint8_t first = 0; - assert_true(buffer_read_u8(&buf, &first)); - assert_int_equal(first, 255); // 0xFF - assert_true(buffer_seek_end(&buf, 0)); // seek at offset 19 - assert_false(buffer_read_u8(&buf, &first)); // can't read 1 byte - - uint16_t second = 0; - assert_true(buffer_seek_set(&buf, 1)); // set back to offset 1 - assert_true(buffer_read_u16(&buf, &second, BE)); // big endian - assert_int_equal(second, 258); // 0x01 0x02 - assert_true(buffer_seek_set(&buf, 1)); // set back to offset 1 - assert_true(buffer_read_u16(&buf, &second, LE)); // little endian - assert_int_equal(second, 513); // 0x02 0x01 - assert_true(buffer_seek_set(&buf, 14)); // seek at offset 14 - assert_false(buffer_read_u16(&buf, &second, BE)); // can't read 2 bytes - - uint32_t third = 0; - assert_true(buffer_seek_set(&buf, 3)); // set back to offset 3 - assert_true(buffer_read_u32(&buf, &third, BE)); // big endian - assert_int_equal(third, 50595078); // 0x03 0x04 0x05 0x06 - assert_true(buffer_seek_set(&buf, 3)); // set back to offset 3 - assert_true(buffer_read_u32(&buf, &third, LE)); // little endian - assert_int_equal(third, 100992003); // 0x06 0x05 0x04 0x03 - assert_true(buffer_seek_set(&buf, 12)); // seek at offset 12 - assert_false(buffer_read_u32(&buf, &third, BE)); // can't read 4 bytes - - uint64_t fourth = 0; - assert_true(buffer_seek_set(&buf, 7)); // set back to offset 7 - assert_true(buffer_read_u64(&buf, &fourth, BE)); // big endian - assert_int_equal(fourth, 506664896818842894); // 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E - assert_true(buffer_seek_set(&buf, 7)); // set back to offset 7 - assert_true(buffer_read_u64(&buf, &fourth, LE)); // little endian - assert_int_equal(fourth, 1012478732780767239); // 0x0E 0x0D 0x0C 0x0B 0x0A 0x09 0x08 0x07 - assert_true(buffer_seek_set(&buf, 8)); // seek at offset 8 - assert_false(buffer_read_u64(&buf, &fourth, BE)); // can't read 8 bytes -} - -static void test_buffer_copy(void **state) { - (void) state; - - uint8_t output[5] = {0}; - uint8_t temp[5] = {0x01, 0x02, 0x03, 0x04, 0x05}; - buffer_t buf = {.ptr = temp, .size = sizeof(temp), .offset = 0}; - - assert_true(buffer_copy(&buf, output, sizeof(output))); - assert_memory_equal(output, temp, sizeof(output)); - - uint8_t output2[3] = {0}; - assert_true(buffer_seek_set(&buf, 2)); - assert_true(buffer_copy(&buf, output2, sizeof(output2))); - assert_memory_equal(output2, ((uint8_t[3]){0x03, 0x04, 0x05}), 3); - assert_true(buffer_seek_set(&buf, 0)); // seek at offset 0 - assert_false(buffer_copy(&buf, output2, sizeof(output2))); // can't read 5 bytes -} - -static void test_buffer_move(void **state) { - (void) state; - - uint8_t output[5] = {0}; - uint8_t temp[5] = {0x01, 0x02, 0x03, 0x04, 0x05}; - buffer_t buf = {.ptr = temp, .size = sizeof(temp), .offset = 0}; - - assert_true(buffer_move(&buf, output, sizeof(output))); - assert_memory_equal(output, temp, sizeof(output)); - assert_int_equal(buf.offset, sizeof(output)); - - uint8_t output2[3] = {0}; - assert_true(buffer_seek_set(&buf, 0)); // seek at offset 0 - assert_false(buffer_move(&buf, output2, sizeof(output2))); // can't read 5 bytes -} - -int main() { - const struct CMUnitTest tests[] = {cmocka_unit_test(test_buffer_can_read), - cmocka_unit_test(test_buffer_seek), - cmocka_unit_test(test_buffer_read), - cmocka_unit_test(test_buffer_copy), - cmocka_unit_test(test_buffer_move)}; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/unit-tests/test_format.c b/unit-tests/test_format.c index 718fd7a..06a1396 100644 --- a/unit-tests/test_format.c +++ b/unit-tests/test_format.c @@ -73,46 +73,46 @@ static void test_format_u64(void **state) { assert_false(format_u64(temp, sizeof(temp) - 5, value)); } -static void test_format_fpu64(void **state) { +static void test_format_fpu64_trimmed(void **state) { (void) state; char temp[22] = {0}; uint64_t amount = 0ull; // satoshi memset(temp, 0, sizeof(temp)); - assert_true(format_fpu64(temp, sizeof(temp), amount, 8)); + assert_true(format_fpu64_trimmed(temp, sizeof(temp), amount, 8)); assert_string_equal(temp, "0"); // BTC amount = 100000000ull; // satoshi memset(temp, 0, sizeof(temp)); - assert_true(format_fpu64(temp, sizeof(temp), amount, 8)); + assert_true(format_fpu64_trimmed(temp, sizeof(temp), amount, 8)); assert_string_equal(temp, "1"); // BTC amount = 24964823ull; // satoshi memset(temp, 0, sizeof(temp)); - assert_true(format_fpu64(temp, sizeof(temp), amount, 8)); + assert_true(format_fpu64_trimmed(temp, sizeof(temp), amount, 8)); assert_string_equal(temp, "0.24964823"); // BTC amount = 100ull; // satoshi memset(temp, 0, sizeof(temp)); - assert_true(format_fpu64(temp, sizeof(temp), amount, 8)); + assert_true(format_fpu64_trimmed(temp, sizeof(temp), amount, 8)); assert_string_equal(temp, "0.000001"); // BTC // buffer too small - assert_false(format_fpu64(temp, sizeof(temp) - 16, amount, 8)); + assert_false(format_fpu64_trimmed(temp, sizeof(temp) - 16, amount, 8)); char temp2[50] = {0}; amount = 1000000000000000000ull; // wei - assert_true(format_fpu64(temp2, sizeof(temp2), amount, 18)); + assert_true(format_fpu64_trimmed(temp2, sizeof(temp2), amount, 18)); assert_string_equal(temp2, "1"); // ETH amount = 100000000000000000ull; // wei - assert_true(format_fpu64(temp2, sizeof(temp2), amount, 18)); + assert_true(format_fpu64_trimmed(temp2, sizeof(temp2), amount, 18)); assert_string_equal(temp2, "0.1"); // ETH // buffer too small amount = 1000000000000000001ull; // wei - assert_false(format_fpu64(temp2, sizeof(temp2) - 20, amount, 18)); + assert_false(format_fpu64_trimmed(temp2, sizeof(temp2) - 20, amount, 18)); } static void test_format_hex(void **state) { @@ -131,7 +131,7 @@ static void test_format_hex(void **state) { int main() { const struct CMUnitTest tests[] = {cmocka_unit_test(test_format_i64), cmocka_unit_test(test_format_u64), - cmocka_unit_test(test_format_fpu64), + cmocka_unit_test(test_format_fpu64_trimmed), cmocka_unit_test(test_format_hex)}; return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/unit-tests/test_write.c b/unit-tests/test_write.c deleted file mode 100644 index ac299ed..0000000 --- a/unit-tests/test_write.c +++ /dev/null @@ -1,87 +0,0 @@ -/***************************************************************************** - * MIT License - * - * Copyright (c) 2023 coderofstuff - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#include -#include -#include -#include -#include -#include - -#include - -#include "common/write.h" - -static void test_write(void **state) { - (void) state; - - uint8_t tmp2[2] = {0}; - - uint8_t expected2[2] = {0x01, 0x07}; - write_u16_be(tmp2, 0, (uint16_t) 263U); - assert_memory_equal(tmp2, expected2, sizeof(expected2)); - - memset(tmp2, 0, sizeof(tmp2)); - expected2[0] = 0x07; - expected2[1] = 0x01; - write_u16_le(tmp2, 0, (uint16_t) 263U); - assert_memory_equal(tmp2, expected2, sizeof(expected2)); - - uint8_t tmp4[4] = {0}; - - uint8_t expected4[4] = {0x01, 0x3B, 0xAC, 0xC7}; - write_u32_be(tmp4, 0, (uint32_t) 20688071UL); - assert_memory_equal(tmp4, expected4, sizeof(expected4)); - - memset(tmp4, 0, sizeof(tmp4)); - expected4[0] = 0xC7; - expected4[1] = 0xAC; - expected4[2] = 0x3B; - expected4[3] = 0x01; - write_u32_le(tmp4, 0, (uint32_t) 20688071UL); - assert_memory_equal(tmp4, expected4, sizeof(expected4)); - - uint8_t tmp8[8] = {0}; - - uint8_t expected8[8] = {0xEB, 0x68, 0x44, 0xC0, 0x2C, 0x61, 0xB0, 0x99}; - write_u64_be(tmp8, 0, (uint64_t) 16962883588659982489ULL); - assert_memory_equal(tmp8, expected8, sizeof(expected8)); - - memset(tmp8, 0, sizeof(tmp8)); - expected8[0] = 0x99; - expected8[1] = 0xB0; - expected8[2] = 0x61; - expected8[3] = 0x2C; - expected8[4] = 0xC0; - expected8[5] = 0x44; - expected8[6] = 0x68; - expected8[7] = 0xEB; - write_u64_le(tmp8, 0, (uint64_t) 16962883588659982489ULL); - assert_memory_equal(tmp8, expected8, sizeof(expected8)); -} - -int main() { - const struct CMUnitTest tests[] = {cmocka_unit_test(test_write)}; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/utils.sh b/utils.sh index db00024..d2b9bee 100755 --- a/utils.sh +++ b/utils.sh @@ -110,7 +110,20 @@ function load_to_device() { build_app $DEVICE - if [ "$DEVICE" == "nanosp" ]; then + if [ "$DEVICE" == "nanox" ]; then \ + python3 -m ledgerblue.loadApp \ + --curve secp256k1 \ + --appFlags 0x000 \ + --path "44'/111111'" \ + --tlv \ + --targetId 0x33000004 \ + --fileName bin/app.hex \ + --appName Kaspa \ + --appVersion 1.0.0 \ + --icon "0100000000ffffff000778001830e21c7807fc017e801ff007de8173048c01e0010e" \ + --apiLevel 1 \ + --delete + elif [ "$DEVICE" == "nanosp" ]; then python3 -m ledgerblue.loadApp \ --curve secp256k1 \ --appFlags 0x000 \