From 2083aa535155abde3c71cf38865cf9c0ee762818 Mon Sep 17 00:00:00 2001 From: Ariel Mendelzon Date: Tue, 21 May 2024 15:21:21 +0200 Subject: [PATCH] Decoupling business layer from hardware layer in Signer component - Added HAL headers - Added HAL implementation for Ledger - Refactored necessary common sources - Refactored necessary Signer sources - Updated Signer Makefile to include HAL code - Removed HSM_SIMULATOR define in favor of HSM_PLATFORM_* defines - Included X86 (partial) implemenations of some HAL modules (exceptions, logging, hashing) --- ledger/src/common/src/apdu.h | 30 +- ledger/src/common/src/memutil.h | 5 +- ledger/src/common/src/runtime.h | 21 +- ledger/src/hal/include/hal/communication.h | 75 +++++ ledger/src/hal/include/hal/endorsement.h | 71 +++++ ledger/src/hal/include/hal/exceptions.h | 219 ++++++++++++++ ledger/src/hal/include/hal/hash.h | 171 +++++++++++ .../src/dbg.h => hal/include/hal/log.h} | 26 +- ledger/src/hal/include/hal/nvmem.h | 43 +++ ledger/src/hal/include/hal/platform.h | 45 +++ ledger/src/hal/include/hal/seed.h | 73 +++++ .../{signer/src => hal/src/common}/sha256.c | 0 .../{signer/src => hal/src/common}/sha256.h | 0 .../src/ledger/communication.c} | 50 ++-- ledger/src/hal/src/ledger/endorsement.c | 69 +++++ ledger/src/hal/src/ledger/hash.c | 80 ++++++ .../hsm-ledger.h => hal/src/ledger/nvmem.c} | 11 +- ledger/src/hal/src/ledger/platform.c | 41 +++ .../src/sign.c => hal/src/ledger/seed.c} | 108 +++---- ledger/src/hal/src/ledger/sha256.c | 1 + ledger/src/hal/src/ledger/sha256.h | 1 + ledger/src/signer/Makefile | 9 +- ledger/src/signer/src/attestation.c | 109 ++++--- ledger/src/signer/src/auth.c | 28 +- ledger/src/signer/src/auth.h | 2 + ledger/src/signer/src/auth_path.c | 4 +- ledger/src/signer/src/auth_receipt.c | 12 +- ledger/src/signer/src/auth_receipt.h | 5 +- ledger/src/signer/src/auth_trie.c | 18 +- ledger/src/signer/src/auth_trie.h | 7 +- ledger/src/signer/src/auth_tx.c | 137 ++++----- ledger/src/signer/src/auth_tx.h | 13 +- ledger/src/signer/src/bc_advance.c | 29 +- ledger/src/signer/src/bc_ancestor.c | 4 +- ledger/src/signer/src/bc_block.h | 7 +- ledger/src/signer/src/bc_diff.c | 4 +- ledger/src/signer/src/bc_diff.h | 2 +- ledger/src/signer/src/bc_err.c | 2 +- ledger/src/signer/src/bc_err.h | 2 + ledger/src/signer/src/bc_hash.h | 24 +- ledger/src/signer/src/bc_nu.h | 2 +- ledger/src/signer/src/bc_state.c | 10 +- ledger/src/signer/src/bc_state.h | 2 +- ledger/src/signer/src/common_requirements.h | 31 ++ ledger/src/signer/src/heartbeat.c | 30 +- ledger/src/signer/src/heartbeat.h | 3 - ledger/src/signer/src/hsm.c | 87 ++++-- ledger/src/signer/src/hsm.h | 8 +- ledger/src/signer/src/keccak256.c | 267 ------------------ ledger/src/signer/src/keccak256.h | 81 ------ ledger/src/signer/src/main.c | 12 +- ledger/src/signer/src/mem.h | 10 +- ledger/src/signer/src/nvm.h | 9 +- ledger/src/signer/src/sign.h | 67 ----- ledger/src/signer/src/srlp.c | 22 +- 55 files changed, 1380 insertions(+), 819 deletions(-) create mode 100644 ledger/src/hal/include/hal/communication.h create mode 100644 ledger/src/hal/include/hal/endorsement.h create mode 100644 ledger/src/hal/include/hal/exceptions.h create mode 100644 ledger/src/hal/include/hal/hash.h rename ledger/src/{signer/src/dbg.h => hal/include/hal/log.h} (82%) create mode 100644 ledger/src/hal/include/hal/nvmem.h create mode 100644 ledger/src/hal/include/hal/platform.h create mode 100644 ledger/src/hal/include/hal/seed.h rename ledger/src/{signer/src => hal/src/common}/sha256.c (100%) rename ledger/src/{signer/src => hal/src/common}/sha256.h (100%) rename ledger/src/{signer/src/hsm-ledger.c => hal/src/ledger/communication.c} (54%) create mode 100644 ledger/src/hal/src/ledger/endorsement.c create mode 100644 ledger/src/hal/src/ledger/hash.c rename ledger/src/{signer/src/hsm-ledger.h => hal/src/ledger/nvmem.c} (88%) create mode 100644 ledger/src/hal/src/ledger/platform.c rename ledger/src/{signer/src/sign.c => hal/src/ledger/seed.c} (59%) create mode 120000 ledger/src/hal/src/ledger/sha256.c create mode 120000 ledger/src/hal/src/ledger/sha256.h create mode 100644 ledger/src/signer/src/common_requirements.h delete mode 100644 ledger/src/signer/src/keccak256.c delete mode 100644 ledger/src/signer/src/keccak256.h delete mode 100644 ledger/src/signer/src/sign.h diff --git a/ledger/src/common/src/apdu.h b/ledger/src/common/src/apdu.h index 80c7e15b..b2b42040 100644 --- a/ledger/src/common/src/apdu.h +++ b/ledger/src/common/src/apdu.h @@ -29,6 +29,8 @@ #ifndef __APDU_H #define __APDU_H +#include "common_requirements.h" + // CLA for the entire protocol #define CLA 0x80 @@ -40,25 +42,29 @@ #define CLAPOS 0 // APDU buffer getters -#define APDU_CLA() (G_io_apdu_buffer[CLAPOS]) -#define APDU_CMD() (G_io_apdu_buffer[CMDPOS]) -#define APDU_OP() (G_io_apdu_buffer[OP]) -#define APDU_TXLEN() (G_io_apdu_buffer[TXLEN]) -#define APDU_AT(pos) (G_io_apdu_buffer[pos]) +#define APDU_CLA() (communication_get_msg_buffer()[CLAPOS]) +#define APDU_CMD() (communication_get_msg_buffer()[CMDPOS]) +#define APDU_OP() (communication_get_msg_buffer()[OP]) +#define APDU_TXLEN() (communication_get_msg_buffer()[TXLEN]) +#define APDU_AT(pos) (communication_get_msg_buffer()[pos]) // APDU buffer setters -#define SET_APDU_CLA() (G_io_apdu_buffer[CLAPOS] = CLA) -#define SET_APDU_CMD(cmd) (G_io_apdu_buffer[CMDPOS] = (cmd)) -#define SET_APDU_OP(op) (G_io_apdu_buffer[OP] = (op)) -#define SET_APDU_TXLEN(len) (G_io_apdu_buffer[TXLEN] = (len)) -#define SET_APDU_AT(pos, value) (G_io_apdu_buffer[pos] = (value)) +#define SET_APDU_CLA() (communication_get_msg_buffer()[CLAPOS] = CLA) +#define SET_APDU_CMD(cmd) (communication_get_msg_buffer()[CMDPOS] = (cmd)) +#define SET_APDU_OP(op) (communication_get_msg_buffer()[OP] = (op)) +#define SET_APDU_TXLEN(len) (communication_get_msg_buffer()[TXLEN] = (len)) +#define SET_APDU_AT(pos, value) (communication_get_msg_buffer()[pos] = (value)) // Get pointer to payload within APDU buffer. // No args, so it can be treated like an array pointer. -#define APDU_DATA_PTR (G_io_apdu_buffer + DATA) +#define APDU_DATA_PTR (communication_get_msg_buffer() + DATA) +// Total size of APDU +#define APDU_TOTAL_SIZE (communication_get_msg_buffer_size()) +// Size of APDU elements +#define APDU_ELEMENT_SIZE (sizeof(communication_get_msg_buffer()[0])) // Total size of APDU data part -#define APDU_TOTAL_DATA_SIZE (sizeof(G_io_apdu_buffer) - DATA) +#define APDU_TOTAL_DATA_SIZE (communication_get_msg_buffer_size() - DATA) // Total size of APDU data part for outputting // (need to leave space for result code) #define APDU_RESULT_CODE_SIZE 2 diff --git a/ledger/src/common/src/memutil.h b/ledger/src/common/src/memutil.h index e480d730..890ff97c 100644 --- a/ledger/src/common/src/memutil.h +++ b/ledger/src/common/src/memutil.h @@ -26,9 +26,8 @@ #define __MEMUTIL_H #include -#include -#include "os.h" +#include "common_requirements.h" #define MEMMOVE_ZERO_OFFSET 0 @@ -54,7 +53,7 @@ __attribute__((always_inline)) static inline int safe_memmove( return false; } else { - os_memmove( + platform_memmove( (unsigned char *)dst + dst_off, (unsigned char *)src + src_off, n); return true; } diff --git a/ledger/src/common/src/runtime.h b/ledger/src/common/src/runtime.h index 45f6eeb6..0746bfba 100644 --- a/ledger/src/common/src/runtime.h +++ b/ledger/src/common/src/runtime.h @@ -25,10 +25,27 @@ #ifndef __RUNTIME_H #define __RUNTIME_H -#ifdef HSM_SIMULATOR +#if defined(HSM_PLATFORM_LEDGER) + +// We can't include any HAL headers here because +// the Ledger UI does not know anything about it +#include "os.h" + +#define NON_VOLATILE const + +#elif defined(HSM_PLATFORM_X86) + +#include "hal/platform.h" +#include "hal/exceptions.h" + +#include "ui_deps.h" + +#define PIC(x) (x) + #define NON_VOLATILE + #else -#define NON_VOLATILE const +#error "HSM Platform undefined" #endif #endif // __RUNTIME_H \ No newline at end of file diff --git a/ledger/src/hal/include/hal/communication.h b/ledger/src/hal/include/hal/communication.h new file mode 100644 index 00000000..018391bd --- /dev/null +++ b/ledger/src/hal/include/hal/communication.h @@ -0,0 +1,75 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * 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. + */ + +#ifndef __HAL_COMMUNICATION_H +#define __HAL_COMMUNICATION_H + +#include +#include +#include + +/** + * @brief Initializes the communication module + * + * @param msg_buffer The buffer to use for communication + * @param msg_buffer_size The size of the message buffer in bytes + * + * @returns whether the initialisation succeeded + */ +bool communication_init(unsigned char* msg_buffer, size_t msg_buffer_size); + +/** + * @brief Get a pointer to the message buffer + * + * @returns a pointer to the message buffer + */ +unsigned char* communication_get_msg_buffer(); + +/** + * @brief Get the message buffer size + * + * @returns the message buffer size + */ +size_t communication_get_msg_buffer_size(); + +/** + * @brief Exchanges bytes with the host. This function blocks until the host sends a + * message. + * + * The message exchanges data with the host using the msg_buffer. If there are any bytes + * to transmit, they are transmitted first. After that the function blocks until a new + * message is received from the host. + * + * @param tx The number of bytes sent to the host + * + * @returns the number of bytes received from the host + */ +unsigned short communication_io_exchange(unsigned short tx); + +/** + * @brief Finalizes the communication module + */ +void communication_finalize(void); + +#endif // __HAL_COMMUNICATION_H diff --git a/ledger/src/hal/include/hal/endorsement.h b/ledger/src/hal/include/hal/endorsement.h new file mode 100644 index 00000000..6930fe30 --- /dev/null +++ b/ledger/src/hal/include/hal/endorsement.h @@ -0,0 +1,71 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * 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. + */ + +#ifndef __HAL_ENDORSEMENT_H +#define __HAL_ENDORSEMENT_H + +#include +#include +#include + +/** + * @brief Endorses the given message + * + * @param msg The message to attest + * @param msg_size The size of the message to attest + * @param signature_out Where the signature should be output + * @param signature_out_length [in/out] the length of the output buffer / + * length of the produced signature + * + * @returns whether endorsement succeeded + */ +bool endorsement_sign(uint8_t* msg, size_t msg_size, + uint8_t* signature_out, + uint8_t* signature_out_length); + +/** + * @brief Grabs the hash of the currently running code + * + * @param code_hash_out Where the code hash should be output + * @param code_hash_out_length [in/out] the length of the output buffer / + * length of the produced code hash + * + * @returns whether code hash gathering succeeded + */ +bool endorsement_get_code_hash(uint8_t* code_hash_out, + uint8_t* code_hash_out_length); + +/** + * @brief Grabs the endorsement public key + * + * @param public_key_out Where the public key should be output + * @param public_key_out_length [in/out] the length of the output buffer / + * length of the produced public key + * + * @returns whether public key gathering succeeded + */ +bool endorsement_get_public_key(uint8_t* public_key_out, + uint8_t* public_key_out_length); + +#endif // __HAL_ENDORSEMENT_H \ No newline at end of file diff --git a/ledger/src/hal/include/hal/exceptions.h b/ledger/src/hal/include/hal/exceptions.h new file mode 100644 index 00000000..5b5fe8eb --- /dev/null +++ b/ledger/src/hal/include/hal/exceptions.h @@ -0,0 +1,219 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * 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. + */ + +/***************************************************************************** + * Ledger Nano S - Secure firmware + * (c) 2016, 2017 Ledger + * + * 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. + *****************************************************************************/ + +#ifndef __HAL_EXCEPTIONS_H +#define __HAL_EXCEPTIONS_H + +#if defined(HSM_PLATFORM_LEDGER) + +#include "os.h" // This includes the exception engine + +#elif defined(HSM_PLATFORM_X86) + +/** + * Modified try...catch exception implementation (taken from nanos-secure-sdk) + * (https://github.com/LedgerHQ/nanos-secure-sdk/blob/nanos-1314/include/os.h) + */ + +#include +#include + +/* ----------------------------------------------------------------------- */ +/* - TYPES - */ +/* ----------------------------------------------------------------------- */ + +// error type definition +typedef unsigned short exception_t; + +// convenience declaration +typedef struct try_context_s try_context_t; + +// structure to reduce the code size generated for the close try (on stm7) +struct try_context_s { + // current exception context + jmp_buf jmp_buf; + + // previous exception contexts (if null, then will fail the same way as + // before, segv, therefore don't mind chaining) + try_context_t* previous; + + // current exception if any + exception_t ex; +}; + +extern try_context_t* G_try_last_open_context; + +/* ----------------------------------------------------------------------- */ +/* - EXCEPTIONS - */ +/* ----------------------------------------------------------------------- */ + +// workaround to make sure defines are replaced by their value for example +#define CPP_CONCAT(x, y) CPP_CONCAT_x(x, y) +#define CPP_CONCAT_x(x, y) x##y + +// ----------------------------------------------------------------------- +// - BEGIN TRY +// ----------------------------------------------------------------------- + +#define BEGIN_TRY_L(L) \ + { \ + try_context_t __try##L; + +// ----------------------------------------------------------------------- +// - TRY +// ----------------------------------------------------------------------- +#define TRY_L(L) \ + __try \ + ##L.previous = G_try_last_open_context; \ + __try \ + ##L.ex = setjmp(__try##L.jmp_buf); \ + G_try_last_open_context = &__try##L; \ + if (__try##L.ex == 0) { +// ----------------------------------------------------------------------- +// - EXCEPTION CATCH +// ----------------------------------------------------------------------- +#define CATCH_L(L, x) \ + goto CPP_CONCAT(__FINALLY, L); \ + } \ + else if (__try##L.ex == x) { \ + G_try_last_open_context = __try##L.previous; + +// ----------------------------------------------------------------------- +// - EXCEPTION CATCH OTHER +// ----------------------------------------------------------------------- +#define CATCH_OTHER_L(L, e) \ + goto CPP_CONCAT(__FINALLY, L); \ + } \ + else { \ + exception_t e; \ + e = __try##L.ex; \ + __try \ + ##L.ex = 0; \ + G_try_last_open_context = __try##L.previous; + +// ----------------------------------------------------------------------- +// - EXCEPTION CATCH ALL +// ----------------------------------------------------------------------- +#define CATCH_ALL_L(L) \ + goto CPP_CONCAT(__FINALLY, L); \ + } \ + else { \ + __try \ + ##L.ex = 0; \ + G_try_last_open_context = __try##L.previous; + +// ----------------------------------------------------------------------- +// - FINALLY +// ----------------------------------------------------------------------- +#define FINALLY_L(L) \ + goto CPP_CONCAT(__FINALLY, L); \ + } \ + CPP_CONCAT(__FINALLY, L) : G_try_last_open_context = __try##L.previous; + +// ----------------------------------------------------------------------- +// - END TRY +// ----------------------------------------------------------------------- +#define END_TRY_L(L) \ + if (__try##L.ex != 0) { \ + THROW_L(L, __try##L.ex); \ + } \ + } + +// ----------------------------------------------------------------------- +// - CLOSE TRY +// ----------------------------------------------------------------------- +#define CLOSE_TRY_L(L) \ + G_try_last_open_context = G_try_last_open_context->previous + +// ----------------------------------------------------------------------- +// - EXCEPTION THROW +// ----------------------------------------------------------------------- +/* +#ifndef BOLOS_RELEASE + +void os_longjmp(jmp_buf b, unsigned int exception); +#define THROW_L(L, x) \ + os_longjmp(G_try_last_open_context->jmp_buf, x) + +#else +*/ +#define THROW_L(L, x) longjmp(G_try_last_open_context->jmp_buf, x) +/* +#endif // BOLOS_RELEASE +*/ + +// Default macros when nesting is not used. +#define THROW_OS(x) THROW_L(EX, x) +#define BEGIN_TRY BEGIN_TRY_L(EX) +#define TRY TRY_L(EX) +#define CATCH(x) CATCH_L(EX, x) +#define CATCH_OTHER(e) CATCH_OTHER_L(EX, e) +#define CATCH_ALL CATCH_ALL_L(EX) +#define FINALLY FINALLY_L(EX) +#define CLOSE_TRY CLOSE_TRY_L(EX) +#define END_TRY END_TRY_L(EX) + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + +#include + +#define IGNORE_WHEN_FUZZING(e) \ + (e == MERKLE_PROOF_MISMATCH || e == CB_TXN_HASH_MISMATCH || \ + e == MM_HASH_MISMATCH || e == CHAIN_MISMATCH || \ + e == ANCESTOR_TIP_MISMATCH || \ + e == 0x6A94) // Validations in Merkle Proof. Not assigned a name. + +#define THROW(e) \ + { \ + if (!IGNORE_WHEN_FUZZING(e)) { \ + THROW_OS(e); \ + } \ + } + +#else + +#define THROW(e) THROW_OS(e) + +#endif + +#endif // HSM_PLATFORM_X86 + +#endif // __HAL_EXCEPTIONS_H diff --git a/ledger/src/hal/include/hal/hash.h b/ledger/src/hal/include/hal/hash.h new file mode 100644 index 00000000..c018720c --- /dev/null +++ b/ledger/src/hal/include/hal/hash.h @@ -0,0 +1,171 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * 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. + */ + +#ifndef __HAL_HASH_H +#define __HAL_HASH_H + +#include +#include +#include + +#define HASH_SIZE 32 + +// BEGINNING of platform-dependent code +#if defined(HSM_PLATFORM_LEDGER) + +#include "os.h" +#include "sha256.h" + +typedef cx_sha256_t hash_sha256_ctx_t; +typedef cx_sha3_t hash_keccak256_ctx_t; +typedef SHA256_CTX hash_sha256_ms_ctx_t; + +#elif defined(HSM_PLATFORM_X86) + +#include "sha256.h" +#include "keccak256.h" + +typedef SHA256_CTX hash_sha256_ctx_t; +typedef SHA3_CTX hash_keccak256_ctx_t; +typedef SHA256_CTX hash_sha256_ms_ctx_t; + +#else + #error "HSM Platform undefined" +#endif +// END of platform-dependent code + +// *** sha256 *** + +/** + * @brief Initialize a sha256 hash context + * + * @param[inout] ctx the context to initialize + * + * @returns whether the initialisation succeeded + */ +bool hash_sha256_init(hash_sha256_ctx_t* ctx); + +/** + * @brief Update a sha256 hash context with given data + * + * @param[inout] ctx the context to update + * @param[in] data pointer to message to hash + * @param[in] len length of message in bytes + * + * @returns whether the update succeeded + */ +bool hash_sha256_update(hash_sha256_ctx_t* ctx, const uint8_t *data, size_t len); + +/** + * @brief Compute the final sha256 hash for the given context + * + * @param[inout] ctx the context to finalise + * @param[out] out_hash The final hash obtained from the incremental hash + * + * @returns whether the finalisation succeeded + */ +bool hash_sha256_final(hash_sha256_ctx_t* ctx, uint8_t *out_hash); + +// *** sha256 with midstate support *** + +/** + * @brief Initialize a sha256 ms hash context + * + * @param[inout] ctx the context to initialize + * + * @returns whether the initialisation succeeded + */ +bool hash_sha256_ms_init(hash_sha256_ms_ctx_t* ctx); + +/** + * @brief Set sha256 ms hash context to the given mid state + * + * @details + * Mid state must be 52 bytes long: + * - midstate[0:8]: ignore + * - midstate[8:16]: counter, as a big-endian uint64_t + * - midstate[16:48]: current hash, as 8 big-endian uint32_t integers + * - midstate[48:52]: ignore + * + * @param[inout] ctx the context to set + * @param[in] midstate pointer to midstate buffer + * + * @returns whether the midstate succeeded + */ +bool hash_sha256_ms_midstate(hash_sha256_ms_ctx_t* ctx, uint8_t *midstate); + +/** + * @brief Update a sha256 ms hash context with given data + * + * @param[inout] ctx the context to update + * @param[in] data pointer to message to hash + * @param[in] len length of message in bytes + * + * @returns whether the update succeeded + */ +bool hash_sha256_ms_update(hash_sha256_ms_ctx_t* ctx, const uint8_t *data, size_t len); + +/** + * @brief Compute the final sha256 ms hash for the given context + * + * @param[inout] ctx the context to finalise + * @param[out] out_hash The final hash obtained from the incremental hash + * + * @returns whether the finalisation succeeded + */ +bool hash_sha256_ms_final(hash_sha256_ms_ctx_t* ctx, uint8_t *out_hash); + +// *** keccak256 *** + +/** + * @brief Initialize a keccak256 hash context + * + * @param[inout] ctx the context to initialize + * + * @returns whether the initialisation succeeded + */ +bool hash_keccak256_init(hash_keccak256_ctx_t* ctx); + +/** + * @brief Update a keccak256 hash context with given data + * + * @param[inout] ctx the context to update + * @param[in] data pointer to message to hash + * @param[in] len length of message in bytes + * + * @returns whether the update succeeded + */ +bool hash_keccak256_update(hash_keccak256_ctx_t* ctx, const uint8_t *data, size_t len); + +/** + * @brief Compute the final keccak256 hash for the given context + * + * @param[inout] ctx the context to finalise + * @param[out] out_hash The final hash obtained from the incremental hash + * + * @returns whether the finalisation succeeded + */ +bool hash_keccak256_final(hash_keccak256_ctx_t* ctx, uint8_t *out_hash); + +#endif // __HAL_HASH_H diff --git a/ledger/src/signer/src/dbg.h b/ledger/src/hal/include/hal/log.h similarity index 82% rename from ledger/src/signer/src/dbg.h rename to ledger/src/hal/include/hal/log.h index 4e73f45d..96ac7ef3 100644 --- a/ledger/src/signer/src/dbg.h +++ b/ledger/src/hal/include/hal/log.h @@ -22,10 +22,10 @@ * IN THE SOFTWARE. */ -#ifndef __DBG_H -#define __DBG_H +#ifndef __LOG_H +#define __LOG_H -#ifdef HSM_SIMULATOR +#if defined(HSM_PLATFORM_X86) #include #include @@ -33,7 +33,11 @@ #include "bigdigits.h" #include "srlp.h" -#define LOG(...) printf(__VA_ARGS__); +/** Set a prefix for all logs */ +void LOG_SET_PREFIX(char* prefix); + +/** Works just like printf */ +void LOG(const char *format, ...); /** Print buffer in hex format with prefix */ void LOG_HEX(const char *prefix, void *buffer, size_t size); @@ -44,20 +48,14 @@ void LOG_BIGD_HEX(const char *prefix, size_t len, const char *suffix); -/** Print N copies of a given char */ -void LOG_N_CHARS(const char c, unsigned int times); - -/** Print the given SRLP context (see srlp.h) */ -void LOG_SRLP_CTX(uint8_t v, rlp_ctx_t ctx[], uint8_t ptr); - -#else +#elif defined(HSM_PLATFORM_LEDGER) #define LOG(...) #define LOG_HEX(...) #define LOG_BIGD_HEX(...) -#define LOG_N_CHARS(...) -#define LOG_SRLP_CTX(...) +#else + #error "HSM Platform undefined" #endif -#endif // __DBG_H +#endif // __LOG_H diff --git a/ledger/src/hal/include/hal/nvmem.h b/ledger/src/hal/include/hal/nvmem.h new file mode 100644 index 00000000..a52a2481 --- /dev/null +++ b/ledger/src/hal/include/hal/nvmem.h @@ -0,0 +1,43 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * 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. + */ + +#ifndef __HAL_NVMEM_H +#define __HAL_NVMEM_H + +#include +#include +#include + +/** + * @brief Write to non volatile memory + * + * @param dst The destination address in non volatile memory + * @param src The source address to write from + * @param length The amount of bytes to write + * + * @returns whether the write succeeded + */ +bool nvmem_write(void *dst, void *src, unsigned int length); + +#endif // __HAL_NVMEM_H \ No newline at end of file diff --git a/ledger/src/hal/include/hal/platform.h b/ledger/src/hal/include/hal/platform.h new file mode 100644 index 00000000..69aece87 --- /dev/null +++ b/ledger/src/hal/include/hal/platform.h @@ -0,0 +1,45 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * 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. + */ + +#ifndef __HAL_PLATFORM_H +#define __HAL_PLATFORM_H + +#include +#include + +/** + * @brief Perform the platform-specific version of memmove + * + * @param dst destination buffer + * @param src source buffer + * @param length number of bytes to copy +*/ +void platform_memmove(void *dst, const void *src, unsigned int length); + +/** + * @brief Request exiting/closing to the underlying platform +*/ +void platform_request_exit(); + +#endif // __HAL_PLATFORM_H diff --git a/ledger/src/hal/include/hal/seed.h b/ledger/src/hal/include/hal/seed.h new file mode 100644 index 00000000..a205fc42 --- /dev/null +++ b/ledger/src/hal/include/hal/seed.h @@ -0,0 +1,73 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * 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. + */ + +#ifndef __HAL_SEED_H +#define __HAL_SEED_H + +#include +#include + +#define SEED_PUBLIC_KEY_SIZE 65 + +/** + * @brief Returns whether there's a generated seed + * + * @returns whether there's a generated seed + */ +bool seed_available(); + +/** + * @brief Derives the main node using the given derivation path and + * computes and outputs its public key in uncompressed format + * + * @param path the BIP32 path to use for derivation + * @param path_length the BIP32 path length in parts (not bytes) + * @param pubkey_out where the public key should be output + * @param pubkey_out_length [in/out] the length of the output buffer / + * length of the produced public key + * + * @returns whether the derivation succeeded + */ +bool seed_derive_pubkey(uint32_t* path, uint8_t path_length, + uint8_t* pubkey_out, uint8_t* pubkey_out_length); + +/** + * @brief Signs the given hash with the private key obtained + * by deriving the main node using the given derivation path, and + * outputs the signature in DER format. + * + * @param path the BIP32 path to use for derivation + * @param hash32 the 32 byte hash to sign + * @param sig_out where the public key should be output + * @param sig_out_length [in/out] the length of the output buffer / + * length of the produced signature + * + * @returns whether the signing succeeded + */ +bool seed_sign(uint32_t* path, uint8_t path_length, + uint8_t* hash32, + uint8_t* sig_out, uint8_t* sig_out_length); + + +#endif // __HAL_SEED_H diff --git a/ledger/src/signer/src/sha256.c b/ledger/src/hal/src/common/sha256.c similarity index 100% rename from ledger/src/signer/src/sha256.c rename to ledger/src/hal/src/common/sha256.c diff --git a/ledger/src/signer/src/sha256.h b/ledger/src/hal/src/common/sha256.h similarity index 100% rename from ledger/src/signer/src/sha256.h rename to ledger/src/hal/src/common/sha256.h diff --git a/ledger/src/signer/src/hsm-ledger.c b/ledger/src/hal/src/ledger/communication.c similarity index 54% rename from ledger/src/signer/src/hsm-ledger.c rename to ledger/src/hal/src/ledger/communication.c index 376052e4..2f12023a 100644 --- a/ledger/src/signer/src/hsm-ledger.c +++ b/ledger/src/hal/src/ledger/communication.c @@ -23,37 +23,27 @@ */ #include "os.h" -#include "hsm.h" -#include "err.h" +#include "hal/communication.h" -void hsm_ledger_main_loop() { - volatile unsigned int rx = 0; - volatile unsigned int tx = 0; +static unsigned char* msg_buffer; +static size_t msg_buffer_size; - // DESIGN NOTE: the bootloader ignores the way APDU are fetched. The only - // goal is to retrieve APDU. - // When APDU are to be fetched from multiple IOs, like NFC+USB+BLE, make - // sure the io_event is called with a - // switch event, before the apdu is replied to the bootloader. This avoid - // APDU injection faults. - while (!hsm_exit_requested()) { - BEGIN_TRY { - TRY { - // ensure no race in catch_other if io_exchange throws - // an error - rx = tx; - tx = 0; - rx = io_exchange(CHANNEL_APDU, rx); +// HAL implementation +bool communication_init(unsigned char* _msg_buffer, size_t _msg_buffer_size) { + // Setup the exchange buffer + msg_buffer = _msg_buffer; + msg_buffer_size = _msg_buffer_size; + return true; +} + +unsigned char* communication_get_msg_buffer() { + return msg_buffer; +} + +size_t communication_get_msg_buffer_size() { + return msg_buffer_size; +} - tx = hsm_process_apdu(rx); - THROW(0x9000); - } - CATCH_OTHER(e) { - tx = hsm_process_exception(e, tx); - } - FINALLY { - } - } - END_TRY; - } +unsigned short communication_io_exchange(unsigned short tx) { + return io_exchange(CHANNEL_APDU, tx); } diff --git a/ledger/src/hal/src/ledger/endorsement.c b/ledger/src/hal/src/ledger/endorsement.c new file mode 100644 index 00000000..d73a7f7b --- /dev/null +++ b/ledger/src/hal/src/ledger/endorsement.c @@ -0,0 +1,69 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * 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 "os.h" +#include "hal/endorsement.h" + +#define MAX_SIGNATURE_LENGTH 72 +#define MAX_CODE_HASH_LENGTH 32 +#define MAX_PUBLIC_KEY_LENGTH 65 + +// Index of the ledger endorsement scheme +#define ENDORSEMENT_SCHEME_INDEX 2 + +bool endorsement_sign(uint8_t* msg, size_t msg_size, + uint8_t* signature_out, + uint8_t* signature_out_length) { + + if (*signature_out_length < MAX_SIGNATURE_LENGTH) { + return false; + } + + *signature_out_length = os_endorsement_key2_derive_sign_data( + msg, msg_size, signature_out); + + return true; +} + +bool endorsement_get_code_hash(uint8_t* code_hash_out, + uint8_t* code_hash_out_length) { + + if (*code_hash_out_length < MAX_CODE_HASH_LENGTH) { + return false; + } + + *code_hash_out_length = os_endorsement_get_code_hash(code_hash_out); + return true; +} + +bool endorsement_get_public_key(uint8_t* public_key_out, + uint8_t* public_key_out_length) { + if (*public_key_out_length < MAX_PUBLIC_KEY_LENGTH) { + return false; + } + + *public_key_out_length = os_endorsement_get_public_key( + ENDORSEMENT_SCHEME_INDEX, public_key_out); + return true; +} \ No newline at end of file diff --git a/ledger/src/hal/src/ledger/hash.c b/ledger/src/hal/src/ledger/hash.c new file mode 100644 index 00000000..333c6b6c --- /dev/null +++ b/ledger/src/hal/src/ledger/hash.c @@ -0,0 +1,80 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * 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 "hal/hash.h" +#include "sha256.h" +#include "os.h" + +// *** sha256 *** +bool hash_sha256_init(hash_sha256_ctx_t* ctx) { + cx_sha256_init(ctx); + return true; +} + +bool hash_sha256_update(hash_sha256_ctx_t* ctx, const uint8_t *data, size_t len) { + cx_hash((cx_hash_t*)(ctx), 0, (unsigned char*)data, len, NULL); + return true; +} + +bool hash_sha256_final(hash_sha256_ctx_t* ctx, uint8_t *out_hash) { + cx_hash((cx_hash_t*)(ctx), CX_LAST, NULL, 0, out_hash); + return true; +} + +// *** sha256 with midstate support *** +bool hash_sha256_ms_init(hash_sha256_ms_ctx_t* ctx) { + sha256_init(ctx); + return true; +} + +bool hash_sha256_ms_midstate(hash_sha256_ms_ctx_t* ctx, uint8_t *midstate) { + sha256_midstate(ctx, midstate); + return true; +} + +bool hash_sha256_ms_update(hash_sha256_ms_ctx_t* ctx, const uint8_t *data, size_t len) { + sha256_update(ctx, data, len); + return true; +} + +bool hash_sha256_ms_final(hash_sha256_ms_ctx_t* ctx, uint8_t *out_hash) { + sha256_final(ctx, out_hash); + return true; +} + +// *** keccak256 *** +bool hash_keccak256_init(hash_keccak256_ctx_t* ctx) { + cx_keccak_init(ctx, 256); + return true; +} + +bool hash_keccak256_update(hash_keccak256_ctx_t* ctx, const uint8_t *data, size_t len) { + cx_hash((cx_hash_t*)(ctx), 0, (unsigned char*)data, len, NULL); + return true; +} + +bool hash_keccak256_final(hash_keccak256_ctx_t* ctx, uint8_t *out_hash) { + cx_hash((cx_hash_t*)(ctx), CX_LAST, NULL, 0, out_hash); + return true; +} \ No newline at end of file diff --git a/ledger/src/signer/src/hsm-ledger.h b/ledger/src/hal/src/ledger/nvmem.c similarity index 88% rename from ledger/src/signer/src/hsm-ledger.h rename to ledger/src/hal/src/ledger/nvmem.c index 2079a4a7..f0c68904 100644 --- a/ledger/src/signer/src/hsm-ledger.h +++ b/ledger/src/hal/src/ledger/nvmem.c @@ -22,9 +22,10 @@ * IN THE SOFTWARE. */ -#ifndef __HSM_LEDGER_H -#define __HSM_LEDGER_H +#include "os.h" +#include "hal/nvmem.h" -void hsm_ledger_main_loop(); - -#endif // __HSM_LEDGER_H +bool nvmem_write(void *dst, void *src, unsigned int length) { + nvm_write(dst, src, length); + return true; +} diff --git a/ledger/src/hal/src/ledger/platform.c b/ledger/src/hal/src/ledger/platform.c new file mode 100644 index 00000000..ecea2a79 --- /dev/null +++ b/ledger/src/hal/src/ledger/platform.c @@ -0,0 +1,41 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * 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 "hal/platform.h" +#include "hal/exceptions.h" + +void platform_memmove(void *dst, const void *src, unsigned int length) { + os_memmove(dst, src, length); +} + +void platform_request_exit() { + BEGIN_TRY_L(exit) { + TRY_L(exit) { + os_sched_exit(-1); + } + FINALLY_L(exit) { + } + } + END_TRY_L(exit); +} \ No newline at end of file diff --git a/ledger/src/signer/src/sign.c b/ledger/src/hal/src/ledger/seed.c similarity index 59% rename from ledger/src/signer/src/sign.c rename to ledger/src/hal/src/ledger/seed.c index ea7cc82e..155dfccb 100644 --- a/ledger/src/signer/src/sign.c +++ b/ledger/src/hal/src/ledger/seed.c @@ -26,64 +26,48 @@ #include "os.h" #include "cx.h" +#include "hal/seed.h" -#include "sign.h" -#include "defs.h" -#include "memutil.h" +#define PRIVATE_KEY_LENGTH 32 +#define HASH_SIZE 32 +#define MAX_SIGNATURE_LENGTH 72 -/* - * Derive the public key for a given path. - * Store the public key into the given destination buffer. - * - * @arg[in] path derivation path - * @arg[in] path_length length of the derivation path - * @arg[in] dest destination buffer - * @arg[in] dest destination buffer size - * @ret size of the public key derived, - * or DO_PUBKEY_ERROR in case of error - */ -int do_pubkey(unsigned int* path, - unsigned char path_length, - unsigned char* dest, - size_t dest_size) { +bool seed_available() { + return os_perso_isonboarded() == 1; +} + +bool seed_derive_pubkey(uint32_t* path, uint8_t path_length, + uint8_t* pubkey_out, uint8_t* pubkey_out_length) { volatile unsigned char private_key_data[PRIVATE_KEY_LENGTH]; volatile cx_ecfp_private_key_t private_key; volatile cx_ecfp_public_key_t public_key; - volatile int pubkey_size; - BEGIN_TRY { TRY { // Derive and init private key os_perso_derive_node_bip32(CX_CURVE_256K1, path, path_length, - (unsigned char*)private_key_data, + (unsigned char*) private_key_data, NULL); cx_ecdsa_init_private_key(CX_CURVE_256K1, - (unsigned char*)private_key_data, + (unsigned char*) private_key_data, PRIVATE_KEY_LENGTH, - (cx_ecfp_private_key_t*)&private_key); + (cx_ecfp_private_key_t*) &private_key); // Cleanup private key data explicit_bzero((void*)private_key_data, sizeof(private_key_data)); // Derive public key cx_ecfp_generate_pair(CX_CURVE_256K1, - (cx_ecfp_public_key_t*)&public_key, - (cx_ecfp_private_key_t*)&private_key, + (cx_ecfp_public_key_t*) &public_key, + (cx_ecfp_private_key_t*) &private_key, 1); // Cleanup private key explicit_bzero((void*)&private_key, sizeof(private_key)); + if (*pubkey_out_length < public_key.W_len) THROW(1); // Output the public key - pubkey_size = public_key.W_len; - SAFE_MEMMOVE(dest, - dest_size, - MEMMOVE_ZERO_OFFSET, - (void*)public_key.W, - public_key.W_len, - MEMMOVE_ZERO_OFFSET, - public_key.W_len, - { pubkey_size = DO_PUBKEY_ERROR; }) + *pubkey_out_length = public_key.W_len; + os_memmove((void*) pubkey_out, (const void*) public_key.W, public_key.W_len); // Cleanup public key explicit_bzero((void*)&public_key, sizeof(public_key)); } @@ -92,45 +76,26 @@ int do_pubkey(unsigned int* path, explicit_bzero((void*)private_key_data, sizeof(private_key_data)); explicit_bzero((void*)&private_key, sizeof(private_key)); explicit_bzero((void*)&public_key, sizeof(public_key)); - // Signal error deriving public key - pubkey_size = DO_PUBKEY_ERROR; + return false; } FINALLY { } } END_TRY; - // Return public key size - return pubkey_size; + + return true; } -/* - * Sign a message with a given path. - * Store the signature into the given destination buffer. - * - * @arg[in] path derivation path - * @arg[in] path_length length of the derivation path - * @arg[in] message message buffer - * @arg[in] message_size message size - * @arg[in] dest destination buffer - * @arg[in] dest destination buffer size - * @ret size of the signature produced, - * or DO_SIGN_ERROR in case of error - */ -int do_sign(unsigned int* path, - unsigned char path_length, - unsigned char* message, - size_t message_size, - unsigned char* dest, - size_t dest_size) { +bool seed_sign(uint32_t* path, uint8_t path_length, + uint8_t* hash32, + uint8_t* sig_out, uint8_t* sig_out_length) { volatile unsigned char private_key_data[PRIVATE_KEY_LENGTH]; volatile cx_ecfp_private_key_t private_key; - volatile int sig_size; - // Check the destination buffer won't be overflowed by the signature - if (dest_size < MAX_SIGNATURE_LENGTH) { - return DO_SIGN_ERROR; + if (*sig_out_length < MAX_SIGNATURE_LENGTH) { + return false; } BEGIN_TRY { @@ -147,12 +112,12 @@ int do_sign(unsigned int* path, (cx_ecfp_private_key_t*)&private_key); // Cleanup private key data explicit_bzero((void*)private_key_data, sizeof(private_key_data)); - sig_size = cx_ecdsa_sign((void*)&private_key, - CX_RND_RFC6979 | CX_LAST, - CX_SHA256, - message, - message_size, - dest); + *sig_out_length = (uint8_t) cx_ecdsa_sign((void*)&private_key, + CX_RND_RFC6979 | CX_LAST, + CX_SHA256, + hash32, + HASH_SIZE, + sig_out); // Cleanup private key explicit_bzero((void*)&private_key, sizeof(private_key)); } @@ -160,13 +125,12 @@ int do_sign(unsigned int* path, // Cleanup key data and fail explicit_bzero((void*)private_key_data, sizeof(private_key_data)); explicit_bzero((void*)&private_key, sizeof(private_key)); - // Signal error signing - sig_size = DO_SIGN_ERROR; + return false; } FINALLY { } } END_TRY; - // Return signature size - return sig_size; -} \ No newline at end of file + + return true; +} diff --git a/ledger/src/hal/src/ledger/sha256.c b/ledger/src/hal/src/ledger/sha256.c new file mode 120000 index 00000000..a21d1a59 --- /dev/null +++ b/ledger/src/hal/src/ledger/sha256.c @@ -0,0 +1 @@ +../common/sha256.c \ No newline at end of file diff --git a/ledger/src/hal/src/ledger/sha256.h b/ledger/src/hal/src/ledger/sha256.h new file mode 120000 index 00000000..65492ab2 --- /dev/null +++ b/ledger/src/hal/src/ledger/sha256.h @@ -0,0 +1 @@ +../common/sha256.h \ No newline at end of file diff --git a/ledger/src/signer/Makefile b/ledger/src/signer/Makefile index aff44a18..4fcbab34 100755 --- a/ledger/src/signer/Makefile +++ b/ledger/src/signer/Makefile @@ -44,13 +44,13 @@ include $(BOLOS_SDK)/Makefile.defines # Main app configuration APPNAME = "RSK Sign" -APPVERSION = 4 +APPVERSION = 5 # No flags APPFLAGS = 0x00 PROG = "app" # Build configuration -APP_SOURCE_PATH += src ../common/src +APP_SOURCE_PATH += src ../common/src ../hal/src/ledger SDK_SOURCE_PATH += lib_stusb lib_stusb_impl DEFINES += APPVERSION=\"$(APPVERSION)\" @@ -65,6 +65,7 @@ DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=3 IO_HID_EP_LENGTH=64 CC := $(CLANGPATH)clang CFLAGS += -O0 -I$(GCC_INCLUDE) CFLAGS += -Werror +CFLAGS += -DHSM_PLATFORM_LEDGER # Convert min required difficulty to what the compiler expects ifneq ($(TARGET_DIFFICULTY),) @@ -128,3 +129,7 @@ delete: # Import generic rules from the SDK include $(BOLOS_SDK)/Makefile.rules + +# This is to prevent individual subdirectory inclusion by using the +# SDK provided APP_SOURCE_PATH variable +INCLUDES_PATH += ../hal/include diff --git a/ledger/src/signer/src/attestation.c b/ledger/src/signer/src/attestation.c index b91dbf41..9c9130c4 100644 --- a/ledger/src/signer/src/attestation.c +++ b/ledger/src/signer/src/attestation.c @@ -24,7 +24,11 @@ #include -#include "os.h" +#include "hal/seed.h" +#include "hal/endorsement.h" +#include "hal/platform.h" +#include "hal/exceptions.h" + #include "attestation.h" #include "apdu.h" #include "defs.h" @@ -43,58 +47,40 @@ const char att_msg_prefix[ATT_MSG_PREFIX_LENGTH] = ATT_MSG_PREFIX; static void hash_public_key(const char* path, size_t path_size, att_t* att_ctx) { - BEGIN_TRY { - TRY { - // Derive public key - - // Skip first byte of path when copying (path size byte) - SAFE_MEMMOVE(att_ctx->path, - sizeof(att_ctx->path), - MEMMOVE_ZERO_OFFSET, - (unsigned int*)path, - path_size, - 1, - sizeof(att_ctx->path), - THROW(ERR_ATT_INTERNAL)); - - // Derive and init private key - os_perso_derive_node_bip32(CX_CURVE_256K1, - att_ctx->path, - DERIVATION_PATH_PARTS, - att_ctx->priv_key_data, - NULL); - cx_ecdsa_init_private_key(CX_CURVE_256K1, - att_ctx->priv_key_data, - PRIVATE_KEY_LENGTH, - &att_ctx->priv_key); - // Cleanup private key data - explicit_bzero(att_ctx->priv_key_data, - sizeof(att_ctx->priv_key_data)); - // Derive public key - cx_ecfp_generate_pair( - CX_CURVE_256K1, &att_ctx->pub_key, &att_ctx->priv_key, 1); - // Cleanup private key - explicit_bzero(&att_ctx->priv_key, sizeof(att_ctx->priv_key)); - - // Hash - SHA256_UPDATE( - &att_ctx->hash_ctx, att_ctx->pub_key.W, att_ctx->pub_key.W_len); - - // Cleanup public key - explicit_bzero(&att_ctx->pub_key, sizeof(att_ctx->pub_key)); - } - CATCH_OTHER(e) { - // Cleanup key data and fail - explicit_bzero(att_ctx->priv_key_data, - sizeof(att_ctx->priv_key_data)); - explicit_bzero(&att_ctx->priv_key, sizeof(att_ctx->priv_key)); - explicit_bzero(&att_ctx->pub_key, sizeof(att_ctx->pub_key)); - THROW(ERR_ATT_INTERNAL); - } - FINALLY { - } + // Derive public key + + // Skip first byte of path when copying (path size byte) + SAFE_MEMMOVE(att_ctx->path, + sizeof(att_ctx->path), + MEMMOVE_ZERO_OFFSET, + (unsigned int*)path, + path_size, + 1, + sizeof(att_ctx->path), + { goto hash_public_key_error; }); + + att_ctx->pubkey_length = sizeof(att_ctx->pubkey); + if (!seed_derive_pubkey(att_ctx->path, + sizeof(att_ctx->path) / sizeof(att_ctx->path[0]), + att_ctx->pubkey, + &att_ctx->pubkey_length)) { + goto hash_public_key_error; } - END_TRY; + + // Hash + SHA256_UPDATE(&att_ctx->hash_ctx, att_ctx->pubkey, att_ctx->pubkey_length); + + // Cleanup public key + explicit_bzero(&att_ctx->pubkey, sizeof(att_ctx->pubkey)); + att_ctx->pubkey_length = 0; + + return; + +hash_public_key_error: + // Cleanup public key + explicit_bzero(&att_ctx->pubkey, sizeof(att_ctx->pubkey)); + att_ctx->pubkey_length = 0; + THROW(ERR_ATT_INTERNAL); } /* @@ -139,15 +125,19 @@ static unsigned int generate_message_to_sign(att_t* att_ctx) { */ unsigned int get_attestation(volatile unsigned int rx, att_t* att_ctx) { unsigned int message_size; + uint8_t code_hash_size; switch (APDU_OP()) { case OP_ATT_GET: - // Generate the message to sign + // Generate the message to attest message_size = generate_message_to_sign(att_ctx); - // Sign message - int endorsement_size = os_endorsement_key2_derive_sign_data( - att_ctx->msg, message_size, APDU_DATA_PTR); + // Attest message + uint8_t endorsement_size = APDU_TOTAL_DATA_SIZE_OUT; + if (!endorsement_sign( + att_ctx->msg, message_size, APDU_DATA_PTR, &endorsement_size)) { + THROW(ERR_ATT_INTERNAL); + } return TX_FOR_DATA_SIZE(endorsement_size); case OP_ATT_GET_MESSAGE: @@ -165,9 +155,14 @@ unsigned int get_attestation(volatile unsigned int rx, att_t* att_ctx) { return TX_FOR_DATA_SIZE(message_size); case OP_ATT_APP_HASH: - return TX_FOR_DATA_SIZE(os_endorsement_get_code_hash(APDU_DATA_PTR)); + code_hash_size = APDU_TOTAL_DATA_SIZE_OUT; + if (!endorsement_get_code_hash(APDU_DATA_PTR, &code_hash_size)) { + THROW(ERR_ATT_INTERNAL); + } + return TX_FOR_DATA_SIZE(code_hash_size); default: THROW(ERR_ATT_PROT_INVALID); break; } + return 0; } diff --git a/ledger/src/signer/src/auth.c b/ledger/src/signer/src/auth.c index c821bc97..54508bab 100644 --- a/ledger/src/signer/src/auth.c +++ b/ledger/src/signer/src/auth.c @@ -24,14 +24,15 @@ #include -#include "os.h" +#include "hal/platform.h" +#include "hal/exceptions.h" + #include "auth.h" #include "err.h" -#include "sign.h" #include "mem.h" #include "compiletime.h" -#include "dbg.h" +#include "hal/log.h" /* * Transition to the given state, performing corresponding @@ -59,6 +60,7 @@ void auth_transition_to(uint8_t state) { */ unsigned int auth_sign(volatile unsigned int rx) { unsigned int tx; + uint8_t sig_size; // Sanity check: tx hash size and // last auth signed tx hash size @@ -95,12 +97,15 @@ unsigned int auth_sign(volatile unsigned int rx) { if (auth.state != STATE_AUTH_SIGN) THROW(ERR_AUTH_INVALID_STATE); // Invalid state - tx = do_sign(auth.path, - DERIVATION_PATH_PARTS, - auth.sig_hash, - sizeof(auth.sig_hash), - APDU_DATA_PTR, - APDU_TOTAL_DATA_SIZE_OUT); + sig_size = APDU_TOTAL_DATA_SIZE_OUT; + if (!seed_sign(auth.path, + sizeof(auth.path) / sizeof(auth.path[0]), + auth.sig_hash, + APDU_DATA_PTR, + &sig_size)) { + THROW(ERR_INTERNAL); + } + tx = sig_size; // Save the BTC tx hash to NVM if this signature required authorization if (auth.auth_required) { @@ -122,11 +127,6 @@ unsigned int auth_sign(volatile unsigned int rx) { } } - // Error signing? - if (tx == DO_SIGN_ERROR) { - THROW(ERR_INTERNAL); - } - SET_APDU_OP(P1_SUCCESS); auth_transition_to(STATE_AUTH_START); return TX_FOR_DATA_SIZE(tx); diff --git a/ledger/src/signer/src/auth.h b/ledger/src/signer/src/auth.h index 644b465c..8a9b4ece 100644 --- a/ledger/src/signer/src/auth.h +++ b/ledger/src/signer/src/auth.h @@ -28,6 +28,8 @@ #include #include +#include "hal/seed.h" + #include "auth_path.h" #include "auth_tx.h" #include "auth_receipt.h" diff --git a/ledger/src/signer/src/auth_path.c b/ledger/src/signer/src/auth_path.c index a3a00f40..a0640a19 100644 --- a/ledger/src/signer/src/auth_path.c +++ b/ledger/src/signer/src/auth_path.c @@ -22,7 +22,8 @@ * IN THE SOFTWARE. */ -#include "os.h" +#include "hal/platform.h" +#include "hal/exceptions.h" #include "auth.h" #include "pathAuth.h" @@ -106,4 +107,5 @@ unsigned int auth_sign_handle_path(volatile unsigned int rx) { // If no path match, then bail out // signalling invalid path THROW(ERR_AUTH_INVALID_PATH); + return 0; } diff --git a/ledger/src/signer/src/auth_receipt.c b/ledger/src/signer/src/auth_receipt.c index 5baaa59b..48c0dc4c 100644 --- a/ledger/src/signer/src/auth_receipt.c +++ b/ledger/src/signer/src/auth_receipt.c @@ -24,7 +24,8 @@ #include -#include "os.h" +#include "hal/platform.h" +#include "hal/exceptions.h" #include "auth.h" #include "auth_constants.h" @@ -34,7 +35,7 @@ #include "flags.h" #include "util.h" -#include "dbg.h" +#include "hal/log.h" // ----------------------------------------------------------------------- // RLP parser callbacks @@ -238,7 +239,7 @@ unsigned int auth_sign_handle_receipt(volatile unsigned int rx) { if (!HAS_FLAG(auth.receipt.flags, IS_INIT)) { rlp_start(&callbacks); - keccak_init(&auth.receipt.hash_ctx); + hash_keccak256_init(&auth.receipt.hash_ctx); SET_FLAG(auth.receipt.flags, IS_INIT); } @@ -249,12 +250,13 @@ unsigned int auth_sign_handle_receipt(volatile unsigned int rx) { } auth.receipt.remaining_bytes -= APDU_DATA_SIZE(rx); - keccak_update(&auth.receipt.hash_ctx, APDU_DATA_PTR, APDU_DATA_SIZE(rx)); + hash_keccak256_update( + &auth.receipt.hash_ctx, APDU_DATA_PTR, APDU_DATA_SIZE(rx)); if (auth.receipt.remaining_bytes == 0) { if (HAS_FLAG(auth.receipt.flags, IS_MATCH)) { // Finalize the hash calculation - keccak_final(&auth.receipt.hash_ctx, auth.receipt_hash); + hash_keccak256_final(&auth.receipt.hash_ctx, auth.receipt_hash); // Log hash for debugging purposes LOG_HEX( diff --git a/ledger/src/signer/src/auth_receipt.h b/ledger/src/signer/src/auth_receipt.h index 8639f892..b978bac5 100644 --- a/ledger/src/signer/src/auth_receipt.h +++ b/ledger/src/signer/src/auth_receipt.h @@ -27,8 +27,9 @@ #include +#include "hal/hash.h" + #include "srlp.h" -#include "keccak256.h" #define RECEIPT_MAX_DEPTH (4) #define RECEIPT_MAX_BUFFER_SIZE (32) @@ -43,7 +44,7 @@ typedef struct { uint8_t aux[RECEIPT_MAX_BUFFER_SIZE]; uint8_t aux_offset; - SHA3_CTX hash_ctx; + hash_keccak256_ctx_t hash_ctx; } receipt_auth_ctx_t; /* diff --git a/ledger/src/signer/src/auth_trie.c b/ledger/src/signer/src/auth_trie.c index f188b4e0..0d247205 100644 --- a/ledger/src/signer/src/auth_trie.c +++ b/ledger/src/signer/src/auth_trie.c @@ -24,14 +24,16 @@ #include -#include "os.h" +#include "hal/hash.h" +#include "hal/platform.h" +#include "hal/exceptions.h" #include "auth.h" #include "mem.h" #include "memutil.h" #include "bc_state.h" -#include "dbg.h" +#include "hal/log.h" #define REQUEST_MORE_IF_NEED() \ { \ @@ -57,7 +59,7 @@ static void trie_cb(const trie_cb_event_t event) { // Update node hash - keccak_update( + hash_keccak256_update( &auth.trie.hash_ctx, auth.trie.ctx.raw, auth.trie.ctx.raw_size); switch (event) { @@ -141,12 +143,12 @@ static void trie_cb(const trie_cb_event_t event) { case TRIE_EV_LEFT_NODE_EMBEDDED_START: case TRIE_EV_RIGHT_NODE_EMBEDDED_START: FAIL_IF_LEAF(); - keccak_init(&auth.trie.aux_hash_ctx); + hash_keccak256_init(&auth.trie.aux_hash_ctx); break; case TRIE_EV_LEFT_NODE_EMBEDDED_DATA: case TRIE_EV_RIGHT_NODE_EMBEDDED_DATA: FAIL_IF_LEAF(); - keccak_update( + hash_keccak256_update( &auth.trie.aux_hash_ctx, auth.trie.ctx.raw, auth.trie.ctx.raw_size); break; case TRIE_EV_LEFT_NODE_END: @@ -156,7 +158,7 @@ static void trie_cb(const trie_cb_event_t event) { FAIL_IF_LEAF(); if (event == TRIE_EV_LEFT_NODE_EMBEDDED_END || event == TRIE_EV_RIGHT_NODE_EMBEDDED_END) - keccak_final(&auth.trie.aux_hash_ctx, auth.trie.child_hash); + hash_keccak256_final(&auth.trie.aux_hash_ctx, auth.trie.child_hash); if (!memcmp(auth.trie.node_hash, auth.trie.child_hash, sizeof(auth.trie.node_hash))) @@ -197,7 +199,7 @@ unsigned int auth_sign_handle_merkleproof(volatile unsigned int rx) { THROW(ERR_AUTH_INVALID_DATA_SIZE); } trie_init(&auth.trie.ctx, &trie_cb, APDU_DATA_PTR[apdu_offset++]); - keccak_init(&auth.trie.hash_ctx); + hash_keccak256_init(&auth.trie.hash_ctx); auth.trie.state = AUTH_TRIE_STATE_NODE; auth.trie.num_linked = 0; @@ -213,7 +215,7 @@ unsigned int auth_sign_handle_merkleproof(volatile unsigned int rx) { // Reusing an existing error code due to legacy protocol THROW(ERR_AUTH_RECEIPT_ROOT_MISMATCH); } else if (trie_result() == TRIE_ST_DONE) { - keccak_final(&auth.trie.hash_ctx, auth.trie.node_hash); + hash_keccak256_final(&auth.trie.hash_ctx, auth.trie.node_hash); LOG("MP@%u ", auth.trie.current_node); LOG_HEX( "hash: ", auth.trie.node_hash, sizeof(auth.trie.node_hash)); diff --git a/ledger/src/signer/src/auth_trie.h b/ledger/src/signer/src/auth_trie.h index 9c45d4ab..963d0b60 100644 --- a/ledger/src/signer/src/auth_trie.h +++ b/ledger/src/signer/src/auth_trie.h @@ -27,8 +27,9 @@ #include +#include "hal/hash.h" + #include "trie.h" -#include "keccak256.h" #include "defs.h" #define AUTH_TRIE_STATE_NODE_LENGTH (0) @@ -42,8 +43,8 @@ typedef struct { uint8_t state; trie_ctx_t ctx; - SHA3_CTX hash_ctx; - SHA3_CTX aux_hash_ctx; + hash_keccak256_ctx_t hash_ctx; + hash_keccak256_ctx_t aux_hash_ctx; uint8_t num_linked; uint8_t offset; diff --git a/ledger/src/signer/src/auth_tx.c b/ledger/src/signer/src/auth_tx.c index ceb3b073..666b50bc 100644 --- a/ledger/src/signer/src/auth_tx.c +++ b/ledger/src/signer/src/auth_tx.c @@ -22,14 +22,16 @@ * IN THE SOFTWARE. */ -#include "os.h" +#include "hal/hash.h" +#include "hal/platform.h" +#include "hal/exceptions.h" #include "auth.h" #include "svarint.h" #include "mem.h" #include "memutil.h" -#include "dbg.h" +#include "hal/log.h" // IMPORTANT: This callback only executes for the scriptSig at the desired input // (the one that is requested to sign) @@ -49,19 +51,20 @@ static void btcscript_cb(const btcscript_cb_event_t event) { svarint_encode(auth.tx.script_ctx.operand_size, redeemscript_length, sizeof(redeemscript_length)); - sha256_update(&auth.tx.sig_hash_ctx, - redeemscript_length, - redeemscript_length_size); + hash_sha256_update(&auth.tx.sig_hash_ctx, + redeemscript_length, + redeemscript_length_size); } else if (event == BTCSCRIPT_EV_OPERAND && auth.tx.redeemscript_found) { - sha256_update(&auth.tx.sig_hash_ctx, - &auth.tx.script_ctx.operand_byte, - sizeof(auth.tx.script_ctx.operand_byte)); + hash_sha256_update(&auth.tx.sig_hash_ctx, + &auth.tx.script_ctx.operand_byte, + sizeof(auth.tx.script_ctx.operand_byte)); } } static void btctx_cb(const btctx_cb_event_t event) { // Update txhash - sha256_update(&auth.tx.tx_hash_ctx, auth.tx.ctx.raw, auth.tx.ctx.raw_size); + hash_sha256_update( + &auth.tx.tx_hash_ctx, auth.tx.ctx.raw, auth.tx.ctx.raw_size); // The bridge currently only generates pegout transactions with // versions 1 or 2. Validate that. @@ -89,7 +92,7 @@ static void btctx_cb(const btctx_cb_event_t event) { } else { // All other scriptSigs get replaced by an empty scriptSig // when calculating the sigHash - sha256_update(&auth.tx.sig_hash_ctx, (uint8_t[]){0x00}, 1); + hash_sha256_update(&auth.tx.sig_hash_ctx, (uint8_t[]){0x00}, 1); } } else if (event == BTCTX_EV_VIN_SCRIPT_DATA && auth.tx.ctx.inout_current == auth.input_index_to_sign) { @@ -118,28 +121,29 @@ static void btctx_cb(const btctx_cb_event_t event) { } } } else if (event != BTCTX_EV_VIN_SCRIPT_DATA) { - sha256_update( + hash_sha256_update( &auth.tx.sig_hash_ctx, auth.tx.ctx.raw, auth.tx.ctx.raw_size); } } static void btctx_cb_segwit(const btctx_cb_event_t event) { // Update txhash - sha256_update(&auth.tx.tx_hash_ctx, auth.tx.ctx.raw, auth.tx.ctx.raw_size); + hash_sha256_update( + &auth.tx.tx_hash_ctx, auth.tx.ctx.raw, auth.tx.ctx.raw_size); if (event == BTCTX_EV_VERSION) { - sha256_update( + hash_sha256_update( &auth.tx.sig_hash_ctx, auth.tx.ctx.raw, auth.tx.ctx.raw_size); } if (event == BTCTX_EV_VIN_COUNT) { - sha256_init(&auth.tx.prevouts_hash_ctx); - sha256_init(&auth.tx.sequence_hash_ctx); + hash_sha256_init(&auth.tx.prevouts_hash_ctx); + hash_sha256_init(&auth.tx.sequence_hash_ctx); auth.tx.aux_offset = 0; } if (event == BTCTX_EV_VIN_TXH_DATA || event == BTCTX_EV_VIN_TXIX) { - sha256_update( + hash_sha256_update( &auth.tx.prevouts_hash_ctx, auth.tx.ctx.raw, auth.tx.ctx.raw_size); if (auth.tx.ctx.inout_current == auth.input_index_to_sign) { @@ -156,7 +160,7 @@ static void btctx_cb_segwit(const btctx_cb_event_t event) { } if (event == BTCTX_EV_VIN_SEQNO) { - sha256_update( + hash_sha256_update( &auth.tx.sequence_hash_ctx, auth.tx.ctx.raw, auth.tx.ctx.raw_size); if (auth.tx.ctx.inout_current == auth.input_index_to_sign) { @@ -172,45 +176,45 @@ static void btctx_cb_segwit(const btctx_cb_event_t event) { } if (event == BTCTX_EV_VOUT_COUNT) { - sha256_final(&auth.tx.prevouts_hash_ctx, auth.tx.aux_hash); - sha256_init(&auth.tx.prevouts_hash_ctx); - sha256_update(&auth.tx.prevouts_hash_ctx, - auth.tx.aux_hash, - sizeof(auth.tx.aux_hash)); - sha256_final(&auth.tx.prevouts_hash_ctx, auth.tx.aux_hash); - sha256_update( + hash_sha256_final(&auth.tx.prevouts_hash_ctx, auth.tx.aux_hash); + hash_sha256_init(&auth.tx.prevouts_hash_ctx); + hash_sha256_update(&auth.tx.prevouts_hash_ctx, + auth.tx.aux_hash, + sizeof(auth.tx.aux_hash)); + hash_sha256_final(&auth.tx.prevouts_hash_ctx, auth.tx.aux_hash); + hash_sha256_update( &auth.tx.sig_hash_ctx, auth.tx.aux_hash, sizeof(auth.tx.aux_hash)); - sha256_final(&auth.tx.sequence_hash_ctx, auth.tx.aux_hash); - sha256_init(&auth.tx.sequence_hash_ctx); - sha256_update(&auth.tx.sequence_hash_ctx, - auth.tx.aux_hash, - sizeof(auth.tx.aux_hash)); - sha256_final(&auth.tx.sequence_hash_ctx, auth.tx.aux_hash); - sha256_update( + hash_sha256_final(&auth.tx.sequence_hash_ctx, auth.tx.aux_hash); + hash_sha256_init(&auth.tx.sequence_hash_ctx); + hash_sha256_update(&auth.tx.sequence_hash_ctx, + auth.tx.aux_hash, + sizeof(auth.tx.aux_hash)); + hash_sha256_final(&auth.tx.sequence_hash_ctx, auth.tx.aux_hash); + hash_sha256_update( &auth.tx.sig_hash_ctx, auth.tx.aux_hash, sizeof(auth.tx.aux_hash)); // Previously saved outpoint of input to sign - sha256_update(&auth.tx.sig_hash_ctx, - auth.tx.ip_prevout, - sizeof(auth.tx.ip_prevout)); + hash_sha256_update(&auth.tx.sig_hash_ctx, + auth.tx.ip_prevout, + sizeof(auth.tx.ip_prevout)); - sha256_init(&auth.tx.outputs_hash_ctx); + hash_sha256_init(&auth.tx.outputs_hash_ctx); } if (event == BTCTX_EV_VOUT_VALUE || event == BTCTX_EV_VOUT_SLENGTH || event == BTCTX_EV_VOUT_SCRIPT_DATA) { - sha256_update( + hash_sha256_update( &auth.tx.outputs_hash_ctx, auth.tx.ctx.raw, auth.tx.ctx.raw_size); } if (event == BTCTX_EV_LOCKTIME) { - sha256_final(&auth.tx.outputs_hash_ctx, auth.tx.outputs_hash); - sha256_init(&auth.tx.outputs_hash_ctx); - sha256_update(&auth.tx.outputs_hash_ctx, - auth.tx.outputs_hash, - sizeof(auth.tx.outputs_hash)); - sha256_final(&auth.tx.outputs_hash_ctx, auth.tx.outputs_hash); + hash_sha256_final(&auth.tx.outputs_hash_ctx, auth.tx.outputs_hash); + hash_sha256_init(&auth.tx.outputs_hash_ctx); + hash_sha256_update(&auth.tx.outputs_hash_ctx, + auth.tx.outputs_hash, + sizeof(auth.tx.outputs_hash)); + hash_sha256_final(&auth.tx.outputs_hash_ctx, auth.tx.outputs_hash); SAFE_MEMMOVE(auth.tx.lock_time, sizeof(auth.tx.lock_time), @@ -251,8 +255,8 @@ unsigned int auth_sign_handle_btctx(volatile unsigned int rx) { auth.tx.remaining_bytes -= BTCTX_LENGTH_SIZE + SIGHASH_COMP_MODE_SIZE + EXTRADATA_SIZE; // Init both hash operations - sha256_init(&auth.tx.tx_hash_ctx); - sha256_init(&auth.tx.sig_hash_ctx); + hash_sha256_init(&auth.tx.tx_hash_ctx); + hash_sha256_init(&auth.tx.sig_hash_ctx); apdu_offset = BTCTX_LENGTH_SIZE; // Following three bytes indicate the sighash computation // mode (1 byte) and extradata size (2 bytes LE, for segwit) @@ -297,10 +301,10 @@ unsigned int auth_sign_handle_btctx(volatile unsigned int rx) { } // Finalize TX hash computation - sha256_final(&auth.tx.tx_hash_ctx, auth.tx_hash); - sha256_init(&auth.tx.tx_hash_ctx); - sha256_update(&auth.tx.tx_hash_ctx, auth.tx_hash, 32); - sha256_final(&auth.tx.tx_hash_ctx, auth.tx_hash); + hash_sha256_final(&auth.tx.tx_hash_ctx, auth.tx_hash); + hash_sha256_init(&auth.tx.tx_hash_ctx); + hash_sha256_update(&auth.tx.tx_hash_ctx, auth.tx_hash, 32); + hash_sha256_final(&auth.tx.tx_hash_ctx, auth.tx_hash); for (int j = 0; j < 16; j++) { uint8_t aux = auth.tx_hash[j]; auth.tx_hash[j] = auth.tx_hash[31 - j]; @@ -319,7 +323,8 @@ unsigned int auth_sign_handle_btctx(volatile unsigned int rx) { } } else { // Hash extradata - sha256_update(&auth.tx.sig_hash_ctx, APDU_DATA_PTR, APDU_DATA_SIZE(rx)); + hash_sha256_update( + &auth.tx.sig_hash_ctx, APDU_DATA_PTR, APDU_DATA_SIZE(rx)); auth.tx.remaining_bytes -= APDU_DATA_SIZE(rx); if (auth.tx.remaining_bytes == 0) { auth.tx.finalise = true; @@ -329,26 +334,26 @@ unsigned int auth_sign_handle_btctx(volatile unsigned int rx) { if (auth.tx.finalise) { if (auth.tx.sighash_computation_mode == SIGHASH_COMPUTE_MODE_SEGWIT) { // Remaining tx items to hash for segwit - sha256_update(&auth.tx.sig_hash_ctx, - auth.tx.ip_seqno, - sizeof(auth.tx.ip_seqno)); - sha256_update(&auth.tx.sig_hash_ctx, - auth.tx.outputs_hash, - sizeof(auth.tx.outputs_hash)); - sha256_update(&auth.tx.sig_hash_ctx, - auth.tx.lock_time, - sizeof(auth.tx.lock_time)); + hash_sha256_update(&auth.tx.sig_hash_ctx, + auth.tx.ip_seqno, + sizeof(auth.tx.ip_seqno)); + hash_sha256_update(&auth.tx.sig_hash_ctx, + auth.tx.outputs_hash, + sizeof(auth.tx.outputs_hash)); + hash_sha256_update(&auth.tx.sig_hash_ctx, + auth.tx.lock_time, + sizeof(auth.tx.lock_time)); } // Add SIGHASH_ALL hash type at the end - sha256_update(&auth.tx.sig_hash_ctx, - (uint8_t[])SIGHASH_ALL_BYTES, - sizeof(SIGHASH_ALL_SIZE)); - sha256_final(&auth.tx.sig_hash_ctx, auth.sig_hash); - - sha256_init(&auth.tx.sig_hash_ctx); - sha256_update(&auth.tx.sig_hash_ctx, auth.sig_hash, 32); - sha256_final(&auth.tx.sig_hash_ctx, auth.sig_hash); + hash_sha256_update(&auth.tx.sig_hash_ctx, + (uint8_t[])SIGHASH_ALL_BYTES, + sizeof(SIGHASH_ALL_SIZE)); + hash_sha256_final(&auth.tx.sig_hash_ctx, auth.sig_hash); + + hash_sha256_init(&auth.tx.sig_hash_ctx); + hash_sha256_update(&auth.tx.sig_hash_ctx, auth.sig_hash, 32); + hash_sha256_final(&auth.tx.sig_hash_ctx, auth.sig_hash); // Log hashes for debugging purposes LOG_HEX("TX hash: ", auth.tx_hash, sizeof(auth.tx_hash)); diff --git a/ledger/src/signer/src/auth_tx.h b/ledger/src/signer/src/auth_tx.h index 9766b9a8..dfd690a5 100644 --- a/ledger/src/signer/src/auth_tx.h +++ b/ledger/src/signer/src/auth_tx.h @@ -27,7 +27,8 @@ #include -#include "sha256.h" +#include "hal/hash.h" + #include "btctx.h" #include "btcscript.h" @@ -48,8 +49,8 @@ typedef struct { bool finalise; btctx_ctx_t ctx; btcscript_ctx_t script_ctx; - SHA256_CTX tx_hash_ctx; - SHA256_CTX sig_hash_ctx; + hash_sha256_ctx_t tx_hash_ctx; + hash_sha256_ctx_t sig_hash_ctx; uint8_t sighash_computation_mode; @@ -58,11 +59,11 @@ typedef struct { bool segwit_processing_extradata; uint16_t segwit_extradata_size; union { - SHA256_CTX prevouts_hash_ctx; - SHA256_CTX outputs_hash_ctx; + hash_sha256_ctx_t prevouts_hash_ctx; + hash_sha256_ctx_t outputs_hash_ctx; uint8_t lock_time[BTCTX_LOCKTIME_SIZE]; }; - SHA256_CTX sequence_hash_ctx; + hash_sha256_ctx_t sequence_hash_ctx; union { uint8_t aux_hash[BTCTX_HASH_SIZE]; uint8_t outputs_hash[BTCTX_HASH_SIZE]; diff --git a/ledger/src/signer/src/bc_advance.c b/ledger/src/signer/src/bc_advance.c index 5f975712..d95a61d3 100644 --- a/ledger/src/signer/src/bc_advance.c +++ b/ledger/src/signer/src/bc_advance.c @@ -24,10 +24,8 @@ #include -#include "os.h" - #include "bc.h" -#include "dbg.h" +#include "hal/log.h" #include "defs.h" #include "ints.h" #include "mem.h" @@ -55,15 +53,14 @@ // 0x000001d5, 0, 0, 0, 0, 0, 0 }; // Here we take it from an external definition (see Makefile for details) -#ifdef PARAM_MIN_REQUIRED_DIFFICULTY +#if defined(HSM_PLATFORM_LEDGER) && defined(PARAM_MIN_REQUIRED_DIFFICULTY) static const DIGIT_T MIN_REQUIRED_DIFFICULTY[BIGINT_LEN] = PARAM_MIN_REQUIRED_DIFFICULTY; +#elif defined(HSM_PLATFORM_X86) +DIGIT_T MIN_REQUIRED_DIFFICULTY[BIGINT_LEN]; #else -#ifndef HSM_SIMULATOR #error "Minimum required difficulty not defined!" #endif -DIGIT_T MIN_REQUIRED_DIFFICULTY[BIGINT_LEN]; -#endif // ----------------------------------------------------------------------- // Blockchain advance validation state @@ -192,15 +189,15 @@ static void compute_cb_txn_hash() { memset(block.wa_buf + CB_MIDSTATE_PREFIX + CB_MIDSTATE_DATA, 0, CB_MIDSTATE_SUFFIX); - sha256_init(&block.mid_ctx); - sha256_midstate(&block.mid_ctx, block.wa_buf); - sha256_update(&block.mid_ctx, - block.cb_txn + CB_MIDSTATE_DATA, - block.cb_off - CB_MIDSTATE_DATA); - sha256_final(&block.mid_ctx, block.wa_buf); - sha256_init(&block.mid_ctx); - sha256_update(&block.mid_ctx, block.wa_buf, HASH_SIZE); - sha256_final(&block.mid_ctx, block.wa_buf); + hash_sha256_ms_init(&block.mid_ctx); + hash_sha256_ms_midstate(&block.mid_ctx, block.wa_buf); + hash_sha256_ms_update(&block.mid_ctx, + block.cb_txn + CB_MIDSTATE_DATA, + block.cb_off - CB_MIDSTATE_DATA); + hash_sha256_ms_final(&block.mid_ctx, block.wa_buf); + hash_sha256_ms_init(&block.mid_ctx); + hash_sha256_ms_update(&block.mid_ctx, block.wa_buf, HASH_SIZE); + hash_sha256_ms_final(&block.mid_ctx, block.wa_buf); REV_HASH(block.wa_buf); } diff --git a/ledger/src/signer/src/bc_ancestor.c b/ledger/src/signer/src/bc_ancestor.c index db7d4d56..f5fbda44 100644 --- a/ledger/src/signer/src/bc_ancestor.c +++ b/ledger/src/signer/src/bc_ancestor.c @@ -24,10 +24,8 @@ #include -#include "os.h" - #include "bc.h" -#include "dbg.h" +#include "hal/log.h" #include "defs.h" #include "ints.h" #include "mem.h" diff --git a/ledger/src/signer/src/bc_block.h b/ledger/src/signer/src/bc_block.h index 3c1bc557..14d9db61 100644 --- a/ledger/src/signer/src/bc_block.h +++ b/ledger/src/signer/src/bc_block.h @@ -27,8 +27,9 @@ #include +#include "hal/hash.h" + #include "bigdigits.h" -#include "sha256.h" #include "bc.h" #include "bc_hash.h" @@ -73,8 +74,8 @@ typedef struct { }; union { - sha256_ctx_t ctx; // Global sha256 context - SHA256_CTX mid_ctx; // Sha256 supporting midstate + hash_sha256_ctx_t ctx; // Global sha256 context + hash_sha256_ms_ctx_t mid_ctx; // Sha256 supporting midstate }; union { diff --git a/ledger/src/signer/src/bc_diff.c b/ledger/src/signer/src/bc_diff.c index 3f3bb0b1..a765da17 100644 --- a/ledger/src/signer/src/bc_diff.c +++ b/ledger/src/signer/src/bc_diff.c @@ -25,7 +25,7 @@ #include #include "bc_diff.h" -#include "dbg.h" +#include "hal/log.h" #include "memutil.h" // Maximum difficulty for block difficulty capping (network dependent) @@ -33,7 +33,7 @@ static const DIGIT_T MAX_BLOCK_DIFFICULTY[BIGINT_LEN] = BCDIFF_MBD_TESTNET; #elif defined(REGTEST) static const DIGIT_T MAX_BLOCK_DIFFICULTY[BIGINT_LEN] = BCDIFF_MBD_REGTEST; -#elif defined(HSM_SIMULATOR) +#elif defined(HSM_PLATFORM_X86) DIGIT_T MAX_BLOCK_DIFFICULTY[BIGINT_LEN]; #else static const DIGIT_T MAX_BLOCK_DIFFICULTY[BIGINT_LEN] = BCDIFF_MBD_MAINNET; diff --git a/ledger/src/signer/src/bc_diff.h b/ledger/src/signer/src/bc_diff.h index 9fec7c38..e268f398 100644 --- a/ledger/src/signer/src/bc_diff.h +++ b/ledger/src/signer/src/bc_diff.h @@ -39,7 +39,7 @@ #define BCDIFF_MBD_REGTEST {0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; // 20 -#ifdef HSM_SIMULATOR +#ifdef HSM_PLATFORM_X86 extern DIGIT_T MAX_BLOCK_DIFFICULTY[BIGINT_LEN]; #endif diff --git a/ledger/src/signer/src/bc_err.c b/ledger/src/signer/src/bc_err.c index 6178d19a..37f38451 100644 --- a/ledger/src/signer/src/bc_err.c +++ b/ledger/src/signer/src/bc_err.c @@ -24,7 +24,7 @@ #include "bc_err.h" -#ifdef HSM_SIMULATOR +#ifdef HSM_PLATFORM_X86 #include diff --git a/ledger/src/signer/src/bc_err.h b/ledger/src/signer/src/bc_err.h index 4c0c3376..5b197986 100644 --- a/ledger/src/signer/src/bc_err.h +++ b/ledger/src/signer/src/bc_err.h @@ -25,6 +25,8 @@ #ifndef __BC_ERR_H #define __BC_ERR_H +#include "hal/exceptions.h" + // Error codes returned by blockchain protocols typedef enum { UNKNOWN = 0, diff --git a/ledger/src/signer/src/bc_hash.h b/ledger/src/signer/src/bc_hash.h index 413dcff9..2750dfcf 100644 --- a/ledger/src/signer/src/bc_hash.h +++ b/ledger/src/signer/src/bc_hash.h @@ -37,22 +37,20 @@ // - Ledger (the real thing): use BOLOS_SDK, version 1.3 // ----------------------------------------------------------------------- -#include "os.h" +#include -typedef cx_sha256_t sha256_ctx_t; -typedef cx_sha3_t keccak_ctx_t; +#include "hal/hash.h" -#define SHA256_INIT(ctx) cx_sha256_init(ctx) -#define SHA256_UPDATE(ctx, data, len) \ - cx_hash((cx_hash_t*)(ctx), 0, data, len, NULL) -#define SHA256_FINAL(ctx, hash) \ - cx_hash((cx_hash_t*)(ctx), CX_LAST, NULL, 0, hash) +typedef hash_sha256_ctx_t sha256_ctx_t; +typedef hash_keccak256_ctx_t keccak_ctx_t; -#define KECCAK_INIT(ctx) cx_keccak_init(ctx, 256) -#define KECCAK_UPDATE(ctx, data, len) \ - cx_hash((cx_hash_t*)(ctx), 0, (uint8_t*)data, len, NULL) -#define KECCAK_FINAL(ctx, hash) \ - cx_hash((cx_hash_t*)(ctx), CX_LAST, NULL, 0, hash) +#define SHA256_INIT(ctx) hash_sha256_init(ctx) +#define SHA256_UPDATE(ctx, data, len) hash_sha256_update(ctx, data, len) +#define SHA256_FINAL(ctx, hash) hash_sha256_final(ctx, hash) + +#define KECCAK_INIT(ctx) hash_keccak256_init(ctx) +#define KECCAK_UPDATE(ctx, data, len) hash_keccak256_update(ctx, data, len) +#define KECCAK_FINAL(ctx, hash) hash_keccak256_final(ctx, hash) // Convenience macros to deal with frequent hash ops #define HEQ(h0, h1) (memcmp(h0, h1, HASH_SIZE) == 0) diff --git a/ledger/src/signer/src/bc_nu.h b/ledger/src/signer/src/bc_nu.h index a2ad7dad..78d87343 100644 --- a/ledger/src/signer/src/bc_nu.h +++ b/ledger/src/signer/src/bc_nu.h @@ -71,7 +71,7 @@ typedef enum { #define SET_NETWORK_UPGRADE(bn, x) \ { *(x) = NU_IRIS; } #define GET_NETWORK_IDENTIFIER() NETID_REGTEST -#elif defined(HSM_SIMULATOR) +#elif defined(HSM_PLATFORM_X86) #include "hsmsim_nu.h" #define SET_NETWORK_UPGRADE(bn, x) hsmsim_set_network_upgrade(bn, x) #define GET_NETWORK_IDENTIFIER() hsmsim_get_network_identifier() diff --git a/ledger/src/signer/src/bc_state.c b/ledger/src/signer/src/bc_state.c index 106b385c..633a5857 100644 --- a/ledger/src/signer/src/bc_state.c +++ b/ledger/src/signer/src/bc_state.c @@ -28,7 +28,7 @@ #include "runtime.h" #include "defs.h" #include "err.h" -#include "dbg.h" +#include "hal/log.h" #include "nvm.h" #include "memutil.h" @@ -42,14 +42,13 @@ // ----------------------------------------------------------------------- // Here we take it from an external definition (see Makefile for details) -#ifdef PARAM_INITIAL_BLOCK_HASH +#if defined(HSM_PLATFORM_LEDGER) && defined(PARAM_INITIAL_BLOCK_HASH) static const uint8_t INITIAL_BLOCK_HASH[] = PARAM_INITIAL_BLOCK_HASH; +#elif defined(HSM_PLATFORM_X86) +uint8_t INITIAL_BLOCK_HASH[HASH_LENGTH]; #else -#ifndef HSM_SIMULATOR #error "Initial block hash not defined!" #endif -uint8_t INITIAL_BLOCK_HASH[HASH_LENGTH]; -#endif /* * Initialize blockchain state. @@ -238,6 +237,7 @@ unsigned int bc_get_state(volatile unsigned int rx) { } FAIL(PROT_INVALID); + return 0; } /* diff --git a/ledger/src/signer/src/bc_state.h b/ledger/src/signer/src/bc_state.h index 7165d993..0551af4c 100644 --- a/ledger/src/signer/src/bc_state.h +++ b/ledger/src/signer/src/bc_state.h @@ -32,7 +32,7 @@ #include #include -#include "os.h" +#include "hal/platform.h" #include "bigdigits.h" #include "nvm.h" diff --git a/ledger/src/signer/src/common_requirements.h b/ledger/src/signer/src/common_requirements.h new file mode 100644 index 00000000..13dd7e6f --- /dev/null +++ b/ledger/src/signer/src/common_requirements.h @@ -0,0 +1,31 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2021 RSK Labs Ltd + * + * 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. + */ + +#ifndef __COMMON_REQUIREMENTS_H +#define __COMMON_REQUIREMENTS_H + +#include "hal/communication.h" +#include "hal/platform.h" + +#endif // __COMMON_REQUIREMENTS_H diff --git a/ledger/src/signer/src/heartbeat.c b/ledger/src/signer/src/heartbeat.c index 19ab4ad4..6e01605d 100644 --- a/ledger/src/signer/src/heartbeat.c +++ b/ledger/src/signer/src/heartbeat.c @@ -24,7 +24,10 @@ #include -#include "os.h" +#include "hal/endorsement.h" +#include "hal/platform.h" +#include "hal/exceptions.h" + #include "heartbeat.h" #include "apdu.h" #include "defs.h" @@ -75,6 +78,8 @@ unsigned int get_heartbeat(volatile unsigned int rx, COMPILE_TIME_ASSERT(MAX_HEARTBEAT_MESSAGE_SIZE <= APDU_TOTAL_DATA_SIZE_OUT); + uint8_t out_size; + switch (APDU_OP()) { case OP_HBT_UD_VALUE: // Should receive a user-defined value @@ -138,8 +143,13 @@ unsigned int get_heartbeat(volatile unsigned int rx, check_state(heartbeat_ctx, STATE_HEARTBEAT_READY); // Sign message - int endorsement_size = os_endorsement_key2_derive_sign_data( - heartbeat_ctx->msg, heartbeat_ctx->msg_offset, APDU_DATA_PTR); + uint8_t endorsement_size = APDU_TOTAL_DATA_SIZE_OUT; + if (!endorsement_sign(heartbeat_ctx->msg, + heartbeat_ctx->msg_offset, + APDU_DATA_PTR, + &endorsement_size)) { + THROW(ERR_HBT_INTERNAL); + } return TX_FOR_DATA_SIZE(endorsement_size); case OP_HBT_GET_MESSAGE: @@ -156,13 +166,21 @@ unsigned int get_heartbeat(volatile unsigned int rx, return TX_FOR_DATA_SIZE(heartbeat_ctx->msg_offset); case OP_HBT_APP_HASH: - return TX_FOR_DATA_SIZE(os_endorsement_get_code_hash(APDU_DATA_PTR)); + out_size = APDU_TOTAL_DATA_SIZE_OUT; + if (!endorsement_get_code_hash(APDU_DATA_PTR, &out_size)) { + THROW(ERR_HBT_INTERNAL); + } + return TX_FOR_DATA_SIZE(out_size); case OP_HBT_PUBKEY: - return TX_FOR_DATA_SIZE(os_endorsement_get_public_key( - ENDORSEMENT_SCHEME_INDEX, APDU_DATA_PTR)); + out_size = APDU_TOTAL_DATA_SIZE_OUT; + if (!endorsement_get_public_key(APDU_DATA_PTR, &out_size)) { + THROW(ERR_HBT_INTERNAL); + } + return TX_FOR_DATA_SIZE(out_size); default: reset_heartbeat(heartbeat_ctx); THROW(ERR_HBT_PROT_INVALID); break; } + return 0; } diff --git a/ledger/src/signer/src/heartbeat.h b/ledger/src/signer/src/heartbeat.h index ba8de8c9..4b68a1ee 100644 --- a/ledger/src/signer/src/heartbeat.h +++ b/ledger/src/signer/src/heartbeat.h @@ -55,9 +55,6 @@ typedef enum { // to include in the message #define LAST_SIGNED_TX_BYTES 8 // bytes -// Index of the endorsement scheme -#define ENDORSEMENT_SCHEME_INDEX 2 - // Maximum heartbeat message to sign size #define MAX_HEARTBEAT_MESSAGE_SIZE 80 diff --git a/ledger/src/signer/src/hsm.c b/ledger/src/signer/src/hsm.c index 4f47062c..f9d0e1eb 100644 --- a/ledger/src/signer/src/hsm.c +++ b/ledger/src/signer/src/hsm.c @@ -24,9 +24,12 @@ #include +#include "hal/communication.h" +#include "hal/seed.h" +#include "hal/platform.h" +#include "hal/exceptions.h" + #include "hsm.h" -#include "os.h" -#include "os_io_seproxyhal.h" #include "defs.h" #include "instructions.h" @@ -37,7 +40,6 @@ #include "pathAuth.h" #include "auth.h" -#include "sign.h" #include "bc_state.h" #include "bc_advance.h" @@ -46,12 +48,12 @@ #include "attestation.h" #include "heartbeat.h" -#include "dbg.h" +#include "hal/log.h" // Macro that throws an error unless // the device is onboarded -#define REQUIRE_ONBOARDED() \ - if (os_perso_isonboarded() != 1) \ +#define REQUIRE_ONBOARDED() \ + if (!seed_available()) \ THROW(ERR_DEVICE_NOT_ONBOARDED); // Operation being currently executed @@ -85,19 +87,13 @@ static void reset_if_starting(unsigned char cmd) { // Exit the application static void app_exit(void) { - BEGIN_TRY_L(exit) { - TRY_L(exit) { - os_sched_exit(-1); - _hsm_exit_requested = true; - } - FINALLY_L(exit) { - } - } - END_TRY_L(exit); + platform_request_exit(); + _hsm_exit_requested = true; } -unsigned int hsm_process_apdu(volatile unsigned int rx) { +static unsigned int hsm_process_apdu(volatile unsigned int rx) { unsigned int tx = 0; + uint8_t pubkey_length; // No apdu received if (rx == 0) { @@ -107,7 +103,8 @@ unsigned int hsm_process_apdu(volatile unsigned int rx) { // Zero out commonly read APDU buffer offsets, // to avoid reading uninitialized memory if (rx < MIN_APDU_BYTES) { - explicit_bzero(G_io_apdu_buffer + rx, MIN_APDU_BYTES - rx); + explicit_bzero(communication_get_msg_buffer() + rx, + MIN_APDU_BYTES - rx); } // Invalid CLA @@ -127,7 +124,7 @@ unsigned int hsm_process_apdu(volatile unsigned int rx) { case RSK_IS_ONBOARD: reset_if_starting(RSK_IS_ONBOARD); uint8_t output_index = CMDPOS; - SET_APDU_AT(output_index++, os_perso_isonboarded()); + SET_APDU_AT(output_index++, seed_available() ? 1 : 0); SET_APDU_AT(output_index++, VERSION_MAJOR); SET_APDU_AT(output_index++, VERSION_MINOR); SET_APDU_AT(output_index++, VERSION_PATCH); @@ -164,16 +161,17 @@ unsigned int hsm_process_apdu(volatile unsigned int rx) { MEMMOVE_ZERO_OFFSET, sizeof(auth.path), THROW(ERR_INVALID_PATH)); - tx = do_pubkey(auth.path, - DERIVATION_PATH_PARTS, - G_io_apdu_buffer, - sizeof(G_io_apdu_buffer)); - // Error deriving? - if (tx == DO_PUBKEY_ERROR) { + pubkey_length = communication_get_msg_buffer_size(); + if (!seed_derive_pubkey(auth.path, + sizeof(auth.path) / sizeof(auth.path[0]), + communication_get_msg_buffer(), + &pubkey_length)) { THROW(ERR_INTERNAL); } + tx = pubkey_length; + break; case INS_SIGN: @@ -253,7 +251,8 @@ unsigned int hsm_process_apdu(volatile unsigned int rx) { return tx; } -unsigned int hsm_process_exception(unsigned short code, unsigned int tx) { +static unsigned int hsm_process_exception(unsigned short code, + unsigned int tx) { unsigned short sw = 0; // Always reset the full state when an error occurs @@ -275,7 +274,7 @@ unsigned int hsm_process_exception(unsigned short code, unsigned int tx) { // Append resulting code to APDU // (check for a potential overflow first) - if (tx + 2 > sizeof(G_io_apdu_buffer)) { + if (tx + 2 > communication_get_msg_buffer_size()) { tx = 0; sw = 0x6983; } @@ -285,6 +284,10 @@ unsigned int hsm_process_exception(unsigned short code, unsigned int tx) { return tx; } +static bool hsm_exit_requested() { + return _hsm_exit_requested; +} + void hsm_init() { // Initialize current operation // (0 = no operation being executed) @@ -297,6 +300,34 @@ void hsm_init() { bc_init_state(); } -bool hsm_exit_requested() { - return _hsm_exit_requested; +void hsm_main_loop() { + volatile unsigned int rx = 0; + volatile unsigned int tx = 0; + + // DESIGN NOTE: the bootloader ignores the way APDU are fetched. The only + // goal is to retrieve APDU. + // When APDU are to be fetched from multiple IOs, like NFC+USB+BLE, make + // sure the io_event is called with a + // switch event, before the apdu is replied to the bootloader. This avoid + // APDU injection faults. + while (!hsm_exit_requested()) { + BEGIN_TRY { + TRY { + // ensure no race in catch_other if io_exchange throws + // an error + rx = tx; + tx = 0; + rx = communication_io_exchange(rx); + + tx = hsm_process_apdu(rx); + THROW(0x9000); + } + CATCH_OTHER(e) { + tx = hsm_process_exception(e, tx); + } + FINALLY { + } + } + END_TRY; + } } diff --git a/ledger/src/signer/src/hsm.h b/ledger/src/signer/src/hsm.h index 72a5bda2..be9a5048 100644 --- a/ledger/src/signer/src/hsm.h +++ b/ledger/src/signer/src/hsm.h @@ -29,10 +29,12 @@ void hsm_init(); -unsigned int hsm_process_apdu(volatile unsigned int rx); +void hsm_main_loop(); -unsigned int hsm_process_exception(unsigned short code, unsigned int tx); +// unsigned int hsm_process_apdu(volatile unsigned int rx); -bool hsm_exit_requested(); +// unsigned int hsm_process_exception(unsigned short code, unsigned int tx); + +// bool hsm_exit_requested(); #endif // __HSM_H diff --git a/ledger/src/signer/src/keccak256.c b/ledger/src/signer/src/keccak256.c deleted file mode 100644 index e5084372..00000000 --- a/ledger/src/signer/src/keccak256.c +++ /dev/null @@ -1,267 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2021 RSK Labs Ltd - * - * 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. - */ - -/** - * Third party library taken from: - * https://github.com/firefly/wallet/blob/29adeaf7029142063b7a6878e049efd4c6534982/source/libs/ethers/src/keccak256.c - */ - -/* sha3 - an implementation of Secure Hash Algorithm 3 (Keccak). - * based on the - * The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011 - * by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche - * - * Copyright: 2013 Aleksey Kravchenko - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! - */ - -#include "keccak256.h" - -//#include - -#include -#include - -#define BLOCK_SIZE ((1600 - 256 * 2) / 8) - -#define I64(x) x##LL -#define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n)))) -#define le2me_64(x) (x) -#define IS_ALIGNED_64(p) (0 == (7 & ((const char*)(p) - (const char*)0))) -#define me64_to_le_str(to, from, length) memcpy((to), (from), (length)) - -/* constants */ - -//const uint8_t round_constant_info[] PROGMEM = { -//const uint8_t constants[] PROGMEM = { -const uint8_t constants[] = { - - 1, 26, 94, 112, 31, 33, 121, 85, 14, 12, 53, 38, 63, 79, 93, 83, 82, 72, 22, 102, 121, 88, 33, 116, -//}; - -//const uint8_t pi_transform[] PROGMEM = { - 1, 6, 9, 22, 14, 20, 2, 12, 13, 19, 23, 15, 4, 24, 21, 8, 16, 5, 3, 18, 17, 11, 7, 10, -//}; - -//const uint8_t rhoTransforms[] PROGMEM = { - 1, 62, 28, 27, 36, 44, 6, 55, 20, 3, 10, 43, 25, 39, 41, 45, 15, 21, 8, 18, 2, 61, 56, 14, -}; - -#define TYPE_ROUND_INFO 0 -#define TYPE_PI_TRANSFORM 24 -#define TYPE_RHO_TRANSFORM 48 - -uint8_t getConstant(uint8_t type, uint8_t index) { - return constants[type + index]; -} - -static uint64_t get_round_constant(uint8_t round) { - uint64_t result = 0; - - uint8_t roundInfo = getConstant(TYPE_ROUND_INFO, round); - if (roundInfo & (1 << 6)) { result |= ((uint64_t)1 << 63); } - if (roundInfo & (1 << 5)) { result |= ((uint64_t)1 << 31); } - if (roundInfo & (1 << 4)) { result |= ((uint64_t)1 << 15); } - if (roundInfo & (1 << 3)) { result |= ((uint64_t)1 << 7); } - if (roundInfo & (1 << 2)) { result |= ((uint64_t)1 << 3); } - if (roundInfo & (1 << 1)) { result |= ((uint64_t)1 << 1); } - if (roundInfo & (1 << 0)) { result |= ((uint64_t)1 << 0); } - - return result; -} - - -/* Initializing a sha3 context for given number of output bits */ -void keccak_init(SHA3_CTX *ctx) { - /* NB: The Keccak capacity parameter = bits * 2 */ - - memset(ctx, 0, sizeof(SHA3_CTX)); -} - -/* Keccak theta() transformation */ -static void keccak_theta(uint64_t *A) { - uint64_t C[5], D[5]; - - for (uint8_t i = 0; i < 5; i++) { - C[i] = A[i]; - for (uint8_t j = 5; j < 25; j += 5) { C[i] ^= A[i + j]; } - } - - for (uint8_t i = 0; i < 5; i++) { - D[i] = ROTL64(C[(i + 1) % 5], 1) ^ C[(i + 4) % 5]; - } - - for (uint8_t i = 0; i < 5; i++) { - //for (uint8_t j = 0; j < 25; j += 5) { - for (uint8_t j = 0; j < 25; j += 5) { A[i + j] ^= D[i]; } - } -} - - -/* Keccak pi() transformation */ -static void keccak_pi(uint64_t *A) { - uint64_t A1 = A[1]; - for (uint8_t i = 1; i < 24; i++) { - A[getConstant(TYPE_PI_TRANSFORM, i - 1)] = A[getConstant(TYPE_PI_TRANSFORM, i)]; - } - A[10] = A1; - /* note: A[ 0] is left as is */ -} - -/* -ketch uses 30084 bytes (93%) of program storage space. Maximum is 32256 bytes. -Global variables use 743 bytes (36%) of dynamic memory, leaving 1305 bytes for local variables. Maximum is 2048 bytes. - -*/ -/* Keccak chi() transformation */ -static void keccak_chi(uint64_t *A) { - for (uint8_t i = 0; i < 25; i += 5) { - uint64_t A0 = A[0 + i], A1 = A[1 + i]; - A[0 + i] ^= ~A1 & A[2 + i]; - A[1 + i] ^= ~A[2 + i] & A[3 + i]; - A[2 + i] ^= ~A[3 + i] & A[4 + i]; - A[3 + i] ^= ~A[4 + i] & A0; - A[4 + i] ^= ~A0 & A1; - } -} - - -static void sha3_permutation(uint64_t *state) { - for (uint8_t round = 0; round < 24; round++) { - keccak_theta(state); - - /* apply Keccak rho() transformation */ - for (uint8_t i = 1; i < 25; i++) { - state[i] = ROTL64(state[i], getConstant(TYPE_RHO_TRANSFORM, i - 1)); - } - - keccak_pi(state); - keccak_chi(state); - - /* apply iota(state, round) */ - *state ^= get_round_constant(round); - } -} - -/** - * The core transformation. Process the specified block of data. - * - * @param hash the algorithm state - * @param block the message block to process - * @param block_size the size of the processed block in bytes - */ -static void sha3_process_block(uint64_t hash[25], const uint64_t *block) { - for (uint8_t i = 0; i < 17; i++) { - hash[i] ^= le2me_64(block[i]); - } - - /* make a permutation of the hash */ - sha3_permutation(hash); -} - -//#define SHA3_FINALIZED 0x80000000 -//#define SHA3_FINALIZED 0x8000 - -/** - * Calculate message hash. - * Can be called repeatedly with chunks of the message to be hashed. - * - * @param ctx the algorithm context containing current hashing state - * @param msg message chunk - * @param size length of the message chunk - */ -void keccak_update(SHA3_CTX *ctx, const unsigned char *msg, uint16_t size) -{ - uint16_t idx = (uint16_t)ctx->rest; - - //if (ctx->rest & SHA3_FINALIZED) return; /* too late for additional input */ - ctx->rest = (unsigned)((ctx->rest + size) % BLOCK_SIZE); - - /* fill partial block */ - if (idx) { - uint16_t left = BLOCK_SIZE - idx; - memcpy((char*)ctx->message + idx, msg, (size < left ? size : left)); - if (size < left) return; - - /* process partial block */ - sha3_process_block(ctx->hash, ctx->message); - msg += left; - size -= left; - } - - while (size >= BLOCK_SIZE) { - uint64_t* aligned_message_block; - if (IS_ALIGNED_64(msg)) { - // the most common case is processing of an already aligned message without copying it - aligned_message_block = (uint64_t*)(void*)msg; - } else { - memcpy(ctx->message, msg, BLOCK_SIZE); - aligned_message_block = ctx->message; - } - - sha3_process_block(ctx->hash, aligned_message_block); - msg += BLOCK_SIZE; - size -= BLOCK_SIZE; - } - - if (size) { - memcpy(ctx->message, msg, size); /* save leftovers */ - } -} - -/** -* Store calculated hash into the given array. -* -* @param ctx the algorithm context containing current hashing state -* @param result calculated hash in binary form -*/ -void keccak_final(SHA3_CTX *ctx, unsigned char* result) -{ - uint16_t digest_length = 100 - BLOCK_SIZE / 2; - -// if (!(ctx->rest & SHA3_FINALIZED)) { - /* clear the rest of the data queue */ - memset((char*)ctx->message + ctx->rest, 0, BLOCK_SIZE - ctx->rest); - ((char*)ctx->message)[ctx->rest] |= 0x01; - ((char*)ctx->message)[BLOCK_SIZE - 1] |= 0x80; - - /* process final block */ - sha3_process_block(ctx->hash, ctx->message); -// ctx->rest = SHA3_FINALIZED; /* mark context as finalized */ -// } - - if (result) { - me64_to_le_str(result, ctx->hash, digest_length); - } -} diff --git a/ledger/src/signer/src/keccak256.h b/ledger/src/signer/src/keccak256.h deleted file mode 100644 index c2d15d7b..00000000 --- a/ledger/src/signer/src/keccak256.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2021 RSK Labs Ltd - * - * 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. - */ - -/** - * Third party library taken from: - * https://github.com/firefly/wallet/blob/29adeaf7029142063b7a6878e049efd4c6534982/source/libs/ethers/src/keccak256.h - */ - -/* sha3 - an implementation of Secure Hash Algorithm 3 (Keccak). - * based on the - * The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011 - * by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche - * - * Copyright: 2013 Aleksey Kravchenko - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! - */ - -#ifndef __KECCAK256_H_ -#define __KECCAK256_H_ - -#include - -#define sha3_max_permutation_size 25 -#define sha3_max_rate_in_qwords 24 - -typedef struct SHA3_CTX { - /* 1600 bits algorithm hashing state */ - uint64_t hash[sha3_max_permutation_size]; - /* 1536-bit buffer for leftovers */ - uint64_t message[sha3_max_rate_in_qwords]; - /* count of bytes in the message[] buffer */ - uint16_t rest; -} SHA3_CTX; - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -void keccak_init(SHA3_CTX *ctx); -void keccak_update(SHA3_CTX *ctx, const unsigned char *msg, uint16_t size); -void keccak_final(SHA3_CTX *ctx, unsigned char* result); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __KECCAK256_H_ */ diff --git a/ledger/src/signer/src/main.c b/ledger/src/signer/src/main.c index 4599f973..7bdaebe8 100644 --- a/ledger/src/signer/src/main.c +++ b/ledger/src/signer/src/main.c @@ -43,7 +43,9 @@ #include "os_io_seproxyhal.h" #include "hsm.h" -#include "hsm-ledger.h" + +// HAL includes +#include "hal/communication.h" unsigned char G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B]; @@ -240,11 +242,17 @@ __attribute__((section(".boot"))) int main(int argc, char **argv) { // APDU buffer initialization os_memset(G_io_apdu_buffer, 0, sizeof(G_io_apdu_buffer)); + // HAL modules initialization + communication_init(G_io_apdu_buffer, sizeof(G_io_apdu_buffer)); + // HSM context initialization hsm_init(); // HSM main loop - hsm_ledger_main_loop(); + hsm_main_loop(); + + // HAL modules finalisation + // Nothing for now } CATCH_OTHER(e) { } diff --git a/ledger/src/signer/src/mem.h b/ledger/src/signer/src/mem.h index 97731a5d..99ebd045 100644 --- a/ledger/src/signer/src/mem.h +++ b/ledger/src/signer/src/mem.h @@ -25,6 +25,9 @@ #ifndef __MEM_H #define __MEM_H +#include "hal/seed.h" +#include "hal/hash.h" + #include "bc_block.h" #include "bc_state.h" #include "btctx.h" @@ -41,13 +44,12 @@ #define MAX_ATT_MESSAGE_SIZE 50 typedef struct att_s { - sha256_ctx_t hash_ctx; // Attestation public keys hashing context + hash_sha256_ctx_t hash_ctx; // Attestation public keys hashing context uint8_t msg[MAX_ATT_MESSAGE_SIZE]; // Attestation message unsigned int path[DERIVATION_PATH_PARTS]; - cx_ecfp_public_key_t pub_key; - cx_ecfp_private_key_t priv_key; - unsigned char priv_key_data[PRIVATE_KEY_LENGTH]; + uint8_t pubkey[SEED_PUBLIC_KEY_SIZE]; + uint8_t pubkey_length; } att_t; typedef union { diff --git a/ledger/src/signer/src/nvm.h b/ledger/src/signer/src/nvm.h index 88128753..d3d90788 100644 --- a/ledger/src/signer/src/nvm.h +++ b/ledger/src/signer/src/nvm.h @@ -25,12 +25,9 @@ #ifndef __NVM_H #define __NVM_H -// ----------------------------------------------------------------------- -// Portable non-volatile memory access. -// ----------------------------------------------------------------------- +#include "hal/nvmem.h" -#include "os.h" -#define NVM_RESET(dst, size) nvm_write((void*)(dst), NULL, size) -#define NVM_WRITE(dst, src, size) nvm_write((void*)(dst), (void*)(src), size) +#define NVM_RESET(dst, size) nvmem_write((void*)(dst), NULL, size) +#define NVM_WRITE(dst, src, size) nvmem_write((void*)(dst), (void*)(src), size) #endif // __NVM_H diff --git a/ledger/src/signer/src/sign.h b/ledger/src/signer/src/sign.h deleted file mode 100644 index 4968a36b..00000000 --- a/ledger/src/signer/src/sign.h +++ /dev/null @@ -1,67 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2021 RSK Labs Ltd - * - * 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. - */ - -#ifndef __SIGN_H -#define __SIGN_H - -#define DO_SIGN_ERROR (0) -#define DO_PUBKEY_ERROR (0) - -/* - * Derive the public key for a given path. - * Store the public key into the given destination buffer. - * - * @arg[in] path derivation path - * @arg[in] path_length length of the derivation path - * @arg[in] dest destination buffer - * @arg[in] dest destination buffer size - * @ret size of the public key derived, - * or DO_PUBKEY_ERROR in case of error - */ -int do_pubkey(unsigned int* path, - unsigned char path_length, - unsigned char* dest, - size_t dest_size); - -/* - * Sign a message with a given path. - * Store the signature into the given destination buffer. - * - * @arg[in] path derivation path - * @arg[in] path_length length of the derivation path - * @arg[in] message message buffer - * @arg[in] message_size message size - * @arg[in] dest destination buffer - * @arg[in] dest destination buffer size - * @ret size of the signature produced, - * or DO_SIGN_ERROR in case of error - */ -int do_sign(unsigned int* path, - unsigned char path_length, - unsigned char* message, - size_t message_size, - unsigned char* dest, - size_t dest_size); - -#endif // __SIGN_H diff --git a/ledger/src/signer/src/srlp.c b/ledger/src/signer/src/srlp.c index b24b6549..b01cb638 100644 --- a/ledger/src/signer/src/srlp.c +++ b/ledger/src/signer/src/srlp.c @@ -26,11 +26,11 @@ #include #include -#include "srlp.h" - -#include "os.h" +#include "hal/platform.h" +#include "hal/log.h" -#include "dbg.h" +#include "srlp.h" +#include "runtime.h" // This code tinkers with function pointers referenced from // const data structures, so we need to use the PIC macro. @@ -181,6 +181,20 @@ void rlp_start(const rlp_callbacks_t* cbs) { } \ } +/** Print the given SRLP context (see srlp.h) */ +#ifdef DEBUG_SRLP +static void LOG_SRLP_CTX(uint8_t v, rlp_ctx_t ctx[], uint8_t ptr) { + LOG("'0x%02x' ; <%u> ; ", v, ptr); + for (int i = ptr; i >= 0; --i) { + rlp_ctx_t cur = ctx[i]; + LOG("{%d, %u, %u} ; ", cur.state, cur.size, cur.cursor); + } + LOG("{EOC}\n"); +} +#else +#define LOG_SRLP_CTX(...) +#endif + /* * Consume a chunk of bytes. *