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 <gerson.budke@ossystems.com.br>
This commit is contained in:
parent
358ad431b8
commit
313049e325
5 changed files with 186 additions and 21 deletions
|
@ -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(
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 <zephyr/net/dns_resolve.h>
|
||||
#include <zephyr/drivers/flash.h>
|
||||
#include <zephyr/sys/reboot.h>
|
||||
#include <tinycrypt/sha256.h>
|
||||
#include <zephyr/data/json.h>
|
||||
#include <zephyr/storage/flash_map.h>
|
||||
|
||||
|
@ -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;
|
||||
|
|
119
subsys/mgmt/updatehub/updatehub_integrity.c
Normal file
119
subsys/mgmt/updatehub/updatehub_integrity.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (c) 2023 O.S.Systems
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
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;
|
||||
}
|
45
subsys/mgmt/updatehub/updatehub_integrity.h
Normal file
45
subsys/mgmt/updatehub/updatehub_integrity.h
Normal file
|
@ -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 <mbedtls/md.h>
|
||||
#elif defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC)
|
||||
#include <tinycrypt/sha256.h>
|
||||
#include <tinycrypt/constants.h>
|
||||
#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__ */
|
Loading…
Add table
Add a link
Reference in a new issue