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