Skip to content

Commit

Permalink
mgmt: updatehub: replace TinyCrypt by PSA
Browse files Browse the repository at this point in the history
As part of ongoing work to move away from TinyCrypt and towards PSA
(zephyrproject-rtos#43712), introduce a PSA option and remove the TinyCrypt one for the
SHA-256 implementation.

The Mbed TLS implementation is modified to use `mbedtls_sha256`
directly for smaller code size.

The reliance of mgmt/updatehub on storage/flash_map's configuration
(`FLASH_AREA_CHECK_INTEGRITY_BACKEND`) is removed.
The choice of which implementation to use is made automatically,
based on whether a PSA API provider is present (`PSA_CRYPTO_CLIENT`).

Signed-off-by: Tomi Fontanilles <tomi.fontanilles@nordicsemi.no>
  • Loading branch information
tomi-font authored and valeriosetti committed Jun 10, 2024
1 parent b46fb46 commit a04ff83
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 80 deletions.
9 changes: 9 additions & 0 deletions doc/releases/migration-guide-3.7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,15 @@ State Machine Framework
action would terminate the state machine. Passing ``NULL`` is now not allowed. Instead create a
'terminate' state at the top level, and call :c:func:`smf_set_terminate` from its entry action.

UpdateHub
=========

* The SHA-256 implementation used to perform integrity checks is not chosen with
:kconfig:option:`CONFIG_FLASH_AREA_CHECK_INTEGRITY_BACKEND` anymore. Instead, the implementation
used (now either Mbed TLS or PSA) is chosen based on :kconfig:option:`CONFIG_PSA_CRYPTO_CLIENT`.
It still defaults to using Mbed TLS (with a smaller footprint than previously) unless the
board is built with TF-M or :kconfig:option:`CONFIG_MBEDTLS_PSA_CRYPTO_C` is enabled. (:github:`73511`)

ZBus
====

Expand Down
10 changes: 4 additions & 6 deletions subsys/mgmt/updatehub/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: Apache-2.0

menuconfig UPDATEHUB
bool"UpdateHub Firmware Over-the-Air support"
bool "UpdateHub Firmware Over-the-Air support"
depends on FLASH
depends on REBOOT
depends on IMG_MANAGER
Expand All @@ -17,6 +17,8 @@ menuconfig UPDATEHUB
select REQUIRES_FULL_LIBC
select IMG_ENABLE_IMAGE_CHECK
select MPU_ALLOW_FLASH_WRITE
select MBEDTLS if !BUILD_WITH_TFM
select MBEDTLS_SHA256 if !PSA_CRYPTO_CLIENT
help
UpdateHub is an enterprise-grade solution which makes simple to
remotely update all your embedded devices in the field. It
Expand Down Expand Up @@ -69,7 +71,7 @@ config UPDATEHUB_SHELL
Activate shell module that provides UpdateHub commands like

config UPDATEHUB_DTLS
bool"Activate communication CoAPS/DTLS"
bool "Activate communication CoAPS/DTLS"
select MBEDTLS
select MBEDTLS_ENABLE_HEAP
select NET_SOCKETS_SOCKOPT_TLS
Expand Down Expand Up @@ -146,10 +148,6 @@ 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.
Expand Down
4 changes: 2 additions & 2 deletions subsys/mgmt/updatehub/updatehub.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static struct updatehub_context {
struct coap_block_context block;
struct k_sem semaphore;
struct updatehub_storage_context storage_ctx;
struct updatehub_crypto_context crypto_ctx;
updatehub_crypto_context_t crypto_ctx;
enum updatehub_response code_status;
uint8_t hash[SHA256_BIN_DIGEST_SIZE];
uint8_t uri_path[MAX_PATH_SIZE];
Expand Down Expand Up @@ -113,7 +113,7 @@ static void prepare_fds(void)

static int metadata_hash_get(char *metadata)
{
struct updatehub_crypto_context local_crypto_ctx;
updatehub_crypto_context_t local_crypto_ctx;

if (updatehub_integrity_init(&local_crypto_ctx)) {
return -1;
Expand Down
100 changes: 44 additions & 56 deletions subsys/mgmt/updatehub/updatehub_integrity.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ LOG_MODULE_DECLARE(updatehub, CONFIG_UPDATEHUB_LOG_LEVEL);

#include "updatehub_integrity.h"

int updatehub_integrity_init(struct updatehub_crypto_context *ctx)
#if defined(CONFIG_PSA_CRYPTO_CLIENT)
#define SUCCESS_VALUE PSA_SUCCESS
#else
#define SUCCESS_VALUE 0
#endif

int updatehub_integrity_init(updatehub_crypto_context_t *ctx)
{
int ret;

Expand All @@ -18,43 +24,22 @@ int updatehub_integrity_init(struct updatehub_crypto_context *ctx)
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");
#if defined(CONFIG_PSA_CRYPTO_CLIENT)
*ctx = psa_hash_operation_init();
ret = psa_hash_setup(ctx, PSA_ALG_SHA_256);
#else
mbedtls_sha256_init(ctx);
ret = mbedtls_sha256_starts(ctx, false);
#endif
if (ret != SUCCESS_VALUE) {
LOG_DBG("Failed to %s SHA-256 operation. (%d)", "set up", ret);
return -EFAULT;
}
#endif

return 0;
}

int updatehub_integrity_update(struct updatehub_crypto_context *ctx,
int updatehub_integrity_update(updatehub_crypto_context_t *ctx,
const uint8_t *buffer, const uint32_t len)
{
int ret;
Expand All @@ -68,24 +53,27 @@ int updatehub_integrity_update(struct updatehub_crypto_context *ctx,
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;
#if defined(CONFIG_PSA_CRYPTO_CLIENT)
ret = psa_hash_update(ctx, buffer, len);
if (ret != PSA_SUCCESS) {
psa_hash_abort(ctx);
}
#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;
#else
ret = mbedtls_sha256_update(ctx, buffer, len);
if (ret != 0) {
mbedtls_sha256_free(ctx);
}
#endif

if (ret != SUCCESS_VALUE) {
LOG_DBG("Failed to %s SHA-256 operation. (%d)", "update", ret);
return -EFAULT;
}

return 0;
}

int updatehub_integrity_finish(struct updatehub_crypto_context *ctx,
int updatehub_integrity_finish(updatehub_crypto_context_t *ctx,
uint8_t *hash, const uint32_t size)
{
int ret;
Expand All @@ -94,26 +82,26 @@ int updatehub_integrity_finish(struct updatehub_crypto_context *ctx,
return -EINVAL;
}

#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS)
if (size < mbedtls_md_get_size(ctx->md_info)) {
if (size < SHA256_BIN_DIGEST_SIZE) {
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;
}
#if defined(CONFIG_PSA_CRYPTO_CLIENT)
size_t hash_len;

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;
ret = psa_hash_finish(ctx, hash, size, &hash_len);
if (ret != PSA_SUCCESS) {
psa_hash_abort(ctx);
}
#else
ret = mbedtls_sha256_finish(ctx, hash);
mbedtls_sha256_free(ctx);
#endif
if (ret != SUCCESS_VALUE) {
LOG_DBG("Failed to %s SHA-256 operation. (%d)", "finish", ret);
return -EFAULT;
}

return 0;
}
26 changes: 10 additions & 16 deletions subsys/mgmt/updatehub/updatehub_integrity.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@
#ifndef __UPDATEHUB_INTEGRITY_H__
#define __UPDATEHUB_INTEGRITY_H__

#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS)
#include <mbedtls/md.h>
#elif defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC)
#include <tinycrypt/sha256.h>
#include <tinycrypt/constants.h>
#if defined(CONFIG_PSA_CRYPTO_CLIENT)
#include <psa/crypto.h>
#else
#error "Integrity check method not defined"
#include <mbedtls/sha256.h>
#endif

#ifdef __cplusplus
Expand All @@ -23,19 +20,16 @@ extern "C" {
#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;
#if defined(CONFIG_PSA_CRYPTO_CLIENT)
typedef psa_hash_operation_t updatehub_crypto_context_t;
#else
typedef mbedtls_sha256_context updatehub_crypto_context_t;
#endif
};

int updatehub_integrity_init(struct updatehub_crypto_context *ctx);
int updatehub_integrity_update(struct updatehub_crypto_context *ctx,
int updatehub_integrity_init(updatehub_crypto_context_t *ctx);
int updatehub_integrity_update(updatehub_crypto_context_t *ctx,
const uint8_t *buffer, const uint32_t len);
int updatehub_integrity_finish(struct updatehub_crypto_context *ctx,
int updatehub_integrity_finish(updatehub_crypto_context_t *ctx,
uint8_t *hash, const uint32_t size);

#ifdef __cplusplus
Expand Down

0 comments on commit a04ff83

Please sign in to comment.