Initial commit
Initial commit.
This commit is contained in:
68
bootloader/mcuboot/boot/bootutil/include/bootutil/bench.h
Normal file
68
bootloader/mcuboot/boot/bootutil/include/bootutil/bench.h
Normal file
@@ -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__ */
|
||||
181
bootloader/mcuboot/boot/bootutil/include/bootutil/boot_hooks.h
Normal file
181
bootloader/mcuboot/boot/bootutil/include/bootutil/boot_hooks.h
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright (c) 2021 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 Hooks definition implementation API
|
||||
*
|
||||
* This file contains API interface definition for hooks which can be
|
||||
* implemented to overide or to amend some of MCUboot's native routines.
|
||||
*/
|
||||
|
||||
#ifndef H_BOOTUTIL_HOOKS
|
||||
#define H_BOOTUTIL_HOOKS
|
||||
|
||||
#ifdef MCUBOOT_IMAGE_ACCESS_HOOKS
|
||||
|
||||
#define BOOT_HOOK_CALL(f, ret_default, ...) f(__VA_ARGS__)
|
||||
|
||||
#define BOOT_HOOK_CALL_FIH(f, fih_ret_default, fih_rc, ...) \
|
||||
do { \
|
||||
FIH_CALL(f, fih_rc, __VA_ARGS__); \
|
||||
} while(0);
|
||||
|
||||
#else
|
||||
|
||||
#define BOOT_HOOK_CALL(f, ret_default, ...) ret_default
|
||||
|
||||
#define BOOT_HOOK_CALL_FIH(f, fih_ret_default, fih_rc, ...) \
|
||||
do { \
|
||||
fih_rc = fih_ret_default; \
|
||||
} while(0);
|
||||
|
||||
#endif
|
||||
|
||||
/** Hook for provide image header data.
|
||||
*
|
||||
* This Hook may be used to overide image header read implementation or doing
|
||||
* a custom action before.
|
||||
*
|
||||
* @param img_index the index of the image pair
|
||||
* @param slot slot number
|
||||
* @param img_head image header structure to be populated
|
||||
*
|
||||
* @retval 0: header was read/populated, skip direct header data read
|
||||
* BOOT_HOOK_REGULAR: follow the normal execution path,
|
||||
* otherwise an error-code value.
|
||||
*/
|
||||
int boot_read_image_header_hook(int img_index, int slot,
|
||||
struct image_header *img_head);
|
||||
|
||||
/** Hook for Validate image hash/signature
|
||||
*
|
||||
* This Hook may be used to overide image validation procedure or doing
|
||||
* a custom action before.
|
||||
*
|
||||
* @param img_index the index of the image pair
|
||||
* @param slot slot number
|
||||
*
|
||||
* @retval FIH_SUCCESS: image is valid, skip direct validation
|
||||
* FIH_FAILURE: image is invalid, skip direct validation
|
||||
* FIH_BOOT_HOOK_REGULAR: follow the normal execution path.
|
||||
*/
|
||||
fih_ret boot_image_check_hook(int img_index, int slot);
|
||||
|
||||
/** Hook for implement image update
|
||||
*
|
||||
* This hook is for for implementing an alternative mechanism of image update or
|
||||
* doing a custom action before.
|
||||
*
|
||||
* @param img_index the index of the image pair
|
||||
* @param img_head the image header of the secondary image
|
||||
* @param area the flash area of the secondary image.
|
||||
*
|
||||
* @retval 0: update was done, skip performing the update
|
||||
* BOOT_HOOK_REGULAR: follow the normal execution path,
|
||||
* otherwise an error-code value.
|
||||
*/
|
||||
int boot_perform_update_hook(int img_index, struct image_header *img_head,
|
||||
const struct flash_area *area);
|
||||
|
||||
/** Hook for implement image's post copying action
|
||||
*
|
||||
* This hook is for implement action which might be done right after image was
|
||||
* copied to the primary slot. This hook is called in MCUBOOT_OVERWRITE_ONLY
|
||||
* mode only.
|
||||
*
|
||||
* @param img_index the index of the image pair
|
||||
* @param area the flash area of the primary image.
|
||||
* @param size size of copied image.
|
||||
*
|
||||
* @retval 0: success, mcuboot will follow normal code execution flow after
|
||||
* execution of this call.
|
||||
* non-zero: an error, mcuboot will return from
|
||||
* boot_copy_image() with error.
|
||||
* Update will be undone so might be resume on the next boot.
|
||||
*/
|
||||
int boot_copy_region_post_hook(int img_index, const struct flash_area *area,
|
||||
size_t size);
|
||||
|
||||
/** Hook for implement image's post recovery upload action
|
||||
*
|
||||
* This hook is for implement action which might be done right after image was
|
||||
* copied to the primary slot. This hook is called in serial recovery upload
|
||||
* operation.
|
||||
*
|
||||
* @param img_index the index of the image pair
|
||||
* @param area the flash area of the primary image.
|
||||
* @param size size of copied image.
|
||||
*
|
||||
* @retval 0: success, mcuboot will follow normal code execution flow after
|
||||
* execution of this call.
|
||||
* non-zero: an error, will be transferred as part of comand response
|
||||
* as "rc" entry.
|
||||
*/
|
||||
int boot_serial_uploaded_hook(int img_index, const struct flash_area *area,
|
||||
size_t size);
|
||||
|
||||
/** Hook for implement the image's slot installation status fetch operation for
|
||||
* the MGMT custom command.
|
||||
*
|
||||
* The image's slot installation status is custom property. It's detailed
|
||||
* definition depends on user implementation. It is only defined that the status
|
||||
* will be set to 0 if this hook not provides another value.
|
||||
*
|
||||
* @param img_index the index of the image pair
|
||||
* @param slot slot number
|
||||
* @param img_install_stat the image installation status to be populated
|
||||
*
|
||||
* @retval 0: the installaton status was fetched successfully,
|
||||
* BOOT_HOOK_REGULAR: follow the normal execution path, status will be
|
||||
* set to 0
|
||||
* otherwise an error-code value. Error-code is ignored, but it is up to
|
||||
* the implementation to reflect this error in img_install_stat.
|
||||
*/
|
||||
int boot_img_install_stat_hook(int image_index, int slot,
|
||||
int *img_install_stat);
|
||||
|
||||
/** Hook will be invoked when boot_serial requests device reset.
|
||||
* The hook may be used to prevent device reset.
|
||||
*
|
||||
* @param force set to true when request tries to force reset.
|
||||
*
|
||||
* @retval 0 when reset should be performed;
|
||||
* BOOT_RESET_REQUEST_HOOK_BUSY when some processing is still in
|
||||
* progress;
|
||||
* BOOT_RESET_REQUEST_HOOK_TIMEOUT internal process timed out;
|
||||
* BOOT_RESET_REQUEST_HOOK_CHECK_FAILED internal code failed to
|
||||
* obtian status;
|
||||
* BOOT_RESET_REQUEST_HOOK_INTERNAL_ERROR unspecified internal
|
||||
* error while checking status.
|
||||
*/
|
||||
int boot_reset_request_hook(bool force);
|
||||
|
||||
#define BOOT_RESET_REQUEST_HOOK_BUSY 1
|
||||
#define BOOT_RESET_REQUEST_HOOK_TIMEOUT 2
|
||||
#define BOOT_RESET_REQUEST_HOOK_CHECK_FAILED 3
|
||||
#define BOOT_RESET_REQUEST_HOOK_INTERNAL_ERROR 4
|
||||
|
||||
#endif /*H_BOOTUTIL_HOOKS*/
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright (c) 2021 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 Hooks definition implementation API
|
||||
*
|
||||
* This file contains API interface definition for hooks which can be
|
||||
* implemented for overide some of MCUboot's native routines.
|
||||
*/
|
||||
|
||||
#ifndef H_BOOTUTIL_PUBLIC_HOOKS
|
||||
#define H_BOOTUTIL_PUBLIC_HOOKS
|
||||
|
||||
#include "bootutil/boot_hooks.h"
|
||||
|
||||
/** Hook for provide primary image swap state.
|
||||
*
|
||||
* @param img_index the index of the image pair
|
||||
* @param state image swap state structure to be populated
|
||||
*
|
||||
* @retval 0: header was read/populated
|
||||
* FIH_FAILURE: image is invalid,
|
||||
* BOOT_HOOK_REGULAR if hook not implemented for the image-slot,
|
||||
* othervise an error-code value.
|
||||
*/
|
||||
int boot_read_swap_state_primary_slot_hook(int image_index,
|
||||
struct boot_swap_state *state);
|
||||
|
||||
#endif /*H_BOOTUTIL_PUBLIC_HOOKS*/
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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 <stddef.h>
|
||||
#include "bootutil/image.h"
|
||||
#include "bootutil/bootutil.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Error codes for using the shared memory area. */
|
||||
enum shared_memory_status {
|
||||
SHARED_MEMORY_OK = 0,
|
||||
SHARED_MEMORY_OVERFLOW,
|
||||
SHARED_MEMORY_OVERWRITE,
|
||||
SHARED_MEMORY_GEN_ERROR,
|
||||
SHARED_MEMORY_WRITE_ERROR,
|
||||
SHARED_MEMORY_READ_ERROR,
|
||||
};
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* @param[in] slot The currently active slot being booted.
|
||||
* @param[in] max_app_sizes The maximum sizes of images that can be loaded.
|
||||
*
|
||||
* @return 0 on success; nonzero on failure.
|
||||
*/
|
||||
int boot_save_shared_data(const struct image_header *hdr,
|
||||
const struct flash_area *fap,
|
||||
const uint8_t active_slot,
|
||||
const struct image_max_size *max_app_sizes);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BOOT_RECORD_H__ */
|
||||
188
bootloader/mcuboot/boot/bootutil/include/bootutil/boot_status.h
Normal file
188
bootloader/mcuboot/boot/bootutil/include/bootutil/boot_status.h
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* 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
|
||||
#define TLV_MAJOR_BLINFO 0x2
|
||||
|
||||
/* 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))
|
||||
|
||||
/* Bootloader information */
|
||||
#define BLINFO_MODE 0x00
|
||||
#define BLINFO_SIGNATURE_TYPE 0x01
|
||||
#define BLINFO_RECOVERY 0x02
|
||||
#define BLINFO_RUNNING_SLOT 0x03
|
||||
#define BLINFO_BOOTLOADER_VERSION 0x04
|
||||
#define BLINFO_MAX_APPLICATION_SIZE 0x05 /* Same as BLINFO_MAX_APPLICATION_SIZE_IMAGE_0, legacy name */
|
||||
#define BLINFO_MAX_APPLICATION_SIZE_IMAGE_0 BLINFO_MAX_APPLICATION_SIZE
|
||||
#define BLINFO_MAX_APPLICATION_SIZE_IMAGE_1 0x06
|
||||
#define BLINFO_MAX_APPLICATION_SIZE_IMAGE_2 0x07
|
||||
#define BLINFO_MAX_APPLICATION_SIZE_IMAGE_3 0x08
|
||||
#define BLINFO_MAX_APPLICATION_SIZE_IMAGE_4 0x09
|
||||
|
||||
enum mcuboot_mode {
|
||||
MCUBOOT_MODE_SINGLE_SLOT,
|
||||
MCUBOOT_MODE_SWAP_USING_SCRATCH,
|
||||
MCUBOOT_MODE_UPGRADE_ONLY,
|
||||
MCUBOOT_MODE_SWAP_USING_MOVE,
|
||||
MCUBOOT_MODE_DIRECT_XIP,
|
||||
MCUBOOT_MODE_DIRECT_XIP_WITH_REVERT,
|
||||
MCUBOOT_MODE_RAM_LOAD,
|
||||
MCUBOOT_MODE_FIRMWARE_LOADER
|
||||
};
|
||||
|
||||
enum mcuboot_signature_type {
|
||||
MCUBOOT_SIGNATURE_TYPE_NONE,
|
||||
MCUBOOT_SIGNATURE_TYPE_RSA,
|
||||
MCUBOOT_SIGNATURE_TYPE_ECDSA_P256,
|
||||
MCUBOOT_SIGNATURE_TYPE_ED25519
|
||||
};
|
||||
|
||||
enum mcuboot_recovery_mode {
|
||||
MCUBOOT_RECOVERY_MODE_NONE,
|
||||
MCUBOOT_RECOVERY_MODE_SERIAL_RECOVERY,
|
||||
MCUBOOT_RECOVERY_MODE_DFU,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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__ */
|
||||
104
bootloader/mcuboot/boot/bootutil/include/bootutil/bootutil.h
Normal file
104
bootloader/mcuboot/boot/bootutil/include/bootutil/bootutil.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright (c) 2017-2019 Linaro LTD
|
||||
* Copyright (c) 2016-2019 JUUL Labs
|
||||
* Copyright (c) 2019-2021 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
|
||||
|
||||
#ifdef MCUBOOT_IMAGE_NUMBER
|
||||
#define BOOT_IMAGE_NUMBER MCUBOOT_IMAGE_NUMBER
|
||||
#else
|
||||
#define BOOT_IMAGE_NUMBER 1
|
||||
#endif
|
||||
|
||||
_Static_assert(BOOT_IMAGE_NUMBER > 0, "Invalid value for BOOT_IMAGE_NUMBER");
|
||||
|
||||
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];
|
||||
#if BOOT_MAX_ALIGN > BOOT_MAGIC_SZ
|
||||
uint8_t pad4[BOOT_MAGIC_ALIGN_SIZE - BOOT_MAGIC_SZ];
|
||||
#endif
|
||||
uint8_t magic[BOOT_MAGIC_SZ];
|
||||
};
|
||||
|
||||
struct image_max_size {
|
||||
bool calculated;
|
||||
uint32_t max_size;
|
||||
};
|
||||
|
||||
/* you must have pre-allocated all the entries within this structure */
|
||||
fih_ret boot_go(struct boot_rsp *rsp);
|
||||
fih_ret boot_go_for_image_id(struct boot_rsp *rsp, uint32_t image_id);
|
||||
|
||||
struct boot_loader_state;
|
||||
void boot_state_clear(struct boot_loader_state *state);
|
||||
fih_ret context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp);
|
||||
const struct image_max_size *boot_get_max_app_size(void);
|
||||
|
||||
#define SPLIT_GO_OK (0)
|
||||
#define SPLIT_GO_NON_MATCHING (-1)
|
||||
#define SPLIT_GO_ERR (-2)
|
||||
|
||||
fih_ret split_go(int loader_slot, int split_slot, void **entry);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
#ifdef MCUBOOT_HAVE_LOGGING
|
||||
#include <mcuboot_config/mcuboot_logging.h>
|
||||
|
||||
#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__)
|
||||
|
||||
#define BOOT_LOG_MODULE_DECLARE(module) MCUBOOT_LOG_MODULE_DECLARE(module)
|
||||
#define BOOT_LOG_MODULE_REGISTER(module) MCUBOOT_LOG_MODULE_REGISTER(module)
|
||||
|
||||
#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__)
|
||||
|
||||
#define BOOT_LOG_MODULE_DECLARE(module)
|
||||
#define BOOT_LOG_MODULE_REGISTER(module)
|
||||
|
||||
#endif /* MCUBOOT_HAVE_LOGGING */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright (c) 2017-2019 Linaro LTD
|
||||
* Copyright (c) 2016-2019 JUUL Labs
|
||||
* Copyright (c) 2019-2021 Arm Limited
|
||||
* Copyright (c) 2020-2021 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 <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <flash_map_backend/flash_map_backend.h>
|
||||
#include <mcuboot_config/mcuboot_config.h>
|
||||
#include <bootutil/image.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef ALIGN_UP
|
||||
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
|
||||
#endif
|
||||
|
||||
#ifndef ALIGN_DOWN
|
||||
#define ALIGN_DOWN(num, align) ((num) & ~((align) - 1))
|
||||
#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_MAGIC_SZ 16
|
||||
|
||||
#ifdef MCUBOOT_BOOT_MAX_ALIGN
|
||||
|
||||
#if defined(MCUBOOT_SWAP_USING_MOVE) || defined(MCUBOOT_SWAP_USING_SCRATCH)
|
||||
_Static_assert(MCUBOOT_BOOT_MAX_ALIGN >= 8 && MCUBOOT_BOOT_MAX_ALIGN <= 32,
|
||||
"Unsupported value for MCUBOOT_BOOT_MAX_ALIGN for SWAP upgrade modes");
|
||||
#endif
|
||||
|
||||
#define BOOT_MAX_ALIGN MCUBOOT_BOOT_MAX_ALIGN
|
||||
#define BOOT_MAGIC_ALIGN_SIZE ALIGN_UP(BOOT_MAGIC_SZ, BOOT_MAX_ALIGN)
|
||||
#else
|
||||
#define BOOT_MAX_ALIGN 8
|
||||
#define BOOT_MAGIC_ALIGN_SIZE BOOT_MAGIC_SZ
|
||||
#endif
|
||||
|
||||
#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_EFLASH 1
|
||||
#define BOOT_EFILE 2
|
||||
#define BOOT_EBADIMAGE 3
|
||||
#define BOOT_EBADVECT 4
|
||||
#define BOOT_EBADSTATUS 5
|
||||
#define BOOT_ENOMEM 6
|
||||
#define BOOT_EBADARGS 7
|
||||
#define BOOT_EBADVERSION 8
|
||||
#define BOOT_EFLASH_SEC 9
|
||||
|
||||
#define BOOT_HOOK_REGULAR 1
|
||||
/*
|
||||
* Extract the swap type and image number from image trailers's swap_info
|
||||
* filed.
|
||||
*/
|
||||
#define BOOT_GET_SWAP_TYPE(swap_info) ((swap_info) & 0x0F)
|
||||
#define BOOT_GET_IMAGE_NUM(swap_info) ((swap_info) >> 4)
|
||||
|
||||
/* Construct the swap_info field from swap type and image number */
|
||||
#define BOOT_SET_SWAP_INFO(swap_info, image, type) { \
|
||||
assert((image) < 0xF); \
|
||||
assert((type) < 0xF); \
|
||||
(swap_info) = (image) << 4 \
|
||||
| (type); \
|
||||
}
|
||||
#ifdef MCUBOOT_HAVE_ASSERT_H
|
||||
#include "mcuboot_config/mcuboot_assert.h"
|
||||
#else
|
||||
#include <assert.h>
|
||||
#ifndef ASSERT
|
||||
#define ASSERT assert
|
||||
#endif
|
||||
#endif
|
||||
|
||||
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 with the given index 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 image_index Image pair index.
|
||||
*
|
||||
* @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_multi(int image_index, int permanent);
|
||||
|
||||
/**
|
||||
* Marks the image with index 0 in the secondary slot as pending. On the next
|
||||
* reboot, the system will perform a one-time boot of the the secondary slot
|
||||
* image. Note that this API is kept for compatibility. The
|
||||
* boot_set_pending_multi() API is recommended.
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Marks the image with the given index 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.
|
||||
*
|
||||
* @param image_index Image pair index.
|
||||
*
|
||||
* @return 0 on success; nonzero on failure.
|
||||
*/
|
||||
int boot_set_confirmed_multi(int image_index);
|
||||
|
||||
/**
|
||||
* Marks the image with index 0 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. Note that this API is kept for compatibility. The
|
||||
* boot_set_confirmed_multi() API is recommended.
|
||||
*
|
||||
* @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 partition from which state will be read;
|
||||
* @param state pointer to structure for storing swap state.
|
||||
*
|
||||
* @return 0 on success; non-zero error code on failure;
|
||||
*/
|
||||
int
|
||||
boot_read_swap_state_by_id(int flash_area_id, struct boot_swap_state *state);
|
||||
|
||||
/**
|
||||
* @brief Read the image swap state
|
||||
*
|
||||
* @param fa pointer to flash_area object;
|
||||
* @param state pointer to structure for storing swap state.
|
||||
*
|
||||
* @return 0 on success; non-zero error code on failure.
|
||||
*/
|
||||
int
|
||||
boot_read_swap_state(const struct flash_area *fa,
|
||||
struct boot_swap_state *state);
|
||||
|
||||
/**
|
||||
* @brief Set next image application slot by flash area pointer
|
||||
*
|
||||
* @param fa pointer to flash_area representing image to set for next boot;
|
||||
* @param active should be true if @fa points to currently running image
|
||||
* slot, false otherwise;
|
||||
* @param confirm confirms image; when @p active is true, this is considered
|
||||
* true, regardless of passed value.
|
||||
*
|
||||
* It is users responsibility to identify whether @p fa provided as parameter
|
||||
* is currently running/active image and provide proper value to @p active.
|
||||
* Failing to do so may render device non-upgradeable.
|
||||
*
|
||||
* Note that in multi-image setup running/active application is the one
|
||||
* that is currently being executed by any MCU core, from the pair of
|
||||
* slots dedicated to that MCU core. As confirming application currently
|
||||
* running on a given slot should be, preferably, done after functional
|
||||
* tests prove application to function correctly, it may not be a good idea
|
||||
* to cross-confirm running images.
|
||||
* An application should only confirm slots designated to MCU core it is
|
||||
* running on.
|
||||
*
|
||||
* @return 0 on success; non-zero error code on failure.
|
||||
*/
|
||||
int
|
||||
boot_set_next(const struct flash_area *fa, bool active, bool confirm);
|
||||
|
||||
/**
|
||||
* Attempts to load image header from flash; verifies flash header fields.
|
||||
*
|
||||
* @param[in] fa_p flash area pointer
|
||||
* @param[out] hdr buffer for image header
|
||||
*
|
||||
* @return 0 on success, error code otherwise
|
||||
*/
|
||||
int
|
||||
boot_image_load_header(const struct flash_area *fa_p,
|
||||
struct image_header *hdr);
|
||||
|
||||
#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
|
||||
67
bootloader/mcuboot/boot/bootutil/include/bootutil/caps.h
Normal file
67
bootloader/mcuboot/boot/bootutil/include/bootutil/caps.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Linaro Limited
|
||||
* Copyright (c) 2021-2023 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 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)
|
||||
/* reserved (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)
|
||||
#define BOOTUTIL_CAP_AES256 (1<<15)
|
||||
#define BOOTUTIL_CAP_RAM_LOAD (1<<16)
|
||||
#define BOOTUTIL_CAP_DIRECT_XIP (1<<17)
|
||||
#define BOOTUTIL_CAP_HW_ROLLBACK_PROT (1<<18)
|
||||
#define BOOTUTIL_CAP_ECDSA_P384 (1<<19)
|
||||
|
||||
/*
|
||||
* 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,158 @@
|
||||
/*
|
||||
* 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) + defined(MCUBOOT_USE_PSA_CRYPTO)) != 1
|
||||
#error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT or PSA"
|
||||
#endif
|
||||
|
||||
#if defined(MCUBOOT_USE_MBED_TLS)
|
||||
#include <mbedtls/aes.h>
|
||||
#include "bootutil/enc_key_public.h"
|
||||
#define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE BOOT_ENC_KEY_SIZE
|
||||
#define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE (16)
|
||||
#endif /* MCUBOOT_USE_MBED_TLS */
|
||||
|
||||
#if defined(MCUBOOT_USE_TINYCRYPT)
|
||||
#if defined(MCUBOOT_AES_256)
|
||||
#error "Cannot use AES-256 for encryption with Tinycrypt library."
|
||||
#endif
|
||||
#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 */
|
||||
|
||||
|
||||
#if defined(MCUBOOT_USE_PSA_CRYPTO)
|
||||
#include <psa/crypto.h>
|
||||
#include "bootutil/enc_key_public.h"
|
||||
#define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE BOOT_ENC_KEY_SIZE
|
||||
#define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE (16)
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MCUBOOT_USE_PSA_CRYPTO)
|
||||
typedef struct {
|
||||
/* Fixme: This should not be, here, psa_key_id should be passed */
|
||||
uint8_t key[BOOT_ENC_KEY_SIZE];
|
||||
} bootutil_aes_ctr_context;
|
||||
|
||||
void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx);
|
||||
|
||||
static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(ctx));
|
||||
}
|
||||
|
||||
static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k)
|
||||
{
|
||||
memcpy(ctx->key, k, sizeof(ctx->key));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
#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)
|
||||
{
|
||||
mbedtls_aes_free(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,142 @@
|
||||
/*
|
||||
* 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)
|
||||
#if defined(MCUBOOT_AES_256)
|
||||
#error "Cannot use AES-256 for encryption with Tinycrypt library."
|
||||
#endif
|
||||
#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)
|
||||
{
|
||||
mbedtls_nist_kw_free(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,29 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright (c) 2021 Arm Limited
|
||||
*/
|
||||
|
||||
#ifndef __BOOTUTIL_CRYPTO_COMMON_H__
|
||||
#define __BOOTUTIL_CRYPTO_COMMON_H__
|
||||
|
||||
/* The check below can be performed even for those cases
|
||||
* where MCUBOOT_USE_MBED_TLS has not been defined
|
||||
*/
|
||||
#include "mbedtls/version.h"
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
#define MBEDTLS_CONTEXT_MEMBER(X) MBEDTLS_PRIVATE(X)
|
||||
#else
|
||||
#define MBEDTLS_CONTEXT_MEMBER(X) X
|
||||
#endif
|
||||
|
||||
/* Newer versions of Mbed TLS have removed the private accessor requirement for
|
||||
* the ASN1 fields.
|
||||
*/
|
||||
#if (MBEDTLS_VERSION_NUMBER >= 0x03000000) && (MBEDTLS_VERSION_NUMBER < 0x03010000)
|
||||
#define ASN1_CONTEXT_MEMBER(X) MBEDTLS_PRIVATE(X)
|
||||
#else
|
||||
#define ASN1_CONTEXT_MEMBER(X) X
|
||||
#endif
|
||||
|
||||
#endif /* __BOOTUTIL_CRYPTO_COMMON_H__ */
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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_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/ecp.h>
|
||||
#include <mbedtls/ecdh.h>
|
||||
#define EC256_PUBK_LEN (65)
|
||||
#endif /* MCUBOOT_USE_MBED_TLS */
|
||||
|
||||
#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;
|
||||
|
||||
if (pk[0] != 0x04) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = uECC_valid_public_key(&pk[1], uECC_secp256r1());
|
||||
if (rc != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = uECC_shared_secret(&pk[1], sk, z, uECC_secp256r1());
|
||||
if (rc != TC_CRYPTO_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* MCUBOOT_USE_TINYCRYPT */
|
||||
|
||||
#if defined(MCUBOOT_USE_MBED_TLS)
|
||||
#define NUM_ECC_BYTES 32
|
||||
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
static int fake_rng(void *p_rng, unsigned char *output, size_t len);
|
||||
#endif
|
||||
|
||||
typedef struct bootutil_ecdh_p256_context {
|
||||
mbedtls_ecp_group grp;
|
||||
mbedtls_ecp_point P;
|
||||
mbedtls_mpi z;
|
||||
mbedtls_mpi d;
|
||||
} bootutil_ecdh_p256_context;
|
||||
|
||||
static inline void bootutil_ecdh_p256_init(bootutil_ecdh_p256_context *ctx)
|
||||
{
|
||||
mbedtls_mpi_init(&ctx->z);
|
||||
mbedtls_mpi_init(&ctx->d);
|
||||
|
||||
mbedtls_ecp_group_init(&ctx->grp);
|
||||
mbedtls_ecp_point_init(&ctx->P);
|
||||
|
||||
if (mbedtls_ecp_group_load(&ctx->grp, MBEDTLS_ECP_DP_SECP256R1) != 0) {
|
||||
mbedtls_ecp_group_free(&ctx->grp);
|
||||
mbedtls_ecp_point_free(&ctx->P);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void bootutil_ecdh_p256_drop(bootutil_ecdh_p256_context *ctx)
|
||||
{
|
||||
mbedtls_mpi_free(&ctx->d);
|
||||
mbedtls_mpi_free(&ctx->z);
|
||||
mbedtls_ecp_group_free(&ctx->grp);
|
||||
mbedtls_ecp_point_free(&ctx->P);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
rc = mbedtls_ecp_point_read_binary(&ctx->grp,
|
||||
&ctx->P,
|
||||
pk,
|
||||
EC256_PUBK_LEN);
|
||||
if (rc != 0) {
|
||||
mbedtls_ecp_group_free(&ctx->grp);
|
||||
mbedtls_ecp_point_free(&ctx->P);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = mbedtls_ecp_check_pubkey(&ctx->grp, &ctx->P);
|
||||
if (rc != 0) {
|
||||
mbedtls_ecp_group_free(&ctx->grp);
|
||||
mbedtls_ecp_point_free(&ctx->P);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mbedtls_mpi_read_binary(&ctx->d, sk, NUM_ECC_BYTES);
|
||||
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
rc = mbedtls_ecdh_compute_shared(&ctx->grp,
|
||||
&ctx->z,
|
||||
&ctx->P,
|
||||
&ctx->d,
|
||||
fake_rng,
|
||||
NULL);
|
||||
#else
|
||||
rc = mbedtls_ecdh_compute_shared(&ctx->grp,
|
||||
&ctx->z,
|
||||
&ctx->P,
|
||||
&ctx->d,
|
||||
NULL,
|
||||
NULL);
|
||||
#endif
|
||||
mbedtls_mpi_write_binary(&ctx->z, z, NUM_ECC_BYTES);
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif /* MCUBOOT_USE_MBED_TLS */
|
||||
|
||||
#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_ */
|
||||
672
bootloader/mcuboot/boot/bootutil/include/bootutil/crypto/ecdsa.h
Normal file
672
bootloader/mcuboot/boot/bootutil/include/bootutil/crypto/ecdsa.h
Normal file
@@ -0,0 +1,672 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright (c) 2023-2024 Arm Limited
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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, the choices are: MCUBOOT_USE_TINYCRYPT, MCUBOOT_USE_CC310,
|
||||
* MCUBOOT_USE_MBED_TLS, MCUBOOT_USE_PSA_CRYPTO. Note that support for
|
||||
* MCUBOOT_USE_PSA_CRYPTO is still experimental and it might not support all
|
||||
* the crypto abstractions that MCUBOOT_USE_MBED_TLS supports. For this
|
||||
* reason, it's allowed to have both of them defined, and for crypto modules
|
||||
* that support both abstractions, the MCUBOOT_USE_PSA_CRYPTO will take
|
||||
* precedence.
|
||||
*/
|
||||
|
||||
#ifndef __BOOTUTIL_CRYPTO_ECDSA_H_
|
||||
#define __BOOTUTIL_CRYPTO_ECDSA_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mcuboot_config/mcuboot_config.h"
|
||||
|
||||
#if defined(MCUBOOT_USE_PSA_CRYPTO) || defined(MCUBOOT_USE_MBED_TLS)
|
||||
#define MCUBOOT_USE_PSA_OR_MBED_TLS
|
||||
#endif /* MCUBOOT_USE_PSA_CRYPTO || MCUBOOT_USE_MBED_TLS */
|
||||
|
||||
#if defined(MCUBOOT_SIGN_EC384) && \
|
||||
!defined(MCUBOOT_USE_PSA_CRYPTO)
|
||||
#error "P384 requires PSA_CRYPTO to be defined"
|
||||
#endif
|
||||
|
||||
#if (defined(MCUBOOT_USE_TINYCRYPT) + \
|
||||
defined(MCUBOOT_USE_CC310) + \
|
||||
defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + \
|
||||
defined(MCUBOOT_USE_PSA_OR_MBED_TLS)) != 1
|
||||
#error "One crypto backend must be defined: either CC310/TINYCRYPT/MBED_TLS/PSA_CRYPTO"
|
||||
#endif
|
||||
|
||||
#if defined(MCUBOOT_USE_TINYCRYPT)
|
||||
#include <tinycrypt/ecc_dsa.h>
|
||||
#include <tinycrypt/constants.h>
|
||||
#endif /* MCUBOOT_USE_TINYCRYPT */
|
||||
|
||||
#if defined(MCUBOOT_USE_CC310)
|
||||
#include <cc310_glue.h>
|
||||
#endif /* MCUBOOT_USE_CC310 */
|
||||
|
||||
#if defined(MCUBOOT_USE_PSA_CRYPTO)
|
||||
#include <psa/crypto.h>
|
||||
#include <string.h>
|
||||
#elif defined(MCUBOOT_USE_MBED_TLS)
|
||||
#include <mbedtls/ecdsa.h>
|
||||
/* Indicate to the caller that the verify function needs the raw ASN.1
|
||||
* signature, not a decoded one. */
|
||||
#define MCUBOOT_ECDSA_NEED_ASN1_SIG
|
||||
#endif /* MCUBOOT_USE_MBED_TLS */
|
||||
|
||||
/*TODO: remove this after cypress port mbedtls to abstract crypto api */
|
||||
#if defined(MCUBOOT_USE_CC310) || defined(MCUBOOT_USE_MBED_TLS)
|
||||
#define NUM_ECC_BYTES (256 / 8)
|
||||
#endif
|
||||
|
||||
/* Universal defines */
|
||||
#define BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE (32)
|
||||
|
||||
#include "mbedtls/oid.h"
|
||||
#include "mbedtls/asn1.h"
|
||||
#include "bootutil/sign_key.h"
|
||||
#include "common.h"
|
||||
|
||||
#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO)
|
||||
#include <bl_crypto.h>
|
||||
#define NUM_ECC_BYTES (256 / 8)
|
||||
#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if (defined(MCUBOOT_USE_TINYCRYPT) || defined(MCUBOOT_USE_MBED_TLS) || \
|
||||
defined(MCUBOOT_USE_CC310) || defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO)) \
|
||||
&& !defined(MCUBOOT_USE_PSA_CRYPTO)
|
||||
/*
|
||||
* Declaring these like this adds NULL termination.
|
||||
*/
|
||||
static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_EC_ALG_UNRESTRICTED;
|
||||
static const uint8_t ec_secp256r1_oid[] = MBEDTLS_OID_EC_GRP_SECP256R1;
|
||||
|
||||
/*
|
||||
* Parse a public key. Helper function.
|
||||
*/
|
||||
static int bootutil_import_key(uint8_t **cp, uint8_t *end)
|
||||
{
|
||||
size_t len;
|
||||
mbedtls_asn1_buf alg;
|
||||
mbedtls_asn1_buf param;
|
||||
|
||||
if (mbedtls_asn1_get_tag(cp, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
|
||||
return -1;
|
||||
}
|
||||
end = *cp + len;
|
||||
|
||||
/* ECParameters (RFC5480) */
|
||||
if (mbedtls_asn1_get_alg(cp, end, &alg, ¶m)) {
|
||||
return -2;
|
||||
}
|
||||
/* id-ecPublicKey (RFC5480) */
|
||||
if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 ||
|
||||
memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
|
||||
return -3;
|
||||
}
|
||||
/* namedCurve (RFC5480) */
|
||||
if (param.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1 ||
|
||||
memcmp(param.ASN1_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) {
|
||||
return -4;
|
||||
}
|
||||
/* ECPoint (RFC5480) */
|
||||
if (mbedtls_asn1_get_bitstring_null(cp, end, &len)) {
|
||||
return -6;
|
||||
}
|
||||
if (*cp + len != end) {
|
||||
return -7;
|
||||
}
|
||||
|
||||
if (len != 2 * NUM_ECC_BYTES + 1) {
|
||||
return -8;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* (MCUBOOT_USE_TINYCRYPT || MCUBOOT_USE_MBED_TLS || MCUBOOT_USE_CC310) && !MCUBOOT_USE_PSA_CRYPTO */
|
||||
|
||||
/*
|
||||
* cp points to ASN1 string containing an integer.
|
||||
* Verify the tag, and that the length is 32 bytes. Helper function.
|
||||
*/
|
||||
static int bootutil_read_bigint(uint8_t i[NUM_ECC_BYTES], uint8_t **cp, uint8_t *end)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (mbedtls_asn1_get_tag(cp, end, &len, MBEDTLS_ASN1_INTEGER)) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (len >= NUM_ECC_BYTES) {
|
||||
memcpy(i, *cp + len - NUM_ECC_BYTES, NUM_ECC_BYTES);
|
||||
} else {
|
||||
memset(i, 0, NUM_ECC_BYTES - len);
|
||||
memcpy(i + NUM_ECC_BYTES - len, *cp, len);
|
||||
}
|
||||
*cp += len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read in signature. Signature has r and s encoded as integers. Helper function.
|
||||
*/
|
||||
static int bootutil_decode_sig(uint8_t signature[NUM_ECC_BYTES * 2], uint8_t *cp, uint8_t *end)
|
||||
{
|
||||
int rc;
|
||||
size_t len;
|
||||
|
||||
rc = mbedtls_asn1_get_tag(&cp, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
|
||||
if (rc) {
|
||||
return -1;
|
||||
}
|
||||
if (cp + len > end) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
rc = bootutil_read_bigint(signature, &cp, end);
|
||||
if (rc) {
|
||||
return -3;
|
||||
}
|
||||
rc = bootutil_read_bigint(signature + NUM_ECC_BYTES, &cp, end);
|
||||
if (rc) {
|
||||
return -4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(MCUBOOT_USE_TINYCRYPT)
|
||||
typedef uintptr_t bootutil_ecdsa_context;
|
||||
static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
}
|
||||
|
||||
static inline void bootutil_ecdsa_drop(bootutil_ecdsa_context *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
}
|
||||
|
||||
static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx,
|
||||
uint8_t *pk, size_t pk_len,
|
||||
uint8_t *hash, size_t hash_len,
|
||||
uint8_t *sig, size_t sig_len)
|
||||
{
|
||||
int rc;
|
||||
(void)ctx;
|
||||
(void)pk_len;
|
||||
(void)sig_len;
|
||||
(void)hash_len;
|
||||
|
||||
uint8_t signature[2 * NUM_ECC_BYTES];
|
||||
rc = bootutil_decode_sig(signature, sig, sig + sig_len);
|
||||
if (rc) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Only support uncompressed keys. */
|
||||
if (pk[0] != 0x04) {
|
||||
return -1;
|
||||
}
|
||||
pk++;
|
||||
|
||||
rc = uECC_verify(pk, hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, signature, uECC_secp256r1());
|
||||
if (rc != TC_CRYPTO_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx,
|
||||
uint8_t **cp,uint8_t *end)
|
||||
{
|
||||
(void)ctx;
|
||||
return bootutil_import_key(cp, end);
|
||||
}
|
||||
#endif /* MCUBOOT_USE_TINYCRYPT */
|
||||
|
||||
#if defined(MCUBOOT_USE_CC310)
|
||||
typedef uintptr_t bootutil_ecdsa_context;
|
||||
static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
}
|
||||
|
||||
static inline void bootutil_ecdsa_drop(bootutil_ecdsa_context *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
}
|
||||
|
||||
static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx,
|
||||
uint8_t *pk, size_t pk_len,
|
||||
uint8_t *hash, size_t hash_len,
|
||||
uint8_t *sig, size_t sig_len)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)pk_len;
|
||||
(void)hash_len;
|
||||
uint8_t dsig[2 * NUM_ECC_BYTES];
|
||||
|
||||
if (bootutil_decode_sig(dsig, sig, sig + sig_len)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Only support uncompressed keys. */
|
||||
if (pk[0] != 0x04) {
|
||||
return -1;
|
||||
}
|
||||
pk++;
|
||||
|
||||
return cc310_ecdsa_verify_secp256r1(hash, pk, dsig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE);
|
||||
}
|
||||
|
||||
static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx,
|
||||
uint8_t **cp,uint8_t *end)
|
||||
{
|
||||
(void)ctx;
|
||||
return bootutil_import_key(cp, end);
|
||||
}
|
||||
#endif /* MCUBOOT_USE_CC310 */
|
||||
|
||||
#if defined(MCUBOOT_USE_PSA_CRYPTO)
|
||||
typedef struct {
|
||||
psa_key_id_t key_id;
|
||||
size_t curve_byte_count;
|
||||
psa_algorithm_t required_algorithm;
|
||||
} bootutil_ecdsa_context;
|
||||
|
||||
/* ECDSA public key with format specified in RFC5280 et al. in ASN.1 syntax
|
||||
*
|
||||
* SEQUENCE {
|
||||
* SEQUENCE {
|
||||
* OBJECT idEcPublicKey
|
||||
* OBJECT namedCurve
|
||||
* }
|
||||
* BIT STRING publicKey
|
||||
* }
|
||||
*
|
||||
* ECDSA signature format specified in RFC3279 et al. in ASN.1 syntax
|
||||
*
|
||||
* SEQUENCE {
|
||||
* INTEGER r
|
||||
* INTEGER s
|
||||
* }
|
||||
*
|
||||
*/
|
||||
|
||||
/* Offset in bytes from the start of the encoding to the length field
|
||||
* of the innermost SEQUENCE in the ECDSA public key
|
||||
*/
|
||||
#define PUB_KEY_LEN_OFF (3)
|
||||
|
||||
/* Offset in bytes from the start of the publicKey encoding of the BIT STRING */
|
||||
#define PUB_KEY_VAL_OFF (3)
|
||||
|
||||
/* Computes the pointer to the idEcPublicKey OID from the base of the encoding */
|
||||
#define PUB_KEY_OID_OFFSET(p) (*p + PUB_KEY_LEN_OFF+1)
|
||||
|
||||
/* Computes the pointer to the namedCurve OID from the base of the encoding */
|
||||
#define CURVE_TYPE_OID_OFFSET(p) PUB_KEY_OID_OFFSET(p) + sizeof(IdEcPublicKey)
|
||||
|
||||
/* This helper function gets a pointer to the bitstring associated to the publicKey
|
||||
* as encoded per RFC 5280. This function assumes that the public key encoding is not
|
||||
* bigger than 127 bytes (i.e. usually up until 384 bit curves)
|
||||
*
|
||||
* \param[in,out] p Double pointer to a buffer containing the RFC 5280 of the ECDSA public key.
|
||||
* On output, the pointer is updated to point to the start of the public key
|
||||
* in BIT STRING form.
|
||||
* \param[out] size Pointer to a buffer containing the size of the public key extracted
|
||||
*
|
||||
*/
|
||||
static inline void get_public_key_from_rfc5280_encoding(uint8_t **p, size_t *size)
|
||||
{
|
||||
uint8_t *key_start = (*p) + (PUB_KEY_LEN_OFF + 1 + (*p)[PUB_KEY_LEN_OFF] + PUB_KEY_VAL_OFF);
|
||||
*p = key_start;
|
||||
*size = key_start[-2]-1; /* -2 from PUB_KEY_VAL_OFF to get the length, -1 to remove the ASN.1 padding byte count */
|
||||
}
|
||||
|
||||
/* This helper function parses a signature as specified in RFC3279 into a pair
|
||||
* (r,s) of contiguous bytes
|
||||
*
|
||||
* \param[in] sig Pointer to a buffer containing the encoded signature
|
||||
* \param[in] num_of_curve_bytes The required number of bytes for r and s
|
||||
* \param[out] r_s_pair Buffer containing the (r,s) pair extracted. It's caller
|
||||
* responsibility to ensure the buffer is big enough to
|
||||
* hold the parsed (r,s) pair.
|
||||
*/
|
||||
static void parse_signature_from_rfc5480_encoding(const uint8_t *sig,
|
||||
size_t num_of_curve_bytes,
|
||||
uint8_t *r_s_pair)
|
||||
{
|
||||
const uint8_t *sig_ptr = NULL;
|
||||
|
||||
/* r or s can be greater than the expected size by one, due to the way
|
||||
* ASN.1 encodes signed integers. If either r or s starts with a bit 1,
|
||||
* a zero byte will be added in front of the encoding
|
||||
*/
|
||||
|
||||
/* sig[0] == 0x30, sig[1] == <length>, sig[2] == 0x02 */
|
||||
|
||||
/* Move r in place */
|
||||
size_t r_len = sig[3];
|
||||
sig_ptr = &sig[4];
|
||||
if (r_len >= num_of_curve_bytes) {
|
||||
sig_ptr = sig_ptr + r_len - num_of_curve_bytes;
|
||||
memcpy(&r_s_pair[0], sig_ptr, num_of_curve_bytes);
|
||||
if(r_len % 2) {
|
||||
r_len--;
|
||||
}
|
||||
} else {
|
||||
/* For encodings that reduce the size of r or s in case of zeros */
|
||||
memcpy(&r_s_pair[num_of_curve_bytes - r_len], sig_ptr, r_len);
|
||||
}
|
||||
|
||||
/* Move s in place */
|
||||
size_t s_len = sig_ptr[r_len+1]; /* + 1 to skip SEQUENCE */
|
||||
sig_ptr = &sig_ptr[r_len+2];
|
||||
if (s_len >= num_of_curve_bytes) {
|
||||
sig_ptr = sig_ptr + s_len - num_of_curve_bytes;
|
||||
memcpy(&r_s_pair[num_of_curve_bytes], sig_ptr, num_of_curve_bytes);
|
||||
} else {
|
||||
/* For encodings that reduce the size of r or s in case of zeros */
|
||||
memcpy(&r_s_pair[2*num_of_curve_bytes - s_len], sig_ptr, s_len);
|
||||
}
|
||||
}
|
||||
|
||||
// OID id-ecPublicKey 1.2.840.10045.2.1.
|
||||
static const uint8_t IdEcPublicKey[] = {0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01};
|
||||
#if defined(MCUBOOT_SIGN_EC256)
|
||||
// OID secp256r1 1.2.840.10045.3.1.7.
|
||||
static const uint8_t Secp256r1[] = {0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07};
|
||||
#endif /* MCUBOOT_SIGN_EC256 */
|
||||
#if defined(MCUBOOT_SIGN_EC384)
|
||||
// OID secp384r1 1.3.132.0.34
|
||||
static const uint8_t Secp384r1[] = {0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22};
|
||||
#endif /* MCUBOOT_SIGN_EC384 */
|
||||
|
||||
static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx)
|
||||
{
|
||||
#if !defined(MCUBOOT_BUILTIN_KEY)
|
||||
ctx->key_id = PSA_KEY_ID_NULL;
|
||||
ctx->curve_byte_count = 0;
|
||||
ctx->required_algorithm = 0;
|
||||
|
||||
#else /* !MCUBOOT_BUILTIN_KEY */
|
||||
/* The incoming key ID is equal to the image index. The key ID value must be
|
||||
* shifted (by one in this case) because zero is reserved (PSA_KEY_ID_NULL)
|
||||
* and considered invalid.
|
||||
*/
|
||||
ctx->key_id++; /* Make sure it is not equal to 0. */
|
||||
#if defined(MCUBOOT_SIGN_EC256)
|
||||
ctx->curve_byte_count = 32;
|
||||
ctx->required_algorithm = PSA_ALG_SHA_256;
|
||||
#endif /* MCUBOOT_SIGN_EC256 */
|
||||
#if defined(MCUBOOT_SIGN_EC384)
|
||||
ctx->curve_byte_count = 48;
|
||||
ctx->required_algorithm = PSA_ALG_SHA_384;
|
||||
#endif /* MCUBOOT_SIGN_EC384 */
|
||||
#endif /* !MCUBOOT_BUILTIN_KEY */
|
||||
}
|
||||
|
||||
static inline void bootutil_ecdsa_drop(bootutil_ecdsa_context *ctx)
|
||||
{
|
||||
if (ctx->key_id != PSA_KEY_ID_NULL) {
|
||||
(void)psa_destroy_key(ctx->key_id);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(MCUBOOT_BUILTIN_KEY)
|
||||
/*
|
||||
* Parse a ECDSA public key with format specified in RFC5280 et al.
|
||||
*
|
||||
* OID for icEcPublicKey is 1.2.840.10045.2.1
|
||||
* OIDs for supported curves are as follows:
|
||||
* secp256r1 (prime256v1): 1.2.840.10045.3.1.7
|
||||
* secp384r1: 1.3.132.0.34
|
||||
*/
|
||||
static int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx,
|
||||
uint8_t **cp, uint8_t *end)
|
||||
{
|
||||
psa_key_attributes_t key_attributes = psa_key_attributes_init();
|
||||
size_t key_size;
|
||||
(void)end;
|
||||
|
||||
/* public key oid is valid */
|
||||
if (memcmp(PUB_KEY_OID_OFFSET(cp), IdEcPublicKey, sizeof(IdEcPublicKey))) {
|
||||
return (int)PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
#if defined(MCUBOOT_SIGN_EC256)
|
||||
if (!memcmp(CURVE_TYPE_OID_OFFSET(cp), Secp256r1, sizeof(Secp256r1))) {
|
||||
ctx->curve_byte_count = 32;
|
||||
ctx->required_algorithm = PSA_ALG_SHA_256;
|
||||
} else
|
||||
#endif /* MCUBOOT_SIGN_EC256 */
|
||||
#if defined(MCUBOOT_SIGN_EC384)
|
||||
if (!memcmp(CURVE_TYPE_OID_OFFSET(cp), Secp384r1, sizeof(Secp384r1))) {
|
||||
ctx->curve_byte_count = 48;
|
||||
ctx->required_algorithm = PSA_ALG_SHA_384;
|
||||
} else
|
||||
#endif /* MCUBOOT_SIGN_EC384 */
|
||||
{
|
||||
return (int)PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
get_public_key_from_rfc5280_encoding(cp, &key_size);
|
||||
/* Set attributes and import key */
|
||||
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_VERIFY_HASH);
|
||||
psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(ctx->required_algorithm));
|
||||
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
|
||||
|
||||
return (int)psa_import_key(&key_attributes, *cp, key_size, &ctx->key_id);
|
||||
}
|
||||
#endif /* !MCUBOOT_BUILTIN_KEY */
|
||||
|
||||
/* Verify the signature against the provided hash. The signature gets parsed from
|
||||
* the encoding first, then PSA Crypto has a dedicated API for ECDSA verification
|
||||
*/
|
||||
static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx,
|
||||
uint8_t *pk, size_t pk_len,
|
||||
uint8_t *hash, size_t hlen,
|
||||
uint8_t *sig, size_t slen)
|
||||
{
|
||||
(void)pk;
|
||||
(void)pk_len;
|
||||
(void)slen;
|
||||
|
||||
uint8_t reformatted_signature[96] = {0}; /* Enough for P-384 signature sizes */
|
||||
parse_signature_from_rfc5480_encoding(sig, ctx->curve_byte_count,reformatted_signature);
|
||||
|
||||
return (int) psa_verify_hash(ctx->key_id, PSA_ALG_ECDSA(ctx->required_algorithm),
|
||||
hash, hlen, reformatted_signature, 2*ctx->curve_byte_count);
|
||||
}
|
||||
#elif defined(MCUBOOT_USE_MBED_TLS)
|
||||
|
||||
typedef mbedtls_ecdsa_context bootutil_ecdsa_context;
|
||||
static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx)
|
||||
{
|
||||
mbedtls_ecdsa_init(ctx);
|
||||
}
|
||||
|
||||
static inline void bootutil_ecdsa_drop(bootutil_ecdsa_context *ctx)
|
||||
{
|
||||
mbedtls_ecdsa_free(ctx);
|
||||
}
|
||||
|
||||
#ifdef CY_MBEDTLS_HW_ACCELERATION
|
||||
/*
|
||||
* Parse the public key used for signing.
|
||||
*/
|
||||
static int bootutil_parse_eckey(bootutil_ecdsa_context *ctx, uint8_t **p, uint8_t *end)
|
||||
{
|
||||
size_t len;
|
||||
mbedtls_asn1_buf alg;
|
||||
mbedtls_asn1_buf param;
|
||||
|
||||
if (mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
|
||||
return -1;
|
||||
}
|
||||
end = *p + len;
|
||||
|
||||
if (mbedtls_asn1_get_alg(p, end, &alg, ¶m)) {
|
||||
return -2;
|
||||
}
|
||||
if (alg.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_pubkey_oid) - 1 ||
|
||||
memcmp(alg.ASN1_CONTEXT_MEMBER(p), ec_pubkey_oid, sizeof(ec_pubkey_oid) - 1)) {
|
||||
return -3;
|
||||
}
|
||||
if (param.ASN1_CONTEXT_MEMBER(len) != sizeof(ec_secp256r1_oid) - 1||
|
||||
memcmp(param.ASN1_CONTEXT_MEMBER(p), ec_secp256r1_oid, sizeof(ec_secp256r1_oid) - 1)) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
if (mbedtls_ecp_group_load(&ctx->grp, MBEDTLS_ECP_DP_SECP256R1)) {
|
||||
return -5;
|
||||
}
|
||||
|
||||
if (mbedtls_asn1_get_bitstring_null(p, end, &len)) {
|
||||
return -6;
|
||||
}
|
||||
if (*p + len != end) {
|
||||
return -7;
|
||||
}
|
||||
|
||||
if (mbedtls_ecp_point_read_binary(&ctx->grp, &ctx->Q, *p, end - *p)) {
|
||||
return -8;
|
||||
}
|
||||
|
||||
if (mbedtls_ecp_check_pubkey(&ctx->grp, &ctx->Q)) {
|
||||
return -9;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx,
|
||||
uint8_t *pk, size_t pk_len,
|
||||
uint8_t *hash, size_t hash_len,
|
||||
uint8_t *sig, size_t sig_len)
|
||||
{
|
||||
(void)pk;
|
||||
(void)pk_len;
|
||||
|
||||
/*
|
||||
* This is simplified, as the hash length is also 32 bytes.
|
||||
*/
|
||||
while (sig[sig_len - 1] == '\0') {
|
||||
sig_len--;
|
||||
}
|
||||
return mbedtls_ecdsa_read_signature(&ctx, hash, hash_len, sig, sig_len);
|
||||
}
|
||||
|
||||
#else /* CY_MBEDTLS_HW_ACCELERATION */
|
||||
|
||||
static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx,
|
||||
uint8_t *pk, size_t pk_len,
|
||||
uint8_t *hash, size_t hash_len,
|
||||
uint8_t *sig, size_t sig_len)
|
||||
{
|
||||
int rc;
|
||||
|
||||
(void)sig;
|
||||
(void)hash;
|
||||
(void)hash_len;
|
||||
|
||||
rc = mbedtls_ecp_group_load(&ctx->MBEDTLS_CONTEXT_MEMBER(grp), MBEDTLS_ECP_DP_SECP256R1);
|
||||
if (rc) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = mbedtls_ecp_point_read_binary(&ctx->MBEDTLS_CONTEXT_MEMBER(grp), &ctx->MBEDTLS_CONTEXT_MEMBER(Q), pk, pk_len);
|
||||
if (rc) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = mbedtls_ecp_check_pubkey(&ctx->MBEDTLS_CONTEXT_MEMBER(grp), &ctx->MBEDTLS_CONTEXT_MEMBER(Q));
|
||||
if (rc) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = mbedtls_ecdsa_read_signature(ctx, hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE,
|
||||
sig, sig_len);
|
||||
if (rc) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CY_MBEDTLS_HW_ACCELERATION */
|
||||
|
||||
static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx,
|
||||
uint8_t **cp,uint8_t *end)
|
||||
{
|
||||
int rc;
|
||||
#ifdef CY_MBEDTLS_HW_ACCELERATION
|
||||
rc = bootutil_parse_eckey(&ctx, cp, end);
|
||||
#else
|
||||
(void)ctx;
|
||||
rc = bootutil_import_key(cp, end);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* MCUBOOT_USE_MBED_TLS */
|
||||
|
||||
#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO)
|
||||
typedef uintptr_t bootutil_ecdsa_context;
|
||||
static inline void bootutil_ecdsa_init(bootutil_ecdsa_context *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
}
|
||||
|
||||
static inline void bootutil_ecdsa_drop(bootutil_ecdsa_context *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
}
|
||||
|
||||
static inline int bootutil_ecdsa_verify(bootutil_ecdsa_context *ctx,
|
||||
uint8_t *pk, size_t pk_len,
|
||||
uint8_t *hash, size_t hash_len,
|
||||
uint8_t *sig, size_t sig_len)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)pk_len;
|
||||
(void)hash_len;
|
||||
uint8_t dsig[2 * NUM_ECC_BYTES];
|
||||
|
||||
if (bootutil_decode_sig(dsig, sig, sig + sig_len)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Only support uncompressed keys. */
|
||||
if (pk[0] != 0x04) {
|
||||
return -1;
|
||||
}
|
||||
pk++;
|
||||
|
||||
return bl_secp256r1_validate(hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, pk, dsig);
|
||||
}
|
||||
|
||||
static inline int bootutil_ecdsa_parse_public_key(bootutil_ecdsa_context *ctx,
|
||||
uint8_t **cp,uint8_t *end)
|
||||
{
|
||||
(void)ctx;
|
||||
return bootutil_import_key(cp, end);
|
||||
}
|
||||
#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BOOTUTIL_CRYPTO_ECDSA_H_ */
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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_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 <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <mbedtls/cmac.h>
|
||||
#include <mbedtls/md.h>
|
||||
#endif /* MCUBOOT_USE_MBED_TLS */
|
||||
|
||||
#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 */
|
||||
|
||||
#if defined(MCUBOOT_USE_MBED_TLS)
|
||||
/**
|
||||
* The generic message-digest context.
|
||||
*/
|
||||
typedef mbedtls_md_context_t bootutil_hmac_sha256_context;
|
||||
|
||||
static inline void bootutil_hmac_sha256_init(bootutil_hmac_sha256_context *ctx)
|
||||
{
|
||||
mbedtls_md_init(ctx);
|
||||
}
|
||||
|
||||
static inline void bootutil_hmac_sha256_drop(bootutil_hmac_sha256_context *ctx)
|
||||
{
|
||||
mbedtls_md_free(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 = mbedtls_md_setup(ctx, mbedtls_md_info_from_string("SHA256"), 1);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
rc = mbedtls_md_hmac_starts(ctx, key, key_size);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline int bootutil_hmac_sha256_update(bootutil_hmac_sha256_context *ctx, const void *data, unsigned int data_length)
|
||||
{
|
||||
return mbedtls_md_hmac_update(ctx, data, data_length);
|
||||
}
|
||||
|
||||
static inline int bootutil_hmac_sha256_finish(bootutil_hmac_sha256_context *ctx, uint8_t *tag, unsigned int taglen)
|
||||
{
|
||||
(void)taglen;
|
||||
/*
|
||||
* HMAC the key and check that our received MAC matches the generated tag
|
||||
*/
|
||||
return mbedtls_md_hmac_finish(ctx, tag);
|
||||
}
|
||||
#endif /* MCUBOOT_USE_MBED_TLS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BOOTUTIL_CRYPTO_HMAC_SHA256_H_ */
|
||||
356
bootloader/mcuboot/boot/bootutil/include/bootutil/crypto/rsa.h
Normal file
356
bootloader/mcuboot/boot/bootutil/include/bootutil/crypto/rsa.h
Normal file
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright (c) 2023 Arm Limited
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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, the choices are: MCUBOOT_USE_MBED_TLS and
|
||||
* MCUBOOT_USE_PSA_CRYPTO. Note that support for MCUBOOT_USE_PSA_CRYPTO is
|
||||
* still experimental and it might not support all the crypto abstractions
|
||||
* that MCUBOOT_USE_MBED_TLS supports. For this reason, it's allowed to have
|
||||
* both of them defined, and for crypto modules that support both abstractions,
|
||||
* the MCUBOOT_USE_PSA_CRYPTO will take precedence.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note: The source file that includes this header should either define one of the
|
||||
* two options BOOTUTIL_CRYPTO_RSA_CRYPT_ENABLED or BOOTUTIL_CRYPTO_RSA_SIGN_ENABLED
|
||||
* This will make the signature functions or encryption functions visible without
|
||||
* generating a "defined but not used" compiler warning
|
||||
*/
|
||||
|
||||
#ifndef __BOOTUTIL_CRYPTO_RSA_H_
|
||||
#define __BOOTUTIL_CRYPTO_RSA_H_
|
||||
|
||||
#include "mcuboot_config/mcuboot_config.h"
|
||||
|
||||
#if defined(MCUBOOT_USE_PSA_CRYPTO) || defined(MCUBOOT_USE_MBED_TLS)
|
||||
#define MCUBOOT_USE_PSA_OR_MBED_TLS
|
||||
#endif /* MCUBOOT_USE_PSA_CRYPTO || MCUBOOT_USE_MBED_TLS */
|
||||
|
||||
#if (defined(MCUBOOT_USE_PSA_OR_MBED_TLS)) != 1
|
||||
#error "One crypto backend must be defined: either MBED_TLS/PSA_CRYPTO"
|
||||
#endif
|
||||
|
||||
#if defined(MCUBOOT_USE_PSA_CRYPTO)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include "bootutil/enc_key_public.h"
|
||||
|
||||
#elif defined(MCUBOOT_USE_MBED_TLS)
|
||||
|
||||
#include "mbedtls/rsa.h"
|
||||
#include "mbedtls/version.h"
|
||||
#if defined(BOOTUTIL_CRYPTO_RSA_CRYPT_ENABLED)
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
#include "rsa_alt_helpers.h"
|
||||
#else
|
||||
#include "mbedtls/rsa_internal.h"
|
||||
#endif
|
||||
#endif /* BOOTUTIL_CRYPTO_RSA_CRYPT_ENABLED */
|
||||
#include "mbedtls/asn1.h"
|
||||
#include "bootutil/crypto/common.h"
|
||||
|
||||
#endif /* MCUBOOT_USE_MBED_TLS */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MCUBOOT_USE_PSA_CRYPTO)
|
||||
|
||||
typedef struct {
|
||||
psa_key_id_t key_id;
|
||||
} bootutil_rsa_context;
|
||||
|
||||
static inline void bootutil_rsa_init(bootutil_rsa_context *ctx)
|
||||
{
|
||||
ctx->key_id = PSA_KEY_ID_NULL;
|
||||
}
|
||||
|
||||
static inline void bootutil_rsa_drop(bootutil_rsa_context *ctx)
|
||||
{
|
||||
if (ctx->key_id != PSA_KEY_ID_NULL) {
|
||||
(void)psa_destroy_key(ctx->key_id);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOTUTIL_CRYPTO_RSA_CRYPT_ENABLED)
|
||||
static int bootutil_rsa_oaep_decrypt(
|
||||
bootutil_rsa_context *ctx,
|
||||
size_t *olen,
|
||||
const uint8_t *input,
|
||||
uint8_t *output,
|
||||
size_t output_max_len)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
|
||||
/* Perform an additional defensive check to compare the modulus of the RSA
|
||||
* key to the expected input of the decryption function, i.e. TLV_ENC_RSA_SZ
|
||||
*/
|
||||
psa_key_attributes_t key_attr = psa_key_attributes_init();
|
||||
status = psa_get_key_attributes(ctx->key_id, &key_attr);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
size_t input_size = PSA_BITS_TO_BYTES(psa_get_key_bits(&key_attr));
|
||||
if (input_size != TLV_ENC_RSA_SZ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = psa_asymmetric_decrypt(ctx->key_id, PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256),
|
||||
input, TLV_ENC_RSA_SZ, NULL, 0,
|
||||
output, output_max_len, olen);
|
||||
return (int)status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a RSA private key with format specified in RFC3447 A.1.2
|
||||
*
|
||||
* The key is meant to be used for OAEP decrypt hence algorithm and usage are hardcoded
|
||||
*/
|
||||
static int
|
||||
bootutil_rsa_parse_private_key(bootutil_rsa_context *ctx, uint8_t **p, uint8_t *end)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
psa_key_attributes_t key_attributes = psa_key_attributes_init();
|
||||
|
||||
/* Set attributes and import key */
|
||||
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&key_attributes, PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256));
|
||||
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
|
||||
|
||||
status = psa_import_key(&key_attributes, *p, (end - *p), &ctx->key_id);
|
||||
return (int)status;
|
||||
}
|
||||
|
||||
#endif /* BOOTUTIL_CRYPTO_RSA_CRYPT_ENABLED */
|
||||
|
||||
#if defined(BOOTUTIL_CRYPTO_RSA_SIGN_ENABLED)
|
||||
/*
|
||||
* Parse a RSA public key with format specified in RFC3447 A.1.1
|
||||
*
|
||||
* The key is meant to be used for PSS signature verification hence algorithm and usage are hardcoded
|
||||
*/
|
||||
static int
|
||||
bootutil_rsa_parse_public_key(bootutil_rsa_context *ctx, uint8_t **p, uint8_t *end)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
psa_key_attributes_t key_attributes = psa_key_attributes_init();
|
||||
|
||||
/* Set attributes and import key */
|
||||
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_VERIFY_HASH);
|
||||
psa_set_key_algorithm(&key_attributes, PSA_ALG_RSA_PSS(PSA_ALG_SHA_256));
|
||||
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
|
||||
|
||||
status = psa_import_key(&key_attributes, *p, (end - *p), &ctx->key_id);
|
||||
return (int)status;
|
||||
}
|
||||
|
||||
/* Get the modulus (N) length in bytes */
|
||||
static size_t bootutil_rsa_get_len(const bootutil_rsa_context *ctx)
|
||||
{
|
||||
psa_key_attributes_t key_attributes = psa_key_attributes_init();
|
||||
psa_status_t status = psa_get_key_attributes(ctx->key_id, &key_attributes);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
return PSA_BITS_TO_BYTES(psa_get_key_bits(&key_attributes));
|
||||
}
|
||||
|
||||
/* PSA Crypto has a dedicated API for RSASSA-PSS verification */
|
||||
static inline int bootutil_rsassa_pss_verify(const bootutil_rsa_context *ctx,
|
||||
uint8_t *hash, size_t hlen, uint8_t *sig, size_t slen)
|
||||
{
|
||||
return (int) psa_verify_hash(ctx->key_id, PSA_ALG_RSA_PSS(PSA_ALG_SHA_256),
|
||||
hash, hlen, sig, slen);
|
||||
}
|
||||
#endif /* BOOTUTIL_CRYPTO_RSA_SIGN_ENABLED */
|
||||
|
||||
#elif defined(MCUBOOT_USE_MBED_TLS)
|
||||
|
||||
typedef mbedtls_rsa_context bootutil_rsa_context;
|
||||
|
||||
static inline void bootutil_rsa_init(bootutil_rsa_context *ctx)
|
||||
{
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
mbedtls_rsa_init(ctx);
|
||||
mbedtls_rsa_set_padding(ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
|
||||
#else
|
||||
mbedtls_rsa_init(ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void bootutil_rsa_drop(bootutil_rsa_context *ctx)
|
||||
{
|
||||
mbedtls_rsa_free(ctx);
|
||||
}
|
||||
|
||||
#if defined(BOOTUTIL_CRYPTO_RSA_CRYPT_ENABLED) && (MBEDTLS_VERSION_NUMBER >= 0x03000000)
|
||||
static int fake_rng(void *p_rng, unsigned char *output, size_t len);
|
||||
#endif /* BOOTUTIL_CRYPTO_RSA_CRYPT_ENABLED && MBEDTLS_VERSION_NUMBER >= 3.0 */
|
||||
|
||||
#if defined(BOOTUTIL_CRYPTO_RSA_CRYPT_ENABLED)
|
||||
static inline int bootutil_rsa_oaep_decrypt(
|
||||
bootutil_rsa_context *ctx,
|
||||
size_t *olen,
|
||||
const uint8_t *input,
|
||||
uint8_t *output,
|
||||
size_t output_max_len)
|
||||
{
|
||||
int rc = -1;
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
rc = mbedtls_rsa_rsaes_oaep_decrypt(ctx, fake_rng, NULL,
|
||||
NULL, 0, olen, input, output, output_max_len);
|
||||
#else
|
||||
rc = mbedtls_rsa_rsaes_oaep_decrypt(ctx, NULL, NULL, MBEDTLS_RSA_PRIVATE,
|
||||
NULL, 0, olen, input, output, output_max_len);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a RSA private key with format specified in RFC3447 A.1.2
|
||||
*/
|
||||
static int
|
||||
bootutil_rsa_parse_private_key(bootutil_rsa_context *ctx, uint8_t **p, uint8_t *end)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*p + len != end) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Non-optional fields. */
|
||||
if ( /* version */
|
||||
mbedtls_asn1_get_int(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(ver)) != 0 ||
|
||||
/* public modulus */
|
||||
mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(N)) != 0 ||
|
||||
/* public exponent */
|
||||
mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(E)) != 0 ||
|
||||
/* private exponent */
|
||||
mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(D)) != 0 ||
|
||||
/* primes */
|
||||
mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(P)) != 0 ||
|
||||
mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(Q)) != 0) {
|
||||
|
||||
return -3;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_RSA_NO_CRT)
|
||||
/*
|
||||
* DP/DQ/QP are only used inside mbedTLS if it was built with the
|
||||
* Chinese Remainder Theorem enabled (default). In case it is disabled
|
||||
* we parse, or if not available, we calculate those values.
|
||||
*/
|
||||
if (*p < end) {
|
||||
if ( /* d mod (p-1) and d mod (q-1) */
|
||||
mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(DP)) != 0 ||
|
||||
mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(DQ)) != 0 ||
|
||||
/* q ^ (-1) mod p */
|
||||
mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(QP)) != 0) {
|
||||
|
||||
return -4;
|
||||
}
|
||||
} else {
|
||||
if (mbedtls_rsa_deduce_crt(&ctx->MBEDTLS_CONTEXT_MEMBER(P),
|
||||
&ctx->MBEDTLS_CONTEXT_MEMBER(Q),
|
||||
&ctx->MBEDTLS_CONTEXT_MEMBER(D),
|
||||
&ctx->MBEDTLS_CONTEXT_MEMBER(DP),
|
||||
&ctx->MBEDTLS_CONTEXT_MEMBER(DQ),
|
||||
&ctx->MBEDTLS_CONTEXT_MEMBER(QP)) != 0) {
|
||||
return -5;
|
||||
}
|
||||
}
|
||||
#endif /* !MBEDTLS_RSA_NO_CRT */
|
||||
|
||||
ctx->MBEDTLS_CONTEXT_MEMBER(len) = mbedtls_mpi_size(&ctx->MBEDTLS_CONTEXT_MEMBER(N));
|
||||
|
||||
if (mbedtls_rsa_check_privkey(ctx) != 0) {
|
||||
return -6;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* BOOTUTIL_CRYPTO_RSA_CRYPT_ENABLED */
|
||||
|
||||
#if defined(BOOTUTIL_CRYPTO_RSA_SIGN_ENABLED)
|
||||
/*
|
||||
* Parse a RSA public key with format specified in RFC3447 A.1.1
|
||||
*/
|
||||
static int
|
||||
bootutil_rsa_parse_public_key(bootutil_rsa_context *ctx, uint8_t **p, uint8_t *end)
|
||||
{
|
||||
int rc;
|
||||
size_t len;
|
||||
|
||||
if ((rc = mbedtls_asn1_get_tag(p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*p + len != end) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if ((rc = mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(N))) != 0 ||
|
||||
(rc = mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(E))) != 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
ctx->MBEDTLS_CONTEXT_MEMBER(len) = mbedtls_mpi_size(&ctx->MBEDTLS_CONTEXT_MEMBER(N));
|
||||
|
||||
if (*p != end) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
/* The Mbed TLS version is more than 2.6.1 */
|
||||
#if MBEDTLS_VERSION_NUMBER > 0x02060100
|
||||
rc = mbedtls_rsa_import(ctx, &ctx->MBEDTLS_CONTEXT_MEMBER(N), NULL,
|
||||
NULL, NULL, &ctx->MBEDTLS_CONTEXT_MEMBER(E));
|
||||
if (rc != 0) {
|
||||
return -5;
|
||||
}
|
||||
#endif
|
||||
|
||||
rc = mbedtls_rsa_check_pubkey(ctx);
|
||||
if (rc != 0) {
|
||||
return -6;
|
||||
}
|
||||
|
||||
ctx->MBEDTLS_CONTEXT_MEMBER(len) = mbedtls_mpi_size(&ctx->MBEDTLS_CONTEXT_MEMBER(N));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the modulus (N) length in bytes */
|
||||
static inline size_t bootutil_rsa_get_len(const bootutil_rsa_context *ctx)
|
||||
{
|
||||
return mbedtls_rsa_get_len(ctx);
|
||||
}
|
||||
|
||||
/* Performs modular exponentiation using the public key output = input^E mod N */
|
||||
static inline int bootutil_rsa_public(bootutil_rsa_context *ctx, const uint8_t *input, uint8_t *output)
|
||||
{
|
||||
return mbedtls_rsa_public(ctx, input, output);
|
||||
}
|
||||
#endif /* BOOTUTIL_CRYPTO_RSA_SIGN_ENABLED */
|
||||
|
||||
#endif /* MCUBOOT_USE_MBED_TLS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BOOTUTIL_CRYPTO_RSA_H_ */
|
||||
250
bootloader/mcuboot/boot/bootutil/include/bootutil/crypto/sha.h
Normal file
250
bootloader/mcuboot/boot/bootutil/include/bootutil/crypto/sha.h
Normal file
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright (c) 2017-2019 Linaro LTD
|
||||
* Copyright (c) 2017-2019 JUUL Labs
|
||||
* Copyright (c) 2021-2023 Arm Limited
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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, the choices are: MCUBOOT_USE_MBED_TLS, MCUBOOT_USE_TINYCRYPT,
|
||||
* MCUBOOT_USE_PSA_CRYPTO, MCUBOOT_USE_CC310. Note that support for MCUBOOT_USE_PSA_CRYPTO
|
||||
* is still experimental and it might not support all the crypto abstractions
|
||||
* that MCUBOOT_USE_MBED_TLS supports. For this reason, it's allowed to have
|
||||
* both of them defined, and for crypto modules that support both abstractions,
|
||||
* the MCUBOOT_USE_PSA_CRYPTO will take precedence.
|
||||
*/
|
||||
|
||||
#ifndef __BOOTUTIL_CRYPTO_SHA_H_
|
||||
#define __BOOTUTIL_CRYPTO_SHA_H_
|
||||
|
||||
#include "mcuboot_config/mcuboot_config.h"
|
||||
#include "mcuboot_config/mcuboot_logging.h"
|
||||
|
||||
#if defined(MCUBOOT_USE_PSA_CRYPTO) || defined(MCUBOOT_USE_MBED_TLS)
|
||||
#define MCUBOOT_USE_PSA_OR_MBED_TLS
|
||||
#endif /* MCUBOOT_USE_PSA_CRYPTO || MCUBOOT_USE_MBED_TLS */
|
||||
|
||||
#if (defined(MCUBOOT_USE_PSA_OR_MBED_TLS) + \
|
||||
defined(MCUBOOT_USE_TINYCRYPT) + \
|
||||
defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO) + \
|
||||
defined(MCUBOOT_USE_CC310)) != 1
|
||||
#error "One crypto backend must be defined: either CC310/MBED_TLS/TINYCRYPT/PSA_CRYPTO"
|
||||
#endif
|
||||
|
||||
#if defined(MCUBOOT_SHA512)
|
||||
#define IMAGE_HASH_SIZE (64)
|
||||
#define EXPECTED_HASH_TLV IMAGE_TLV_SHA512
|
||||
#elif defined(MCUBOOT_SIGN_EC384)
|
||||
#define IMAGE_HASH_SIZE (48)
|
||||
#define EXPECTED_HASH_TLV IMAGE_TLV_SHA384
|
||||
#else
|
||||
#define IMAGE_HASH_SIZE (32)
|
||||
#define EXPECTED_HASH_TLV IMAGE_TLV_SHA256
|
||||
#endif /* MCUBOOT_SIGN */
|
||||
|
||||
/* Universal defines for SHA-256 */
|
||||
#define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE (64)
|
||||
#define BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE (32)
|
||||
|
||||
#if defined(MCUBOOT_USE_PSA_CRYPTO)
|
||||
|
||||
#include <psa/crypto.h>
|
||||
|
||||
#elif defined(MCUBOOT_USE_MBED_TLS)
|
||||
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <mbedtls/version.h>
|
||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||
#include <mbedtls/compat-2.x.h>
|
||||
#endif
|
||||
|
||||
#endif /* MCUBOOT_USE_MBED_TLS */
|
||||
|
||||
#if defined(MCUBOOT_USE_TINYCRYPT)
|
||||
#include <tinycrypt/sha256.h>
|
||||
#include <tinycrypt/constants.h>
|
||||
#endif /* MCUBOOT_USE_TINYCRYPT */
|
||||
|
||||
#if defined(MCUBOOT_USE_CC310)
|
||||
#include <cc310_glue.h>
|
||||
#endif /* MCUBOOT_USE_CC310 */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MCUBOOT_USE_PSA_CRYPTO)
|
||||
|
||||
typedef psa_hash_operation_t bootutil_sha_context;
|
||||
|
||||
static inline int bootutil_sha_init(bootutil_sha_context *ctx)
|
||||
{
|
||||
*ctx = psa_hash_operation_init();
|
||||
#if defined(MCUBOOT_SHA512)
|
||||
psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_512);
|
||||
#elif defined(MCUBOOT_SIGN_EC384)
|
||||
psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_384);
|
||||
#else
|
||||
psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_256);
|
||||
#endif
|
||||
return (int)status;
|
||||
}
|
||||
|
||||
static inline int bootutil_sha_drop(bootutil_sha_context *ctx)
|
||||
{
|
||||
return (int)psa_hash_abort(ctx);
|
||||
}
|
||||
|
||||
static inline int bootutil_sha_update(bootutil_sha_context *ctx,
|
||||
const void *data,
|
||||
uint32_t data_len)
|
||||
{
|
||||
return (int)psa_hash_update(ctx, data, data_len);
|
||||
}
|
||||
|
||||
static inline int bootutil_sha_finish(bootutil_sha_context *ctx,
|
||||
uint8_t *output)
|
||||
{
|
||||
size_t hash_length = 0;
|
||||
/* Assumes the output buffer is at least the expected size of the hash */
|
||||
#if defined(MCUBOOT_SHA512)
|
||||
return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_512), &hash_length);
|
||||
#elif defined(MCUBOOT_SIGN_EC384)
|
||||
return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_384), &hash_length);
|
||||
#else
|
||||
return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_256), &hash_length);
|
||||
#endif
|
||||
}
|
||||
|
||||
#elif defined(MCUBOOT_USE_MBED_TLS)
|
||||
|
||||
typedef mbedtls_sha256_context bootutil_sha_context;
|
||||
|
||||
static inline int bootutil_sha_init(bootutil_sha_context *ctx)
|
||||
{
|
||||
mbedtls_sha256_init(ctx);
|
||||
return mbedtls_sha256_starts_ret(ctx, 0);
|
||||
}
|
||||
|
||||
static inline int bootutil_sha_drop(bootutil_sha_context *ctx)
|
||||
{
|
||||
mbedtls_sha256_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int bootutil_sha_update(bootutil_sha_context *ctx,
|
||||
const void *data,
|
||||
uint32_t data_len)
|
||||
{
|
||||
return mbedtls_sha256_update_ret(ctx, data, data_len);
|
||||
}
|
||||
|
||||
static inline int bootutil_sha_finish(bootutil_sha_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_sha_context;
|
||||
|
||||
static inline int bootutil_sha_init(bootutil_sha_context *ctx)
|
||||
{
|
||||
tc_sha256_init(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int bootutil_sha_drop(bootutil_sha_context *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int bootutil_sha_update(bootutil_sha_context *ctx,
|
||||
const void *data,
|
||||
uint32_t data_len)
|
||||
{
|
||||
return tc_sha256_update(ctx, data, data_len);
|
||||
}
|
||||
|
||||
static inline int bootutil_sha_finish(bootutil_sha_context *ctx,
|
||||
uint8_t *output)
|
||||
{
|
||||
return tc_sha256_final(output, ctx);
|
||||
}
|
||||
#endif /* MCUBOOT_USE_TINYCRYPT */
|
||||
|
||||
#if defined(MCUBOOT_USE_CC310)
|
||||
static inline int bootutil_sha_init(bootutil_sha_context *ctx)
|
||||
{
|
||||
cc310_sha256_init(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int bootutil_sha_drop(bootutil_sha_context *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
nrf_cc310_disable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int bootutil_sha_update(bootutil_sha_context *ctx,
|
||||
const void *data,
|
||||
uint32_t data_len)
|
||||
{
|
||||
cc310_sha256_update(ctx, data, data_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int bootutil_sha_finish(bootutil_sha_context *ctx,
|
||||
uint8_t *output)
|
||||
{
|
||||
cc310_sha256_finalize(ctx, output);
|
||||
return 0;
|
||||
}
|
||||
#endif /* MCUBOOT_USE_CC310 */
|
||||
|
||||
#if defined(MCUBOOT_USE_NRF_EXTERNAL_CRYPTO)
|
||||
|
||||
#include <bl_crypto.h>
|
||||
|
||||
typedef bl_sha256_ctx_t bootutil_sha_context;
|
||||
|
||||
static inline void bootutil_sha_init(bootutil_sha_context *ctx)
|
||||
{
|
||||
bl_sha256_init(ctx);
|
||||
}
|
||||
|
||||
static inline void bootutil_sha_drop(bootutil_sha_context *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
}
|
||||
|
||||
static inline int bootutil_sha_update(bootutil_sha_context *ctx,
|
||||
const void *data,
|
||||
uint32_t data_len)
|
||||
{
|
||||
return bl_sha256_update(ctx, data, data_len);
|
||||
}
|
||||
|
||||
static inline int bootutil_sha_finish(bootutil_sha_context *ctx,
|
||||
uint8_t *output)
|
||||
{
|
||||
bl_sha256_finalize(ctx, output);
|
||||
return 0;
|
||||
}
|
||||
#endif /* MCUBOOT_USE_NRF_EXTERNAL_CRYPTO */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BOOTUTIL_CRYPTO_SHA_H_ */
|
||||
83
bootloader/mcuboot/boot/bootutil/include/bootutil/enc_key.h
Normal file
83
bootloader/mcuboot/boot/bootutil/include/bootutil/enc_key.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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"
|
||||
#include "bootutil/sign_key.h"
|
||||
#include "bootutil/enc_key_public.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BOOT_ENC_TLV_ALIGN_SIZE ALIGN_UP(BOOT_ENC_TLV_SIZE, BOOT_MAX_ALIGN)
|
||||
|
||||
struct enc_key_data {
|
||||
uint8_t valid;
|
||||
bootutil_aes_ctr_context aes_ctr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve the private key for image encryption.
|
||||
*
|
||||
* @param[out] private_key structure to store the private key and
|
||||
* its length.
|
||||
*
|
||||
* @return 0 on success; nonzero on failure.
|
||||
*
|
||||
*/
|
||||
int boot_enc_retrieve_private_key(struct bootutil_key **private_key);
|
||||
|
||||
struct boot_status;
|
||||
|
||||
/* Decrypt random, symmetric encryption key */
|
||||
int boot_decrypt_key(const uint8_t *buf, uint8_t *enckey);
|
||||
|
||||
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 slot,
|
||||
const struct image_header *hdr, const struct flash_area *fap,
|
||||
struct boot_status *bs);
|
||||
bool boot_enc_valid(struct enc_key_data *enc_state, int slot);
|
||||
void boot_enc_encrypt(struct enc_key_data *enc_state, int slot,
|
||||
uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf);
|
||||
void boot_enc_decrypt(struct enc_key_data *enc_state, int slot,
|
||||
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,66 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright (c) 2018-2019 JUUL Labs
|
||||
* Copyright (c) 2019-2021 Arm Limited
|
||||
* Copyright (c) 2021 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 BOOTUTIL_ENC_KEY_PUBLIC_H
|
||||
#define BOOTUTIL_ENC_KEY_PUBLIC_H
|
||||
#include <mcuboot_config/mcuboot_config.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef ALIGN_UP
|
||||
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
|
||||
#endif
|
||||
|
||||
#ifdef MCUBOOT_AES_256
|
||||
#define BOOT_ENC_KEY_SIZE 32
|
||||
#else
|
||||
#define BOOT_ENC_KEY_SIZE 16
|
||||
#endif
|
||||
|
||||
#define BOOT_ENC_KEY_ALIGN_SIZE ALIGN_UP(BOOT_ENC_KEY_SIZE, BOOT_MAX_ALIGN)
|
||||
|
||||
#define TLV_ENC_RSA_SZ 256
|
||||
#define TLV_ENC_KW_SZ (BOOT_ENC_KEY_SIZE + 8)
|
||||
#define TLV_ENC_EC256_SZ (65 + 32 + BOOT_ENC_KEY_SIZE)
|
||||
#define TLV_ENC_X25519_SZ (32 + 32 + BOOT_ENC_KEY_SIZE)
|
||||
|
||||
#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
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BOOTUTIL_ENC_KEY_PUBLIC_H */
|
||||
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
* 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_DECLARE(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
|
||||
#define FIH_CONST1 0x1FCDEA88
|
||||
#define FIH_CONST2 0x19C1F6E1
|
||||
#else
|
||||
#define FIH_POSITIVE_VALUE 0
|
||||
#define FIH_NEGATIVE_VALUE -1
|
||||
#define FIH_CONST1 1
|
||||
#define FIH_CONST2 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;
|
||||
typedef volatile int fih_ret;
|
||||
|
||||
#else
|
||||
|
||||
typedef int fih_int;
|
||||
typedef int fih_ret;
|
||||
|
||||
#endif /* FIH_ENABLE_DOUBLE_VARS */
|
||||
|
||||
extern fih_ret FIH_SUCCESS;
|
||||
extern fih_ret FIH_FAILURE;
|
||||
extern fih_ret FIH_NO_BOOTABLE_IMAGE;
|
||||
extern fih_ret FIH_BOOT_HOOK_REGULAR;
|
||||
|
||||
#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 */
|
||||
#define FIH_EQ(x, y) ((x == y) && fih_delay() && !(y != x))
|
||||
#define FIH_NOT_EQ(x, y) ((x != y) || !fih_delay() || !(y == x))
|
||||
#define FIH_SET(x, y) x = y; if(fih_delay() && (x != y)) FIH_PANIC
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
#define FIH_EQ(x, y) (x == y)
|
||||
#define FIH_NOT_EQ(x, y) (x != y)
|
||||
#define FIH_SET(x, y) x = y
|
||||
|
||||
#endif /* FIH_ENABLE_DOUBLE_VARS */
|
||||
|
||||
#define FIH_DECLARE(var, val) \
|
||||
fih_ret FIH_SET(var, val)
|
||||
|
||||
/* 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_ret fih_ret_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 "::" ::);
|
||||
#elif defined(__APPLE__)
|
||||
#define FIH_LABEL(str) do {} while (0)
|
||||
#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__ */
|
||||
70
bootloader/mcuboot/boot/bootutil/include/bootutil/ignore.h
Normal file
70
bootloader/mcuboot/boot/bootutil/include/bootutil/ignore.h
Normal file
@@ -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
|
||||
228
bootloader/mcuboot/boot/bootutil/include/bootutil/image.h
Normal file
228
bootloader/mcuboot/boot/bootutil/include/bootutil/image.h
Normal file
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright (c) 2016-2019 Linaro LTD
|
||||
* Copyright (c) 2016-2019 JUUL Labs
|
||||
* Copyright (c) 2019-2023 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
|
||||
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((__packed__))
|
||||
#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
|
||||
#define IMAGE_HASH_LEN 32 /* Size of SHA256 TLV hash */
|
||||
|
||||
/*
|
||||
* Image header flags.
|
||||
*/
|
||||
#define IMAGE_F_PIC 0x00000001 /* Not supported. */
|
||||
#define IMAGE_F_ENCRYPTED_AES128 0x00000004 /* Encrypted using AES128. */
|
||||
#define IMAGE_F_ENCRYPTED_AES256 0x00000008 /* Encrypted using AES256. */
|
||||
#define IMAGE_F_NON_BOOTABLE 0x00000010 /* Split image app. */
|
||||
/*
|
||||
* 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
|
||||
|
||||
/*
|
||||
* Indicates that ih_load_addr stores information on flash/ROM address the
|
||||
* image has been built for.
|
||||
*/
|
||||
#define IMAGE_F_ROM_FIXED 0x00000100
|
||||
|
||||
/*
|
||||
* Flags that indicate if the image data is compressed
|
||||
*/
|
||||
#define IMAGE_F_COMPRESSED_LZMA1 0x00000200
|
||||
#define IMAGE_F_COMPRESSED_LZMA2 0x00000400
|
||||
#define IMAGE_F_COMPRESSED_ARM_THUMB_FLT 0x00000800
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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_SHA384 0x11 /* SHA384 of image hdr and body */
|
||||
#define IMAGE_TLV_SHA512 0x12 /* SHA512 of image hdr and body */
|
||||
#define IMAGE_TLV_RSA2048_PSS 0x20 /* RSA2048 of hash output */
|
||||
#define IMAGE_TLV_ECDSA224 0x21 /* ECDSA of hash output - Not supported anymore */
|
||||
#define IMAGE_TLV_ECDSA_SIG 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_SIG_PURE 0x25 /* Indicator that attached signature has been prepared
|
||||
* over image rather than its digest.
|
||||
*/
|
||||
#define IMAGE_TLV_ENC_RSA2048 0x30 /* Key encrypted with RSA-OAEP-2048 */
|
||||
#define IMAGE_TLV_ENC_KW 0x31 /* Key encrypted with AES-KW 128 or 256*/
|
||||
#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 */
|
||||
/* The following flags relate to compressed images and are for the decompressed image data */
|
||||
#define IMAGE_TLV_DECOMP_SIZE 0x70 /* Decompressed image size excluding header/TLVs */
|
||||
#define IMAGE_TLV_DECOMP_SHA 0x71 /*
|
||||
* Decompressed image shaX hash, this field must match
|
||||
* the format and size of the raw slot (compressed)
|
||||
* shaX hash
|
||||
*/
|
||||
#define IMAGE_TLV_DECOMP_SIGNATURE 0x72 /*
|
||||
* Decompressed image signature, this field must match
|
||||
* the format and size of the raw slot (compressed)
|
||||
* signature
|
||||
*/
|
||||
/*
|
||||
* 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_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;
|
||||
} __packed;
|
||||
|
||||
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;
|
||||
} __packed;
|
||||
|
||||
/** 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) */
|
||||
} __packed;
|
||||
|
||||
/** 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). */
|
||||
} __packed;
|
||||
|
||||
#define ENCRYPTIONFLAGS (IMAGE_F_ENCRYPTED_AES128 | IMAGE_F_ENCRYPTED_AES256)
|
||||
#define IS_ENCRYPTED(hdr) (((hdr)->ih_flags & IMAGE_F_ENCRYPTED_AES128) \
|
||||
|| ((hdr)->ih_flags & IMAGE_F_ENCRYPTED_AES256))
|
||||
#define MUST_DECRYPT(fap, idx, hdr) \
|
||||
(flash_area_get_id(fap) == FLASH_AREA_IMAGE_SECONDARY(idx) && IS_ENCRYPTED(hdr))
|
||||
|
||||
#define COMPRESSIONFLAGS (IMAGE_F_COMPRESSED_LZMA1 | IMAGE_F_COMPRESSED_LZMA2 \
|
||||
| IMAGE_F_COMPRESSED_ARM_THUMB_FLT)
|
||||
#define IS_COMPRESSED(hdr) ((hdr)->ih_flags & COMPRESSIONFLAGS)
|
||||
#define MUST_DECOMPRESS(fap, idx, hdr) \
|
||||
(flash_area_get_id(fap) == FLASH_AREA_IMAGE_SECONDARY(idx) && IS_COMPRESSED(hdr))
|
||||
|
||||
_Static_assert(sizeof(struct image_header) == IMAGE_HEADER_SIZE,
|
||||
"struct image_header not required size");
|
||||
|
||||
struct enc_key_data;
|
||||
fih_ret 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);
|
||||
int bootutil_tlv_iter_is_prot(struct image_tlv_iter *it, uint32_t off);
|
||||
|
||||
int32_t bootutil_get_img_security_cnt(struct image_header *hdr,
|
||||
const struct flash_area *fap,
|
||||
uint32_t *security_cnt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Laird Connectivity
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef H_MCUBOOT_STATUS_
|
||||
#define H_MCUBOOT_STATUS_
|
||||
|
||||
/* Enumeration representing the states that MCUboot can be in */
|
||||
typedef enum
|
||||
{
|
||||
MCUBOOT_STATUS_STARTUP = 0,
|
||||
MCUBOOT_STATUS_UPGRADING,
|
||||
MCUBOOT_STATUS_BOOTABLE_IMAGE_FOUND,
|
||||
MCUBOOT_STATUS_NO_BOOTABLE_IMAGE_FOUND,
|
||||
MCUBOOT_STATUS_BOOT_FAILED,
|
||||
MCUBOOT_STATUS_USB_DFU_WAITING,
|
||||
MCUBOOT_STATUS_USB_DFU_ENTERED,
|
||||
MCUBOOT_STATUS_USB_DFU_TIMED_OUT,
|
||||
MCUBOOT_STATUS_SERIAL_DFU_ENTERED,
|
||||
} mcuboot_status_type_t;
|
||||
|
||||
#if defined(CONFIG_MCUBOOT_ACTION_HOOKS)
|
||||
extern void mcuboot_status_change(mcuboot_status_type_t status);
|
||||
#else
|
||||
#define mcuboot_status_change(_status) do {} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* H_MCUBOOT_STATUS_ */
|
||||
35
bootloader/mcuboot/boot/bootutil/include/bootutil/ramload.h
Normal file
35
bootloader/mcuboot/boot/bootutil/include/bootutil/ramload.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __RAMLOAD_H__
|
||||
#define __RAMLOAD_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef MULTIPLE_EXECUTABLE_RAM_REGIONS
|
||||
/**
|
||||
* Provides information about the Executable RAM for a given image ID.
|
||||
*
|
||||
* @param image_id Index of the image (from 0).
|
||||
* @param exec_ram_start Pointer to store the start address of the exec RAM
|
||||
* @param exec_ram_size Pointer to store the size of the exec RAM
|
||||
*
|
||||
* @return 0 on success; nonzero on failure.
|
||||
*/
|
||||
int boot_get_image_exec_ram_info(uint32_t image_id,
|
||||
uint32_t *exec_ram_start,
|
||||
uint32_t *exec_ram_size);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __RAMLOAD_H__ */
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
/**
|
||||
* Initialises the security counters.
|
||||
*
|
||||
* @return FIH_SUCCESS on success
|
||||
*/
|
||||
fih_ret 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_ret 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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SECURITY_CNT_H__ */
|
||||
71
bootloader/mcuboot/boot/bootutil/include/bootutil/sign_key.h
Normal file
71
bootloader/mcuboot/boot/bootutil/include/bootutil/sign_key.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
/* mcuboot_config.h is needed for MCUBOOT_HW_KEY to work */
|
||||
#include "mcuboot_config/mcuboot_config.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_ */
|
||||
Reference in New Issue
Block a user