mgmt: mcumgr: replace Tinycrypt by PSA

As part of ongoing work to move away from TinyCrypt and towards PSA
(#43712), make fs_mgmt use either PSA (when available) or MbedTLS
(as a fallback) for SHA-256.

The use of PSA is guarded by CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT
which requires a locally-built PSA core for devices without TF-M.

Signed-off-by: Tomi Fontanilles <tomi.fontanilles@nordicsemi.no>
This commit is contained in:
Tomi Fontanilles 2024-04-25 16:16:44 +03:00 committed by Anas Nashif
commit 6002abe519
6 changed files with 87 additions and 86 deletions

View file

@ -370,6 +370,12 @@ LoRaWAN
MCUmgr
======
* The support for SHA-256 (when using checksum/hash functions), previously provided
by either TinyCrypt or MbedTLS, is now provided by either PSA or MbedTLS.
PSA is the recommended API going forward, however, if it is not already enabled
(:kconfig:option:`CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT`) and you have tight code size
constraints, you may be able to save 1.3 KB by using MbedTLS instead.
Modem
=====

View file

@ -125,7 +125,8 @@ config MCUMGR_GRP_FS_CHECKSUM_IEEE_CRC32
config MCUMGR_GRP_FS_HASH_SHA256
bool "SHA256 hash support"
depends on TINYCRYPT_SHA256 || MBEDTLS_MAC_SHA256_ENABLED
depends on BUILD_WITH_TFM || MBEDTLS_MAC_SHA256_ENABLED
select PSA_WANT_ALG_SHA_256 if BUILD_WITH_TFM
help
Enable SHA256 hash support for MCUmgr.

View file

@ -13,33 +13,41 @@
#include <mgmt/mcumgr/grp/fs_mgmt/fs_mgmt_config.h>
#include <mgmt/mcumgr/grp/fs_mgmt/fs_mgmt_hash_checksum_sha256.h>
#if defined(CONFIG_TINYCRYPT_SHA256)
#include <tinycrypt/constants.h>
#include <tinycrypt/sha256.h>
#ifdef CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT
#include <psa/crypto.h>
typedef psa_hash_operation_t hash_ctx_t;
#define SUCCESS_VALUE PSA_SUCCESS
#else
#include <mbedtls/md.h>
#include <mbedtls/sha256.h>
#endif
typedef mbedtls_sha256_context hash_ctx_t;
#define SUCCESS_VALUE 0
#endif /* CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT */
#define SHA256_DIGEST_SIZE 32
#if defined(CONFIG_TINYCRYPT_SHA256)
/* Tinycrypt SHA256 implementation */
/* The API that the different hash implementations provide further down. */
static int hash_setup(hash_ctx_t *);
static int hash_update(hash_ctx_t *, const uint8_t *input, size_t ilen);
static int hash_finish(hash_ctx_t *, uint8_t *output);
static void hash_teardown(hash_ctx_t *);
static int fs_mgmt_hash_checksum_sha256(struct fs_file_t *file, uint8_t *output,
size_t *out_len, size_t len)
{
int rc = 0;
int rc = MGMT_ERR_EUNKNOWN;
ssize_t bytes_read = 0;
size_t read_size = CONFIG_MCUMGR_GRP_FS_CHECKSUM_HASH_CHUNK_SIZE;
uint8_t buffer[CONFIG_MCUMGR_GRP_FS_CHECKSUM_HASH_CHUNK_SIZE];
struct tc_sha256_state_struct sha;
hash_ctx_t hash_ctx;
/* Clear variables prior to calculation */
*out_len = 0;
memset(output, 0, SHA256_DIGEST_SIZE);
if (tc_sha256_init(&sha) != TC_CRYPTO_SUCCESS) {
return MGMT_ERR_EUNKNOWN;
if (hash_setup(&hash_ctx) != SUCCESS_VALUE) {
goto teardown;
}
/* Read all data from file and add to SHA256 hash calculation */
@ -52,11 +60,11 @@ static int fs_mgmt_hash_checksum_sha256(struct fs_file_t *file, uint8_t *output,
bytes_read = fs_read(file, buffer, read_size);
if (bytes_read < 0) {
/* Failed to read file data, pass generic unknown error back */
return MGMT_ERR_EUNKNOWN;
/* Failed to read file data */
goto teardown;
} else if (bytes_read > 0) {
if (tc_sha256_update(&sha, buffer, bytes_read) != TC_CRYPTO_SUCCESS) {
return MGMT_ERR_EUNKNOWN;
if (hash_update(&hash_ctx, buffer, bytes_read) != SUCCESS_VALUE) {
goto teardown;
}
*out_len += bytes_read;
@ -64,74 +72,15 @@ static int fs_mgmt_hash_checksum_sha256(struct fs_file_t *file, uint8_t *output,
} while (bytes_read > 0 && *out_len < len);
/* Finalise SHA256 hash calculation and store output in provided output buffer */
if (tc_sha256_final(output, &sha) != TC_CRYPTO_SUCCESS) {
rc = MGMT_ERR_EUNKNOWN;
if (hash_finish(&hash_ctx, output) == SUCCESS_VALUE) {
rc = 0;
}
teardown:
hash_teardown(&hash_ctx);
return rc;
}
#else
/* mbedtls SHA256 implementation */
static int fs_mgmt_hash_checksum_sha256(struct fs_file_t *file, uint8_t *output,
size_t *out_len, size_t len)
{
int rc = 0;
ssize_t bytes_read = 0;
size_t read_size = CONFIG_MCUMGR_GRP_FS_CHECKSUM_HASH_CHUNK_SIZE;
uint8_t buffer[CONFIG_MCUMGR_GRP_FS_CHECKSUM_HASH_CHUNK_SIZE];
mbedtls_md_context_t mbed_hash_ctx;
const mbedtls_md_info_t *mbed_hash_info;
/* Clear variables prior to calculation */
*out_len = 0;
memset(output, 0, SHA256_DIGEST_SIZE);
mbed_hash_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
mbedtls_md_init(&mbed_hash_ctx);
if (mbedtls_md_setup(&mbed_hash_ctx, mbed_hash_info, 0) != 0) {
return MGMT_ERR_EUNKNOWN;
}
if (mbedtls_md_starts(&mbed_hash_ctx)) {
rc = MGMT_ERR_EUNKNOWN;
goto error;
}
/* Read all data from file and add to SHA256 hash calculation */
do {
if ((read_size + *out_len) >= len) {
/* Limit read size to size of requested data */
read_size = len - *out_len;
}
bytes_read = fs_read(file, buffer, read_size);
if (bytes_read < 0) {
/* Failed to read file data, pass generic unknown error back */
rc = MGMT_ERR_EUNKNOWN;
goto error;
} else if (bytes_read > 0) {
if (mbedtls_md_update(&mbed_hash_ctx, buffer, bytes_read) != 0) {
rc = MGMT_ERR_EUNKNOWN;
goto error;
}
*out_len += bytes_read;
}
} while (bytes_read > 0 && *out_len < len);
/* Finalise SHA256 hash calculation and store output in provided output buffer */
if (mbedtls_md_finish(&mbed_hash_ctx, output) != 0) {
rc = MGMT_ERR_EUNKNOWN;
}
error:
mbedtls_md_free(&mbed_hash_ctx);
return rc;
}
#endif
static struct fs_mgmt_hash_checksum_group sha256 = {
.group_name = "sha256",
@ -149,3 +98,47 @@ void fs_mgmt_hash_checksum_unregister_sha256(void)
{
fs_mgmt_hash_checksum_unregister_group(&sha256);
}
#ifdef CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT
static int hash_setup(psa_hash_operation_t *ctx)
{
*ctx = psa_hash_operation_init();
return psa_hash_setup(ctx, PSA_ALG_SHA_256);
}
static int hash_update(psa_hash_operation_t *ctx, const uint8_t *input, size_t ilen)
{
return psa_hash_update(ctx, input, ilen);
}
static int hash_finish(psa_hash_operation_t *ctx, uint8_t *output)
{
size_t output_length;
return psa_hash_finish(ctx, output, SHA256_DIGEST_SIZE, &output_length);
}
static void hash_teardown(psa_hash_operation_t *ctx)
{
psa_hash_abort(ctx);
}
#else
static int hash_setup(mbedtls_sha256_context *ctx)
{
mbedtls_sha256_init(ctx);
return mbedtls_sha256_starts(ctx, false);
}
static int hash_update(mbedtls_sha256_context *ctx, const uint8_t *input, size_t ilen)
{
return mbedtls_sha256_update(ctx, input, ilen);
}
static int hash_finish(mbedtls_sha256_context *ctx, uint8_t *output)
{
return mbedtls_sha256_finish(ctx, output);
}
static void hash_teardown(mbedtls_sha256_context *ctx)
{
mbedtls_sha256_free(ctx);
}
#endif /* CONFIG_MBEDTLS_PSA_CRYPTO_CLIENT */

View file

@ -4,8 +4,8 @@
# SPDX-License-Identifier: Apache-2.0
#
CONFIG_ZTEST=y
CONFIG_TINYCRYPT=y
CONFIG_TINYCRYPT_SHA256=y
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_MAC_SHA256_ENABLED=y
CONFIG_FILE_SYSTEM=y
CONFIG_BASE64=y
CONFIG_NET_BUF=y

View file

@ -3,7 +3,7 @@
#
# SPDX-License-Identifier: Apache-2.0
#
CONFIG_TINYCRYPT=y
CONFIG_TINYCRYPT_SHA256=y
CONFIG_MCUMGR_GRP_FS_CHECKSUM_IEEE_CRC32=y
CONFIG_MCUMGR_GRP_FS_HASH_SHA256=y
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_MAC_SHA256_ENABLED=y

View file

@ -3,6 +3,7 @@
#
# SPDX-License-Identifier: Apache-2.0
#
CONFIG_TINYCRYPT=y
CONFIG_TINYCRYPT_SHA256=y
CONFIG_MCUMGR_GRP_FS_CHECKSUM_IEEE_CRC32=n
CONFIG_MCUMGR_GRP_FS_HASH_SHA256=y
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_MAC_SHA256_ENABLED=y