From 4ed270efee8e801ada216c5a555e5a2879a64c42 Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Thu, 7 Sep 2023 00:24:38 +0200 Subject: [PATCH] blake2s --- .../embed/ble_bootloader/nrf_dfu_validation.c | 158 ++++-------------- 1 file changed, 29 insertions(+), 129 deletions(-) diff --git a/core/embed/ble_bootloader/nrf_dfu_validation.c b/core/embed/ble_bootloader/nrf_dfu_validation.c index 3cd0ab835..c71ebdc8d 100644 --- a/core/embed/ble_bootloader/nrf_dfu_validation.c +++ b/core/embed/ble_bootloader/nrf_dfu_validation.c @@ -55,6 +55,11 @@ #include "nrf_dfu_ver_validation.h" #include "nrf_strerror.h" +#include "blake2s.h" +#include "ed25519-donna/ed25519.h" +#include "secbool.h" + + #define NRF_LOG_MODULE_NAME nrf_dfu_validation #include "nrf_log.h" #include "nrf_log_ctrl.h" @@ -85,17 +90,6 @@ extern const uint8_t NRF_BOOTLOADER_KEY_M; extern const uint8_t NRF_BOOTLOADER_KEY_N; extern const uint8_t * const NRF_BOOTLOADER_KEYS[]; -/** @brief Structure to hold a signature - */ -static nrf_crypto_ecdsa_secp256r1_signature_t m_signature; - -/** @brief Structure to hold the hash for signature verification - */ -static nrf_crypto_hash_sha256_digest_t m_sig_hash; - -/** @brief Structure to hold the hash for the firmware image - */ -static nrf_crypto_hash_sha256_digest_t m_fw_hash; /** @brief Flag used by parser code to indicate that the init command has been found to be invalid. */ @@ -292,9 +286,6 @@ static bool signature_required(dfu_fw_type_t fw_type_to_be_updated) return result; } -#include "ed25519-donna/ed25519.h" -#include "secbool.h" - static secbool compute_pubkey(uint8_t sig_m, uint8_t sig_n, const uint8_t *const *pub, uint8_t sigmask, ed25519_public_key res) { @@ -346,13 +337,10 @@ static nrf_dfu_result_t nrf_dfu_validation_signature_check(dfu_signature_type_t uint8_t const * p_data, uint32_t data_len) { - ret_code_t err_code; - size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256; - - nrf_crypto_hash_context_t hash_context = {0}; -// nrf_crypto_ecdsa_verify_context_t verify_context = {0}; + ret_code_t err_code = NRF_SUCCESS; - // crypto_init(); + uint8_t hash_digest[BLAKE2S_DIGEST_LENGTH]; + uint8_t signature[64]; NRF_LOG_INFO("Signature required. Checking signature.") if (p_signature == NULL) @@ -361,36 +349,24 @@ static nrf_dfu_result_t nrf_dfu_validation_signature_check(dfu_signature_type_t return EXT_ERR(NRF_DFU_EXT_ERROR_SIGNATURE_MISSING); } - if (signature_type != DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256) - { - NRF_LOG_INFO("Invalid signature type"); - return EXT_ERR(NRF_DFU_EXT_ERROR_WRONG_SIGNATURE_TYPE); - } NRF_LOG_INFO("Calculating hash (len: %d)", data_len); - err_code = nrf_crypto_hash_calculate(&hash_context, - &g_nrf_crypto_hash_sha256_info, - p_data, - data_len, - m_sig_hash, - &hash_len); - if (err_code != NRF_SUCCESS) - { - return NRF_DFU_RES_CODE_OPERATION_FAILED; - } - if (sizeof(m_signature) != signature_len) + blake2s(p_data, data_len, hash_digest, BLAKE2S_DIGEST_LENGTH); + + + if (sizeof(signature) != signature_len) { return NRF_DFU_RES_CODE_OPERATION_FAILED; } // Prepare the signature received over the air. - memcpy(m_signature, p_signature, signature_len); + memcpy(signature, p_signature, signature_len); // Calculate the signature. NRF_LOG_INFO("Verify signature"); - if (sectrue != check_trezor_sig(m_sig_hash, hash_len, NRF_BOOTLOADER_KEY_M, NRF_BOOTLOADER_KEY_N, 3, NRF_BOOTLOADER_KEYS, m_signature)){ + if (sectrue != check_trezor_sig(hash_digest, BLAKE2S_DIGEST_LENGTH, NRF_BOOTLOADER_KEY_M, NRF_BOOTLOADER_KEY_N, 3, NRF_BOOTLOADER_KEYS, signature)){ NRF_LOG_ERROR("Signature failed"); err_code = NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE; } @@ -399,9 +375,9 @@ static nrf_dfu_result_t nrf_dfu_validation_signature_check(dfu_signature_type_t { NRF_LOG_ERROR("Signature failed (err_code: 0x%x)", err_code); NRF_LOG_DEBUG("Signature:"); - NRF_LOG_HEXDUMP_DEBUG(m_signature, sizeof(m_signature)); + NRF_LOG_HEXDUMP_DEBUG(signature, sizeof(signature)); NRF_LOG_DEBUG("Hash:"); - NRF_LOG_HEXDUMP_DEBUG(m_sig_hash, hash_len); + NRF_LOG_HEXDUMP_DEBUG(hash_digest, BLAKE2S_DIGEST_LENGTH); NRF_LOG_FLUSH(); return NRF_DFU_RES_CODE_INVALID_OBJECT; @@ -633,47 +609,25 @@ nrf_dfu_result_t nrf_dfu_validation_init_cmd_execute(uint32_t * p_dst_data_addr, // Function to check the hash received in the init command against the received firmware. // little_endian specifies the endianness of @p p_hash. -static bool nrf_dfu_validation_hash_ok(uint8_t const * p_hash, uint32_t src_addr, uint32_t data_len, bool little_endian) +static bool nrf_dfu_validation_hash_ok(uint8_t const * p_hash, uint32_t src_addr, uint32_t data_len) { - ret_code_t err_code; bool result = true; - uint8_t hash_be[NRF_CRYPTO_HASH_SIZE_SHA256]; - size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256; + uint8_t hash[BLAKE2S_DIGEST_LENGTH]; - nrf_crypto_hash_context_t hash_context = {0}; - - if (little_endian) - { - // Convert to hash to big-endian format for use in nrf_crypto. - nrf_crypto_internal_swap_endian(hash_be, - p_hash, - NRF_CRYPTO_HASH_SIZE_SHA256); - p_hash = hash_be; - } NRF_LOG_DEBUG("Hash verification. start address: 0x%x, size: 0x%x", src_addr, data_len); - err_code = nrf_crypto_hash_calculate(&hash_context, - &g_nrf_crypto_hash_sha256_info, - (uint8_t*)src_addr, - data_len, - m_fw_hash, - &hash_len); + blake2s( (uint8_t*)src_addr, data_len, hash, BLAKE2S_DIGEST_LENGTH); - if (err_code != NRF_SUCCESS) - { - NRF_LOG_ERROR("Could not run hash verification (err_code 0x%x).", err_code); - result = false; - } - else if (memcmp(m_fw_hash, p_hash, NRF_CRYPTO_HASH_SIZE_SHA256) != 0) + if (memcmp(hash, p_hash, NRF_CRYPTO_HASH_SIZE_SHA256) != 0) { NRF_LOG_WARNING("Hash verification failed."); NRF_LOG_DEBUG("Expected FW hash:") NRF_LOG_HEXDUMP_DEBUG(p_hash, NRF_CRYPTO_HASH_SIZE_SHA256); NRF_LOG_DEBUG("Actual FW hash:") - NRF_LOG_HEXDUMP_DEBUG(m_fw_hash, NRF_CRYPTO_HASH_SIZE_SHA256); + NRF_LOG_HEXDUMP_DEBUG(hash, NRF_CRYPTO_HASH_SIZE_SHA256); NRF_LOG_FLUSH(); result = false; @@ -687,7 +641,7 @@ static bool nrf_dfu_validation_hash_ok(uint8_t const * p_hash, uint32_t src_addr bool fw_hash_ok(dfu_init_command_t const * p_init, uint32_t fw_start_addr, uint32_t fw_size) { ASSERT(p_init != NULL); - return nrf_dfu_validation_hash_ok((uint8_t *)p_init->hash.hash.bytes, fw_start_addr, fw_size, true); + return nrf_dfu_validation_hash_ok((uint8_t *)p_init->hash.hash.bytes, fw_start_addr, fw_size); } @@ -754,11 +708,6 @@ static bool boot_validation_extract(boot_validation_t * p_boot_validation, uint32_t data_len, boot_validation_type_t default_type) { - ret_code_t err_code; - size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256; - - nrf_crypto_hash_context_t hash_context = {0}; - memset(p_boot_validation, 0, sizeof(boot_validation_t)); p_boot_validation->type = (p_init->boot_validation_count > index) ? (boot_validation_type_t)p_init->boot_validation[index].type @@ -766,27 +715,6 @@ static bool boot_validation_extract(boot_validation_t * p_boot_validation, switch(p_boot_validation->type) { - case NO_VALIDATION: - break; - - case VALIDATE_CRC: - *(uint32_t *)&p_boot_validation->bytes[0] = crc32_compute((uint8_t *)start_addr, data_len, NULL); - break; - - case VALIDATE_SHA256: - err_code = nrf_crypto_hash_calculate(&hash_context, - &g_nrf_crypto_hash_sha256_info, - (uint8_t*)start_addr, - data_len, - p_boot_validation->bytes, - &hash_len); - if (err_code != NRF_SUCCESS) - { - NRF_LOG_ERROR("nrf_crypto_hash_calculate() failed with error %s", nrf_strerror_get(err_code)); - return false; - } - break; - case VALIDATE_ECDSA_P256_SHA256: memcpy(p_boot_validation->bytes, p_init->boot_validation[index].bytes.bytes, p_init->boot_validation[index].bytes.size); break; @@ -949,43 +877,15 @@ static bool postvalidate_sd_bl(dfu_init_command_t const * p_init, bool nrf_dfu_validation_boot_validate(boot_validation_t const * p_validation, uint32_t data_addr, uint32_t data_len) { uint8_t const * p_data = (uint8_t*) data_addr; - switch(p_validation->type) - { - case NO_VALIDATION: - return true; - case VALIDATE_CRC: - { - uint32_t current_crc = *(uint32_t *)p_validation->bytes; - uint32_t crc = crc32_compute(p_data, data_len, NULL); + nrf_dfu_result_t res_code = nrf_dfu_validation_signature_check( + p_validation->sigmask, + p_validation->bytes, + NRF_CRYPTO_ECDSA_SECP256R1_SIGNATURE_SIZE, + p_data, + data_len); + return (res_code == NRF_DFU_RES_CODE_SUCCESS); - if (crc != current_crc) - { - // CRC does not match with what is stored. - NRF_LOG_DEBUG("CRC check of app failed. Return %d", NRF_DFU_DEBUG); - return NRF_DFU_DEBUG; - } - return true; - } - - case VALIDATE_SHA256: - return nrf_dfu_validation_hash_ok(p_validation->bytes, data_addr, data_len, false); - - case VALIDATE_ECDSA_P256_SHA256: - { - nrf_dfu_result_t res_code = nrf_dfu_validation_signature_check( - DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256, - p_validation->bytes, - NRF_CRYPTO_ECDSA_SECP256R1_SIGNATURE_SIZE, - p_data, - data_len); - return (res_code == NRF_DFU_RES_CODE_SUCCESS); - } - - default: - ASSERT(false); - return false; - } }