228 lines
8.5 KiB
C
228 lines
8.5 KiB
C
//*****************************************************************************
|
|
//
|
|
// am_hal_secure_ota.h
|
|
//! @file
|
|
//!
|
|
//! @brief Functions for secure over-the-air.
|
|
//!
|
|
//! @addtogroup
|
|
//! @ingroup apollo3hal
|
|
//! @{
|
|
//
|
|
//*****************************************************************************
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Copyright (c) 2020, Ambiq Micro
|
|
// All rights reserved.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions are met:
|
|
//
|
|
// 1. Redistributions of source code must retain the above copyright notice,
|
|
// this list of conditions and the following disclaimer.
|
|
//
|
|
// 2. Redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in the
|
|
// documentation and/or other materials provided with the distribution.
|
|
//
|
|
// 3. Neither the name of the copyright holder nor the names of its
|
|
// contributors may be used to endorse or promote products derived from this
|
|
// software without specific prior written permission.
|
|
//
|
|
// Third party software included in this distribution is subject to the
|
|
// additional license terms as defined in the /docs/licenses directory.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
//
|
|
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
|
|
//
|
|
//*****************************************************************************
|
|
|
|
#ifndef AM_HAL_SECURE_OTA_H
|
|
#define AM_HAL_SECURE_OTA_H
|
|
// Ambiq Standard Image Format related definitions
|
|
// Magic Numbers
|
|
#define AM_IMAGE_MAGIC_SBL 0xA3
|
|
#define AM_IMAGE_MAGIC_AM3P 0x3A
|
|
#define AM_IMAGE_MAGIC_PATCH 0xAF
|
|
#define AM_IMAGE_MAGIC_MAIN 0xC0
|
|
#define AM_IMAGE_MAGIC_CHILD 0xCC
|
|
#define AM_IMAGE_MAGIC_NONSECURE 0xCB
|
|
#define AM_IMAGE_MAGIC_INFO0 0xCF
|
|
|
|
// First 30 words of the image headers follow similar pattern
|
|
typedef struct
|
|
{
|
|
union
|
|
{
|
|
uint32_t ui32;
|
|
struct
|
|
{
|
|
uint32_t blobSize : 20;
|
|
uint32_t resvd : 3;
|
|
uint32_t encrypted : 1;
|
|
uint32_t magicNum : 8;
|
|
} s;
|
|
} w0;
|
|
uint32_t crc;
|
|
union
|
|
{
|
|
uint32_t ui32;
|
|
struct
|
|
{
|
|
uint32_t authAlgo : 4;
|
|
uint32_t authKeyIdx : 4;
|
|
uint32_t encAlgo : 4;
|
|
uint32_t keyIdx : 4;
|
|
uint32_t resvd3 : 8;
|
|
uint32_t crcBoot : 1;
|
|
uint32_t authBoot : 1;
|
|
uint32_t resvd2 : 2;
|
|
uint32_t crcInstall : 1;
|
|
uint32_t authInstall : 1;
|
|
uint32_t resvd1 : 2;
|
|
} s;
|
|
} w2;
|
|
uint32_t w3;
|
|
uint32_t signature[8]; // w4-11
|
|
uint32_t iv[4]; // w12-w15
|
|
uint32_t kek[4]; // w16-w19
|
|
uint32_t signatureClear[8]; // w20-w27
|
|
union
|
|
{
|
|
uint32_t ui32;
|
|
struct
|
|
{
|
|
uint32_t offsetWords : 16;
|
|
uint32_t sizeWords : 16;
|
|
} info0;
|
|
struct
|
|
{
|
|
uint32_t encap : 1;
|
|
uint32_t resvd : 1;
|
|
uint32_t loadAddrMsb : 30;
|
|
} s1;
|
|
struct
|
|
{
|
|
uint32_t writeProtect : 1;
|
|
uint32_t copyProtect : 1;
|
|
uint32_t loadAddrMsb : 30;
|
|
} s;
|
|
} addrWord; // w28
|
|
union
|
|
{
|
|
uint32_t ui32;
|
|
uint32_t resv;
|
|
uint32_t key; // For info
|
|
struct
|
|
{
|
|
uint32_t version : 15;
|
|
uint32_t erasePrev : 1;
|
|
uint32_t resv : 16;
|
|
} s;
|
|
} versionKeyWord; // w29
|
|
} am_image_hdr_common_t;
|
|
|
|
// Bitmask used to clear encrypted status in flash
|
|
#define AM_IMAGE_BITMASK_ENCRYPTED 0x00800000
|
|
// Number of most significant bits in w28 used for load address
|
|
#define AM_IMAGE_LOAD_ADDR_MSB_BITS 30
|
|
|
|
#define AM_IMAGE_GET_LOADADDR(common) (((am_image_hdr_common_t *)(common))->addrWord.s.loadAddrMsb << (32 - AM_IMAGE_LOAD_ADDR_MSB_BITS))
|
|
|
|
#define AM_IMAGE_NUM_TRAILING_WORDS_TO_256 ((256 - sizeof(am_image_hdr_common_t))/4)
|
|
#define AM_IMAGE_MAX_CHILD_IMAGE AM_IMAGE_NUM_TRAILING_WORDS_TO_256
|
|
|
|
typedef struct
|
|
{
|
|
am_image_hdr_common_t common;
|
|
uint32_t childPtr[AM_IMAGE_MAX_CHILD_IMAGE];
|
|
} am_main_image_hdr_t;
|
|
|
|
typedef struct
|
|
{
|
|
am_image_hdr_common_t common;
|
|
uint32_t featureKey;
|
|
uint32_t resvd[1];
|
|
} am_thirdparty_image_hdr_t;
|
|
|
|
typedef struct
|
|
{
|
|
am_image_hdr_common_t common;
|
|
uint32_t resvd[AM_IMAGE_NUM_TRAILING_WORDS_TO_256];
|
|
} am_sbl_image_hdr_t;
|
|
|
|
// Reserved magic numbers allowed to be used by customer's own bootloader
|
|
#define AM_IMAGE_MAGIC_CUST(x) ((((x) & 0xF0) == 0xC0) && ((x) != 0xC0) && ((x) != 0xCC) && ((x) != 0xCB) && ((x) != 0xCF))
|
|
|
|
// OTA Upgrade related definitions
|
|
|
|
// Maximum number of OTAs
|
|
#define AM_HAL_SECURE_OTA_MAX_OTA 8
|
|
|
|
// OTA Protocol between OTA application and SecureBoot
|
|
// OTAPOINTER will be initialized as follows:
|
|
// Most significant 30 bits will correspond to most significant 30 bits of OTA Descriptor
|
|
// Least Significant bit (bit 0) should be initialized to 1 to indicate a valid OTA Descriptor
|
|
// bit 1 should be initialized to 1 to indicate that the list contains an SBL OTA
|
|
// OTA Descriptor points to a list of entries, each corresponding to an OTA blob, list terminating in 0xFFFFFFFF
|
|
// Each list entry word comprises of following:
|
|
// Most significant 30 bits will correspond to most significant 30 bits of OTA blob pointer
|
|
// Blob pointer needs to be aligned to Flash Page boundary (8K)
|
|
// Least Significant 2 bits should be initialized to 1 to indicate a valid OTA Pending
|
|
// After Secboot processes an OTA, it clears the least significant bit (bit 0)
|
|
// bit 1 indicates the status of the OTA - 0 for Success, 1 for Failure
|
|
#define AM_HAL_SECURE_OTA_OTA_VALID_MASK 0x3
|
|
#define AM_HAL_SECURE_OTA_OTA_GET_BLOB_PTR(ptr) ((uint32_t)(ptr) & ~AM_HAL_SECURE_OTA_OTA_VALID_MASK)
|
|
#define AM_HAL_SECURE_OTA_OTA_IS_VALID(ptr) (((uint32_t)(ptr) & AM_HAL_SECURE_OTA_OTA_VALID_MASK) == AM_HAL_SECURE_OTA_OTA_VALID_MASK)
|
|
#define AM_HAL_SECURE_OTA_OTA_LIST_END_MARKER 0xFFFFFFFF
|
|
|
|
// Bitmasks signifying the bit to be cleared for OTA success/failure
|
|
#define AM_HAL_SECURE_OTA_OTA_DONE_FAILURE_CLRMASK 0x1
|
|
#define AM_HAL_SECURE_OTA_OTA_DONE_SUCCESS_CLRMASK 0x3
|
|
|
|
|
|
// OTA Status
|
|
typedef enum
|
|
{
|
|
AM_HAL_OTA_STATUS_SUCCESS = 0x0,
|
|
AM_HAL_OTA_STATUS_ERROR = 0x1, // This should never happen
|
|
AM_HAL_OTA_STATUS_FAILURE = 0x2,
|
|
AM_HAL_OTA_STATUS_PENDING = 0x3,
|
|
} am_hal_ota_status_e;
|
|
|
|
// Per Image OTA Status information
|
|
typedef struct
|
|
{
|
|
uint32_t *pImage;
|
|
am_hal_ota_status_e status;
|
|
} am_hal_ota_status_t;
|
|
|
|
// pOtaDesc should be start of a flash page designated for OTA Descriptor
|
|
// This call will erase the flash page, which will then be incrementally populated as OTA's are added
|
|
// It will also initialize the OTAPOINTER to point to this descriptor, with LSB indicating it as invalid
|
|
uint32_t am_hal_ota_init(uint32_t ui32ProgamKey, uint32_t *pOtaDesc);
|
|
|
|
// Add a new OTA to descriptor
|
|
// This will program the next available entry in OTA descriptor
|
|
// Will also set the valid/sbl flags in OTA pointer register
|
|
uint32_t am_hal_ota_add(uint32_t ui32ProgamKey, uint8_t imageMagic, uint32_t *pImage);
|
|
|
|
// Get OTA Status
|
|
// Can be called anytime (generally after coming back from reset to check the status of OTA
|
|
// Will be also used by sbl_main to identify list of OTA's left for it (would show up as PENDING)
|
|
uint32_t am_hal_get_ota_status(uint32_t *pOtaDesc, uint32_t maxOta, am_hal_ota_status_t *pStatus);
|
|
|
|
#endif // AM_HAL_SECURE_OTA_H
|