diff --git a/boot/bootutil/CMakeLists.txt b/boot/bootutil/CMakeLists.txt index 3d1b32717..950a4c152 100644 --- a/boot/bootutil/CMakeLists.txt +++ b/boot/bootutil/CMakeLists.txt @@ -17,6 +17,9 @@ target_include_directories(bootutil target_sources(bootutil PRIVATE src/boot_record.c + src/bootutil_find_key.c + src/bootutil_img_hash.c + src/bootutil_img_security_cnt.c src/bootutil_misc.c src/bootutil_public.c src/caps.c diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h index 2bd20061d..413ae80c2 100644 --- a/boot/bootutil/include/bootutil/image.h +++ b/boot/bootutil/include/bootutil/image.h @@ -243,6 +243,19 @@ int32_t bootutil_get_img_security_cnt(struct boot_loader_state *state, int slot, const struct flash_area *fap, uint32_t *img_security_cnt); +#if !defined(MCUBOOT_HW_KEY) +int bootutil_find_key(uint8_t *keyhash, uint8_t keyhash_len); +#else +int bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len); +#endif + +int +bootutil_img_hash(struct boot_loader_state *state, + struct image_header *hdr, const struct flash_area *fap, + uint8_t *tmp_buf, uint32_t tmp_buf_sz, uint8_t *hash_result, + uint8_t *seed, int seed_len + ); + #ifdef __cplusplus } #endif diff --git a/boot/bootutil/src/bootutil_find_key.c b/boot/bootutil/src/bootutil_find_key.c new file mode 100644 index 000000000..628f84168 --- /dev/null +++ b/boot/bootutil/src/bootutil_find_key.c @@ -0,0 +1,134 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2017-2019 Linaro LTD + * Copyright (c) 2016-2019 JUUL Labs + * Copyright (c) 2019-2025 Arm Limited + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * Original license: + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include + +#include "bootutil/crypto/sha.h" +#include "bootutil/fault_injection_hardening.h" +#include "bootutil/image.h" +#include "bootutil/sign_key.h" +#include "bootutil_priv.h" +#include "mcuboot_config/mcuboot_config.h" +#include "bootutil/bootutil_log.h" + +BOOT_LOG_MODULE_DECLARE(mcuboot); + +#if defined(MCUBOOT_SIGN_RSA) || \ + defined(MCUBOOT_SIGN_EC256) || \ + defined(MCUBOOT_SIGN_EC384) || \ + defined(MCUBOOT_SIGN_EC) || \ + defined(MCUBOOT_SIGN_ED25519) +#define EXPECTED_SIG_TLV +#else + /* no signing, sha256 digest only */ +#endif + +#ifdef EXPECTED_SIG_TLV +#if !defined(MCUBOOT_BYPASS_KEY_MATCH) +/* Find functions are only needed when key is checked first */ +#if !defined(MCUBOOT_BUILTIN_KEY) +#if !defined(MCUBOOT_HW_KEY) +int bootutil_find_key(uint8_t *keyhash, uint8_t keyhash_len) +{ + bootutil_sha_context sha_ctx; + int i; + const struct bootutil_key *key; + uint8_t hash[IMAGE_HASH_SIZE]; + + BOOT_LOG_DBG("bootutil_find_key"); + + if (keyhash_len > IMAGE_HASH_SIZE) { + return -1; + } + + for (i = 0; i < bootutil_key_cnt; i++) { + key = &bootutil_keys[i]; + bootutil_sha_init(&sha_ctx); + bootutil_sha_update(&sha_ctx, key->key, *key->len); + bootutil_sha_finish(&sha_ctx, hash); + bootutil_sha_drop(&sha_ctx); + if (!memcmp(hash, keyhash, keyhash_len)) { + return i; + } + } + return -1; +} +#else /* !MCUBOOT_HW_KEY */ +extern unsigned int pub_key_len; +int bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len) +{ + bootutil_sha_context sha_ctx; + uint8_t hash[IMAGE_HASH_SIZE]; + uint8_t key_hash[IMAGE_HASH_SIZE]; + size_t key_hash_size = sizeof(key_hash); + int rc; + FIH_DECLARE(fih_rc, FIH_FAILURE); + + BOOT_LOG_DBG("bootutil_find_key: image_index %d", image_index); + + bootutil_sha_init(&sha_ctx); + bootutil_sha_update(&sha_ctx, key, key_len); + bootutil_sha_finish(&sha_ctx, hash); + bootutil_sha_drop(&sha_ctx); + + rc = boot_retrieve_public_key_hash(image_index, key_hash, &key_hash_size); + if (rc) { + return -1; + } + + /* Adding hardening to avoid this potential attack: + * - Image is signed with an arbitrary key and the corresponding public + * key is added as a TLV field. + * - During public key validation (comparing against key-hash read from + * HW) a fault is injected to accept the public key as valid one. + */ + FIH_CALL(boot_fih_memequal, fih_rc, hash, key_hash, key_hash_size); + if (FIH_EQ(fih_rc, FIH_SUCCESS)) { + bootutil_keys[0].key = key; + pub_key_len = key_len; + return 0; + } + + return -1; +} +#endif /* !MCUBOOT_HW_KEY */ +#endif /* !MCUBOOT_BUILTIN_KEY */ + +#else /* !MCUBOOT_BYPASS_KEY_MATCH */ +static inline int +bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len) +{ + (void)image_index; + (void)key; + (void)key_len; + + /* There is only one key, so it always matches */ + return 0; +} +#endif /* !MCUBOOT_BYPASS_KEY_MATCH */ +#endif /* EXPECTED_SIG_TLV */ diff --git a/boot/bootutil/src/bootutil_img_hash.c b/boot/bootutil/src/bootutil_img_hash.c new file mode 100644 index 000000000..ff8340d70 --- /dev/null +++ b/boot/bootutil/src/bootutil_img_hash.c @@ -0,0 +1,199 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2017-2019 Linaro LTD + * Copyright (c) 2016-2019 JUUL Labs + * Copyright (c) 2019-2025 Arm Limited + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * Original license: + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include + +#include "bootutil/crypto/sha.h" +#include "bootutil/image.h" +#include "bootutil_priv.h" +#include "mcuboot_config/mcuboot_config.h" +#include "bootutil/bootutil_log.h" + +BOOT_LOG_MODULE_DECLARE(mcuboot); + +#ifndef MCUBOOT_SIGN_PURE +/* + * Compute SHA hash over the image. + * (SHA384 if ECDSA-P384 is being used, + * SHA256 otherwise). + */ +int +bootutil_img_hash(struct boot_loader_state *state, + struct image_header *hdr, const struct flash_area *fap, + uint8_t *tmp_buf, uint32_t tmp_buf_sz, uint8_t *hash_result, + uint8_t *seed, int seed_len + ) +{ + bootutil_sha_context sha_ctx; + uint32_t size; + uint16_t hdr_size; + uint32_t blk_off; + uint32_t tlv_off; +#if !defined(MCUBOOT_HASH_STORAGE_DIRECTLY) + int rc; + uint32_t off; + uint32_t blk_sz; +#endif +#ifdef MCUBOOT_HASH_STORAGE_DIRECTLY + uintptr_t base = 0; + int fa_ret; +#endif +#if defined(MCUBOOT_ENC_IMAGES) + struct enc_key_data *enc_state; + int image_index; +#endif +#if defined(MCUBOOT_SWAP_USING_OFFSET) + uint32_t sector_off = 0; +#endif + +#if (BOOT_IMAGE_NUMBER == 1) || !defined(MCUBOOT_ENC_IMAGES) || \ + defined(MCUBOOT_RAM_LOAD) + (void)state; + (void)hdr_size; + (void)blk_off; + (void)tlv_off; +#ifdef MCUBOOT_RAM_LOAD + (void)blk_sz; + (void)off; + (void)rc; + (void)fap; + (void)tmp_buf; + (void)tmp_buf_sz; +#endif +#endif + BOOT_LOG_DBG("bootutil_img_hash"); + +#ifdef MCUBOOT_ENC_IMAGES + if (state == NULL) { + enc_state = NULL; + image_index = 0; + } else { + enc_state = BOOT_CURR_ENC(state); + image_index = BOOT_CURR_IMG(state); + } + + /* Encrypted images only exist in the secondary slot */ + if (MUST_DECRYPT(fap, image_index, hdr) && + !boot_enc_valid(enc_state, 1)) { + BOOT_LOG_DBG("bootutil_img_hash: error encrypted image found in primary slot"); + return -1; + } +#endif + +#if defined(MCUBOOT_SWAP_USING_OFFSET) + /* For swap using offset mode, the image starts in the second sector of the upgrade slot, so + * apply the offset when this is needed + */ + sector_off = boot_get_state_secondary_offset(state, fap); +#endif + + bootutil_sha_init(&sha_ctx); + + /* in some cases (split image) the hash is seeded with data from + * the loader image */ + if (seed && (seed_len > 0)) { + bootutil_sha_update(&sha_ctx, seed, seed_len); + } + + /* Hash is computed over image header and image itself. */ + size = hdr_size = hdr->ih_hdr_size; + size += hdr->ih_img_size; + tlv_off = size; + + /* If protected TLVs are present they are also hashed. */ + size += hdr->ih_protect_tlv_size; + +#ifdef MCUBOOT_HASH_STORAGE_DIRECTLY + /* No chunk loading, storage is mapped to address space and can + * be directly given to hashing function. + */ + fa_ret = flash_device_base(flash_area_get_device_id(fap), &base); + if (fa_ret != 0) { + base = 0; + } + + bootutil_sha_update(&sha_ctx, (void *)(base + flash_area_get_off(fap)), size); +#else /* MCUBOOT_HASH_STORAGE_DIRECTLY */ +#ifdef MCUBOOT_RAM_LOAD + bootutil_sha_update(&sha_ctx, + (void*)(IMAGE_RAM_BASE + hdr->ih_load_addr), + size); +#else + for (off = 0; off < size; off += blk_sz) { + blk_sz = size - off; + if (blk_sz > tmp_buf_sz) { + blk_sz = tmp_buf_sz; + } +#ifdef MCUBOOT_ENC_IMAGES + /* The only data that is encrypted in an image is the payload; + * both header and TLVs (when protected) are not. + */ + if ((off < hdr_size) && ((off + blk_sz) > hdr_size)) { + /* read only the header */ + blk_sz = hdr_size - off; + } + if ((off < tlv_off) && ((off + blk_sz) > tlv_off)) { + /* read only up to the end of the image payload */ + blk_sz = tlv_off - off; + } +#endif +#if defined(MCUBOOT_SWAP_USING_OFFSET) + rc = flash_area_read(fap, off + sector_off, tmp_buf, blk_sz); +#else + rc = flash_area_read(fap, off, tmp_buf, blk_sz); +#endif + if (rc) { + bootutil_sha_drop(&sha_ctx); + BOOT_LOG_DBG("bootutil_img_validate Error %d reading data chunk %p %u %u", + rc, fap, off, blk_sz); + return rc; + } +#ifdef MCUBOOT_ENC_IMAGES + if (MUST_DECRYPT(fap, image_index, hdr)) { + /* Only payload is encrypted (area between header and TLVs) */ + int slot = flash_area_id_to_multi_image_slot(image_index, + flash_area_get_id(fap)); + + if (off >= hdr_size && off < tlv_off) { + blk_off = (off - hdr_size) & 0xf; + boot_enc_decrypt(enc_state, slot, off - hdr_size, + blk_sz, blk_off, tmp_buf); + } + } +#endif + bootutil_sha_update(&sha_ctx, tmp_buf, blk_sz); + } +#endif /* MCUBOOT_RAM_LOAD */ +#endif /* MCUBOOT_HASH_STORAGE_DIRECTLY */ + bootutil_sha_finish(&sha_ctx, hash_result); + bootutil_sha_drop(&sha_ctx); + + return 0; +} +#endif /* !MCUBOOT_SIGN_PURE */ diff --git a/boot/bootutil/src/bootutil_img_security_cnt.c b/boot/bootutil/src/bootutil_img_security_cnt.c new file mode 100644 index 000000000..4fa179b5f --- /dev/null +++ b/boot/bootutil/src/bootutil_img_security_cnt.c @@ -0,0 +1,102 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2017-2019 Linaro LTD + * Copyright (c) 2016-2019 JUUL Labs + * Copyright (c) 2019-2025 Arm Limited + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * Original license: + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include + +#include "bootutil/image.h" +#include "bootutil/security_cnt.h" +#include "bootutil_priv.h" + +#include "mcuboot_config/mcuboot_config.h" + +/** + * Reads the value of an image's security counter. + * + * @param state Pointer to the boot state object. + * @param slot Slot of the current image to get the security counter of. + * @param fap Pointer to a description structure of the image's + * flash area. + * @param security_cnt Pointer to store the security counter value. + * + * @return 0 on success; nonzero on failure. + */ +int32_t +bootutil_get_img_security_cnt(struct boot_loader_state *state, int slot, + const struct flash_area *fap, + uint32_t *img_security_cnt) +{ + struct image_tlv_iter it; + uint32_t off; + uint16_t len; + int32_t rc; + + if ((state == NULL) || + (boot_img_hdr(state, slot) == NULL) || + (fap == NULL) || + (img_security_cnt == NULL)) { + /* Invalid parameter. */ + return BOOT_EBADARGS; + } + + /* The security counter TLV is in the protected part of the TLV area. */ + if (boot_img_hdr(state, slot)->ih_protect_tlv_size == 0) { + return BOOT_EBADIMAGE; + } + +#if defined(MCUBOOT_SWAP_USING_OFFSET) + it.start_off = boot_get_state_secondary_offset(state, fap); +#endif + + rc = bootutil_tlv_iter_begin(&it, boot_img_hdr(state, slot), fap, IMAGE_TLV_SEC_CNT, true); + if (rc) { + return rc; + } + + /* Traverse through the protected TLV area to find + * the security counter TLV. + */ + + rc = bootutil_tlv_iter_next(&it, &off, &len, NULL); + if (rc != 0) { + /* Security counter TLV has not been found. */ + return -1; + } + + if (len != sizeof(*img_security_cnt)) { + /* Security counter is not valid. */ + return BOOT_EBADIMAGE; + } + + rc = LOAD_IMAGE_DATA(boot_img_hdr(state, slot), fap, off, img_security_cnt, len); + if (rc != 0) { + return BOOT_EFLASH; + } + + return 0; +} diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 4fdd3d8dc..7f45d8e02 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -57,167 +57,6 @@ BOOT_LOG_MODULE_DECLARE(mcuboot); #include "bootutil_priv.h" -#ifndef MCUBOOT_SIGN_PURE -/* - * Compute SHA hash over the image. - * (SHA384 if ECDSA-P384 is being used, - * SHA256 otherwise). - */ -static int -bootutil_img_hash(struct boot_loader_state *state, - struct image_header *hdr, const struct flash_area *fap, - uint8_t *tmp_buf, uint32_t tmp_buf_sz, uint8_t *hash_result, - uint8_t *seed, int seed_len - ) -{ - bootutil_sha_context sha_ctx; - uint32_t size; - uint16_t hdr_size; - uint32_t blk_off; - uint32_t tlv_off; -#if !defined(MCUBOOT_HASH_STORAGE_DIRECTLY) - int rc; - uint32_t off; - uint32_t blk_sz; -#endif -#ifdef MCUBOOT_HASH_STORAGE_DIRECTLY - uintptr_t base = 0; - int fa_ret; -#endif -#if defined(MCUBOOT_ENC_IMAGES) - struct enc_key_data *enc_state; - int image_index; -#endif -#if defined(MCUBOOT_SWAP_USING_OFFSET) - uint32_t sector_off = 0; -#endif - -#if (BOOT_IMAGE_NUMBER == 1) || !defined(MCUBOOT_ENC_IMAGES) || \ - defined(MCUBOOT_RAM_LOAD) - (void)state; - (void)hdr_size; - (void)blk_off; - (void)tlv_off; -#ifdef MCUBOOT_RAM_LOAD - (void)blk_sz; - (void)off; - (void)rc; - (void)fap; - (void)tmp_buf; - (void)tmp_buf_sz; -#endif -#endif - BOOT_LOG_DBG("bootutil_img_hash"); - -#ifdef MCUBOOT_ENC_IMAGES - if (state == NULL) { - enc_state = NULL; - image_index = 0; - } else { - enc_state = BOOT_CURR_ENC(state); - image_index = BOOT_CURR_IMG(state); - } - - /* Encrypted images only exist in the secondary slot */ - if (MUST_DECRYPT(fap, image_index, hdr) && - !boot_enc_valid(enc_state, 1)) { - BOOT_LOG_DBG("bootutil_img_hash: error encrypted image found in primary slot"); - return -1; - } -#endif - -#if defined(MCUBOOT_SWAP_USING_OFFSET) - /* For swap using offset mode, the image starts in the second sector of the upgrade slot, so - * apply the offset when this is needed - */ - sector_off = boot_get_state_secondary_offset(state, fap); -#endif - - bootutil_sha_init(&sha_ctx); - - /* in some cases (split image) the hash is seeded with data from - * the loader image */ - if (seed && (seed_len > 0)) { - bootutil_sha_update(&sha_ctx, seed, seed_len); - } - - /* Hash is computed over image header and image itself. */ - size = hdr_size = hdr->ih_hdr_size; - size += hdr->ih_img_size; - tlv_off = size; - - /* If protected TLVs are present they are also hashed. */ - size += hdr->ih_protect_tlv_size; - -#ifdef MCUBOOT_HASH_STORAGE_DIRECTLY - /* No chunk loading, storage is mapped to address space and can - * be directly given to hashing function. - */ - fa_ret = flash_device_base(flash_area_get_device_id(fap), &base); - if (fa_ret != 0) { - base = 0; - } - - bootutil_sha_update(&sha_ctx, (void *)(base + flash_area_get_off(fap)), size); -#else /* MCUBOOT_HASH_STORAGE_DIRECTLY */ -#ifdef MCUBOOT_RAM_LOAD - bootutil_sha_update(&sha_ctx, - (void*)(IMAGE_RAM_BASE + hdr->ih_load_addr), - size); -#else - for (off = 0; off < size; off += blk_sz) { - blk_sz = size - off; - if (blk_sz > tmp_buf_sz) { - blk_sz = tmp_buf_sz; - } -#ifdef MCUBOOT_ENC_IMAGES - /* The only data that is encrypted in an image is the payload; - * both header and TLVs (when protected) are not. - */ - if ((off < hdr_size) && ((off + blk_sz) > hdr_size)) { - /* read only the header */ - blk_sz = hdr_size - off; - } - if ((off < tlv_off) && ((off + blk_sz) > tlv_off)) { - /* read only up to the end of the image payload */ - blk_sz = tlv_off - off; - } -#endif -#if defined(MCUBOOT_SWAP_USING_OFFSET) - rc = flash_area_read(fap, off + sector_off, tmp_buf, blk_sz); -#else - rc = flash_area_read(fap, off, tmp_buf, blk_sz); -#endif - if (rc) { - bootutil_sha_drop(&sha_ctx); - BOOT_LOG_DBG("bootutil_img_validate Error %d reading data chunk %p %u %u", - rc, fap, off, blk_sz); - return rc; - } -#ifdef MCUBOOT_ENC_IMAGES - if (MUST_DECRYPT(fap, image_index, hdr)) { - /* Only payload is encrypted (area between header and TLVs) */ - int slot = flash_area_id_to_multi_image_slot(image_index, - flash_area_get_id(fap)); - - if (off >= hdr_size && off < tlv_off) { - blk_off = (off - hdr_size) & 0xf; - boot_enc_decrypt(enc_state, slot, off - hdr_size, - blk_sz, blk_off, tmp_buf); - } - } -#endif - bootutil_sha_update(&sha_ctx, tmp_buf, blk_sz); - } -#endif /* MCUBOOT_RAM_LOAD */ -#endif /* MCUBOOT_HASH_STORAGE_DIRECTLY */ - bootutil_sha_finish(&sha_ctx, hash_result); - bootutil_sha_drop(&sha_ctx); - - return 0; -} -#endif - /* * Currently, we only support being able to verify one type of * signature, because there is a single verification function that we @@ -275,156 +114,8 @@ bootutil_img_hash(struct boot_loader_state *state, # define EXPECTED_KEY_TLV IMAGE_TLV_PUBKEY # define KEY_BUF_SIZE (SIG_BUF_SIZE + 24) #endif /* !MCUBOOT_HW_KEY */ - -#if !defined(MCUBOOT_BYPASS_KEY_MATCH) -/* Find functions are only needed when key is checked first */ -#if !defined(MCUBOOT_HW_KEY) -static int -bootutil_find_key(uint8_t *keyhash, uint8_t keyhash_len) -{ - bootutil_sha_context sha_ctx; - int i; - const struct bootutil_key *key; - uint8_t hash[IMAGE_HASH_SIZE]; - - BOOT_LOG_DBG("bootutil_find_key"); - - if (keyhash_len > IMAGE_HASH_SIZE) { - return -1; - } - - for (i = 0; i < bootutil_key_cnt; i++) { - key = &bootutil_keys[i]; - bootutil_sha_init(&sha_ctx); - bootutil_sha_update(&sha_ctx, key->key, *key->len); - bootutil_sha_finish(&sha_ctx, hash); - bootutil_sha_drop(&sha_ctx); - if (!memcmp(hash, keyhash, keyhash_len)) { - return i; - } - } - return -1; -} -#else /* !MCUBOOT_HW_KEY */ -extern unsigned int pub_key_len; -static int -bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len) -{ - bootutil_sha_context sha_ctx; - uint8_t hash[IMAGE_HASH_SIZE]; - uint8_t key_hash[IMAGE_HASH_SIZE]; - size_t key_hash_size = sizeof(key_hash); - int rc; - FIH_DECLARE(fih_rc, FIH_FAILURE); - - BOOT_LOG_DBG("bootutil_find_key: image_index %d", image_index); - - bootutil_sha_init(&sha_ctx); - bootutil_sha_update(&sha_ctx, key, key_len); - bootutil_sha_finish(&sha_ctx, hash); - bootutil_sha_drop(&sha_ctx); - - rc = boot_retrieve_public_key_hash(image_index, key_hash, &key_hash_size); - if (rc) { - return -1; - } - - /* Adding hardening to avoid this potential attack: - * - Image is signed with an arbitrary key and the corresponding public - * key is added as a TLV field. - * - During public key validation (comparing against key-hash read from - * HW) a fault is injected to accept the public key as valid one. - */ - FIH_CALL(boot_fih_memequal, fih_rc, hash, key_hash, key_hash_size); - if (FIH_EQ(fih_rc, FIH_SUCCESS)) { - bootutil_keys[0].key = key; - pub_key_len = key_len; - return 0; - } - - return -1; -} -#endif /* !MCUBOOT_HW_KEY */ #endif /* !MCUBOOT_BUILTIN_KEY */ #endif /* EXPECTED_SIG_TLV */ -#else /* !MCUBOOT_BYPASS_KEY_MATCH */ -static inline int -bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len) -{ - (void)image_index; - (void)key; - (void)key_len; - - /* There is only one key, so it always matches */ - return 0; -} -#endif /* !MCUBOOT_BYPASS_KEY_MATCH */ - -/** - * Reads the value of an image's security counter. - * - * @param state Pointer to the boot state object. - * @param slot Slot of the current image to get the security counter of. - * @param fap Pointer to a description structure of the image's - * flash area. - * @param security_cnt Pointer to store the security counter value. - * - * @return 0 on success; nonzero on failure. - */ -int32_t -bootutil_get_img_security_cnt(struct boot_loader_state *state, int slot, - const struct flash_area *fap, - uint32_t *img_security_cnt) -{ - struct image_tlv_iter it; - uint32_t off; - uint16_t len; - int32_t rc; - - if ((state == NULL) || - (boot_img_hdr(state, slot) == NULL) || - (fap == NULL) || - (img_security_cnt == NULL)) { - /* Invalid parameter. */ - return BOOT_EBADARGS; - } - - /* The security counter TLV is in the protected part of the TLV area. */ - if (boot_img_hdr(state, slot)->ih_protect_tlv_size == 0) { - return BOOT_EBADIMAGE; - } - -#if defined(MCUBOOT_SWAP_USING_OFFSET) - it.start_off = boot_get_state_secondary_offset(state, fap); -#endif - - rc = bootutil_tlv_iter_begin(&it, boot_img_hdr(state, slot), fap, IMAGE_TLV_SEC_CNT, true); - if (rc) { - return rc; - } - - /* Traverse through the protected TLV area to find - * the security counter TLV. - */ - - rc = bootutil_tlv_iter_next(&it, &off, &len, NULL); - if (rc != 0) { - /* Security counter TLV has not been found. */ - return -1; - } - - if (len != sizeof(*img_security_cnt)) { - /* Security counter is not valid. */ - return BOOT_EBADIMAGE; - } - - rc = LOAD_IMAGE_DATA(boot_img_hdr(state, slot), fap, off, img_security_cnt, len); - if (rc != 0) { - return BOOT_EFLASH; - } - - return 0; -} #if defined(MCUBOOT_SIGN_PURE) /* Returns: diff --git a/boot/espressif/CMakeLists.txt b/boot/espressif/CMakeLists.txt index 05358839c..0fa2759ea 100644 --- a/boot/espressif/CMakeLists.txt +++ b/boot/espressif/CMakeLists.txt @@ -236,6 +236,9 @@ endif() set(bootutil_srcs ${BOOTUTIL_DIR}/src/boot_record.c + ${BOOTUTIL_DIR}/src/bootutil_find_key.c + ${BOOTUTIL_DIR}/src/bootutil_img_hash.c + ${BOOTUTIL_DIR}/src/bootutil_img_security_cnt.c ${BOOTUTIL_DIR}/src/bootutil_misc.c ${BOOTUTIL_DIR}/src/bootutil_public.c ${BOOTUTIL_DIR}/src/caps.c diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index e1d2d3e80..c523bf399 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -100,6 +100,9 @@ endif() zephyr_library_include_directories(${BOOT_DIR}/bootutil/include) zephyr_library_sources( ${BOOT_DIR}/bootutil/src/image_validate.c + ${BOOT_DIR}/bootutil/src/bootutil_find_key.c + ${BOOT_DIR}/bootutil/src/bootutil_img_hash.c + ${BOOT_DIR}/bootutil/src/bootutil_img_security_cnt.c ${BOOT_DIR}/bootutil/src/tlv.c ${BOOT_DIR}/bootutil/src/encrypted.c ${BOOT_DIR}/bootutil/src/image_rsa.c diff --git a/sim/mcuboot-sys/build.rs b/sim/mcuboot-sys/build.rs index 12726f928..b2595689b 100644 --- a/sim/mcuboot-sys/build.rs +++ b/sim/mcuboot-sys/build.rs @@ -466,6 +466,9 @@ fn main() { } conf.file("../../boot/bootutil/src/image_validate.c"); + conf.file("../../boot/bootutil/src/bootutil_find_key.c"); + conf.file("../../boot/bootutil/src/bootutil_img_hash.c"); + conf.file("../../boot/bootutil/src/bootutil_img_security_cnt.c"); if sig_rsa || sig_rsa3072 { conf.file("../../boot/bootutil/src/image_rsa.c"); } else if sig_ecdsa || sig_ecdsa_mbedtls || sig_ecdsa_psa {