1 /****************************************************************************** 2 * Copyright (c) 2022-2023 Texas Instruments Incorporated 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * 1) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * 2) Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * 3) Neither the name of the copyright holder nor the names of its 15 * contributors may be used to endorse or promote products derived from this 16 * software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 * 30 ******************************************************************************/ 31 32 #ifndef __HAPI_H__ 33 #define __HAPI_H__ 34 35 #include <stdint.h> 36 #include "sha256sw.h" 37 38 /*! Magic value used to protect against inadvertent flash erasures/programming. 39 * (prevents corruption due to random jumps into the flash API, for example 40 * due to stack overflow or errant function pointers) 41 * Must be passed in key argument to all flash functions 42 */ 43 #define FLASH_API_KEY 0xB7E3A08F 44 45 /*! Define HAPI table and the functions it points to */ 46 typedef struct 47 { 48 // 0: Enter standby power state (from privileged thread mode with MSP as call stack) 49 void (*enterStandby)(const uint32_t *copyList); 50 // 1: [Utility] Calculate CRC32 over nBytes bytes at data 51 uint32_t (*crc32)(const uint8_t *data, uint32_t nBytes); 52 // 2: Apply copy list 53 void (*applyCopyList)(const uint32_t *list); 54 // 3: Erase (main) flash sector 55 uint32_t (*flashSectorErase)(uint32_t key, uint32_t sectorAddress); 56 // 4: Erase (main) flash bank 57 uint32_t (*flashBankErase)(uint32_t key); 58 // 5: Program (main) flash sector 59 uint32_t (*flashProgram)(uint32_t key, const uint8_t *dataBuffer, uint32_t address, uint32_t nBytes); 60 // 6: [Utility] Hamming weight of 32b word (number of bits set) 61 uint32_t (*countBits)(uint32_t word); 62 // 7: [Utility] Perform SECDED encoding on array of 64b words 63 void (*secdedEncode)(uint8_t *parity, const uint64_t *data, uint32_t nWords64); 64 // 8: [Utility] Perform SECDED detection/correction on array of 64b words and parity bytes 65 int32_t (*secdedDecode)(uint64_t *data, const uint8_t *parity, uint32_t nWords64); 66 // 9: Function to be called from boot code or bootloader to enter application properly 67 void (*enterApplication)(); 68 // 10: SHA256: hash single block of data and produce digest 69 int_fast16_t (*sha256SwHashData)(SHA256SW_Handle handle, 70 SHA2SW_HashType hashType, // Only SHA2SW_HASH_TYPE_256 supported 71 const void *data, 72 size_t length, 73 uint32_t digest[8]); 74 // 11: SHA256: initialize hash state 75 int_fast16_t (*sha256SwStart)(SHA256SW_Handle handle, 76 SHA2SW_HashType hashType // Only SHA2SW_HASH_TYPE_256 supported 77 ); 78 // 12: SHA256: update hash with data 79 int_fast16_t (*sha256SwAddData)(SHA256SW_Handle handle, const void *data, size_t length); 80 // 13: SHA256: finalize and produce digest 81 int_fast16_t (*sha256SwFinalize)(SHA256SW_Handle handle, uint32_t digest[8]); 82 // 14: [Utility] Reset device 83 void (*resetDevice)(void); 84 // 15: SHA256: Process Block 85 void (*sha256SwProcessBlock)(uint32_t digest[8], uint32_t Ws[16]); 86 // 16: SHA256: Round constants 87 const uint32_t (*sha256SW_K256)[64]; 88 // 17: SHA256: Initial constants 89 const uint32_t (*sha256Sw_initialDigest256)[8]; 90 // 18: Busy loop that waits for nUs microseconds 91 void (*waitUs)(uint32_t nUs); 92 // 19: Count leading zeros 93 uint32_t (*clz)(uint32_t x); 94 } HARD_API_T; 95 96 // Define address of HAPI table in ROM and macro for pointer to it 97 #define HAPI_TABLE_BASE_ADDR 0x0F00004C 98 #define HAPI_TABLE_POINTER ((const HARD_API_T *)HAPI_TABLE_BASE_ADDR) 99 100 // ------------------------------------------------------------ 101 // Macros used in applications to actually call HAPI functions 102 // ------------------------------------------------------------ 103 104 // void HapiEnterStandby(const uint32_t *copyList) 105 /***************************************************************************** 106 * \brief Enter standby power state 107 * Stores the full state of the CPU to MSP call stack so that it can get 108 * restored once we come back out of standby (at which point CPU is reset). 109 * When exiting standby the CPU will appear to return from this function. 110 * 111 * \param[in] copyList 112 * If non-null, the copy list to apply through ApplyCopyList() in the 113 * AsmExitStandby function while waiting for flash to become ready. 114 * 115 * \pre 116 * - Execution state is privileged and call stack being used is MSP 117 * - MSP call stack must reside in retained SRAM (obviously) 118 * - Interrupts have been turned off with CPSID but interrupts enabled in NVIC 119 * - Wakeup event(s) have been configured in AON event fabric 120 * - SCB.SCR.DSLP_EN=0 (if not, in debug standby exit will enter standby again) 121 * \warning 122 * The preconditions must be followed to the letter or bad things will happen 123 * \note 124 * Clobbers r0-r3 (normal per AAPCS) 125 *****************************************************************************/ 126 #define HapiEnterStandby(p) HAPI_TABLE_POINTER->enterStandby((p)) 127 128 // uint32_t HapiCrc32(const uint8_t *data, uint32_t nBytes) 129 /***************************************************************************** 130 * \brief Calculate CRC32 over a data image 131 * CRC32 implementation that uses a 256-entry LUT 132 * 133 * \param[in] data 134 * Pointer to the image data 135 * \param[in] nBytes 136 * Size of image in bytes 137 * 138 * \return 139 * CRC-32 checksum of the image 140 *****************************************************************************/ 141 #define HapiCrc32(p, n) HAPI_TABLE_POINTER->crc32((p), (n)) 142 143 // void HapiApplyCopyList(const uint32_t *list) 144 /***************************************************************************** 145 * \brief Process copy list 146 * Processes a copy list in a flexible CopyList format. Used by trims 147 * in FCFG, for user-defined initialization in CCFG and may be used by 148 * peripheral drivers to do HW reinitialization during wakeup from standby. 149 * The copy list is processed as a sequence of 32b command words, followed by 150 * zero or more literal words (LW): 151 * 152 * Command |31:28|27:20 |19:2 |1:0|LW|Description 153 * -------------|-----|---------|----------------------|---|--|------------------- 154 * EOL |0000 |0000_0000|0000_0000_0000_0000_00|00 |0 |End-of-list 155 * WAIT(N) |0001 |0000_0000|nnnn_nnnn_nnnn_nnnn_nn|00 |0 |Wait N/12 us 156 * NOP = WAIT(0)|0001 |0000_0000|0000_0000_0000_0000_00|00 |0 |No operation 157 * CPY(A*,N) |aaaa |nnnn_nnnn|aaaa_aaaa_aaaa_aaaa_aa|00 |N |Copy N literal words to address A* 158 * CPY(A,1) |aaaa |aaaa_aaaa|aaaa_aaaa_aaaa_aaaa_aa|01 |1 |Copy single literal word to full address A 159 * JMP(A) |aaaa |aaaa_aaaa|aaaa_aaaa_aaaa_aaaa_aa|10 |0 |Jump to new list at full address A 160 * CALL(A) |aaaa |aaaa_aaaa|aaaa_aaaa_aaaa_aaaa_aa|11 |0 |Recurse to list at full address A 161 * 162 * A* is a reduced address space that covers all SRAM and peripheral space. 163 * Bits 27:20 of this address will be assumed to be all zero. Full addresses 164 * must have 32b alignment 165 * 166 * \param[in] list 167 * Pointer to the copy list 168 *****************************************************************************/ 169 #define HapiApplyCopyList(p) HAPI_TABLE_POINTER->applyCopyList((p)) 170 171 // uint32_t HapiFlashSectorErase(uint32_t key, uint32_t addr); 172 /***************************************************************************** 173 * \brief Erase a flash sector. 174 * 175 * Erase the flash sector that begins at address addr. Function will not return 176 * before erase operation completes or error occurs. Only main sectors and the 177 * CCFG sector is supported and are subject to flash write/erase restrictions. 178 * No default data is written back to CCFG after an erase. 179 * 180 * \warning No accesses to flash may occur during an erase operation. Interrupts 181 * must be disabled prior to calling or care taken that no reads to flash occur. 182 * DMA operations targeting flash must be suspended. 183 * 184 * \param key 185 * Magic number \ref FLASH_API_KEY (0xB7E3A08F) to protect against inadvertent 186 * flash erasures 187 * \param addr 188 * First address of a main sector or the CCFG sector 189 * 190 * \return 191 * Return code 192 * - \ref FAPI_STATUS_SUCCESS (0) 193 * - \ref FAPI_STATUS_ADDRESS_ERROR 194 * - \ref FAPI_STATUS_INVALID_KEY 195 * - \ref FAPI_STATUS_FSM_ERROR 196 *****************************************************************************/ 197 #define HapiFlashSectorErase(k, p) HAPI_TABLE_POINTER->flashSectorErase((k), (p)) 198 199 // uint32_t HapiFlashBankErase(uint32_t key); 200 /****************************************************************************** 201 * \brief Erase all unprotected sectors in the flash main bank. 202 * 203 * Function will not return before mass erase operation completes or error occurs. 204 * 205 * \warning No accesses to flash may occur during an erase operation. Interrupts 206 * must be disabled prior to calling or care taken that no reads to flash occur. 207 * DMA operations targeting flash must be suspended. 208 * 209 * \param key 210 * Magic number \ref FLASH_API_KEY (0xB7E3A08F) to protect against inadvertent 211 * flash erasures 212 * 213 * \return 214 * Return code 215 * - \ref FAPI_STATUS_SUCCESS (0) 216 * - \ref FAPI_STATUS_INVALID_KEY 217 * - \ref FAPI_STATUS_FSM_ERROR 218 *****************************************************************************/ 219 #define HapiFlashBankErase(k) HAPI_TABLE_POINTER->flashBankErase((k)) 220 221 // uint32_t HapiFlashProgram(uint32_t key, const uint8_t *data, uint32_t addr, uint32_t nBytes) 222 /****************************************************************************** 223 * \brief Program to flash (MAIN or CCFG) 224 * 225 * This function programs a sequence of bytes into the on-chip flash. 226 * Programming each location consists of the result of an AND operation 227 * of the new data and the existing data; in other words bits that contain 228 * 1 can remain 1 or be changed to 0, but bits that are 0 cannot be changed 229 * to 1. Therefore, a byte can be programmed multiple times as long as these 230 * rules are followed; if a program operation attempts to change a 0 bit to 231 * a 1 bit, that bit will not have its value changed. 232 * 233 * Programming may cross main sector boundaries. This function does not 234 * return until the data has been programmed or a programming error occurs. 235 * 236 * \note It is recommended to disable cache and line buffer before 237 * programming the flash and re-enable/clear cache and line buffer when the 238 * program operation completes. 239 * 240 * \warning Please note that code can not execute in flash while any part of 241 * the flash is being programmed or erased. The application must disable 242 * interrupts that have interrupt routines in flash. 243 * 244 * \warning The \c data pointer can not point to flash. 245 * 246 * \param key 247 * Magic number that must be \ref FLASH_API_KEY. The key protects against 248 * random jumps into the flash API 249 * \param data 250 * Pointer to the byte array of new data to be programmed 251 * \param addr 252 * First byte address in flash to be programmed 253 * \param nBytes 254 * Number of bytes to be programmed 255 * 256 * \return 257 * Return code 258 * - \ref FAPI_STATUS_SUCCESS (0) 259 * - \ref FAPI_STATUS_ADDRESS_ERROR 260 * - \ref FAPI_STATUS_INVALID_KEY 261 * - \ref FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH 262 * - \ref FAPI_STATUS_FSM_ERROR 263 *****************************************************************************/ 264 #define HapiFlashProgram(k, s, d, n) HAPI_TABLE_POINTER->flashProgram((k), (s), (d), (n)) 265 266 // uint32_t HapiCountBits(uint32_t word) 267 /***************************************************************************** 268 * \brief Return Hamming weight (# bits that are set) of word 269 * 270 * \param[in] word 271 * 32-bit word to count bits for 272 * 273 * \return 274 * Number of bits set in word (0-32) 275 *****************************************************************************/ 276 #define HapiCountBits(w) HAPI_TABLE_POINTER->countBits((w)) 277 278 // void HapiSecdedEncode(uint8_t *parity, const uint64_t *data, uint32_t nWords64) 279 /***************************************************************************** 280 * \brief Perform SECDED encoding over data array and produce parity array 281 * Uses the usual (72,64) SECDED generator matrix: 282 * DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDDDD PPPPPPPP 283 * 66665555 55555544 44444444 33333333 33222222 22221111 11111100 00000000 00000000 284 * 32109876 54321098 76543210 98765432 10987654 32109876 54321098 76543210 76543210 285 * ------------------------------------------------------------------------------------- 286 * P7: 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 01111111 287 * P6: 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111110 00000000 288 * P5: 11111111 11111111 11111111 11111111 00000000 00000000 00000000 00000001 00000000 289 * P4: 11111111 11111111 00000000 00000000 11111111 11111111 00000000 00000001 00000000 290 * P3: 11111111 00000000 11111111 00000000 11111111 00000000 11111111 00000001 00000000 291 * P2: 11110000 11110000 11110000 11110000 11110000 11110000 11110000 11110001 00000000 292 * P1: 11001100 11001100 11001100 11001100 11001100 11001100 11001100 11001101 00000000 293 * P0: 10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101011 00000000 294 * 295 * \param[out] parity 296 * Pointer to where to store parity bytes (one byte per 64b word of data) 297 * \param[in] data 298 * Pointer to the data (4B aligned) 299 * \param[in] nWords64 300 * Number of 64b words of data / bytes of parity 301 *****************************************************************************/ 302 #define HapiSecdedEncode(p, d, n) HAPI_TABLE_POINTER->secdedEncode((p), (d), (n)) 303 304 // int32_t HapiSecdedDecode(uint64_t *data, const uint8_t *parity, uint32_t nWords64) 305 /***************************************************************************** 306 * \brief Perform SECDED correction/detection over data array using parity array 307 * Uses the usual (72,64) SECDED generator matrix. 308 * 309 * \param[inout] data 310 * Pointer to the data (4B aligned) 311 * \param[in] parity 312 * Pointer to the parity bytes (one byte per 64b word of data) 313 * \param[in] nWords64 314 * Number of 64b words of data / bytes of parity 315 * 316 * \return 317 * <0: uncorrectable error detected 318 * >=0: number of bits corrected 319 *****************************************************************************/ 320 #define HapiSecdedDecode(d, p, n) HAPI_TABLE_POINTER->secdedDecode((d), (p), (n)) 321 322 // void BootEnterApplication(void) 323 /***************************************************************************** 324 * \brief Called from bootloader to transfer into application 325 * When called from a bootloader this function will apply application security 326 * restrictions and transfer to application (set up VTOR register, setup SP and 327 * jump to entry point as defined by application vector table in CCFG). The 328 * function will never return. 329 * 330 * When called from an application the function will return without doing 331 * anything. 332 *****************************************************************************/ 333 #define HapiEnterApplication() HAPI_TABLE_POINTER->enterApplication() 334 335 // int_fast16_t HapiSha256SwHashData( 336 // SHA256SW_Handle handle, 337 // const void *data, 338 // size_t length, 339 // uint32_t digest[8] 340 // ) 341 /***************************************************************************** 342 * \brief Performs a complete SHA256 hash operation, producing a final 343 * digest for the data. 344 * 345 * This function wraps #HapiSha256SwStart(), #HapiSha256SwAddData(), and 346 * #HapiSha256SwFinalize(). 347 * 348 * There is no need to call #HapiSha256SwStart() prior to calling this function. 349 * 350 * The total length of data that can be hashed by this implementation 351 * is 512MiB (0x20000000 bytes.) 352 * 353 * \param[in] handle A #SHA256SW_Handle. 354 * 355 * \param[in] data Data (message) to hash. May point to zero. 356 * 357 * \param[in] length The number of bytes (pointed to by \c data parameter) 358 * to add to the hash. 359 * 360 * \param[out] digest Output location for the final digest. Must be 361 * able to hold 32 bytes of output and be 32-bit aligned. 362 * 363 * \retval #SHA2SW_STATUS_SUCCESS (0) The hash operation succeeded. 364 * \retval #SHA2SW_STATUS_ERROR The hash operation failed. 365 * \retval #SHA2SW_STATUS_UNSUPPORTED Requested Hash Type is unsupported. 366 * \retval #SHA2SW_STATUS_LENGTH_TOO_LARGE The requested length of data to hash 367 * is more than the implementation 368 * supports. 369 * \retval #SHA2SW_STATUS_NULL_INPUT One or more of the pointer inputs is 370 * NULL. 371 *****************************************************************************/ 372 #define HapiSha256SwHashData(h, d, l, g) HAPI_TABLE_POINTER->sha256SwHashData((h), SHA2SW_HASH_TYPE_256, (d), (l), (g)) 373 374 // int_fast16_t HapiSha256SwStart(SHA256SW_Handle handle) 375 /***************************************************************************** 376 * \brief Initialize a SHA256SW_Handle, preparing for hashing data. 377 * 378 * \param[in] handle A #SHA256SW_Handle. 379 * 380 * \retval #SHA2SW_STATUS_SUCCESS (0) The hash operation succeeded. 381 * \retval #SHA2SW_STATUS_UNSUPPORTED Requested Hash Type is unsupported. 382 * \retval #SHA2SW_STATUS_NULL_INPUT One or more of the pointer inputs is 383 * NULL. 384 * 385 * \sa #HapiSha256SwAddData() 386 * \sa #HapiSha256SwFinalize() 387 *****************************************************************************/ 388 #define HapiSha256SwStart(h) HAPI_TABLE_POINTER->sha256SwStart((h), SHA2SW_HASH_TYPE_256) 389 390 // int_fast16_t HapiSha256SwAddData(SHA256SW_Handle handle, const void *data, size_t length) 391 /***************************************************************************** 392 * \brief Add data to a SHA256 operation. 393 * 394 * Adds data to a hash operation. The \c handle must have been 395 * initialized by a call to HapiSha256SwStart first. 396 * 397 * The total length of data that can be hashed by this implementation 398 * is 512MiB (0x20000000 bytes.) 399 * 400 * After passing in all data to be hashed, call #HapiSha256SwFinalize() 401 * to obtain the final digest. 402 * 403 * \pre handle was previously passed to #HapiSha256SwStart(). 404 * 405 * \param[in] handle A #SHA256SW_Handle. 406 * 407 * \param[in] data Data (message) to add to the hash. May point to zero. 408 * 409 * \param[in] length The number of bytes (pointed to by \c data parameter) 410 * to add to the hash. 411 * 412 * \retval #SHA2SW_STATUS_SUCCESS (0) The hash operation succeeded. 413 * \retval #SHA2SW_STATUS_LENGTH_TOO_LARGE The requested length of data to hash 414 * is more than the implementation 415 * supports. 416 * \retval #SHA2SW_STATUS_NULL_INPUT One or more of the pointer inputs is 417 * NULL. 418 * 419 * \sa #HapiSha256SwStart() 420 * \sa #HapiSha256SwFinalize() 421 *****************************************************************************/ 422 #define HapiSha256SwAddData(h, d, l) HAPI_TABLE_POINTER->sha256SwAddData((h), (d), (l)) 423 424 // int_fast16_t HapiSha256SwFinalize(SHA256SW_Handle handle, uint32_t digest[8]); 425 /***************************************************************************** 426 * \brief Finalize a SHA256 operation, creating the final digest. 427 * 428 * After calling this function, \c handle should not be used again 429 * until it has been reinitialized via a call to #HapiSha256SwStart(). 430 * 431 * \pre handle was previously passed to #HapiSha256SwStart() and data to 432 * be hashed was passed to #HapiSha256SwAddData() 433 * 434 * \param[in] handle A #SHA256SW_Handle. 435 * 436 * \param[out] digest Output location for the final digest. Must be 437 * able to hold 32 bytes of output and be 32-bit aligned. 438 * 439 * \retval #SHA2SW_STATUS_SUCCESS (0) The hash operation succeeded. 440 * \retval #SHA2SW_STATUS_NULL_INPUT One or more of the pointer inputs is 441 * NULL. 442 * 443 * \sa #HapiSha256SwStart() 444 * \sa #HapiSha256SwAddData() 445 *****************************************************************************/ 446 #define HapiSha256SwFinalize(h, g) HAPI_TABLE_POINTER->sha256SwFinalize((h), (g)) 447 448 // __noreturn void HapiResetDevice(void) 449 /***************************************************************************** 450 * \brief Perform system reset of the device 451 * 452 * This function will perform a system reset of the device equal to a pin 453 * reset. Software can determine that this was the cause of reset once 454 * rebooted. The function will never return. 455 *****************************************************************************/ 456 #define HapiResetDevice() HAPI_TABLE_POINTER->resetDevice() 457 458 // HAPI entry used for internal purposes 459 #define HapiSha256SwProcessBlock(d, w) HAPI_TABLE_POINTER->sha256SwProcessBlock((d), (w)) 460 461 // HAPI entry used for internal purposes 462 #define HapiSha256Sw_K256 (*HAPI_TABLE_POINTER->sha256SW_K256) 463 464 // HAPI entry used for internal purposes 465 #define HapiSha256Sw_initialDigest256 (*HAPI_TABLE_POINTER->sha256Sw_initialDigest256) 466 467 // void HapiWaitUs(uint32_t nUs) 468 /***************************************************************************** 469 * \brief Wait function 470 * 471 * \param[in] nUs 472 * Number of microseconds to wait (min: 1 us, max: 2^24 us) 473 *****************************************************************************/ 474 #define HapiWaitUs(n) HAPI_TABLE_POINTER->waitUs((n)) 475 476 // uint32_t HapiClz(uint32_t x) 477 /***************************************************************************** 478 * \brief Count leading zeros 479 * 480 * \param[in] x 481 * Value to count leading zeros for 482 * \return 483 * Number of leading zeroes (0 to 32) 484 *****************************************************************************/ 485 #define HapiClz(x) HAPI_TABLE_POINTER->clz((x)) 486 487 #endif //__HAPI_H__ 488