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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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