From 313049e325edd423b6e8f165db715db12a850607 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Sat, 31 Dec 2022 13:50:50 +0100 Subject: [PATCH] mgmt: updatehub: Rework check integrity The TinyCrypt is the current library used by UpdateHub to perform SHA-256 integrity check. This refactor code and add support to mbedTLS library. It changes default library to mbedTLS to use hardware accelerator when available. Signed-off-by: Gerson Fernando Budke --- subsys/mgmt/updatehub/CMakeLists.txt | 3 +- subsys/mgmt/updatehub/Kconfig | 8 +- subsys/mgmt/updatehub/updatehub.c | 32 +++--- subsys/mgmt/updatehub/updatehub_integrity.c | 119 ++++++++++++++++++++ subsys/mgmt/updatehub/updatehub_integrity.h | 45 ++++++++ 5 files changed, 186 insertions(+), 21 deletions(-) create mode 100644 subsys/mgmt/updatehub/updatehub_integrity.c create mode 100644 subsys/mgmt/updatehub/updatehub_integrity.h diff --git a/subsys/mgmt/updatehub/CMakeLists.txt b/subsys/mgmt/updatehub/CMakeLists.txt index cf63f1331de..1b28c8470f3 100644 --- a/subsys/mgmt/updatehub/CMakeLists.txt +++ b/subsys/mgmt/updatehub/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2018 O.S.Systems +# Copyright (c) 2018-2023 O.S.Systems # # SPDX -License-Identifier: Apache-2.0 # @@ -10,6 +10,7 @@ zephyr_library_sources_ifdef(CONFIG_UPDATEHUB updatehub.c) zephyr_library_sources_ifdef(CONFIG_UPDATEHUB updatehub_device.c) zephyr_library_sources_ifdef(CONFIG_UPDATEHUB updatehub_firmware.c) zephyr_library_sources_ifdef(CONFIG_UPDATEHUB updatehub_timer.c) +zephyr_library_sources_ifdef(CONFIG_UPDATEHUB updatehub_integrity.c) zephyr_library_sources_ifdef(CONFIG_UPDATEHUB_SHELL shell.c) zephyr_include_directories( diff --git a/subsys/mgmt/updatehub/Kconfig b/subsys/mgmt/updatehub/Kconfig index 92e51cf6ff1..da268610da4 100644 --- a/subsys/mgmt/updatehub/Kconfig +++ b/subsys/mgmt/updatehub/Kconfig @@ -1,4 +1,4 @@ -# Copyright (c) 2018-2020 O.S.Systems +# Copyright (c) 2018-2023 O.S.Systems # SPDX -License-Identifier: Apache-2.0 menuconfig UPDATEHUB @@ -17,8 +17,6 @@ menuconfig UPDATEHUB select COAP select DNS_RESOLVER select JSON_LIBRARY - select TINYCRYPT - select TINYCRYPT_SHA256 select HWINFO help UpdateHub is an enterprise-grade solution which makes simple to @@ -149,6 +147,10 @@ config UPDATEHUB_DOWNLOAD_STORAGE_SHA256_VERIFICATION endchoice +choice FLASH_AREA_CHECK_INTEGRITY_BACKEND + default FLASH_AREA_CHECK_INTEGRITY_MBEDTLS +endchoice + module = UPDATEHUB module-str = Log level for UpdateHub module-help = Enables logging for UpdateHub code. diff --git a/subsys/mgmt/updatehub/updatehub.c b/subsys/mgmt/updatehub/updatehub.c index 53c29c8a169..63083b04763 100644 --- a/subsys/mgmt/updatehub/updatehub.c +++ b/subsys/mgmt/updatehub/updatehub.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020 O.S.Systems + * Copyright (c) 2018-2023 O.S.Systems * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,7 +18,6 @@ LOG_MODULE_REGISTER(updatehub, CONFIG_UPDATEHUB_LOG_LEVEL); #include #include #include -#include #include #include @@ -27,6 +26,7 @@ LOG_MODULE_REGISTER(updatehub, CONFIG_UPDATEHUB_LOG_LEVEL); #include "updatehub_firmware.h" #include "updatehub_device.h" #include "updatehub_timer.h" +#include "updatehub_integrity.h" #if defined(CONFIG_UPDATEHUB_DTLS) #define CA_CERTIFICATE_TAG 1 @@ -45,8 +45,6 @@ LOG_MODULE_REGISTER(updatehub, CONFIG_UPDATEHUB_LOG_LEVEL); #define MAX_DOWNLOAD_DATA (MAX_PAYLOAD_SIZE + 32) #define MAX_IP_SIZE 30 -#define SHA256_HEX_DIGEST_SIZE ((TC_SHA256_DIGEST_SIZE * 2) + 1) - #if defined(CONFIG_UPDATEHUB_CE) #define UPDATEHUB_SERVER CONFIG_UPDATEHUB_SERVER #else @@ -66,9 +64,9 @@ static struct updatehub_context { struct coap_block_context block; struct k_sem semaphore; struct flash_img_context flash_ctx; - struct tc_sha256_state_struct sha256sum; + struct updatehub_crypto_context crypto_ctx; enum updatehub_response code_status; - uint8_t hash[TC_SHA256_DIGEST_SIZE]; + uint8_t hash[SHA256_BIN_DIGEST_SIZE]; uint8_t uri_path[MAX_PATH_SIZE]; uint8_t payload[MAX_PAYLOAD_SIZE]; int downloaded_size; @@ -118,21 +116,21 @@ static void prepare_fds(void) static int metadata_hash_get(char *metadata) { - struct tc_sha256_state_struct sha256sum; + struct updatehub_crypto_context local_crypto_ctx; - if (tc_sha256_init(&sha256sum) == 0) { + if (updatehub_integrity_init(&local_crypto_ctx)) { return -1; } - if (tc_sha256_update(&sha256sum, metadata, strlen(metadata)) == 0) { + if (updatehub_integrity_update(&local_crypto_ctx, metadata, strlen(metadata))) { return -1; } - if (tc_sha256_final(ctx.hash, &sha256sum) == 0) { + if (updatehub_integrity_finish(&local_crypto_ctx, ctx.hash, sizeof(ctx.hash))) { return -1; } - if (bin2hex_str(ctx.hash, TC_SHA256_DIGEST_SIZE, + if (bin2hex_str(ctx.hash, SHA256_BIN_DIGEST_SIZE, update_info.package_uid, SHA256_HEX_DIGEST_SIZE)) { return -1; } @@ -367,12 +365,12 @@ static bool install_update_cb_sha256(void) { char sha256[SHA256_HEX_DIGEST_SIZE]; - if (tc_sha256_final(ctx.hash, &ctx.sha256sum) < 1) { + if (updatehub_integrity_finish(&ctx.crypto_ctx, ctx.hash, sizeof(ctx.hash))) { LOG_ERR("Could not finish sha256sum"); return false; } - if (bin2hex_str(ctx.hash, TC_SHA256_DIGEST_SIZE, + if (bin2hex_str(ctx.hash, SHA256_BIN_DIGEST_SIZE, sha256, SHA256_HEX_DIGEST_SIZE)) { LOG_ERR("Could not create sha256sum hex representation"); return false; @@ -461,9 +459,9 @@ static void install_update_cb(void) ctx.downloaded_size = ctx.downloaded_size + payload_len; #ifdef _DOWNLOAD_SHA256_VERIFICATION - if (tc_sha256_update(&ctx.sha256sum, + if (updatehub_integrity_update(&ctx.crypto_ctx, payload_start, - payload_len) < 1) { + payload_len)) { LOG_ERR("Could not update sha256sum"); ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR; goto cleanup; @@ -506,7 +504,7 @@ static void install_update_cb(void) #else if (hex2bin(update_info.sha256sum_image, SHA256_HEX_DIGEST_SIZE - 1, ctx.hash, - TC_SHA256_DIGEST_SIZE) != TC_SHA256_DIGEST_SIZE) { + SHA256_BIN_DIGEST_SIZE) != SHA256_BIN_DIGEST_SIZE) { LOG_ERR("Firmware - metadata validation has failed"); ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR; goto cleanup; @@ -541,7 +539,7 @@ static enum updatehub_response install_update(void) } #ifdef _DOWNLOAD_SHA256_VERIFICATION - if (tc_sha256_init(&ctx.sha256sum) < 1) { + if (updatehub_integrity_init(&ctx.crypto_ctx)) { LOG_ERR("Could not start sha256sum"); ctx.code_status = UPDATEHUB_DOWNLOAD_ERROR; goto error; diff --git a/subsys/mgmt/updatehub/updatehub_integrity.c b/subsys/mgmt/updatehub/updatehub_integrity.c new file mode 100644 index 00000000000..d9f0c8e1a35 --- /dev/null +++ b/subsys/mgmt/updatehub/updatehub_integrity.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2023 O.S.Systems + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(updatehub, CONFIG_UPDATEHUB_LOG_LEVEL); + +#include "updatehub_integrity.h" + +int updatehub_integrity_init(struct updatehub_crypto_context *ctx) +{ + int ret; + + if (ctx == NULL) { + LOG_DBG("Invalid integrity context"); + return -EINVAL; + } + + memset(ctx, 0, sizeof(struct updatehub_crypto_context)); + +#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS) + ctx->md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); + if (ctx->md_info == NULL) { + LOG_DBG("Message Digest not found or not enabled"); + return -ENOENT; + } + + mbedtls_md_init(&ctx->md_ctx); + ret = mbedtls_md_setup(&ctx->md_ctx, ctx->md_info, 0); + if (ret == MBEDTLS_ERR_MD_BAD_INPUT_DATA) { + LOG_DBG("Bad Message Digest selected"); + return -EFAULT; + } + if (ret == MBEDTLS_ERR_MD_ALLOC_FAILED) { + LOG_DBG("Failed to allocate memory"); + return -ENOMEM; + } + + ret = mbedtls_md_starts(&ctx->md_ctx); + if (ret == MBEDTLS_ERR_MD_BAD_INPUT_DATA) { + LOG_DBG("Bad Message Digest selected"); + return -EFAULT; + } +#elif defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC) + ret = tc_sha256_init(&ctx->sha256sum); + if (ret != TC_CRYPTO_SUCCESS) { + LOG_DBG("Invalid integrity context"); + return -EFAULT; + } +#endif + + return 0; +} + +int updatehub_integrity_update(struct updatehub_crypto_context *ctx, + const uint8_t *buffer, const uint32_t len) +{ + int ret; + + if (ctx == NULL || buffer == NULL) { + return -EINVAL; + } + + /* bypass */ + if (len == 0) { + return 0; + } + +#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS) + ret = mbedtls_md_update(&ctx->md_ctx, buffer, len); + if (ret == MBEDTLS_ERR_MD_BAD_INPUT_DATA) { + LOG_DBG("Bad Message Digest selected"); + return -EFAULT; + } +#elif defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC) + ret = tc_sha256_update(&ctx->sha256sum, buffer, len); + if (ret != TC_CRYPTO_SUCCESS) { + LOG_DBG("Invalid integrity context or invalid buffer"); + return -EFAULT; + } +#endif + + return 0; +} + +int updatehub_integrity_finish(struct updatehub_crypto_context *ctx, + uint8_t *hash, const uint32_t size) +{ + int ret; + + if (ctx == NULL || hash == NULL) { + return -EINVAL; + } + +#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS) + if (size < mbedtls_md_get_size(ctx->md_info)) { + LOG_DBG("HASH input buffer is to small to store the message digest"); + return -EINVAL; + } + + ret = mbedtls_md_finish(&ctx->md_ctx, hash); + if (ret == MBEDTLS_ERR_MD_BAD_INPUT_DATA) { + LOG_DBG("Bad Message Digest selected"); + return -EFAULT; + } + + mbedtls_md_free(&ctx->md_ctx); +#elif defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC) + ret = tc_sha256_final(hash, &ctx->sha256sum); + if (ret != TC_CRYPTO_SUCCESS) { + LOG_DBG("Invalid integrity context or invalid hash pointer"); + return -EFAULT; + } +#endif + + return 0; +} diff --git a/subsys/mgmt/updatehub/updatehub_integrity.h b/subsys/mgmt/updatehub/updatehub_integrity.h new file mode 100644 index 00000000000..d960c8f8ef8 --- /dev/null +++ b/subsys/mgmt/updatehub/updatehub_integrity.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 O.S.Systems + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __UPDATEHUB_INTEGRITY_H__ +#define __UPDATEHUB_INTEGRITY_H__ + +#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS) +#include +#elif defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC) +#include +#include +#else +#error "Integrity check method not defined" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define SHA256_BIN_DIGEST_SIZE (32) +#define SHA256_HEX_DIGEST_SIZE ((SHA256_BIN_DIGEST_SIZE * 2) + 1) + +struct updatehub_crypto_context { +#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS) + mbedtls_md_context_t md_ctx; + const mbedtls_md_info_t *md_info; +#elif defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC) + struct tc_sha256_state_struct sha256sum; +#endif +}; + +int updatehub_integrity_init(struct updatehub_crypto_context *ctx); +int updatehub_integrity_update(struct updatehub_crypto_context *ctx, + const uint8_t *buffer, const uint32_t len); +int updatehub_integrity_finish(struct updatehub_crypto_context *ctx, + uint8_t *hash, const uint32_t size); + +#ifdef __cplusplus +} +#endif + +#endif /* __UPDATEHUB_INTEGRITY_H__ */