1 //*****************************************************************************
2 //
3 //! @file am_hal_secure_ota.h
4 //!
5 //! @brief Functions for secure over-the-air.
6 //!
7 //! @addtogroup SecOTA3p Secure-OTA - Secure Over-the-Air Functionality
8 //! @ingroup apollo3p_hal
9 //! @{
10 //
11 //*****************************************************************************
12 
13 //*****************************************************************************
14 //
15 // Copyright (c) 2024, Ambiq Micro, Inc.
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are met:
20 //
21 // 1. Redistributions of source code must retain the above copyright notice,
22 // this list of conditions and the following disclaimer.
23 //
24 // 2. Redistributions in binary form must reproduce the above copyright
25 // notice, this list of conditions and the following disclaimer in the
26 // documentation and/or other materials provided with the distribution.
27 //
28 // 3. Neither the name of the copyright holder nor the names of its
29 // contributors may be used to endorse or promote products derived from this
30 // software without specific prior written permission.
31 //
32 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
36 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 // POSSIBILITY OF SUCH DAMAGE.
43 //
44 // This is part of revision release_sdk_3_2_0-dd5f40c14b of the AmbiqSuite Development Package.
45 //
46 //*****************************************************************************
47 
48 #ifndef AM_HAL_SECURE_OTA_H
49 #define AM_HAL_SECURE_OTA_H
50 //! Ambiq Standard Image Format related definitions
51 //! Magic Numbers
52 #define AM_IMAGE_MAGIC_SBL                0xA3
53 #define AM_IMAGE_MAGIC_AM3P               0x3A
54 #define AM_IMAGE_MAGIC_PATCH              0xAF
55 #define AM_IMAGE_MAGIC_INFO1_UPDATE       0xA0
56 #define AM_IMAGE_MAGIC_MAIN               0xC0
57 #define AM_IMAGE_MAGIC_CHILD              0xCC
58 #define AM_IMAGE_MAGIC_NONSECURE          0xCB
59 #define AM_IMAGE_MAGIC_INFO0              0xCF
60 
61 //! First 30 words of the image headers follow similar pattern
62 typedef struct
63 {
64     union
65     {
66         uint32_t     ui32;
67         struct
68         {
69             uint32_t    blobSize     : 21;
70             uint32_t    resvd        : 2;
71             uint32_t    encrypted    : 1;
72             uint32_t    magicNum     : 8;
73         } s;
74     } w0;
75     uint32_t        crc;
76     union
77     {
78         uint32_t    ui32;
79         struct
80         {
81             uint32_t    authAlgo     : 4;
82             uint32_t    authKeyIdx   : 4;
83             uint32_t    encAlgo      : 4;
84             uint32_t    keyIdx       : 4;
85             uint32_t    resvd3       : 8;
86             uint32_t    crcBoot      : 1;
87             uint32_t    authBoot     : 1;
88             uint32_t    resvd2       : 2;
89             uint32_t    crcInstall   : 1;
90             uint32_t    authInstall  : 1;
91             uint32_t    resvd1       : 2;
92         } s;
93     } w2;
94     uint32_t        w3;
95     uint32_t        signature[8]; // w4-11
96     uint32_t        iv[4]; // w12-w15
97     uint32_t        kek[4]; // w16-w19
98     uint32_t        signatureClear[8]; // w20-w27
99     union
100     {
101         uint32_t   ui32;
102         struct
103         {
104             uint32_t    offsetWords     : 16;
105             uint32_t    sizeWords       : 16;
106         } info0;
107         struct
108         {
109             uint32_t    encap        : 1;
110             uint32_t    resvd        : 1;
111             uint32_t    loadAddrMsb  : 30;
112         } s1;
113         struct
114         {
115             uint32_t    writeProtect : 1;
116             uint32_t    copyProtect  : 1;
117             uint32_t    loadAddrMsb  : 30;
118         } s;
119     } addrWord; // w28
120     union
121     {
122         uint32_t   ui32;
123         uint32_t   resv;
124         uint32_t   key; // For info
125         struct
126         {
127             uint32_t    version         : 15;
128             uint32_t    erasePrev       : 1;
129             uint32_t    resv            : 16;
130         } s;
131     } versionKeyWord; // w29
132 } am_image_hdr_common_t;
133 
134 //! Bitmask used to clear encrypted status in flash
135 #define AM_IMAGE_BITMASK_ENCRYPTED            0x00800000
136 //! Number of most significant bits in w28 used for load address
137 #define AM_IMAGE_LOAD_ADDR_MSB_BITS           30
138 
139 #define AM_IMAGE_GET_LOADADDR(common)         (((am_image_hdr_common_t *)(common))->addrWord.s.loadAddrMsb << (32 - AM_IMAGE_LOAD_ADDR_MSB_BITS))
140 
141 #define AM_IMAGE_NUM_TRAILING_WORDS_TO_256    ((256 - sizeof(am_image_hdr_common_t))/4)
142 #define AM_IMAGE_MAX_CHILD_IMAGE              AM_IMAGE_NUM_TRAILING_WORDS_TO_256
143 
144 typedef struct
145 {
146     am_image_hdr_common_t common;
147     uint32_t        childPtr[AM_IMAGE_MAX_CHILD_IMAGE];
148 } am_main_image_hdr_t;
149 
150 typedef struct
151 {
152     am_image_hdr_common_t common;
153     uint32_t        featureKey;
154     uint32_t        resvd[1];
155 } am_thirdparty_image_hdr_t;
156 
157 typedef struct
158 {
159     am_image_hdr_common_t common;
160     uint32_t        resvd[AM_IMAGE_NUM_TRAILING_WORDS_TO_256];
161 } am_sbl_image_hdr_t;
162 
163 //! Reserved magic numbers allowed to be used by customer's own bootloader
164 #define AM_IMAGE_MAGIC_CUST(x)   ((((x) & 0xF0) == 0xC0) && ((x) != 0xC0) && ((x) != 0xCC) && ((x) != 0xCB) && ((x) != 0xCF))
165 
166 //! OTA Upgrade related definitions
167 
168 //! Maximum number of OTAs
169 #define AM_HAL_SECURE_OTA_MAX_OTA           8
170 
171 //! OTA Protocol between OTA application and SecureBoot
172 //! OTAPOINTER will be initialized as follows:
173 //! Most significant 30 bits will correspond to most significant 30 bits of OTA Descriptor
174 //! Least Significant bit (bit 0) should be initialized to 1 to indicate a valid OTA Descriptor
175 //! bit 1 should be initialized to 1 to indicate that the list contains an SBL OTA
176 //! OTA Descriptor points to a list of entries, each corresponding to an OTA blob, list terminating in 0xFFFFFFFF
177 //! Each list entry word comprises of following:
178 //! Most significant 30 bits will correspond to most significant 30 bits of OTA blob pointer
179 //! Blob pointer needs to be aligned to Flash Page boundary (8K)
180 //! Least Significant 2 bits should be initialized to 1 to indicate a valid OTA Pending
181 //! After Secboot processes an OTA, it clears the least significant bit (bit 0)
182 //! bit 1 indicates the status of the OTA - 0 for Success, 1 for Failure
183 #define AM_HAL_SECURE_OTA_OTA_VALID_MASK                0x3
184 #define AM_HAL_SECURE_OTA_OTA_GET_BLOB_PTR(ptr)         ((uint32_t)(ptr) & ~AM_HAL_SECURE_OTA_OTA_VALID_MASK)
185 #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)
186 #define AM_HAL_SECURE_OTA_OTA_LIST_END_MARKER           0xFFFFFFFF
187 
188 //! Bitmasks signifying the bit to be cleared for OTA success/failure
189 #define AM_HAL_SECURE_OTA_OTA_DONE_FAILURE_CLRMASK      0x1
190 #define AM_HAL_SECURE_OTA_OTA_DONE_SUCCESS_CLRMASK      0x3
191 
192 
193 //! OTA Status
194 typedef enum
195 {
196     AM_HAL_OTA_STATUS_SUCCESS = 0x0,
197     AM_HAL_OTA_STATUS_ERROR = 0x1, // This should never happen
198     AM_HAL_OTA_STATUS_FAILURE = 0x2,
199     AM_HAL_OTA_STATUS_PENDING = 0x3,
200 } am_hal_ota_status_e;
201 
202 //! Per Image OTA Status information
203 typedef struct
204 {
205     uint32_t            *pImage;
206     am_hal_ota_status_e status;
207 } am_hal_ota_status_t;
208 
209 #ifdef __cplusplus
210 extern "C"
211 {
212 #endif
213 
214 //*****************************************************************************
215 //
216 //! @brief  Initialize OTA state
217 //!
218 //! Initializes the OTA state. This should be called before doing any other operation
219 //!
220 //! @param  ui32ProgamKey - The Flash programming key
221 //! @param  pOtaDesc  - Should be start of a flash page designated for OTA Descriptor
222 //!
223 //! @note This call will erase the flash page, which will then be incrementally
224 //! populated as OTA's are added.  It will also initialize the OTAPOINTER to point
225 //! to this descriptor, marking it as invalid at the same time
226 //!
227 //! @return Returns AM_HAL_STATUS_SUCCESS on success
228 //
229 //*****************************************************************************
230 uint32_t am_hal_ota_init(uint32_t ui32ProgamKey, uint32_t *pOtaDesc);
231 
232 //*****************************************************************************
233 //
234 //! @brief  Add a new image for OTA
235 //!
236 //! Adds a new image to the OTA Descriptor.
237 //!
238 //! @param  ui32ProgamKey - The Flash programming key
239 //! @param  imageMagic    - Image magic# identifying type of image being
240 //!                         added to OTA descr
241 //! @param  pImage        - Should point to the start of new image to
242 //!                         be added to descr
243 //!
244 //! This will program the next available entry in OTA descriptor. It will also set
245 //! appropriate state in the OTA pointer register
246 //!
247 //! @return Returns AM_HAL_STATUS_SUCCESS on success
248 //
249 //*****************************************************************************
250 uint32_t am_hal_ota_add(uint32_t ui32ProgamKey, uint8_t imageMagic, uint32_t *pImage);
251 
252 //*****************************************************************************
253 //
254 //! @brief  Get Current OTA Descriptor state
255 //!
256 //! @details This will retrieve the current OTA status of various images added to the OTA descr
257 //!
258 //! @note Can be called anytime (generally after coming back from reset to check
259 //!        the status of OTA
260 //! @par
261 //! @note Will be also used by sbl_main to identify list of OTA's left for it
262 //!        (would show up as PENDING)
263 //!
264 //! @param  pOtaDesc - Should be start of a flash page designated for OTA Descriptor
265 //! @param  maxOta   - Determines the size of the following buffer
266 //! @param  pStatus  - Return Parameter - populated by this function indicating the OTA
267 //! status of various OTA's
268 //!
269 //! @return Returns AM_HAL_STATUS_SUCCESS on success
270 //
271 //*****************************************************************************
272 uint32_t am_hal_get_ota_status(uint32_t *pOtaDesc, uint32_t maxOta, am_hal_ota_status_t *pStatus);
273 
274 #ifdef __cplusplus
275 }
276 #endif
277 
278 #endif // AM_HAL_SECURE_OTA_H
279 //*****************************************************************************
280 //
281 // End Doxygen group.
282 //! @}
283 //
284 //*****************************************************************************
285