subsys/mgmt/hawkbit: Check the hash of stored firmware
Previously, the hash of the firmware is checked while we are downloading the firmware. This isn't ideal as the validity of the firmware written into the flash is not verified and can be corrupted. Furthermore, checking while downloading will have an negative impact to the download speed as the CPU need to do more work during the data transfer. This PR removes the previous verify-hash-while-download implementation and use the flash_img_check API instead. Signed-off-by: Yong Cong Sin <yongcong.sin@gmail.com>
This commit is contained in:
parent
77d829e31e
commit
313c49ec21
2 changed files with 17 additions and 48 deletions
|
@ -7,8 +7,6 @@ menuconfig HAWKBIT
|
||||||
select FLASH
|
select FLASH
|
||||||
select REBOOT
|
select REBOOT
|
||||||
select HWINFO
|
select HWINFO
|
||||||
select MBEDTLS
|
|
||||||
select MBEDTLS_ENABLE_HEAP
|
|
||||||
select NET_TCP
|
select NET_TCP
|
||||||
select NET_SOCKETS
|
select NET_SOCKETS
|
||||||
select IMG_MANAGER
|
select IMG_MANAGER
|
||||||
|
@ -18,6 +16,7 @@ menuconfig HAWKBIT
|
||||||
select JSON_LIBRARY
|
select JSON_LIBRARY
|
||||||
select BOOTLOADER_MCUBOOT
|
select BOOTLOADER_MCUBOOT
|
||||||
select MPU_ALLOW_FLASH_WRITE
|
select MPU_ALLOW_FLASH_WRITE
|
||||||
|
select IMG_ENABLE_IMAGE_CHECK
|
||||||
select IMG_ERASE_PROGRESSIVELY
|
select IMG_ERASE_PROGRESSIVELY
|
||||||
select NET_SOCKETS_POSIX_NAMES
|
select NET_SOCKETS_POSIX_NAMES
|
||||||
help
|
help
|
||||||
|
|
|
@ -33,8 +33,6 @@ LOG_MODULE_REGISTER(hawkbit, CONFIG_HAWKBIT_LOG_LEVEL);
|
||||||
#include "mgmt/hawkbit.h"
|
#include "mgmt/hawkbit.h"
|
||||||
#include "hawkbit_firmware.h"
|
#include "hawkbit_firmware.h"
|
||||||
|
|
||||||
#include "mbedtls/md.h"
|
|
||||||
|
|
||||||
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
|
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
|
||||||
#define CA_CERTIFICATE_TAG 1
|
#define CA_CERTIFICATE_TAG 1
|
||||||
#include <net/tls_credentials.h>
|
#include <net/tls_credentials.h>
|
||||||
|
@ -71,7 +69,6 @@ struct hawkbit_download {
|
||||||
int download_progress;
|
int download_progress;
|
||||||
size_t downloaded_size;
|
size_t downloaded_size;
|
||||||
size_t http_content_size;
|
size_t http_content_size;
|
||||||
mbedtls_md_context_t hash_ctx;
|
|
||||||
uint8_t file_hash[SHA256_HASH_SIZE];
|
uint8_t file_hash[SHA256_HASH_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -805,14 +802,6 @@ static void response_cb(struct http_response *rsp,
|
||||||
body_data = rsp->body_frag_start;
|
body_data = rsp->body_frag_start;
|
||||||
body_len = rsp->body_frag_len;
|
body_len = rsp->body_frag_len;
|
||||||
|
|
||||||
ret = mbedtls_md_update(&hb_context.dl.hash_ctx, body_data,
|
|
||||||
body_len);
|
|
||||||
if (ret != 0) {
|
|
||||||
LOG_ERR("mbedTLS md update error: %d", ret);
|
|
||||||
hb_context.code_status = HAWKBIT_DOWNLOAD_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = flash_img_buffered_write(
|
ret = flash_img_buffered_write(
|
||||||
&hb_context.flash_ctx, body_data, body_len,
|
&hb_context.flash_ctx, body_data, body_len,
|
||||||
final_data == HTTP_DATA_FINAL);
|
final_data == HTTP_DATA_FINAL);
|
||||||
|
@ -1037,8 +1026,7 @@ enum hawkbit_response hawkbit_probe(void)
|
||||||
int ret;
|
int ret;
|
||||||
int32_t action_id;
|
int32_t action_id;
|
||||||
int32_t file_size = 0;
|
int32_t file_size = 0;
|
||||||
uint8_t response_hash[SHA256_HASH_SIZE] = { 0 };
|
struct flash_img_check fic;
|
||||||
const mbedtls_md_info_t *hash_info;
|
|
||||||
char device_id[DEVICE_ID_HEX_MAX_SIZE] = { 0 },
|
char device_id[DEVICE_ID_HEX_MAX_SIZE] = { 0 },
|
||||||
cancel_base[CANCEL_BASE_SIZE] = { 0 },
|
cancel_base[CANCEL_BASE_SIZE] = { 0 },
|
||||||
download_http[DOWNLOAD_HTTP_SIZE] = { 0 },
|
download_http[DOWNLOAD_HTTP_SIZE] = { 0 },
|
||||||
|
@ -1228,67 +1216,49 @@ enum hawkbit_response hawkbit_probe(void)
|
||||||
|
|
||||||
flash_img_init(&hb_context.flash_ctx);
|
flash_img_init(&hb_context.flash_ctx);
|
||||||
|
|
||||||
hash_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
|
||||||
if (!hash_info) {
|
|
||||||
LOG_ERR("Unable to request hash type from mbedTLS");
|
|
||||||
hb_context.code_status = HAWKBIT_METADATA_ERROR;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
mbedtls_md_init(&hb_context.dl.hash_ctx);
|
|
||||||
if (mbedtls_md_setup(&hb_context.dl.hash_ctx, hash_info, 0) < 0) {
|
|
||||||
LOG_ERR("Can't setup mbedTLS hash engine");
|
|
||||||
mbedtls_md_free(&hb_context.dl.hash_ctx);
|
|
||||||
hb_context.code_status = HAWKBIT_METADATA_ERROR;
|
|
||||||
goto free_md;
|
|
||||||
}
|
|
||||||
|
|
||||||
mbedtls_md_starts(&hb_context.dl.hash_ctx);
|
|
||||||
|
|
||||||
ret = (int)send_request(HTTP_GET, HAWKBIT_DOWNLOAD,
|
ret = (int)send_request(HTTP_GET, HAWKBIT_DOWNLOAD,
|
||||||
HAWKBIT_STATUS_FINISHED_NONE,
|
HAWKBIT_STATUS_FINISHED_NONE,
|
||||||
HAWKBIT_STATUS_EXEC_NONE);
|
HAWKBIT_STATUS_EXEC_NONE);
|
||||||
|
|
||||||
mbedtls_md_finish(&hb_context.dl.hash_ctx, response_hash);
|
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
LOG_ERR("Send request failed (HAWKBIT_DOWNLOAD): %d", ret);
|
LOG_ERR("Send request failed (HAWKBIT_DOWNLOAD): %d", ret);
|
||||||
hb_context.code_status = HAWKBIT_NETWORKING_ERROR;
|
hb_context.code_status = HAWKBIT_NETWORKING_ERROR;
|
||||||
goto free_md;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hb_context.code_status == HAWKBIT_DOWNLOAD_ERROR) {
|
if (hb_context.code_status == HAWKBIT_DOWNLOAD_ERROR) {
|
||||||
goto free_md;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if download finished */
|
||||||
if (!hb_context.final_data_received) {
|
if (!hb_context.final_data_received) {
|
||||||
LOG_ERR("Download is not complete");
|
LOG_ERR("Download is not complete");
|
||||||
hb_context.code_status = HAWKBIT_DOWNLOAD_ERROR;
|
hb_context.code_status = HAWKBIT_DOWNLOAD_ERROR;
|
||||||
goto free_md;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memcmp(response_hash, hb_context.dl.file_hash, mbedtls_md_get_size(hash_info)) != 0) {
|
/* Verify the hash of the stored firmware */
|
||||||
LOG_ERR("Hash mismatch");
|
fic.match = hb_context.dl.file_hash;
|
||||||
LOG_HEXDUMP_DBG(response_hash, sizeof(response_hash), "resp");
|
fic.clen = hb_context.dl.downloaded_size;
|
||||||
LOG_HEXDUMP_DBG(hb_context.dl.file_hash, sizeof(hb_context.dl.file_hash), "file");
|
if (flash_img_check(&hb_context.flash_ctx, &fic, FLASH_AREA_ID(image_1))) {
|
||||||
|
LOG_ERR("Firmware - flash validation has failed");
|
||||||
hb_context.code_status = HAWKBIT_DOWNLOAD_ERROR;
|
hb_context.code_status = HAWKBIT_DOWNLOAD_ERROR;
|
||||||
goto free_md;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Request mcuboot to upgrade */
|
||||||
if (boot_request_upgrade(BOOT_UPGRADE_TEST)) {
|
if (boot_request_upgrade(BOOT_UPGRADE_TEST)) {
|
||||||
LOG_ERR("Failed to mark the image in slot 1 as pending");
|
LOG_ERR("Failed to mark the image in slot 1 as pending");
|
||||||
hb_context.code_status = HAWKBIT_DOWNLOAD_ERROR;
|
hb_context.code_status = HAWKBIT_DOWNLOAD_ERROR;
|
||||||
goto free_md;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_context.code_status = HAWKBIT_UPDATE_INSTALLED;
|
/* If everything is successful */
|
||||||
hawkbit_device_acid_update(hb_context.json_action_id);
|
hb_context.code_status = HAWKBIT_UPDATE_INSTALLED;
|
||||||
|
hawkbit_device_acid_update(hb_context.json_action_id);
|
||||||
|
|
||||||
hb_context.dl.http_content_size = 0;
|
hb_context.dl.http_content_size = 0;
|
||||||
|
|
||||||
free_md:
|
|
||||||
mbedtls_md_free(&hb_context.dl.hash_ctx);
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
cleanup_connection();
|
cleanup_connection();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue