init:初始框架

This commit is contained in:
SkyLi
2026-06-06 20:50:54 +08:00
commit b5be64b642
685 changed files with 398844 additions and 0 deletions
@@ -0,0 +1,68 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2019 Linaro Limited
*
* Licensed 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.
*/
#ifndef H_BOOTUTIL_BENCH_H__
#define H_BOOTUTIL_BENCH_H__
#include "ignore.h"
#ifdef MCUBOOT_USE_BENCH
/* The platform-specific benchmark code should define a
* `bench_state_t` type that holds the information needed for the
* benchmark. This is generally something small, such as an integer
* holding the state. This should also define plat_bench_start and
* plat_bench_end, which likely have to be macros so that log messages
* come from the right place in the code. */
#include <platform-bench.h>
/*
* These are simple barrier-type benchmarks. If a platform has
* benchmarks that are enabled, calling `boot_bench_start()` before a
* block of code and `boot_bench_stop()` after that block of code will
* present this information in some manner (usually through logging).
* The details of what is measured and how it is printed are specific
* to the platform and the implementation. A pointer to the
* platform-specific state should be passed in.
*/
#define boot_bench_start(_state) do { \
plat_bench_start(_state); \
} while (0)
#define boot_bench_stop(_state) do { \
plat_bench_stop(_state); \
} while (0)
#else /* not MCUBOOT_USE_BENCH */
/* The type needs to take space. As long as it remains unused, the C
* compiler should eliminate this value entirely. */
typedef int bench_state_t;
/* Without benchmarking enabled, these are just empty. */
#define boot_bench_start(_state) do { \
IGNORE(_state); \
} while(0)
#define boot_bench_stop(_state) do { \
IGNORE(_state); \
} while(0)
#endif /* not MCUBOOT_USE_BENCH */
#endif /* not H_BOOTUTIL_BENCH_H__ */
@@ -0,0 +1,73 @@
/*
* Copyright (c) 2018-2021 Arm Limited
*
* Licensed 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.
*/
#ifndef __BOOT_RECORD_H__
#define __BOOT_RECORD_H__
#include <stdint.h>
#include "bootutil/image.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Add a data item to the shared data area between bootloader and
* runtime SW
*
* @param[in] major_type TLV major type, identify consumer
* @param[in] minor_type TLV minor type, identify TLV type
* @param[in] size length of added data
* @param[in] data pointer to data
*
* @return 0 on success; nonzero on failure.
*/
int boot_add_data_to_shared_area(uint8_t major_type,
uint16_t minor_type,
size_t size,
const uint8_t *data);
/**
* Add an image's all boot status information to the shared memory area
* between the bootloader and runtime SW.
*
* @param[in] sw_module Identifier of the SW component.
* @param[in] hdr Pointer to the image header stored in RAM.
* @param[in] fap Pointer to the flash area where image is stored.
*
* @return 0 on success; nonzero on failure.
*/
int boot_save_boot_status(uint8_t sw_module,
const struct image_header *hdr,
const struct flash_area *fap);
/**
* Add application specific data to the shared memory area between the
* bootloader and runtime SW.
*
* @param[in] hdr Pointer to the image header stored in RAM.
* @param[in] fap Pointer to the flash area where image is stored.
*
* @return 0 on success; nonzero on failure.
*/
int boot_save_shared_data(const struct image_header *hdr,
const struct flash_area *fap);
#ifdef __cplusplus
}
#endif
#endif /* __BOOT_RECORD_H__ */
@@ -0,0 +1,150 @@
/*
* Copyright (c) 2018-2020 Arm Limited
* Copyright (c) 2020 Linaro Limited
*
* Licensed 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.
*/
#ifndef __BOOT_STATUS_H__
#define __BOOT_STATUS_H__
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* The shared data between boot loader and runtime SW is TLV encoded. The
* shared data is stored in a well known location in memory and this is a
* contract between boot loader and runtime SW.
*
* The structure of shared data must be the following:
* - At the beginning there must be a header: struct shared_data_tlv_header
* This contains a magic number and a size field which covers the entire
* size of the shared data area including this header.
* - After the header there come the entries which are composed from an entry
* header structure: struct shared_data_tlv_entry and the data. In the entry
* header is a type field (tly_type) which identify the consumer of the
* entry in the runtime SW and specify the subtype of that data item. There
* is a size field (tlv_len) which covers the size of the the data. After
* this structure comes the actual data.
*
* - Arbitrary number and size of data entry can be in the shared memory area.
*
* This table gives of overview about the tlv_type field in the entry header.
* The tlv_type always composed from a major and minor number. Major number
* identifies the addressee in runtime SW, who should process the data entry.
* Minor number used to encode more info about the data entry. The actual
* definition of minor number could change per major number.
*
* In case of boot status data, which can be processed by an attestation
* service the minor number is split further to two part: sw_module and claim.
* The sw_module identifies the SW component in the system which the data item
* belongs to and the claim part identifies the exact type of the data.
*
* |---------------------------------------|
* | tlv_type (16) |
* |---------------------------------------|
* | tlv_major(4)| tlv_minor(12) |
* |---------------------------------------|
* | MAJOR_IAS | sw_module(6) | claim(6) |
* |---------------------------------------|
*/
/* General macros to handle TLV type */
#define MAJOR_MASK 0xF /* 4 bit */
#define MAJOR_POS 12 /* 12 bit */
#define MINOR_MASK 0xFFF /* 12 bit */
#define SET_TLV_TYPE(major, minor) \
(((uint16_t)((major) & MAJOR_MASK) << MAJOR_POS) \
| ((minor) & MINOR_MASK))
#define GET_MAJOR(tlv_type) ((uint16_t)(tlv_type) >> MAJOR_POS)
#define GET_MINOR(tlv_type) ((tlv_type) & MINOR_MASK)
/* Magic value which marks the beginning of shared data area in memory */
#define SHARED_DATA_TLV_INFO_MAGIC 0x2016
/* Initial attestation specific macros */
/**
* Major numbers (4 bit) to identify the
* consumer of shared data in runtime SW.
*/
#define TLV_MAJOR_IAS 0x1
/* Initial attestation: Claim per SW components / SW modules */
/* Bits: 0-2 */
#define SW_VERSION 0x00
#define SW_SIGNER_ID 0x01
/* Reserved 0x02 */
#define SW_TYPE 0x03
/* Bits: 3-5 */
#define SW_MEASURE_VALUE 0x08
#define SW_MEASURE_TYPE 0x09
#define SW_BOOT_RECORD 0x3F
#define MODULE_POS 6 /* 6 bit */
#define CLAIM_MASK 0x3F /* 6 bit */
#define MEASUREMENT_CLAIM_POS 3 /* 3 bit */
#define GET_IAS_MODULE(tlv_type) ((uint16_t)GET_MINOR(tlv_type) >> MODULE_POS)
#define GET_IAS_CLAIM(tlv_type) (GET_MINOR(tlv_type) & CLAIM_MASK)
#define SET_IAS_MINOR(sw_module, claim) \
(((uint16_t)(sw_module) << MODULE_POS) | (claim))
/**
* Shared data TLV header. All fields in little endian.
*
* -----------------------------------
* | tlv_magic(16) | tlv_tot_len(16) |
* -----------------------------------
*/
struct shared_data_tlv_header {
uint16_t tlv_magic;
uint16_t tlv_tot_len; /* size of whole TLV area (including this header) */
};
#define SHARED_DATA_HEADER_SIZE sizeof(struct shared_data_tlv_header)
/**
* Shared data TLV entry header format. All fields in little endian.
*
* -------------------------------
* | tlv_type(16) | tlv_len(16) |
* -------------------------------
* | Raw data |
* -------------------------------
*/
struct shared_data_tlv_entry {
uint16_t tlv_type;
uint16_t tlv_len; /* TLV data length (not including this header). */
};
#define SHARED_DATA_ENTRY_HEADER_SIZE sizeof(struct shared_data_tlv_entry)
#define SHARED_DATA_ENTRY_SIZE(size) (size + SHARED_DATA_ENTRY_HEADER_SIZE)
/* Structure to store the boot data for the runtime SW. */
struct shared_boot_data {
struct shared_data_tlv_header header;
uint8_t data[];
};
#ifdef __cplusplus
}
#endif
#endif /* __BOOT_STATUS_H__ */
@@ -0,0 +1,88 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2017-2019 Linaro LTD
* Copyright (c) 2016-2019 JUUL Labs
* Copyright (c) 2019-2020 Arm Limited
*
* 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.
*/
#ifndef H_BOOTUTIL_
#define H_BOOTUTIL_
#include <inttypes.h>
#include "bootutil/fault_injection_hardening.h"
#include "bootutil/bootutil_public.h"
#ifdef __cplusplus
extern "C" {
#endif
struct image_header;
/**
* A response object provided by the boot loader code; indicates where to jump
* to execute the main image.
*/
struct boot_rsp {
/** A pointer to the header of the image to be executed. */
const struct image_header *br_hdr;
/**
* The flash offset of the image to execute. Indicates the position of
* the image header within its flash device.
*/
uint8_t br_flash_dev_id;
uint32_t br_image_off;
};
/* This is not actually used by mcuboot's code but can be used by apps
* when attempting to read/write a trailer.
*/
struct image_trailer {
uint8_t swap_type;
uint8_t pad1[BOOT_MAX_ALIGN - 1];
uint8_t copy_done;
uint8_t pad2[BOOT_MAX_ALIGN - 1];
uint8_t image_ok;
uint8_t pad3[BOOT_MAX_ALIGN - 1];
uint8_t magic[16];
};
/* you must have pre-allocated all the entries within this structure */
fih_int boot_go(struct boot_rsp *rsp);
struct boot_loader_state;
fih_int context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp);
#define SPLIT_GO_OK (0)
#define SPLIT_GO_NON_MATCHING (-1)
#define SPLIT_GO_ERR (-2)
fih_int split_go(int loader_slot, int split_slot, void **entry);
/* The following was added by TI */
fih_int boot_return_highest_version(struct boot_rsp *rsp);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,53 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2017 Linaro Limited
*
* Licensed 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.
*/
#ifndef H_BOOTUTIL_LOG_H_
#define H_BOOTUTIL_LOG_H_
#include "ignore.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <mcuboot_config/mcuboot_config.h>
#include <mcuboot_config/mcuboot_logging.h>
#ifdef MCUBOOT_HAVE_LOGGING
#define BOOT_LOG_ERR(...) MCUBOOT_LOG_ERR(__VA_ARGS__)
#define BOOT_LOG_WRN(...) MCUBOOT_LOG_WRN(__VA_ARGS__)
#define BOOT_LOG_INF(...) MCUBOOT_LOG_INF(__VA_ARGS__)
#define BOOT_LOG_DBG(...) MCUBOOT_LOG_DBG(__VA_ARGS__)
#define BOOT_LOG_SIM(...) MCUBOOT_LOG_SIM(__VA_ARGS__)
#else
#define BOOT_LOG_ERR(...) IGNORE(__VA_ARGS__)
#define BOOT_LOG_WRN(...) IGNORE(__VA_ARGS__)
#define BOOT_LOG_INF(...) IGNORE(__VA_ARGS__)
#define BOOT_LOG_DBG(...) IGNORE(__VA_ARGS__)
#define BOOT_LOG_SIM(...) IGNORE(__VA_ARGS__)
#endif /* MCUBOOT_HAVE_LOGGING */
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,184 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2017-2019 Linaro LTD
* Copyright (c) 2016-2019 JUUL Labs
* Copyright (c) 2019-2020 Arm Limited
* Copyright (c) 2020 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.
*/
/**
* @file
* @brief Public MCUBoot interface API
*
* This file contains API which can be combined with the application in order
* to interact with the MCUBoot bootloader. This API are shared code-base betwen
* MCUBoot and the application which controls DFU process.
*/
#ifndef H_BOOTUTIL_PUBLIC
#define H_BOOTUTIL_PUBLIC
#include <inttypes.h>
#include <string.h>
#include <flash_map_backend/flash_map_backend.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Attempt to boot the contents of the primary slot. */
#define BOOT_SWAP_TYPE_NONE 1
/**
* Swap to the secondary slot.
* Absent a confirm command, revert back on next boot.
*/
#define BOOT_SWAP_TYPE_TEST 2
/**
* Swap to the secondary slot,
* and permanently switch to booting its contents.
*/
#define BOOT_SWAP_TYPE_PERM 3
/** Swap back to alternate slot. A confirm changes this state to NONE. */
#define BOOT_SWAP_TYPE_REVERT 4
/** Swap failed because image to be run is not valid */
#define BOOT_SWAP_TYPE_FAIL 5
/** Swapping encountered an unrecoverable error */
#define BOOT_SWAP_TYPE_PANIC 0xff
#define BOOT_MAX_ALIGN 8
#define BOOT_MAGIC_GOOD 1
#define BOOT_MAGIC_BAD 2
#define BOOT_MAGIC_UNSET 3
#define BOOT_MAGIC_ANY 4 /* NOTE: control only, not dependent on sector */
#define BOOT_MAGIC_NOTGOOD 5 /* NOTE: control only, not dependent on sector */
/*
* NOTE: leave BOOT_FLAG_SET equal to one, this is written to flash!
*/
#define BOOT_FLAG_SET 1
#define BOOT_FLAG_BAD 2
#define BOOT_FLAG_UNSET 3
#define BOOT_FLAG_ANY 4 /* NOTE: control only, not dependent on sector */
#define BOOT_MAGIC_SZ (sizeof boot_img_magic)
struct boot_swap_state {
uint8_t magic; /* One of the BOOT_MAGIC_[...] values. */
uint8_t swap_type; /* One of the BOOT_SWAP_TYPE_[...] values. */
uint8_t copy_done; /* One of the BOOT_FLAG_[...] values. */
uint8_t image_ok; /* One of the BOOT_FLAG_[...] values. */
uint8_t image_num; /* Boot status belongs to this image */
};
/**
* @brief Determines the action, if any, that mcuboot will take on a image pair.
*
* @param image_index Image pair index.
*
* @return a BOOT_SWAP_TYPE_[...] constant on success, negative errno code on
* fail.
*/
int boot_swap_type_multi(int image_index);
/**
* @brief Determines the action, if any, that mcuboot will take.
*
* Works the same as a boot_swap_type_multi(0) call;
*
* @return a BOOT_SWAP_TYPE_[...] constant on success, negative errno code on
* fail.
*/
int boot_swap_type(void);
/**
* Marks the image in the secondary slot as pending. On the next reboot,
* the system will perform a one-time boot of the the secondary slot image.
*
* @param permanent Whether the image should be used permanently or
* only tested once:
* 0=run image once, then confirm or revert.
* 1=run image forever.
*
* @return 0 on success; nonzero on failure.
*/
int boot_set_pending(int permanent);
/**
* @brief Marks the image in the primary slot as confirmed.
*
* The system will continue booting into the image in the primary slot until
* told to boot from a different slot.
*
* @return 0 on success; nonzero on failure.
*/
int boot_set_confirmed(void);
/**
* @brief Get offset of the swap info field in the image trailer.
*
* @param fap Flash are for which offset is determined.
*
* @retval offset of the swap info field.
*/
uint32_t boot_swap_info_off(const struct flash_area *fap);
/**
* @brief Get value of image-ok flag of the image.
*
* If called from chin-loaded image the image-ok flag value can be used to check
* whether application itself is already confirmed.
*
* @param fap Flash area of the image.
* @param image_ok[out] image-ok value.
*
* @return 0 on success; nonzero on failure.
*/
int boot_read_image_ok(const struct flash_area *fap, uint8_t *image_ok);
/**
* @brief Read the image swap state
*
* @param flash_area_id Id of flash parttition from which trailer will be read.
* @param state Struture for holding swap state.
*
* @return 0 on success, nonzero errno code on fail.
*/
int
boot_read_swap_state_by_id(int flash_area_id, struct boot_swap_state *state);
#define BOOT_MAGIC_ARR_SZ \
(sizeof boot_img_magic / sizeof boot_img_magic[0])
extern const uint32_t boot_img_magic[4];
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,35 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*/
#ifndef H_BOOTUTIL_TEST_
#define H_BOOTUTIL_TEST_
#ifdef __cplusplus
extern "C" {
#endif
int boot_test_all(void);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2017 Linaro Limited
*
* Licensed 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.
*/
#ifndef H_BOOTUTIL_CAPS_H_
#define H_BOOTUTIL_CAPS_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* The bootloader can be compile with different capabilities selected
* at compile time. This function provides runtime access to these
* capabilities. This is intended primarily for testing, although
* these will possibly be available at runtime to the application
* running within the bootloader.
*/
uint32_t bootutil_get_caps(void);
#define BOOTUTIL_CAP_RSA2048 (1<<0)
#define BOOTUTIL_CAP_ECDSA_P224 (1<<1)
#define BOOTUTIL_CAP_ECDSA_P256 (1<<2)
#define BOOTUTIL_CAP_SWAP_USING_SCRATCH (1<<3)
#define BOOTUTIL_CAP_OVERWRITE_UPGRADE (1<<4)
#define BOOTUTIL_CAP_ENC_RSA (1<<5)
#define BOOTUTIL_CAP_ENC_KW (1<<6)
#define BOOTUTIL_CAP_VALIDATE_PRIMARY_SLOT (1<<7)
#define BOOTUTIL_CAP_RSA3072 (1<<8)
#define BOOTUTIL_CAP_ED25519 (1<<9)
#define BOOTUTIL_CAP_ENC_EC256 (1<<10)
#define BOOTUTIL_CAP_SWAP_USING_MOVE (1<<11)
#define BOOTUTIL_CAP_DOWNGRADE_PREVENTION (1<<12)
#define BOOTUTIL_CAP_ENC_X25519 (1<<13)
#define BOOTUTIL_CAP_BOOTSTRAP (1<<14)
/*
* Query the number of images this bootloader is configured for. This
* is also primarily used for testing.
*/
uint32_t bootutil_get_num_images(void);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,122 @@
/*
* This module provides a thin abstraction over some of the crypto
* primitives to make it easier to swap out the used crypto library.
*
* At this point, there are two choices: MCUBOOT_USE_MBED_TLS, or
* MCUBOOT_USE_TINYCRYPT. It is a compile error there is not exactly
* one of these defined.
*/
#ifndef __BOOTUTIL_CRYPTO_AES_CTR_H_
#define __BOOTUTIL_CRYPTO_AES_CTR_H_
#include <string.h>
#include "mcuboot_config/mcuboot_config.h"
#if (defined(MCUBOOT_USE_MBED_TLS) + \
defined(MCUBOOT_USE_TINYCRYPT)) != 1
#error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT"
#endif
#if defined(MCUBOOT_USE_MBED_TLS)
#include <mbedtls/aes.h>
#define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE (16)
#define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE (16)
#endif /* MCUBOOT_USE_MBED_TLS */
#if defined(MCUBOOT_USE_TINYCRYPT)
#include <string.h>
#include <tinycrypt/aes.h>
#include <tinycrypt/ctr_mode.h>
#include <tinycrypt/constants.h>
#define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE TC_AES_KEY_SIZE
#define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE TC_AES_BLOCK_SIZE
#endif /* MCUBOOT_USE_TINYCRYPT */
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MCUBOOT_USE_MBED_TLS)
typedef mbedtls_aes_context bootutil_aes_ctr_context;
static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx)
{
(void)mbedtls_aes_init(ctx);
}
static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx)
{
/* XXX: config defines MBEDTLS_PLATFORM_NO_STD_FUNCTIONS so no need to free */
/* (void)mbedtls_aes_free(ctx); */
(void)ctx;
}
static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k)
{
return mbedtls_aes_setkey_enc(ctx, k, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE * 8);
}
static inline int bootutil_aes_ctr_encrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, const uint8_t *m, uint32_t mlen, size_t blk_off, uint8_t *c)
{
uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
return mbedtls_aes_crypt_ctr(ctx, mlen, &blk_off, counter, stream_block, m, c);
}
static inline int bootutil_aes_ctr_decrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, const uint8_t *c, uint32_t clen, size_t blk_off, uint8_t *m)
{
uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
return mbedtls_aes_crypt_ctr(ctx, clen, &blk_off, counter, stream_block, c, m);
}
#endif /* MCUBOOT_USE_MBED_TLS */
#if defined(MCUBOOT_USE_TINYCRYPT)
typedef struct tc_aes_key_sched_struct bootutil_aes_ctr_context;
static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx)
{
(void)ctx;
}
static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx)
{
(void)ctx;
}
static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k)
{
int rc;
rc = tc_aes128_set_encrypt_key(ctx, k);
if (rc != TC_CRYPTO_SUCCESS) {
return -1;
}
return 0;
}
static int _bootutil_aes_ctr_crypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, const uint8_t *in, uint32_t inlen, uint32_t blk_off, uint8_t *out)
{
int rc;
rc = tc_ctr_mode(out, inlen, in, inlen, counter, &blk_off, ctx);
if (rc != TC_CRYPTO_SUCCESS) {
return -1;
}
return 0;
}
static inline int bootutil_aes_ctr_encrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, const uint8_t *m, uint32_t mlen, uint32_t blk_off, uint8_t *c)
{
return _bootutil_aes_ctr_crypt(ctx, counter, m, mlen, blk_off, c);
}
static inline int bootutil_aes_ctr_decrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, const uint8_t *c, uint32_t clen, uint32_t blk_off, uint8_t *m)
{
return _bootutil_aes_ctr_crypt(ctx, counter, c, clen, blk_off, m);
}
#endif /* MCUBOOT_USE_TINYCRYPT */
#ifdef __cplusplus
}
#endif
#endif /* __BOOTUTIL_CRYPTO_AES_CTR_H_ */
@@ -0,0 +1,141 @@
/*
* This module provides a thin abstraction over some of the crypto
* primitives to make it easier to swap out the used crypto library.
*
* At this point, there are two choices: MCUBOOT_USE_MBED_TLS, or
* MCUBOOT_USE_TINYCRYPT. It is a compile error there is not exactly
* one of these defined.
*/
#ifndef __BOOTUTIL_CRYPTO_AES_KW_H_
#define __BOOTUTIL_CRYPTO_AES_KW_H_
#include "mcuboot_config/mcuboot_config.h"
#if (defined(MCUBOOT_USE_MBED_TLS) + \
defined(MCUBOOT_USE_TINYCRYPT)) != 1
#error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT"
#endif
#if defined(MCUBOOT_USE_MBED_TLS)
#include <mbedtls/aes.h>
#include <mbedtls/nist_kw.h>
#endif /* MCUBOOT_USE_MBED_TLS */
#if defined(MCUBOOT_USE_TINYCRYPT)
#include <tinycrypt/aes.h>
#include <tinycrypt/constants.h>
#endif /* MCUBOOT_USE_TINYCRYPT */
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MCUBOOT_USE_MBED_TLS)
typedef mbedtls_nist_kw_context bootutil_aes_kw_context;
static inline void bootutil_aes_kw_init(bootutil_aes_kw_context *ctx)
{
(void)mbedtls_nist_kw_init(ctx);
}
static inline void bootutil_aes_kw_drop(bootutil_aes_kw_context *ctx)
{
/* XXX: config defines MBEDTLS_PLATFORM_NO_STD_FUNCTIONS so no need to free */
/* (void)mbedtls_aes_free(ctx); */
(void)ctx;
}
static inline int bootutil_aes_kw_set_unwrap_key(bootutil_aes_kw_context *ctx, const uint8_t *k, uint32_t klen)
{
return mbedtls_nist_kw_setkey(ctx, MBEDTLS_CIPHER_ID_AES, k, klen * 8, 0);
}
static inline int bootutil_aes_kw_unwrap(bootutil_aes_kw_context *ctx, const uint8_t *wrapped_key, uint32_t wrapped_key_len, uint8_t *key, uint32_t key_len)
{
size_t olen;
return mbedtls_nist_kw_unwrap(ctx, MBEDTLS_KW_MODE_KW, wrapped_key, wrapped_key_len, key, &olen, key_len);
}
#endif /* MCUBOOT_USE_MBED_TLS */
#if defined(MCUBOOT_USE_TINYCRYPT)
typedef struct tc_aes_key_sched_struct bootutil_aes_kw_context;
static inline void bootutil_aes_kw_init(bootutil_aes_kw_context *ctx)
{
(void)ctx;
}
static inline void bootutil_aes_kw_drop(bootutil_aes_kw_context *ctx)
{
(void)ctx;
}
static inline int bootutil_aes_kw_set_unwrap_key(bootutil_aes_kw_context *ctx, const uint8_t *k, uint32_t klen)
{
int rc;
if (klen != 16) {
return -1;
}
rc = tc_aes128_set_decrypt_key(ctx, k);
if (rc != TC_CRYPTO_SUCCESS) {
return -1;
}
return 0;
}
/*
* Implements AES key unwrapping following RFC-3394 section 2.2.2, using
* tinycrypt for AES-128 decryption.
*/
static int bootutil_aes_kw_unwrap(bootutil_aes_kw_context *ctx, const uint8_t *wrapped_key, uint32_t wrapped_key_len, uint8_t *key, uint32_t key_len)
{
uint8_t A[8];
uint8_t B[16];
int8_t i, j, k;
if (wrapped_key_len != 24 || key_len != 16) {
return -1;
}
for (k = 0; k < 8; k++) {
A[k] = wrapped_key[k];
key[k] = wrapped_key[8 + k];
key[8 + k] = wrapped_key[16 + k];
}
for (j = 5; j >= 0; j--) {
for (i = 2; i > 0; i--) {
for (k = 0; k < 8; k++) {
B[k] = A[k];
B[8 + k] = key[((i-1) * 8) + k];
}
B[7] ^= 2 * j + i;
if (tc_aes_decrypt((uint8_t *)&B, (uint8_t *)&B, ctx) != TC_CRYPTO_SUCCESS) {
return -1;
}
for (k = 0; k < 8; k++) {
A[k] = B[k];
key[((i-1) * 8) + k] = B[8 + k];
}
}
}
for (i = 0, k = 0; i < 8; i++) {
k |= A[i] ^ 0xa6;
}
if (k) {
return -1;
}
return 0;
}
#endif /* MCUBOOT_USE_TINYCRYPT */
#ifdef __cplusplus
}
#endif
#endif /* __BOOTUTIL_CRYPTO_AES_KW_H_ */
@@ -0,0 +1,63 @@
/*
* This module provides a thin abstraction over some of the crypto
* primitives to make it easier to swap out the used crypto library.
*
* At this point, there are two choices: MCUBOOT_USE_MBED_TLS, or
* MCUBOOT_USE_TINYCRYPT. It is a compile error there is not exactly
* one of these defined.
*/
#ifndef __BOOTUTIL_CRYPTO_ECDH_P256_H_
#define __BOOTUTIL_CRYPTO_ECDH_P256_H_
#include "mcuboot_config/mcuboot_config.h"
#if (defined(MCUBOOT_USE_TINYCRYPT)) != 1
#error "One crypto backend must be defined: TINYCRYPT"
#endif
#if defined(MCUBOOT_USE_TINYCRYPT)
#include <tinycrypt/ecc_dh.h>
#include <tinycrypt/constants.h>
#define BOOTUTIL_CRYPTO_ECDH_P256_HASH_SIZE (4 * 8)
#endif /* MCUBOOT_USE_TINYCRYPT */
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MCUBOOT_USE_TINYCRYPT)
typedef uintptr_t bootutil_ecdh_p256_context;
static inline void bootutil_ecdh_p256_init(bootutil_ecdh_p256_context *ctx)
{
(void)ctx;
}
static inline void bootutil_ecdh_p256_drop(bootutil_ecdh_p256_context *ctx)
{
(void)ctx;
}
static inline int bootutil_ecdh_p256_shared_secret(bootutil_ecdh_p256_context *ctx, const uint8_t *pk, const uint8_t *sk, uint8_t *z)
{
int rc;
(void)ctx;
rc = uECC_valid_public_key(pk, uECC_secp256r1());
if (rc != 0) {
return -1;
}
rc = uECC_shared_secret(pk, sk, z, uECC_secp256r1());
if (rc != TC_CRYPTO_SUCCESS) {
return -1;
}
return 0;
}
#endif /* MCUBOOT_USE_TINYCRYPT */
#ifdef __cplusplus
}
#endif
#endif /* __BOOTUTIL_CRYPTO_ECDH_P256_H_ */
@@ -0,0 +1,57 @@
/*
* This module provides a thin abstraction over some of the crypto
* primitives to make it easier to swap out the used crypto library.
*
* At this point, there are two choices: MCUBOOT_USE_MBED_TLS, or
* MCUBOOT_USE_TINYCRYPT. It is a compile error there is not exactly
* one of these defined.
*/
#ifndef __BOOTUTIL_CRYPTO_ECDH_X25519_H_
#define __BOOTUTIL_CRYPTO_ECDH_X25519_H_
#include "mcuboot_config/mcuboot_config.h"
#if (defined(MCUBOOT_USE_MBED_TLS) + \
defined(MCUBOOT_USE_TINYCRYPT)) != 1
#error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MCUBOOT_USE_TINYCRYPT) || defined(MCUBOOT_USE_MBED_TLS)
extern int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
const uint8_t peer_public_value[32]);
typedef uintptr_t bootutil_ecdh_x25519_context;
static inline void bootutil_ecdh_x25519_init(bootutil_ecdh_x25519_context *ctx)
{
(void)ctx;
}
static inline void bootutil_ecdh_x25519_drop(bootutil_ecdh_x25519_context *ctx)
{
(void)ctx;
}
static inline int bootutil_ecdh_x25519_shared_secret(bootutil_ecdh_x25519_context *ctx, const uint8_t *pk, const uint8_t *sk, uint8_t *z)
{
int rc;
(void)ctx;
rc = X25519(z, sk, pk);
if (rc != 0) {
return -1;
}
return 0;
}
#endif /* MCUBOOT_USE_TINYCRYPT */
#ifdef __cplusplus
}
#endif
#endif /* __BOOTUTIL_CRYPTO_ECDH_X25519_H_ */
@@ -0,0 +1,131 @@
/*
* This module provides a thin abstraction over some of the crypto
* primitives to make it easier to swap out the used crypto library.
*
* At this point, there are two choices: MCUBOOT_USE_MBED_TLS, or
* MCUBOOT_USE_TINYCRYPT. It is a compile error there is not exactly
* one of these defined.
*/
#ifndef __BOOTUTIL_CRYPTO_ECDSA_P256_H_
#define __BOOTUTIL_CRYPTO_ECDSA_P256_H_
#include "mcuboot_config/mcuboot_config.h"
#if (defined(MCUBOOT_USE_TINYCRYPT) + \
defined(MCUBOOT_USE_CC310) + \
defined(MCUBOOT_USE_TI_CRYPTO) + \
defined(MCUBOOT_USE_MSP_CRYPTO) + \
defined(MCUBOOT_USE_MBED_TLS)) != 1
#error "One crypto backend must be defined: either CC310 or TINYCRYPT"
#endif
#if defined(MCUBOOT_USE_TINYCRYPT)
#include <tinycrypt/ecc_dsa.h>
#include <tinycrypt/constants.h>
#define BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE (4 * 8)
#endif /* MCUBOOT_USE_TINYCRYPT */
#if defined(MCUBOOT_USE_CC310)
#include <cc310_glue.h>
#define BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE (4 * 8)
#endif /* MCUBOOT_USE_CC310 */
#if defined(MCUBOOT_USE_TI_CRYPTO)
#define BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE (4 * 8)
#endif /* MCUBOOT_USE_TI_CRYPTO */
#if defined(MCUBOOT_USE_MSP_CRYPTO)
#define BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE (4 * 8)
#endif /* MCUBOOT_USE_TI_CRYPTO */
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MCUBOOT_USE_TINYCRYPT)
typedef uintptr_t bootutil_ecdsa_p256_context;
static inline void bootutil_ecdsa_p256_init(bootutil_ecdsa_p256_context *ctx)
{
(void)ctx;
}
static inline void bootutil_ecdsa_p256_drop(bootutil_ecdsa_p256_context *ctx)
{
(void)ctx;
}
static inline int bootutil_ecdsa_p256_verify(bootutil_ecdsa_p256_context *ctx, const uint8_t *pk, const uint8_t *hash, const uint8_t *sig)
{
int rc;
(void)ctx;
rc = uECC_verify(pk, hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, sig, uECC_secp256r1());
if (rc != TC_CRYPTO_SUCCESS) {
return -1;
}
return 0;
}
#endif /* MCUBOOT_USE_TINYCRYPT */
#if defined(MCUBOOT_USE_CC310)
typedef uintptr_t bootutil_ecdsa_p256_context;
static inline void bootutil_ecdsa_p256_init(bootutil_ecdsa_p256_context *ctx)
{
(void)ctx;
}
static inline void bootutil_ecdsa_p256_drop(bootutil_ecdsa_p256_context *ctx)
{
(void)ctx;
}
static inline int bootutil_ecdsa_p256_verify(bootutil_ecdsa_p256_context *ctx, uint8_t *pk, uint8_t *hash, uint8_t *sig)
{
(void)ctx;
return cc310_ecdsa_verify_secp256r1(hash, pk, sig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE);
}
#endif /* MCUBOOT_USE_CC310 */
#if defined(MCUBOOT_USE_TI_CRYPTO)
#include "ti-crypto/sl_crypto.h"
typedef void* bootutil_ecdsa_p256_context;
static inline void bootutil_ecdsa_p256_init(bootutil_ecdsa_p256_context *ctx)
{
SlCrypto_ecdsa_p256_init();
}
static inline void bootutil_ecdsa_p256_drop(bootutil_ecdsa_p256_context *ctx)
{
SlCrypto_ecdsa_p256_drop();
}
static inline int bootutil_ecdsa_p256_verify(bootutil_ecdsa_p256_context *ctx, const uint8_t *pk, const uint8_t *hash, const uint8_t *sig)
{
return SlCrypto_ecdsa_p256_verify(pk, hash, sig);
}
#endif /* MCUBOOT_USE_TI_CRYPTO */
#if defined(MCUBOOT_USE_MSP_CRYPTO)
#include "msp-crypto/msp_crypto.h"
typedef void* bootutil_ecdsa_p256_context;
static inline void bootutil_ecdsa_p256_init(bootutil_ecdsa_p256_context *ctx)
{
MSPCrypto_ecdsa_p256_init();
}
static inline void bootutil_ecdsa_p256_drop(bootutil_ecdsa_p256_context *ctx)
{
MSPCrypto_ecdsa_p256_drop();
}
static inline int bootutil_ecdsa_p256_verify(bootutil_ecdsa_p256_context *ctx, const uint8_t *pk, const uint8_t *hash, const uint8_t *sig)
{
return MSPCrypto_ecdsa_p256_verify(pk, hash, sig);
}
#endif /* MCUBOOT_USE_MSP_CRYPTO */
#ifdef __cplusplus
}
#endif
#endif /* __BOOTUTIL_CRYPTO_ECDSA_P256_H_ */
@@ -0,0 +1,83 @@
/*
* This module provides a thin abstraction over some of the crypto
* primitives to make it easier to swap out the used crypto library.
*
* At this point, there are two choices: MCUBOOT_USE_MBED_TLS, or
* MCUBOOT_USE_TINYCRYPT. It is a compile error there is not exactly
* one of these defined.
*/
#ifndef __BOOTUTIL_CRYPTO_HMAC_SHA256_H_
#define __BOOTUTIL_CRYPTO_HMAC_SHA256_H_
#include "mcuboot_config/mcuboot_config.h"
#if (defined(MCUBOOT_USE_TINYCRYPT)) != 1
#error "One crypto backend must be defined: TINYCRYPT"
#endif
#if defined(MCUBOOT_USE_TINYCRYPT)
#include <tinycrypt/sha256.h>
#include <tinycrypt/utils.h>
#include <tinycrypt/constants.h>
#include <tinycrypt/hmac.h>
#endif /* MCUBOOT_USE_TINYCRYPT */
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MCUBOOT_USE_TINYCRYPT)
typedef struct tc_hmac_state_struct bootutil_hmac_sha256_context;
static inline void bootutil_hmac_sha256_init(bootutil_hmac_sha256_context *ctx)
{
(void)ctx;
}
static inline void bootutil_hmac_sha256_drop(bootutil_hmac_sha256_context *ctx)
{
(void)ctx;
}
static inline int bootutil_hmac_sha256_set_key(bootutil_hmac_sha256_context *ctx, const uint8_t *key, unsigned int key_size)
{
int rc;
rc = tc_hmac_set_key(ctx, key, key_size);
if (rc != TC_CRYPTO_SUCCESS) {
return -1;
}
rc = tc_hmac_init(ctx);
if (rc != TC_CRYPTO_SUCCESS) {
return -1;
}
return 0;
}
static inline int bootutil_hmac_sha256_update(bootutil_hmac_sha256_context *ctx, const void *data, unsigned int data_length)
{
int rc;
rc = tc_hmac_update(ctx, data, data_length);
if (rc != TC_CRYPTO_SUCCESS) {
return -1;
}
return 0;
}
static inline int bootutil_hmac_sha256_finish(bootutil_hmac_sha256_context *ctx, uint8_t *tag, unsigned int taglen)
{
int rc;
rc = tc_hmac_final(tag, taglen, ctx);
if (rc != TC_CRYPTO_SUCCESS) {
return -1;
}
return 0;
}
#endif /* MCUBOOT_USE_TINYCRYPT */
#ifdef __cplusplus
}
#endif
#endif /* __BOOTUTIL_CRYPTO_HMAC_SHA256_H_ */
@@ -0,0 +1,205 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2017-2019 Linaro LTD
* Copyright (c) 2017-2019 JUUL Labs
*/
/*
* This module provides a thin abstraction over some of the crypto
* primitives to make it easier to swap out the used crypto library.
*
* At this point, there are two choices: MCUBOOT_USE_MBED_TLS, or
* MCUBOOT_USE_TINYCRYPT. It is a compile error there is not exactly
* one of these defined.
*/
#ifndef __BOOTUTIL_CRYPTO_SHA256_H_
#define __BOOTUTIL_CRYPTO_SHA256_H_
#include "mcuboot_config/mcuboot_config.h"
#if (defined(MCUBOOT_USE_MBED_TLS) + \
defined(MCUBOOT_USE_TINYCRYPT) + \
defined(MCUBOOT_USE_TI_CRYPTO) + \
defined(MCUBOOT_USE_MSP_CRYPTO) + \
defined(MCUBOOT_USE_CC310)) != 1
#error "One crypto backend must be defined: either CC310, MBED_TLS or TINYCRYPT"
#endif
#if defined(MCUBOOT_USE_MBED_TLS)
#include <mbedtls/sha256.h>
#define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE (64)
#define BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE (32)
#endif /* MCUBOOT_USE_MBED_TLS */
#if defined(MCUBOOT_USE_TINYCRYPT)
#include <tinycrypt/sha256.h>
#include <tinycrypt/constants.h>
#define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE TC_SHA256_BLOCK_SIZE
#define BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE TC_SHA256_DIGEST_SIZE
#endif /* MCUBOOT_USE_TINYCRYPT */
#if defined(MCUBOOT_USE_CC310)
#include <cc310_glue.h>
#define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE (64)
#define BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE (32)
#endif /* MCUBOOT_USE_CC310 */
#if defined(MCUBOOT_USE_TI_CRYPTO) || defined(MCUBOOT_USE_MSP_CRYPTO)
#define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE (64)
#define BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE (32)
#endif /* MCUBOOT_USE_TI_CRYPTO */
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MCUBOOT_USE_MBED_TLS)
typedef mbedtls_sha256_context bootutil_sha256_context;
static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
{
mbedtls_sha256_init(ctx);
(void)mbedtls_sha256_starts_ret(ctx, 0);
}
static inline void bootutil_sha256_drop(bootutil_sha256_context *ctx)
{
/* XXX: config defines MBEDTLS_PLATFORM_NO_STD_FUNCTIONS so no need to free */
/* (void)mbedtls_sha256_free(ctx); */
(void)ctx;
}
static inline int bootutil_sha256_update(bootutil_sha256_context *ctx,
const void *data,
uint32_t data_len)
{
return mbedtls_sha256_update_ret(ctx, data, data_len);
}
static inline int bootutil_sha256_finish(bootutil_sha256_context *ctx,
uint8_t *output)
{
return mbedtls_sha256_finish_ret(ctx, output);
}
#endif /* MCUBOOT_USE_MBED_TLS */
#if defined(MCUBOOT_USE_TINYCRYPT)
typedef struct tc_sha256_state_struct bootutil_sha256_context;
static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
{
tc_sha256_init(ctx);
}
static inline void bootutil_sha256_drop(bootutil_sha256_context *ctx)
{
(void)ctx;
}
static inline int bootutil_sha256_update(bootutil_sha256_context *ctx,
const void *data,
uint32_t data_len)
{
return tc_sha256_update(ctx, data, data_len);
}
static inline int bootutil_sha256_finish(bootutil_sha256_context *ctx,
uint8_t *output)
{
return tc_sha256_final(output, ctx);
}
#endif /* MCUBOOT_USE_TINYCRYPT */
#if defined(MCUBOOT_USE_CC310)
static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
{
cc310_sha256_init(ctx);
}
static inline void bootutil_sha256_drop(bootutil_sha256_context *ctx)
{
(void)ctx;
nrf_cc310_disable();
}
static inline int bootutil_sha256_update(bootutil_sha256_context *ctx,
const void *data,
uint32_t data_len)
{
cc310_sha256_update(ctx, data, data_len);
return 0;
}
static inline int bootutil_sha256_finish(bootutil_sha256_context *ctx,
uint8_t *output)
{
cc310_sha256_finalize(ctx, output);
return 0;
}
#endif /* MCUBOOT_USE_CC310 */
#if defined(MCUBOOT_USE_TI_CRYPTO)
#include "ti-crypto/sl_crypto.h"
typedef void* bootutil_sha256_context;
static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
{
SlCrypto_sha256_init();
}
static inline void bootutil_sha256_drop(bootutil_sha256_context *ctx)
{
SlCrypto_sha256_drop();
}
static inline int bootutil_sha256_update(bootutil_sha256_context *ctx,
const void *data,
uint32_t data_len)
{
return SlCrypto_sha256_update(data, data_len);
}
static inline int bootutil_sha256_finish(bootutil_sha256_context *ctx,
uint8_t *output)
{
return SlCrypto_sha256_final(output);
}
#endif /* MCUBOOT_USE_TI_CRYPTO */
#if defined(MCUBOOT_USE_MSP_CRYPTO)
#include "msp-crypto/msp_crypto.h"
typedef uint32_t bootutil_sha256_context;
static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
{
MSPCrypto_sha256_init();
}
static inline void bootutil_sha256_drop(bootutil_sha256_context *ctx)
{
MSPCrypto_sha256_drop();
}
static inline int bootutil_sha256_update(bootutil_sha256_context *ctx,
const void *data,
uint32_t data_len)
{
return MSPCrypto_sha256_update(data, data_len);
}
static inline int bootutil_sha256_finish(bootutil_sha256_context *ctx,
uint8_t *output)
{
return MSPCrypto_sha256_finish(output);
}
#endif /* MCUBOOT_USE_MSP_CRYPTO */
#ifdef __cplusplus
}
#endif
#endif /* __BOOTUTIL_CRYPTO_SHA256_H_ */
@@ -0,0 +1,88 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2018-2019 JUUL Labs
* Copyright (c) 2019 Arm Limited
*
* 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.
*/
#ifndef BOOTUTIL_ENC_KEY_H
#define BOOTUTIL_ENC_KEY_H
#include <stdbool.h>
#include <stdint.h>
#include <flash_map_backend/flash_map_backend.h>
#include "bootutil/crypto/aes_ctr.h"
#include "bootutil/image.h"
#ifdef __cplusplus
extern "C" {
#endif
#define BOOT_ENC_KEY_SIZE 16
#define BOOT_ENC_KEY_SIZE_BITS (BOOT_ENC_KEY_SIZE * 8)
#define TLV_ENC_RSA_SZ 256
#define TLV_ENC_KW_SZ 24
#define TLV_ENC_EC256_SZ (65 + 32 + 16)
#define TLV_ENC_X25519_SZ (32 + 32 + 16)
#if defined(MCUBOOT_ENCRYPT_RSA)
#define BOOT_ENC_TLV_SIZE TLV_ENC_RSA_SZ
#elif defined(MCUBOOT_ENCRYPT_EC256)
#define BOOT_ENC_TLV_SIZE TLV_ENC_EC256_SZ
#elif defined(MCUBOOT_ENCRYPT_X25519)
#define BOOT_ENC_TLV_SIZE TLV_ENC_X25519_SZ
#else
#define BOOT_ENC_TLV_SIZE TLV_ENC_KW_SZ
#endif
#define BOOT_ENC_TLV_ALIGN_SIZE \
((((BOOT_ENC_TLV_SIZE - 1) / BOOT_MAX_ALIGN) + 1) * BOOT_MAX_ALIGN)
struct enc_key_data {
uint8_t valid;
bootutil_aes_ctr_context aes_ctr;
};
extern const struct bootutil_key bootutil_enc_key;
struct boot_status;
int boot_enc_init(struct enc_key_data *enc_state, uint8_t slot);
int boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot);
int boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot,
const struct boot_status *bs);
int boot_enc_load(struct enc_key_data *enc_state, int image_index,
const struct image_header *hdr, const struct flash_area *fap,
struct boot_status *bs);
int boot_enc_decrypt(const uint8_t *buf, uint8_t *enckey);
bool boot_enc_valid(struct enc_key_data *enc_state, int image_index,
const struct flash_area *fap);
void boot_encrypt(struct enc_key_data *enc_state, int image_index,
const struct flash_area *fap, uint32_t off, uint32_t sz,
uint32_t blk_off, uint8_t *buf);
void boot_enc_zeroize(struct enc_key_data *enc_state);
#ifdef __cplusplus
}
#endif
#endif /* BOOTUTIL_ENC_KEY_H */
@@ -0,0 +1,377 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2020 Arm Limited
*/
#ifndef __FAULT_INJECTION_HARDENING_H__
#define __FAULT_INJECTION_HARDENING_H__
/* Fault injection mitigation library.
*
* Has support for different measures, which can either be enabled/disabled
* separately or by defining one of the MCUBOOT_FIH_PROFILEs.
*
* NOTE: These constructs against fault injection attacks are not guaranteed to
* be secure for all compilers, but execution is going to be correct and
* including them will certainly help to harden the code.
*
* FIH_ENABLE_DOUBLE_VARS makes critical variables into a tuple (x, x ^ msk).
* Then the correctness of x can be checked by XORing the two tuple values
* together. This also means that comparisons between fih_ints can be verified
* by doing x == y && x_msk == y_msk.
*
* FIH_ENABLE_GLOBAL_FAIL makes all while(1) failure loops redirect to a global
* failure loop. This loop has mitigations against loop escapes / unlooping.
* This also means that any unlooping won't immediately continue executing the
* function that was executing before the failure.
*
* FIH_ENABLE_CFI (Control Flow Integrity) creates a global counter that is
* incremented before every FIH_CALL of vulnerable functions. On the function
* return the counter is decremented, and after the return it is verified that
* the counter has the same value as before this process. This can be used to
* verify that the function has actually been called. This protection is
* intended to discover that important functions are called in an expected
* sequence and neither of them is missed due to an instruction skip which could
* be a result of glitching attack. It does not provide protection against ROP
* or JOP attacks.
*
* FIH_ENABLE_DELAY causes random delays. This makes it hard to cause faults
* precisely. It requires an RNG. An mbedtls integration is provided in
* fault_injection_hardening_delay_mbedtls.h, but any RNG that has an entropy
* source can be used by implementing the fih_delay_random_uchar function.
*
* The basic call pattern is:
*
* fih_int fih_rc = FIH_FAILURE;
* FIH_CALL(vulnerable_function, fih_rc, arg1, arg2);
* if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
* FIH_PANIC;
* }
*
* Note that any function called by FIH_CALL must only return using FIH_RETURN,
* as otherwise the CFI counter will not be decremented and the CFI check will
* fail causing a panic.
*/
#include "mcuboot_config/mcuboot_config.h"
#if defined(MCUBOOT_FIH_PROFILE_HIGH)
#define FIH_ENABLE_DELAY /* Requires an entropy source */
#define FIH_ENABLE_DOUBLE_VARS
#define FIH_ENABLE_GLOBAL_FAIL
#define FIH_ENABLE_CFI
#elif defined(MCUBOOT_FIH_PROFILE_MEDIUM)
#define FIH_ENABLE_DOUBLE_VARS
#define FIH_ENABLE_GLOBAL_FAIL
#define FIH_ENABLE_CFI
#elif defined(MCUBOOT_FIH_PROFILE_LOW)
#define FIH_ENABLE_GLOBAL_FAIL
#define FIH_ENABLE_CFI
#elif !defined(MCUBOOT_FIH_PROFILE_OFF)
#define MCUBOOT_FIH_PROFILE_OFF
#endif /* MCUBOOT_FIH_PROFILE */
#ifdef FIH_ENABLE_DELAY
#include "fault_injection_hardening_delay_rng.h"
#endif /* FIH_ENABLE_DELAY */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Non-zero success value to defend against register resets. Zero is the most
* common value for a corrupted register so complex bit-patterns are used
*/
#ifndef MCUBOOT_FIH_PROFILE_OFF
#define FIH_POSITIVE_VALUE 0x1AAAAAAA
#define FIH_NEGATIVE_VALUE 0x15555555
#else
#define FIH_POSITIVE_VALUE 0
#define FIH_NEGATIVE_VALUE -1
#endif
/* A volatile mask is used to prevent compiler optimization - the mask is xored
* with the variable to create the backup and the integrity can be checked with
* another xor. The mask value doesn't _really_ matter that much, as long as
* it has reasonably high hamming weight.
*/
#define _FIH_MASK_VALUE 0xBEEF
#ifdef FIH_ENABLE_DOUBLE_VARS
/* All ints are replaced with two int - the normal one and a backup which is
* XORed with the mask.
*/
extern volatile int _fih_mask;
typedef volatile struct {
volatile int val;
volatile int msk;
} fih_int;
#else
typedef int fih_int;
#endif /* FIH_ENABLE_DOUBLE_VARS */
extern fih_int FIH_SUCCESS;
extern fih_int FIH_FAILURE;
#ifdef FIH_ENABLE_GLOBAL_FAIL
/* Global failure handler - more resistant to unlooping. noinline and used are
* used to prevent optimization
*/
__attribute__((noinline)) __attribute__((used))
void fih_panic_loop(void);
#define FIH_PANIC fih_panic_loop()
#else
#define FIH_PANIC while (1) {}
#endif /* FIH_ENABLE_GLOBAL_FAIL */
/* NOTE: For functions to be inlined outside their compilation unit they have to
* have the body in the header file. This is required as function calls are easy
* to skip.
*/
#ifdef FIH_ENABLE_DELAY
/* Delaying logic, with randomness from a CSPRNG */
__attribute__((always_inline)) inline
int fih_delay(void)
{
unsigned char delay;
int foo = 0;
volatile int rc;
delay = fih_delay_random_uchar();
for (volatile int i = 0; i < delay; i++) {
foo++;
}
rc = 1;
/* rc is volatile so if it is the return value then the function cannot be
* optimized
*/
return rc;
}
#else
__attribute__((always_inline)) inline
int fih_delay_init(void)
{
return 1;
}
__attribute__((always_inline)) inline
int fih_delay(void)
{
return 1;
}
#endif /* FIH_ENABLE_DELAY */
#ifdef FIH_ENABLE_DOUBLE_VARS
__attribute__((always_inline)) inline
void fih_int_validate(fih_int x)
{
if (x.val != (x.msk ^ _fih_mask)) {
FIH_PANIC;
}
}
/* Convert a fih_int to an int. Validate for tampering. */
__attribute__((always_inline)) inline
int fih_int_decode(fih_int x)
{
fih_int_validate(x);
return x.val;
}
/* Convert an int to a fih_int, can be used to encode specific error codes. */
__attribute__((always_inline)) inline
fih_int fih_int_encode(int x)
{
fih_int ret = {x, x ^ _fih_mask};
return ret;
}
/* Standard equality. If A == B then 1, else 0 */
__attribute__((always_inline)) inline
int fih_eq(fih_int x, fih_int y)
{
fih_int_validate(x);
fih_int_validate(y);
return (x.val == y.val) && fih_delay() && (x.msk == y.msk);
}
__attribute__((always_inline)) inline
int fih_not_eq(fih_int x, fih_int y)
{
fih_int_validate(x);
fih_int_validate(y);
return (x.val != y.val) && fih_delay() && (x.msk != y.msk);
}
#else
/* NOOP */
__attribute__((always_inline)) inline
void fih_int_validate(fih_int x)
{
(void) x;
return;
}
/* NOOP */
__attribute__((always_inline)) inline
int fih_int_decode(fih_int x)
{
return x;
}
/* NOOP */
__attribute__((always_inline)) inline
fih_int fih_int_encode(int x)
{
return x;
}
__attribute__((always_inline)) inline
int fih_eq(fih_int x, fih_int y)
{
return x == y;
}
__attribute__((always_inline)) inline
int fih_not_eq(fih_int x, fih_int y)
{
return x != y;
}
#endif /* FIH_ENABLE_DOUBLE_VARS */
/* C has a common return pattern where 0 is a correct value and all others are
* errors. This function converts 0 to FIH_SUCCESS and any other number to a
* value that is not FIH_SUCCESS
*/
__attribute__((always_inline)) inline
fih_int fih_int_encode_zero_equality(int x)
{
if (x) {
return FIH_FAILURE;
} else {
return FIH_SUCCESS;
}
}
#ifdef FIH_ENABLE_CFI
extern fih_int _fih_cfi_ctr;
#endif /* FIH_ENABLE_CFI */
fih_int fih_cfi_get_and_increment(void);
void fih_cfi_validate(fih_int saved);
void fih_cfi_decrement(void);
/* Label for interacting with FIH testing tool. Can be parsed from the elf file
* after compilation. Does not require debug symbols.
*/
#if defined(__ICCARM__)
#define FIH_LABEL(str, lin, cnt) __asm volatile ("FIH_LABEL_" str "_" #lin "_" #cnt "::" ::);
#else
#define FIH_LABEL(str) __asm volatile ("FIH_LABEL_" str "_%=:" ::);
#endif
/* Main FIH calling macro. return variable is second argument. Does some setup
* before and validation afterwards. Inserts labels for use with testing script.
*
* First perform the precall step - this gets the current value of the CFI
* counter and saves it to a local variable, and then increments the counter.
*
* Then set the return variable to FIH_FAILURE as a base case.
*
* Then perform the function call. As part of the funtion FIH_RET must be called
* which will decrement the counter.
*
* The postcall step gets the value of the counter and compares it to the
* previously saved value. If this is equal then the function call and all child
* function calls were performed.
*/
#if defined(__ICCARM__)
#define FIH_CALL(f, ret, ...) FIH_CALL2(f, ret, __LINE__, __COUNTER__, __VA_ARGS__)
#define FIH_CALL2(f, ret, l, c, ...) \
do { \
FIH_LABEL("FIH_CALL_START", l, c); \
FIH_CFI_PRECALL_BLOCK; \
ret = FIH_FAILURE; \
if (fih_delay()) { \
ret = f(__VA_ARGS__); \
} \
FIH_CFI_POSTCALL_BLOCK; \
FIH_LABEL("FIH_CALL_END", l, c); \
} while (0)
#else
#define FIH_CALL(f, ret, ...) \
do { \
FIH_LABEL("FIH_CALL_START"); \
FIH_CFI_PRECALL_BLOCK; \
ret = FIH_FAILURE; \
if (fih_delay()) { \
ret = f(__VA_ARGS__); \
} \
FIH_CFI_POSTCALL_BLOCK; \
FIH_LABEL("FIH_CALL_END"); \
} while (0)
#endif
/* FIH return changes the state of the internal state machine. If you do a
* FIH_CALL then you need to do a FIH_RET else the state machine will detect
* tampering and panic.
*/
#define FIH_RET(ret) \
do { \
FIH_CFI_PRERET; \
return ret; \
} while (0)
#ifdef FIH_ENABLE_CFI
/* Macro wrappers for functions - Even when the functions have zero body this
* saves a few bytes on noop functions as it doesn't generate the call/ret
*
* CFI precall function saves the CFI counter and then increments it - the
* postcall then checks if the counter is equal to the saved value. In order for
* this to be the case a FIH_RET must have been performed inside the called
* function in order to decrement the counter, so the function must have been
* called.
*/
#define FIH_CFI_PRECALL_BLOCK \
fih_int _fih_cfi_saved_value = fih_cfi_get_and_increment()
#define FIH_CFI_POSTCALL_BLOCK \
fih_cfi_validate(_fih_cfi_saved_value)
#define FIH_CFI_PRERET \
fih_cfi_decrement()
#else
#define FIH_CFI_PRECALL_BLOCK
#define FIH_CFI_POSTCALL_BLOCK
#define FIH_CFI_PRERET
#endif /* FIH_ENABLE_CFI */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __FAULT_INJECTION_HARDENING_H__ */
@@ -0,0 +1,30 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2020 Arm Limited
*/
#ifndef __FAULT_INJECTION_HARDENING_DELAY_RNG_H__
#define __FAULT_INJECTION_HARDENING_DELAY_RNG_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* \brief Set up the RNG for use with random delays. Called once at startup.
*/
int fih_delay_init(void);
/**
* \brief Get a random unsigned char from an RNG seeded with an entropy source.
*
* \return A random value that fits inside an unsigned char.
*/
unsigned char fih_delay_random_uchar(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __FAULT_INJECTION_HARDENING_DELAY_RNG_H__ */
@@ -0,0 +1,70 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2017 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.
*/
#ifndef H_IGNORE_
#define H_IGNORE_
#ifdef __cplusplus
extern "C" {
#endif
/**
* These macros prevent the "set but not used" warnings for log writes below
* the log level.
*/
#define IGN_1(X) ((void)(X))
#define IGN_2(X, ...) ((void)(X));IGN_1(__VA_ARGS__)
#define IGN_3(X, ...) ((void)(X));IGN_2(__VA_ARGS__)
#define IGN_4(X, ...) ((void)(X));IGN_3(__VA_ARGS__)
#define IGN_5(X, ...) ((void)(X));IGN_4(__VA_ARGS__)
#define IGN_6(X, ...) ((void)(X));IGN_5(__VA_ARGS__)
#define IGN_7(X, ...) ((void)(X));IGN_6(__VA_ARGS__)
#define IGN_8(X, ...) ((void)(X));IGN_7(__VA_ARGS__)
#define IGN_9(X, ...) ((void)(X));IGN_8(__VA_ARGS__)
#define IGN_10(X, ...) ((void)(X));IGN_9(__VA_ARGS__)
#define IGN_11(X, ...) ((void)(X));IGN_10(__VA_ARGS__)
#define IGN_12(X, ...) ((void)(X));IGN_11(__VA_ARGS__)
#define IGN_13(X, ...) ((void)(X));IGN_12(__VA_ARGS__)
#define IGN_14(X, ...) ((void)(X));IGN_13(__VA_ARGS__)
#define IGN_15(X, ...) ((void)(X));IGN_14(__VA_ARGS__)
#define IGN_16(X, ...) ((void)(X));IGN_15(__VA_ARGS__)
#define IGN_17(X, ...) ((void)(X));IGN_16(__VA_ARGS__)
#define IGN_18(X, ...) ((void)(X));IGN_17(__VA_ARGS__)
#define IGN_19(X, ...) ((void)(X));IGN_18(__VA_ARGS__)
#define IGN_20(X, ...) ((void)(X));IGN_19(__VA_ARGS__)
#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, \
_13, _14, _15, _16, _17, _18, _19, _20, NAME, ...) NAME
#define IGNORE(...) \
GET_MACRO(__VA_ARGS__, IGN_20, IGN_19, IGN_18, IGN_17, IGN_16, IGN_15, \
IGN_14, IGN_13, IGN_12, IGN_11, IGN_10, IGN_9, IGN_8, IGN_7, \
IGN_6, IGN_5, IGN_4, IGN_3, IGN_2, IGN_1)(__VA_ARGS__)
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,191 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2016-2019 Linaro LTD
* Copyright (c) 2016-2019 JUUL Labs
* Copyright (c) 2019-2020 Arm Limited
*
* 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.
*/
#ifndef H_IMAGE_
#define H_IMAGE_
#include <inttypes.h>
#include <stdbool.h>
#include "bootutil/fault_injection_hardening.h"
#ifdef __cplusplus
extern "C" {
#endif
struct flash_area;
#define IMAGE_MAGIC 0x96f3b83d
#define IMAGE_MAGIC_V1 0x96f3b83c
#define IMAGE_MAGIC_NONE 0xffffffff
#define IMAGE_TLV_INFO_MAGIC 0x6907
#define IMAGE_TLV_PROT_INFO_MAGIC 0x6908
#define IMAGE_HEADER_SIZE 32
/*
* Image header flags.
*/
#define IMAGE_F_PIC 0x00000001 /* Not supported. */
#define IMAGE_F_NON_BOOTABLE 0x00000010 /* Split image app. */
#define IMAGE_F_ENCRYPTED 0x00000004 /* Encrypted. */
/*
* Indicates that this image should be loaded into RAM instead of run
* directly from flash. The address to load should be in the
* ih_load_addr field of the header.
*/
#define IMAGE_F_RAM_LOAD 0x00000020
/*
* ECSDA224 is with NIST P-224
* ECSDA256 is with NIST P-256
*/
/*
* Image trailer TLV types.
*
* Signature is generated by computing signature over the image hash.
* Currently the only image hash type is SHA256.
*
* Signature comes in the form of 2 TLVs.
* 1st on identifies the public key which should be used to verify it.
* 2nd one is the actual signature.
*/
#define IMAGE_TLV_KEYHASH 0x01 /* hash of the public key */
#define IMAGE_TLV_PUBKEY 0x02 /* public key */
#define IMAGE_TLV_SHA256 0x10 /* SHA256 of image hdr and body */
#define IMAGE_TLV_RSA2048_PSS 0x20 /* RSA2048 of hash output */
#define IMAGE_TLV_ECDSA224 0x21 /* ECDSA of hash output */
#define IMAGE_TLV_ECDSA256 0x22 /* ECDSA of hash output */
#define IMAGE_TLV_RSA3072_PSS 0x23 /* RSA3072 of hash output */
#define IMAGE_TLV_ED25519 0x24 /* ed25519 of hash output */
#define IMAGE_TLV_ENC_RSA2048 0x30 /* Key encrypted with RSA-OAEP-2048 */
#define IMAGE_TLV_ENC_KW128 0x31 /* Key encrypted with AES-KW-128 */
#define IMAGE_TLV_ENC_EC256 0x32 /* Key encrypted with ECIES-EC256 */
#define IMAGE_TLV_ENC_X25519 0x33 /* Key encrypted with ECIES-X25519 */
#define IMAGE_TLV_DEPENDENCY 0x40 /* Image depends on other image */
#define IMAGE_TLV_SEC_CNT 0x50 /* security counter */
#define IMAGE_TLV_BOOT_RECORD 0x60 /* measured boot record */
/*
* vendor reserved TLVs at xxA0-xxFF,
* where xx denotes the upper byte
* range. Examples:
* 0x00a0 - 0x00ff
* 0x01a0 - 0x01ff
* 0x02a0 - 0x02ff
* ...
* 0xffa0 - 0xfffe
*/
#define IMAGE_TLV_CUSTOM_TI_ADD_KEY 0xCC /* Custom TLV to add key based on hash */
#define IMAGE_TLV_CUSTOM_TI_REVOKE_KEY 0xCD /* Custom TLV to revoke key based on hash */
#define IMAGE_TLV_ANY 0xffff /* Used to iterate over all TLV */
struct image_version {
uint8_t iv_major;
uint8_t iv_minor;
uint16_t iv_revision;
uint32_t iv_build_num;
};
struct image_dependency {
uint8_t image_id; /* Image index (from 0) */
uint8_t _pad1;
uint16_t _pad2;
struct image_version image_min_version; /* Indicates at minimum which
* version of firmware must be
* available to satisfy compliance
*/
};
/** Image header. All fields are in little endian byte order. */
struct image_header {
uint32_t ih_magic;
uint32_t ih_load_addr;
uint16_t ih_hdr_size; /* Size of image header (bytes). */
uint16_t ih_protect_tlv_size; /* Size of protected TLV area (bytes). */
uint32_t ih_img_size; /* Does not include header. */
uint32_t ih_flags; /* IMAGE_F_[...]. */
struct image_version ih_ver;
uint32_t _pad1;
};
/** Image TLV header. All fields in little endian. */
struct image_tlv_info {
uint16_t it_magic;
uint16_t it_tlv_tot; /* size of TLV area (including tlv_info header) */
};
/** Image trailer TLV format. All fields in little endian. */
struct image_tlv {
uint16_t it_type; /* IMAGE_TLV_[...]. */
uint16_t it_len; /* Data length (not including TLV header). */
};
#define IS_ENCRYPTED(hdr) ((hdr)->ih_flags & IMAGE_F_ENCRYPTED)
#define MUST_DECRYPT(fap, idx, hdr) \
((fap)->fa_id == FLASH_AREA_IMAGE_SECONDARY(idx) && IS_ENCRYPTED(hdr))
_Static_assert(sizeof(struct image_header) == IMAGE_HEADER_SIZE,
"struct image_header not required size");
struct enc_key_data;
fih_int bootutil_img_validate(struct enc_key_data *enc_state, int image_index,
struct image_header *hdr,
const struct flash_area *fap,
uint8_t *tmp_buf, uint32_t tmp_buf_sz,
uint8_t *seed, int seed_len, uint8_t *out_hash);
struct image_tlv_iter {
const struct image_header *hdr;
const struct flash_area *fap;
uint16_t type;
bool prot;
uint32_t prot_end;
uint32_t tlv_off;
uint32_t tlv_end;
};
int bootutil_tlv_iter_begin(struct image_tlv_iter *it,
const struct image_header *hdr,
const struct flash_area *fap, uint16_t type,
bool prot);
int bootutil_tlv_iter_next(struct image_tlv_iter *it, uint32_t *off,
uint16_t *len, uint16_t *type);
int32_t bootutil_get_img_security_cnt(struct image_header *hdr,
const struct flash_area *fap,
uint32_t *security_cnt);
int boot_compare_version(struct image_version *ver1,
volatile const struct image_version *ver2);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,103 @@
/*
* Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __SECURITY_CNT_H__
#define __SECURITY_CNT_H__
/**
* @file security_cnt.h
*
* @note The interface must be implemented in a fail-safe way that is
* resistant to asynchronous power failures or it can use hardware
* counters that have this capability, if supported by the platform.
* When a counter incrementation was interrupted it must be able to
* continue the incrementation process or recover the previous consistent
* status of the counters. If the counters have reached a stable status
* (every counter incrementation operation has finished), from that point
* their value cannot decrease due to any kind of power failure.
*
* @note A security counter might be implemented using non-volatile OTP memory
* (i.e. fuses) in which case it is the responsibility of the platform
* code to map each possible security counter values onto the fuse bits
* as the direct usage of counter values can be costly / impractical.
*/
#include <stdint.h>
#include "bootutil/fault_injection_hardening.h"
#ifdef __cplusplus
extern "C" {
#endif
#define BIM_INFO_PAGE_MAGIC 0x96fa
#define BIM_INFO_PAGE_ERASED 0xFFFF
#define BIM_INFO_MAGIC_SZ 2
#define BIM_ITEM_SZ 10
#define BIMINFO_SUCCESS 0
#define BIMINFO_FAIL 22
#define BIMINFO_FULL 0xFF
/* each item consists of status (2 bytes) + image id (4 bytes) + security counter (4 bytes) + item id (2 bytes) */
#define SC_ITEM_ID 0x9373
#define SC_STATUS_EMPTY 0xFFFF
#define SC_STATUS_VALID 0xFCFC
#define SC_STATUS_INVALID 0xF0F0
typedef struct sc_page_head {
uint16_t sc_page_id;
}sc_page_head_t;
typedef struct sc_item {
uint16_t sc_status;
uint16_t image_id;
uint32_t security_counter;
uint16_t item_id;
}sc_item_t;
/**
* Initialises the security counters.
*
* @return FIH_SUCCESS on success
*/
fih_int boot_nv_security_counter_init(void);
/**
* Reads the stored value of a given image's security counter.
*
* @param image_id Index of the image (from 0).
* @param security_cnt Pointer to store the security counter value.
*
* @return FIH_SUCCESS on success
*/
fih_int boot_nv_security_counter_get(uint32_t image_id, fih_int *security_cnt);
/**
* Updates the stored value of a given image's security counter with a new
* security counter value if the new one is greater.
*
* @param image_id Index of the image (from 0).
* @param img_security_cnt New security counter value. The new value must be
* between 0 and UINT32_MAX and it must be greater than
* or equal to the current security counter value.
*
* @return 0 on success; nonzero on failure.
*/
int32_t boot_nv_security_counter_update(uint32_t image_id,
uint32_t img_security_cnt);
/**
* Lock the BIM INFO sector
*/
void lockBimSector(void);
#ifdef __cplusplus
}
#endif
#endif /* __SECURITY_CNT_H__ */
@@ -0,0 +1,68 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*/
#ifndef __BOOTUTIL_SIGN_KEY_H_
#define __BOOTUTIL_SIGN_KEY_H_
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef MCUBOOT_HW_KEY
struct bootutil_key {
const uint8_t *key;
const unsigned int *len;
};
extern const struct bootutil_key bootutil_keys[];
#else
struct bootutil_key {
uint8_t *key;
unsigned int *len;
};
extern struct bootutil_key bootutil_keys[];
/**
* Retrieve the hash of the corresponding public key for image authentication.
*
* @param[in] image_index Index of the image to be authenticated.
* @param[out] public_key_hash Buffer to store the key-hash in.
* @param[in,out] key_hash_size As input the size of the buffer. As output
* the actual key-hash length.
*
* @return 0 on success; nonzero on failure.
*/
int boot_retrieve_public_key_hash(uint8_t image_index,
uint8_t *public_key_hash,
size_t *key_hash_size);
#endif /* !MCUBOOT_HW_KEY */
extern const int bootutil_key_cnt;
#ifdef __cplusplus
}
#endif
#endif /* __BOOTUTIL_SIGN_KEY_H_ */