1 /*
2  * Copyright 2017-2018 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_cau3.h"
10 
11 /*******************************************************************************
12  * Definitions
13  ******************************************************************************/
14 
15 /* Component ID definition, used by tools. */
16 #ifndef FSL_COMPONENT_ID
17 #define FSL_COMPONENT_ID "platform.drivers.cau3"
18 #endif
19 
20 /*! Compile time sizeof() check */
21 #define BUILD_ASSURE(condition, msg) extern int msg[1 - 2 * (!(condition))] __attribute__((unused))
22 
23 #define CAU3_SR_TKCS_INITRUN 0x00000000U
24 #define CAU3_SR_TKCS_RUN 0x00000100U
25 #define CAU3_SR_TKCS_DBGHALT 0x00000200U
26 #define CAU3_SR_TKCS_STOPNOERR 0x00000900U
27 #define CAU3_SR_TKCS_STOPERROR 0x00000A00U
28 #define CAU3_SR_TKCS_SECV 0x00000E00U
29 #define CAU3_SR_TKCS_EXTSECV 0x00000F00U
30 
31 #define CAU3_DMEM_STK_BASE 0xfff003f8U
32 #define CAU3_DMEM_AES_RCON 0xfff00A00U
33 
34 #define CAU3_TASK_SECV_INIT 0x00 * 4
35 #define CAU3_TASK_STOPERROR 0x01 * 4
36 #define CAU3_TASK_STOPNOERR 0x02 * 4
37 #define CAU3_TASK_NULL 0x02 * 4
38 #define CAU3_TASK_BLKLD_DMEM 0x03 * 4
39 #define CAU3_TASK_LD_KEYCTX 0x04 * 4
40 #define CAU3_TASK_LD_SP_KEYCTX 0x05 * 4
41 #define CAU3_TASK_CLR_KEYCTX 0x06 * 4
42 #define CAU3_TASK_LD_KEY 0x07 * 4
43 #define CAU3_TASK_LD_KEK 0x08 * 4
44 #define CAU3_TASK_LD_IV 0x09 * 4
45 #define CAU3_TASK_AES_KEY_SCH 0x0A * 4
46 #define CAU3_TASK_AES_ENCRYPT 0x0B * 4
47 #define CAU3_TASK_AES_DECRYPT 0x0C * 4
48 #define CAU3_TASK_AES128_ENCRYPT 0x0D * 4
49 #define CAU3_TASK_AES128_DECRYPT 0x0E * 4
50 #define CAU3_TASK_AES128_CMAC 0x0F * 4
51 #define CAU3_TASK_SHA256_INIT_STATE 0x10 * 4
52 #define CAU3_TASK_SHA256_UPDATE 0x11 * 4
53 #define CAU3_TASK_KEY_BLOB_UNWRAP 0x12 * 4
54 #define CAU3_TASK_SHA1_HASH 0x13 * 4
55 #define CAU3_TASK_SHA1_INIT_STATE 0x14 * 4
56 #define CAU3_TASK_SHA512_INIT_STATE 0x15 * 4
57 #define CAU3_TASK_SHA512_UPDATE 0x16 * 4
58 #define CAU3_TASK_3DES_CHECK_PARITY 0x17 * 4
59 #define CAU3_TASK_3DES_ENCRYPT 0x18 * 4
60 #define CAU3_TASK_3DES_DECRYPT 0x19 * 4
61 #define CAU3_TASK_CHA_POLY_ENCRYPT 0x1A * 4
62 #define CAU3_TASK_CHA_POLY_DECRYPT 0x1B * 4
63 
64 #define CAU3_SEMA4_LOCK 0x80000000U
65 #define CAU3_SEMA4_RELEASE 0x00000000U
66 #define CAU3_SMOWNR_OWNED_BY_ME 0x00000001U
67 #define CAU3_SMOWNR_UNLOCKED 0x80000000U
68 
69 /*! @brief keyContext structure in the CAU3's DataMemory */
70 typedef struct _cau3_key_context
71 {
72     uint32_t keySize;    /*!< key size in bytes, 0 = invalid context */
73     uint32_t streamSize; /*!< rfu-firmware; stream length in bytes */
74     uint32_t *keySched;  /*!< rfu-firmware; ptr to expanded key schedule */
75     uint32_t zeroFill;   /*!< zero (unused) to keep 0-mod-4 alignment */
76     uint8_t iv[16];      /*!< initialization vector */
77     uint8_t key[32];     /*!< key for 3des, aes[128,192,256] */
78 } cau3_key_context_t;
79 
80 typedef enum _cau3_crypt {
81     kCAU3_Encrypt = 0,
82     kCAU3_Decrypt = 1,
83 } cau3_crypt_t;
84 
85 #define cau3_memcpy memcpy
86 
87 /*! Internal states of the HASH creation process */
88 typedef enum _cau3_hash_algo_state {
89     kCAU3_StateHashInit = 1u, /*!< Init state. */
90     kCAU3_StateHashUpdate,    /*!< Update state. */
91 } cau3_hash_algo_state_t;
92 
93 /*! multiple of 64-byte block represented as byte array of 32-bit words */
94 typedef union _cau3_hash_block {
95     uint32_t w[CAU3_HASH_BLOCK_SIZE / 4]; /*!< array of 32-bit words */
96     uint8_t b[CAU3_HASH_BLOCK_SIZE];      /*!< byte array */
97 } cau3_hash_block_t;
98 
99 /*! internal cau3_hash context structure */
100 typedef struct _cau3_hash_ctx_internal
101 {
102     cau3_hash_block_t blk;        /*!< memory buffer. only full blocks are written to CAU3 during hash/cmac updates */
103     size_t blksz;                 /*!< number of valid bytes in memory buffer */
104     cau3_hash_algo_t algo;        /*!< selected algorithm from the set of supported algorithms */
105     cau3_hash_algo_state_t state; /*!< finite machine state of the hash software process */
106     size_t fullMessageSize;       /*!< track message size during CAU3_HASH_Update(). The value is used for padding. */
107     uint32_t runningHash[8];
108 } cau3_hash_ctx_internal_t;
109 
110 /*!< SHA-1/SHA-2 digest length in bytes  */
111 enum _cau3_hash_digest_len
112 {
113     kCAU3_OutLenSha1 = 20u,
114     kCAU3_OutLenSha256 = 32u,
115 };
116 
117 /*! 64-byte block represented as byte array of 16 32-bit words */
118 typedef union _cau3_sha_block {
119     uint32_t w[64 / 4]; /*!< array of 32-bit words */
120     uint8_t b[64];      /*!< byte array */
121 } cau3_sha_block_t;
122 
123 /*! Full word representing the actual bit values for the CAU3 1.0 mode register. */
124 typedef uint32_t cau3_mode_t;
125 
126 #define CAU3_MDPK_ALG_PKHA (0x80U) /*!< Bit field value for CAU3_MDPK_ALG: PKHA */
127 #define CAU3_MD_ALG_SHIFT 16
128 
129 typedef enum _cau3_algorithm {
130     kCAU3_AlgorithmPKHA = CAU3_MDPK_ALG_PKHA << CAU3_MD_ALG_SHIFT,
131 } cau3_algorithm_t;
132 
133 /*! @brief CAU3 status flags */
134 enum _cau3_status_flag
135 {
136     kCAU3_StatusPkhaBusy = 1U << CAU3_STA_PB_SHIFT,
137     kCAU3_StatusDoneIsr = 1U << CAU3_STA_DI_SHIFT,
138     kCAU3_StatusErrorIsr = 1U << CAU3_STA_EI_SHIFT,
139     kCAU3_StatusPublicKeyPrime = 1U << CAU3_STA_PKP_SHIFT,
140     kCAU3_StatusPublicKeyOpOne = 1U << CAU3_STA_PKO_SHIFT,
141     kCAU3_StatusPublicKeyOpZero = 1U << CAU3_STA_PKZ_SHIFT,
142     kCAU3_StatusAll = 0 | kCAU3_StatusDoneIsr | kCAU3_StatusErrorIsr | kCAU3_StatusPkhaBusy |
143                       kCAU3_StatusPublicKeyPrime | kCAU3_StatusPublicKeyOpOne | kCAU3_StatusPublicKeyOpZero
144 };
145 
146 /*! @brief CAU3 clear register */
147 typedef enum _cau3_clear_written {
148     kCAU3_ClearMode = 1U << 0,
149     kCAU3_ClearDataSize = 1U << 2,
150     kCAU3_ClearPkhaSizeA = 1U << 12,
151     kCAU3_ClearPkhaSizeB = 1U << 13,
152     kCAU3_ClearPkhaSizeN = 1U << 14,
153     kCAU3_ClearPkhaSizeE = 1U << 15,
154     kCAU3_ClearAllSize = (int)kCAU3_ClearPkhaSizeA | kCAU3_ClearPkhaSizeB | kCAU3_ClearPkhaSizeN | kCAU3_ClearPkhaSizeE,
155     kCAU3_ClearAll = (int)(kCAU3_ClearMode | kCAU3_ClearDataSize | kCAU3_ClearAllSize | 0)
156 } cau3_clear_written_t;
157 
158 /*! @brief PKHA functions - arithmetic, copy/clear memory. */
159 typedef enum _cau3_pkha_func_t {
160     kCAU3_PKHA_ClearMem = 1U,
161     kCAU3_PKHA_ArithModAdd = 2U,         /*!< (A + B) mod N */
162     kCAU3_PKHA_ArithModSub1 = 3U,        /*!< (A - B) mod N */
163     kCAU3_PKHA_ArithModSub2 = 4U,        /*!< (B - A) mod N */
164     kCAU3_PKHA_ArithModMul = 5U,         /*!< (A x B) mod N */
165     kCAU3_PKHA_ArithModExp = 6U,         /*!< (A^E) mod N */
166     kCAU3_PKHA_ArithModRed = 7U,         /*!< (A) mod N */
167     kCAU3_PKHA_ArithModInv = 8U,         /*!< (A^-1) mod N */
168     kCAU3_PKHA_ArithEccAdd = 9U,         /*!< (P1 + P2) */
169     kCAU3_PKHA_ArithEccDouble = 10U,     /*!< (P2 + P2) */
170     kCAU3_PKHA_ArithEccMul = 11U,        /*!< (E x P(A0,A1) */
171     kCAU3_PKHA_ArithModR2 = 12U,         /*!< (R^2 mod N) */
172     kCAU3_PKHA_ArithModRR = 13U,         /*!< (RERP mod N) */
173     kCAU3_PKHA_ArithGcd = 14U,           /*!< GCD (A, N) */
174     kCAU3_PKHA_ArithPrimalityTest = 15U, /*!< Miller-Rabin */
175     kCAU3_PKHA_CopyMemSizeN = 16U,
176     kCAU3_PKHA_CopyMemSizeSrc = 17U,
177     kCAU3_PKHA_ArithModSqrt = 0x17U, /*!< (B0 x B0) mod N = A mod N */
178     kCAU3_PKHA_ArithEcmMul = 0x4B,   /*!< (E x P[A0]) */
179     kCAU3_PKHA_ArithEctAdd = 0x89,   /*!< (P[A0,A1] + P[B1,B2]) */
180     kCAU3_PKHA_ArithEctMul = 0x8B,   /*!< (E x P[A0,A1]) */
181 } cau3_pkha_func_t;
182 
183 /*! @brief Register areas for PKHA clear memory operations. */
184 typedef enum _cau3_pkha_reg_area {
185     kCAU3_PKHA_RegA = 8U,
186     kCAU3_PKHA_RegB = 4U,
187     kCAU3_PKHA_RegE = 2U,
188     kCAU3_PKHA_RegN = 1U,
189     kCAU3_PKHA_RegAll = kCAU3_PKHA_RegA | kCAU3_PKHA_RegB | kCAU3_PKHA_RegE | kCAU3_PKHA_RegN,
190 } cau3_pkha_reg_area_t;
191 
192 /*! @brief Quadrant areas for 2048-bit registers for PKHA copy memory
193  * operations. */
194 typedef enum _cau3_pkha_quad_area_t {
195     kCAU3_PKHA_Quad0 = 0U,
196     kCAU3_PKHA_Quad1 = 1U,
197     kCAU3_PKHA_Quad2 = 2U,
198     kCAU3_PKHA_Quad3 = 3U,
199 } cau3_pkha_quad_area_t;
200 
201 /*! @brief User-supplied (R^2 mod N) input or CAU3 should calculate. */
202 typedef enum _cau3_pkha_r2_t {
203     kCAU3_PKHA_CalcR2 = 0U, /*!< Calculate (R^2 mod N) */
204     kCAU3_PKHA_InputR2 = 1U /*!< (R^2 mod N) supplied as input */
205 } cau3_pkha_r2_t;
206 
207 /*! @brief CAU3 PKHA parameters */
208 typedef struct _cau3_pkha_mode_params_t
209 {
210     cau3_pkha_func_t func;
211     cau3_pkha_f2m_t arithType;
212     cau3_pkha_montgomery_form_t montFormIn;
213     cau3_pkha_montgomery_form_t montFormOut;
214     cau3_pkha_reg_area_t srcReg;
215     cau3_pkha_quad_area_t srcQuad;
216     cau3_pkha_reg_area_t dstReg;
217     cau3_pkha_quad_area_t dstQuad;
218     cau3_pkha_timing_t equalTime;
219     cau3_pkha_r2_t r2modn;
220 } cau3_pkha_mode_params_t;
221 
222 /*******************************************************************************
223  * Variables
224  ******************************************************************************/
225 /*******************************************************************************
226  * CAU3 Read-Only Data Constants and CryptoCore Code Image
227  ******************************************************************************/
228 
229 /*  in the cau3's private, local data memory, there is a section for read-only  */
230 /*  constants associated with AES, SHA-1, SHA-256, SHA-384 and SHA-512.  */
231 /*  the memory organization and layout of this section is defined as:  */
232 /*   */
233 /*  description            size dmem_base       description  */
234 /*  cau_dmem_aes_rcon        48  FFF00800       RO aes constants        10 x 32b  */
235 /*  cau_dmem_sha1_k          16  FFF00830       RO sha1 initial "k"      4 x 32b              */
236 /*  cau_dmem_sha1_init_h     32  FFF00840       RO sha1 initial state    5 x 32b  */
237 /*  cau_dmem_sha224_init_h   32  FFF00860       RO sha224 initial state  8 x 32b              */
238 /*  cau_dmem_sha256_init_h   32  FFF00880       RO sha256 initial state  8 x 32b              */
239 /*  cau_dmem_sha256_k       256  FFF008A0       RO sha256 initial "k"   64 x 32b  */
240 /*  cau_dmem_sha384_init_h   64  FFF009A0       RO sha384 initial state 16 x 32b  */
241 /*  cau_dmem_sha512_init_h   64  FFF009E0       RO sha512 initial state 16 x 32b  */
242 /*  cau_dmem_sha512_k       640  FFF00A20       RO sha512 initial "k"   160 x 32b  */
243 /*   */
244 /*  data size allocation are rounded up to be modulo 16 bytes as required.  */
245 /*   */
246 
247 static const uint32_t s_cau3ReadOnlyConstants[] __attribute__((aligned(16))) = {
248     /*  AES RCON[]  */
249     0x01000000U, 0x02000000U, 0x04000000U, 0x08000000U, 0x10000000U, 0x20000000U, 0x40000000U, 0x80000000U, 0x1b000000U,
250     0x36000000U, 0x00000000U, 0x00000000U, /*  zero fill for 0-mod-16 alignment  */
251 
252     /*  SHA1_K[]  */
253     0x5a827999U, 0x6ed9eba1U, 0x8f1bbcdcU, 0xca62c1d6U,
254 
255     /*  SHA1_INIT_H[]  */
256     0x67452301U, 0xefcdab89U, 0x98badcfeU, 0x10325476U, 0xc3d2e1f0U, 0x00000000U, 0x00000000U,
257     0x00000000U, /*  zero fill for 0-mod-16 alignemnt  */
258 
259     /*  SHA224_INIT_H[]  */
260     0xc1059ed8U, 0x367cd507U, 0x3070dd17U, 0xf70e5939U, 0xffc00b31U, 0x68581511U, 0x64f98fa7U, 0xbefa4fa4U,
261 
262     /*  SHA256_INIT_H[]  */
263     /*  As described in FIPS PUB 180-4 "Secure Hash Standard", the initial hash value  */
264     /*  for SHA-256 is obtained by taking the first thirty-two bits of the fractional  */
265     /*  parts of the square roots of the first eight prime numbers.  */
266     0x6a09e667U, 0xbb67ae85U, 0x3c6ef372U, 0xa54ff53aU, 0x510e527fU, 0x9b05688cU, 0x1f83d9abU, 0x5be0cd19U,
267 
268     /*  SHA256_K[], also used as SHA224_K[]  */
269     /*  As described in FIPS PUB 180-4 "Secure Hash Standard", SHA-224 & SHA-256 use  */
270     /*  the same sequence of sixty-four constant 32-bit words (K[]), where the words  */
271     /*  represent the first thirty-two bits of the fractional parts of the cube roots  */
272     /*  of the first sixty-four prime numbers.  */
273 
274     0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU, 0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U, 0xd807aa98U,
275     0x12835b01U, 0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U, 0xc19bf174U, 0xe49b69c1U, 0xefbe4786U,
276     0x0fc19dc6U, 0x240ca1ccU, 0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, 0x983e5152U, 0xa831c66dU, 0xb00327c8U,
277     0xbf597fc7U, 0xc6e00bf3U, 0xd5a79147U, 0x06ca6351U, 0x14292967U, 0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU, 0x53380d13U,
278     0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U, 0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U,
279     0xd6990624U, 0xf40e3585U, 0x106aa070U, 0x19a4c116U, 0x1e376c08U, 0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU,
280     0x5b9cca4fU, 0x682e6ff3U, 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U, 0x90befffaU, 0xa4506cebU, 0xbef9a3f7U,
281     0xc67178f2U,
282 
283     /*  SHA384_INIT_H[]  */
284     /*  8 x 64-bit words in little-endian format  */
285     0xc1059ed8U, 0xcbbb9d5dU, 0x367cd507U, 0x629a292aU, 0x3070dd17U, 0x9159015aU, 0xf70e5939U, 0x152fecd8U, 0xffc00b31U,
286     0x67332667U, 0x68581511U, 0x8eb44a87U, 0x64f98fa7U, 0xdb0c2e0dU, 0xbefa4fa4U, 0x47b5481dU,
287 
288     /*  SHA512_INIT_H[]  */
289     /*  8 x 64-bit words in little-endian format  */
290     0xf3bcc908U, 0x6a09e667U, 0x84caa73bU, 0xbb67ae85U, 0xfe94f82bU, 0x3c6ef372U, 0x5f1d36f1U, 0xa54ff53aU, 0xade682d1U,
291     0x510e527fU, 0x2b3e6c1fU, 0x9b05688cU, 0xfb41bd6bU, 0x1f83d9abU, 0x137e2179U, 0x5be0cd19U,
292 
293     /*  SHA512_K[]  */
294     /*  80 x 64-bit words in little-endian format  */
295     0xd728ae22U, 0x428a2f98U, 0x23ef65cdU, 0x71374491U, 0xec4d3b2fU, 0xb5c0fbcfU, 0x8189dbbcU, 0xe9b5dba5U, 0xf348b538U,
296     0x3956c25bU, 0xb605d019U, 0x59f111f1U, 0xaf194f9bU, 0x923f82a4U, 0xda6d8118U, 0xab1c5ed5U, 0xa3030242U, 0xd807aa98U,
297     0x45706fbeU, 0x12835b01U, 0x4ee4b28cU, 0x243185beU, 0xd5ffb4e2U, 0x550c7dc3U, 0xf27b896fU, 0x72be5d74U, 0x3b1696b1U,
298     0x80deb1feU, 0x25c71235U, 0x9bdc06a7U, 0xcf692694U, 0xc19bf174U, 0x9ef14ad2U, 0xe49b69c1U, 0x384f25e3U, 0xefbe4786U,
299     0x8b8cd5b5U, 0x0fc19dc6U, 0x77ac9c65U, 0x240ca1ccU, 0x592b0275U, 0x2de92c6fU, 0x6ea6e483U, 0x4a7484aaU, 0xbd41fbd4U,
300     0x5cb0a9dcU, 0x831153b5U, 0x76f988daU, 0xee66dfabU, 0x983e5152U, 0x2db43210U, 0xa831c66dU, 0x98fb213fU, 0xb00327c8U,
301     0xbeef0ee4U, 0xbf597fc7U, 0x3da88fc2U, 0xc6e00bf3U, 0x930aa725U, 0xd5a79147U, 0xe003826fU, 0x06ca6351U, 0x0a0e6e70U,
302     0x14292967U, 0x46d22ffcU, 0x27b70a85U, 0x5c26c926U, 0x2e1b2138U, 0x5ac42aedU, 0x4d2c6dfcU, 0x9d95b3dfU, 0x53380d13U,
303     0x8baf63deU, 0x650a7354U, 0x3c77b2a8U, 0x766a0abbU, 0x47edaee6U, 0x81c2c92eU, 0x1482353bU, 0x92722c85U, 0x4cf10364U,
304     0xa2bfe8a1U, 0xbc423001U, 0xa81a664bU, 0xd0f89791U, 0xc24b8b70U, 0x0654be30U, 0xc76c51a3U, 0xd6ef5218U, 0xd192e819U,
305     0x5565a910U, 0xd6990624U, 0x5771202aU, 0xf40e3585U, 0x32bbd1b8U, 0x106aa070U, 0xb8d2d0c8U, 0x19a4c116U, 0x5141ab53U,
306     0x1e376c08U, 0xdf8eeb99U, 0x2748774cU, 0xe19b48a8U, 0x34b0bcb5U, 0xc5c95a63U, 0x391c0cb3U, 0xe3418acbU, 0x4ed8aa4aU,
307     0x7763e373U, 0x5b9cca4fU, 0xd6b2b8a3U, 0x682e6ff3U, 0x5defb2fcU, 0x748f82eeU, 0x43172f60U, 0x78a5636fU, 0xa1f0ab72U,
308     0x84c87814U, 0x1a6439ecU, 0x8cc70208U, 0x23631e28U, 0x90befffaU, 0xde82bde9U, 0xa4506cebU, 0xb2c67915U, 0xbef9a3f7U,
309     0xe372532bU, 0xc67178f2U, 0xea26619cU, 0xca273eceU, 0x21c0c207U, 0xd186b8c7U, 0xcde0eb1eU, 0xeada7dd6U, 0xee6ed178U,
310     0xf57d4f7fU, 0x72176fbaU, 0x06f067aaU, 0xa2c898a6U, 0x0a637dc5U, 0xbef90daeU, 0x113f9804U, 0x131c471bU, 0x1b710b35U,
311     0x23047d84U, 0x28db77f5U, 0x40c72493U, 0x32caab7bU, 0x15c9bebcU, 0x3c9ebe0aU, 0x9c100d4cU, 0x431d67c4U, 0xcb3e42b6U,
312     0x4cc5d4beU, 0xfc657e2aU, 0x597f299cU, 0x3ad6faecU, 0x5fcb6fabU, 0x4a475817U, 0x6c44198cU,
313     /*  CHACHA_K[]  */
314     0x61707865U, 0x3320646eU, 0x79622d32U, 0x6b206574U};
315 
316 static const uint32_t s_cau3ReadOnlyConstantsBytes = sizeof(s_cau3ReadOnlyConstants);
317 
318 static const uint32_t s_cau3ImemImage[] __attribute__((aligned(16))) = {
319     0x60C00000U, 0x54000040U, 0x54000020U, 0x60812760U, 0x608128C0U, 0x60812F00U, 0x60813640U, 0x608138C0U, 0x54000040U,
320     0x60813C20U, 0x60813F40U, 0x60802060U, 0x60803BC0U, 0x60805780U, 0x54000040U, 0x60806800U, 0x60808AA0U, 0x60808D00U,
321     0x60814120U, 0x6080C100U, 0x6080BF60U, 0x54000040U, 0x54000040U, 0x6080FB60U, 0x6080FE20U, 0x608112C0U, 0x608150C0U,
322     0x60815700U, 0x54000040U, 0x54000040U, 0x54000040U, 0x54000040U, 0x86000280U, 0x86002282U, 0x08C82236U, 0x2000C011U,
323     0x101FFE11U, 0x00405A31U, 0x20014015U, 0x101FFE15U, 0x00800004U, 0x00800425U, 0x00800846U, 0x00800C67U, 0xCE002220U,
324     0xCE002222U, 0x3C000192U, 0x66801420U, 0x63801400U, 0x86004284U, 0x86006286U, 0xCE002224U, 0xCE002226U, 0x08D020E8U,
325     0x01800108U, 0xAC0012A8U, 0x008C2000U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x01800068U,
326     0x008C2084U, 0x008C10A5U, 0x008C14C6U, 0x008C18E7U, 0xCE002224U, 0xCE002226U, 0x08D020E8U, 0x01800108U, 0xAC0012A8U,
327     0x008C2000U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x01800068U, 0x008C2084U, 0x008C10A5U,
328     0x008C14C6U, 0x008C18E7U, 0xCE002224U, 0xCE002226U, 0x08D020E8U, 0x01800108U, 0xAC0012A8U, 0x008C2000U, 0x008C0021U,
329     0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x01800068U, 0x008C2084U, 0x008C10A5U, 0x008C14C6U, 0x008C18E7U,
330     0xCE002224U, 0xCE002226U, 0x08D020E8U, 0x01800108U, 0xAC0012A8U, 0x008C2000U, 0x008C0021U, 0x008C0442U, 0x008C0863U,
331     0xCE002220U, 0xCE002222U, 0x01800068U, 0x008C2084U, 0x008C10A5U, 0x008C14C6U, 0x008C18E7U, 0xCE002224U, 0xCE002226U,
332     0x08D020E8U, 0x01800108U, 0xAC0012A8U, 0x008C2000U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U,
333     0x01800068U, 0x008C2084U, 0x008C10A5U, 0x008C14C6U, 0x008C18E7U, 0xCE002224U, 0xCE002226U, 0x08D020E8U, 0x01800108U,
334     0xAC0012A8U, 0x008C2000U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x01800068U, 0x008C2084U,
335     0x008C10A5U, 0x008C14C6U, 0x008C18E7U, 0xCE002224U, 0xCE002226U, 0x08D020E8U, 0x01800108U, 0xAC0012A8U, 0x008C2000U,
336     0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x29FFE211U, 0x60801F80U, 0x54000040U, 0x08D02067U,
337     0x018000E7U, 0xAC0012A7U, 0x008C1C00U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U,
338     0x018000E7U, 0xAC0012A7U, 0x008C1C00U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U,
339     0x018000E7U, 0xAC0012A7U, 0x008C1C00U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U,
340     0x018000E7U, 0xAC0012A7U, 0x008C1C00U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U,
341     0x018000E7U, 0xAC0012A7U, 0x008C1C00U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U,
342     0x018000E7U, 0xAC0012A7U, 0x008C1C00U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U,
343     0x018000E7U, 0xAC0012A7U, 0x008C1C00U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U,
344     0x018000E7U, 0xAC0012A7U, 0x008C1C00U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U,
345     0x018000E7U, 0xAC0012A7U, 0x008C1C00U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U,
346     0x018000E7U, 0xAC0012A7U, 0x008C1C00U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x29FFEA11U,
347     0x04807FFFU, 0xC4FFA291U, 0x63802000U, 0x7080001FU, 0x5C1FFFE0U, 0x581FFFE0U, 0x54000020U, 0x08800E31U, 0x08C81A20U,
348     0x2000A012U, 0x101FFE12U, 0x80000252U, 0x3C000312U, 0x668021A0U, 0x63802180U, 0x08501A52U, 0x08501A52U, 0x08501A52U,
349     0x08C82236U, 0x2000C011U, 0x101FFE11U, 0x00405A31U, 0x0C800E04U, 0x638029C0U, 0x3C000024U, 0x63802780U, 0x3C000044U,
350     0x63802540U, 0x94FFF605U, 0x08C860A0U, 0x94000605U, 0x08CC20A6U, 0x00881800U, 0x08C860A1U, 0x94001605U, 0x08CC20A6U,
351     0x00881821U, 0x08C860A2U, 0x94002605U, 0x08CC20A6U, 0x00881842U, 0x08C860A3U, 0x94003605U, 0x08CC20A6U, 0x00881863U,
352     0x60802A40U, 0x94FFFA05U, 0x08C840A0U, 0x94000A05U, 0x08CC40A6U, 0x00881800U, 0x08C840A1U, 0x94001A05U, 0x08CC40A6U,
353     0x00881821U, 0x08C840A2U, 0x94002A05U, 0x08CC40A6U, 0x00881842U, 0x08C840A3U, 0x94003A05U, 0x08CC40A6U, 0x00881863U,
354     0x60802A40U, 0x94FFFE05U, 0x08C820A0U, 0x94000E05U, 0x08CC60A6U, 0x00881800U, 0x08C820A1U, 0x94001E05U, 0x08CC60A6U,
355     0x00881821U, 0x08C820A2U, 0x94002E05U, 0x08CC60A6U, 0x00881842U, 0x08C820A3U, 0x94003E05U, 0x08CC60A6U, 0x00881863U,
356     0x60802A40U, 0x94000200U, 0x94001201U, 0x94002202U, 0x94003203U, 0xAC001220U, 0xAC001221U, 0xAC001222U, 0xAC001223U,
357     0x08500A48U, 0x08CC0508U, 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0x8E002224U, 0x8E002226U,
358     0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U, 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U,
359     0x8E002224U, 0x8E002226U, 0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U, 0x60002B08U, 0x01800000U, 0x01800021U,
360     0x01800042U, 0x01800063U, 0x01900000U, 0x8E002224U, 0x8E002226U, 0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U,
361     0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0xAC001220U, 0xAC001221U, 0xAC001222U, 0xAC001223U,
362     0x0C800E64U, 0x63803A80U, 0x3C000024U, 0x63803760U, 0x3C000044U, 0x63803440U, 0x94FFF664U, 0x08CC2084U, 0x08C82084U,
363     0x08CC6005U, 0x008810A5U, 0xD4FFF665U, 0x08C82005U, 0x08CC6024U, 0x008810A5U, 0xD4000665U, 0x08C82025U, 0x08CC6044U,
364     0x008810A5U, 0xD4001665U, 0x08C82045U, 0x08CC6064U, 0x008810A5U, 0xD4002665U, 0x94003664U, 0x08C86084U, 0x08CC6084U,
365     0x08C82065U, 0x008810A5U, 0xD4003665U, 0x60803B00U, 0x94FFFA64U, 0x08CC4084U, 0x08C84084U, 0x08CC4005U, 0x008810A5U,
366     0xD4FFFA65U, 0x08C84005U, 0x08CC4024U, 0x008810A5U, 0xD4000A65U, 0x08C84025U, 0x08CC4044U, 0x008810A5U, 0xD4001A65U,
367     0x08C84045U, 0x08CC4064U, 0x008810A5U, 0xD4002A65U, 0x94003A64U, 0x08C84084U, 0x08CC4084U, 0x08C84065U, 0x008810A5U,
368     0xD4003A65U, 0x60803B00U, 0x94FFFE64U, 0x08CC6084U, 0x08C86084U, 0x08CC2005U, 0x008810A5U, 0xD4FFFE65U, 0x08C86005U,
369     0x08CC2024U, 0x008810A5U, 0xD4000E65U, 0x08C86025U, 0x08CC2044U, 0x008810A5U, 0xD4001E65U, 0x08C86045U, 0x08CC2064U,
370     0x008810A5U, 0xD4002E65U, 0x94003E64U, 0x08C82084U, 0x08CC2084U, 0x08C86065U, 0x008810A5U, 0xD4003E65U, 0x60803B00U,
371     0xD4000260U, 0xD4001261U, 0xD4002262U, 0xD4003263U, 0x04807FFFU, 0x63803B60U, 0x7080001FU, 0x5C1FFFE0U, 0x581FFFE0U,
372     0x54000020U, 0x08800E31U, 0x08C81A20U, 0x2000A012U, 0x101FFE12U, 0x80000252U, 0x3C000312U, 0x66803D00U, 0x63803CE0U,
373     0x08501A52U, 0x08501A52U, 0x08501A52U, 0x08C82236U, 0x2000C011U, 0x101FFE11U, 0x00405A31U, 0x0C800E04U, 0x63804520U,
374     0x3C000024U, 0x638042E0U, 0x3C000044U, 0x638040A0U, 0x94FFF605U, 0x08C860A0U, 0x94000605U, 0x08CC20A6U, 0x00881800U,
375     0x08C860A1U, 0x94001605U, 0x08CC20A6U, 0x00881821U, 0x08C860A2U, 0x94002605U, 0x08CC20A6U, 0x00881842U, 0x08C860A3U,
376     0x94003605U, 0x08CC20A6U, 0x00881863U, 0x608045A0U, 0x94FFFA05U, 0x08C840A0U, 0x94000A05U, 0x08CC40A6U, 0x00881800U,
377     0x08C840A1U, 0x94001A05U, 0x08CC40A6U, 0x00881821U, 0x08C840A2U, 0x94002A05U, 0x08CC40A6U, 0x00881842U, 0x08C840A3U,
378     0x94003A05U, 0x08CC40A6U, 0x00881863U, 0x608045A0U, 0x94FFFE05U, 0x08C820A0U, 0x94000E05U, 0x08CC60A6U, 0x00881800U,
379     0x08C820A1U, 0x94001E05U, 0x08CC60A6U, 0x00881821U, 0x08C820A2U, 0x94002E05U, 0x08CC60A6U, 0x00881842U, 0x08C820A3U,
380     0x94003E05U, 0x08CC60A6U, 0x00881863U, 0x608045A0U, 0x94000200U, 0x94001201U, 0x94002202U, 0x94003203U, 0x08C81259U,
381     0x00406631U, 0xA8003223U, 0xA8FFF222U, 0xA8FFF221U, 0xA8FFF220U, 0x08500A59U, 0x08CC0739U, 0x01940000U, 0x01840063U,
382     0x01840042U, 0x01840021U, 0x01840000U, 0x8AFFE23CU, 0x8AFFE23AU, 0x018C7463U, 0x018C7042U, 0x018C6C21U, 0x018C6800U,
383     0x01940000U, 0x01840063U, 0x01840042U, 0x01840021U, 0x01840000U, 0x8AFFE23CU, 0x8AFFE23AU, 0x018C7463U, 0x018C7042U,
384     0x018C6C21U, 0x018C6800U, 0x600046B9U, 0x01940000U, 0x01840063U, 0x01840042U, 0x01840021U, 0x01840000U, 0x8AFFE23CU,
385     0x8AFFE23AU, 0x018C7463U, 0x018C7042U, 0x018C6C21U, 0x018C6800U, 0x01940000U, 0x01840063U, 0x01840042U, 0x01840021U,
386     0x01840000U, 0xA8FFF223U, 0xA8FFF222U, 0xA8FFF221U, 0xA8FFF220U, 0x0C800E79U, 0x63805620U, 0x3C000039U, 0x63805300U,
387     0x3C000059U, 0x63804FE0U, 0x94FFF664U, 0x08CC2084U, 0x08C82084U, 0x08CC6005U, 0x008810A5U, 0xD4FFF665U, 0x08C82005U,
388     0x08CC6024U, 0x008810A5U, 0xD4000665U, 0x08C82025U, 0x08CC6044U, 0x008810A5U, 0xD4001665U, 0x08C82045U, 0x08CC6064U,
389     0x008810A5U, 0xD4002665U, 0x94003664U, 0x08C86084U, 0x08CC6084U, 0x08C82065U, 0x008810A5U, 0xD4003665U, 0x608056A0U,
390     0x94FFFA64U, 0x08CC4084U, 0x08C84084U, 0x08CC4005U, 0x008810A5U, 0xD4FFFA65U, 0x08C84005U, 0x08CC4024U, 0x008810A5U,
391     0xD4000A65U, 0x08C84025U, 0x08CC4044U, 0x008810A5U, 0xD4001A65U, 0x08C84045U, 0x08CC4064U, 0x008810A5U, 0xD4002A65U,
392     0x94003A64U, 0x08C84084U, 0x08CC4084U, 0x08C84065U, 0x008810A5U, 0xD4003A65U, 0x608056A0U, 0x94FFFE64U, 0x08CC6084U,
393     0x08C86084U, 0x08CC2005U, 0x008810A5U, 0xD4FFFE65U, 0x08C86005U, 0x08CC2024U, 0x008810A5U, 0xD4000E65U, 0x08C86025U,
394     0x08CC2044U, 0x008810A5U, 0xD4001E65U, 0x08C86045U, 0x08CC2064U, 0x008810A5U, 0xD4002E65U, 0x94003E64U, 0x08C82084U,
395     0x08CC2084U, 0x08C86065U, 0x008810A5U, 0xD4003E65U, 0x608056A0U, 0xD4003263U, 0xD4002262U, 0xD4001261U, 0xD4000260U,
396     0x04807FFFU, 0x63805700U, 0x7080001FU, 0x5C1FFFE0U, 0x581FFFE0U, 0x54000020U, 0x7080001FU, 0x08800E31U, 0x08C82236U,
397     0x2000C011U, 0x101FFE11U, 0x00405A31U, 0x94000200U, 0x94001201U, 0x94002202U, 0x94003203U, 0xAC001220U, 0xAC001221U,
398     0xAC001222U, 0xAC001223U, 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0x8E002224U, 0x8E002226U,
399     0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U, 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U,
400     0x8E002224U, 0x8E002226U, 0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U, 0x01800000U, 0x01800021U, 0x01800042U,
401     0x01800063U, 0x01900000U, 0x8E002224U, 0x8E002226U, 0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U, 0x01800000U,
402     0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0x8E002224U, 0x8E002226U, 0x01881000U, 0x01881421U, 0x01881842U,
403     0x01881C63U, 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0x8E002224U, 0x8E002226U, 0x01881000U,
404     0x01881421U, 0x01881842U, 0x01881C63U, 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0x8E002224U,
405     0x8E002226U, 0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U, 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U,
406     0x01900000U, 0x8E002224U, 0x8E002226U, 0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U, 0x01800000U, 0x01800021U,
407     0x01800042U, 0x01800063U, 0x01900000U, 0x8E002224U, 0x8E002226U, 0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U,
408     0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0x8E002224U, 0x8E002226U, 0x01881000U, 0x01881421U,
409     0x01881842U, 0x01881C63U, 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0xAC001220U, 0xAC001221U,
410     0xAC001222U, 0xAC001223U, 0xD4000260U, 0xD4001261U, 0xD4002262U, 0xD4003263U, 0x04807FFFU, 0x29FFEA11U, 0x638067A0U,
411     0x7080001FU, 0x5C1FFFE0U, 0x581FFFE0U, 0x54000020U, 0xC8FF03DEU, 0xC40013DFU, 0x2000A114U, 0x101FFE14U, 0x08C81A31U,
412     0x00405231U, 0x84000231U, 0x04804631U, 0x63006940U, 0x54000040U, 0x5C0001E0U, 0x700058BFU, 0x08CC7C04U, 0x04800000U,
413     0x04980063U, 0x04980042U, 0x04980021U, 0x04980000U, 0x60006A84U, 0x088E1C63U, 0xC40043C0U, 0xC40053C1U, 0xC40063C2U,
414     0xC40073C3U, 0x08CC7C04U, 0x04800000U, 0x04980063U, 0x04980042U, 0x04980021U, 0x04980000U, 0x60006C04U, 0x088E1C63U,
415     0xC40083C0U, 0xC40093C1U, 0xC400A3C2U, 0xC400B3C3U, 0x0C800E09U, 0x63806D20U, 0x08C80D2AU, 0x088C7D4BU, 0x2800002BU,
416     0x08403E4DU, 0x0CCC11ADU, 0x63006DE0U, 0x2000002DU, 0x2000000EU, 0x60806E80U, 0x0C803E4FU, 0x63806E60U, 0x2000000EU,
417     0x60806E80U, 0x2000002EU, 0x085005ADU, 0x08C811ACU, 0x0040418CU, 0x600072CEU, 0x0C800E09U, 0x638071A0U, 0x0050258CU,
418     0x9C001189U, 0x00C82920U, 0x9C001189U, 0x00CC2D39U, 0x00886400U, 0x00C82921U, 0x9C001189U, 0x00CC2D39U, 0x00886421U,
419     0x00C82922U, 0x9C001189U, 0x00CC2D39U, 0x00886442U, 0x00C82923U, 0x9C001189U, 0x00CC2D39U, 0x00886463U, 0x60807220U,
420     0x94000180U, 0x94001181U, 0x94002182U, 0x94003183U, 0xA40043C0U, 0xA40053C1U, 0xA40063C2U, 0xA40073C3U, 0x60808340U,
421     0x5C003E00U, 0x04803DEFU, 0x638077C0U, 0x0C800E09U, 0x63807680U, 0x0050258CU, 0x9C001189U, 0x00C82924U, 0x9C001189U,
422     0x00CC2D39U, 0x00886484U, 0x0C5015F8U, 0x658077C0U, 0x00C82925U, 0x9C001189U, 0x00CC2D39U, 0x008864A5U, 0x0C501318U,
423     0x658077C0U, 0x00C82926U, 0x9C001189U, 0x00CC2D39U, 0x008864C6U, 0x0C501318U, 0x658077C0U, 0x00C82927U, 0x9C001189U,
424     0x00CC2D39U, 0x008864E7U, 0x608077C0U, 0x94000184U, 0x0C5015E9U, 0x658077C0U, 0x94001185U, 0x0C501129U, 0x658077C0U,
425     0x94002186U, 0x0C501129U, 0x658077C0U, 0x94003187U, 0x2001E194U, 0x10000014U, 0x08C809EFU, 0x00403E9FU, 0x7080001FU,
426     0x60807A60U, 0x60807AC0U, 0x60807B60U, 0x60807C00U, 0x60807C80U, 0x60807CE0U, 0x60807D80U, 0x60807E20U, 0x60807EA0U,
427     0x60807F00U, 0x60807FA0U, 0x60808040U, 0x608080C0U, 0x60808120U, 0x608081C0U, 0x60808260U, 0x10100008U, 0x00882084U,
428     0x608082C0U, 0x101FE008U, 0x00802084U, 0x10001008U, 0x00882084U, 0x608082C0U, 0x101FFFE8U, 0x00802084U, 0x30100008U,
429     0x00882084U, 0x608082C0U, 0x31FFE008U, 0x00802084U, 0x088A0084U, 0x608082C0U, 0x10100008U, 0x008820A5U, 0x608082C0U,
430     0x101FE008U, 0x008020A5U, 0x10001008U, 0x008820A5U, 0x608082C0U, 0x101FFFE8U, 0x008020A5U, 0x30100008U, 0x008820A5U,
431     0x608082C0U, 0x31FFE008U, 0x008020A5U, 0x088A00A5U, 0x608082C0U, 0x10100008U, 0x008820C6U, 0x608082C0U, 0x101FE008U,
432     0x008020C6U, 0x10001008U, 0x008820C6U, 0x608082C0U, 0x101FFFE8U, 0x008020C6U, 0x30100008U, 0x008820C6U, 0x608082C0U,
433     0x31FFE008U, 0x008020C6U, 0x088A00C6U, 0x608082C0U, 0x10100008U, 0x008820E7U, 0x608082C0U, 0x101FE008U, 0x008020E7U,
434     0x10001008U, 0x008820E7U, 0x608082C0U, 0x101FFFE8U, 0x008020E7U, 0x30100008U, 0x008820E7U, 0x608082C0U, 0x31FFE008U,
435     0x008020E7U, 0x088A00E7U, 0x008C1000U, 0x008C1421U, 0x008C1842U, 0x008C1C63U, 0xC400C3C0U, 0xC400D3C1U, 0xC400E3C2U,
436     0xC400F3C3U, 0x5C0001E0U, 0x048035ADU, 0x63808880U, 0x0C800E09U, 0x638087A0U, 0x00502617U, 0x9C0012E9U, 0x00C82938U,
437     0x9C0012E9U, 0x00CC2D39U, 0x00886718U, 0x008C6000U, 0x00C82938U, 0x9C0012E9U, 0x00CC2D39U, 0x00886718U, 0x008C6021U,
438     0x00C82938U, 0x9C0012E9U, 0x00CC2D39U, 0x00886718U, 0x008C6042U, 0x00C82938U, 0x9C0012E9U, 0x00CC2D39U, 0x00886718U,
439     0x008C6063U, 0x700058BFU, 0x28000210U, 0x600084ADU, 0x60808880U, 0xB4000200U, 0xB4001201U, 0xB4002202U, 0xB4003203U,
440     0x700058BFU, 0x28000210U, 0x600087ADU, 0xA400C3C0U, 0xA400D3C1U, 0xA400E3C2U, 0xA400F3C3U, 0x700058BFU, 0xD4000260U,
441     0xD4001261U, 0xD4002262U, 0xD4003263U, 0x840013DFU, 0x840003DEU, 0x04807FFFU, 0x63808A40U, 0x7080001FU, 0x5C1FFFE0U,
442     0x581FFFE0U, 0x54000020U, 0x20015000U, 0x101FFE00U, 0x84000001U, 0x84001002U, 0x84002003U, 0x84003004U, 0x84004005U,
443     0x84005006U, 0x84006007U, 0x84007008U, 0xD40003A1U, 0xD40013A2U, 0xD40023A3U, 0xD40033A4U, 0xD40043A5U, 0xD40053A6U,
444     0xD40063A7U, 0xD40073A8U, 0x54000020U, 0xC8FF93DEU, 0xC40013DFU, 0x940003A1U, 0x940013A2U, 0x940023A3U, 0x940033A4U,
445     0x940043A5U, 0x940053A6U, 0x940063A7U, 0x940073A8U, 0xC40043DBU, 0x0C800F7AU, 0x63808F80U, 0x00506B7BU, 0x2800009BU,
446     0x08C80F5AU, 0xC40053DAU, 0x088C7F5AU, 0x2800003AU, 0xC40063DAU, 0x2001541AU, 0x101FFE1AU, 0xC40033DDU, 0xC40023DCU,
447     0x840043DFU, 0x0C800FFFU, 0x6380A8A0U, 0x94FFF37FU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU,
448     0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U,
449     0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U,
450     0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U,
451     0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU,
452     0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U,
453     0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U,
454     0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U,
455     0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU,
456     0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U,
457     0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U,
458     0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U,
459     0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU,
460     0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U,
461     0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U,
462     0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U,
463     0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU,
464     0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U,
465     0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U,
466     0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U,
467     0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU,
468     0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x6080B6A0U, 0x9C001369U,
469     0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U,
470     0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U,
471     0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU,
472     0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U,
473     0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U,
474     0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U,
475     0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U,
476     0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U,
477     0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U,
478     0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU,
479     0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U,
480     0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U,
481     0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x2000019FU, 0x00406609U, 0x01E06169U, 0x8C001340U, 0x01E80120U, 0x01E41500U,
482     0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x00406609U, 0x01E06169U, 0x8C001340U, 0x01E80120U, 0x01E41500U, 0x00400084U,
483     0x01EC0020U, 0x41FFFEFFU, 0x00406609U, 0x01E06169U, 0x8C001340U, 0x01E80120U, 0x01E41500U, 0x00400084U, 0x01EC0020U,
484     0x41FFFEFFU, 0x00406609U, 0x01E06169U, 0x8C001340U, 0x01E80120U, 0x01E41500U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU,
485     0x6000B6DFU, 0x840033DDU, 0x940003A0U, 0x00400021U, 0x940013A0U, 0x00400042U, 0x940023A0U, 0x00400063U, 0x940033A0U,
486     0x00400084U, 0x940043A0U, 0x004000A5U, 0x940053A0U, 0x004000C6U, 0x940063A0U, 0x004000E7U, 0x940073A0U, 0x00400108U,
487     0xD40003A1U, 0xD40013A2U, 0xD40023A3U, 0xD40033A4U, 0xD40043A5U, 0xD40053A6U, 0xD40063A7U, 0xD40073A8U, 0x29FFE01AU,
488     0x840023DCU, 0x60008FDCU, 0x840013DFU, 0x840003DEU, 0x04807FFFU, 0x6380BF00U, 0x7080001FU, 0x581FFFE0U, 0x5C1FFFE0U,
489     0x54000020U, 0x20014800U, 0x101FFE00U, 0x84000001U, 0x84001002U, 0x84002003U, 0x84003004U, 0x84004005U, 0xD40003A1U,
490     0xD40013A2U, 0xD40023A3U, 0xD40033A4U, 0xD40043A5U, 0x54000020U, 0xC8FF43DEU, 0xC40013DFU, 0xC40033DDU, 0x940003A1U,
491     0x940013A2U, 0x940023A3U, 0x940033A4U, 0x940043A5U, 0xC40043C1U, 0xC40053C2U, 0xC40063C3U, 0xC40073C4U, 0xC40083C5U,
492     0xC40093DBU, 0x0C800F7DU, 0x6380C3E0U, 0x0050777BU, 0x08C80FBFU, 0xC400A3DFU, 0x088C7FE7U, 0x28000027U, 0xC400B3C7U,
493     0x9C00137DU, 0xC40023DCU, 0x20014608U, 0x101FFE08U, 0x00800420U, 0x08D01400U, 0x84000108U, 0x840093DCU, 0x0C800F9CU,
494     0x6380DD60U, 0x8400A3DFU, 0x8400B3C7U, 0x01D41400U, 0x00402000U, 0x00C87FA9U, 0x9C00137DU, 0x00CC1FBCU, 0x00887129U,
495     0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U, 0x00C87FA9U,
496     0x9C00137DU, 0x00CC1FBCU, 0x00887129U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U,
497     0x01D41400U, 0x00402000U, 0x00C87FA9U, 0x9C00137DU, 0x00CC1FBCU, 0x00887129U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU,
498     0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U, 0x00C87FA9U, 0x9C00137DU, 0x00CC1FBCU, 0x00887129U,
499     0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U, 0x00C87FA9U,
500     0x9C00137DU, 0x00CC1FBCU, 0x00887129U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U,
501     0x01D41400U, 0x00402000U, 0x00C87FA9U, 0x9C00137DU, 0x00CC1FBCU, 0x00887129U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU,
502     0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U, 0x00C87FA9U, 0x9C00137DU, 0x00CC1FBCU, 0x00887129U,
503     0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U, 0x00C87FA9U,
504     0x9C00137DU, 0x00CC1FBCU, 0x00887129U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U,
505     0x01D41400U, 0x00402000U, 0x00C87FA9U, 0x9C00137DU, 0x00CC1FBCU, 0x00887129U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU,
506     0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U, 0x00C87FA9U, 0x9C00137DU, 0x00CC1FBCU, 0x00887129U,
507     0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U, 0x00C87FA9U,
508     0x9C00137DU, 0x00CC1FBCU, 0x00887129U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U,
509     0x01D41400U, 0x00402000U, 0x00C87FA9U, 0x9C00137DU, 0x00CC1FBCU, 0x00887129U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU,
510     0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U, 0x00C87FA9U, 0x9C00137DU, 0x00CC1FBCU, 0x00887129U,
511     0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U, 0x00C87FA9U,
512     0x9C00137DU, 0x00CC1FBCU, 0x00887129U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U,
513     0x01D41400U, 0x00402000U, 0x00C87FA9U, 0x9C00137DU, 0x00CC1FBCU, 0x00887129U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU,
514     0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U, 0x00C87FA9U, 0x9C00137DU, 0x00CC1FBCU, 0x00887129U,
515     0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x6080EF60U, 0x01D41400U, 0x00402000U,
516     0x9C001369U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U,
517     0x9C001369U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U,
518     0x9C001369U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U,
519     0x9C001369U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U,
520     0x9C001369U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U,
521     0x9C001369U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U,
522     0x9C001369U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U,
523     0x9C001369U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U,
524     0x9C001369U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U,
525     0x9C001369U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U,
526     0x9C001369U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U,
527     0x9C001369U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U,
528     0x9C001369U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U,
529     0x9C001369U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U,
530     0x9C001369U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x01D41400U, 0x00402000U,
531     0x9C001369U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x2000009FU, 0x01D41400U,
532     0x00402000U, 0x00803189U, 0x008C4529U, 0x008C5D29U, 0x008C6529U, 0x08D00529U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU,
533     0x4000001BU, 0x00806B43U, 0x08D01400U, 0x6000EF9FU, 0x2000029FU, 0x20014687U, 0x101FFE07U, 0x8C0010E8U, 0x01D01400U,
534     0x00402000U, 0x00803189U, 0x008C4529U, 0x008C5D29U, 0x008C6529U, 0x08D00529U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU,
535     0x4000001BU, 0x00806B43U, 0x08D01400U, 0x6000F1DFU, 0x2000029FU, 0x8C0010E8U, 0x01D81400U, 0x00402000U, 0x00803189U,
536     0x008C4529U, 0x008C5D29U, 0x008C6529U, 0x08D00529U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U,
537     0x08D01400U, 0x6000F3DFU, 0x2000029FU, 0x840000E8U, 0x01D01400U, 0x00402000U, 0x00803189U, 0x008C4529U, 0x008C5D29U,
538     0x008C6529U, 0x08D00529U, 0x00402400U, 0x41FFFE00U, 0x08D0785AU, 0x4000001BU, 0x00806B43U, 0x08D01400U, 0x6000F5DFU,
539     0x840043C0U, 0x00400021U, 0xC40043C1U, 0x840053C0U, 0x00400042U, 0xC40053C2U, 0x840063C0U, 0x00400063U, 0xC40063C3U,
540     0x840073C0U, 0x00400084U, 0xC40073C4U, 0x840083C0U, 0x004000A5U, 0xC40083C5U, 0x840023DCU, 0x6000C3FCU, 0x840033DDU,
541     0xDC0013A1U, 0xDC0013A2U, 0xDC0013A3U, 0xDC0013A4U, 0xDC0013A5U, 0x840013DFU, 0x840003DEU, 0x04807FFFU, 0x6380FB00U,
542     0x7080001FU, 0x5C1FFFE0U, 0x581FFFE0U, 0x54000020U, 0x08800E31U, 0x08C81A20U, 0x2000A412U, 0x101FFE12U, 0x00400251U,
543     0x84000220U, 0x84001221U, 0x01A42012U, 0x04804A52U, 0x6300FE00U, 0x84002220U, 0x84003221U, 0x01A42012U, 0x04804A52U,
544     0x6300FE00U, 0x84004220U, 0x84005221U, 0x01A42012U, 0x04804A52U, 0x6300FE00U, 0x54000020U, 0x54000040U, 0x08800E31U,
545     0x08C81A20U, 0x2000A412U, 0x101FFE12U, 0x00400251U, 0x84000220U, 0x84001221U, 0x0C800E07U, 0x63810380U, 0x3C000027U,
546     0x63810240U, 0x3C000047U, 0x63810100U, 0x94FFF607U, 0x08C860E2U, 0x94000607U, 0x08CC20E8U, 0x00882042U, 0x08C860E3U,
547     0x94001607U, 0x08CC20E8U, 0x00882063U, 0x608103C0U, 0x94FFFA07U, 0x08C840E2U, 0x94000A07U, 0x08CC40E8U, 0x00882042U,
548     0x08C840E3U, 0x94001A07U, 0x08CC40E8U, 0x00882063U, 0x608103C0U, 0x94FFFE07U, 0x08C820E2U, 0x94000E07U, 0x08CC60E8U,
549     0x00882042U, 0x08C820E3U, 0x94001E07U, 0x08CC60E8U, 0x00882063U, 0x608103C0U, 0x9C001202U, 0x94000203U, 0x01A40000U,
550     0x01A02000U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00000U, 0x01A00400U,
551     0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00000U, 0x01A01000U, 0x84002220U, 0x84003221U,
552     0x01A41000U, 0x01A02800U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00800U,
553     0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00800U, 0x01A01000U, 0x84004220U,
554     0x84005221U, 0x01A40000U, 0x01A02000U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00400U,
555     0x01A00000U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00000U, 0x01A01000U,
556     0x0C800E67U, 0x638111C0U, 0x3C000027U, 0x63810FA0U, 0x3C000047U, 0x63810D80U, 0x94FFF668U, 0x08CC2108U, 0x08C82108U,
557     0x08CC6047U, 0x008820E7U, 0xD4FFF667U, 0x08C82047U, 0x08CC6062U, 0x00881C42U, 0xD4000662U, 0x94001668U, 0x08C86108U,
558     0x08CC6108U, 0x08C82067U, 0x008820E7U, 0xD4001667U, 0x60811200U, 0x94FFFA68U, 0x08CC4108U, 0x08C84108U, 0x08CC4047U,
559     0x008820E7U, 0xD4FFFA67U, 0x08C84047U, 0x08CC4062U, 0x00881C42U, 0xD4000A62U, 0x94001A68U, 0x08C84108U, 0x08CC4108U,
560     0x08C84067U, 0x008820E7U, 0xD4001A67U, 0x60811200U, 0x94FFFE68U, 0x08CC6108U, 0x08C86108U, 0x08CC2047U, 0x008820E7U,
561     0xD4FFFE67U, 0x08C86047U, 0x08CC2062U, 0x00881C42U, 0xD4000E62U, 0x94001E68U, 0x08C82108U, 0x08CC2108U, 0x08C86067U,
562     0x008820E7U, 0xD4001E67U, 0x60811200U, 0xDC001262U, 0xD4000263U, 0x04807FFFU, 0x63811260U, 0x7080001FU, 0x5C1FFFE0U,
563     0x581FFFE0U, 0x54000020U, 0x08800E31U, 0x08C81A20U, 0x2000A412U, 0x101FFE12U, 0x00400251U, 0x84004220U, 0x84005221U,
564     0x0C800E07U, 0x63811820U, 0x3C000027U, 0x638116E0U, 0x3C000047U, 0x638115A0U, 0x94FFF607U, 0x08C860E2U, 0x94000607U,
565     0x08CC20E8U, 0x00882042U, 0x08C860E3U, 0x94001607U, 0x08CC20E8U, 0x00882063U, 0x60811860U, 0x94FFFA07U, 0x08C840E2U,
566     0x94000A07U, 0x08CC40E8U, 0x00882042U, 0x08C840E3U, 0x94001A07U, 0x08CC40E8U, 0x00882063U, 0x60811860U, 0x94FFFE07U,
567     0x08C820E2U, 0x94000E07U, 0x08CC60E8U, 0x00882042U, 0x08C820E3U, 0x94001E07U, 0x08CC60E8U, 0x00882063U, 0x60811860U,
568     0x9C001202U, 0x94000203U, 0x01A41000U, 0x01A02800U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U,
569     0x01A00C00U, 0x01A00800U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00800U,
570     0x01A01000U, 0x84002220U, 0x84003221U, 0x01A40000U, 0x01A02000U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00400U,
571     0x01A00400U, 0x01A00400U, 0x01A00000U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00400U, 0x01A00400U,
572     0x01A00000U, 0x01A01000U, 0x84000220U, 0x84001221U, 0x01A41000U, 0x01A02800U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U,
573     0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00800U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U, 0x01A00C00U,
574     0x01A00C00U, 0x01A00800U, 0x01A01000U, 0x0C800E67U, 0x63812660U, 0x3C000027U, 0x63812440U, 0x3C000047U, 0x63812220U,
575     0x94FFF668U, 0x08CC2108U, 0x08C82108U, 0x08CC6047U, 0x008820E7U, 0xD4FFF667U, 0x08C82047U, 0x08CC6062U, 0x00881C42U,
576     0xD4000662U, 0x94001668U, 0x08C86108U, 0x08CC6108U, 0x08C82067U, 0x008820E7U, 0xD4001667U, 0x608126A0U, 0x94FFFA68U,
577     0x08CC4108U, 0x08C84108U, 0x08CC4047U, 0x008820E7U, 0xD4FFFA67U, 0x08C84047U, 0x08CC4062U, 0x00881C42U, 0xD4000A62U,
578     0x94001A68U, 0x08C84108U, 0x08CC4108U, 0x08C84067U, 0x008820E7U, 0xD4001A67U, 0x608126A0U, 0x94FFFE68U, 0x08CC6108U,
579     0x08C86108U, 0x08CC2047U, 0x008820E7U, 0xD4FFFE67U, 0x08C86047U, 0x08CC2062U, 0x00881C42U, 0xD4000E62U, 0x94001E68U,
580     0x08C82108U, 0x08CC2108U, 0x08C86067U, 0x008820E7U, 0xD4001E67U, 0x608126A0U, 0xDC001262U, 0xD4000263U, 0x04807FFFU,
581     0x63812700U, 0x7080001FU, 0x5C1FFFE0U, 0x581FFFE0U, 0x54000020U, 0xC8FFE3DEU, 0x08CC1234U, 0x8C001200U, 0x8C001201U,
582     0x8C001202U, 0x8C001203U, 0xCE002240U, 0xCE002242U, 0x600127B4U, 0x840003DEU, 0x54000020U, 0xC8FFE3DEU, 0x5C001FE0U,
583     0x08800E31U, 0x0CC81A31U, 0x2000A012U, 0x101FFE12U, 0x00404652U, 0x8C004200U, 0x9C001204U, 0x9C001205U, 0x9C001206U,
584     0x9C001207U, 0xCE002240U, 0xCE002242U, 0xCE002244U, 0xCE002246U, 0x9C001200U, 0x9C001201U, 0x9C001202U, 0x9C001203U,
585     0x9C001204U, 0x9C001205U, 0x9C001206U, 0x9C001207U, 0xCE002240U, 0xCE002242U, 0xCE002244U, 0xCE002246U, 0x08510252U,
586     0x84000240U, 0x0880E000U, 0x3C000400U, 0x67812D00U, 0x20000400U, 0xC4000240U, 0x3C000100U, 0x08408254U, 0x00800012U,
587     0x08CC1A31U, 0x67812EA0U, 0x3C000300U, 0x66812E60U, 0x63812E40U, 0x08501A52U, 0x08501A52U, 0x08501A52U, 0x7000041FU,
588     0x5C1FFFE0U, 0x5801FFE0U, 0x54000020U, 0xC8FFE3DEU, 0x5C001FE0U, 0x08800E31U, 0x0CC81A31U, 0x2000A012U, 0x101FFE12U,
589     0x00404652U, 0x00804200U, 0xCE002240U, 0xCE002242U, 0x20D4D4C4U, 0x1014D4C4U, 0x20D4D4C5U, 0x1014D4C5U, 0xCE002244U,
590     0xCE002246U, 0x24000100U, 0x24000121U, 0x24000142U, 0x24000163U, 0x24000184U, 0x240001A5U, 0x240001C6U, 0x240001E7U,
591     0x00040000U, 0x00040021U, 0x00040042U, 0x00040063U, 0x00040084U, 0x000400A5U, 0x000400C6U, 0x000400E7U, 0xCE002240U,
592     0xCE002242U, 0xCE002244U, 0xCE002246U, 0x08510252U, 0x84000240U, 0x0880E000U, 0x3C000400U, 0x67813440U, 0x20000400U,
593     0xC4000240U, 0x3C000100U, 0x08408254U, 0x00800012U, 0x08CC1A31U, 0x678135E0U, 0x3C000300U, 0x668135A0U, 0x63813580U,
594     0x08501A52U, 0x08501A52U, 0x08501A52U, 0x7000041FU, 0x5C1FFFE0U, 0x5801FFE0U, 0x54000020U, 0x08800E31U, 0x08C81A31U,
595     0x2000A012U, 0x101FFE12U, 0x00404652U, 0x5C1FFFE0U, 0xCE002240U, 0xCE002242U, 0xCE002244U, 0xCE002246U, 0xCE002240U,
596     0xCE002242U, 0xCE002244U, 0xCE002246U, 0x5C1FFFE0U, 0x5801FFE0U, 0x04807FFFU, 0x638138A0U, 0x7080001FU, 0x54000020U,
597     0x0CCC7E48U, 0x63813940U, 0x088C7E52U, 0x28000032U, 0x08800E52U, 0x08C81A52U, 0x2000A013U, 0x101FFE13U, 0x00404A73U,
598     0xC4000271U, 0x28000413U, 0x0C800E21U, 0x08CC0A31U, 0x63813AA0U, 0x28000031U, 0x3C000008U, 0x63813B60U, 0x8C001201U,
599     0xCC001261U, 0x60013AF1U, 0x60813BC0U, 0x8C001201U, 0xDC001261U, 0x60013B71U, 0x5C1FFFE0U, 0x581FFFE0U, 0x54000020U,
600     0x0CCC7E28U, 0x63813CA0U, 0x088C7E31U, 0x28000031U, 0x08800E31U, 0x08C81A31U, 0x2000A212U, 0x101FFE12U, 0x00404652U,
601     0x8C001204U, 0x8C001205U, 0x8C001206U, 0x8C001207U, 0x3C000008U, 0x63813E60U, 0xCE002244U, 0xCE002246U, 0x60813EE0U,
602     0xDC001244U, 0xDC001245U, 0xDC001246U, 0xDC001247U, 0x5C1FFFE0U, 0x5801FFE0U, 0x54000020U, 0xC8FFE3DEU, 0x08800E31U,
603     0x08C81A20U, 0x2000A014U, 0x101FFE14U, 0x00400294U, 0x84000292U, 0x3C000312U, 0x668140C0U, 0x638140A0U, 0x08501A52U,
604     0x08501A52U, 0x08501A52U, 0x28000414U, 0x60800400U, 0x0C8013C6U, 0x638141C0U, 0xC8FEB3DEU, 0xC40013DFU, 0x60814200U,
605     0xC8FEC3DEU, 0xC40013DFU, 0x00804A55U, 0x00804636U, 0x00804E77U, 0x084006F4U, 0x3C000094U, 0x630142E0U, 0x20000034U,
606     0x3C000055U, 0x63814400U, 0x3C000095U, 0x63814400U, 0x3C000115U, 0x63814400U, 0x3C000095U, 0x67014B00U, 0x60814A80U,
607     0x08800EC6U, 0x08C818C6U, 0x2000A00CU, 0x101FFE0CU, 0x0040198CU, 0x8C004198U, 0x08800E31U, 0x08C82226U, 0x2000C011U,
608     0x101FFE11U, 0x00401A31U, 0x3C000318U, 0x66814600U, 0x63814A40U, 0x200001D2U, 0x60814620U, 0x20000152U, 0x2001D613U,
609     0x101FFE13U, 0x9C001200U, 0x9C001201U, 0x20000106U, 0x004078C6U, 0x008056AAU, 0x9C00120EU, 0x9C00120FU, 0xCE0020CEU,
610     0x6001470AU, 0x200000C9U, 0x008056AAU, 0x08500527U, 0x01001EA7U, 0x004028E6U, 0x008C1821U, 0x08C80D48U, 0x800023C2U,
611     0x08401108U, 0x800023C3U, 0x700045BFU, 0x08501108U, 0xC00023C2U, 0x08401108U, 0xC00023C3U, 0x6001480AU, 0x600147A9U,
612     0x8600018EU, 0x008C01CBU, 0x008C05E6U, 0x0488196BU, 0x63814BE0U, 0x3C000115U, 0x63814B00U, 0x00805EF1U, 0x7001365FU,
613     0x581FFFE0U, 0x54000040U, 0x00805EF1U, 0x0080529DU, 0x7001365FU, 0x008077B1U, 0x7001365FU, 0x581FFFE0U, 0x54000040U,
614     0x00805EE7U, 0x08800EF7U, 0x08C81AE6U, 0x2000A017U, 0x101FFE17U, 0x00401AF7U, 0x3C000055U, 0x63814D60U, 0x3C000095U,
615     0x63814D60U, 0x20000407U, 0x60814D80U, 0x08C80EA7U, 0xCC0082E7U, 0x20000106U, 0x004078C6U, 0x008056AAU, 0x3C000115U,
616     0x63814EC0U, 0x8E0020C0U, 0xCE0022E0U, 0x60014E4AU, 0x608150A0U, 0x0850114AU, 0x8E0020C0U, 0xCE0022E0U, 0x60014EEAU,
617     0x08800E94U, 0x08C81A87U, 0x2000A014U, 0x101FFE14U, 0x00401E94U, 0x2000008AU, 0x20000407U, 0xCC008287U, 0x8E0020C0U,
618     0xCE002280U, 0x6001504AU, 0x54000020U, 0xC4FFF3DFU, 0xC8FFE3DEU, 0x2001D600U, 0x101FFE00U, 0x700162BFU, 0x3C000017U,
619     0x63815600U, 0x0C800EFDU, 0x63015280U, 0xC40002E2U, 0xC40012E3U, 0xC40022E4U, 0xC40032E5U, 0x60815600U, 0x005076F7U,
620     0x08C80FBDU, 0x088C7FBCU, 0x2800003CU, 0x840002FAU, 0x00C8735FU, 0x00CC73FFU, 0x00C8745AU, 0x00887F5AU, 0xC40002FAU,
621     0x00CC705FU, 0x00C8747AU, 0x00887F5AU, 0xC40012FAU, 0x00CC707FU, 0x00C8749AU, 0x00887F5AU, 0xC40022FAU, 0x00CC709FU,
622     0x00C874BAU, 0x00887F5AU, 0xC40032FAU, 0x00CC70BFU, 0x840042FAU, 0x00CC775AU, 0x00C8775AU, 0x00887F5AU, 0xC40042FAU,
623     0x840013DFU, 0x04807FFFU, 0x638156A0U, 0x840003DEU, 0x7080001FU, 0x5C1FFFE0U, 0x581FFFE0U, 0x54000020U, 0xC4FFF3D5U,
624     0xC4FFE3D6U, 0xC4FFD3DFU, 0xC8FFC3DEU, 0x2001DE00U, 0x101FFE00U, 0x700162BFU, 0x84FFD3DFU, 0x20000033U, 0x3C000017U,
625     0x638161A0U, 0x0C800EFDU, 0x63015940U, 0x840002E6U, 0x840012E7U, 0x840022E8U, 0x840032E9U, 0x60815BE0U, 0x005076F7U,
626     0x08C80FBDU, 0x088C7FBCU, 0x2800003CU, 0x840002FAU, 0x00CC775FU, 0x840012FAU, 0x00C87346U, 0x00887CC6U, 0x00CC775FU,
627     0x840022FAU, 0x00C87347U, 0x00887CE7U, 0x00CC775FU, 0x840032FAU, 0x00C87348U, 0x00887D08U, 0x00CC775FU, 0x840042FAU,
628     0x00C87349U, 0x00887D29U, 0x008C1857U, 0x008C1C7AU, 0x00886AF7U, 0x008C209AU, 0x00886AF7U, 0x008C24BAU, 0x04886AF7U,
629     0x638161A0U, 0x20000053U, 0x840033D5U, 0x3C000015U, 0x638161A0U, 0x840023D6U, 0x0C800EDAU, 0x63816020U, 0x00506AD6U,
630     0x00406AB5U, 0x0C5012B5U, 0x2000001CU, 0x66015F20U, 0x840002DCU, 0x28000095U, 0x08C80EB5U, 0x00CC579CU, 0x00C8579CU,
631     0x20000015U, 0x08C80F5AU, 0x088C7F5AU, 0x2800003AU, 0x840002DBU, 0x00C86B7BU, 0x00CC6B7BU, 0x0088737BU, 0xCC0012DBU,
632     0x0CCC0ABBU, 0x638160C0U, 0x2000001AU, 0xCC0012DAU, 0x6001609BU, 0x0C800EBAU, 0x638161A0U, 0x08C80F5AU, 0x840002DBU,
633     0x00CC6B7BU, 0x00C86B7BU, 0xCC0012DBU, 0x840013DFU, 0x04807FFFU, 0x63816240U, 0x840003DEU, 0x7080001FU, 0x5C1FFFE0U,
634     0x581FFEE0U, 0x50000013U, 0x0C8013DAU, 0x63816320U, 0xCAFD13DEU, 0x60816340U, 0xCAFD23DEU, 0xC402D3C0U, 0xC402A3D3U,
635     0xC402B3D5U, 0x3C000011U, 0x0080463AU, 0x660165C0U, 0x20000015U, 0x20000011U, 0x088C0F5AU, 0x2800003AU, 0x08800F5AU,
636     0x08C81B5AU, 0x2000A41BU, 0x101FFE1BU, 0x00406B7AU, 0x8E002340U, 0x8E002342U, 0x8E002344U, 0x8E002346U, 0x60816840U,
637     0x08800F5AU, 0x08C81B5AU, 0x2000A011U, 0x101FFE11U, 0x00406A31U, 0x0C800E9CU, 0x00507294U, 0x08C80F9CU, 0x63816740U,
638     0x8C001290U, 0x00CC7210U, 0xC40263D0U, 0x08800EDDU, 0x005076D6U, 0x08C80FBDU, 0xC60243DCU, 0x20000019U, 0x3C000017U,
639     0x63817A80U, 0x7001B07FU, 0xC60023C0U, 0xC60043C2U, 0xC60063C4U, 0xC60083C6U, 0x08C81808U, 0x08CC1908U, 0x08CC6009U,
640     0x08C8203AU, 0x00886929U, 0x08CC0929U, 0x21FFE07AU, 0x10007FFAU, 0x00806929U, 0x08CC402AU, 0x08C8405AU, 0x0088694AU,
641     0x08CC114AU, 0x21F81FFAU, 0x10007FFAU, 0x0080694AU, 0x08CC204BU, 0x08C8607AU, 0x0088696BU, 0x08CC196BU, 0x2007FFFAU,
642     0x10007E1AU, 0x0080696BU, 0x08CC206CU, 0x08C8318CU, 0x08CC318CU, 0xC60103C8U, 0xC60123CAU, 0xC40143CCU, 0x860103C6U,
643     0x860123C8U, 0x840143CBU, 0x08C808ECU, 0x00401D8CU, 0x08C8090DU, 0x004021ADU, 0x08C8092EU, 0x004025CEU, 0x08C8096FU,
644     0x00402DEFU, 0xC60203CCU, 0xC60223CEU, 0x2000001AU, 0x2000001BU, 0xC600A3DAU, 0xC600C3DAU, 0xC400E3DAU, 0x3C000013U,
645     0x63817A80U, 0x00804A5CU, 0x0C800E5AU, 0x63017220U, 0x8402D3C8U, 0x08CC0A7BU, 0x0C800E7DU, 0x63816FE0U, 0x2800003BU,
646     0x3C000813U, 0x67817060U, 0x2000081BU, 0x08CC0B7BU, 0x8C001240U, 0xCC001100U, 0x6001707BU, 0x3C000813U, 0x67817800U,
647     0xC40153D3U, 0x20000813U, 0xC402C3D2U, 0x7001C1DFU, 0x840153D3U, 0x8402C3D2U, 0x2000081DU, 0x00507673U, 0x60816F40U,
648     0x20000038U, 0x08800E4AU, 0x08C80D4AU, 0x088C7D49U, 0x28000029U, 0x08800E7CU, 0x00406B9CU, 0x3C00009CU, 0x67817360U,
649     0x28000038U, 0x8402D3C8U, 0x00506A5AU, 0x08CC0A7BU, 0x0C800E7DU, 0x63817420U, 0x2800003BU, 0x3C000813U, 0x678174A0U,
650     0x2000081BU, 0x08CC0B7BU, 0x00806F7DU, 0x0040637BU, 0x8C001340U, 0x00CC2801U, 0x0850077BU, 0x00506FBDU, 0x8C001340U,
651     0x00C82402U, 0x00880442U, 0x00CC2801U, 0xCC001102U, 0x6001757BU, 0x3C00001DU, 0x63817680U, 0xCC001101U, 0x3C000813U,
652     0x67817800U, 0xC40153D3U, 0x20000813U, 0xC402C3D2U, 0x7001C1DFU, 0x840153D3U, 0x8402C3D2U, 0x2000081DU, 0x00507673U,
653     0x00407652U, 0x60816EE0U, 0x0C803E7DU, 0x63817A20U, 0x3C000011U, 0x638179E0U, 0x00507672U, 0x8402D3DDU, 0x00407652U,
654     0xC4FFF3DFU, 0xC8FFE3DEU, 0x7001F3DFU, 0x840013DFU, 0x840003DEU, 0x08CC1273U, 0x08C81273U, 0x28000213U, 0x7001C1DFU,
655     0x60817A80U, 0x3C000013U, 0x63817A80U, 0x7001C1DFU, 0x3C000015U, 0x6381AD40U, 0x860243DCU, 0x840263D0U, 0x840002DFU,
656     0x20000039U, 0x088C7FBBU, 0x2800003BU, 0x00C86FFFU, 0x00CC6FFFU, 0xC40273DFU, 0x7001B07FU, 0x840273DFU, 0x2001D61AU,
657     0x101FFE1AU, 0xC6000340U, 0xC6002342U, 0xC6004344U, 0xC6006346U, 0xC6008348U, 0xC600A34AU, 0xC600C34CU, 0xC600E34EU,
658     0x0C5102B5U, 0x860243DCU, 0x66819BC0U, 0x0C807F9CU, 0x63018020U, 0x8C001280U, 0x8C001281U, 0x8C001282U, 0x8C001283U,
659     0x8C001284U, 0x8C001285U, 0x8C001286U, 0x8C001287U, 0x8C001288U, 0x8C001289U, 0x8C00128AU, 0x8C00128BU, 0x8C00128CU,
660     0x8C00128DU, 0x8C00128EU, 0x8C00128FU, 0x60818880U, 0x088C7F9DU, 0x2800003DU, 0x8C00129BU, 0x00C8777AU, 0x00884340U,
661     0x00CC7370U, 0x8C00129BU, 0x00C8777AU, 0x00884341U, 0x00CC7370U, 0x8C00129BU, 0x00C8777AU, 0x00884342U, 0x00CC7370U,
662     0x8C00129BU, 0x00C8777AU, 0x00884343U, 0x00CC7370U, 0x8C00129BU, 0x00C8777AU, 0x00884344U, 0x00CC7370U, 0x8C00129BU,
663     0x00C8777AU, 0x00884345U, 0x00CC7370U, 0x8C00129BU, 0x00C8777AU, 0x00884346U, 0x00CC7370U, 0x8C00129BU, 0x00C8777AU,
664     0x00884347U, 0x00CC7370U, 0x8C00129BU, 0x00C8777AU, 0x00884348U, 0x00CC7370U, 0x8C00129BU, 0x00C8777AU, 0x00884349U,
665     0x00CC7370U, 0x8C00129BU, 0x00C8777AU, 0x0088434AU, 0x00CC7370U, 0x8C00129BU, 0x00C8777AU, 0x0088434BU, 0x00CC7370U,
666     0x8C00129BU, 0x00C8777AU, 0x0088434CU, 0x00CC7370U, 0x8C00129BU, 0x00C8777AU, 0x0088434DU, 0x00CC7370U, 0x8C00129BU,
667     0x00C8777AU, 0x0088434EU, 0x00CC7370U, 0x8C00129BU, 0x00C8777AU, 0x0088434FU, 0x00CC7370U, 0xC40263D0U, 0x3C000017U,
668     0x63818A00U, 0x2001DE12U, 0x101FFE12U, 0xC6000240U, 0xC6002242U, 0xC6004244U, 0xC6006246U, 0xC6008248U, 0xC600A24AU,
669     0xC600C24CU, 0xC600E24EU, 0x2001D61AU, 0x101FFE1AU, 0xA4000340U, 0xA4001341U, 0xA4002342U, 0xA4003343U, 0xA4004344U,
670     0xA4005345U, 0xA4006346U, 0xA4007347U, 0xA4008348U, 0xA4009349U, 0xA400A34AU, 0xA400B34BU, 0xA400C34CU, 0xA400D34DU,
671     0xA400E34EU, 0xA400F34FU, 0x63818F20U, 0xC6000340U, 0xC6002342U, 0xC6004344U, 0xC6006346U, 0xC6008348U, 0xC600A34AU,
672     0xC600C34CU, 0xC600E34EU, 0xC402C3DFU, 0x20000813U, 0x7001C1DFU, 0x8402C3DFU, 0x2001D61AU, 0x101FFE1AU, 0x86000340U,
673     0x86002342U, 0x86004344U, 0x86006346U, 0x86008348U, 0x8600A34AU, 0x8600C34CU, 0x8600E34EU, 0x860243DCU, 0x0C807FBDU,
674     0x63019200U, 0xCC0012C0U, 0xCC0012C1U, 0xCC0012C2U, 0xCC0012C3U, 0xCC0012C4U, 0xCC0012C5U, 0xCC0012C6U, 0xCC0012C7U,
675     0xCC0012C8U, 0xCC0012C9U, 0xCC0012CAU, 0xCC0012CBU, 0xCC0012CCU, 0xCC0012CDU, 0xCC0012CEU, 0xCC0012CFU, 0x3C000015U,
676     0x6381AD20U, 0x67017BC0U, 0x54000040U, 0x860243DCU, 0x088C7FBCU, 0x2800003CU, 0x00C8741BU, 0x00887F7BU, 0xCC0012DBU,
677     0x00CC701FU, 0x00C8743BU, 0x00887F7BU, 0xCC0012DBU, 0x00CC703FU, 0x00C8745BU, 0x00887F7BU, 0xCC0012DBU, 0x00CC705FU,
678     0x00C8747BU, 0x00887F7BU, 0xCC0012DBU, 0x00CC707FU, 0x00C8749BU, 0x00887F7BU, 0xCC0012DBU, 0x00CC709FU, 0x00C874BBU,
679     0x00887F7BU, 0xCC0012DBU, 0x00CC70BFU, 0x00C874DBU, 0x00887F7BU, 0xCC0012DBU, 0x00CC70DFU, 0x00C874FBU, 0x00887F7BU,
680     0xCC0012DBU, 0x00CC70FFU, 0x00C8751BU, 0x00887F7BU, 0xCC0012DBU, 0x00CC711FU, 0x00C8753BU, 0x00887F7BU, 0xCC0012DBU,
681     0x00CC713FU, 0x00C8755BU, 0x00887F7BU, 0xCC0012DBU, 0x00CC715FU, 0x00C8757BU, 0x00887F7BU, 0xCC0012DBU, 0x00CC717FU,
682     0x00C8759BU, 0x00887F7BU, 0xCC0012DBU, 0x00CC719FU, 0x00C875BBU, 0x00887F7BU, 0xCC0012DBU, 0x00CC71BFU, 0x00C875DBU,
683     0x00887F7BU, 0xCC0012DBU, 0x00CC71DFU, 0x00C875FBU, 0x00887F7BU, 0xCC0012DBU, 0x00CC71FFU, 0xC40273DFU, 0x3C000015U,
684     0x67017BC0U, 0x63819B00U, 0x54000040U, 0x840002DBU, 0x00CC777BU, 0x00C8777BU, 0x00887F7BU, 0xC40002DBU, 0x6081AD20U,
685     0x28000815U, 0x860243DCU, 0x2001D69DU, 0x101FFE1DU, 0x2001DE0DU, 0x101FFE0DU, 0x0C800EBCU, 0x08CC0ABBU, 0x63819D00U,
686     0x2800003BU, 0x840243DCU, 0x0C807F9CU, 0x63019E40U, 0x8C00129AU, 0xCC0011BAU, 0x008C6800U, 0xC4FFF3A0U, 0x8C0013A0U,
687     0x60019D7BU, 0x60819FA0U, 0x088C7F8BU, 0x2800002BU, 0x8C001281U, 0x00C82C3AU, 0x0088435AU, 0xCC0011BAU, 0x008C6800U,
688     0x00CC7030U, 0xC4FFF3A0U, 0x8C0013A0U, 0x60019E9BU, 0x3C000017U, 0x6381A180U, 0xC402C3DFU, 0x008056B3U, 0x0C803E7AU,
689     0x6381A140U, 0x00506A72U, 0x8402D3DAU, 0x00406A52U, 0x7001F3DFU, 0x08803E7AU, 0x00506A73U, 0x28000213U, 0x7001C1DFU,
690     0x8402C3DFU, 0x2001D61AU, 0x101FFE1AU, 0x860243DCU, 0x0C807FBDU, 0x6301A4C0U, 0x0CCC0ABBU, 0x6381A2C0U, 0x8C001340U,
691     0xCC0012C0U, 0x6001A27BU, 0x0C800EBBU, 0x6381AD20U, 0x8C000340U, 0x840002DCU, 0x08800EBDU, 0x08C80FBDU, 0x088C7FBBU,
692     0x2800003BU, 0x00C86C00U, 0x00CC6C00U, 0x00CC779CU, 0x00C8779CU, 0xC4001340U, 0x00887000U, 0xC40002C0U, 0x6081AD20U,
693     0x0CCC0AB0U, 0x6381A720U, 0x08CC0FBCU, 0x08800EABU, 0x0040716BU, 0x3C00008BU, 0x6781A5E0U, 0x28000030U, 0x0C800D6BU,
694     0x840273DFU, 0x088C7FBCU, 0x2800003CU, 0x8C001340U, 0x00C8741BU, 0x00887F7BU, 0xCC0012DBU, 0x00CC701FU, 0x6001A650U,
695     0x6301AB40U, 0x860243DCU, 0x088C7FBBU, 0x2800003BU, 0x8C00135CU, 0x00C87780U, 0x00887C00U, 0x00CC6F9FU, 0x840002DCU,
696     0x08CC0FABU, 0x08800EAAU, 0x00402D4AU, 0x3C00008AU, 0x6681A9A0U, 0x6381AB00U, 0xCC0012C0U, 0x840002DCU, 0x8C001340U,
697     0x00C87400U, 0x00887C00U, 0x08800D4AU, 0x08C80D4AU, 0x088C7D5BU, 0x2800003BU, 0x00C86C00U, 0x00CC6C00U, 0xC4001140U,
698     0x00CC2B9CU, 0x00C82B9CU, 0x00887000U, 0xC40002C0U, 0x6081AD20U, 0xC40002C0U, 0x6081AD20U, 0x08C80D6BU, 0x088C7D7CU,
699     0x2800003CU, 0x84000340U, 0x00C87400U, 0x00887C00U, 0x00C87000U, 0x00CC7000U, 0x00CC740AU, 0xC400134AU, 0x840002DBU,
700     0x00CC2F7BU, 0x00C82F7BU, 0x0088037BU, 0xC40002DBU, 0x008056B3U, 0x3C000017U, 0x6381AFE0U, 0x3C000011U, 0x6381AF60U,
701     0x2001DE12U, 0x101FFE12U, 0x8402A3DAU, 0x2000001BU, 0x8402B3DCU, 0x2000001DU, 0xC600025AU, 0xC600225CU, 0x20000213U,
702     0x7001C1FFU, 0x20000013U, 0x7001C1DFU, 0x6081AFE0U, 0x0C803E73U, 0x6301AFE0U, 0x20000013U, 0x7001C1DFU, 0x840013DFU,
703     0x04807FFFU, 0x840003DEU, 0x7080001FU, 0x2001D41AU, 0x101FFE1AU, 0x86000340U, 0x86002342U, 0x86008224U, 0x8600A226U,
704     0x8600C228U, 0x8600E22AU, 0x0080672CU, 0x8400422DU, 0x8400522EU, 0x8400622FU, 0x20000158U, 0x00401000U, 0x008C018CU,
705     0x08D0418CU, 0x00403108U, 0x008C2084U, 0x08D03084U, 0x00401000U, 0x008C018CU, 0x08D0218CU, 0x00403108U, 0x008C2084U,
706     0x08D01C84U, 0x00401421U, 0x008C05ADU, 0x08D041ADU, 0x00403529U, 0x008C24A5U, 0x08D030A5U, 0x00401421U, 0x008C05ADU,
707     0x08D021ADU, 0x00403529U, 0x008C24A5U, 0x08D01CA5U, 0x00401842U, 0x008C09CEU, 0x08D041CEU, 0x0040394AU, 0x008C28C6U,
708     0x08D030C6U, 0x00401842U, 0x008C09CEU, 0x08D021CEU, 0x0040394AU, 0x008C28C6U, 0x08D01CC6U, 0x00401C63U, 0x008C0DEFU,
709     0x08D041EFU, 0x00403D6BU, 0x008C2CE7U, 0x08D030E7U, 0x00401C63U, 0x008C0DEFU, 0x08D021EFU, 0x00403D6BU, 0x008C2CE7U,
710     0x08D01CE7U, 0x00401400U, 0x008C01EFU, 0x08D041EFU, 0x00403D4AU, 0x008C28A5U, 0x08D030A5U, 0x00401400U, 0x008C01EFU,
711     0x08D021EFU, 0x00403D4AU, 0x008C28A5U, 0x08D01CA5U, 0x00401821U, 0x008C058CU, 0x08D0418CU, 0x0040316BU, 0x008C2CC6U,
712     0x08D030C6U, 0x00401821U, 0x008C058CU, 0x08D0218CU, 0x0040316BU, 0x008C2CC6U, 0x08D01CC6U, 0x00401C42U, 0x008C09ADU,
713     0x08D041ADU, 0x00403508U, 0x008C20E7U, 0x08D030E7U, 0x00401C42U, 0x008C09ADU, 0x08D021ADU, 0x00403508U, 0x008C20E7U,
714     0x08D01CE7U, 0x00401063U, 0x008C0DCEU, 0x08D041CEU, 0x00403929U, 0x008C2484U, 0x08D03084U, 0x00401063U, 0x008C0DCEU,
715     0x08D021CEU, 0x00403929U, 0x008C2484U, 0x08D01C84U, 0x6001B218U, 0x2001D41AU, 0x101FFE1AU, 0x8600035CU, 0x00407000U,
716     0x00407421U, 0x8600235CU, 0x00407042U, 0x00407463U, 0x8600823AU, 0x8600A23CU, 0x00406884U, 0x00406CA5U, 0x004070C6U,
717     0x004074E7U, 0x8600C23AU, 0x8600E23CU, 0x00406908U, 0x00406D29U, 0x0040714AU, 0x0040756BU, 0x0040658CU, 0x8400423AU,
718     0x004069ADU, 0x8400523AU, 0x004069CEU, 0x8400623AU, 0x004069EFU, 0x28000039U, 0x7080001FU, 0x8402D3D2U, 0xC40263D0U,
719     0xC60283C0U, 0x8600A3C2U, 0x8600C3C4U, 0x8400E3CAU, 0x3C000013U, 0x6381E8A0U, 0x20000010U, 0x10002010U, 0x860103C6U,
720     0x860123C8U, 0x840143CBU, 0x860203CCU, 0x860223CEU, 0x0CCC1278U, 0x6381E7A0U, 0x8C00125DU, 0x08C81BBAU, 0x08CC1B5AU,
721     0x00406842U, 0x08CC63BAU, 0x8C00125DU, 0x08C823BBU, 0x00886F5AU, 0x08CC0B5AU, 0x08C81B5AU, 0x08CC1B5AU, 0x00406863U,
722     0x08CC43BAU, 0x8C00125DU, 0x08C843BBU, 0x00886F5AU, 0x08CC135AU, 0x08C81B5AU, 0x08CC1B5AU, 0x00406884U, 0x08CC23BAU,
723     0x8C00125DU, 0x08C863BBU, 0x00886F5AU, 0x08CC1B5AU, 0x08C81B5AU, 0x08CC1B5AU, 0x004068A5U, 0x08CC23BAU, 0x0088435AU,
724     0x0040694AU, 0x008C1840U, 0x08C47C00U, 0x008C0041U, 0x08CC7C00U, 0x00400021U, 0x03041820U, 0x0080001AU, 0x0080043BU,
725     0x008C3C60U, 0x08C47C00U, 0x008C0061U, 0x08CC7C00U, 0x00400021U, 0x03043C20U, 0x0440035AU, 0x0044077BU, 0x008C3880U,
726     0x08C47C00U, 0x008C0081U, 0x08CC7C00U, 0x00400021U, 0x03043820U, 0x0440035AU, 0x0044077BU, 0x008C34A0U, 0x08C47C00U,
727     0x008C00A1U, 0x08CC7C00U, 0x00400021U, 0x03043420U, 0x0440035AU, 0x0044077BU, 0x008C3140U, 0x08C47C00U, 0x008C0141U,
728     0x08CC7C00U, 0x00400021U, 0x03043020U, 0x0440035AU, 0x0044077BU, 0xC60163DAU, 0x008C1C40U, 0x08C47C00U, 0x008C0041U,
729     0x08CC7C00U, 0x00400021U, 0x03041C20U, 0x0080001AU, 0x0080043BU, 0x008C1860U, 0x08C47C00U, 0x008C0061U, 0x08CC7C00U,
730     0x00400021U, 0x03041820U, 0x0440035AU, 0x0044077BU, 0x008C3C80U, 0x08C47C00U, 0x008C0081U, 0x08CC7C00U, 0x00400021U,
731     0x03043C20U, 0x0440035AU, 0x0044077BU, 0x008C38A0U, 0x08C47C00U, 0x008C00A1U, 0x08CC7C00U, 0x00400021U, 0x03043820U,
732     0x0440035AU, 0x0044077BU, 0x008C3540U, 0x08C47C00U, 0x008C0141U, 0x08CC7C00U, 0x00400021U, 0x03043420U, 0x0440035AU,
733     0x0044077BU, 0xC60183DAU, 0x008C2040U, 0x08C47C00U, 0x008C0041U, 0x08CC7C00U, 0x00400021U, 0x03042020U, 0x0080001AU,
734     0x0080043BU, 0x008C1C60U, 0x08C47C00U, 0x008C0061U, 0x08CC7C00U, 0x00400021U, 0x03041C20U, 0x0440035AU, 0x0044077BU,
735     0x008C1880U, 0x08C47C00U, 0x008C0081U, 0x08CC7C00U, 0x00400021U, 0x03041820U, 0x0440035AU, 0x0044077BU, 0x008C3CA0U,
736     0x08C47C00U, 0x008C00A1U, 0x08CC7C00U, 0x00400021U, 0x03043C20U, 0x0440035AU, 0x0044077BU, 0x008C3940U, 0x08C47C00U,
737     0x008C0141U, 0x08CC7C00U, 0x00400021U, 0x03043820U, 0x0440035AU, 0x0044077BU, 0xC601A3DAU, 0x008C2440U, 0x08C47C00U,
738     0x008C0041U, 0x08CC7C00U, 0x00400021U, 0x03042420U, 0x0080001AU, 0x0080043BU, 0x008C2060U, 0x08C47C00U, 0x008C0061U,
739     0x08CC7C00U, 0x00400021U, 0x03042020U, 0x0440035AU, 0x0044077BU, 0x008C1C80U, 0x08C47C00U, 0x008C0081U, 0x08CC7C00U,
740     0x00400021U, 0x03041C20U, 0x0440035AU, 0x0044077BU, 0x008C18A0U, 0x08C47C00U, 0x008C00A1U, 0x08CC7C00U, 0x00400021U,
741     0x03041820U, 0x0440035AU, 0x0044077BU, 0x008C3D40U, 0x08C47C00U, 0x008C0141U, 0x08CC7C00U, 0x00400021U, 0x03043C20U,
742     0x0440035AU, 0x0044077BU, 0xC601C3DAU, 0x008C2C40U, 0x08C47C00U, 0x008C0041U, 0x08CC7C00U, 0x00400021U, 0x03042C20U,
743     0x0080001AU, 0x0080043BU, 0x008C2460U, 0x08C47C00U, 0x008C0061U, 0x08CC7C00U, 0x00400021U, 0x03042420U, 0x0440035AU,
744     0x0044077BU, 0x008C2080U, 0x08C47C00U, 0x008C0081U, 0x08CC7C00U, 0x00400021U, 0x03042020U, 0x0440035AU, 0x0044077BU,
745     0x008C1CA0U, 0x08C47C00U, 0x008C00A1U, 0x08CC7C00U, 0x00400021U, 0x03041C20U, 0x0440035AU, 0x0044077BU, 0x008C1940U,
746     0x08C47C00U, 0x008C0141U, 0x08CC7C00U, 0x00400021U, 0x03041820U, 0x0440035AU, 0x0044077BU, 0xC601E3DAU, 0x860163DAU,
747     0x08CC6B40U, 0x08C81B62U, 0x00880800U, 0x08C81B42U, 0x08CC1842U, 0x860183DAU, 0x0440035AU, 0x0844037BU, 0x08CC6B40U,
748     0x08C81B63U, 0x00880C00U, 0x08C81B43U, 0x08CC1863U, 0x8601A3DAU, 0x0440035AU, 0x0844037BU, 0x08CC6B40U, 0x08C81B64U,
749     0x00881000U, 0x08C81B44U, 0x08CC1884U, 0x8601C3DAU, 0x0440035AU, 0x0844037BU, 0x08CC6B40U, 0x08C81B65U, 0x00881400U,
750     0x08C81B45U, 0x08CC18A5U, 0x8601E3DAU, 0x0440035AU, 0x0844037BU, 0x08CC6B40U, 0x08C81B6AU, 0x00882800U, 0x08C81B4AU,
751     0x08CC194AU, 0x08C8081AU, 0x00406842U, 0x00400042U, 0x08CC6840U, 0x08C81842U, 0x08CC1842U, 0x00400063U, 0x6001C3F8U,
752     0x3C000010U, 0x6381E8A0U, 0x0C803E73U, 0x6381F2A0U, 0xC4FFF3DFU, 0xC8FFE3DEU, 0x7001F37FU, 0x840013DFU, 0x840003DEU,
753     0x20000010U, 0x20000038U, 0x6081C3E0U, 0x08CC6860U, 0x08C81863U, 0x08CC1863U, 0x00400084U, 0x08CC6880U, 0x08C81884U,
754     0x08CC1884U, 0x004000A5U, 0x08CC68A0U, 0x08C818A5U, 0x08CC18A5U, 0x0040014AU, 0x08CC6940U, 0x08C8194AU, 0x08CC194AU,
755     0x00400042U, 0x08C8081AU, 0x00406842U, 0x08CC6840U, 0x08C81842U, 0x08CC1842U, 0x00400063U, 0x00800846U, 0x280000A6U,
756     0x08CC68C0U, 0x08C818C6U, 0x08CC18C6U, 0x00400067U, 0x08CC68E0U, 0x08C818E7U, 0x08CC18E7U, 0x00400088U, 0x08CC6900U,
757     0x08C81908U, 0x08CC1908U, 0x004000A9U, 0x08CC6920U, 0x08C81929U, 0x08CC1929U, 0x0040014BU, 0x2000003AU, 0x08C86B5AU,
758     0x0050696BU, 0x08CC7D7AU, 0x0850075AU, 0x008068C6U, 0x008068E7U, 0x00806908U, 0x00806929U, 0x0080696BU, 0x2000001BU,
759     0x00506B7AU, 0x0850075AU, 0x00806842U, 0x00881842U, 0x00806863U, 0x00881C63U, 0x00806884U, 0x00882084U, 0x008068A5U,
760     0x008824A5U, 0x0080694AU, 0x00882D4AU, 0x08C8687BU, 0x00886C42U, 0x08CC1863U, 0x08C8509BU, 0x00886C63U, 0x08CC3084U,
761     0x08C838BBU, 0x00886C84U, 0x08CC48A5U, 0x08C8215BU, 0x00886CA5U, 0x860063DAU, 0x860083DCU, 0x04406842U, 0x04446C63U,
762     0x04447084U, 0x004474A5U, 0xC600A3C2U, 0xC600C3C4U, 0xC400E3CAU, 0x840263D0U, 0x860283C0U, 0x7080001FU, 0x20000020U,
763     0x0CCC0400U, 0x6081F3E0U, 0x04500000U, 0x8E00225AU, 0x8EFFE25CU, 0x08803E61U, 0x20000000U, 0x00500400U, 0x08C47C01U,
764     0x0080075AU, 0x28000080U, 0x08C47C01U, 0x0080077BU, 0x28000080U, 0x08C47C01U, 0x0080079CU, 0x28000080U, 0x08C47C01U,
765     0x008007BDU, 0xCE00225AU, 0xCEFFE25CU, 0x08800E7AU, 0x08C80F5AU, 0x20000000U, 0x08440000U, 0x00C86800U, 0x2000001CU,
766     0x00506B9AU, 0x00806B5CU, 0x08C47F9CU, 0x2800041AU, 0x00CC6B9CU, 0x0880327BU, 0x00404B7BU, 0x8400037DU, 0x008073BDU,
767     0x008803BDU, 0xC400037DU, 0x7080001FU, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U,
768     0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U,
769     0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U,
770     0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U,
771     0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U,
772     0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U,
773     0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U,
774     0x00000000U};
775 
776 static const uint32_t s_cau3ImemBytes = sizeof(s_cau3ImemImage);
777 
778 /*******************************************************************************
779  * Prototypes
780  ******************************************************************************/
781 
782 static status_t cau3_initialize_inst_memory(CAU3_Type *base, const uint32_t *cau3ImemImage, size_t cau3ImemBytes);
783 static status_t cau3_initialize_data_memory(CAU3_Type *base, cau3_task_done_t taskDone);
784 static status_t cau3_initialize_read_only_data_memory(CAU3_Type *base,
785                                                       const uint32_t *cau3ReadOnlyConstants,
786                                                       size_t cau3ReadOnlyConstantsBytes,
787                                                       cau3_task_done_t taskDone);
788 static status_t cau3_load_key_context(CAU3_Type *base,
789                                       cau3_key_context_t *cauKeyContext,
790                                       cau3_key_slot_t keySlot,
791                                       cau3_task_done_t taskDone);
792 static status_t cau3_load_key(
793     CAU3_Type *base, const uint8_t *key, size_t keySize, uint32_t keySlot, cau3_task_done_t taskDone);
794 static status_t cau3_pkha_clear_regabne(CAU3_Type *base, bool A, bool B, bool N, bool E);
795 
796 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
797 static status_t cau3_execute_null_task(CAU3_Type *base, cau3_task_done_t taskDone);
798 static status_t cau3_lock_semaphore(CAU3_Type *base);
799 static void cau3_release_semaphore(CAU3_Type *base);
800 #endif
801 
802 /*******************************************************************************
803  * Code
804  ******************************************************************************/
805 
cau3_process_task_completion(CAU3_Type * base,cau3_task_done_t taskDone)806 static status_t cau3_process_task_completion(CAU3_Type *base, cau3_task_done_t taskDone)
807 {
808     status_t taskCompletionStatus;
809 
810     taskCompletionStatus = kStatus_Fail; /* assume an error completion status */
811     switch (((uint32_t)taskDone >> 16U) & 7U)
812     {
813         uint32_t tkcs;
814 
815         case 0: /* poll the cau3 status register */
816             tkcs = base->SR & CAU3_SR_TKCS_MASK;
817             while (tkcs == CAU3_SR_TKCS_RUN)
818             {
819                 tkcs = base->SR & CAU3_SR_TKCS_MASK;
820             };
821 
822             /* check the task completion status*/
823             if (tkcs == CAU3_SR_TKCS_STOPNOERR)
824             {
825                 taskCompletionStatus = kStatus_Success; /* signal error-free completion status */
826             }
827 
828             break;
829 
830         case 2: /* task completion signaled by event_done */
831             do
832             {
833                 __WFE(); /* cpu is waiting for cau3 event_done */
834                 tkcs = base->SR & CAU3_SR_TKCS_MASK;
835             } while (tkcs == CAU3_SR_TKCS_RUN);
836 
837             /* check the task completion status */
838             if (tkcs == CAU3_SR_TKCS_STOPNOERR)
839             {
840                 taskCompletionStatus = kStatus_Success; /* signal error-free completion status */
841             }
842             break;
843 
844         case 1: /* task completion signaled by irq */
845         /* TEMP FIX - for boot ROM with IRQ task completion, simply return */
846         case 4: /* task completion signaled by dma_req */
847             /* processing here is complete */
848             taskCompletionStatus = kStatus_Success; /* signal error-free completion status */
849             break;
850 
851         default: /* undefined taskDone specifier defaults to kStatus_Fail */
852             break;
853     } /* end - switch (taskDone & 7U) */
854 
855     return (taskCompletionStatus);
856 }
857 
858 /*!
859  * @brief   Initialize the CAU3's Instruction Memory
860  *
861  * Initializes the CAU3, including configuring it to enable the execution of
862  * crypto tasks, loading the CryptoCore's firmware image into the CAU3's
863  * instruction memory, and then performing a simple read-verify of its contents.
864  * NOTE: All the operations for this function are executed on the host processor.
865  *
866  * cau3_initialize_inst_memory
867  * @param   cau3ImemImage - binary firmware image for CryptoCore
868  * @param   cau3ImemBytes - size of the firmware image in bytes
869  *
870  * @retval  status from the readVerify check: CAU_[OK (=0), ERROR (!0)]
871  *          if an error is signaled, the retval is 0xbad10000UU + i, where i is
872  *          the first miscompare word index location
873  */
cau3_initialize_inst_memory(CAU3_Type * base,const uint32_t * cau3ImemImage,size_t cau3ImemBytes)874 static status_t cau3_initialize_inst_memory(CAU3_Type *base, const uint32_t *cau3ImemImage, size_t cau3ImemBytes)
875 {
876     uint32_t i;
877 
878     /* enable the cau3 */
879     base->CR = 0U;
880 
881     /* poll if/while the cau3 is running initialization */
882     while ((base->SR & CAU3_SR_TKCS_MASK) == CAU3_SR_TKCS_INITRUN)
883     {
884     };
885 
886     /* check for error-free stop state */
887     if ((base->SR & CAU3_SR_TKCS_MASK) != CAU3_SR_TKCS_STOPNOERR)
888     {
889         return (0xbad00000U + (base->SR & CAU3_SR_TKCS_MASK)); /* exit with error */
890     }
891 
892     base->SR = CAU3_SR_TCIRQ_MASK; /* clear the TCIRQ interrupt flag */
893 
894     /* write the code hex image into the cau3's imem
895      * initialize the memory cmd and address registers */
896     base->DBGMCMD = 0xac000000U; /* wt=1, ia=1, imem=0 */
897     base->DBGMADR = 0U;          /* imem starting address */
898     for (i = 0; i < cau3ImemBytes / 4; i++)
899     {
900         base->DBGMDR = cau3ImemImage[i]; /* indirect write into cau3Imem */
901     }
902 
903     /* read-verify the cau3 imem code image
904      * initialize the memory cmd and address registers */
905     base->DBGMCMD = 0x8c000000U; /* wt=0, ia=1, imem=0 */
906     base->DBGMADR = 0U;          /* imem starting address */
907     for (i = 0; i < cau3ImemBytes / 4; i++)
908     {
909         if (base->DBGMDR != cau3ImemImage[i]) /* indirect read from cau3Imem */
910         {
911             return (0xbad10000U + i); /* exit on miscompare */
912         }
913     }
914 
915     /* this function does *not* disable reads/writes of the cau3 local memories
916      * but, this operation is needed to "secure" (i.e., make private) the cau3
917      * local memories */
918 
919     return 0U;
920 }
921 
922 /*!
923  * @brief   Initializes the CAU3's entire private Data Memory
924  *
925  * Initialize the CAU3's data memory, and then perform a read-verify versus a
926  * precalculated "pseudo-hash" value.
927  *
928  * cau3_initialize_data_memory
929  * @param   taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
930  *
931  * @retval  status from the readVerify check: CAU_[OK, ERROR]
932  */
cau3_initialize_data_memory(CAU3_Type * base,cau3_task_done_t taskDone)933 static status_t cau3_initialize_data_memory(CAU3_Type *base, cau3_task_done_t taskDone)
934 {
935     status_t completionStatus;
936 
937     /* execute the cau3 "security violation + data initialization" task */
938     base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
939     base->CC_R31 = 0U;                 /* set LR = 0 to signal a host task */
940     base->CC_PC = CAU3_TASK_SECV_INIT; /* call cau_secv_init() */
941     base->CC_CMD = taskDone;           /* trigger cau3 execution */
942 
943     /* process the cau3 task completion signal specified by taskDone */
944     completionStatus = cau3_process_task_completion(base, taskDone);
945     return (completionStatus);
946 }
947 
948 /*!
949  * @brief   Copies read-only constants from sysMemory to CAU3's DataMemory
950  *
951  * Initialize the read-only constants in the CAU3's data memory. This includes
952  * the AES constants (RCON) and most of the constants used in the hash functions.
953  * The constants associated with SHA-512 are NOT included and must be loaded
954  * separately.
955  *
956  * cau3_initialize_read_only_data_memory
957  * @param   cauReadOnlyConstants - sysMemory table of constants needed by CAU3
958  * @param   cauReadOnlyConstantsSize - size of read-only constants in bytes
959  * @param   taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
960  *
961  * @retval  status check from task completion: CAU_[OK, ERROR]
962  */
cau3_initialize_read_only_data_memory(CAU3_Type * base,const uint32_t * cau3ReadOnlyConstants,size_t cau3ReadOnlyConstantsBytes,cau3_task_done_t taskDone)963 static status_t cau3_initialize_read_only_data_memory(CAU3_Type *base,
964                                                       const uint32_t *cau3ReadOnlyConstants,
965                                                       size_t cau3ReadOnlyConstantsBytes,
966                                                       cau3_task_done_t taskDone)
967 {
968     status_t completionStatus;
969 
970     /* execute the cau3 "initialize dmem read-only constants" task */
971     base->CC_R[16] = (uint32_t)s_cau3ReadOnlyConstants; /* pReadOnlyConstants */
972     base->CC_R[17] = s_cau3ReadOnlyConstantsBytes;      /* byte count (0-mod-16) */
973     base->CC_R[18] = CAU3_DMEM_AES_RCON;                /* pDMEM_AES_RCON constants base */
974     base->CC_R30 = CAU3_DMEM_STK_BASE;                  /* initialize stack pointer (sp) */
975     base->CC_R31 = 0U;                                  /* set LR = 0 to signal a host task */
976     base->CC_PC = CAU3_TASK_BLKLD_DMEM;                 /* call cau_block_load_dmem task */
977     base->CC_CMD = taskDone;                            /* trigger cau3 execution */
978 
979     /* process the cau3 task completion signal specified by taskDone */
980     completionStatus = cau3_process_task_completion(base, taskDone);
981     return (completionStatus);
982 }
983 
CAU3_MakeMemsPrivate(CAU3_Type * base,cau3_task_done_t taskDone)984 status_t CAU3_MakeMemsPrivate(CAU3_Type *base, cau3_task_done_t taskDone)
985 {
986 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
987     uint32_t completionStatus;
988     completionStatus = cau3_lock_semaphore(base);
989     if (kStatus_Success != completionStatus)
990     {
991         cau3_release_semaphore(base);
992         return completionStatus;
993     }
994 #endif /* FSL_CAU3_USE_HW_SEMA */
995 
996     /* making the xMEMs private involves setting DBGCSR[DDBGMC] = 1 */
997     base->DBGCSR = CAU3_DBGCSR_DDBGMC_MASK; /* set DBGCSR[DDBGMC] */
998 
999 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1000     cau3_release_semaphore(base);
1001 #endif
1002     return kStatus_Success;
1003 }
1004 
1005 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1006 /*!
1007  * @brief   Execute a CAU3 null task to "establish ownership" by host processor
1008  *
1009  * Execute a null task to claim ownership of the CAU3 by the host processor.
1010  * This is required for correct IRQ, EVT and DMA_REQ signaling by subsequent
1011  * PKHA operations. The CryptoCore task executes one instruction - a "stop".
1012  *
1013  * cau3_execute_null_task
1014  * @param   taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
1015  *
1016  * @retval  status check from task completion: CAU_[OK, ERROR]
1017  */
cau3_execute_null_task(CAU3_Type * base,cau3_task_done_t taskDone)1018 static status_t cau3_execute_null_task(CAU3_Type *base, cau3_task_done_t taskDone)
1019 {
1020     status_t completionStatus;
1021 
1022     /* execute the cau3 null task */
1023     base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
1024     base->CC_R31 = 0;                  /* set LR = 0 to signal a host task */
1025     base->CC_PC = CAU3_TASK_NULL;      /* call cau_null() */
1026     base->CC_CMD = taskDone;           /* trigger cau3 execution */
1027 
1028     /* process the cau3 task completion signal specified by taskDone */
1029     completionStatus = cau3_process_task_completion(base, taskDone);
1030     return (completionStatus);
1031 }
1032 #endif /* FSL_CAU3_USE_HW_SEMA */
1033 
1034 /*!
1035  * @brief   Load a key into a key context
1036  *
1037  * Loads up to 32-byte key into the specified key slot.
1038  * There is support for a maximum of 4 key slots.
1039  * This does not do AES key expansion (as in cau3_load_key_context() case) so we use this one for loading TDES keys.
1040  *
1041  * @param   key is the key pointer, ALIGNED ON A 0-MOD-4 ADDRESS
1042  * @param   keySize is the size in bytes of the key
1043  * @param   keySlot is the destination key context
1044  * @param   taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
1045  *
1046  * @retval  status check from task completion: CAU_[OK, ERROR]
1047  */
cau3_load_key(CAU3_Type * base,const uint8_t * key,size_t keySize,uint32_t keySlot,cau3_task_done_t taskDone)1048 static status_t cau3_load_key(
1049     CAU3_Type *base, const uint8_t *key, size_t keySize, uint32_t keySlot, cau3_task_done_t taskDone)
1050 {
1051     status_t completionStatus;
1052 
1053 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1054     completionStatus = cau3_lock_semaphore(base);
1055     if (kStatus_Success != completionStatus)
1056     {
1057         cau3_release_semaphore(base);
1058         return completionStatus;
1059     }
1060 #endif
1061 
1062     /*  execute the cau3 "load initialization vector into key context" task  */
1063     base->CC_R[16] = (uintptr_t)key;   /*  pKey  */
1064     base->CC_R[17] = keySize;          /*  IV size  */
1065     base->CC_R[18] = keySlot;          /*  keySlot  */
1066     base->CC_R30 = CAU3_DMEM_STK_BASE; /*  initialize stack pointer (sp)  */
1067     base->CC_R31 = 0U;                 /*  set LR = 0 to signal a host task  */
1068     base->CC_PC = CAU3_TASK_LD_KEY;    /*  call cau_load_key()  */
1069     base->CC_CMD = taskDone;           /*  trigger cau3 execution  */
1070 
1071     /*  process the cau3 task completion signal specified by taskDone  */
1072     completionStatus = cau3_process_task_completion(base, taskDone);
1073 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1074     cau3_release_semaphore(base);
1075 #endif
1076     return (completionStatus);
1077 }
1078 
CAU3_AES_Encrypt(CAU3_Type * base,cau3_handle_t * handle,const uint8_t plaintext[16],uint8_t ciphertext[16])1079 status_t CAU3_AES_Encrypt(CAU3_Type *base, cau3_handle_t *handle, const uint8_t plaintext[16], uint8_t ciphertext[16])
1080 {
1081     status_t completionStatus;
1082     cau3_task_done_t taskDone;
1083 
1084     taskDone = handle->taskDone;
1085 
1086 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1087     completionStatus = cau3_lock_semaphore(base);
1088     if (kStatus_Success != completionStatus)
1089     {
1090         cau3_release_semaphore(base);
1091         return completionStatus;
1092     }
1093 #endif
1094 
1095     /* execute the cau3 "aes_encrypt_ecb" task */
1096     base->CC_R[16] = (uint32_t)plaintext;  /* pPlainText */
1097     base->CC_R[17] = handle->keySlot;      /* keySlot */
1098     base->CC_R[19] = (uint32_t)ciphertext; /* pCipherText */
1099     base->CC_R30 = CAU3_DMEM_STK_BASE;     /* initialize stack pointer (sp) */
1100     base->CC_R31 = 0U;                     /* set LR = 0 to signal a host task */
1101     base->CC_PC = CAU3_TASK_AES_ENCRYPT;   /* call cau_aes_encrypt() */
1102     base->CC_CMD = taskDone;               /* trigger cau3 execution */
1103 
1104     /* process the cau3 task completion signal specified by taskDone */
1105     completionStatus = cau3_process_task_completion(base, taskDone);
1106 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1107     cau3_release_semaphore(base);
1108 #endif
1109     return (completionStatus);
1110 }
1111 
CAU3_AES_Decrypt(CAU3_Type * base,cau3_handle_t * handle,const uint8_t ciphertext[16],uint8_t plaintext[16])1112 status_t CAU3_AES_Decrypt(CAU3_Type *base, cau3_handle_t *handle, const uint8_t ciphertext[16], uint8_t plaintext[16])
1113 {
1114     status_t completionStatus;
1115     cau3_task_done_t taskDone;
1116 
1117     taskDone = handle->taskDone;
1118 
1119 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1120     completionStatus = cau3_lock_semaphore(base);
1121     if (kStatus_Success != completionStatus)
1122     {
1123         cau3_release_semaphore(base);
1124         return completionStatus;
1125     }
1126 #endif
1127 
1128     /* execute the cau3 "aes_decrypt_ecb" task */
1129     base->CC_R[16] = (uint32_t)ciphertext; /* pCipherText */
1130     base->CC_R[17] = handle->keySlot;      /* keySlot */
1131     base->CC_R[19] = (uint32_t)plaintext;  /* pPlainText */
1132     base->CC_R30 = CAU3_DMEM_STK_BASE;     /* initialize stack pointer (sp) */
1133     base->CC_R31 = 0U;                     /* set LR = 0 to signal a host task */
1134     base->CC_PC = CAU3_TASK_AES_DECRYPT;   /* call cau_aes_decrypt() */
1135     base->CC_CMD = taskDone;               /* trigger cau3 execution */
1136 
1137     /* process the cau3 task completion signal specified by taskDone */
1138     completionStatus = cau3_process_task_completion(base, taskDone);
1139 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1140     cau3_release_semaphore(base);
1141 #endif
1142     return (completionStatus);
1143 }
1144 
CAU3_Init(CAU3_Type * base)1145 void CAU3_Init(CAU3_Type *base)
1146 {
1147 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
1148     /* ungate clock */
1149     CLOCK_EnableClock(kCLOCK_Cau3);
1150 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1151     CLOCK_EnableClock(FSL_CAU3_SEMA42_CLOCK_NAME);
1152 #endif /* FSL_CAU3_USE_HW_SEMA */
1153 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
1154 
1155     base->CR = CAU3_CR_RSTSM4(1);
1156     base->CR = CAU3_CR_RSTSM4(2);
1157     cau3_initialize_inst_memory(base, s_cau3ImemImage, s_cau3ImemBytes);
1158     cau3_initialize_data_memory(base, kCAU3_TaskDonePoll);
1159     cau3_initialize_read_only_data_memory(base, s_cau3ReadOnlyConstants, s_cau3ReadOnlyConstantsBytes,
1160                                           kCAU3_TaskDonePoll);
1161     cau3_pkha_clear_regabne(base, true, true, true, true);
1162 }
1163 
1164 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
cau3_lock_semaphore(CAU3_Type * base)1165 static status_t cau3_lock_semaphore(CAU3_Type *base)
1166 {
1167     uint32_t processorNumber = 0;
1168 
1169     /* cm4 will be 1, cm0+ will be 2 */
1170     /* For next SoC, the processor number shall be defined in the SoC header file */
1171 #if __CORTEX_M == 0U
1172     processorNumber++;
1173 #endif
1174     processorNumber++;
1175 
1176     while (processorNumber != SEMA42_GATEn(FSL_CAU3_SEMA42_BASE, 1))
1177     {
1178         /* Wait for unlocked status. */
1179         while (SEMA42_GATEn(FSL_CAU3_SEMA42_BASE, FSL_CAU3_SEMA42_GATE))
1180         {
1181         }
1182 
1183         /* Lock the gate. */
1184         SEMA42_GATEn(FSL_CAU3_SEMA42_BASE, FSL_CAU3_SEMA42_GATE) = processorNumber;
1185     }
1186 
1187     return cau3_execute_null_task(base, kCAU3_TaskDonePoll);
1188 }
1189 #endif /* FSL_CAU3_USE_HW_SEMA */
1190 
1191 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
cau3_release_semaphore(CAU3_Type * base)1192 static void cau3_release_semaphore(CAU3_Type *base)
1193 {
1194     /* unlock the semaphore */
1195     SEMA42_GATEn(FSL_CAU3_SEMA42_BASE, FSL_CAU3_SEMA42_GATE) = 0;
1196 }
1197 #endif /* FSL_CAU3_USE_HW_SEMA */
1198 
1199 /*!
1200  * @brief   Load a 64-byte "key context" into the CAU3's private data memory
1201  *
1202  * Load the key context into the private DMEM. This includes size and config
1203  * information, a 16-byte initialization vector and a key of size [8,16,24,32]
1204  * bytes (for DES or AES-[128,192,256]). There is support for 4 "key slots" with
1205  * slot 0 typically used for the system key encryption key (KEK).
1206  *
1207  * See the GENERAL COMMENTS for more information on the keyContext structure.
1208  *
1209  * NOTE: This function also performs an AES key expansion if a keySize > 8
1210  * is specified.
1211  *
1212  * cau3_load_key_context
1213  * @param   cauKeyContext is pointer to key structure in sysMemory
1214  * @param   keySlot is the destination key slot number [0-3]
1215  * @param   taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
1216  *
1217  * @return  status check from task completion: CAU_[OK, ERROR]
1218  */
cau3_load_key_context(CAU3_Type * base,cau3_key_context_t * cauKeyContext,cau3_key_slot_t keySlot,cau3_task_done_t taskDone)1219 static status_t cau3_load_key_context(CAU3_Type *base,
1220                                       cau3_key_context_t *cauKeyContext,
1221                                       cau3_key_slot_t keySlot,
1222                                       cau3_task_done_t taskDone)
1223 {
1224     status_t completionStatus;
1225 
1226 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1227     completionStatus = cau3_lock_semaphore(base);
1228     if (kStatus_Success != completionStatus)
1229     {
1230         cau3_release_semaphore(base);
1231         return completionStatus;
1232     }
1233 #endif
1234 
1235     /* execute the cau3 "load key context" task */
1236     base->CC_R[16] = (uint32_t)cauKeyContext; /* pKeyContext */
1237     base->CC_R[17] = keySlot;                 /* keySlot */
1238     base->CC_R30 = CAU3_DMEM_STK_BASE;        /* initialize stack pointer (sp) */
1239     base->CC_R31 = 0U;                        /* set LR = 0 to signal a host task */
1240     base->CC_PC = CAU3_TASK_LD_KEYCTX;        /* call cau_load_key_context() */
1241     base->CC_CMD = taskDone;                  /* trigger cau3 execution */
1242 
1243     /* process the cau3 task completion signal specified by taskDone */
1244     completionStatus = cau3_process_task_completion(base, taskDone);
1245 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1246     cau3_release_semaphore(base);
1247 #endif
1248     return (completionStatus);
1249 }
1250 
CAU3_ForceError(CAU3_Type * base,cau3_task_done_t taskDone)1251 status_t CAU3_ForceError(CAU3_Type *base, cau3_task_done_t taskDone)
1252 {
1253     status_t completionStatus;
1254 
1255 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1256     completionStatus = cau3_lock_semaphore(base);
1257     if (kStatus_Success != completionStatus)
1258     {
1259         cau3_release_semaphore(base);
1260         return completionStatus;
1261     }
1262 #endif
1263 
1264     /*  execute the cau3 null task  */
1265     base->CC_R30 = CAU3_DMEM_STK_BASE; /*  initialize stack pointer (sp)  */
1266     base->CC_R31 = 0;                  /*  set LR = 0 to signal a host task  */
1267     base->CC_PC = CAU3_TASK_STOPERROR;
1268     base->CC_CMD = taskDone; /*  trigger cau3 execution  */
1269 
1270     /*  process the cau3 task completion signal specified by taskDone  */
1271     completionStatus = cau3_process_task_completion(base, taskDone);
1272 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1273     cau3_release_semaphore(base);
1274 #endif
1275     return (completionStatus);
1276 }
1277 
CAU3_LoadSpecialKeyContext(CAU3_Type * base,size_t keySize,cau3_key_slot_t keySlot,cau3_task_done_t taskDone)1278 status_t CAU3_LoadSpecialKeyContext(CAU3_Type *base, size_t keySize, cau3_key_slot_t keySlot, cau3_task_done_t taskDone)
1279 {
1280     status_t completionStatus;
1281 
1282 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1283     completionStatus = cau3_lock_semaphore(base);
1284     if (kStatus_Success != completionStatus)
1285     {
1286         cau3_release_semaphore(base);
1287         return completionStatus;
1288     }
1289 #endif
1290 
1291     /*  execute the cau3 "load special key context" task  */
1292     base->CC_R[16] = keySize;             /*  keySize [8,16,24,32]  */
1293     base->CC_R[17] = keySlot;             /*  keySlot  */
1294     base->CC_R30 = CAU3_DMEM_STK_BASE;    /*  initialize stack pointer (sp)  */
1295     base->CC_R31 = 0U;                    /*  set LR = 0 to signal a host task  */
1296     base->CC_PC = CAU3_TASK_LD_SP_KEYCTX; /*  call cau_load_special_key_context()  */
1297     base->CC_CMD = taskDone;              /*  trigger cau3 execution  */
1298 
1299     /*  process the cau3 task completion signal specified by taskDone  */
1300     completionStatus = cau3_process_task_completion(base, taskDone);
1301 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1302     cau3_release_semaphore(base);
1303 #endif
1304     return (completionStatus);
1305 }
1306 
CAU3_ClearKeyContext(CAU3_Type * base,cau3_key_slot_t keySlot,cau3_task_done_t taskDone)1307 status_t CAU3_ClearKeyContext(CAU3_Type *base, cau3_key_slot_t keySlot, cau3_task_done_t taskDone)
1308 {
1309     uint32_t completionStatus;
1310 
1311 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1312     completionStatus = cau3_lock_semaphore(base);
1313     if (kStatus_Success != completionStatus)
1314     {
1315         cau3_release_semaphore(base);
1316         return completionStatus;
1317     }
1318 #endif
1319 
1320     /*  execute the cau3 "clear key context" task  */
1321     base->CC_R[17] = keySlot;           /*  keySlot  */
1322     base->CC_R30 = CAU3_DMEM_STK_BASE;  /*  initialize stack pointer (sp)  */
1323     base->CC_R31 = 0U;                  /*  set LR = 0 to signal a host task  */
1324     base->CC_PC = CAU3_TASK_CLR_KEYCTX; /*  call cau_clear_key_context()  */
1325     base->CC_CMD = taskDone;            /*  trigger cau3 execution  */
1326 
1327     /*  process the cau3 task completion signal specified by taskDone  */
1328     completionStatus = cau3_process_task_completion(base, taskDone);
1329 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1330     cau3_release_semaphore(base);
1331 #endif
1332     return (completionStatus);
1333 }
1334 
CAU3_LoadKeyInitVector(CAU3_Type * base,const uint8_t * iv,cau3_key_slot_t keySlot,cau3_task_done_t taskDone)1335 status_t CAU3_LoadKeyInitVector(CAU3_Type *base, const uint8_t *iv, cau3_key_slot_t keySlot, cau3_task_done_t taskDone)
1336 {
1337     status_t completionStatus;
1338 
1339 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1340     completionStatus = cau3_lock_semaphore(base);
1341     if (kStatus_Success != completionStatus)
1342     {
1343         cau3_release_semaphore(base);
1344         return completionStatus;
1345     }
1346 #endif
1347 
1348     /*  execute the cau3 "load initialization vector into key context" task  */
1349     base->CC_R[16] = (uintptr_t)iv;    /*  pIv  */
1350     base->CC_R[17] = keySlot;          /*  keySlot  */
1351     base->CC_R30 = CAU3_DMEM_STK_BASE; /*  initialize stack pointer (sp)  */
1352     base->CC_R31 = 0U;                 /*  set LR = 0 to signal a host task  */
1353     base->CC_PC = CAU3_TASK_LD_IV;     /*  call cau_load_iv()  */
1354     base->CC_CMD = taskDone;           /*  trigger cau3 execution  */
1355 
1356     /*  process the cau3 task completion signal specified by taskDone  */
1357     completionStatus = cau3_process_task_completion(base, taskDone);
1358 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1359     cau3_release_semaphore(base);
1360 #endif
1361     return (completionStatus);
1362 }
1363 
CAU3_AES_KeyExpansion(CAU3_Type * base,cau3_key_slot_t keySlot,cau3_task_done_t taskDone)1364 status_t CAU3_AES_KeyExpansion(CAU3_Type *base, cau3_key_slot_t keySlot, cau3_task_done_t taskDone)
1365 {
1366     status_t completionStatus;
1367 
1368 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1369     completionStatus = cau3_lock_semaphore(base);
1370     if (kStatus_Success != completionStatus)
1371     {
1372         cau3_release_semaphore(base);
1373         return completionStatus;
1374     }
1375 #endif
1376 
1377     /* execute the cau3 "aes_key_expansion" task */
1378     base->CC_R[17] = keySlot;            /* keySlot */
1379     base->CC_R30 = CAU3_DMEM_STK_BASE;   /* initialize stack pointer (sp) */
1380     base->CC_R31 = 0U;                   /* set LR = 0 to signal a host task */
1381     base->CC_PC = CAU3_TASK_AES_KEY_SCH; /* call cau_aes_key_sched() */
1382     base->CC_CMD = taskDone;             /* trigger cau3 execution */
1383 
1384     /* process the cau3 task completion signal specified by taskDone */
1385     completionStatus = cau3_process_task_completion(base, taskDone);
1386 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1387     cau3_release_semaphore(base);
1388 #endif
1389     return (completionStatus);
1390 }
1391 
CAU3_AES_SetKey(CAU3_Type * base,cau3_handle_t * handle,const uint8_t * key,size_t keySize)1392 status_t CAU3_AES_SetKey(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *key, size_t keySize)
1393 {
1394     cau3_key_context_t cau3KeyCtx = {0};
1395 
1396     /* only work with aligned key[] */
1397     if (0x3U & (uintptr_t)key)
1398     {
1399         return kStatus_InvalidArgument;
1400     }
1401 
1402     /* keySize must be 16 or 32. initial CAU3 firmware doesn't support 24 bytes. */
1403     if ((keySize != 16U) && (keySize != 32U))
1404     {
1405         return kStatus_InvalidArgument;
1406     }
1407 
1408     cau3KeyCtx.keySize = keySize;
1409 
1410     /* move the key by 32-bit words */
1411     int i = 0;
1412     while (keySize)
1413     {
1414         keySize -= sizeof(uint32_t);
1415         ((uint32_t *)((uintptr_t)cau3KeyCtx.key))[i] = ((uint32_t *)(uintptr_t)key)[i];
1416         i++;
1417     }
1418 
1419     return cau3_load_key_context(base, &cau3KeyCtx, handle->keySlot, handle->taskDone);
1420 }
1421 
CAU3_AES_Cmac(CAU3_Type * base,cau3_handle_t * handle,const uint8_t * message,size_t size,uint8_t * mac)1422 status_t CAU3_AES_Cmac(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *message, size_t size, uint8_t *mac)
1423 {
1424     status_t completionStatus;
1425 
1426     /* mac must be 0-mod-4 aligned */
1427     if (0x3U & (uintptr_t)mac)
1428     {
1429         return kStatus_InvalidArgument;
1430     }
1431 
1432 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1433     completionStatus = cau3_lock_semaphore(base);
1434     if (kStatus_Success != completionStatus)
1435     {
1436         cau3_release_semaphore(base);
1437         return completionStatus;
1438     }
1439 #endif
1440 
1441     /*  execute the cau3 "aes_cmac" task  */
1442     base->CC_R[16] = (uintptr_t)message; /*  pMessage  */
1443     base->CC_R[17] = handle->keySlot;    /*  keySlot  */
1444     base->CC_R[18] = size;               /*  messageSize  */
1445     base->CC_R[19] = (uintptr_t)mac;     /*  pMac  */
1446     base->CC_R30 = CAU3_DMEM_STK_BASE;   /*  initialize stack pointer (sp)  */
1447     base->CC_R31 = 0U;                   /*  set LR = 0 to signal a host task  */
1448     base->CC_PC = CAU3_TASK_AES128_CMAC; /*  call cau_aes128_cmac()  */
1449     base->CC_CMD = handle->taskDone;     /*  trigger cau3 execution  */
1450 
1451     /*  process the cau3 task completion signal specified by taskDone  */
1452     completionStatus = cau3_process_task_completion(base, handle->taskDone);
1453 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1454     cau3_release_semaphore(base);
1455 #endif
1456     return (completionStatus);
1457 }
1458 
1459 /*!
1460  * @brief Check validity of algoritm.
1461  *
1462  * This function checks the validity of input argument.
1463  *
1464  * @param algo Tested algorithm value.
1465  * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
1466  */
cau3_hash_check_input_alg(cau3_hash_algo_t algo)1467 static status_t cau3_hash_check_input_alg(cau3_hash_algo_t algo)
1468 {
1469     if ((algo != kCAU3_Sha256) && (algo != kCAU3_Sha1))
1470     {
1471         return kStatus_InvalidArgument;
1472     }
1473     return kStatus_Success;
1474 }
1475 
1476 /*!
1477  * @brief Check validity of input arguments.
1478  *
1479  * This function checks the validity of input arguments.
1480  *
1481  * @param base CAU3 peripheral base address.
1482  * @param ctx Memory buffer given by user application where the CAU3_HASH_Init/CAU3_HASH_Update/CAU3_HASH_Finish store
1483  * context.
1484  * @param algo Tested algorithm value.
1485  * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
1486  */
cau3_hash_check_input_args(CAU3_Type * base,cau3_hash_ctx_t * ctx,cau3_hash_algo_t algo)1487 static status_t cau3_hash_check_input_args(CAU3_Type *base, cau3_hash_ctx_t *ctx, cau3_hash_algo_t algo)
1488 {
1489     /* Check validity of input algorithm */
1490     if (kStatus_Success != cau3_hash_check_input_alg(algo))
1491     {
1492         return kStatus_InvalidArgument;
1493     }
1494 
1495     if ((NULL == ctx) || (NULL == base))
1496     {
1497         return kStatus_InvalidArgument;
1498     }
1499 
1500     return kStatus_Success;
1501 }
1502 
1503 /*!
1504  * @brief Check validity of internal software context.
1505  *
1506  * This function checks if the internal context structure looks correct.
1507  *
1508  * @param ctxInternal Internal context.
1509  * @param message Input message address.
1510  * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
1511  */
cau3_hash_check_context(cau3_hash_ctx_internal_t * ctxInternal,const uint8_t * message)1512 static status_t cau3_hash_check_context(cau3_hash_ctx_internal_t *ctxInternal, const uint8_t *message)
1513 {
1514     if ((NULL == message) || (NULL == ctxInternal) || (kStatus_Success != cau3_hash_check_input_alg(ctxInternal->algo)))
1515     {
1516         return kStatus_InvalidArgument;
1517     }
1518     return kStatus_Success;
1519 }
1520 
1521 /*!
1522  * @brief   Initialize message digest output state for SHA-1 hash
1523  *
1524  * Initializes the message digest output state for a SHA-1 hash.
1525  *
1526  * @param   sha1State is message digest output in sysMemory in BE format
1527  * @param   taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
1528  *
1529  * @retval  status check from task completion: CAU_[OK, ERROR]
1530  */
1531 
CAU3_Sha1InitializeOutput(CAU3_Type * base,uint32_t * sha1State,cau3_task_done_t taskDone)1532 static status_t CAU3_Sha1InitializeOutput(CAU3_Type *base, uint32_t *sha1State, cau3_task_done_t taskDone)
1533 {
1534     status_t completionStatus;
1535 
1536 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1537     completionStatus = cau3_lock_semaphore(base);
1538     if (kStatus_Success != completionStatus)
1539     {
1540         cau3_release_semaphore(base);
1541         return completionStatus;
1542     }
1543 #endif
1544 
1545     /*  execute the cau3 "sha1_init_output" task  */
1546     base->CC_R[29] = (uintptr_t)sha1State;   /*  pSha1State  */
1547     base->CC_R30 = CAU3_DMEM_STK_BASE;       /*  initialize stack pointer (sp)  */
1548     base->CC_R31 = 0U;                       /*  set LR = 0 to signal a host task  */
1549     base->CC_PC = CAU3_TASK_SHA1_INIT_STATE; /*  call cau_sha1_init_state()  */
1550     base->CC_CMD = taskDone;                 /*  trigger cau3 execution  */
1551 
1552     /*  process the cau3 task completion signal specified by taskDone  */
1553     completionStatus = cau3_process_task_completion(base, taskDone);
1554 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1555     cau3_release_semaphore(base);
1556 #endif
1557     return (completionStatus);
1558 }
1559 
1560 /*!
1561  * @brief   Perform a SHA-1 hash function over a message of "n" 64-byte blocks
1562  *
1563  * Perform a SHA-1 hash function over a message of "n" 64-byte data blocks,
1564  * returning an 8-word message digest (aka "state"). The input message must
1565  * be padded appropriately as defined by the SHA-1 algorithm.
1566  *
1567  * @param   message is the uint8_t input message, any alignment
1568  * @param   numberOfBlocks is the message length as multiple of 64-byte blocks
1569  * @param   sha1State is uint32_t message digest output (state) in BE format
1570  * @param   taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
1571  *
1572  * @retval  status check from task completion: CAU_[OK, ERROR]
1573  */
1574 
CAU3_Sha1Update(CAU3_Type * base,const uint8_t * message,uint32_t numberOfBlocks,uint32_t * sha1State,cau3_task_done_t taskDone)1575 static status_t CAU3_Sha1Update(
1576     CAU3_Type *base, const uint8_t *message, uint32_t numberOfBlocks, uint32_t *sha1State, cau3_task_done_t taskDone)
1577 {
1578     status_t completionStatus;
1579 
1580 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1581     completionStatus = cau3_lock_semaphore(base);
1582     if (kStatus_Success != completionStatus)
1583     {
1584         cau3_release_semaphore(base);
1585         return completionStatus;
1586     }
1587 #endif
1588 
1589     /*  execute the cau3 "sha1_update" task  */
1590     base->CC_R[27] = (uintptr_t)message;   /*  pMessage  */
1591     base->CC_R[28] = numberOfBlocks;       /*  n blocks  */
1592     base->CC_R[29] = (uintptr_t)sha1State; /*  output  */
1593     base->CC_R30 = CAU3_DMEM_STK_BASE;     /*  initialize stack pointer (sp)  */
1594     base->CC_R31 = 0U;                     /*  set LR = 0 to signal a host task  */
1595     base->CC_PC = CAU3_TASK_SHA1_HASH;     /*  call cau_sha1_hash_n()  */
1596     base->CC_CMD = taskDone;               /*  trigger cau3 execution  */
1597 
1598     /*  process the cau3 task completion signal specified by taskDone  */
1599     completionStatus = cau3_process_task_completion(base, taskDone);
1600 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1601     cau3_release_semaphore(base);
1602 #endif
1603     return (completionStatus);
1604 }
1605 
1606 /*!
1607  * @brief   Initialize message digest output state for SHA-256 hash
1608  *
1609  * Initializes the message digest output state for a SHA-256 hash.
1610  *
1611  * CAU3_Sha256InitializeOutput
1612  * @param   sha256State is message digest output in sysMemory in BE format
1613  * @param   taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
1614  *
1615  * @retval  status check from task completion: CAU_[OK, ERROR]
1616  */
1617 
CAU3_Sha256InitializeOutput(CAU3_Type * base,uint32_t * sha256State,cau3_task_done_t taskDone)1618 status_t CAU3_Sha256InitializeOutput(CAU3_Type *base, uint32_t *sha256State, cau3_task_done_t taskDone)
1619 {
1620     status_t completionStatus;
1621 
1622 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1623     completionStatus = cau3_lock_semaphore(base);
1624     if (kStatus_Success != completionStatus)
1625     {
1626         cau3_release_semaphore(base);
1627         return completionStatus;
1628     }
1629 #endif
1630 
1631     /* execute the cau3 "sha256_init_output" task */
1632     base->CC_R[29] = (uint32_t)sha256State;    /* pSha256State */
1633     base->CC_R30 = CAU3_DMEM_STK_BASE;         /* initialize stack pointer (sp) */
1634     base->CC_R31 = 0U;                         /* set LR = 0 to signal a host task */
1635     base->CC_PC = CAU3_TASK_SHA256_INIT_STATE; /* call cau_sha256_init_state() */
1636     base->CC_CMD = taskDone;                   /* trigger cau3 execution */
1637 
1638     /* process the cau3 task completion signal specified by taskDone */
1639     completionStatus = cau3_process_task_completion(base, taskDone);
1640 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1641     cau3_release_semaphore(base);
1642 #endif
1643     return (completionStatus);
1644 }
1645 
1646 /*!
1647  * @brief   Perform a SHA-256 hash function over a message of "n" 64-byte blocks
1648  *
1649  * Perform a SHA-256 hash function over a message of "n" 64-byte data blocks,
1650  * returning an 8-word message digest (aka "state"). The input message must
1651  * be padded appropriately as defined by the SHA-256 algorithm.
1652  *
1653  * CAU_Sha256Update
1654  * @param   message is the uint8_t input message, LE, ANY ALIGNMENT
1655  * @param   numberOfBlocks is the message length as multiple of 64-byte blocks
1656  * @param   sha256State is uint32_t message digest output (state) in BE format
1657  * @param   taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
1658  *
1659  * @retval  status check from task completion: CAU_[OK, ERROR]
1660  */
1661 
CAU3_Sha256Update(CAU3_Type * base,const uint8_t * message,uint32_t numberOfBlocks,uint32_t * sha256State,cau3_task_done_t taskDone)1662 status_t CAU3_Sha256Update(
1663     CAU3_Type *base, const uint8_t *message, uint32_t numberOfBlocks, uint32_t *sha256State, cau3_task_done_t taskDone)
1664 {
1665     status_t completionStatus;
1666 
1667 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1668     completionStatus = cau3_lock_semaphore(base);
1669     if (kStatus_Success != completionStatus)
1670     {
1671         cau3_release_semaphore(base);
1672         return completionStatus;
1673     }
1674 #endif
1675 
1676     /* execute the cau3 "sha256_update" task */
1677     base->CC_R[27] = (uint32_t)message;     /* pMessage */
1678     base->CC_R[28] = numberOfBlocks;        /* = (64*numberOfBlocks) bytes */
1679     base->CC_R[29] = (uint32_t)sha256State; /* pSha256State */
1680     base->CC_R30 = CAU3_DMEM_STK_BASE;      /* initialize stack pointer (sp) */
1681     base->CC_R31 = 0U;                      /* set LR = 0 to signal a host task */
1682     base->CC_PC = CAU3_TASK_SHA256_UPDATE;  /* call cau_sha256_update() */
1683     base->CC_CMD = taskDone;                /* trigger cau3 execution */
1684 
1685     /* process the cau3 task completion signal specified by taskDone */
1686     completionStatus = cau3_process_task_completion(base, taskDone);
1687 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1688     cau3_release_semaphore(base);
1689 #endif
1690     return (completionStatus);
1691 }
1692 
1693 /*!
1694  * @brief Initialize the SHA engine for new hash.
1695  *
1696  * This function sets NEW and MODE fields in SHA Control register to start new hash.
1697  *
1698  * @param base SHA peripheral base address.
1699  * @param ctxInternal Internal context.
1700  */
cau3_hash_engine_init(CAU3_Type * base,cau3_hash_ctx_internal_t * ctxInternal)1701 static status_t cau3_hash_engine_init(CAU3_Type *base, cau3_hash_ctx_internal_t *ctxInternal)
1702 {
1703     status_t status;
1704 
1705     status = kStatus_InvalidArgument;
1706 
1707     if (kCAU3_Sha256 == ctxInternal->algo)
1708     {
1709         status = CAU3_Sha256InitializeOutput(base, ctxInternal->runningHash, kCAU3_TaskDonePoll);
1710     }
1711 
1712     if (kCAU3_Sha1 == ctxInternal->algo)
1713     {
1714         status = CAU3_Sha1InitializeOutput(base, ctxInternal->runningHash, kCAU3_TaskDonePoll);
1715     }
1716 
1717     return status;
1718 }
1719 
1720 /*!
1721  * @brief Adds message to current hash.
1722  *
1723  * This function merges the message to fill the internal buffer, empties the internal buffer if
1724  * it becomes full, then process all remaining message data.
1725  *
1726  *
1727  * @param base CAU3 peripheral base address.
1728  * @param ctxInternal Internal context.
1729  * @param message Input message.
1730  * @param messageSize Size of input message in bytes.
1731  * @return kStatus_Success.
1732  */
cau3_hash_process_message_data(CAU3_Type * base,cau3_hash_ctx_internal_t * ctxInternal,const uint8_t * message,size_t messageSize)1733 static status_t cau3_hash_process_message_data(CAU3_Type *base,
1734                                                cau3_hash_ctx_internal_t *ctxInternal,
1735                                                const uint8_t *message,
1736                                                size_t messageSize)
1737 {
1738     status_t status;
1739     status_t (*funcUpdate)(CAU3_Type * cau3base, const uint8_t *msg, uint32_t numberOfBlocks, uint32_t *shaState,
1740                            cau3_task_done_t taskDone);
1741 
1742     /* first fill the internal buffer to full block */
1743     size_t toCopy = CAU3_HASH_BLOCK_SIZE - ctxInternal->blksz;
1744     cau3_memcpy(&ctxInternal->blk.b[ctxInternal->blksz], message, toCopy);
1745     message += toCopy;
1746     messageSize -= toCopy;
1747 
1748     status = kStatus_InvalidArgument;
1749     funcUpdate = NULL;
1750 
1751     switch (ctxInternal->algo)
1752     {
1753         case kCAU3_Sha256:
1754             funcUpdate = CAU3_Sha256Update;
1755             break;
1756 
1757         case kCAU3_Sha1:
1758             funcUpdate = CAU3_Sha1Update;
1759             break;
1760 
1761         default:
1762             break;
1763     }
1764 
1765     if (NULL != funcUpdate)
1766     {
1767         /* process full internal block */
1768         status = funcUpdate(base, &ctxInternal->blk.b[0], CAU3_HASH_BLOCK_SIZE / 64u, ctxInternal->runningHash,
1769                             kCAU3_TaskDonePoll);
1770         if (kStatus_Success != status)
1771         {
1772             return status;
1773         }
1774 
1775         /* process all full blocks in message[] */
1776         while (messageSize >= CAU3_HASH_BLOCK_SIZE)
1777         {
1778             status =
1779                 funcUpdate(base, message, CAU3_HASH_BLOCK_SIZE / 64u, ctxInternal->runningHash, kCAU3_TaskDonePoll);
1780             if (kStatus_Success != status)
1781             {
1782                 return status;
1783             }
1784             message += CAU3_HASH_BLOCK_SIZE;
1785             messageSize -= CAU3_HASH_BLOCK_SIZE;
1786         }
1787 
1788         /* copy last incomplete message bytes into internal block */
1789         cau3_memcpy(&ctxInternal->blk.b[0], message, messageSize);
1790         ctxInternal->blksz = messageSize;
1791     }
1792 
1793     return status;
1794 }
1795 
1796 /*!
1797  * @brief Finalize the running hash to make digest.
1798  *
1799  * This function empties the internal buffer, adds padding bits, and generates final digest.
1800  *
1801  * @param base SHA peripheral base address.
1802  * @param ctxInternal Internal context.
1803  * @return kStatus_Success.
1804  */
cau3_hash_finalize(CAU3_Type * base,cau3_hash_ctx_internal_t * ctxInternal)1805 static status_t cau3_hash_finalize(CAU3_Type *base, cau3_hash_ctx_internal_t *ctxInternal)
1806 {
1807     cau3_sha_block_t lastBlock;
1808     status_t status;
1809     status_t (*funcUpdate)(CAU3_Type * cau3base, const uint8_t *msg, uint32_t numberOfBlocks, uint32_t *shaState,
1810                            cau3_task_done_t taskDone);
1811 
1812     status = kStatus_InvalidArgument;
1813     funcUpdate = NULL;
1814 
1815     switch (ctxInternal->algo)
1816     {
1817         case kCAU3_Sha256:
1818             funcUpdate = CAU3_Sha256Update;
1819             break;
1820 
1821         case kCAU3_Sha1:
1822             funcUpdate = CAU3_Sha1Update;
1823             break;
1824 
1825         default:
1826             break;
1827     }
1828 
1829     if (NULL == funcUpdate)
1830     {
1831         return kStatus_InvalidArgument;
1832     }
1833 
1834     memset(&lastBlock, 0, sizeof(cau3_sha_block_t));
1835     status = kStatus_Success;
1836 
1837     while (ctxInternal->blksz >= 64u)
1838     {
1839         status = funcUpdate(base, &ctxInternal->blk.b[0], 1, ctxInternal->runningHash, kCAU3_TaskDonePoll);
1840         if (kStatus_Success != status)
1841         {
1842             return status;
1843         }
1844         ctxInternal->blksz -= 64u;
1845         cau3_memcpy(&ctxInternal->blk.b[0], &ctxInternal->blk.b[64], ctxInternal->blksz);
1846     }
1847 
1848     /* this is last call, so need to flush buffered message bytes along with padding */
1849     if (ctxInternal->blksz <= 55u)
1850     {
1851         /* last data is 440 bits or less. */
1852         cau3_memcpy(&lastBlock.b[0], &ctxInternal->blk.b[0], ctxInternal->blksz);
1853         lastBlock.b[ctxInternal->blksz] = (uint8_t)0x80U;
1854         lastBlock.w[15] = __REV(8u * ctxInternal->fullMessageSize);
1855         status = funcUpdate(base, &lastBlock.b[0], 1, ctxInternal->runningHash, kCAU3_TaskDonePoll);
1856         if (kStatus_Success != status)
1857         {
1858             return status;
1859         }
1860     }
1861     else
1862     {
1863         if (ctxInternal->blksz < 64u)
1864         {
1865             ctxInternal->blk.b[ctxInternal->blksz] = (uint8_t)0x80U;
1866             for (uint32_t i = ctxInternal->blksz + 1u; i < 64u; i++)
1867             {
1868                 ctxInternal->blk.b[i] = 0;
1869             }
1870         }
1871         else
1872         {
1873             lastBlock.b[0] = (uint8_t)0x80U;
1874         }
1875 
1876         status = funcUpdate(base, &ctxInternal->blk.b[0], 1, ctxInternal->runningHash, kCAU3_TaskDonePoll);
1877         if (kStatus_Success != status)
1878         {
1879             return status;
1880         }
1881         lastBlock.w[15] = __REV(8u * ctxInternal->fullMessageSize);
1882         status = funcUpdate(base, &lastBlock.b[0], 1, ctxInternal->runningHash, kCAU3_TaskDonePoll);
1883         if (kStatus_Success != status)
1884         {
1885             return status;
1886         }
1887     }
1888     return status;
1889 }
1890 
CAU3_HASH_Init(CAU3_Type * base,cau3_hash_ctx_t * ctx,cau3_hash_algo_t algo)1891 status_t CAU3_HASH_Init(CAU3_Type *base, cau3_hash_ctx_t *ctx, cau3_hash_algo_t algo)
1892 {
1893     status_t status;
1894 
1895     cau3_hash_ctx_internal_t *ctxInternal;
1896     /* compile time check for the correct structure size */
1897     BUILD_ASSURE(sizeof(cau3_hash_ctx_t) >= sizeof(cau3_hash_ctx_internal_t), cau3_hash_ctx_t_size);
1898     uint32_t i;
1899 
1900     status = cau3_hash_check_input_args(base, ctx, algo);
1901     if (status != kStatus_Success)
1902     {
1903         return status;
1904     }
1905 
1906     /* set algorithm in context struct for later use */
1907     ctxInternal = (cau3_hash_ctx_internal_t *)ctx;
1908     ctxInternal->algo = algo;
1909     ctxInternal->blksz = 0u;
1910     for (i = 0; i < sizeof(ctxInternal->blk.w) / sizeof(ctxInternal->blk.w[0]); i++)
1911     {
1912         ctxInternal->blk.w[0] = 0u;
1913     }
1914     ctxInternal->state = kCAU3_StateHashInit;
1915     ctxInternal->fullMessageSize = 0;
1916 
1917     return status;
1918 }
1919 
CAU3_HASH_Update(CAU3_Type * base,cau3_hash_ctx_t * ctx,const uint8_t * input,size_t inputSize)1920 status_t CAU3_HASH_Update(CAU3_Type *base, cau3_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize)
1921 {
1922     bool isUpdateState;
1923     status_t status;
1924     cau3_hash_ctx_internal_t *ctxInternal;
1925     size_t blockSize;
1926 
1927     if (inputSize == 0)
1928     {
1929         return kStatus_Success;
1930     }
1931 
1932     ctxInternal = (cau3_hash_ctx_internal_t *)ctx;
1933     status = cau3_hash_check_context(ctxInternal, input);
1934     if (kStatus_Success != status)
1935     {
1936         return status;
1937     }
1938 
1939     ctxInternal->fullMessageSize += inputSize;
1940     blockSize = CAU3_HASH_BLOCK_SIZE;
1941     /* if we are still less than CAU3_HASH_BLOCK_SIZE bytes, keep only in context */
1942     if ((ctxInternal->blksz + inputSize) <= blockSize)
1943     {
1944         cau3_memcpy((&ctxInternal->blk.b[0]) + ctxInternal->blksz, input, inputSize);
1945         ctxInternal->blksz += inputSize;
1946         return status;
1947     }
1948     else
1949     {
1950         isUpdateState = ctxInternal->state == kCAU3_StateHashUpdate;
1951         if (!isUpdateState)
1952         {
1953             /* start NEW hash */
1954             status = cau3_hash_engine_init(base, ctxInternal);
1955             if (status != kStatus_Success)
1956             {
1957                 return status;
1958             }
1959             ctxInternal->state = kCAU3_StateHashUpdate;
1960         }
1961     }
1962 
1963     /* process input data */
1964     status = cau3_hash_process_message_data(base, ctxInternal, input, inputSize);
1965     return status;
1966 }
1967 
CAU3_HASH_Finish(CAU3_Type * base,cau3_hash_ctx_t * ctx,uint8_t * output,size_t * outputSize)1968 status_t CAU3_HASH_Finish(CAU3_Type *base, cau3_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize)
1969 {
1970     size_t algOutSize = 0;
1971     status_t status;
1972     cau3_hash_ctx_internal_t *ctxInternal;
1973 
1974     ctxInternal = (cau3_hash_ctx_internal_t *)ctx;
1975     status = cau3_hash_check_context(ctxInternal, output);
1976     if (kStatus_Success != status)
1977     {
1978         return status;
1979     }
1980 
1981     if (ctxInternal->state == kCAU3_StateHashInit)
1982     {
1983         status = cau3_hash_engine_init(base, ctxInternal);
1984         if (status != kStatus_Success)
1985         {
1986             return status;
1987         }
1988     }
1989 
1990     size_t outSize = 0u;
1991 
1992     /* compute algorithm output length */
1993     switch (ctxInternal->algo)
1994     {
1995         case kCAU3_Sha256:
1996             outSize = kCAU3_OutLenSha256;
1997             break;
1998         case kCAU3_Sha1:
1999             outSize = kCAU3_OutLenSha1;
2000             break;
2001         default:
2002             break;
2003     }
2004     algOutSize = outSize;
2005 
2006     /* flush message last incomplete block, if there is any, and add padding bits */
2007     status = cau3_hash_finalize(base, ctxInternal);
2008 
2009     if (outputSize)
2010     {
2011         if (algOutSize < *outputSize)
2012         {
2013             *outputSize = algOutSize;
2014         }
2015         else
2016         {
2017             algOutSize = *outputSize;
2018         }
2019     }
2020 
2021     cau3_memcpy(&output[0], ctxInternal->runningHash, algOutSize);
2022 
2023     memset(ctx, 0, sizeof(cau3_hash_ctx_t));
2024     return status;
2025 }
2026 
CAU3_HASH(CAU3_Type * base,cau3_hash_algo_t algo,const uint8_t * input,size_t inputSize,uint8_t * output,size_t * outputSize)2027 status_t CAU3_HASH(
2028     CAU3_Type *base, cau3_hash_algo_t algo, const uint8_t *input, size_t inputSize, uint8_t *output, size_t *outputSize)
2029 {
2030     cau3_hash_ctx_t hashCtx;
2031     status_t status;
2032 
2033     status = CAU3_HASH_Init(base, &hashCtx, algo);
2034     if (status != kStatus_Success)
2035     {
2036         return status;
2037     }
2038 
2039     status = CAU3_HASH_Update(base, &hashCtx, input, inputSize);
2040     if (status != kStatus_Success)
2041     {
2042         return status;
2043     }
2044 
2045     status = CAU3_HASH_Finish(base, &hashCtx, output, outputSize);
2046 
2047     return status;
2048 }
2049 
2050 /*! @brief CAU3 driver wait mechanism. */
cau3_wait(CAU3_Type * base)2051 status_t cau3_wait(CAU3_Type *base)
2052 {
2053     status_t status;
2054 
2055     bool error = false;
2056     bool done = false;
2057 
2058     /* Wait for 'done' or 'error' flag. */
2059     while ((!error) && (!done))
2060     {
2061         uint32_t temp32 = base->STA;
2062         error = temp32 & kCAU3_StatusErrorIsr;
2063         done = temp32 & kCAU3_StatusDoneIsr;
2064     }
2065 
2066     if (error)
2067     {
2068         base->COM = CAU3_COM_ALL_MASK; /* Reset all engine to clear the error flag */
2069         status = kStatus_Fail;
2070     }
2071     else /* 'done' */
2072     {
2073         status = kStatus_Success;
2074 
2075         base->CW = kCAU3_ClearDataSize;
2076         /* Clear 'done' interrupt status.  This also clears the mode register. */
2077         base->STA = kCAU3_StatusDoneIsr;
2078     }
2079 
2080     return status;
2081 }
2082 
2083 /*!
2084  * @brief Clears the CAU3 module.
2085  * This function can be used to clear all sensitive data from theCAU3 module, such as private keys. It is called
2086  * internally by the CAU3 driver in case of an error or operation complete.
2087  * @param base CAU3 peripheral base address
2088  * @param pkha Include CAU3 PKHA register clear. If there is no PKHA, the argument is ignored.
2089  */
cau3_clear_all(CAU3_Type * base,bool addPKHA)2090 void cau3_clear_all(CAU3_Type *base, bool addPKHA)
2091 {
2092     base->CW = (uint32_t)kCAU3_ClearAll;
2093     if (addPKHA)
2094     {
2095         cau3_pkha_clear_regabne(base, true, true, true, true);
2096     }
2097 }
2098 
2099 /*!
2100  * @brief Reads an unaligned word.
2101  *
2102  * This function creates a 32-bit word from an input array of four bytes.
2103  *
2104  * @param src Input array of four bytes. The array can start at any address in memory.
2105  * @return 32-bit unsigned int created from the input byte array.
2106  */
cau3_get_word_from_unaligned(const uint8_t * srcAddr)2107 static inline uint32_t cau3_get_word_from_unaligned(const uint8_t *srcAddr)
2108 {
2109 #if (!(defined(__CORTEX_M)) || (defined(__CORTEX_M) && (__CORTEX_M == 0)))
2110     register const uint8_t *src = srcAddr;
2111     /* Cortex M0 does not support misaligned loads */
2112     if ((uint32_t)src & 0x3u)
2113     {
2114         union _align_bytes_t {
2115             uint32_t word;
2116             uint8_t byte[sizeof(uint32_t)];
2117         } my_bytes;
2118 
2119         my_bytes.byte[0] = *src;
2120         my_bytes.byte[1] = *(src + 1);
2121         my_bytes.byte[2] = *(src + 2);
2122         my_bytes.byte[3] = *(src + 3);
2123         return my_bytes.word;
2124     }
2125     else
2126     {
2127         /* addr aligned to 0-modulo-4 so it is safe to type cast */
2128         return *((const uint32_t *)src);
2129     }
2130 #elif defined(__CC_ARM)
2131     /* -O3 optimization in Keil Compiler 5 uses LDM instruction here (LDM r4!, {r0})
2132      *    which is wrong, because srcAddr might be unaligned.
2133      *    LDM on unaligned address causes hard-fault. so use memcpy() */
2134     uint32_t ret;
2135     memcpy(&ret, srcAddr, sizeof(uint32_t));
2136     return ret;
2137 #else
2138     return *((const uint32_t *)srcAddr);
2139 #endif
2140 }
2141 
2142 /*******************************************************************************
2143  * PKHA Code static
2144  ******************************************************************************/
2145 
cau3_pkha_clear_regabne(CAU3_Type * base,bool A,bool B,bool N,bool E)2146 static status_t cau3_pkha_clear_regabne(CAU3_Type *base, bool A, bool B, bool N, bool E)
2147 {
2148     cau3_mode_t mode;
2149 
2150     /* Set the PKHA algorithm and the appropriate function. */
2151     mode = (uint32_t)kCAU3_AlgorithmPKHA | 1U;
2152 
2153     /* Set ram area to clear. Clear all. */
2154     if (A)
2155     {
2156         mode |= 1U << 19U;
2157     }
2158     if (B)
2159     {
2160         mode |= 1U << 18U;
2161     }
2162     if (N)
2163     {
2164         mode |= 1U << 16U;
2165     }
2166     if (E)
2167     {
2168         mode |= 1U << 17U;
2169     }
2170 
2171     /* Write the mode register to the hardware.
2172      * NOTE: This will begin the operation. */
2173     base->MDPK = mode;
2174 
2175     /* Wait for 'done' */
2176     return cau3_wait(base);
2177 }
2178 
cau3_pkha_default_parms(cau3_pkha_mode_params_t * params)2179 static void cau3_pkha_default_parms(cau3_pkha_mode_params_t *params)
2180 {
2181     params->func = (cau3_pkha_func_t)0;
2182     params->arithType = kCAU3_PKHA_IntegerArith;
2183     params->montFormIn = kCAU3_PKHA_NormalValue;
2184     params->montFormOut = kCAU3_PKHA_NormalValue;
2185     params->srcReg = kCAU3_PKHA_RegAll;
2186     params->srcQuad = kCAU3_PKHA_Quad0;
2187     params->dstReg = kCAU3_PKHA_RegAll;
2188     params->dstQuad = kCAU3_PKHA_Quad0;
2189     params->equalTime = kCAU3_PKHA_NoTimingEqualized;
2190     params->r2modn = kCAU3_PKHA_CalcR2;
2191 }
2192 
cau3_pkha_write_word(CAU3_Type * base,cau3_pkha_reg_area_t reg,uint8_t index,uint32_t data)2193 static void cau3_pkha_write_word(CAU3_Type *base, cau3_pkha_reg_area_t reg, uint8_t index, uint32_t data)
2194 {
2195     __IO uint32_t *pka = base->PKA0;
2196     __IO uint32_t *pkb = base->PKB0;
2197     __IO uint32_t *pkn = base->PKN0;
2198 
2199     switch (reg)
2200     {
2201         case kCAU3_PKHA_RegA:
2202             pka[index] = data;
2203             break;
2204 
2205         case kCAU3_PKHA_RegB:
2206             pkb[index] = data;
2207             break;
2208 
2209         case kCAU3_PKHA_RegN:
2210             pkn[index] = data;
2211             break;
2212 
2213         case kCAU3_PKHA_RegE:
2214             base->PKE[index] = data;
2215             break;
2216 
2217         default:
2218             break;
2219     }
2220 }
2221 
cau3_pkha_read_word(CAU3_Type * base,cau3_pkha_reg_area_t reg,uint8_t index)2222 static uint32_t cau3_pkha_read_word(CAU3_Type *base, cau3_pkha_reg_area_t reg, uint8_t index)
2223 {
2224     uint32_t retval;
2225     __IO uint32_t *pka = base->PKA0;
2226     __IO uint32_t *pkb = base->PKB0;
2227     __IO uint32_t *pkn = base->PKN0;
2228 
2229     switch (reg)
2230     {
2231         case kCAU3_PKHA_RegA:
2232             retval = pka[index];
2233             break;
2234 
2235         case kCAU3_PKHA_RegB:
2236             retval = pkb[index];
2237             break;
2238 
2239         case kCAU3_PKHA_RegN:
2240             retval = pkn[index];
2241             break;
2242 
2243         default:
2244             retval = 0;
2245             break;
2246     }
2247     return retval;
2248 }
2249 
cau3_pkha_write_reg(CAU3_Type * base,cau3_pkha_reg_area_t reg,uint8_t quad,const uint8_t * data,size_t dataSize)2250 static status_t cau3_pkha_write_reg(
2251     CAU3_Type *base, cau3_pkha_reg_area_t reg, uint8_t quad, const uint8_t *data, size_t dataSize)
2252 {
2253     /* Select the word-based start index for each quadrant of 128 bytes. */
2254     uint8_t startIndex = (quad * 32u);
2255     uint32_t outWord;
2256 
2257     while (dataSize > 0)
2258     {
2259         if (dataSize >= sizeof(uint32_t))
2260         {
2261             cau3_pkha_write_word(base, reg, startIndex++, cau3_get_word_from_unaligned(data));
2262             dataSize -= sizeof(uint32_t);
2263             data += sizeof(uint32_t);
2264         }
2265         else /* (dataSize > 0) && (dataSize < 4) */
2266         {
2267             outWord = 0;
2268             cau3_memcpy(&outWord, data, dataSize);
2269             cau3_pkha_write_word(base, reg, startIndex, outWord);
2270             dataSize = 0;
2271         }
2272     }
2273 
2274     return kStatus_Success;
2275 }
2276 
cau3_pkha_read_reg(CAU3_Type * base,cau3_pkha_reg_area_t reg,uint8_t quad,uint8_t * data,size_t dataSize)2277 static void cau3_pkha_read_reg(CAU3_Type *base, cau3_pkha_reg_area_t reg, uint8_t quad, uint8_t *data, size_t dataSize)
2278 {
2279     /* Select the word-based start index for each quadrant of 128 bytes. */
2280     uint8_t startIndex = (quad * 32u);
2281     size_t calcSize;
2282     uint32_t word;
2283 
2284     while (dataSize > 0)
2285     {
2286         word = cau3_pkha_read_word(base, reg, startIndex++);
2287 
2288         calcSize = (dataSize >= sizeof(uint32_t)) ? sizeof(uint32_t) : dataSize;
2289         cau3_memcpy(data, &word, calcSize);
2290 
2291         data += calcSize;
2292         dataSize -= calcSize;
2293     }
2294 }
2295 
cau3_pkha_init_data(CAU3_Type * base,const uint8_t * A,size_t sizeA,const uint8_t * B,size_t sizeB,const uint8_t * N,size_t sizeN,const uint8_t * E,size_t sizeE)2296 static void cau3_pkha_init_data(CAU3_Type *base,
2297                                 const uint8_t *A,
2298                                 size_t sizeA,
2299                                 const uint8_t *B,
2300                                 size_t sizeB,
2301                                 const uint8_t *N,
2302                                 size_t sizeN,
2303                                 const uint8_t *E,
2304                                 size_t sizeE)
2305 {
2306     uint32_t clearMask = kCAU3_ClearMode; /* clear Mode Register */
2307 
2308     /* Clear internal register states. */
2309     if (sizeA)
2310     {
2311         clearMask |= kCAU3_ClearPkhaSizeA;
2312     }
2313     if (sizeB)
2314     {
2315         clearMask |= kCAU3_ClearPkhaSizeB;
2316     }
2317     if (sizeN)
2318     {
2319         clearMask |= kCAU3_ClearPkhaSizeN;
2320     }
2321     if (sizeE)
2322     {
2323         clearMask |= kCAU3_ClearPkhaSizeE;
2324     }
2325 
2326     base->CW = clearMask;
2327     base->STA = kCAU3_StatusDoneIsr;
2328     cau3_pkha_clear_regabne(base, A, B, N, E);
2329 
2330     /* Write register sizes. */
2331     /* Write modulus (N) and A and B register arguments. */
2332     if (sizeN)
2333     {
2334         base->PKNSZ = sizeN;
2335         if (N)
2336         {
2337             cau3_pkha_write_reg(base, kCAU3_PKHA_RegN, 0, N, sizeN);
2338         }
2339     }
2340 
2341     if (sizeA)
2342     {
2343         base->PKASZ = sizeA;
2344         if (A)
2345         {
2346             cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 0, A, sizeA);
2347         }
2348     }
2349 
2350     if (sizeB)
2351     {
2352         base->PKBSZ = sizeB;
2353         if (B)
2354         {
2355             cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 0, B, sizeB);
2356         }
2357     }
2358 
2359     if (sizeE)
2360     {
2361         base->PKESZ = sizeE;
2362         if (E)
2363         {
2364             cau3_pkha_write_reg(base, kCAU3_PKHA_RegE, 0, E, sizeE);
2365         }
2366     }
2367 }
2368 
cau3_pkha_mode_set_src_reg_copy(cau3_mode_t * outMode,cau3_pkha_reg_area_t reg)2369 static void cau3_pkha_mode_set_src_reg_copy(cau3_mode_t *outMode, cau3_pkha_reg_area_t reg)
2370 {
2371     int i = 0;
2372 
2373     do
2374     {
2375         reg = (cau3_pkha_reg_area_t)(((uint32_t)reg) >> 1u);
2376         i++;
2377     } while (reg);
2378 
2379     i = 4 - i;
2380     /* Source register must not be E. */
2381     if (i != 2)
2382     {
2383         *outMode |= ((uint32_t)i << 17u);
2384     }
2385 }
2386 
cau3_pkha_mode_set_dst_reg_copy(cau3_mode_t * outMode,cau3_pkha_reg_area_t reg)2387 static void cau3_pkha_mode_set_dst_reg_copy(cau3_mode_t *outMode, cau3_pkha_reg_area_t reg)
2388 {
2389     int i = 0;
2390 
2391     do
2392     {
2393         reg = (cau3_pkha_reg_area_t)(((uint32_t)reg) >> 1u);
2394         i++;
2395     } while (reg);
2396 
2397     i = 4 - i;
2398     *outMode |= ((uint32_t)i << 10u);
2399 }
2400 
cau3_pkha_mode_set_src_seg_copy(cau3_mode_t * outMode,const cau3_pkha_quad_area_t quad)2401 static void cau3_pkha_mode_set_src_seg_copy(cau3_mode_t *outMode, const cau3_pkha_quad_area_t quad)
2402 {
2403     *outMode |= ((uint32_t)quad << 8u);
2404 }
2405 
cau3_pkha_mode_set_dst_seg_copy(cau3_mode_t * outMode,const cau3_pkha_quad_area_t quad)2406 static void cau3_pkha_mode_set_dst_seg_copy(cau3_mode_t *outMode, const cau3_pkha_quad_area_t quad)
2407 {
2408     *outMode |= ((uint32_t)quad << 6u);
2409 }
2410 
2411 /*!
2412  * @brief Starts the PKHA operation.
2413  *
2414  * This function starts an operation configured by the params parameter.
2415  *
2416  * @param base CAU3 peripheral base address
2417  * @param params Configuration structure containing all settings required for PKHA operation.
2418  */
cau3_pkha_init_mode(CAU3_Type * base,const cau3_pkha_mode_params_t * params)2419 static status_t cau3_pkha_init_mode(CAU3_Type *base, const cau3_pkha_mode_params_t *params)
2420 {
2421     cau3_mode_t modeReg;
2422     status_t retval;
2423 
2424     /* Set the PKHA algorithm and the appropriate function. */
2425     modeReg = kCAU3_AlgorithmPKHA;
2426     modeReg |= (uint32_t)params->func;
2427 
2428     if ((params->func == kCAU3_PKHA_CopyMemSizeN) || (params->func == kCAU3_PKHA_CopyMemSizeSrc))
2429     {
2430         /* Set source and destination registers and quads. */
2431         cau3_pkha_mode_set_src_reg_copy(&modeReg, params->srcReg);
2432         cau3_pkha_mode_set_dst_reg_copy(&modeReg, params->dstReg);
2433         cau3_pkha_mode_set_src_seg_copy(&modeReg, params->srcQuad);
2434         cau3_pkha_mode_set_dst_seg_copy(&modeReg, params->dstQuad);
2435     }
2436     else
2437     {
2438         /* Set the arithmetic type - integer or binary polynomial (F2m). */
2439         modeReg |= ((uint32_t)params->arithType << 17u);
2440 
2441         /* Set to use Montgomery form of inputs and/or outputs. */
2442         modeReg |= ((uint32_t)params->montFormIn << 19u);
2443         modeReg |= ((uint32_t)params->montFormOut << 18u);
2444 
2445         /* Set to use pre-computed R2modN */
2446         modeReg |= ((uint32_t)params->r2modn << 16u);
2447     }
2448 
2449     modeReg |= ((uint32_t)params->equalTime << 10u);
2450 
2451     /* Write the mode register to the hardware.
2452      * NOTE: This will begin the operation. */
2453     base->MDPK = modeReg;
2454 
2455     retval = cau3_wait(base);
2456     return (retval);
2457 }
2458 
cau3_pkha_modR2(CAU3_Type * base,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,cau3_pkha_f2m_t arithType)2459 static status_t cau3_pkha_modR2(
2460     CAU3_Type *base, const uint8_t *N, size_t sizeN, uint8_t *result, size_t *resultSize, cau3_pkha_f2m_t arithType)
2461 {
2462     status_t status;
2463     cau3_pkha_mode_params_t params;
2464 
2465     cau3_pkha_default_parms(&params);
2466     params.func = kCAU3_PKHA_ArithModR2;
2467     params.arithType = arithType;
2468 
2469     cau3_pkha_init_data(base, NULL, 0, NULL, 0, N, sizeN, NULL, 0);
2470     status = cau3_pkha_init_mode(base, &params);
2471 
2472     if (status == kStatus_Success)
2473     {
2474         /* Read the result and size from register B0. */
2475         if (resultSize && result)
2476         {
2477             *resultSize = base->PKBSZ;
2478             /* Read the data from the result register into place. */
2479             cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
2480         }
2481     }
2482 
2483     return status;
2484 }
2485 
cau3_pkha_modmul(CAU3_Type * base,const uint8_t * A,size_t sizeA,const uint8_t * B,size_t sizeB,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,cau3_pkha_f2m_t arithType,cau3_pkha_montgomery_form_t montIn,cau3_pkha_montgomery_form_t montOut,cau3_pkha_timing_t equalTime)2486 static status_t cau3_pkha_modmul(CAU3_Type *base,
2487                                  const uint8_t *A,
2488                                  size_t sizeA,
2489                                  const uint8_t *B,
2490                                  size_t sizeB,
2491                                  const uint8_t *N,
2492                                  size_t sizeN,
2493                                  uint8_t *result,
2494                                  size_t *resultSize,
2495                                  cau3_pkha_f2m_t arithType,
2496                                  cau3_pkha_montgomery_form_t montIn,
2497                                  cau3_pkha_montgomery_form_t montOut,
2498                                  cau3_pkha_timing_t equalTime)
2499 {
2500     cau3_pkha_mode_params_t params;
2501     status_t status;
2502 
2503     if (arithType == kCAU3_PKHA_IntegerArith)
2504     {
2505         if (CAU3_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
2506         {
2507             return (kStatus_InvalidArgument);
2508         }
2509 
2510         if (CAU3_PKHA_CompareBigNum(B, sizeB, N, sizeN) >= 0)
2511         {
2512             return (kStatus_InvalidArgument);
2513         }
2514     }
2515 
2516     cau3_pkha_default_parms(&params);
2517     params.func = kCAU3_PKHA_ArithModMul;
2518     params.arithType = arithType;
2519     params.montFormIn = montIn;
2520     params.montFormOut = montOut;
2521     params.equalTime = equalTime;
2522 
2523     cau3_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0);
2524     status = cau3_pkha_init_mode(base, &params);
2525 
2526     if (status == kStatus_Success)
2527     {
2528         /* Read the result and size from register B0. */
2529         if (resultSize && result)
2530         {
2531             *resultSize = base->PKBSZ;
2532             /* Read the data from the result register into place. */
2533             cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
2534         }
2535     }
2536 
2537     return status;
2538 }
2539 
2540 /*******************************************************************************
2541  * PKHA Code public
2542  ******************************************************************************/
CAU3_PKHA_CompareBigNum(const uint8_t * a,size_t sizeA,const uint8_t * b,size_t sizeB)2543 int CAU3_PKHA_CompareBigNum(const uint8_t *a, size_t sizeA, const uint8_t *b, size_t sizeB)
2544 {
2545     int retval = 0;
2546 
2547     /* skip zero msbytes - integer a */
2548     while ((sizeA) && (0u == a[sizeA - 1]))
2549     {
2550         sizeA--;
2551     }
2552 
2553     /* skip zero msbytes - integer b */
2554     while ((sizeB) && (0u == b[sizeB - 1]))
2555     {
2556         sizeB--;
2557     }
2558 
2559     if (sizeA > sizeB)
2560     {
2561         retval = 1;
2562     } /* int a has more non-zero bytes, thus it is bigger than b */
2563     else if (sizeA < sizeB)
2564     {
2565         retval = -1;
2566     } /* int b has more non-zero bytes, thus it is bigger than a */
2567     else if (sizeA == 0)
2568     {
2569         retval = 0;
2570     } /* sizeA = sizeB = 0 */
2571     else
2572     {
2573         int n;
2574         int i;
2575         int val;
2576         uint32_t equal;
2577 
2578         n = sizeA - 1;
2579         i = 0;
2580         equal = 0;
2581 
2582         while (n >= 0)
2583         {
2584             uint32_t chXor = a[i] ^ b[i];
2585 
2586             equal |= chXor;
2587             val = (int)chXor * (a[i] - b[i]);
2588 
2589             if (val < 0)
2590             {
2591                 retval = -1;
2592             }
2593 
2594             if (val > 0)
2595             {
2596                 retval = 1;
2597             }
2598 
2599             if (val == 0)
2600             {
2601                 val = 1;
2602             }
2603 
2604             if (val)
2605             {
2606                 i++;
2607                 n--;
2608             }
2609         }
2610 
2611         if (0 == equal)
2612         {
2613             retval = 0;
2614         }
2615     }
2616     return (retval);
2617 }
2618 
CAU3_PKHA_NormalToMontgomery(CAU3_Type * base,const uint8_t * N,size_t sizeN,uint8_t * A,size_t * sizeA,uint8_t * B,size_t * sizeB,uint8_t * R2,size_t * sizeR2,cau3_pkha_timing_t equalTime,cau3_pkha_f2m_t arithType)2619 status_t CAU3_PKHA_NormalToMontgomery(CAU3_Type *base,
2620                                       const uint8_t *N,
2621                                       size_t sizeN,
2622                                       uint8_t *A,
2623                                       size_t *sizeA,
2624                                       uint8_t *B,
2625                                       size_t *sizeB,
2626                                       uint8_t *R2,
2627                                       size_t *sizeR2,
2628                                       cau3_pkha_timing_t equalTime,
2629                                       cau3_pkha_f2m_t arithType)
2630 {
2631     status_t status;
2632 
2633 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2634     status = cau3_lock_semaphore(base);
2635     if (kStatus_Success != status)
2636     {
2637         cau3_release_semaphore(base);
2638         return status;
2639     }
2640 #endif
2641 
2642     /* need to convert our Integer inputs into Montgomery format */
2643     if (N && sizeN && R2 && sizeR2)
2644     {
2645         /* 1. R2 = MOD_R2(N) */
2646         status = cau3_pkha_modR2(base, N, sizeN, R2, sizeR2, arithType);
2647         if (status != kStatus_Success)
2648         {
2649 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2650             cau3_release_semaphore(base);
2651 #endif
2652             return status;
2653         }
2654 
2655         /* 2. A(Montgomery) = MOD_MUL_IM_OM(A, R2, N) */
2656         if (A && sizeA)
2657         {
2658             status = cau3_pkha_modmul(base, A, *sizeA, R2, *sizeR2, N, sizeN, A, sizeA, arithType,
2659                                       kCAU3_PKHA_MontgomeryFormat, kCAU3_PKHA_MontgomeryFormat, equalTime);
2660             if (status != kStatus_Success)
2661             {
2662 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2663                 cau3_release_semaphore(base);
2664 #endif
2665                 return status;
2666             }
2667         }
2668 
2669         /* 2. B(Montgomery) = MOD_MUL_IM_OM(B, R2, N) */
2670         if (B && sizeB)
2671         {
2672             status = cau3_pkha_modmul(base, B, *sizeB, R2, *sizeR2, N, sizeN, B, sizeB, arithType,
2673                                       kCAU3_PKHA_MontgomeryFormat, kCAU3_PKHA_MontgomeryFormat, equalTime);
2674             if (status != kStatus_Success)
2675             {
2676 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2677                 cau3_release_semaphore(base);
2678 #endif
2679                 return status;
2680             }
2681         }
2682 
2683         cau3_clear_all(base, true);
2684     }
2685     else
2686     {
2687         status = kStatus_InvalidArgument;
2688     }
2689 
2690 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2691     cau3_release_semaphore(base);
2692 #endif
2693     return status;
2694 }
2695 
CAU3_PKHA_MontgomeryToNormal(CAU3_Type * base,const uint8_t * N,size_t sizeN,uint8_t * A,size_t * sizeA,uint8_t * B,size_t * sizeB,cau3_pkha_timing_t equalTime,cau3_pkha_f2m_t arithType)2696 status_t CAU3_PKHA_MontgomeryToNormal(CAU3_Type *base,
2697                                       const uint8_t *N,
2698                                       size_t sizeN,
2699                                       uint8_t *A,
2700                                       size_t *sizeA,
2701                                       uint8_t *B,
2702                                       size_t *sizeB,
2703                                       cau3_pkha_timing_t equalTime,
2704                                       cau3_pkha_f2m_t arithType)
2705 {
2706     uint8_t one = 1;
2707     status_t status = kStatus_InvalidArgument;
2708 
2709 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2710     status = cau3_lock_semaphore(base);
2711     if (kStatus_Success != status)
2712     {
2713         cau3_release_semaphore(base);
2714         return status;
2715     }
2716 #endif
2717 
2718     /* A = MOD_MUL_IM_OM(A(Montgomery), 1, N) */
2719     if (A && sizeA)
2720     {
2721         status = cau3_pkha_modmul(base, A, *sizeA, &one, sizeof(one), N, sizeN, A, sizeA, arithType,
2722                                   kCAU3_PKHA_MontgomeryFormat, kCAU3_PKHA_MontgomeryFormat, equalTime);
2723         if (kStatus_Success != status)
2724         {
2725 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2726             cau3_release_semaphore(base);
2727 #endif
2728             return status;
2729         }
2730     }
2731 
2732     /* B = MOD_MUL_IM_OM(B(Montgomery), 1, N) */
2733     if (B && sizeB)
2734     {
2735         status = cau3_pkha_modmul(base, B, *sizeB, &one, sizeof(one), N, sizeN, B, sizeB, arithType,
2736                                   kCAU3_PKHA_MontgomeryFormat, kCAU3_PKHA_MontgomeryFormat, equalTime);
2737         if (kStatus_Success != status)
2738         {
2739 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2740             cau3_release_semaphore(base);
2741 #endif
2742             return status;
2743         }
2744     }
2745 
2746     cau3_clear_all(base, true);
2747 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2748     cau3_release_semaphore(base);
2749 #endif
2750     return status;
2751 }
2752 
CAU3_PKHA_ModAdd(CAU3_Type * base,const uint8_t * A,size_t sizeA,const uint8_t * B,size_t sizeB,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,cau3_pkha_f2m_t arithType)2753 status_t CAU3_PKHA_ModAdd(CAU3_Type *base,
2754                           const uint8_t *A,
2755                           size_t sizeA,
2756                           const uint8_t *B,
2757                           size_t sizeB,
2758                           const uint8_t *N,
2759                           size_t sizeN,
2760                           uint8_t *result,
2761                           size_t *resultSize,
2762                           cau3_pkha_f2m_t arithType)
2763 {
2764     cau3_pkha_mode_params_t params;
2765     status_t status;
2766 
2767     if (arithType == kCAU3_PKHA_IntegerArith)
2768     {
2769         if (CAU3_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
2770         {
2771             return (kStatus_InvalidArgument);
2772         }
2773 
2774         if (CAU3_PKHA_CompareBigNum(B, sizeB, N, sizeN) >= 0)
2775         {
2776             return (kStatus_InvalidArgument);
2777         }
2778     }
2779 
2780 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2781     status = cau3_lock_semaphore(base);
2782     if (kStatus_Success != status)
2783     {
2784         cau3_release_semaphore(base);
2785         return status;
2786     }
2787 #endif
2788 
2789     cau3_pkha_default_parms(&params);
2790     params.func = kCAU3_PKHA_ArithModAdd;
2791     params.arithType = arithType;
2792 
2793     cau3_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0);
2794     status = cau3_pkha_init_mode(base, &params);
2795 
2796     if (status == kStatus_Success)
2797     {
2798         /* Read the result and size from register B0. */
2799         if (resultSize && result)
2800         {
2801             *resultSize = base->PKBSZ;
2802             /* Read the data from the result register into place. */
2803             cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
2804         }
2805     }
2806 
2807     cau3_clear_all(base, true);
2808 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2809     cau3_release_semaphore(base);
2810 #endif
2811     return status;
2812 }
2813 
CAU3_PKHA_ModSub1(CAU3_Type * base,const uint8_t * A,size_t sizeA,const uint8_t * B,size_t sizeB,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize)2814 status_t CAU3_PKHA_ModSub1(CAU3_Type *base,
2815                            const uint8_t *A,
2816                            size_t sizeA,
2817                            const uint8_t *B,
2818                            size_t sizeB,
2819                            const uint8_t *N,
2820                            size_t sizeN,
2821                            uint8_t *result,
2822                            size_t *resultSize)
2823 {
2824     cau3_pkha_mode_params_t params;
2825     status_t status;
2826 
2827     if (CAU3_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
2828     {
2829         return (kStatus_InvalidArgument);
2830     }
2831 
2832     if (CAU3_PKHA_CompareBigNum(B, sizeB, N, sizeN) >= 0)
2833     {
2834         return (kStatus_InvalidArgument);
2835     }
2836 
2837 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2838     status = cau3_lock_semaphore(base);
2839     if (kStatus_Success != status)
2840     {
2841         cau3_release_semaphore(base);
2842         return status;
2843     }
2844 #endif
2845 
2846     cau3_pkha_default_parms(&params);
2847     params.func = kCAU3_PKHA_ArithModSub1;
2848     cau3_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0);
2849 
2850     status = cau3_pkha_init_mode(base, &params);
2851 
2852     if (status == kStatus_Success)
2853     {
2854         /* Read the result and size from register B0. */
2855         if (resultSize && result)
2856         {
2857             *resultSize = base->PKBSZ;
2858             /* Read the data from the result register into place. */
2859             cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
2860         }
2861     }
2862 
2863     cau3_clear_all(base, true);
2864 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2865     cau3_release_semaphore(base);
2866 #endif
2867     return status;
2868 }
2869 
CAU3_PKHA_ModSub2(CAU3_Type * base,const uint8_t * A,size_t sizeA,const uint8_t * B,size_t sizeB,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize)2870 status_t CAU3_PKHA_ModSub2(CAU3_Type *base,
2871                            const uint8_t *A,
2872                            size_t sizeA,
2873                            const uint8_t *B,
2874                            size_t sizeB,
2875                            const uint8_t *N,
2876                            size_t sizeN,
2877                            uint8_t *result,
2878                            size_t *resultSize)
2879 {
2880     cau3_pkha_mode_params_t params;
2881     status_t status;
2882 
2883 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2884     status = cau3_lock_semaphore(base);
2885     if (kStatus_Success != status)
2886     {
2887         cau3_release_semaphore(base);
2888         return status;
2889     }
2890 #endif
2891 
2892     cau3_pkha_default_parms(&params);
2893     params.func = kCAU3_PKHA_ArithModSub2;
2894 
2895     cau3_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0);
2896     status = cau3_pkha_init_mode(base, &params);
2897 
2898     if (status == kStatus_Success)
2899     {
2900         /* Read the result and size from register B0. */
2901         if (resultSize && result)
2902         {
2903             *resultSize = base->PKBSZ;
2904             /* Read the data from the result register into place. */
2905             cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
2906         }
2907     }
2908 
2909     cau3_clear_all(base, true);
2910 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2911     cau3_release_semaphore(base);
2912 #endif
2913     return status;
2914 }
2915 
CAU3_PKHA_ModMul(CAU3_Type * base,const uint8_t * A,size_t sizeA,const uint8_t * B,size_t sizeB,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,cau3_pkha_f2m_t arithType,cau3_pkha_montgomery_form_t montIn,cau3_pkha_montgomery_form_t montOut,cau3_pkha_timing_t equalTime)2916 status_t CAU3_PKHA_ModMul(CAU3_Type *base,
2917                           const uint8_t *A,
2918                           size_t sizeA,
2919                           const uint8_t *B,
2920                           size_t sizeB,
2921                           const uint8_t *N,
2922                           size_t sizeN,
2923                           uint8_t *result,
2924                           size_t *resultSize,
2925                           cau3_pkha_f2m_t arithType,
2926                           cau3_pkha_montgomery_form_t montIn,
2927                           cau3_pkha_montgomery_form_t montOut,
2928                           cau3_pkha_timing_t equalTime)
2929 {
2930     status_t status;
2931 
2932 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2933     status = cau3_lock_semaphore(base);
2934     if (kStatus_Success != status)
2935     {
2936         cau3_release_semaphore(base);
2937         return status;
2938     }
2939 #endif
2940 
2941     status =
2942         cau3_pkha_modmul(base, A, sizeA, B, sizeB, N, sizeN, result, resultSize, arithType, montIn, montOut, equalTime);
2943 
2944     cau3_clear_all(base, true);
2945 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2946     cau3_release_semaphore(base);
2947 #endif
2948     return status;
2949 }
2950 
CAU3_PKHA_ModExp(CAU3_Type * base,const uint8_t * A,size_t sizeA,const uint8_t * N,size_t sizeN,const uint8_t * E,size_t sizeE,uint8_t * result,size_t * resultSize,cau3_pkha_f2m_t arithType,cau3_pkha_montgomery_form_t montIn,cau3_pkha_timing_t equalTime)2951 status_t CAU3_PKHA_ModExp(CAU3_Type *base,
2952                           const uint8_t *A,
2953                           size_t sizeA,
2954                           const uint8_t *N,
2955                           size_t sizeN,
2956                           const uint8_t *E,
2957                           size_t sizeE,
2958                           uint8_t *result,
2959                           size_t *resultSize,
2960                           cau3_pkha_f2m_t arithType,
2961                           cau3_pkha_montgomery_form_t montIn,
2962                           cau3_pkha_timing_t equalTime)
2963 {
2964     cau3_pkha_mode_params_t params;
2965     status_t status;
2966 
2967     if (arithType == kCAU3_PKHA_IntegerArith)
2968     {
2969         if (CAU3_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
2970         {
2971             return (kStatus_InvalidArgument);
2972         }
2973     }
2974 
2975 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2976     status = cau3_lock_semaphore(base);
2977     if (kStatus_Success != status)
2978     {
2979         cau3_release_semaphore(base);
2980         return status;
2981     }
2982 #endif
2983 
2984     cau3_pkha_default_parms(&params);
2985     params.func = kCAU3_PKHA_ArithModExp;
2986     params.arithType = arithType;
2987     params.montFormIn = montIn;
2988     params.equalTime = equalTime;
2989 
2990     cau3_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, E, sizeE);
2991     status = cau3_pkha_init_mode(base, &params);
2992 
2993     if (status == kStatus_Success)
2994     {
2995         /* Read the result and size from register B0. */
2996         if (resultSize && result)
2997         {
2998             *resultSize = base->PKBSZ;
2999             /* Read the data from the result register into place. */
3000             cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
3001         }
3002     }
3003 
3004     cau3_clear_all(base, true);
3005 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3006     cau3_release_semaphore(base);
3007 #endif
3008     return status;
3009 }
3010 
CAU3_PKHA_ModSqrt(CAU3_Type * base,const uint8_t * A,size_t sizeA,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize)3011 status_t CAU3_PKHA_ModSqrt(CAU3_Type *base,
3012                            const uint8_t *A,
3013                            size_t sizeA,
3014                            const uint8_t *N,
3015                            size_t sizeN,
3016                            uint8_t *result,
3017                            size_t *resultSize)
3018 {
3019     cau3_pkha_mode_params_t params;
3020     status_t status;
3021 
3022     /* A < N */
3023     if (CAU3_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
3024     {
3025         return (kStatus_InvalidArgument);
3026     }
3027 
3028 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3029     status = cau3_lock_semaphore(base);
3030     if (kStatus_Success != status)
3031     {
3032         cau3_release_semaphore(base);
3033         return status;
3034     }
3035 #endif
3036 
3037     cau3_pkha_default_parms(&params);
3038     params.func = kCAU3_PKHA_ArithModSqrt;
3039 
3040     cau3_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, NULL, 0);
3041     status = cau3_pkha_init_mode(base, &params);
3042 
3043     if (status == kStatus_Success)
3044     {
3045         /* Read the result and size from register B0. */
3046         if (resultSize && result)
3047         {
3048             *resultSize = base->PKBSZ;
3049             /* Read the data from the result register into place. */
3050             cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
3051         }
3052     }
3053 
3054     cau3_clear_all(base, true);
3055 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3056     cau3_release_semaphore(base);
3057 #endif
3058     return status;
3059 }
3060 
CAU3_PKHA_ModRed(CAU3_Type * base,const uint8_t * A,size_t sizeA,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,cau3_pkha_f2m_t arithType)3061 status_t CAU3_PKHA_ModRed(CAU3_Type *base,
3062                           const uint8_t *A,
3063                           size_t sizeA,
3064                           const uint8_t *N,
3065                           size_t sizeN,
3066                           uint8_t *result,
3067                           size_t *resultSize,
3068                           cau3_pkha_f2m_t arithType)
3069 {
3070     cau3_pkha_mode_params_t params;
3071     status_t status;
3072 
3073 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3074     status = cau3_lock_semaphore(base);
3075     if (kStatus_Success != status)
3076     {
3077         cau3_release_semaphore(base);
3078         return status;
3079     }
3080 #endif
3081 
3082     cau3_pkha_default_parms(&params);
3083     params.func = kCAU3_PKHA_ArithModRed;
3084     params.arithType = arithType;
3085 
3086     cau3_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, NULL, 0);
3087     status = cau3_pkha_init_mode(base, &params);
3088 
3089     if (status == kStatus_Success)
3090     {
3091         /* Read the result and size from register B0. */
3092         if (resultSize && result)
3093         {
3094             *resultSize = base->PKBSZ;
3095             /* Read the data from the result register into place. */
3096             cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
3097         }
3098     }
3099 
3100     cau3_clear_all(base, true);
3101 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3102     cau3_release_semaphore(base);
3103 #endif
3104     return status;
3105 }
3106 
CAU3_PKHA_ModInv(CAU3_Type * base,const uint8_t * A,size_t sizeA,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,cau3_pkha_f2m_t arithType)3107 status_t CAU3_PKHA_ModInv(CAU3_Type *base,
3108                           const uint8_t *A,
3109                           size_t sizeA,
3110                           const uint8_t *N,
3111                           size_t sizeN,
3112                           uint8_t *result,
3113                           size_t *resultSize,
3114                           cau3_pkha_f2m_t arithType)
3115 {
3116     cau3_pkha_mode_params_t params;
3117     status_t status;
3118 
3119     /* A must be less than N -> CAU3_PKHA_CompareBigNum() must return -1 */
3120     if (arithType == kCAU3_PKHA_IntegerArith)
3121     {
3122         if (CAU3_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
3123         {
3124             return (kStatus_InvalidArgument);
3125         }
3126     }
3127 
3128 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3129     status = cau3_lock_semaphore(base);
3130     if (kStatus_Success != status)
3131     {
3132         cau3_release_semaphore(base);
3133         return status;
3134     }
3135 #endif
3136 
3137     cau3_pkha_default_parms(&params);
3138     params.func = kCAU3_PKHA_ArithModInv;
3139     params.arithType = arithType;
3140 
3141     cau3_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, NULL, 0);
3142     status = cau3_pkha_init_mode(base, &params);
3143 
3144     if (status == kStatus_Success)
3145     {
3146         /* Read the result and size from register B0. */
3147         if (resultSize && result)
3148         {
3149             *resultSize = base->PKBSZ;
3150             /* Read the data from the result register into place. */
3151             cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
3152         }
3153     }
3154 
3155     cau3_clear_all(base, true);
3156 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3157     cau3_release_semaphore(base);
3158 #endif
3159     return status;
3160 }
3161 
CAU3_PKHA_ModR2(CAU3_Type * base,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,cau3_pkha_f2m_t arithType)3162 status_t CAU3_PKHA_ModR2(
3163     CAU3_Type *base, const uint8_t *N, size_t sizeN, uint8_t *result, size_t *resultSize, cau3_pkha_f2m_t arithType)
3164 {
3165     status_t status;
3166 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3167     status = cau3_lock_semaphore(base);
3168     if (kStatus_Success != status)
3169     {
3170         cau3_release_semaphore(base);
3171         return status;
3172     }
3173 #endif
3174     status = cau3_pkha_modR2(base, N, sizeN, result, resultSize, arithType);
3175     cau3_clear_all(base, true);
3176 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3177     cau3_release_semaphore(base);
3178 #endif
3179     return status;
3180 }
3181 
CAU3_PKHA_ModRR(CAU3_Type * base,const uint8_t * P,size_t sizeP,size_t sizeE,uint8_t * result,size_t * resultSize)3182 status_t CAU3_PKHA_ModRR(
3183     CAU3_Type *base, const uint8_t *P, size_t sizeP, size_t sizeE, uint8_t *result, size_t *resultSize)
3184 {
3185     status_t status;
3186     cau3_pkha_mode_params_t params;
3187 
3188 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3189     status = cau3_lock_semaphore(base);
3190     if (kStatus_Success != status)
3191     {
3192         cau3_release_semaphore(base);
3193         return status;
3194     }
3195 #endif
3196 
3197     cau3_pkha_default_parms(&params);
3198     params.func = kCAU3_PKHA_ArithModRR;
3199 
3200     cau3_pkha_init_data(base, NULL, 0, NULL, 0, P, sizeP, NULL, sizeE);
3201     status = cau3_pkha_init_mode(base, &params);
3202 
3203     if (status == kStatus_Success)
3204     {
3205         /* Read the result and size from register B0. */
3206         if (resultSize && result)
3207         {
3208             *resultSize = base->PKBSZ;
3209             /* Read the data from the result register into place. */
3210             cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
3211         }
3212     }
3213 
3214 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3215     cau3_release_semaphore(base);
3216 #endif
3217     return status;
3218 }
3219 
CAU3_PKHA_ModGcd(CAU3_Type * base,const uint8_t * A,size_t sizeA,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,cau3_pkha_f2m_t arithType)3220 status_t CAU3_PKHA_ModGcd(CAU3_Type *base,
3221                           const uint8_t *A,
3222                           size_t sizeA,
3223                           const uint8_t *N,
3224                           size_t sizeN,
3225                           uint8_t *result,
3226                           size_t *resultSize,
3227                           cau3_pkha_f2m_t arithType)
3228 {
3229     cau3_pkha_mode_params_t params;
3230     status_t status;
3231 
3232 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3233     status = cau3_lock_semaphore(base);
3234     if (kStatus_Success != status)
3235     {
3236         cau3_release_semaphore(base);
3237         return status;
3238     }
3239 #endif
3240 
3241     cau3_pkha_default_parms(&params);
3242     params.func = kCAU3_PKHA_ArithGcd;
3243     params.arithType = arithType;
3244 
3245     cau3_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, NULL, 0);
3246     status = cau3_pkha_init_mode(base, &params);
3247 
3248     if (status == kStatus_Success)
3249     {
3250         /* Read the result and size from register B0. */
3251         if (resultSize && result)
3252         {
3253             *resultSize = base->PKBSZ;
3254             /* Read the data from the result register into place. */
3255             cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
3256         }
3257     }
3258 
3259     cau3_clear_all(base, true);
3260 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3261     cau3_release_semaphore(base);
3262 #endif
3263     return status;
3264 }
3265 
CAU3_PKHA_PrimalityTest(CAU3_Type * base,const uint8_t * A,size_t sizeA,const uint8_t * B,size_t sizeB,const uint8_t * N,size_t sizeN,bool * res)3266 status_t CAU3_PKHA_PrimalityTest(CAU3_Type *base,
3267                                  const uint8_t *A,
3268                                  size_t sizeA,
3269                                  const uint8_t *B,
3270                                  size_t sizeB,
3271                                  const uint8_t *N,
3272                                  size_t sizeN,
3273                                  bool *res)
3274 {
3275     uint8_t result;
3276     cau3_pkha_mode_params_t params;
3277     status_t status;
3278 
3279 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3280     status = cau3_lock_semaphore(base);
3281     if (kStatus_Success != status)
3282     {
3283         cau3_release_semaphore(base);
3284         return status;
3285     }
3286 #endif
3287 
3288     cau3_pkha_default_parms(&params);
3289     params.func = kCAU3_PKHA_ArithPrimalityTest;
3290     cau3_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0);
3291     status = cau3_pkha_init_mode(base, &params);
3292 
3293     if (status == kStatus_Success)
3294     {
3295         /* Read the data from the result register into place. */
3296         cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, &result, 1);
3297 
3298         *res = (bool)result;
3299     }
3300 
3301     cau3_clear_all(base, true);
3302 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3303     cau3_release_semaphore(base);
3304 #endif
3305     return status;
3306 }
3307 
CAU3_PKHA_ECC_PointAdd(CAU3_Type * base,const cau3_pkha_ecc_point_t * A,const cau3_pkha_ecc_point_t * B,const uint8_t * N,const uint8_t * R2modN,const uint8_t * aCurveParam,const uint8_t * bCurveParam,size_t size,cau3_pkha_f2m_t arithType,cau3_pkha_ecc_point_t * result)3308 status_t CAU3_PKHA_ECC_PointAdd(CAU3_Type *base,
3309                                 const cau3_pkha_ecc_point_t *A,
3310                                 const cau3_pkha_ecc_point_t *B,
3311                                 const uint8_t *N,
3312                                 const uint8_t *R2modN,
3313                                 const uint8_t *aCurveParam,
3314                                 const uint8_t *bCurveParam,
3315                                 size_t size,
3316                                 cau3_pkha_f2m_t arithType,
3317                                 cau3_pkha_ecc_point_t *result)
3318 {
3319     cau3_pkha_mode_params_t params;
3320     uint32_t clearMask;
3321     status_t status;
3322 
3323 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3324     status = cau3_lock_semaphore(base);
3325     if (kStatus_Success != status)
3326     {
3327         cau3_release_semaphore(base);
3328         return status;
3329     }
3330 #endif
3331 
3332     cau3_pkha_default_parms(&params);
3333     params.func = kCAU3_PKHA_ArithEccAdd;
3334     params.arithType = arithType;
3335     params.r2modn = R2modN ? kCAU3_PKHA_InputR2 : kCAU3_PKHA_CalcR2;
3336 
3337     clearMask = kCAU3_ClearMode;
3338 
3339     /* Clear internal register states. */
3340     clearMask |= kCAU3_ClearPkhaSizeA;
3341     clearMask |= kCAU3_ClearPkhaSizeB;
3342     clearMask |= kCAU3_ClearPkhaSizeN;
3343     clearMask |= kCAU3_ClearPkhaSizeE;
3344 
3345     base->CW = clearMask;
3346     base->STA = kCAU3_StatusDoneIsr;
3347     cau3_pkha_clear_regabne(base, true, true, true, false);
3348 
3349     /* sizeN should be less than 64 bytes. */
3350     base->PKNSZ = size;
3351     cau3_pkha_write_reg(base, kCAU3_PKHA_RegN, 0, N, size);
3352 
3353     base->PKASZ = size;
3354     cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 0, A->X, size);
3355     cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 1, A->Y, size);
3356     cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 3, aCurveParam, size);
3357 
3358     base->PKBSZ = size;
3359     cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 0, bCurveParam, size);
3360     cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 1, B->X, size);
3361     cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 2, B->Y, size);
3362     if (R2modN)
3363     {
3364         cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 3, R2modN, size);
3365     }
3366 
3367     status = cau3_pkha_init_mode(base, &params);
3368 
3369     if (status == kStatus_Success)
3370     {
3371         /* Read the data from the result register into place. */
3372         cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 1, result->X, size);
3373         cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 2, result->Y, size);
3374     }
3375 
3376     cau3_clear_all(base, true);
3377 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3378     cau3_release_semaphore(base);
3379 #endif
3380     return status;
3381 }
3382 
CAU3_PKHA_ECC_PointDouble(CAU3_Type * base,const cau3_pkha_ecc_point_t * B,const uint8_t * N,const uint8_t * aCurveParam,const uint8_t * bCurveParam,size_t size,cau3_pkha_f2m_t arithType,cau3_pkha_ecc_point_t * result)3383 status_t CAU3_PKHA_ECC_PointDouble(CAU3_Type *base,
3384                                    const cau3_pkha_ecc_point_t *B,
3385                                    const uint8_t *N,
3386                                    const uint8_t *aCurveParam,
3387                                    const uint8_t *bCurveParam,
3388                                    size_t size,
3389                                    cau3_pkha_f2m_t arithType,
3390                                    cau3_pkha_ecc_point_t *result)
3391 {
3392     cau3_pkha_mode_params_t params;
3393     uint32_t clearMask;
3394     status_t status;
3395 
3396 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3397     status = cau3_lock_semaphore(base);
3398     if (kStatus_Success != status)
3399     {
3400         cau3_release_semaphore(base);
3401         return status;
3402     }
3403 #endif
3404 
3405     cau3_pkha_default_parms(&params);
3406     params.func = kCAU3_PKHA_ArithEccDouble;
3407     params.arithType = arithType;
3408 
3409     clearMask = kCAU3_ClearMode;
3410 
3411     /* Clear internal register states. */
3412     clearMask |= kCAU3_ClearPkhaSizeA;
3413     clearMask |= kCAU3_ClearPkhaSizeB;
3414     clearMask |= kCAU3_ClearPkhaSizeN;
3415     clearMask |= kCAU3_ClearPkhaSizeE;
3416 
3417     base->CW = clearMask;
3418     base->STA = kCAU3_StatusDoneIsr;
3419     cau3_pkha_clear_regabne(base, true, true, true, false);
3420 
3421     /* sizeN should be less than 64 bytes. */
3422     base->PKNSZ = size;
3423     cau3_pkha_write_reg(base, kCAU3_PKHA_RegN, 0, N, size);
3424 
3425     base->PKASZ = size;
3426     cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 3, aCurveParam, size);
3427 
3428     base->PKBSZ = size;
3429     cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 0, bCurveParam, size);
3430     cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 1, B->X, size);
3431     cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 2, B->Y, size);
3432     status = cau3_pkha_init_mode(base, &params);
3433 
3434     if (status == kStatus_Success)
3435     {
3436         /* Read the data from the result register into place. */
3437         cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 1, result->X, size);
3438         cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 2, result->Y, size);
3439     }
3440 
3441     cau3_clear_all(base, true);
3442 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3443     cau3_release_semaphore(base);
3444 #endif
3445     return status;
3446 }
3447 
CAU3_PKHA_ECC_PointMul(CAU3_Type * base,const cau3_pkha_ecc_point_t * A,const uint8_t * E,size_t sizeE,const uint8_t * N,const uint8_t * R2modN,const uint8_t * aCurveParam,const uint8_t * bCurveParam,size_t size,cau3_pkha_timing_t equalTime,cau3_pkha_f2m_t arithType,cau3_pkha_ecc_point_t * result)3448 status_t CAU3_PKHA_ECC_PointMul(CAU3_Type *base,
3449                                 const cau3_pkha_ecc_point_t *A,
3450                                 const uint8_t *E,
3451                                 size_t sizeE,
3452                                 const uint8_t *N,
3453                                 const uint8_t *R2modN,
3454                                 const uint8_t *aCurveParam,
3455                                 const uint8_t *bCurveParam,
3456                                 size_t size,
3457                                 cau3_pkha_timing_t equalTime,
3458                                 cau3_pkha_f2m_t arithType,
3459                                 cau3_pkha_ecc_point_t *result)
3460 {
3461     cau3_pkha_mode_params_t params;
3462     uint32_t clearMask;
3463     status_t status;
3464 
3465 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3466     status = cau3_lock_semaphore(base);
3467     if (kStatus_Success != status)
3468     {
3469         cau3_release_semaphore(base);
3470         return status;
3471     }
3472 #endif
3473 
3474     cau3_pkha_default_parms(&params);
3475     params.func = kCAU3_PKHA_ArithEccMul;
3476     params.equalTime = equalTime;
3477     params.arithType = arithType;
3478     params.r2modn = R2modN ? kCAU3_PKHA_InputR2 : kCAU3_PKHA_CalcR2;
3479 
3480     clearMask = kCAU3_ClearMode;
3481 
3482     /* Clear internal register states. */
3483     clearMask |= kCAU3_ClearPkhaSizeA;
3484     clearMask |= kCAU3_ClearPkhaSizeB;
3485     clearMask |= kCAU3_ClearPkhaSizeN;
3486     clearMask |= kCAU3_ClearPkhaSizeE;
3487 
3488     base->CW = clearMask;
3489     base->STA = kCAU3_StatusDoneIsr;
3490     cau3_pkha_clear_regabne(base, true, true, true, true);
3491 
3492     /* sizeN should be less than 64 bytes. */
3493     base->PKNSZ = size;
3494     cau3_pkha_write_reg(base, kCAU3_PKHA_RegN, 0, N, size);
3495 
3496     base->PKESZ = sizeE;
3497     cau3_pkha_write_reg(base, kCAU3_PKHA_RegE, 0, E, sizeE);
3498 
3499     base->PKASZ = size;
3500     cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 0, A->X, size);
3501     cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 1, A->Y, size);
3502     cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 3, aCurveParam, size);
3503 
3504     base->PKBSZ = size;
3505     cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 0, bCurveParam, size);
3506     if (R2modN)
3507     {
3508         cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 1, R2modN, size);
3509     }
3510 
3511     status = cau3_pkha_init_mode(base, &params);
3512 
3513     if (status == kStatus_Success)
3514     {
3515         /* Read the data from the result register into place. */
3516         cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 1, result->X, size);
3517         cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 2, result->Y, size);
3518     }
3519 
3520     cau3_clear_all(base, true);
3521 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3522     cau3_release_semaphore(base);
3523 #endif
3524     return status;
3525 }
3526 
CAU3_PKHA_ECM_PointMul(CAU3_Type * base,const uint8_t * E,size_t sizeE,const uint8_t * inputCoordinate,const uint8_t * A24,const uint8_t * N,const uint8_t * R2modN,size_t size,cau3_pkha_timing_t equalTime,uint8_t * outputCoordinate)3527 status_t CAU3_PKHA_ECM_PointMul(CAU3_Type *base,
3528                                 const uint8_t *E,
3529                                 size_t sizeE,
3530                                 const uint8_t *inputCoordinate,
3531                                 const uint8_t *A24,
3532                                 const uint8_t *N,
3533                                 const uint8_t *R2modN,
3534                                 size_t size,
3535                                 cau3_pkha_timing_t equalTime,
3536                                 uint8_t *outputCoordinate)
3537 {
3538     cau3_pkha_mode_params_t params;
3539     uint32_t clearMask;
3540     status_t status;
3541 
3542 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3543     status = cau3_lock_semaphore(base);
3544     if (kStatus_Success != status)
3545     {
3546         cau3_release_semaphore(base);
3547         return status;
3548     }
3549 #endif
3550 
3551     cau3_pkha_default_parms(&params);
3552     params.func = kCAU3_PKHA_ArithEcmMul;
3553     params.equalTime = equalTime;
3554     params.r2modn = R2modN ? kCAU3_PKHA_InputR2 : kCAU3_PKHA_CalcR2;
3555 
3556     clearMask = kCAU3_ClearMode;
3557 
3558     /* Clear internal register states. */
3559     clearMask |= kCAU3_ClearPkhaSizeA;
3560     clearMask |= kCAU3_ClearPkhaSizeB;
3561     clearMask |= kCAU3_ClearPkhaSizeN;
3562     clearMask |= kCAU3_ClearPkhaSizeE;
3563 
3564     base->CW = clearMask;
3565     base->STA = kCAU3_StatusDoneIsr;
3566     cau3_pkha_clear_regabne(base, true, true, true, true);
3567 
3568     base->PKNSZ = size;
3569     cau3_pkha_write_reg(base, kCAU3_PKHA_RegN, 0, N, size);
3570 
3571     base->PKESZ = sizeE;
3572     cau3_pkha_write_reg(base, kCAU3_PKHA_RegE, 0, E, sizeE);
3573 
3574     base->PKASZ = size;
3575     cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 0, inputCoordinate, size);
3576     cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 3, A24, size);
3577 
3578     if (R2modN)
3579     {
3580         base->PKBSZ = size;
3581         cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 1, R2modN, size);
3582     }
3583 
3584     status = cau3_pkha_init_mode(base, &params);
3585 
3586     if (status == kStatus_Success)
3587     {
3588         /* Read the data from the result register into place. */
3589         cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 1, outputCoordinate, size);
3590     }
3591 
3592     cau3_clear_all(base, true);
3593 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3594     cau3_release_semaphore(base);
3595 #endif
3596     return status;
3597 }
3598 
CAU3_PKHA_ECT_PointMul(CAU3_Type * base,const cau3_pkha_ecc_point_t * A,const uint8_t * E,size_t sizeE,const uint8_t * N,const uint8_t * R2modN,const uint8_t * aCurveParam,const uint8_t * dCurveParam,size_t size,cau3_pkha_timing_t equalTime,cau3_pkha_ecc_point_t * result)3599 status_t CAU3_PKHA_ECT_PointMul(CAU3_Type *base,
3600                                 const cau3_pkha_ecc_point_t *A,
3601                                 const uint8_t *E,
3602                                 size_t sizeE,
3603                                 const uint8_t *N,
3604                                 const uint8_t *R2modN,
3605                                 const uint8_t *aCurveParam,
3606                                 const uint8_t *dCurveParam,
3607                                 size_t size,
3608                                 cau3_pkha_timing_t equalTime,
3609                                 cau3_pkha_ecc_point_t *result)
3610 {
3611     cau3_pkha_mode_params_t params;
3612     uint32_t clearMask;
3613     status_t status;
3614 
3615 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3616     status = cau3_lock_semaphore(base);
3617     if (kStatus_Success != status)
3618     {
3619         cau3_release_semaphore(base);
3620         return status;
3621     }
3622 #endif
3623 
3624     cau3_pkha_default_parms(&params);
3625     params.func = kCAU3_PKHA_ArithEctMul;
3626     params.equalTime = equalTime;
3627     params.r2modn = R2modN ? kCAU3_PKHA_InputR2 : kCAU3_PKHA_CalcR2;
3628 
3629     clearMask = kCAU3_ClearMode;
3630 
3631     /* Clear internal register states. */
3632     clearMask |= kCAU3_ClearPkhaSizeA;
3633     clearMask |= kCAU3_ClearPkhaSizeB;
3634     clearMask |= kCAU3_ClearPkhaSizeN;
3635     clearMask |= kCAU3_ClearPkhaSizeE;
3636 
3637     base->CW = clearMask;
3638     base->STA = kCAU3_StatusDoneIsr;
3639     cau3_pkha_clear_regabne(base, true, true, true, true);
3640 
3641     base->PKNSZ = size;
3642     cau3_pkha_write_reg(base, kCAU3_PKHA_RegN, 0, N, size);
3643 
3644     base->PKESZ = sizeE;
3645     cau3_pkha_write_reg(base, kCAU3_PKHA_RegE, 0, E, sizeE);
3646 
3647     base->PKASZ = size;
3648     cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 0, A->X, size);
3649     cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 1, A->Y, size);
3650     cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 3, aCurveParam, size);
3651 
3652     base->PKBSZ = size;
3653     cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 0, dCurveParam, size);
3654     if (R2modN)
3655     {
3656         cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 1, R2modN, size);
3657     }
3658 
3659     status = cau3_pkha_init_mode(base, &params);
3660 
3661     if (status == kStatus_Success)
3662     {
3663         /* Read the data from the result register into place. */
3664         cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 1, result->X, size);
3665         cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 2, result->Y, size);
3666     }
3667 
3668     cau3_clear_all(base, true);
3669 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3670     cau3_release_semaphore(base);
3671 #endif
3672     return status;
3673 }
3674 
CAU3_PKHA_ECT_PointAdd(CAU3_Type * base,const cau3_pkha_ecc_point_t * A,const cau3_pkha_ecc_point_t * B,const uint8_t * N,const uint8_t * R2modN,const uint8_t * aCurveParam,const uint8_t * dCurveParam,size_t size,cau3_pkha_ecc_point_t * result)3675 status_t CAU3_PKHA_ECT_PointAdd(CAU3_Type *base,
3676                                 const cau3_pkha_ecc_point_t *A,
3677                                 const cau3_pkha_ecc_point_t *B,
3678                                 const uint8_t *N,
3679                                 const uint8_t *R2modN,
3680                                 const uint8_t *aCurveParam,
3681                                 const uint8_t *dCurveParam,
3682                                 size_t size,
3683                                 cau3_pkha_ecc_point_t *result)
3684 {
3685     cau3_pkha_mode_params_t params;
3686     uint32_t clearMask;
3687     status_t status;
3688 
3689 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3690     status = cau3_lock_semaphore(base);
3691     if (kStatus_Success != status)
3692     {
3693         cau3_release_semaphore(base);
3694         return status;
3695     }
3696 #endif
3697 
3698     cau3_pkha_default_parms(&params);
3699     params.func = kCAU3_PKHA_ArithEctAdd;
3700     params.r2modn = R2modN ? kCAU3_PKHA_InputR2 : kCAU3_PKHA_CalcR2;
3701 
3702     clearMask = kCAU3_ClearMode;
3703 
3704     /* Clear internal register states. */
3705     clearMask |= kCAU3_ClearPkhaSizeA;
3706     clearMask |= kCAU3_ClearPkhaSizeB;
3707     clearMask |= kCAU3_ClearPkhaSizeN;
3708     clearMask |= kCAU3_ClearPkhaSizeE;
3709 
3710     base->CW = clearMask;
3711     base->STA = kCAU3_StatusDoneIsr;
3712     cau3_pkha_clear_regabne(base, true, true, true, false);
3713 
3714     /* sizeN should be less than 64 bytes. */
3715     base->PKNSZ = size;
3716     cau3_pkha_write_reg(base, kCAU3_PKHA_RegN, 0, N, size);
3717 
3718     base->PKASZ = size;
3719     cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 0, A->X, size);
3720     cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 1, A->Y, size);
3721     cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 3, aCurveParam, size);
3722 
3723     base->PKBSZ = size;
3724     cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 0, dCurveParam, size);
3725     cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 1, B->X, size);
3726     cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 2, B->Y, size);
3727     if (R2modN)
3728     {
3729         cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 3, R2modN, size);
3730     }
3731 
3732     status = cau3_pkha_init_mode(base, &params);
3733 
3734     if (status == kStatus_Success)
3735     {
3736         /* Read the data from the result register into place. */
3737         cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 1, result->X, size);
3738         cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 2, result->Y, size);
3739     }
3740 
3741     cau3_clear_all(base, true);
3742 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3743     cau3_release_semaphore(base);
3744 #endif
3745     return status;
3746 }
3747 
CAU3_TDES_CheckParity(CAU3_Type * base,cau3_key_slot_t keySlot)3748 status_t CAU3_TDES_CheckParity(CAU3_Type *base, cau3_key_slot_t keySlot)
3749 {
3750     status_t completionStatus;
3751     cau3_task_done_t taskDone;
3752 
3753 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3754     completionStatus = cau3_lock_semaphore(base);
3755     if (kStatus_Success != completionStatus)
3756     {
3757         cau3_release_semaphore(base);
3758         return completionStatus;
3759     }
3760 #endif
3761 
3762     taskDone = kCAU3_TaskDonePoll;
3763 
3764     /*  execute the cau3 "3des_check_parity" task  */
3765     base->CC_R[17] = keySlot;                  /*  keySlot  */
3766     base->CC_R30 = CAU3_DMEM_STK_BASE;         /*  initialize stack pointer (sp)  */
3767     base->CC_R31 = 0U;                         /*  set LR = 0 to signal a host task  */
3768     base->CC_PC = CAU3_TASK_3DES_CHECK_PARITY; /*  call cau_3des_chk_parity()  */
3769     base->CC_CMD = taskDone;                   /*  trigger cau3 execution  */
3770 
3771     /*  process the cau3 task completion signal specified by taskDone  */
3772     completionStatus = cau3_process_task_completion(base, taskDone);
3773 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3774     cau3_release_semaphore(base);
3775 #endif
3776     return (completionStatus);
3777 }
3778 
CAU3_TDES_SetKey(CAU3_Type * base,cau3_handle_t * handle,const uint8_t * key,size_t keySize)3779 status_t CAU3_TDES_SetKey(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *key, size_t keySize)
3780 {
3781     /* only work with aligned key[] */
3782     if (0x3U & (uintptr_t)key)
3783     {
3784         return kStatus_InvalidArgument;
3785     }
3786 
3787     /* keySize must be 24. */
3788     if (keySize != 24U)
3789     {
3790         return kStatus_InvalidArgument;
3791     }
3792 
3793     return cau3_load_key(base, key, keySize, handle->keySlot, handle->taskDone);
3794 }
3795 
CAU3_TDES_Encrypt(CAU3_Type * base,cau3_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext)3796 status_t CAU3_TDES_Encrypt(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext)
3797 {
3798     status_t completionStatus;
3799 
3800 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3801     completionStatus = cau3_lock_semaphore(base);
3802     if (kStatus_Success != completionStatus)
3803     {
3804         cau3_release_semaphore(base);
3805         return completionStatus;
3806     }
3807 #endif
3808 
3809     /*  execute the cau3 "3des_encrypt_ecb" task  */
3810     base->CC_R[16] = (uintptr_t)plaintext;  /*  pPlainText  */
3811     base->CC_R[17] = handle->keySlot;       /*  keySlot  */
3812     base->CC_R[19] = (uintptr_t)ciphertext; /*  pCipherText  */
3813     base->CC_R30 = CAU3_DMEM_STK_BASE;      /*  initialize stack pointer (sp)  */
3814     base->CC_R31 = 0U;                      /*  set LR = 0 to signal a host task  */
3815     base->CC_PC = CAU3_TASK_3DES_ENCRYPT;   /*  call cau_3des_encrypt()  */
3816     base->CC_CMD = handle->taskDone;        /*  trigger cau3 execution  */
3817 
3818     /*  process the cau3 task completion signal specified by taskDone  */
3819     completionStatus = cau3_process_task_completion(base, handle->taskDone);
3820 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3821     cau3_release_semaphore(base);
3822 #endif
3823     return (completionStatus);
3824 }
3825 
CAU3_TDES_Decrypt(CAU3_Type * base,cau3_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext)3826 status_t CAU3_TDES_Decrypt(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext)
3827 {
3828     status_t completionStatus;
3829 
3830 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3831     completionStatus = cau3_lock_semaphore(base);
3832     if (kStatus_Success != completionStatus)
3833     {
3834         cau3_release_semaphore(base);
3835         return completionStatus;
3836     }
3837 #endif
3838 
3839     /*  execute the cau3 "3des_decrypt_ecb" task  */
3840     base->CC_R[16] = (uintptr_t)ciphertext; /*  pCipherText  */
3841     base->CC_R[17] = handle->keySlot;       /*  keySlot  */
3842     base->CC_R[19] = (uintptr_t)plaintext;  /*  pPlainText  */
3843     base->CC_R30 = CAU3_DMEM_STK_BASE;      /*  initialize stack pointer (sp)  */
3844     base->CC_R31 = 0U;                      /*  set LR = 0 to signal a host task  */
3845     base->CC_PC = CAU3_TASK_3DES_DECRYPT;   /*  call cau_3des_decrypt()  */
3846     base->CC_CMD = handle->taskDone;        /*  trigger cau3 execution  */
3847 
3848     /*  process the cau3 task completion signal specified by taskDone  */
3849     completionStatus = cau3_process_task_completion(base, handle->taskDone);
3850 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3851     cau3_release_semaphore(base);
3852 #endif
3853     return (completionStatus);
3854 }
3855 
CAU3_CHACHA20_POLY1305_SetKey(CAU3_Type * base,cau3_handle_t * handle,const uint8_t * key,size_t keySize)3856 status_t CAU3_CHACHA20_POLY1305_SetKey(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *key, size_t keySize)
3857 {
3858     /* only work with aligned key[] */
3859     if (0x3U & (uintptr_t)key)
3860     {
3861         return kStatus_InvalidArgument;
3862     }
3863 
3864     /* keySize must be 32. */
3865     if (keySize != 32U)
3866     {
3867         return kStatus_InvalidArgument;
3868     }
3869 
3870     union {
3871         uint8_t b[32];
3872         uint32_t w[8];
3873     } tempKey;
3874 
3875     for (int i = 0; i < ARRAY_SIZE(tempKey.w); i++)
3876     {
3877         tempKey.w[i] = __REV(((const uint32_t *)(uintptr_t)key)[i]);
3878     }
3879 
3880     return cau3_load_key(base, tempKey.b, keySize, handle->keySlot, handle->taskDone);
3881 }
3882 
cau3_load_nonce(CAU3_Type * base,const uint8_t * nonce,cau3_key_slot_t keySlot)3883 static status_t cau3_load_nonce(CAU3_Type *base, const uint8_t *nonce, cau3_key_slot_t keySlot)
3884 {
3885     union {
3886         uint8_t b[16];
3887         uint32_t w[4];
3888     } tempIv;
3889 
3890     memset(&tempIv, 0, sizeof(tempIv));
3891 
3892     /* set nonce to keySlot */
3893     memcpy(tempIv.b, nonce, 12);
3894     /* swap bytes */
3895     tempIv.w[0] = __REV(tempIv.w[0]);
3896     tempIv.w[1] = __REV(tempIv.w[1]);
3897     tempIv.w[2] = __REV(tempIv.w[2]);
3898 
3899     return CAU3_LoadKeyInitVector(base, tempIv.b, keySlot, kCAU3_TaskDonePoll);
3900 }
3901 
CAU3_CHACHA20_POLY1305_Encrypt(CAU3_Type * base,cau3_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t * aad,size_t aadLen,const uint8_t * nonce,uint8_t * tag)3902 status_t CAU3_CHACHA20_POLY1305_Encrypt(CAU3_Type *base,
3903                                         cau3_handle_t *handle,
3904                                         const uint8_t *plaintext,
3905                                         uint8_t *ciphertext,
3906                                         size_t size,
3907                                         const uint8_t *aad,
3908                                         size_t aadLen,
3909                                         const uint8_t *nonce,
3910                                         uint8_t *tag)
3911 {
3912     status_t completionStatus;
3913 
3914     completionStatus = cau3_load_nonce(base, nonce, handle->keySlot);
3915     if (kStatus_Success != completionStatus)
3916     {
3917         return completionStatus;
3918     }
3919 
3920 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3921     completionStatus = cau3_lock_semaphore(base);
3922     if (kStatus_Success != completionStatus)
3923     {
3924         cau3_release_semaphore(base);
3925         return completionStatus;
3926     }
3927 #endif
3928 
3929     base->CC_R[17] = handle->keySlot;         /*  key/iv slot  */
3930     base->CC_R[18] = (uintptr_t)aad;          /*  AAD pointer  */
3931     base->CC_R[19] = aadLen;                  /*  AAD length (bytes)  */
3932     base->CC_R[20] = (uintptr_t)plaintext;    /*  Plaintext pointer  */
3933     base->CC_R[21] = size;                    /*  Plaintext length  */
3934     base->CC_R[22] = (uintptr_t)ciphertext;   /*  Ciphertext pointer  */
3935     base->CC_R[23] = (uintptr_t)tag;          /*  Tag pointer  */
3936     base->CC_R30 = CAU3_DMEM_STK_BASE;        /*  initialize stack pointer (sp)  */
3937     base->CC_R31 = 0U;                        /*  set LR = 0 to signal a host task  */
3938     base->CC_PC = CAU3_TASK_CHA_POLY_ENCRYPT; /*  ChaChaPoly encrypt vector  */
3939     base->CC_CMD = handle->taskDone;          /*  trigger cau3 execution  */
3940 
3941     /*  process the cau3 task completion signal specified by taskDone  */
3942     completionStatus = cau3_process_task_completion(base, handle->taskDone);
3943 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3944     cau3_release_semaphore(base);
3945 #endif
3946     return (completionStatus);
3947 }
3948 
CAU3_CHACHA20_POLY1305_Decrypt(CAU3_Type * base,cau3_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t * aad,size_t aadLen,const uint8_t * nonce,const uint8_t * tag)3949 status_t CAU3_CHACHA20_POLY1305_Decrypt(CAU3_Type *base,
3950                                         cau3_handle_t *handle,
3951                                         const uint8_t *ciphertext,
3952                                         uint8_t *plaintext,
3953                                         size_t size,
3954                                         const uint8_t *aad,
3955                                         size_t aadLen,
3956                                         const uint8_t *nonce,
3957                                         const uint8_t *tag)
3958 {
3959     status_t completionStatus;
3960 
3961     completionStatus = cau3_load_nonce(base, nonce, handle->keySlot);
3962     if (kStatus_Success != completionStatus)
3963     {
3964         return completionStatus;
3965     }
3966 
3967 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3968     completionStatus = cau3_lock_semaphore(base);
3969     if (kStatus_Success != completionStatus)
3970     {
3971         cau3_release_semaphore(base);
3972         return completionStatus;
3973     }
3974 #endif
3975 
3976     base->CC_R[17] = handle->keySlot;         /*  key/iv slot  */
3977     base->CC_R[18] = (uintptr_t)aad;          /*  AAD pointer  */
3978     base->CC_R[19] = aadLen;                  /*  AAD length (bytes)  */
3979     base->CC_R[20] = (uintptr_t)ciphertext;   /*  Ciphertext pointer  */
3980     base->CC_R[21] = size;                    /*  Cyphertext length  */
3981     base->CC_R[22] = (uintptr_t)plaintext;    /*  Plaintext pointer  */
3982     base->CC_R[23] = (uintptr_t)tag;          /*  Tag pointer  */
3983     base->CC_R30 = CAU3_DMEM_STK_BASE;        /*  initialize stack pointer (sp)  */
3984     base->CC_R31 = 0U;                        /*  set LR = 0 to signal a host task  */
3985     base->CC_PC = CAU3_TASK_CHA_POLY_DECRYPT; /*  ChaChaPoly decrypt vector  */
3986     base->CC_CMD = handle->taskDone;          /*  trigger cau3 execution  */
3987 
3988     /*  process the cau3 task completion signal specified by taskDone  */
3989     completionStatus = cau3_process_task_completion(base, handle->taskDone);
3990 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3991     cau3_release_semaphore(base);
3992 #endif
3993     return (completionStatus);
3994 }
3995 
CAU3_KeyBlobUnwrap(CAU3_Type * base,cau3_key_slot_t keySlot,const uint8_t * keyBlob,uint32_t numberOfBlocks,cau3_key_slot_t dstContext)3996 status_t CAU3_KeyBlobUnwrap(CAU3_Type *base,
3997                             cau3_key_slot_t keySlot,
3998                             const uint8_t *keyBlob,
3999                             uint32_t numberOfBlocks,
4000                             cau3_key_slot_t dstContext)
4001 {
4002     status_t completionStatus;
4003     cau3_task_done_t taskDone;
4004 
4005     if (0x3U & (uintptr_t)keyBlob)
4006     {
4007         return kStatus_InvalidArgument;
4008     }
4009 
4010 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
4011     completionStatus = cau3_lock_semaphore(base);
4012     if (kStatus_Success != completionStatus)
4013     {
4014         cau3_release_semaphore(base);
4015         return completionStatus;
4016     }
4017 #endif
4018 
4019     taskDone = kCAU3_TaskDonePoll;
4020 
4021     /*  execute the cau3 "key blob unwrap" task  */
4022     base->CC_R[16] = (uintptr_t)keyBlob;     /*  pKeyBlob  */
4023     base->CC_R[17] = keySlot;                /*  keySlot  */
4024     base->CC_R[18] = numberOfBlocks;         /*  numberOfBlocks  */
4025     base->CC_R[19] = dstContext;             /*  destination key context  */
4026     base->CC_R30 = CAU3_DMEM_STK_BASE;       /*  initialize stack pointer (sp)  */
4027     base->CC_R31 = 0U;                       /*  set LR = 0 to signal a host task  */
4028     base->CC_PC = CAU3_TASK_KEY_BLOB_UNWRAP; /*  call cau_key_blob_unwrap()  */
4029     base->CC_CMD = taskDone;                 /*  trigger cau3 execution  */
4030 
4031     /*  process the cau3 task completion signal specified by taskDone  */
4032     completionStatus = cau3_process_task_completion(base, taskDone);
4033 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
4034     cau3_release_semaphore(base);
4035 #endif
4036     return (completionStatus);
4037 }
4038