//***************************************************************************** // // am_hal_secure_ota.h //! @file //! //! @brief Functions for secure over-the-air. //! //! @addtogroup //! @ingroup apollo3phal //! @{ // //***************************************************************************** //***************************************************************************** // // 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_INFO1_UPDATE 0xA0 #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 : 21; uint32_t resvd : 2; 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; #ifdef __cplusplus extern "C" { #endif // 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); #ifdef __cplusplus } #endif #endif // AM_HAL_SECURE_OTA_H