1 /*
2 * Copyright 2019 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include "fsl_cau3_ble.h"
8
9 /*******************************************************************************
10 * Definitions
11 ******************************************************************************/
12
13 /* Component ID definition, used by tools. */
14 #ifndef FSL_COMPONENT_ID
15 #define FSL_COMPONENT_ID "platform.drivers.cau3"
16 #endif
17
18 /*! Compile time sizeof() check */
19 #define BUILD_ASSURE(condition, msg) extern int msg[1 - 2 * (!(condition))] __attribute__((unused))
20
21 #define CAU3_SR_TKCS_INITRUN 0x00000000U
22 #define CAU3_SR_TKCS_RUN 0x00000100U
23 #define CAU3_SR_TKCS_DBGHALT 0x00000200U
24 #define CAU3_SR_TKCS_STOPNOERR 0x00000900U
25 #define CAU3_SR_TKCS_STOPERROR 0x00000A00U
26 #define CAU3_SR_TKCS_SECV 0x00000E00U
27 #define CAU3_SR_TKCS_EXTSECV 0x00000F00U
28
29 #define CAU3_DMEM_STK_BASE 0xfff003f8U
30 #define CAU3_DMEM_AES_RCON 0xfff00A00U
31
32 #define CAU3_TASK_SECV_INIT (0x00 * 4)
33 #define CAU3_TASK_STOPERROR (0x01 * 4)
34 #define CAU3_TASK_STOPNOERR (0x02 * 4)
35 #define CAU3_TASK_NULL (0x02 * 4)
36 #define CAU3_TASK_BLKLD_DMEM (0x03 * 4)
37 #define CAU3_TASK_LD_KEYCTX (0x04 * 4)
38 #define CAU3_TASK_LD_SP_KEYCTX (0x05 * 4)
39 #define CAU3_TASK_CLR_KEYCTX (0x06 * 4)
40 #define CAU3_TASK_LD_KEY (0x07 * 4)
41 #define CAU3_TASK_LD_IV (0x08 * 4)
42 #define CAU3_TASK_AES_KEY_SCH (0x09 * 4)
43 #define CAU3_TASK_AES_ENCRYPT (0x0A * 4)
44 #define CAU3_TASK_AES_DECRYPT (0x0B * 4)
45 #define CAU3_TASK_AES128_ENCRYPT (0x0C * 4)
46 #define CAU3_TASK_AES128_DECRYPT (0x0D * 4)
47 #define CAU3_TASK_AES128_CMAC (0x0E * 4)
48 #define CAU3_TASK_SHA256_INIT_STATE (0x0F * 4)
49 #define CAU3_TASK_SHA256_UPDATE (0x10 * 4)
50 #define CAU3_TASK_KEY_BLOB_UNWRAP (0x11 * 4)
51 #define CAU3_TASK_SHA1_HASH (0x12 * 4)
52 #define CAU3_TASK_SHA1_INIT_STATE (0x13 * 4)
53 #define CAU3_TASK_SHA512_INIT_STATE (0x14 * 4)
54 #define CAU3_TASK_SHA512_UPDATE (0x15 * 4)
55 #define CAU3_TASK_3DES_CHECK_PARITY (0x16 * 4)
56 #define CAU3_TASK_3DES_ENCRYPT (0x17 * 4)
57 #define CAU3_TASK_3DES_DECRYPT (0x18 * 4)
58 #define CAU3_TASK_CHA_POLY_ENCRYPT (0x19 * 4)
59 #define CAU3_TASK_CHA_POLY_DECRYPT (0x1A * 4)
60 #define CAU3_TASK_RPA_TABLE_SIZE (0x1B * 4)
61 #define CAU3_TASK_RPA_INSERT_KEY (0x1C * 4)
62 #define CAU3_TASK_RPA_REMOVE_KEY (0x1D * 4)
63 #define CAU3_TASK_RPA_TABLE_SEARCH (0x1E * 4)
64
65 #define CAU3_SEMA4_LOCK 0x80000000U
66 #define CAU3_SEMA4_RELEASE 0x00000000U
67 #define CAU3_SMOWNR_OWNED_BY_ME 0x00000001U
68 #define CAU3_SMOWNR_UNLOCKED 0x80000000U
69
70 /*! @brief keyContext structure in the CAU3's DataMemory */
71 typedef struct _cau3_key_context
72 {
73 uint32_t keySize; /*!< key size in bytes, 0 = invalid context */
74 uint32_t streamSize; /*!< rfu-firmware; stream length in bytes */
75 uint32_t *keySched; /*!< rfu-firmware; ptr to expanded key schedule */
76 uint32_t zeroFill; /*!< zero (unused) to keep 0-mod-4 alignment */
77 uint8_t iv[16]; /*!< initialization vector */
78 uint8_t key[32]; /*!< key for 3des, aes[128,192,256] */
79 } cau3_key_context_t;
80
81 typedef enum _cau3_crypt {
82 kCAU3_Encrypt = 0,
83 kCAU3_Decrypt = 1,
84 } cau3_crypt_t;
85
86 #define cau3_memcpy memcpy
87 #define cau3_force_zero(ptr, len) (memset((ptr), 0, (len)))
88
89 /*! Internal states of the HASH creation process */
90 typedef enum _cau3_hash_algo_state {
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 uint32_t w[CAU3_HASH_BLOCK_SIZE / 4]; /*!< array of 32-bit words */
98 uint8_t b[CAU3_HASH_BLOCK_SIZE]; /*!< byte array */
99 } cau3_hash_block_t;
100
101 /*! internal cau3_hash context structure */
102 typedef struct _cau3_hash_ctx_internal
103 {
104 cau3_hash_block_t blk; /*!< memory buffer. only full blocks are written to CAU3 during hash/cmac updates */
105 size_t blksz; /*!< number of valid bytes in memory buffer */
106 cau3_hash_algo_t algo; /*!< selected algorithm from the set of supported algorithms */
107 cau3_hash_algo_state_t state; /*!< finite machine state of the hash software process */
108 size_t fullMessageSize; /*!< track message size during CAU3_HASH_Update(). The value is used for padding. */
109 uint32_t runningHash[8];
110 } cau3_hash_ctx_internal_t;
111
112 /*!< SHA-1/SHA-2 digest length in bytes */
113 enum _cau3_hash_digest_len
114 {
115 kCAU3_OutLenSha1 = 20u,
116 kCAU3_OutLenSha256 = 32u,
117 };
118
119 /*! 64-byte block represented as byte array of 16 32-bit words */
120 typedef union _cau3_sha_block {
121 uint32_t w[64 / 4]; /*!< array of 32-bit words */
122 uint8_t b[64]; /*!< byte array */
123 } cau3_sha_block_t;
124
125 /*! Full word representing the actual bit values for the CAU3 1.0 mode register. */
126 typedef uint32_t cau3_mode_t;
127
128 #define CAU3_MDPK_ALG_PKHA (0x80U) /*!< Bit field value for CAU3_MDPK_ALG: PKHA */
129 #define CAU3_MD_ALG_SHIFT 16
130
131 typedef enum _cau3_algorithm {
132 kCAU3_AlgorithmPKHA = CAU3_MDPK_ALG_PKHA << CAU3_MD_ALG_SHIFT,
133 } cau3_algorithm_t;
134
135 /*! @brief CAU3 status flags */
136 enum _cau3_status_flag
137 {
138 kCAU3_StatusPkhaBusy = 1U << CAU3_STA_PB_SHIFT,
139 kCAU3_StatusDoneIsr = 1U << CAU3_STA_DI_SHIFT,
140 kCAU3_StatusErrorIsr = 1U << CAU3_STA_EI_SHIFT,
141 kCAU3_StatusPublicKeyPrime = 1U << CAU3_STA_PKP_SHIFT,
142 kCAU3_StatusPublicKeyOpOne = 1U << CAU3_STA_PKO_SHIFT,
143 kCAU3_StatusPublicKeyOpZero = 1U << CAU3_STA_PKZ_SHIFT,
144 kCAU3_StatusAll = 0 | kCAU3_StatusDoneIsr | kCAU3_StatusErrorIsr | kCAU3_StatusPkhaBusy |
145 kCAU3_StatusPublicKeyPrime | kCAU3_StatusPublicKeyOpOne | kCAU3_StatusPublicKeyOpZero
146 };
147
148 /*! @brief CAU3 clear register */
149 typedef enum _cau3_clear_written {
150 kCAU3_ClearMode = 1U << 0,
151 kCAU3_ClearDataSize = 1U << 2,
152 kCAU3_ClearPkhaSizeA = 1U << 12,
153 kCAU3_ClearPkhaSizeB = 1U << 13,
154 kCAU3_ClearPkhaSizeN = 1U << 14,
155 kCAU3_ClearPkhaSizeE = 1U << 15,
156 kCAU3_ClearAllSize = (int)kCAU3_ClearPkhaSizeA | kCAU3_ClearPkhaSizeB | kCAU3_ClearPkhaSizeN | kCAU3_ClearPkhaSizeE,
157 kCAU3_ClearAll = (int)(kCAU3_ClearMode | kCAU3_ClearDataSize | kCAU3_ClearAllSize | 0)
158 } cau3_clear_written_t;
159
160 /*! @brief PKHA functions - arithmetic, copy/clear memory. */
161 typedef enum _cau3_pkha_func_t {
162 kCAU3_PKHA_ClearMem = 1U,
163 kCAU3_PKHA_ArithModAdd = 2U, /*!< (A + B) mod N */
164 kCAU3_PKHA_ArithModSub1 = 3U, /*!< (A - B) mod N */
165 kCAU3_PKHA_ArithModSub2 = 4U, /*!< (B - A) mod N */
166 kCAU3_PKHA_ArithModMul = 5U, /*!< (A x B) mod N */
167 kCAU3_PKHA_ArithModExp = 6U, /*!< (A^E) mod N */
168 kCAU3_PKHA_ArithModRed = 7U, /*!< (A) mod N */
169 kCAU3_PKHA_ArithModInv = 8U, /*!< (A^-1) mod N */
170 kCAU3_PKHA_ArithEccAdd = 9U, /*!< (P1 + P2) */
171 kCAU3_PKHA_ArithEccDouble = 10U, /*!< (P2 + P2) */
172 kCAU3_PKHA_ArithEccMul = 11U, /*!< (E x P(A0,A1) */
173 kCAU3_PKHA_ArithModR2 = 12U, /*!< (R^2 mod N) */
174 kCAU3_PKHA_ArithModRR = 13U, /*!< (RERP mod N) */
175 kCAU3_PKHA_ArithGcd = 14U, /*!< GCD (A, N) */
176 kCAU3_PKHA_ArithPrimalityTest = 15U, /*!< Miller-Rabin */
177 kCAU3_PKHA_CopyMemSizeN = 16U,
178 kCAU3_PKHA_CopyMemSizeSrc = 17U,
179 kCAU3_PKHA_ArithModSqrt = 0x17U, /*!< (B0 x B0) mod N = A mod N */
180 kCAU3_PKHA_ArithEcmMul = 0x4B, /*!< (E x P[A0]) */
181 kCAU3_PKHA_ArithEctAdd = 0x89, /*!< (P[A0,A1] + P[B1,B2]) */
182 kCAU3_PKHA_ArithEctMul = 0x8B, /*!< (E x P[A0,A1]) */
183 } cau3_pkha_func_t;
184
185 /*! @brief Register areas for PKHA clear memory operations. */
186 typedef enum _cau3_pkha_reg_area {
187 kCAU3_PKHA_RegA = 8U,
188 kCAU3_PKHA_RegB = 4U,
189 kCAU3_PKHA_RegE = 2U,
190 kCAU3_PKHA_RegN = 1U,
191 kCAU3_PKHA_RegAll = kCAU3_PKHA_RegA | kCAU3_PKHA_RegB | kCAU3_PKHA_RegE | kCAU3_PKHA_RegN,
192 } cau3_pkha_reg_area_t;
193
194 /*! @brief Quadrant areas for 2048-bit registers for PKHA copy memory
195 * operations. */
196 typedef enum _cau3_pkha_quad_area_t {
197 kCAU3_PKHA_Quad0 = 0U,
198 kCAU3_PKHA_Quad1 = 1U,
199 kCAU3_PKHA_Quad2 = 2U,
200 kCAU3_PKHA_Quad3 = 3U,
201 } cau3_pkha_quad_area_t;
202
203 /*! @brief User-supplied (R^2 mod N) input or CAU3 should calculate. */
204 typedef enum _cau3_pkha_r2_t {
205 kCAU3_PKHA_CalcR2 = 0U, /*!< Calculate (R^2 mod N) */
206 kCAU3_PKHA_InputR2 = 1U /*!< (R^2 mod N) supplied as input */
207 } cau3_pkha_r2_t;
208
209 /*! @brief CAU3 PKHA parameters */
210 typedef struct _cau3_pkha_mode_params_t
211 {
212 cau3_pkha_func_t func;
213 cau3_pkha_f2m_t arithType;
214 cau3_pkha_montgomery_form_t montFormIn;
215 cau3_pkha_montgomery_form_t montFormOut;
216 cau3_pkha_reg_area_t srcReg;
217 cau3_pkha_quad_area_t srcQuad;
218 cau3_pkha_reg_area_t dstReg;
219 cau3_pkha_quad_area_t dstQuad;
220 cau3_pkha_timing_t equalTime;
221 cau3_pkha_r2_t r2modn;
222 } cau3_pkha_mode_params_t;
223
224 /*******************************************************************************
225 * Variables
226 ******************************************************************************/
227 /*******************************************************************************
228 * CAU3 Read-Only Data Constants and CryptoCore Code Image
229 ******************************************************************************/
230
231 /* in the cau3's private, local data memory, there is a section for read-only */
232 /* constants associated with AES, SHA-1, SHA-256, SHA-384 and SHA-512. */
233 /* the memory organization and layout of this section is defined as: */
234 /* */
235 /* description size dmem_base description */
236 /* cau_dmem_aes_rcon 48 FFF00800 RO aes constants 10 x 32b */
237 /* cau_dmem_sha1_k 16 FFF00830 RO sha1 initial "k" 4 x 32b */
238 /* cau_dmem_sha1_init_h 32 FFF00840 RO sha1 initial state 5 x 32b */
239 /* cau_dmem_sha224_init_h 32 FFF00860 RO sha224 initial state 8 x 32b */
240 /* cau_dmem_sha256_init_h 32 FFF00880 RO sha256 initial state 8 x 32b */
241 /* cau_dmem_sha256_k 256 FFF008A0 RO sha256 initial "k" 64 x 32b */
242 /* cau_dmem_sha384_init_h 64 FFF009A0 RO sha384 initial state 16 x 32b */
243 /* cau_dmem_sha512_init_h 64 FFF009E0 RO sha512 initial state 16 x 32b */
244 /* cau_dmem_sha512_k 640 FFF00A20 RO sha512 initial "k" 160 x 32b */
245 /* */
246 /* data size allocation are rounded up to be modulo 16 bytes as required. */
247 /* */
248
249 static const uint32_t s_cau3ReadOnlyConstants[] __attribute__((aligned(16))) = {
250 /* AES RCON[] */
251 0x01000000U, 0x02000000U, 0x04000000U, 0x08000000U, 0x10000000U, 0x20000000U, 0x40000000U, 0x80000000U, 0x1b000000U,
252 0x36000000U, 0x00000000U, 0x00000000U, /* zero fill for 0-mod-16 alignment */
253
254 /* SHA1_K[] */
255 0x5a827999U, 0x6ed9eba1U, 0x8f1bbcdcU, 0xca62c1d6U,
256
257 /* SHA1_INIT_H[] */
258 0x67452301U, 0xefcdab89U, 0x98badcfeU, 0x10325476U, 0xc3d2e1f0U, 0x00000000U, 0x00000000U,
259 0x00000000U, /* zero fill for 0-mod-16 alignemnt */
260
261 /* SHA224_INIT_H[] */
262 0xc1059ed8U, 0x367cd507U, 0x3070dd17U, 0xf70e5939U, 0xffc00b31U, 0x68581511U, 0x64f98fa7U, 0xbefa4fa4U,
263
264 /* SHA256_INIT_H[] */
265 /* As described in FIPS PUB 180-4 "Secure Hash Standard", the initial hash value */
266 /* for SHA-256 is obtained by taking the first thirty-two bits of the fractional */
267 /* parts of the square roots of the first eight prime numbers. */
268 0x6a09e667U, 0xbb67ae85U, 0x3c6ef372U, 0xa54ff53aU, 0x510e527fU, 0x9b05688cU, 0x1f83d9abU, 0x5be0cd19U,
269
270 /* SHA256_K[], also used as SHA224_K[] */
271 /* As described in FIPS PUB 180-4 "Secure Hash Standard", SHA-224 & SHA-256 use */
272 /* the same sequence of sixty-four constant 32-bit words (K[]), where the words */
273 /* represent the first thirty-two bits of the fractional parts of the cube roots */
274 /* of the first sixty-four prime numbers. */
275
276 0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU, 0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U, 0xd807aa98U,
277 0x12835b01U, 0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U, 0xc19bf174U, 0xe49b69c1U, 0xefbe4786U,
278 0x0fc19dc6U, 0x240ca1ccU, 0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, 0x983e5152U, 0xa831c66dU, 0xb00327c8U,
279 0xbf597fc7U, 0xc6e00bf3U, 0xd5a79147U, 0x06ca6351U, 0x14292967U, 0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU, 0x53380d13U,
280 0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U, 0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U,
281 0xd6990624U, 0xf40e3585U, 0x106aa070U, 0x19a4c116U, 0x1e376c08U, 0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU,
282 0x5b9cca4fU, 0x682e6ff3U, 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U, 0x90befffaU, 0xa4506cebU, 0xbef9a3f7U,
283 0xc67178f2U,
284
285 /* SHA384_INIT_H[] */
286 /* 8 x 64-bit words in little-endian format */
287 0xc1059ed8U, 0xcbbb9d5dU, 0x367cd507U, 0x629a292aU, 0x3070dd17U, 0x9159015aU, 0xf70e5939U, 0x152fecd8U, 0xffc00b31U,
288 0x67332667U, 0x68581511U, 0x8eb44a87U, 0x64f98fa7U, 0xdb0c2e0dU, 0xbefa4fa4U, 0x47b5481dU,
289
290 /* SHA512_INIT_H[] */
291 /* 8 x 64-bit words in little-endian format */
292 0xf3bcc908U, 0x6a09e667U, 0x84caa73bU, 0xbb67ae85U, 0xfe94f82bU, 0x3c6ef372U, 0x5f1d36f1U, 0xa54ff53aU, 0xade682d1U,
293 0x510e527fU, 0x2b3e6c1fU, 0x9b05688cU, 0xfb41bd6bU, 0x1f83d9abU, 0x137e2179U, 0x5be0cd19U,
294
295 /* SHA512_K[] */
296 /* 80 x 64-bit words in little-endian format */
297 0xd728ae22U, 0x428a2f98U, 0x23ef65cdU, 0x71374491U, 0xec4d3b2fU, 0xb5c0fbcfU, 0x8189dbbcU, 0xe9b5dba5U, 0xf348b538U,
298 0x3956c25bU, 0xb605d019U, 0x59f111f1U, 0xaf194f9bU, 0x923f82a4U, 0xda6d8118U, 0xab1c5ed5U, 0xa3030242U, 0xd807aa98U,
299 0x45706fbeU, 0x12835b01U, 0x4ee4b28cU, 0x243185beU, 0xd5ffb4e2U, 0x550c7dc3U, 0xf27b896fU, 0x72be5d74U, 0x3b1696b1U,
300 0x80deb1feU, 0x25c71235U, 0x9bdc06a7U, 0xcf692694U, 0xc19bf174U, 0x9ef14ad2U, 0xe49b69c1U, 0x384f25e3U, 0xefbe4786U,
301 0x8b8cd5b5U, 0x0fc19dc6U, 0x77ac9c65U, 0x240ca1ccU, 0x592b0275U, 0x2de92c6fU, 0x6ea6e483U, 0x4a7484aaU, 0xbd41fbd4U,
302 0x5cb0a9dcU, 0x831153b5U, 0x76f988daU, 0xee66dfabU, 0x983e5152U, 0x2db43210U, 0xa831c66dU, 0x98fb213fU, 0xb00327c8U,
303 0xbeef0ee4U, 0xbf597fc7U, 0x3da88fc2U, 0xc6e00bf3U, 0x930aa725U, 0xd5a79147U, 0xe003826fU, 0x06ca6351U, 0x0a0e6e70U,
304 0x14292967U, 0x46d22ffcU, 0x27b70a85U, 0x5c26c926U, 0x2e1b2138U, 0x5ac42aedU, 0x4d2c6dfcU, 0x9d95b3dfU, 0x53380d13U,
305 0x8baf63deU, 0x650a7354U, 0x3c77b2a8U, 0x766a0abbU, 0x47edaee6U, 0x81c2c92eU, 0x1482353bU, 0x92722c85U, 0x4cf10364U,
306 0xa2bfe8a1U, 0xbc423001U, 0xa81a664bU, 0xd0f89791U, 0xc24b8b70U, 0x0654be30U, 0xc76c51a3U, 0xd6ef5218U, 0xd192e819U,
307 0x5565a910U, 0xd6990624U, 0x5771202aU, 0xf40e3585U, 0x32bbd1b8U, 0x106aa070U, 0xb8d2d0c8U, 0x19a4c116U, 0x5141ab53U,
308 0x1e376c08U, 0xdf8eeb99U, 0x2748774cU, 0xe19b48a8U, 0x34b0bcb5U, 0xc5c95a63U, 0x391c0cb3U, 0xe3418acbU, 0x4ed8aa4aU,
309 0x7763e373U, 0x5b9cca4fU, 0xd6b2b8a3U, 0x682e6ff3U, 0x5defb2fcU, 0x748f82eeU, 0x43172f60U, 0x78a5636fU, 0xa1f0ab72U,
310 0x84c87814U, 0x1a6439ecU, 0x8cc70208U, 0x23631e28U, 0x90befffaU, 0xde82bde9U, 0xa4506cebU, 0xb2c67915U, 0xbef9a3f7U,
311 0xe372532bU, 0xc67178f2U, 0xea26619cU, 0xca273eceU, 0x21c0c207U, 0xd186b8c7U, 0xcde0eb1eU, 0xeada7dd6U, 0xee6ed178U,
312 0xf57d4f7fU, 0x72176fbaU, 0x06f067aaU, 0xa2c898a6U, 0x0a637dc5U, 0xbef90daeU, 0x113f9804U, 0x131c471bU, 0x1b710b35U,
313 0x23047d84U, 0x28db77f5U, 0x40c72493U, 0x32caab7bU, 0x15c9bebcU, 0x3c9ebe0aU, 0x9c100d4cU, 0x431d67c4U, 0xcb3e42b6U,
314 0x4cc5d4beU, 0xfc657e2aU, 0x597f299cU, 0x3ad6faecU, 0x5fcb6fabU, 0x4a475817U, 0x6c44198cU,
315 /* CHACHA_K[] */
316 0x61707865U, 0x3320646eU, 0x79622d32U, 0x6b206574U};
317
318 static const uint32_t s_cau3ReadOnlyConstantsBytes = sizeof(s_cau3ReadOnlyConstants);
319
320 static const uint32_t s_cau3ImemImage[] __attribute__((aligned(16))) = {
321 0x60C00000U, 0x54000040U, 0x54000020U, 0x608003E0U, 0x60800540U, 0x60800B80U, 0x608012C0U, 0x60801540U, 0x608018A0U,
322 0x60801BC0U, 0x608049E0U, 0x60806540U, 0x60808100U, 0x54000040U, 0x54000040U, 0x60809180U, 0x608093E0U, 0x60801DA0U,
323 0x54000040U, 0x54000040U, 0x54000040U, 0x54000040U, 0x54000040U, 0x54000040U, 0x54000040U, 0x54000040U, 0x54000040U,
324 0x6080C640U, 0x6080C7A0U, 0x6080CAC0U, 0x6080CDE0U, 0xC8FFE3DEU, 0x08CC1234U, 0x8C001200U, 0x8C001201U, 0x8C001202U,
325 0x8C001203U, 0xCE002240U, 0xCE002242U, 0x60000434U, 0x840003DEU, 0x54000020U, 0xC8FFE3DEU, 0x5C001FE0U, 0x08800E31U,
326 0x0CC81A31U, 0x2000A012U, 0x101FFE12U, 0x00404652U, 0x8C004200U, 0x9C001204U, 0x9C001205U, 0x9C001206U, 0x9C001207U,
327 0xCE002240U, 0xCE002242U, 0xCE002244U, 0xCE002246U, 0x9C001200U, 0x9C001201U, 0x9C001202U, 0x9C001203U, 0x9C001204U,
328 0x9C001205U, 0x9C001206U, 0x9C001207U, 0xCE002240U, 0xCE002242U, 0xCE002244U, 0xCE002246U, 0x08510252U, 0x84000240U,
329 0x0880E000U, 0x3C000400U, 0x67800980U, 0x20000400U, 0xC4000240U, 0x3C000100U, 0x08408254U, 0x00800012U, 0x08CC1A31U,
330 0x67800B20U, 0x3C000300U, 0x66800AE0U, 0x63800AC0U, 0x08501A52U, 0x08501A52U, 0x08501A52U, 0x70002D5FU, 0x5C1FFFE0U,
331 0x5801FFE0U, 0x54000020U, 0xC8FFE3DEU, 0x5C001FE0U, 0x08800E31U, 0x0CC81A31U, 0x2000A012U, 0x101FFE12U, 0x00404652U,
332 0x00804200U, 0xCE002240U, 0xCE002242U, 0x20D4D4C4U, 0x1014D4C4U, 0x20D4D4C5U, 0x1014D4C5U, 0xCE002244U, 0xCE002246U,
333 0x24000100U, 0x24000121U, 0x24000142U, 0x24000163U, 0x24000184U, 0x240001A5U, 0x240001C6U, 0x240001E7U, 0x00040000U,
334 0x00040021U, 0x00040042U, 0x00040063U, 0x00040084U, 0x000400A5U, 0x000400C6U, 0x000400E7U, 0xCE002240U, 0xCE002242U,
335 0xCE002244U, 0xCE002246U, 0x08510252U, 0x84000240U, 0x0880E000U, 0x3C000400U, 0x678010C0U, 0x20000400U, 0xC4000240U,
336 0x3C000100U, 0x08408254U, 0x00800012U, 0x08CC1A31U, 0x67801260U, 0x3C000300U, 0x66801220U, 0x63801200U, 0x08501A52U,
337 0x08501A52U, 0x08501A52U, 0x70002D5FU, 0x5C1FFFE0U, 0x5801FFE0U, 0x54000020U, 0x08800E31U, 0x08C81A31U, 0x2000A012U,
338 0x101FFE12U, 0x00404652U, 0x5C1FFFE0U, 0xCE002240U, 0xCE002242U, 0xCE002244U, 0xCE002246U, 0xCE002240U, 0xCE002242U,
339 0xCE002244U, 0xCE002246U, 0x5C1FFFE0U, 0x5801FFE0U, 0x04807FFFU, 0x63801520U, 0x7080001FU, 0x54000020U, 0x0CCC7E48U,
340 0x638015C0U, 0x088C7E52U, 0x28000032U, 0x08800E52U, 0x08C81A52U, 0x2000A013U, 0x101FFE13U, 0x00404A73U, 0xC4000271U,
341 0x28000413U, 0x0C800E21U, 0x08CC0A31U, 0x63801720U, 0x28000031U, 0x3C000008U, 0x638017E0U, 0x8C001201U, 0xCC001261U,
342 0x60001771U, 0x60801840U, 0x8C001201U, 0xDC001261U, 0x600017F1U, 0x5C1FFFE0U, 0x581FFFE0U, 0x54000020U, 0x0CCC7E28U,
343 0x63801920U, 0x088C7E31U, 0x28000031U, 0x08800E31U, 0x08C81A31U, 0x2000A212U, 0x101FFE12U, 0x00404652U, 0x8C001204U,
344 0x8C001205U, 0x8C001206U, 0x8C001207U, 0x3C000008U, 0x63801AE0U, 0xCE002244U, 0xCE002246U, 0x60801B60U, 0xDC001244U,
345 0xDC001245U, 0xDC001246U, 0xDC001247U, 0x5C1FFFE0U, 0x5801FFE0U, 0x54000020U, 0xC8FFE3DEU, 0x08800E31U, 0x08C81A20U,
346 0x2000A014U, 0x101FFE14U, 0x00400294U, 0x84000292U, 0x3C000312U, 0x66801D40U, 0x63801D20U, 0x08501A52U, 0x08501A52U,
347 0x08501A52U, 0x28000414U, 0x60802D40U, 0x0C8013C6U, 0x63801E40U, 0xC8FEB3DEU, 0xC40013DFU, 0x60801E80U, 0xC8FEC3DEU,
348 0xC40013DFU, 0x00804A55U, 0x00804636U, 0x00804E77U, 0x084006F4U, 0x3C000094U, 0x63001F60U, 0x20000034U, 0x3C000055U,
349 0x63802080U, 0x3C000095U, 0x63802080U, 0x3C000115U, 0x63802080U, 0x3C000095U, 0x67002780U, 0x60802700U, 0x08800EC6U,
350 0x08C818C6U, 0x2000A00CU, 0x101FFE0CU, 0x0040198CU, 0x8C004198U, 0x08800E31U, 0x08C82226U, 0x2000C011U, 0x101FFE11U,
351 0x00401A31U, 0x3C000318U, 0x66802280U, 0x638026C0U, 0x200001D2U, 0x608022A0U, 0x20000152U, 0x2001E313U, 0x101FFE13U,
352 0x9C001200U, 0x9C001201U, 0x20000106U, 0x004078C6U, 0x008056AAU, 0x9C00120EU, 0x9C00120FU, 0xCE0020CEU, 0x6000238AU,
353 0x200000C9U, 0x008056AAU, 0x08500527U, 0x01001EA7U, 0x004028E6U, 0x008C1821U, 0x08C80D48U, 0x800023C2U, 0x08401108U,
354 0x800023C3U, 0x70006F3FU, 0x08501108U, 0xC00023C2U, 0x08401108U, 0xC00023C3U, 0x6000248AU, 0x60002429U, 0x8600018EU,
355 0x008C01CBU, 0x008C05E6U, 0x0488196BU, 0x63802860U, 0x3C000115U, 0x63802780U, 0x00805EF1U, 0x700012DFU, 0x581FFFE0U,
356 0x54000040U, 0x00805EF1U, 0x0080529DU, 0x700012DFU, 0x008077B1U, 0x700012DFU, 0x581FFFE0U, 0x54000040U, 0x00805EE7U,
357 0x08800EF7U, 0x08C81AE6U, 0x2000A017U, 0x101FFE17U, 0x00401AF7U, 0x3C000055U, 0x638029E0U, 0x3C000095U, 0x638029E0U,
358 0x20000407U, 0x60802A00U, 0x08C80EA7U, 0xCC0082E7U, 0x20000106U, 0x004078C6U, 0x008056AAU, 0x3C000115U, 0x63802B40U,
359 0x8E0020C0U, 0xCE0022E0U, 0x60002ACAU, 0x60802D20U, 0x0850114AU, 0x8E0020C0U, 0xCE0022E0U, 0x60002B6AU, 0x08800E94U,
360 0x08C81A87U, 0x2000A014U, 0x101FFE14U, 0x00401E94U, 0x2000008AU, 0x20000407U, 0xCC008287U, 0x8E0020C0U, 0xCE002280U,
361 0x60002CCAU, 0x54000020U, 0x08C82236U, 0x2000C011U, 0x101FFE11U, 0x00405A31U, 0x86000280U, 0x86002282U, 0x20014015U,
362 0x101FFE15U, 0x00800004U, 0x00800425U, 0x00800846U, 0x00800C67U, 0xCE002220U, 0xCE002222U, 0x3C000192U, 0x66803D60U,
363 0x63803D40U, 0x86004284U, 0x86006286U, 0xCE002224U, 0xCE002226U, 0x08D020E8U, 0x01800108U, 0xAC0012A8U, 0x008C2000U,
364 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x01800068U, 0x008C2084U, 0x008C10A5U, 0x008C14C6U,
365 0x008C18E7U, 0xCE002224U, 0xCE002226U, 0x08D020E8U, 0x01800108U, 0xAC0012A8U, 0x008C2000U, 0x008C0021U, 0x008C0442U,
366 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x01800068U, 0x008C2084U, 0x008C10A5U, 0x008C14C6U, 0x008C18E7U, 0xCE002224U,
367 0xCE002226U, 0x08D020E8U, 0x01800108U, 0xAC0012A8U, 0x008C2000U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U,
368 0xCE002222U, 0x01800068U, 0x008C2084U, 0x008C10A5U, 0x008C14C6U, 0x008C18E7U, 0xCE002224U, 0xCE002226U, 0x08D020E8U,
369 0x01800108U, 0xAC0012A8U, 0x008C2000U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x01800068U,
370 0x008C2084U, 0x008C10A5U, 0x008C14C6U, 0x008C18E7U, 0xCE002224U, 0xCE002226U, 0x08D020E8U, 0x01800108U, 0xAC0012A8U,
371 0x008C2000U, 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x01800068U, 0x008C2084U, 0x008C10A5U,
372 0x008C14C6U, 0x008C18E7U, 0xCE002224U, 0xCE002226U, 0x08D020E8U, 0x01800108U, 0xAC0012A8U, 0x008C2000U, 0x008C0021U,
373 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x01800068U, 0x008C2084U, 0x008C10A5U, 0x008C14C6U, 0x008C18E7U,
374 0xCE002224U, 0xCE002226U, 0x08D020E8U, 0x01800108U, 0xAC0012A8U, 0x008C2000U, 0x008C0021U, 0x008C0442U, 0x008C0863U,
375 0xCE002220U, 0xCE002222U, 0x29FFE211U, 0x608048C0U, 0x54000040U, 0x08D02067U, 0x018000E7U, 0xAC0012A7U, 0x008C1C00U,
376 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U, 0x018000E7U, 0xAC0012A7U, 0x008C1C00U,
377 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U, 0x018000E7U, 0xAC0012A7U, 0x008C1C00U,
378 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U, 0x018000E7U, 0xAC0012A7U, 0x008C1C00U,
379 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U, 0x018000E7U, 0xAC0012A7U, 0x008C1C00U,
380 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U, 0x018000E7U, 0xAC0012A7U, 0x008C1C00U,
381 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U, 0x018000E7U, 0xAC0012A7U, 0x008C1C00U,
382 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U, 0x018000E7U, 0xAC0012A7U, 0x008C1C00U,
383 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U, 0x018000E7U, 0xAC0012A7U, 0x008C1C00U,
384 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x08D02067U, 0x018000E7U, 0xAC0012A7U, 0x008C1C00U,
385 0x008C0021U, 0x008C0442U, 0x008C0863U, 0xCE002220U, 0xCE002222U, 0x29FFEA11U, 0x04805294U, 0x63804920U, 0xC4FFA291U,
386 0x04807FFFU, 0x63804980U, 0x7080001FU, 0x5C1FFFE0U, 0x581FFFE0U, 0x54000020U, 0x08800E31U, 0x08C81A20U, 0x2000A012U,
387 0x101FFE12U, 0x80000252U, 0x3C000312U, 0x66804B20U, 0x63804B00U, 0x08501A52U, 0x08501A52U, 0x08501A52U, 0x08C82236U,
388 0x2000C011U, 0x101FFE11U, 0x00405A31U, 0x0C800E04U, 0x63805340U, 0x3C000024U, 0x63805100U, 0x3C000044U, 0x63804EC0U,
389 0x94FFF605U, 0x08C860A0U, 0x94000605U, 0x08CC20A6U, 0x00881800U, 0x08C860A1U, 0x94001605U, 0x08CC20A6U, 0x00881821U,
390 0x08C860A2U, 0x94002605U, 0x08CC20A6U, 0x00881842U, 0x08C860A3U, 0x94003605U, 0x08CC20A6U, 0x00881863U, 0x608053C0U,
391 0x94FFFA05U, 0x08C840A0U, 0x94000A05U, 0x08CC40A6U, 0x00881800U, 0x08C840A1U, 0x94001A05U, 0x08CC40A6U, 0x00881821U,
392 0x08C840A2U, 0x94002A05U, 0x08CC40A6U, 0x00881842U, 0x08C840A3U, 0x94003A05U, 0x08CC40A6U, 0x00881863U, 0x608053C0U,
393 0x94FFFE05U, 0x08C820A0U, 0x94000E05U, 0x08CC60A6U, 0x00881800U, 0x08C820A1U, 0x94001E05U, 0x08CC60A6U, 0x00881821U,
394 0x08C820A2U, 0x94002E05U, 0x08CC60A6U, 0x00881842U, 0x08C820A3U, 0x94003E05U, 0x08CC60A6U, 0x00881863U, 0x608053C0U,
395 0x94000200U, 0x94001201U, 0x94002202U, 0x94003203U, 0xAC001220U, 0xAC001221U, 0xAC001222U, 0xAC001223U, 0x08500A48U,
396 0x08CC0508U, 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0x8E002224U, 0x8E002226U, 0x01881000U,
397 0x01881421U, 0x01881842U, 0x01881C63U, 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0x8E002224U,
398 0x8E002226U, 0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U, 0x60005488U, 0x01800000U, 0x01800021U, 0x01800042U,
399 0x01800063U, 0x01900000U, 0x8E002224U, 0x8E002226U, 0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U, 0x01800000U,
400 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0xAC001220U, 0xAC001221U, 0xAC001222U, 0xAC001223U, 0x0C800E64U,
401 0x63806400U, 0x3C000024U, 0x638060E0U, 0x3C000044U, 0x63805DC0U, 0x94FFF664U, 0x08CC2084U, 0x08C82084U, 0x08CC6005U,
402 0x008810A5U, 0xD4FFF665U, 0x08C82005U, 0x08CC6024U, 0x008810A5U, 0xD4000665U, 0x08C82025U, 0x08CC6044U, 0x008810A5U,
403 0xD4001665U, 0x08C82045U, 0x08CC6064U, 0x008810A5U, 0xD4002665U, 0x94003664U, 0x08C86084U, 0x08CC6084U, 0x08C82065U,
404 0x008810A5U, 0xD4003665U, 0x60806480U, 0x94FFFA64U, 0x08CC4084U, 0x08C84084U, 0x08CC4005U, 0x008810A5U, 0xD4FFFA65U,
405 0x08C84005U, 0x08CC4024U, 0x008810A5U, 0xD4000A65U, 0x08C84025U, 0x08CC4044U, 0x008810A5U, 0xD4001A65U, 0x08C84045U,
406 0x08CC4064U, 0x008810A5U, 0xD4002A65U, 0x94003A64U, 0x08C84084U, 0x08CC4084U, 0x08C84065U, 0x008810A5U, 0xD4003A65U,
407 0x60806480U, 0x94FFFE64U, 0x08CC6084U, 0x08C86084U, 0x08CC2005U, 0x008810A5U, 0xD4FFFE65U, 0x08C86005U, 0x08CC2024U,
408 0x008810A5U, 0xD4000E65U, 0x08C86025U, 0x08CC2044U, 0x008810A5U, 0xD4001E65U, 0x08C86045U, 0x08CC2064U, 0x008810A5U,
409 0xD4002E65U, 0x94003E64U, 0x08C82084U, 0x08CC2084U, 0x08C86065U, 0x008810A5U, 0xD4003E65U, 0x60806480U, 0xD4000260U,
410 0xD4001261U, 0xD4002262U, 0xD4003263U, 0x04807FFFU, 0x638064E0U, 0x7080001FU, 0x5C1FFFE0U, 0x581FFFE0U, 0x54000020U,
411 0x08800E31U, 0x08C81A20U, 0x2000A012U, 0x101FFE12U, 0x80000252U, 0x3C000312U, 0x66806680U, 0x63806660U, 0x08501A52U,
412 0x08501A52U, 0x08501A52U, 0x08C82236U, 0x2000C011U, 0x101FFE11U, 0x00405A31U, 0x0C800E04U, 0x63806EA0U, 0x3C000024U,
413 0x63806C60U, 0x3C000044U, 0x63806A20U, 0x94FFF605U, 0x08C860A0U, 0x94000605U, 0x08CC20A6U, 0x00881800U, 0x08C860A1U,
414 0x94001605U, 0x08CC20A6U, 0x00881821U, 0x08C860A2U, 0x94002605U, 0x08CC20A6U, 0x00881842U, 0x08C860A3U, 0x94003605U,
415 0x08CC20A6U, 0x00881863U, 0x60806F20U, 0x94FFFA05U, 0x08C840A0U, 0x94000A05U, 0x08CC40A6U, 0x00881800U, 0x08C840A1U,
416 0x94001A05U, 0x08CC40A6U, 0x00881821U, 0x08C840A2U, 0x94002A05U, 0x08CC40A6U, 0x00881842U, 0x08C840A3U, 0x94003A05U,
417 0x08CC40A6U, 0x00881863U, 0x60806F20U, 0x94FFFE05U, 0x08C820A0U, 0x94000E05U, 0x08CC60A6U, 0x00881800U, 0x08C820A1U,
418 0x94001E05U, 0x08CC60A6U, 0x00881821U, 0x08C820A2U, 0x94002E05U, 0x08CC60A6U, 0x00881842U, 0x08C820A3U, 0x94003E05U,
419 0x08CC60A6U, 0x00881863U, 0x60806F20U, 0x94000200U, 0x94001201U, 0x94002202U, 0x94003203U, 0x08C81259U, 0x00406631U,
420 0xA8003223U, 0xA8FFF222U, 0xA8FFF221U, 0xA8FFF220U, 0x08500A59U, 0x08CC0739U, 0x01940000U, 0x01840063U, 0x01840042U,
421 0x01840021U, 0x01840000U, 0x8AFFE23CU, 0x8AFFE23AU, 0x018C7463U, 0x018C7042U, 0x018C6C21U, 0x018C6800U, 0x01940000U,
422 0x01840063U, 0x01840042U, 0x01840021U, 0x01840000U, 0x8AFFE23CU, 0x8AFFE23AU, 0x018C7463U, 0x018C7042U, 0x018C6C21U,
423 0x018C6800U, 0x60007039U, 0x01940000U, 0x01840063U, 0x01840042U, 0x01840021U, 0x01840000U, 0x8AFFE23CU, 0x8AFFE23AU,
424 0x018C7463U, 0x018C7042U, 0x018C6C21U, 0x018C6800U, 0x01940000U, 0x01840063U, 0x01840042U, 0x01840021U, 0x01840000U,
425 0xA8FFF223U, 0xA8FFF222U, 0xA8FFF221U, 0xA8FFF220U, 0x0C800E79U, 0x63807FA0U, 0x3C000039U, 0x63807C80U, 0x3C000059U,
426 0x63807960U, 0x94FFF664U, 0x08CC2084U, 0x08C82084U, 0x08CC6005U, 0x008810A5U, 0xD4FFF665U, 0x08C82005U, 0x08CC6024U,
427 0x008810A5U, 0xD4000665U, 0x08C82025U, 0x08CC6044U, 0x008810A5U, 0xD4001665U, 0x08C82045U, 0x08CC6064U, 0x008810A5U,
428 0xD4002665U, 0x94003664U, 0x08C86084U, 0x08CC6084U, 0x08C82065U, 0x008810A5U, 0xD4003665U, 0x60808020U, 0x94FFFA64U,
429 0x08CC4084U, 0x08C84084U, 0x08CC4005U, 0x008810A5U, 0xD4FFFA65U, 0x08C84005U, 0x08CC4024U, 0x008810A5U, 0xD4000A65U,
430 0x08C84025U, 0x08CC4044U, 0x008810A5U, 0xD4001A65U, 0x08C84045U, 0x08CC4064U, 0x008810A5U, 0xD4002A65U, 0x94003A64U,
431 0x08C84084U, 0x08CC4084U, 0x08C84065U, 0x008810A5U, 0xD4003A65U, 0x60808020U, 0x94FFFE64U, 0x08CC6084U, 0x08C86084U,
432 0x08CC2005U, 0x008810A5U, 0xD4FFFE65U, 0x08C86005U, 0x08CC2024U, 0x008810A5U, 0xD4000E65U, 0x08C86025U, 0x08CC2044U,
433 0x008810A5U, 0xD4001E65U, 0x08C86045U, 0x08CC2064U, 0x008810A5U, 0xD4002E65U, 0x94003E64U, 0x08C82084U, 0x08CC2084U,
434 0x08C86065U, 0x008810A5U, 0xD4003E65U, 0x60808020U, 0xD4003263U, 0xD4002262U, 0xD4001261U, 0xD4000260U, 0x04807FFFU,
435 0x63808080U, 0x7080001FU, 0x5C1FFFE0U, 0x581FFFE0U, 0x54000020U, 0x7080001FU, 0x08800E31U, 0x08C82236U, 0x2000C011U,
436 0x101FFE11U, 0x00405A31U, 0x94000200U, 0x94001201U, 0x94002202U, 0x94003203U, 0xAC001220U, 0xAC001221U, 0xAC001222U,
437 0xAC001223U, 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0x8E002224U, 0x8E002226U, 0x01881000U,
438 0x01881421U, 0x01881842U, 0x01881C63U, 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0x8E002224U,
439 0x8E002226U, 0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U, 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U,
440 0x01900000U, 0x8E002224U, 0x8E002226U, 0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U, 0x01800000U, 0x01800021U,
441 0x01800042U, 0x01800063U, 0x01900000U, 0x8E002224U, 0x8E002226U, 0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U,
442 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0x8E002224U, 0x8E002226U, 0x01881000U, 0x01881421U,
443 0x01881842U, 0x01881C63U, 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0x8E002224U, 0x8E002226U,
444 0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U, 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U,
445 0x8E002224U, 0x8E002226U, 0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U, 0x01800000U, 0x01800021U, 0x01800042U,
446 0x01800063U, 0x01900000U, 0x8E002224U, 0x8E002226U, 0x01881000U, 0x01881421U, 0x01881842U, 0x01881C63U, 0x01800000U,
447 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0x8E002224U, 0x8E002226U, 0x01881000U, 0x01881421U, 0x01881842U,
448 0x01881C63U, 0x01800000U, 0x01800021U, 0x01800042U, 0x01800063U, 0x01900000U, 0xAC001220U, 0xAC001221U, 0xAC001222U,
449 0xAC001223U, 0xD4000260U, 0xD4001261U, 0xD4002262U, 0xD4003263U, 0x04807FFFU, 0x29FFEA11U, 0x63809120U, 0x7080001FU,
450 0x5C1FFFE0U, 0x581FFFE0U, 0x54000020U, 0x20015000U, 0x101FFE00U, 0x84000001U, 0x84001002U, 0x84002003U, 0x84003004U,
451 0x84004005U, 0x84005006U, 0x84006007U, 0x84007008U, 0xD40003A1U, 0xD40013A2U, 0xD40023A3U, 0xD40033A4U, 0xD40043A5U,
452 0xD40053A6U, 0xD40063A7U, 0xD40073A8U, 0x54000020U, 0xC8FF93DEU, 0xC40013DFU, 0x940003A1U, 0x940013A2U, 0x940023A3U,
453 0x940033A4U, 0x940043A5U, 0x940053A6U, 0x940063A7U, 0x940073A8U, 0xC40043DBU, 0x0C800F7AU, 0x63809660U, 0x00506B7BU,
454 0x2800009BU, 0x08C80F5AU, 0xC40053DAU, 0x088C7F5AU, 0x2800003AU, 0xC40063DAU, 0x2001541AU, 0x101FFE1AU, 0xC40033DDU,
455 0xC40023DCU, 0x840043DFU, 0x0C800FFFU, 0x6380AF80U, 0x94FFF37FU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU,
456 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU,
457 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U,
458 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U,
459 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU,
460 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU,
461 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U,
462 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U,
463 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU,
464 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU,
465 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U,
466 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U,
467 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU,
468 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU,
469 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U,
470 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U,
471 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU,
472 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU,
473 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U,
474 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU, 0x00CC73FDU, 0x00887529U, 0x8C001340U,
475 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x840053DCU, 0x00C873E9U, 0x9C00137FU, 0x840063DCU,
476 0x00CC73FDU, 0x00887529U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x6080BD80U,
477 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U,
478 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U,
479 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U,
480 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U,
481 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U,
482 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U,
483 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU,
484 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U,
485 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U,
486 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U,
487 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U,
488 0x8C001340U, 0x01E80100U, 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x9C001369U, 0x8C001340U, 0x01E80100U,
489 0x01E41520U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x2000019FU, 0x00406609U, 0x01E06169U, 0x8C001340U, 0x01E80120U,
490 0x01E41500U, 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x00406609U, 0x01E06169U, 0x8C001340U, 0x01E80120U, 0x01E41500U,
491 0x00400084U, 0x01EC0020U, 0x41FFFEFFU, 0x00406609U, 0x01E06169U, 0x8C001340U, 0x01E80120U, 0x01E41500U, 0x00400084U,
492 0x01EC0020U, 0x41FFFEFFU, 0x00406609U, 0x01E06169U, 0x8C001340U, 0x01E80120U, 0x01E41500U, 0x00400084U, 0x01EC0020U,
493 0x41FFFEFFU, 0x6000BDBFU, 0x840033DDU, 0x940003A0U, 0x00400021U, 0x940013A0U, 0x00400042U, 0x940023A0U, 0x00400063U,
494 0x940033A0U, 0x00400084U, 0x940043A0U, 0x004000A5U, 0x940053A0U, 0x004000C6U, 0x940063A0U, 0x004000E7U, 0x940073A0U,
495 0x00400108U, 0xD40003A1U, 0xD40013A2U, 0xD40023A3U, 0xD40033A4U, 0xD40043A5U, 0xD40053A6U, 0xD40063A7U, 0xD40073A8U,
496 0x29FFE01AU, 0x840023DCU, 0x600096BCU, 0x840013DFU, 0x840003DEU, 0x04807FFFU, 0x6380C5E0U, 0x7080001FU, 0x581FFFE0U,
497 0x5C1FFFE0U, 0x54000020U, 0x04804210U, 0x6300C700U, 0x2001D611U, 0x101FFE11U, 0x84000231U, 0x54000020U, 0x20000011U,
498 0x2001D610U, 0x101FFE10U, 0xC4000211U, 0x54000020U, 0x2001D608U, 0x101FFE08U, 0x84000108U, 0x3C000108U, 0x6680C860U,
499 0x54000040U, 0x2000160AU, 0x0100290AU, 0x2001DB11U, 0x101FFE11U, 0x00402A31U, 0x28000028U, 0x2001D60AU, 0x101FFE0AU,
500 0xC4000148U, 0x84003200U, 0x84002201U, 0x84001202U, 0x84000203U, 0x20000152U, 0x20000014U, 0x70002E1FU, 0x5C1FFFE0U,
501 0x581FFFE0U, 0x54000020U, 0x2001D60AU, 0x101FFE0AU, 0x84000148U, 0x04584100U, 0x6700CB80U, 0x54000040U, 0x08500508U,
502 0xC4000148U, 0x04584100U, 0x6380CDC0U, 0x2000160CU, 0x0100310AU, 0x2001DB09U, 0x101FFE09U, 0x0080252DU, 0x00402929U,
503 0x0100320AU, 0x004029ADU, 0x200002CCU, 0x8E00212AU, 0xCE0021AAU, 0x6000CD2CU, 0x5C1FFFE0U, 0x581FFFE0U, 0x54000020U,
504 0x2001D70BU, 0x101FFE0BU, 0x2000000AU, 0xD400016AU, 0xD400116AU, 0xD400216AU, 0xD4003170U, 0x2001DB09U, 0x101FFE09U,
505 0x00802D70U, 0x2001D913U, 0x101FFE13U, 0x2001D608U, 0x101FFE08U, 0x84000108U, 0x2000000CU, 0x085053DEU, 0xC40003C8U,
506 0xC40033D1U, 0xC40043DFU, 0x04582180U, 0x20001FF2U, 0x6600D2E0U, 0xC40023CCU, 0xC40013C9U, 0x00802531U, 0x700081BFU,
507 0x9400326DU, 0x08C821ADU, 0x08CC21ADU, 0x840033CEU, 0x840023CCU, 0x045839A0U, 0x6380D2C0U, 0x2800002CU, 0x840013C9U,
508 0x28001609U, 0x840003C8U, 0x6080D060U, 0x00803192U, 0x840043DFU, 0x2800029EU, 0x04807FFFU, 0x6380D380U, 0x7080001FU,
509 0x5C1FFFE0U, 0x581FFF60U, 0x54000020U, 0x00000000};
510
511 static const uint32_t s_cau3ImemBytes = sizeof(s_cau3ImemImage);
512
513 /*******************************************************************************
514 * Prototypes
515 ******************************************************************************/
516
517 static status_t cau3_initialize_inst_memory(CAU3_Type *base, const uint32_t *cau3ImemImage, size_t cau3ImemBytes);
518 static status_t cau3_initialize_data_memory(CAU3_Type *base, cau3_task_done_t taskDone);
519 static status_t cau3_initialize_read_only_data_memory(CAU3_Type *base,
520 const uint32_t *cau3ReadOnlyConstants,
521 size_t cau3ReadOnlyConstantsBytes,
522 cau3_task_done_t taskDone);
523 static status_t cau3_load_key_context(CAU3_Type *base,
524 cau3_key_context_t *cauKeyContext,
525 cau3_key_slot_t keySlot,
526 cau3_task_done_t taskDone);
527 static status_t cau3_load_key(
528 CAU3_Type *base, const uint8_t *key, size_t keySize, uint32_t keySlot, cau3_task_done_t taskDone);
529 static status_t cau3_pkha_clear_regabne(CAU3_Type *base, bool A, bool B, bool N, bool E);
530
531 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
532 static status_t cau3_lock_semaphore(CAU3_Type *base);
533 static void cau3_release_semaphore(CAU3_Type *base);
534 #endif
535
536 /*******************************************************************************
537 * Code
538 ******************************************************************************/
539
cau3_process_task_completion(CAU3_Type * base,cau3_task_done_t taskDone)540 static status_t cau3_process_task_completion(CAU3_Type *base, cau3_task_done_t taskDone)
541 {
542 status_t taskCompletionStatus;
543
544 taskCompletionStatus = kStatus_Fail; /* assume an error completion status */
545 switch (((uint32_t)taskDone >> 16U) & 7U)
546 {
547 uint32_t tkcs;
548
549 case 0: /* poll the cau3 status register */
550 tkcs = base->SR & CAU3_SR_TKCS_MASK;
551 while (tkcs == CAU3_SR_TKCS_RUN)
552 {
553 tkcs = base->SR & CAU3_SR_TKCS_MASK;
554 };
555
556 /* check the task completion status*/
557 if (tkcs == CAU3_SR_TKCS_STOPNOERR)
558 {
559 taskCompletionStatus = kStatus_Success; /* signal error-free completion status */
560 }
561
562 break;
563
564 case 2: /* task completion signaled by event_done */
565 do
566 {
567 __WFE(); /* cpu is waiting for cau3 event_done */
568 tkcs = base->SR & CAU3_SR_TKCS_MASK;
569 } while (tkcs == CAU3_SR_TKCS_RUN);
570
571 /* check the task completion status */
572 if (tkcs == CAU3_SR_TKCS_STOPNOERR)
573 {
574 taskCompletionStatus = kStatus_Success; /* signal error-free completion status */
575 }
576 break;
577
578 case 1: /* task completion signaled by irq */
579 /* TEMP FIX - for boot ROM with IRQ task completion, simply return */
580 case 4: /* task completion signaled by dma_req */
581 /* processing here is complete */
582 taskCompletionStatus = kStatus_Success; /* signal error-free completion status */
583 break;
584
585 default: /* undefined taskDone specifier defaults to kStatus_Fail */
586 break;
587 } /* end - switch (taskDone & 7U) */
588
589 return (taskCompletionStatus);
590 }
591
592 /*!
593 * @brief Initialize the CAU3's Instruction Memory
594 *
595 * Initializes the CAU3, including configuring it to enable the execution of
596 * crypto tasks, loading the CryptoCore's firmware image into the CAU3's
597 * instruction memory, and then performing a simple read-verify of its contents.
598 * NOTE: All the operations for this function are executed on the host processor.
599 *
600 * cau3_initialize_inst_memory
601 * @param cau3ImemImage - binary firmware image for CryptoCore
602 * @param cau3ImemBytes - size of the firmware image in bytes
603 *
604 * @retval status from the readVerify check: CAU_[OK (=0), ERROR (!0)]
605 * if an error is signaled, the retval is 0xbad10000UU + i, where i is
606 * the first miscompare word index location
607 */
cau3_initialize_inst_memory(CAU3_Type * base,const uint32_t * cau3ImemImage,size_t cau3ImemBytes)608 static status_t cau3_initialize_inst_memory(CAU3_Type *base, const uint32_t *cau3ImemImage, size_t cau3ImemBytes)
609 {
610 uint32_t i;
611
612 /* enable the cau3 */
613 base->CR = 0U;
614
615 /* poll if/while the cau3 is running initialization */
616 while ((base->SR & CAU3_SR_TKCS_MASK) == CAU3_SR_TKCS_INITRUN)
617 {
618 };
619
620 /* check for error-free stop state */
621 if ((base->SR & CAU3_SR_TKCS_MASK) != CAU3_SR_TKCS_STOPNOERR)
622 {
623 return (0xbad00000U + (base->SR & CAU3_SR_TKCS_MASK)); /* exit with error */
624 }
625
626 base->SR = CAU3_SR_TCIRQ_MASK; /* clear the TCIRQ interrupt flag */
627
628 /* write the code hex image into the cau3's imem
629 * initialize the memory cmd and address registers */
630 base->DBGMCMD = 0xac000000U; /* wt=1, ia=1, imem=0 */
631 base->DBGMADR = 0U; /* imem starting address */
632 for (i = 0; i < cau3ImemBytes / 4; i++)
633 {
634 base->DBGMDR = cau3ImemImage[i]; /* indirect write into cau3Imem */
635 }
636
637 /* read-verify the cau3 imem code image
638 * initialize the memory cmd and address registers */
639 base->DBGMCMD = 0x8c000000U; /* wt=0, ia=1, imem=0 */
640 base->DBGMADR = 0U; /* imem starting address */
641 for (i = 0; i < cau3ImemBytes / 4; i++)
642 {
643 if (base->DBGMDR != cau3ImemImage[i]) /* indirect read from cau3Imem */
644 {
645 return (0xbad10000U + i); /* exit on miscompare */
646 }
647 }
648
649 /* this function does *not* disable reads/writes of the cau3 local memories
650 * but, this operation is needed to "secure" (i.e., make private) the cau3
651 * local memories */
652
653 return 0U;
654 }
655
656 /*!
657 * @brief Initializes the CAU3's entire private Data Memory
658 *
659 * Initialize the CAU3's data memory, and then perform a read-verify versus a
660 * precalculated "pseudo-hash" value.
661 *
662 * cau3_initialize_data_memory
663 * @param taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
664 *
665 * @retval status from the readVerify check: CAU_[OK, ERROR]
666 */
cau3_initialize_data_memory(CAU3_Type * base,cau3_task_done_t taskDone)667 static status_t cau3_initialize_data_memory(CAU3_Type *base, cau3_task_done_t taskDone)
668 {
669 status_t completionStatus;
670
671 /* execute the cau3 "security violation + data initialization" task */
672 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
673 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
674 base->CC_PC = CAU3_TASK_SECV_INIT; /* call cau_secv_init() */
675 base->CC_CMD = taskDone; /* trigger cau3 execution */
676
677 /* process the cau3 task completion signal specified by taskDone */
678 completionStatus = cau3_process_task_completion(base, taskDone);
679 return (completionStatus);
680 }
681
682 /*!
683 * @brief Copies read-only constants from sysMemory to CAU3's DataMemory
684 *
685 * Initialize the read-only constants in the CAU3's data memory. This includes
686 * the AES constants (RCON) and most of the constants used in the hash functions.
687 * The constants associated with SHA-512 are NOT included and must be loaded
688 * separately.
689 *
690 * cau3_initialize_read_only_data_memory
691 * @param cauReadOnlyConstants - sysMemory table of constants needed by CAU3
692 * @param cauReadOnlyConstantsSize - size of read-only constants in bytes
693 * @param taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
694 *
695 * @retval status check from task completion: CAU_[OK, ERROR]
696 */
cau3_initialize_read_only_data_memory(CAU3_Type * base,const uint32_t * cau3ReadOnlyConstants,size_t cau3ReadOnlyConstantsBytes,cau3_task_done_t taskDone)697 static status_t cau3_initialize_read_only_data_memory(CAU3_Type *base,
698 const uint32_t *cau3ReadOnlyConstants,
699 size_t cau3ReadOnlyConstantsBytes,
700 cau3_task_done_t taskDone)
701 {
702 status_t completionStatus;
703
704 /* execute the cau3 "initialize dmem read-only constants" task */
705 base->CC_R[16] = (uint32_t)s_cau3ReadOnlyConstants; /* pReadOnlyConstants */
706 base->CC_R[17] = s_cau3ReadOnlyConstantsBytes; /* byte count (0-mod-16) */
707 base->CC_R[18] = CAU3_DMEM_AES_RCON; /* pDMEM_AES_RCON constants base */
708 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
709 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
710 base->CC_PC = CAU3_TASK_BLKLD_DMEM; /* call cau_block_load_dmem task */
711 base->CC_CMD = taskDone; /* trigger cau3 execution */
712
713 /* process the cau3 task completion signal specified by taskDone */
714 completionStatus = cau3_process_task_completion(base, taskDone);
715 return (completionStatus);
716 }
717
CAU3_MakeMemsPrivate(CAU3_Type * base,cau3_task_done_t taskDone)718 status_t CAU3_MakeMemsPrivate(CAU3_Type *base, cau3_task_done_t taskDone)
719 {
720 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
721 uint32_t completionStatus;
722 completionStatus = cau3_lock_semaphore(base);
723 if (kStatus_Success != completionStatus)
724 {
725 cau3_release_semaphore(base);
726 return completionStatus;
727 }
728 #endif /* FSL_CAU3_USE_HW_SEMA */
729
730 /* making the xMEMs private involves setting DBGCSR[DDBGMC] = 1 */
731 base->DBGCSR = CAU3_DBGCSR_DDBGMC_MASK; /* set DBGCSR[DDBGMC] */
732
733 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
734 cau3_release_semaphore(base);
735 #endif
736 return kStatus_Success;
737 }
738
739 /*!
740 * @brief Execute a CAU3 null task to "establish ownership" by host processor
741 *
742 * Execute a null task to claim ownership of the CAU3 by the host processor.
743 * This is required for correct IRQ, EVT and DMA_REQ signaling by subsequent
744 * PKHA operations. The CryptoCore task executes one instruction - a "stop".
745 *
746 * cau3_execute_null_task
747 * @param taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
748 *
749 * @retval status check from task completion: CAU_[OK, ERROR]
750 */
cau3_execute_null_task(CAU3_Type * base,cau3_task_done_t taskDone)751 static status_t cau3_execute_null_task(CAU3_Type *base, cau3_task_done_t taskDone)
752 {
753 status_t completionStatus;
754
755 /* execute the cau3 null task */
756 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
757 base->CC_R31 = 0; /* set LR = 0 to signal a host task */
758 base->CC_PC = CAU3_TASK_NULL; /* call cau_null() */
759 base->CC_CMD = taskDone; /* trigger cau3 execution */
760
761 /* process the cau3 task completion signal specified by taskDone */
762 completionStatus = cau3_process_task_completion(base, taskDone);
763 return (completionStatus);
764 }
765
766 /*!
767 * @brief Load a key into a key context
768 *
769 * Loads up to 32-byte key into the specified key slot.
770 * There is support for a maximum of 4 key slots.
771 * This does not do AES key expansion (as in cau3_load_key_context() case) so we use this one for loading TDES keys.
772 *
773 * @param key is the key pointer, ALIGNED ON A 0-MOD-4 ADDRESS
774 * @param keySize is the size in bytes of the key
775 * @param keySlot is the destination key context
776 * @param taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
777 *
778 * @retval status check from task completion: CAU_[OK, ERROR]
779 */
cau3_load_key(CAU3_Type * base,const uint8_t * key,size_t keySize,uint32_t keySlot,cau3_task_done_t taskDone)780 static status_t cau3_load_key(
781 CAU3_Type *base, const uint8_t *key, size_t keySize, uint32_t keySlot, cau3_task_done_t taskDone)
782 {
783 status_t completionStatus;
784
785 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
786 completionStatus = cau3_lock_semaphore(base);
787 if (kStatus_Success != completionStatus)
788 {
789 cau3_release_semaphore(base);
790 return completionStatus;
791 }
792 #endif
793
794 /* execute the cau3 "load initialization vector into key context" task */
795 base->CC_R[16] = (uintptr_t)key; /* pKey */
796 base->CC_R[17] = keySize; /* IV size */
797 base->CC_R[18] = keySlot; /* keySlot */
798 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
799 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
800 base->CC_PC = CAU3_TASK_LD_KEY; /* call cau_load_key() */
801 base->CC_CMD = taskDone; /* trigger cau3 execution */
802
803 /* process the cau3 task completion signal specified by taskDone */
804 completionStatus = cau3_process_task_completion(base, taskDone);
805 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
806 cau3_release_semaphore(base);
807 #endif
808 return (completionStatus);
809 }
810
CAU3_AES_Encrypt(CAU3_Type * base,cau3_handle_t * handle,const uint8_t plaintext[16],uint8_t ciphertext[16])811 status_t CAU3_AES_Encrypt(CAU3_Type *base, cau3_handle_t *handle, const uint8_t plaintext[16], uint8_t ciphertext[16])
812 {
813 status_t completionStatus;
814 cau3_task_done_t taskDone;
815
816 taskDone = handle->taskDone;
817
818 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
819 completionStatus = cau3_lock_semaphore(base);
820 if (kStatus_Success != completionStatus)
821 {
822 cau3_release_semaphore(base);
823 return completionStatus;
824 }
825 #endif
826
827 /* execute the cau3 "aes_encrypt_ecb" task */
828 base->CC_R[16] = (uint32_t)plaintext; /* pPlainText */
829 base->CC_R[17] = handle->keySlot; /* keySlot */
830 base->CC_R[19] = (uint32_t)ciphertext; /* pCipherText */
831 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
832 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
833 base->CC_PC = CAU3_TASK_AES_ENCRYPT; /* call cau_aes_encrypt() */
834 base->CC_CMD = taskDone; /* trigger cau3 execution */
835
836 /* process the cau3 task completion signal specified by taskDone */
837 completionStatus = cau3_process_task_completion(base, taskDone);
838 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
839 cau3_release_semaphore(base);
840 #endif
841 return (completionStatus);
842 }
843
CAU3_AES_Decrypt(CAU3_Type * base,cau3_handle_t * handle,const uint8_t ciphertext[16],uint8_t plaintext[16])844 status_t CAU3_AES_Decrypt(CAU3_Type *base, cau3_handle_t *handle, const uint8_t ciphertext[16], uint8_t plaintext[16])
845 {
846 status_t completionStatus;
847 cau3_task_done_t taskDone;
848
849 taskDone = handle->taskDone;
850
851 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
852 completionStatus = cau3_lock_semaphore(base);
853 if (kStatus_Success != completionStatus)
854 {
855 cau3_release_semaphore(base);
856 return completionStatus;
857 }
858 #endif
859
860 /* execute the cau3 "aes_decrypt_ecb" task */
861 base->CC_R[16] = (uint32_t)ciphertext; /* pCipherText */
862 base->CC_R[17] = handle->keySlot; /* keySlot */
863 base->CC_R[19] = (uint32_t)plaintext; /* pPlainText */
864 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
865 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
866 base->CC_PC = CAU3_TASK_AES_DECRYPT; /* call cau_aes_decrypt() */
867 base->CC_CMD = taskDone; /* trigger cau3 execution */
868
869 /* process the cau3 task completion signal specified by taskDone */
870 completionStatus = cau3_process_task_completion(base, taskDone);
871 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
872 cau3_release_semaphore(base);
873 #endif
874 return (completionStatus);
875 }
876
cau3_xor_buf(uint8_t * buf,const uint8_t * mask,uint32_t count)877 static void cau3_xor_buf(uint8_t *buf, const uint8_t *mask, uint32_t count)
878 {
879 uint32_t i;
880
881 for (i = 0; i < count; i++)
882 *(buf + i) ^= (uint8_t)*(mask + i);
883 }
884
cau3_aes_ctr_inc(uint8_t * B,uint32_t lenSz)885 static void cau3_aes_ctr_inc(uint8_t *B, uint32_t lenSz)
886 {
887 uint32_t i;
888 uint8_t *ptr;
889
890 for (i = 0; i < lenSz; i++)
891 {
892 ptr = B + CAU3_AES_BLOCK_SIZE - 1 - i;
893 *ptr += (uint8_t) 1;
894 if ((uint8_t) *ptr != 0)
895 return;
896 }
897 }
898
899 /* CAU3_Type *base, cau3_handle_t *handle, const uint8_t plaintext[16], uint8_t ciphertext[16] */
cau3_aes_ecb_encrypt(CAU3_Type * base,cau3_key_slot_t keySlot,const uint8_t * inBlock,uint8_t * outBlock)900 static status_t cau3_aes_ecb_encrypt(CAU3_Type *base,
901 cau3_key_slot_t keySlot,
902 const uint8_t *inBlock,
903 uint8_t *outBlock)
904 {
905 status_t completionStatus;
906 cau3_handle_t handle;
907
908 handle.keySlot = keySlot;
909 handle.taskDone = kCAU3_TaskDonePoll;
910
911 completionStatus = CAU3_AES_Encrypt(base, &handle, inBlock, outBlock);
912 if (completionStatus != kStatus_Success)
913 cau3_force_zero(outBlock, CAU3_AES_BLOCK_SIZE);
914
915 return completionStatus;
916 }
917
cau3_aes_ccm_auth(CAU3_Type * base,cau3_key_slot_t keySlot,const uint8_t * data,uint32_t len,uint8_t * x)918 static status_t cau3_aes_ccm_auth(CAU3_Type *base,
919 cau3_key_slot_t keySlot,
920 const uint8_t *data,
921 uint32_t len,
922 uint8_t *x)
923 {
924 uint32_t last = len % CAU3_AES_BLOCK_SIZE, i;
925 status_t completionStatus = kStatus_Success;
926
927 for (i = 0; i < len / CAU3_AES_BLOCK_SIZE; i++)
928 {
929 /* X_i+1 = E(K, X_i XOR B_i) */
930 cau3_xor_buf(x, data, CAU3_AES_BLOCK_SIZE);
931 data += CAU3_AES_BLOCK_SIZE;
932 completionStatus = cau3_aes_ecb_encrypt(base, keySlot, x, x);
933 if (completionStatus != kStatus_Success)
934 return (completionStatus);
935 }
936
937 if (last)
938 {
939 /* XOR zero-padded last block */
940 for (i = 0; i < last; i++)
941 x[i] ^= (uint8_t) *data++;
942 completionStatus = cau3_aes_ecb_encrypt(base, keySlot, x, x);
943 if (completionStatus != kStatus_Success)
944 return (completionStatus);
945 }
946
947 return (completionStatus);
948 }
949
cau3_aes_ccm_auth_start(CAU3_Type * base,cau3_key_slot_t keySlot,uint32_t authTagSz,uint32_t L,const uint8_t * nonce,const uint8_t * authIn,uint32_t authInSz,uint32_t inSz,uint8_t * x)950 static status_t cau3_aes_ccm_auth_start(CAU3_Type *base,
951 cau3_key_slot_t keySlot,
952 uint32_t authTagSz,
953 uint32_t L,
954 const uint8_t *nonce,
955 const uint8_t *authIn,
956 uint32_t authInSz,
957 uint32_t inSz,
958 uint8_t *x)
959 {
960 uint32_t wordSz = (uint32_t)sizeof(uint32_t);
961 status_t completionStatus = kStatus_Success;
962 uint32_t authLenSz, remainder, i;
963 uint8_t b[CAU3_AES_BLOCK_SIZE];
964 uint8_t *bPtr = (uint8_t *)&b[0];
965 uint8_t mask = 0xFF;
966
967 /* Authentication */
968 /* B_0: Flags | Nonce N | l(m) */
969 b[0] = authInSz ? 0x40 : 0 /* Adata */;
970 b[0] |= (((authTagSz - 2) / 2) /* M' */<< 3);
971 b[0] |= (L - 1) /* L' */;
972 cau3_memcpy(&b[1], nonce, 15 - L);
973
974 for (i = 0; i < L; i++)
975 {
976 if (mask && i >= wordSz)
977 mask = 0x00;
978 b[CAU3_AES_BLOCK_SIZE - 1 - i] = (uint8_t)((inSz >> ((8 * i) & mask))
979 & mask);
980 }
981
982 /* X_1 = E(K, B_0) */
983 completionStatus = cau3_aes_ecb_encrypt(base, keySlot, bPtr, x);
984 if (completionStatus != kStatus_Success)
985 return (completionStatus);
986
987 if (!authInSz)
988 return 0;
989
990 /* encode the length in */
991 if (authInSz <= 0xFEFF)
992 {
993 authLenSz = 2;
994 x[0] ^= (uint8_t) ((authInSz & 0xFF00) >> 8);
995 x[1] ^= (uint8_t) (authInSz & 0x00FF);
996 }
997 else if (authInSz <= 0xFFFFFFFF)
998 {
999 authLenSz = 6;
1000 x[0] ^= (uint8_t) 0xFF;
1001 x[1] ^= (uint8_t) 0xFE;
1002 x[2] ^= (uint8_t) ((authInSz & 0xFF000000) >> 24);
1003 x[3] ^= (uint8_t) ((authInSz & 0x00FF0000) >> 16);
1004 x[4] ^= (uint8_t) ((authInSz & 0x0000FF00) >> 8);
1005 x[5] ^= (uint8_t) (authInSz & 0x000000FF);
1006 }
1007 /* Note, the protocol handles auth data up to 2^64, but we are
1008 * using 32-bit sizes right now, so the bigger data isn't handled
1009 * else if (inSz <= 0xFFFFFFFFFFFFFFFF) {} */
1010 else
1011 return (completionStatus);
1012
1013 /* start fill out the rest of the first block */
1014 remainder = CAU3_AES_BLOCK_SIZE - authLenSz;
1015 if (authInSz >= remainder)
1016 {
1017 /* plenty of bulk data to fill the remainder of this block */
1018 cau3_xor_buf(x + authLenSz, authIn, remainder);
1019 authInSz -= remainder;
1020 authIn += remainder;
1021 }
1022 else
1023 {
1024 /* not enough bulk data, copy what is available, and pad zero */
1025 cau3_xor_buf(x + authLenSz, authIn, authInSz);
1026 authInSz = 0;
1027 }
1028
1029 completionStatus = cau3_aes_ecb_encrypt(base, keySlot, x, x);
1030 if (completionStatus != kStatus_Success)
1031 return (completionStatus);
1032
1033 if (authInSz > 0)
1034 {
1035 completionStatus = cau3_aes_ccm_auth(base, keySlot, authIn, authInSz, x);
1036 if (completionStatus != kStatus_Success)
1037 return (completionStatus);
1038 }
1039
1040 return (completionStatus);
1041 }
1042
cau3_aes_ccm_encr(CAU3_Type * base,cau3_key_slot_t keySlot,uint32_t L,const uint8_t * in,uint32_t inSz,uint8_t * out,uint8_t * a)1043 static status_t cau3_aes_ccm_encr(CAU3_Type *base,
1044 cau3_key_slot_t keySlot,
1045 uint32_t L,
1046 const uint8_t *in,
1047 uint32_t inSz,
1048 uint8_t *out,
1049 uint8_t * a)
1050 {
1051 uint32_t last = inSz % CAU3_AES_BLOCK_SIZE, i;
1052 status_t completionStatus = kStatus_Success;
1053
1054 for (i = 0; i < L; i++)
1055 a[CAU3_AES_BLOCK_SIZE - 1 - i] = (uint8_t)0;
1056
1057 /* crypt = msg XOR (S_1 | S_2 | ... | S_n) */
1058 for (i = 1; i <= (inSz / CAU3_AES_BLOCK_SIZE); i++)
1059 {
1060 cau3_aes_ctr_inc(a, L);
1061 /* S_i = E(K, A_i) */
1062 completionStatus = cau3_aes_ecb_encrypt(base, keySlot, a, out);
1063 if (completionStatus != kStatus_Success)
1064 return (completionStatus);
1065
1066 cau3_xor_buf(out, in,CAU3_AES_BLOCK_SIZE);
1067 out += CAU3_AES_BLOCK_SIZE;
1068 in += CAU3_AES_BLOCK_SIZE;
1069 }
1070
1071 if (last)
1072 {
1073 cau3_aes_ctr_inc(a, L);
1074 completionStatus = cau3_aes_ecb_encrypt(base, keySlot, a, out);
1075 if (completionStatus != kStatus_Success)
1076 return (completionStatus);
1077
1078 /* XOR zero-padded last block */
1079 for (i = 0; i < last; i++)
1080 *out++ ^= (uint8_t) *in++;
1081 }
1082
1083 return (completionStatus);
1084 }
1085
cau3_aes_ccm_encr_start(uint32_t L,const uint8_t * nonce,uint8_t * a)1086 static void cau3_aes_ccm_encr_start(uint32_t L, const uint8_t *nonce, uint8_t *a)
1087 {
1088 /* A_i = Flags | Nonce N | Counter i */
1089 a[0] = L - 1; /* Flags = L' */
1090 cau3_memcpy(&a[1], nonce, 15 - L);
1091 }
1092
cau3_aes_ccm_encr_auth(CAU3_Type * base,cau3_key_slot_t keySlot,uint32_t L,uint32_t authTagSz,uint8_t * x,uint8_t * a,uint8_t * authTag)1093 static status_t cau3_aes_ccm_encr_auth(CAU3_Type *base,
1094 cau3_key_slot_t keySlot,
1095 uint32_t L,
1096 uint32_t authTagSz,
1097 uint8_t *x,
1098 uint8_t *a,
1099 uint8_t *authTag)
1100 {
1101 uint32_t i;
1102 uint8_t tmp[CAU3_AES_BLOCK_SIZE];
1103
1104 /* U = T XOR S_0; S_0 = E(K, A_0) */
1105 for (i = 0; i < L; i++)
1106 a[CAU3_AES_BLOCK_SIZE - 1 - i] = (uint8_t) 0;
1107
1108 if (cau3_aes_ecb_encrypt(base, keySlot, a, &tmp[0]))
1109 {
1110 cau3_force_zero(&tmp[0], CAU3_AES_BLOCK_SIZE);
1111 return kStatus_Fail;
1112 }
1113
1114 for (i = 0; i < authTagSz; i++)
1115 authTag[i] = (uint8_t) x[i] ^ (uint8_t) tmp[i];
1116
1117 return kStatus_Success;
1118 }
cau3_aes_ccm_decr_auth(CAU3_Type * base,cau3_key_slot_t keySlot,uint32_t L,uint32_t authTagSz,uint8_t * a,const uint8_t * authTag,uint8_t * t)1119 static status_t cau3_aes_ccm_decr_auth(CAU3_Type *base,
1120 cau3_key_slot_t keySlot,
1121 uint32_t L,
1122 uint32_t authTagSz,
1123 uint8_t *a,
1124 const uint8_t *authTag,
1125 uint8_t *t)
1126 {
1127 uint32_t i;
1128 uint8_t tmp[CAU3_AES_BLOCK_SIZE];
1129
1130 /* U = T XOR S_0; S_0 = E(K, A_0) */
1131 for (i = 0; i < L; i++)
1132 a[CAU3_AES_BLOCK_SIZE - 1 - i] = (uint8_t) 0;
1133
1134 if (cau3_aes_ecb_encrypt(base, keySlot, a, &tmp[0]))
1135 {
1136 cau3_force_zero(&tmp[0], CAU3_AES_BLOCK_SIZE);
1137 return kStatus_Fail;
1138 }
1139
1140 for (i = 0; i < authTagSz; i++)
1141 t[i] = (uint8_t) authTag[i] ^ (uint8_t) tmp[i];
1142
1143 return kStatus_Success;
1144 }
1145
cau3_aes_ccm_clear_mem(uint8_t * A,uint8_t * B,uint32_t len)1146 static inline void cau3_aes_ccm_clear_mem(uint8_t *A, uint8_t *B, uint32_t len)
1147 {
1148 cau3_force_zero(A, len);
1149 cau3_force_zero(B, len);
1150 }
1151
cau3_aes_ccm_encrypt(CAU3_Type * base,cau3_key_slot_t keySlot,const uint8_t * in,uint32_t inSz,uint8_t * out,const uint8_t * nonce,uint32_t nonceSz,const uint8_t * authIn,uint32_t authInSz,uint8_t * authTag,uint32_t authTagSz)1152 static status_t cau3_aes_ccm_encrypt(CAU3_Type *base,
1153 cau3_key_slot_t keySlot,
1154 const uint8_t *in,
1155 uint32_t inSz,
1156 uint8_t *out,
1157 const uint8_t *nonce,
1158 uint32_t nonceSz,
1159 const uint8_t *authIn,
1160 uint32_t authInSz,
1161 uint8_t *authTag,
1162 uint32_t authTagSz)
1163 {
1164 const uint32_t L = CAU3_AES_BLOCK_SIZE - 1 - nonceSz;
1165 uint8_t x[CAU3_AES_BLOCK_SIZE];
1166 uint8_t *xPtr = (uint8_t*) &x[0];
1167 uint8_t a[CAU3_AES_BLOCK_SIZE];
1168 uint8_t *aPtr = (uint8_t*) &a[0];
1169 status_t completionStatus;
1170
1171 /* sanity check on arguments */
1172 if (nonceSz < 7 || nonceSz > 13 || authTagSz < 4 || authTagSz > 16)
1173 return kStatus_InvalidArgument;
1174
1175 completionStatus = cau3_aes_ccm_auth_start(base, keySlot, authTagSz, L, nonce,
1176 authIn, authInSz, inSz, xPtr);
1177 if (completionStatus != kStatus_Success)
1178 {
1179 cau3_aes_ccm_clear_mem(xPtr, aPtr, CAU3_AES_BLOCK_SIZE);
1180 return (completionStatus);
1181 }
1182
1183 completionStatus = cau3_aes_ccm_auth(base, keySlot, in, inSz, xPtr);
1184 if (completionStatus != kStatus_Success)
1185 {
1186 cau3_aes_ccm_clear_mem(xPtr, aPtr, CAU3_AES_BLOCK_SIZE);
1187 return (completionStatus);
1188 }
1189
1190 /* Encryption */
1191 cau3_aes_ccm_encr_start(L, nonce, aPtr);
1192
1193 completionStatus = cau3_aes_ccm_encr(base, keySlot, L, in, inSz, out, aPtr);
1194 if (completionStatus != kStatus_Success)
1195 {
1196 cau3_aes_ccm_clear_mem(xPtr, aPtr, CAU3_AES_BLOCK_SIZE);
1197 return (completionStatus);
1198 }
1199
1200 completionStatus = cau3_aes_ccm_encr_auth(base, keySlot, L, authTagSz, xPtr, aPtr, authTag);
1201 if (completionStatus != kStatus_Success)
1202 {
1203 cau3_aes_ccm_clear_mem(xPtr, aPtr, CAU3_AES_BLOCK_SIZE);
1204 return (completionStatus);
1205 }
1206
1207 cau3_aes_ccm_clear_mem(xPtr, aPtr, CAU3_AES_BLOCK_SIZE);
1208
1209 return (completionStatus);
1210 }
1211
cau3_aes_ccm_decrypt(CAU3_Type * base,cau3_key_slot_t keySlot,uint8_t * out,const uint8_t * in,uint32_t inSz,const uint8_t * nonce,uint32_t nonceSz,const uint8_t * authTag,uint32_t authTagSz,uint8_t * authPassed,const uint8_t * authIn,uint32_t authInSz)1212 static int cau3_aes_ccm_decrypt(CAU3_Type *base,
1213 cau3_key_slot_t keySlot,
1214 uint8_t *out,
1215 const uint8_t *in,
1216 uint32_t inSz,
1217 const uint8_t *nonce,
1218 uint32_t nonceSz,
1219 const uint8_t *authTag,
1220 uint32_t authTagSz,
1221 uint8_t *authPassed,
1222 const uint8_t *authIn,
1223 uint32_t authInSz)
1224 {
1225 const uint32_t L = CAU3_AES_BLOCK_SIZE - 1 - nonceSz;
1226 uint8_t x[CAU3_AES_BLOCK_SIZE];
1227 uint8_t *xPtr = (uint8_t*) &x[0];
1228 uint8_t a[CAU3_AES_BLOCK_SIZE];
1229 uint8_t *aPtr = (uint8_t*) &a[0];
1230 uint8_t t[CAU3_AES_BLOCK_SIZE];
1231 uint8_t *tPtr = (uint8_t*) &t[0];
1232 status_t completionStatus;
1233
1234 /* sanity check on arguments */
1235 if (nonceSz < 7 || nonceSz > 13 || authTagSz < 4 || authTagSz > 16)
1236 return kStatus_InvalidArgument;
1237
1238 /* Decryption */
1239 cau3_aes_ccm_encr_start(L, nonce, aPtr);
1240
1241 completionStatus = cau3_aes_ccm_decr_auth(base, keySlot, L, authTagSz, aPtr, authTag, tPtr);
1242 if (completionStatus != kStatus_Success)
1243 {
1244 cau3_aes_ccm_clear_mem(xPtr, aPtr, CAU3_AES_BLOCK_SIZE);
1245 cau3_force_zero(tPtr, CAU3_AES_BLOCK_SIZE);
1246 return (completionStatus);
1247 }
1248
1249 /* plaintext = msg XOR (S_1 | S_2 | ... | S_n) */
1250 completionStatus = cau3_aes_ccm_encr(base, keySlot, L, in, inSz, out, aPtr);
1251 if (completionStatus != kStatus_Success)
1252 {
1253 cau3_aes_ccm_clear_mem(xPtr, aPtr, CAU3_AES_BLOCK_SIZE);
1254 cau3_force_zero(tPtr, CAU3_AES_BLOCK_SIZE);
1255 return (completionStatus);
1256 }
1257
1258 completionStatus = cau3_aes_ccm_auth_start(base, keySlot, authTagSz, L, nonce, authIn,
1259 authInSz, inSz, xPtr);
1260 if (completionStatus != kStatus_Success) {
1261 cau3_aes_ccm_clear_mem(xPtr, aPtr, CAU3_AES_BLOCK_SIZE);
1262 cau3_force_zero(tPtr, CAU3_AES_BLOCK_SIZE);
1263 return (completionStatus);
1264 }
1265
1266 completionStatus = cau3_aes_ccm_auth(base, keySlot, out, inSz, xPtr);
1267 if (completionStatus != kStatus_Success)
1268 {
1269 cau3_aes_ccm_clear_mem(xPtr, aPtr, CAU3_AES_BLOCK_SIZE);
1270 cau3_force_zero(tPtr, CAU3_AES_BLOCK_SIZE);
1271 return (completionStatus);
1272 }
1273
1274 if (memcmp(xPtr, tPtr, authTagSz) != 0) {
1275 // If the authTag check fails, don't keep the decrypted data.
1276 memset(out, 0, inSz);
1277 *authPassed = 0;
1278 return (completionStatus);
1279 } else {
1280 *authPassed = 1;
1281 }
1282
1283 cau3_aes_ccm_clear_mem(xPtr, aPtr, CAU3_AES_BLOCK_SIZE);
1284 cau3_force_zero(tPtr, CAU3_AES_BLOCK_SIZE);
1285
1286 return (completionStatus);
1287 }
1288
CAU3_AES_CCM_EncryptTag(CAU3_Type * base,cau3_handle_t * handle,const uint8_t * plainText,size_t plainTextSize,uint8_t * cipherText,const uint8_t * nonce,size_t nonceSize,const uint8_t * aad,size_t aadSize,uint8_t * authTag,size_t authTagSize)1289 status_t CAU3_AES_CCM_EncryptTag(CAU3_Type *base,
1290 cau3_handle_t *handle,
1291 const uint8_t *plainText,
1292 size_t plainTextSize,
1293 uint8_t *cipherText,
1294 const uint8_t *nonce,
1295 size_t nonceSize,
1296 const uint8_t *aad,
1297 size_t aadSize,
1298 uint8_t *authTag,
1299 size_t authTagSize)
1300 {
1301 status_t completionStatus;
1302
1303 completionStatus = cau3_aes_ccm_encrypt(base, handle->keySlot, plainText, plainTextSize, cipherText,
1304 nonce, nonceSize, aad, aadSize, authTag, authTagSize);
1305 if (completionStatus != kStatus_Success)
1306 CAU3_ForceError(base, handle->taskDone);
1307 else
1308 completionStatus = cau3_execute_null_task(base, handle->taskDone);
1309
1310 return (completionStatus);
1311 }
1312
CAU3_AES_CCM_DecryptTag(CAU3_Type * base,cau3_handle_t * handle,const uint8_t * cipherText,uint8_t * plainText,size_t plainTextSize,const uint8_t * nonce,size_t nonceSize,const uint8_t * aad,size_t aadSize,const uint8_t * authTag,size_t authTagSize)1313 uint32_t CAU3_AES_CCM_DecryptTag(CAU3_Type *base,
1314 cau3_handle_t *handle,
1315 const uint8_t *cipherText,
1316 uint8_t *plainText,
1317 size_t plainTextSize,
1318 const uint8_t *nonce,
1319 size_t nonceSize,
1320 const uint8_t *aad,
1321 size_t aadSize,
1322 const uint8_t *authTag,
1323 size_t authTagSize)
1324 {
1325 status_t completionStatus;
1326 uint8_t authPassed = 0;
1327
1328 completionStatus = cau3_aes_ccm_decrypt(base, handle->keySlot, plainText, cipherText, plainTextSize,
1329 nonce, nonceSize, authTag, authTagSize, &authPassed, aad, aadSize);
1330
1331 if (completionStatus != kStatus_Success)
1332 CAU3_ForceError(base, handle->taskDone);
1333 else
1334 completionStatus = cau3_execute_null_task(base, handle->taskDone);
1335
1336 handle->micPassed = authPassed;
1337 return (completionStatus);
1338 }
1339
CAU3_Init(CAU3_Type * base)1340 void CAU3_Init(CAU3_Type *base)
1341 {
1342 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
1343 /* ungate clock */
1344 CLOCK_EnableClock(kCLOCK_Cau3);
1345 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1346 CLOCK_EnableClock(FSL_CAU3_SEMA42_CLOCK_NAME);
1347 #endif /* FSL_CAU3_USE_HW_SEMA */
1348 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
1349
1350 base->CR = CAU3_CR_RSTSM4(1);
1351 base->CR = CAU3_CR_RSTSM4(2);
1352 cau3_initialize_inst_memory(base, s_cau3ImemImage, s_cau3ImemBytes);
1353 cau3_initialize_data_memory(base, kCAU3_TaskDonePoll);
1354 cau3_initialize_read_only_data_memory(base, s_cau3ReadOnlyConstants, s_cau3ReadOnlyConstantsBytes,
1355 kCAU3_TaskDonePoll);
1356 cau3_pkha_clear_regabne(base, true, true, true, true);
1357 }
1358
1359 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
cau3_lock_semaphore(CAU3_Type * base)1360 static status_t cau3_lock_semaphore(CAU3_Type *base)
1361 {
1362 uint32_t processorNumber = 0;
1363
1364 /* cm4 will be 1, cm0+ will be 2 */
1365 /* For next SoC, the processor number shall be defined in the SoC header file */
1366 #if __CORTEX_M == 0U
1367 processorNumber++;
1368 #endif
1369 processorNumber++;
1370
1371 while (processorNumber != SEMA42_GATEn(FSL_CAU3_SEMA42_BASE, 1))
1372 {
1373 /* Wait for unlocked status. */
1374 while (SEMA42_GATEn(FSL_CAU3_SEMA42_BASE, FSL_CAU3_SEMA42_GATE))
1375 {
1376 }
1377
1378 /* Lock the gate. */
1379 SEMA42_GATEn(FSL_CAU3_SEMA42_BASE, FSL_CAU3_SEMA42_GATE) = processorNumber;
1380 }
1381
1382 return cau3_execute_null_task(base, kCAU3_TaskDonePoll);
1383 }
1384 #endif /* FSL_CAU3_USE_HW_SEMA */
1385
1386 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
cau3_release_semaphore(CAU3_Type * base)1387 static void cau3_release_semaphore(CAU3_Type *base)
1388 {
1389 /* unlock the semaphore */
1390 SEMA42_GATEn(FSL_CAU3_SEMA42_BASE, FSL_CAU3_SEMA42_GATE) = 0;
1391 }
1392 #endif /* FSL_CAU3_USE_HW_SEMA */
1393
1394 /*!
1395 * @brief Load a 64-byte "key context" into the CAU3's private data memory
1396 *
1397 * Load the key context into the private DMEM. This includes size and config
1398 * information, a 16-byte initialization vector and a key of size [8,16,24,32]
1399 * bytes (for DES or AES-[128,192,256]). There is support for 4 "key slots" with
1400 * slot 0 typically used for the system key encryption key (KEK).
1401 *
1402 * See the GENERAL COMMENTS for more information on the keyContext structure.
1403 *
1404 * NOTE: This function also performs an AES key expansion if a keySize > 8
1405 * is specified.
1406 *
1407 * cau3_load_key_context
1408 * @param cauKeyContext is pointer to key structure in sysMemory
1409 * @param keySlot is the destination key slot number [0-3]
1410 * @param taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
1411 *
1412 * @return status check from task completion: CAU_[OK, ERROR]
1413 */
cau3_load_key_context(CAU3_Type * base,cau3_key_context_t * cauKeyContext,cau3_key_slot_t keySlot,cau3_task_done_t taskDone)1414 static status_t cau3_load_key_context(CAU3_Type *base,
1415 cau3_key_context_t *cauKeyContext,
1416 cau3_key_slot_t keySlot,
1417 cau3_task_done_t taskDone)
1418 {
1419 status_t completionStatus;
1420
1421 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1422 completionStatus = cau3_lock_semaphore(base);
1423 if (kStatus_Success != completionStatus)
1424 {
1425 cau3_release_semaphore(base);
1426 return completionStatus;
1427 }
1428 #endif
1429
1430 /* execute the cau3 "load key context" task */
1431 base->CC_R[16] = (uint32_t)cauKeyContext; /* pKeyContext */
1432 base->CC_R[17] = keySlot; /* keySlot */
1433 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
1434 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
1435 base->CC_PC = CAU3_TASK_LD_KEYCTX; /* call cau_load_key_context() */
1436 base->CC_CMD = taskDone; /* trigger cau3 execution */
1437
1438 /* process the cau3 task completion signal specified by taskDone */
1439 completionStatus = cau3_process_task_completion(base, taskDone);
1440 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1441 cau3_release_semaphore(base);
1442 #endif
1443 return (completionStatus);
1444 }
1445
CAU3_ForceError(CAU3_Type * base,cau3_task_done_t taskDone)1446 status_t CAU3_ForceError(CAU3_Type *base, cau3_task_done_t taskDone)
1447 {
1448 status_t completionStatus;
1449
1450 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1451 completionStatus = cau3_lock_semaphore(base);
1452 if (kStatus_Success != completionStatus)
1453 {
1454 cau3_release_semaphore(base);
1455 return completionStatus;
1456 }
1457 #endif
1458
1459 /* execute the cau3 null task */
1460 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
1461 base->CC_R31 = 0; /* set LR = 0 to signal a host task */
1462 base->CC_PC = CAU3_TASK_STOPERROR;
1463 base->CC_CMD = taskDone; /* trigger cau3 execution */
1464
1465 /* process the cau3 task completion signal specified by taskDone */
1466 completionStatus = cau3_process_task_completion(base, taskDone);
1467 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1468 cau3_release_semaphore(base);
1469 #endif
1470 return (completionStatus);
1471 }
1472
CAU3_LoadSpecialKeyContext(CAU3_Type * base,size_t keySize,cau3_key_slot_t keySlot,cau3_task_done_t taskDone)1473 status_t CAU3_LoadSpecialKeyContext(CAU3_Type *base, size_t keySize, cau3_key_slot_t keySlot, cau3_task_done_t taskDone)
1474 {
1475 status_t completionStatus;
1476
1477 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1478 completionStatus = cau3_lock_semaphore(base);
1479 if (kStatus_Success != completionStatus)
1480 {
1481 cau3_release_semaphore(base);
1482 return completionStatus;
1483 }
1484 #endif
1485
1486 /* execute the cau3 "load special key context" task */
1487 base->CC_R[16] = keySize; /* keySize [8,16,24,32] */
1488 base->CC_R[17] = keySlot; /* keySlot */
1489 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
1490 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
1491 base->CC_PC = CAU3_TASK_LD_SP_KEYCTX; /* call cau_load_special_key_context() */
1492 base->CC_CMD = taskDone; /* trigger cau3 execution */
1493
1494 /* process the cau3 task completion signal specified by taskDone */
1495 completionStatus = cau3_process_task_completion(base, taskDone);
1496 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1497 cau3_release_semaphore(base);
1498 #endif
1499 return (completionStatus);
1500 }
1501
CAU3_ClearKeyContext(CAU3_Type * base,cau3_key_slot_t keySlot,cau3_task_done_t taskDone)1502 status_t CAU3_ClearKeyContext(CAU3_Type *base, cau3_key_slot_t keySlot, cau3_task_done_t taskDone)
1503 {
1504 uint32_t completionStatus;
1505
1506 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1507 completionStatus = cau3_lock_semaphore(base);
1508 if (kStatus_Success != completionStatus)
1509 {
1510 cau3_release_semaphore(base);
1511 return completionStatus;
1512 }
1513 #endif
1514
1515 /* execute the cau3 "clear key context" task */
1516 base->CC_R[17] = keySlot; /* keySlot */
1517 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
1518 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
1519 base->CC_PC = CAU3_TASK_CLR_KEYCTX; /* call cau_clear_key_context() */
1520 base->CC_CMD = taskDone; /* trigger cau3 execution */
1521
1522 /* process the cau3 task completion signal specified by taskDone */
1523 completionStatus = cau3_process_task_completion(base, taskDone);
1524 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1525 cau3_release_semaphore(base);
1526 #endif
1527 return (completionStatus);
1528 }
1529
CAU3_LoadKeyInitVector(CAU3_Type * base,const uint8_t * iv,cau3_key_slot_t keySlot,cau3_task_done_t taskDone)1530 status_t CAU3_LoadKeyInitVector(CAU3_Type *base, const uint8_t *iv, cau3_key_slot_t keySlot, cau3_task_done_t taskDone)
1531 {
1532 status_t completionStatus;
1533
1534 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1535 completionStatus = cau3_lock_semaphore(base);
1536 if (kStatus_Success != completionStatus)
1537 {
1538 cau3_release_semaphore(base);
1539 return completionStatus;
1540 }
1541 #endif
1542
1543 /* execute the cau3 "load initialization vector into key context" task */
1544 base->CC_R[16] = (uintptr_t)iv; /* pIv */
1545 base->CC_R[17] = keySlot; /* keySlot */
1546 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
1547 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
1548 base->CC_PC = CAU3_TASK_LD_IV; /* call cau_load_iv() */
1549 base->CC_CMD = taskDone; /* trigger cau3 execution */
1550
1551 /* process the cau3 task completion signal specified by taskDone */
1552 completionStatus = cau3_process_task_completion(base, taskDone);
1553 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1554 cau3_release_semaphore(base);
1555 #endif
1556 return (completionStatus);
1557 }
1558
CAU3_AES_KeyExpansion(CAU3_Type * base,cau3_key_slot_t keySlot,cau3_task_done_t taskDone)1559 status_t CAU3_AES_KeyExpansion(CAU3_Type *base, cau3_key_slot_t keySlot, cau3_task_done_t taskDone)
1560 {
1561 status_t completionStatus;
1562
1563 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1564 completionStatus = cau3_lock_semaphore(base);
1565 if (kStatus_Success != completionStatus)
1566 {
1567 cau3_release_semaphore(base);
1568 return completionStatus;
1569 }
1570 #endif
1571
1572 /* execute the cau3 "aes_key_expansion" task */
1573 base->CC_R[17] = keySlot; /* keySlot */
1574 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
1575 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
1576 base->CC_PC = CAU3_TASK_AES_KEY_SCH; /* call cau_aes_key_sched() */
1577 base->CC_CMD = taskDone; /* trigger cau3 execution */
1578
1579 /* process the cau3 task completion signal specified by taskDone */
1580 completionStatus = cau3_process_task_completion(base, taskDone);
1581 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1582 cau3_release_semaphore(base);
1583 #endif
1584 return (completionStatus);
1585 }
1586
CAU3_AES_SetKey(CAU3_Type * base,cau3_handle_t * handle,const uint8_t * key,size_t keySize)1587 status_t CAU3_AES_SetKey(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *key, size_t keySize)
1588 {
1589 cau3_key_context_t cau3KeyCtx = {0};
1590
1591 /* only work with aligned key[] */
1592 if (0x3U & (uintptr_t)key)
1593 {
1594 return kStatus_InvalidArgument;
1595 }
1596
1597 /* keySize must be 16 or 32. initial CAU3 firmware doesn't support 24 bytes. */
1598 if ((keySize != 16U) && (keySize != 32U))
1599 {
1600 return kStatus_InvalidArgument;
1601 }
1602
1603 cau3KeyCtx.keySize = keySize;
1604
1605 /* move the key by 32-bit words */
1606 int i = 0;
1607 while (keySize)
1608 {
1609 keySize -= sizeof(uint32_t);
1610 ((uint32_t *)((uintptr_t)cau3KeyCtx.key))[i] = ((uint32_t *)(uintptr_t)key)[i];
1611 i++;
1612 }
1613
1614 return cau3_load_key_context(base, &cau3KeyCtx, handle->keySlot, handle->taskDone);
1615 }
1616
CAU3_AES_Cmac(CAU3_Type * base,cau3_handle_t * handle,const uint8_t * message,size_t size,uint8_t * mac)1617 status_t CAU3_AES_Cmac(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *message, size_t size, uint8_t *mac)
1618 {
1619 status_t completionStatus;
1620
1621 /* mac must be 0-mod-4 aligned */
1622 if (0x3U & (uintptr_t)mac)
1623 {
1624 return kStatus_InvalidArgument;
1625 }
1626
1627 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1628 completionStatus = cau3_lock_semaphore(base);
1629 if (kStatus_Success != completionStatus)
1630 {
1631 cau3_release_semaphore(base);
1632 return completionStatus;
1633 }
1634 #endif
1635
1636 /* execute the cau3 "aes_cmac" task */
1637 base->CC_R[16] = (uintptr_t)message; /* pMessage */
1638 base->CC_R[17] = handle->keySlot; /* keySlot */
1639 base->CC_R[18] = size; /* messageSize */
1640 base->CC_R[19] = (uintptr_t)mac; /* pMac */
1641 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
1642 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
1643 base->CC_PC = CAU3_TASK_AES128_CMAC; /* call cau_aes128_cmac() */
1644 base->CC_CMD = handle->taskDone; /* trigger cau3 execution */
1645
1646 /* process the cau3 task completion signal specified by taskDone */
1647 completionStatus = cau3_process_task_completion(base, handle->taskDone);
1648 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1649 cau3_release_semaphore(base);
1650 #endif
1651 return (completionStatus);
1652 }
1653
1654 /*!
1655 * @brief Check validity of algoritm.
1656 *
1657 * This function checks the validity of input argument.
1658 *
1659 * @param algo Tested algorithm value.
1660 * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
1661 */
cau3_hash_check_input_alg(cau3_hash_algo_t algo)1662 static status_t cau3_hash_check_input_alg(cau3_hash_algo_t algo)
1663 {
1664 if ((algo != kCAU3_Sha256) && (algo != kCAU3_Sha1))
1665 {
1666 return kStatus_InvalidArgument;
1667 }
1668 return kStatus_Success;
1669 }
1670
1671 /*!
1672 * @brief Check validity of input arguments.
1673 *
1674 * This function checks the validity of input arguments.
1675 *
1676 * @param base CAU3 peripheral base address.
1677 * @param ctx Memory buffer given by user application where the CAU3_HASH_Init/CAU3_HASH_Update/CAU3_HASH_Finish store
1678 * context.
1679 * @param algo Tested algorithm value.
1680 * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
1681 */
cau3_hash_check_input_args(CAU3_Type * base,cau3_hash_ctx_t * ctx,cau3_hash_algo_t algo)1682 static status_t cau3_hash_check_input_args(CAU3_Type *base, cau3_hash_ctx_t *ctx, cau3_hash_algo_t algo)
1683 {
1684 /* Check validity of input algorithm */
1685 if (kStatus_Success != cau3_hash_check_input_alg(algo))
1686 {
1687 return kStatus_InvalidArgument;
1688 }
1689
1690 if ((NULL == ctx) || (NULL == base))
1691 {
1692 return kStatus_InvalidArgument;
1693 }
1694
1695 return kStatus_Success;
1696 }
1697
1698 /*!
1699 * @brief Check validity of internal software context.
1700 *
1701 * This function checks if the internal context structure looks correct.
1702 *
1703 * @param ctxInternal Internal context.
1704 * @param message Input message address.
1705 * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
1706 */
cau3_hash_check_context(cau3_hash_ctx_internal_t * ctxInternal,const uint8_t * message)1707 static status_t cau3_hash_check_context(cau3_hash_ctx_internal_t *ctxInternal, const uint8_t *message)
1708 {
1709 if ((NULL == message) || (NULL == ctxInternal) || (kStatus_Success != cau3_hash_check_input_alg(ctxInternal->algo)))
1710 {
1711 return kStatus_InvalidArgument;
1712 }
1713 return kStatus_Success;
1714 }
1715
1716 /*!
1717 * @brief Initialize message digest output state for SHA-1 hash
1718 *
1719 * Initializes the message digest output state for a SHA-1 hash.
1720 *
1721 * @param sha1State is message digest output in sysMemory in BE format
1722 * @param taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
1723 *
1724 * @retval status check from task completion: CAU_[OK, ERROR]
1725 */
1726
CAU3_Sha1InitializeOutput(CAU3_Type * base,uint32_t * sha1State,cau3_task_done_t taskDone)1727 static status_t CAU3_Sha1InitializeOutput(CAU3_Type *base, uint32_t *sha1State, cau3_task_done_t taskDone)
1728 {
1729 status_t completionStatus;
1730
1731 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1732 completionStatus = cau3_lock_semaphore(base);
1733 if (kStatus_Success != completionStatus)
1734 {
1735 cau3_release_semaphore(base);
1736 return completionStatus;
1737 }
1738 #endif
1739
1740 /* execute the cau3 "sha1_init_output" task */
1741 base->CC_R[29] = (uintptr_t)sha1State; /* pSha1State */
1742 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
1743 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
1744 base->CC_PC = CAU3_TASK_SHA1_INIT_STATE; /* call cau_sha1_init_state() */
1745 base->CC_CMD = taskDone; /* trigger cau3 execution */
1746
1747 /* process the cau3 task completion signal specified by taskDone */
1748 completionStatus = cau3_process_task_completion(base, taskDone);
1749 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1750 cau3_release_semaphore(base);
1751 #endif
1752 return (completionStatus);
1753 }
1754
1755 /*!
1756 * @brief Perform a SHA-1 hash function over a message of "n" 64-byte blocks
1757 *
1758 * Perform a SHA-1 hash function over a message of "n" 64-byte data blocks,
1759 * returning an 8-word message digest (aka "state"). The input message must
1760 * be padded appropriately as defined by the SHA-1 algorithm.
1761 *
1762 * @param message is the uint8_t input message, any alignment
1763 * @param numberOfBlocks is the message length as multiple of 64-byte blocks
1764 * @param sha1State is uint32_t message digest output (state) in BE format
1765 * @param taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
1766 *
1767 * @retval status check from task completion: CAU_[OK, ERROR]
1768 */
1769
CAU3_Sha1Update(CAU3_Type * base,const uint8_t * message,uint32_t numberOfBlocks,uint32_t * sha1State,cau3_task_done_t taskDone)1770 static status_t CAU3_Sha1Update(
1771 CAU3_Type *base, const uint8_t *message, uint32_t numberOfBlocks, uint32_t *sha1State, cau3_task_done_t taskDone)
1772 {
1773 status_t completionStatus;
1774
1775 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1776 completionStatus = cau3_lock_semaphore(base);
1777 if (kStatus_Success != completionStatus)
1778 {
1779 cau3_release_semaphore(base);
1780 return completionStatus;
1781 }
1782 #endif
1783
1784 /* execute the cau3 "sha1_update" task */
1785 base->CC_R[27] = (uintptr_t)message; /* pMessage */
1786 base->CC_R[28] = numberOfBlocks; /* n blocks */
1787 base->CC_R[29] = (uintptr_t)sha1State; /* output */
1788 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
1789 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
1790 base->CC_PC = CAU3_TASK_SHA1_HASH; /* call cau_sha1_hash_n() */
1791 base->CC_CMD = taskDone; /* trigger cau3 execution */
1792
1793 /* process the cau3 task completion signal specified by taskDone */
1794 completionStatus = cau3_process_task_completion(base, taskDone);
1795 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1796 cau3_release_semaphore(base);
1797 #endif
1798 return (completionStatus);
1799 }
1800
1801 /*!
1802 * @brief Initialize message digest output state for SHA-256 hash
1803 *
1804 * Initializes the message digest output state for a SHA-256 hash.
1805 *
1806 * CAU3_Sha256InitializeOutput
1807 * @param sha256State is message digest output in sysMemory in BE format
1808 * @param taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
1809 *
1810 * @retval status check from task completion: CAU_[OK, ERROR]
1811 */
1812
CAU3_Sha256InitializeOutput(CAU3_Type * base,uint32_t * sha256State,cau3_task_done_t taskDone)1813 status_t CAU3_Sha256InitializeOutput(CAU3_Type *base, uint32_t *sha256State, cau3_task_done_t taskDone)
1814 {
1815 status_t completionStatus;
1816
1817 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1818 completionStatus = cau3_lock_semaphore(base);
1819 if (kStatus_Success != completionStatus)
1820 {
1821 cau3_release_semaphore(base);
1822 return completionStatus;
1823 }
1824 #endif
1825
1826 /* execute the cau3 "sha256_init_output" task */
1827 base->CC_R[29] = (uint32_t)sha256State; /* pSha256State */
1828 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
1829 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
1830 base->CC_PC = CAU3_TASK_SHA256_INIT_STATE; /* call cau_sha256_init_state() */
1831 base->CC_CMD = taskDone; /* trigger cau3 execution */
1832
1833 /* process the cau3 task completion signal specified by taskDone */
1834 completionStatus = cau3_process_task_completion(base, taskDone);
1835 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1836 cau3_release_semaphore(base);
1837 #endif
1838 return (completionStatus);
1839 }
1840
1841 /*!
1842 * @brief Perform a SHA-256 hash function over a message of "n" 64-byte blocks
1843 *
1844 * Perform a SHA-256 hash function over a message of "n" 64-byte data blocks,
1845 * returning an 8-word message digest (aka "state"). The input message must
1846 * be padded appropriately as defined by the SHA-256 algorithm.
1847 *
1848 * CAU_Sha256Update
1849 * @param message is the uint8_t input message, LE, ANY ALIGNMENT
1850 * @param numberOfBlocks is the message length as multiple of 64-byte blocks
1851 * @param sha256State is uint32_t message digest output (state) in BE format
1852 * @param taskDone indicates completion signal: CAU_[POLL, IRQ, EVENT, DMAREQ]
1853 *
1854 * @retval status check from task completion: CAU_[OK, ERROR]
1855 */
1856
CAU3_Sha256Update(CAU3_Type * base,const uint8_t * message,uint32_t numberOfBlocks,uint32_t * sha256State,cau3_task_done_t taskDone)1857 status_t CAU3_Sha256Update(
1858 CAU3_Type *base, const uint8_t *message, uint32_t numberOfBlocks, uint32_t *sha256State, cau3_task_done_t taskDone)
1859 {
1860 status_t completionStatus;
1861
1862 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1863 completionStatus = cau3_lock_semaphore(base);
1864 if (kStatus_Success != completionStatus)
1865 {
1866 cau3_release_semaphore(base);
1867 return completionStatus;
1868 }
1869 #endif
1870
1871 /* execute the cau3 "sha256_update" task */
1872 base->CC_R[27] = (uint32_t)message; /* pMessage */
1873 base->CC_R[28] = numberOfBlocks; /* = (64*numberOfBlocks) bytes */
1874 base->CC_R[29] = (uint32_t)sha256State; /* pSha256State */
1875 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
1876 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
1877 base->CC_PC = CAU3_TASK_SHA256_UPDATE; /* call cau_sha256_update() */
1878 base->CC_CMD = taskDone; /* trigger cau3 execution */
1879
1880 /* process the cau3 task completion signal specified by taskDone */
1881 completionStatus = cau3_process_task_completion(base, taskDone);
1882 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
1883 cau3_release_semaphore(base);
1884 #endif
1885 return (completionStatus);
1886 }
1887
1888 /*!
1889 * @brief Initialize the SHA engine for new hash.
1890 *
1891 * This function sets NEW and MODE fields in SHA Control register to start new hash.
1892 *
1893 * @param base SHA peripheral base address.
1894 * @param ctxInternal Internal context.
1895 */
cau3_hash_engine_init(CAU3_Type * base,cau3_hash_ctx_internal_t * ctxInternal)1896 static status_t cau3_hash_engine_init(CAU3_Type *base, cau3_hash_ctx_internal_t *ctxInternal)
1897 {
1898 status_t status;
1899
1900 status = kStatus_InvalidArgument;
1901
1902 if (kCAU3_Sha256 == ctxInternal->algo)
1903 {
1904 status = CAU3_Sha256InitializeOutput(base, ctxInternal->runningHash, kCAU3_TaskDonePoll);
1905 }
1906
1907 if (kCAU3_Sha1 == ctxInternal->algo)
1908 {
1909 status = CAU3_Sha1InitializeOutput(base, ctxInternal->runningHash, kCAU3_TaskDonePoll);
1910 }
1911
1912 return status;
1913 }
1914
1915 /*!
1916 * @brief Adds message to current hash.
1917 *
1918 * This function merges the message to fill the internal buffer, empties the internal buffer if
1919 * it becomes full, then process all remaining message data.
1920 *
1921 *
1922 * @param base CAU3 peripheral base address.
1923 * @param ctxInternal Internal context.
1924 * @param message Input message.
1925 * @param messageSize Size of input message in bytes.
1926 * @return kStatus_Success.
1927 */
cau3_hash_process_message_data(CAU3_Type * base,cau3_hash_ctx_internal_t * ctxInternal,const uint8_t * message,size_t messageSize)1928 static status_t cau3_hash_process_message_data(CAU3_Type *base,
1929 cau3_hash_ctx_internal_t *ctxInternal,
1930 const uint8_t *message,
1931 size_t messageSize)
1932 {
1933 status_t status;
1934 status_t (*funcUpdate)(CAU3_Type * cau3base, const uint8_t *msg, uint32_t numberOfBlocks, uint32_t *shaState,
1935 cau3_task_done_t taskDone);
1936
1937 /* first fill the internal buffer to full block */
1938 size_t toCopy = CAU3_HASH_BLOCK_SIZE - ctxInternal->blksz;
1939 cau3_memcpy(&ctxInternal->blk.b[ctxInternal->blksz], message, toCopy);
1940 message += toCopy;
1941 messageSize -= toCopy;
1942
1943 status = kStatus_InvalidArgument;
1944 funcUpdate = NULL;
1945
1946 switch (ctxInternal->algo)
1947 {
1948 case kCAU3_Sha256:
1949 funcUpdate = CAU3_Sha256Update;
1950 break;
1951
1952 case kCAU3_Sha1:
1953 funcUpdate = CAU3_Sha1Update;
1954 break;
1955
1956 default:
1957 break;
1958 }
1959
1960 if (NULL != funcUpdate)
1961 {
1962 /* process full internal block */
1963 status = funcUpdate(base, &ctxInternal->blk.b[0], CAU3_HASH_BLOCK_SIZE / 64u, ctxInternal->runningHash,
1964 kCAU3_TaskDonePoll);
1965 if (kStatus_Success != status)
1966 {
1967 return status;
1968 }
1969
1970 /* process all full blocks in message[] */
1971 while (messageSize >= CAU3_HASH_BLOCK_SIZE)
1972 {
1973 status =
1974 funcUpdate(base, message, CAU3_HASH_BLOCK_SIZE / 64u, ctxInternal->runningHash, kCAU3_TaskDonePoll);
1975 if (kStatus_Success != status)
1976 {
1977 return status;
1978 }
1979 message += CAU3_HASH_BLOCK_SIZE;
1980 messageSize -= CAU3_HASH_BLOCK_SIZE;
1981 }
1982
1983 /* copy last incomplete message bytes into internal block */
1984 cau3_memcpy(&ctxInternal->blk.b[0], message, messageSize);
1985 ctxInternal->blksz = messageSize;
1986 }
1987
1988 return status;
1989 }
1990
1991 /*!
1992 * @brief Finalize the running hash to make digest.
1993 *
1994 * This function empties the internal buffer, adds padding bits, and generates final digest.
1995 *
1996 * @param base SHA peripheral base address.
1997 * @param ctxInternal Internal context.
1998 * @return kStatus_Success.
1999 */
cau3_hash_finalize(CAU3_Type * base,cau3_hash_ctx_internal_t * ctxInternal)2000 static status_t cau3_hash_finalize(CAU3_Type *base, cau3_hash_ctx_internal_t *ctxInternal)
2001 {
2002 cau3_sha_block_t lastBlock;
2003 status_t status;
2004 status_t (*funcUpdate)(CAU3_Type * cau3base, const uint8_t *msg, uint32_t numberOfBlocks, uint32_t *shaState,
2005 cau3_task_done_t taskDone);
2006
2007 status = kStatus_InvalidArgument;
2008 funcUpdate = NULL;
2009
2010 switch (ctxInternal->algo)
2011 {
2012 case kCAU3_Sha256:
2013 funcUpdate = CAU3_Sha256Update;
2014 break;
2015
2016 case kCAU3_Sha1:
2017 funcUpdate = CAU3_Sha1Update;
2018 break;
2019
2020 default:
2021 break;
2022 }
2023
2024 if (NULL == funcUpdate)
2025 {
2026 return kStatus_InvalidArgument;
2027 }
2028
2029 memset(&lastBlock, 0, sizeof(cau3_sha_block_t));
2030 status = kStatus_Success;
2031
2032 while (ctxInternal->blksz >= 64u)
2033 {
2034 status = funcUpdate(base, &ctxInternal->blk.b[0], 1, ctxInternal->runningHash, kCAU3_TaskDonePoll);
2035 if (kStatus_Success != status)
2036 {
2037 return status;
2038 }
2039 ctxInternal->blksz -= 64u;
2040 cau3_memcpy(&ctxInternal->blk.b[0], &ctxInternal->blk.b[64], ctxInternal->blksz);
2041 }
2042
2043 /* this is last call, so need to flush buffered message bytes along with padding */
2044 if (ctxInternal->blksz <= 55u)
2045 {
2046 /* last data is 440 bits or less. */
2047 cau3_memcpy(&lastBlock.b[0], &ctxInternal->blk.b[0], ctxInternal->blksz);
2048 lastBlock.b[ctxInternal->blksz] = (uint8_t)0x80U;
2049 lastBlock.w[15] = __REV(8u * ctxInternal->fullMessageSize);
2050 status = funcUpdate(base, &lastBlock.b[0], 1, ctxInternal->runningHash, kCAU3_TaskDonePoll);
2051 if (kStatus_Success != status)
2052 {
2053 return status;
2054 }
2055 }
2056 else
2057 {
2058 if (ctxInternal->blksz < 64u)
2059 {
2060 ctxInternal->blk.b[ctxInternal->blksz] = (uint8_t)0x80U;
2061 for (uint32_t i = ctxInternal->blksz + 1u; i < 64u; i++)
2062 {
2063 ctxInternal->blk.b[i] = 0;
2064 }
2065 }
2066 else
2067 {
2068 lastBlock.b[0] = (uint8_t)0x80U;
2069 }
2070
2071 status = funcUpdate(base, &ctxInternal->blk.b[0], 1, ctxInternal->runningHash, kCAU3_TaskDonePoll);
2072 if (kStatus_Success != status)
2073 {
2074 return status;
2075 }
2076 lastBlock.w[15] = __REV(8u * ctxInternal->fullMessageSize);
2077 status = funcUpdate(base, &lastBlock.b[0], 1, ctxInternal->runningHash, kCAU3_TaskDonePoll);
2078 if (kStatus_Success != status)
2079 {
2080 return status;
2081 }
2082 }
2083 return status;
2084 }
2085
CAU3_HASH_Init(CAU3_Type * base,cau3_hash_ctx_t * ctx,cau3_hash_algo_t algo)2086 status_t CAU3_HASH_Init(CAU3_Type *base, cau3_hash_ctx_t *ctx, cau3_hash_algo_t algo)
2087 {
2088 status_t status;
2089
2090 cau3_hash_ctx_internal_t *ctxInternal;
2091 /* compile time check for the correct structure size */
2092 BUILD_ASSURE(sizeof(cau3_hash_ctx_t) >= sizeof(cau3_hash_ctx_internal_t), cau3_hash_ctx_t_size);
2093 uint32_t i;
2094
2095 status = cau3_hash_check_input_args(base, ctx, algo);
2096 if (status != kStatus_Success)
2097 {
2098 return status;
2099 }
2100
2101 /* set algorithm in context struct for later use */
2102 ctxInternal = (cau3_hash_ctx_internal_t *)ctx;
2103 ctxInternal->algo = algo;
2104 ctxInternal->blksz = 0u;
2105 for (i = 0; i < sizeof(ctxInternal->blk.w) / sizeof(ctxInternal->blk.w[0]); i++)
2106 {
2107 ctxInternal->blk.w[0] = 0u;
2108 }
2109 ctxInternal->state = kCAU3_StateHashInit;
2110 ctxInternal->fullMessageSize = 0;
2111
2112 return status;
2113 }
2114
CAU3_HASH_Update(CAU3_Type * base,cau3_hash_ctx_t * ctx,const uint8_t * input,size_t inputSize)2115 status_t CAU3_HASH_Update(CAU3_Type *base, cau3_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize)
2116 {
2117 bool isUpdateState;
2118 status_t status;
2119 cau3_hash_ctx_internal_t *ctxInternal;
2120 size_t blockSize;
2121
2122 if (inputSize == 0)
2123 {
2124 return kStatus_Success;
2125 }
2126
2127 ctxInternal = (cau3_hash_ctx_internal_t *)ctx;
2128 status = cau3_hash_check_context(ctxInternal, input);
2129 if (kStatus_Success != status)
2130 {
2131 return status;
2132 }
2133
2134 ctxInternal->fullMessageSize += inputSize;
2135 blockSize = CAU3_HASH_BLOCK_SIZE;
2136 /* if we are still less than CAU3_HASH_BLOCK_SIZE bytes, keep only in context */
2137 if ((ctxInternal->blksz + inputSize) <= blockSize)
2138 {
2139 cau3_memcpy((&ctxInternal->blk.b[0]) + ctxInternal->blksz, input, inputSize);
2140 ctxInternal->blksz += inputSize;
2141 return status;
2142 }
2143 else
2144 {
2145 isUpdateState = ctxInternal->state == kCAU3_StateHashUpdate;
2146 if (!isUpdateState)
2147 {
2148 /* start NEW hash */
2149 status = cau3_hash_engine_init(base, ctxInternal);
2150 if (status != kStatus_Success)
2151 {
2152 return status;
2153 }
2154 ctxInternal->state = kCAU3_StateHashUpdate;
2155 }
2156 }
2157
2158 /* process input data */
2159 status = cau3_hash_process_message_data(base, ctxInternal, input, inputSize);
2160 return status;
2161 }
2162
CAU3_HASH_Finish(CAU3_Type * base,cau3_hash_ctx_t * ctx,uint8_t * output,size_t * outputSize)2163 status_t CAU3_HASH_Finish(CAU3_Type *base, cau3_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize)
2164 {
2165 size_t algOutSize = 0;
2166 status_t status;
2167 cau3_hash_ctx_internal_t *ctxInternal;
2168
2169 ctxInternal = (cau3_hash_ctx_internal_t *)ctx;
2170 status = cau3_hash_check_context(ctxInternal, output);
2171 if (kStatus_Success != status)
2172 {
2173 return status;
2174 }
2175
2176 if (ctxInternal->state == kCAU3_StateHashInit)
2177 {
2178 status = cau3_hash_engine_init(base, ctxInternal);
2179 if (status != kStatus_Success)
2180 {
2181 return status;
2182 }
2183 }
2184
2185 size_t outSize = 0u;
2186
2187 /* compute algorithm output length */
2188 switch (ctxInternal->algo)
2189 {
2190 case kCAU3_Sha256:
2191 outSize = kCAU3_OutLenSha256;
2192 break;
2193 case kCAU3_Sha1:
2194 outSize = kCAU3_OutLenSha1;
2195 break;
2196 default:
2197 break;
2198 }
2199 algOutSize = outSize;
2200
2201 /* flush message last incomplete block, if there is any, and add padding bits */
2202 status = cau3_hash_finalize(base, ctxInternal);
2203
2204 if (outputSize)
2205 {
2206 if (algOutSize < *outputSize)
2207 {
2208 *outputSize = algOutSize;
2209 }
2210 else
2211 {
2212 algOutSize = *outputSize;
2213 }
2214 }
2215
2216 cau3_memcpy(&output[0], ctxInternal->runningHash, algOutSize);
2217
2218 memset(ctx, 0, sizeof(cau3_hash_ctx_t));
2219 return status;
2220 }
2221
CAU3_HASH(CAU3_Type * base,cau3_hash_algo_t algo,const uint8_t * input,size_t inputSize,uint8_t * output,size_t * outputSize)2222 status_t CAU3_HASH(
2223 CAU3_Type *base, cau3_hash_algo_t algo, const uint8_t *input, size_t inputSize, uint8_t *output, size_t *outputSize)
2224 {
2225 cau3_hash_ctx_t hashCtx;
2226 status_t status;
2227
2228 status = CAU3_HASH_Init(base, &hashCtx, algo);
2229 if (status != kStatus_Success)
2230 {
2231 return status;
2232 }
2233
2234 status = CAU3_HASH_Update(base, &hashCtx, input, inputSize);
2235 if (status != kStatus_Success)
2236 {
2237 return status;
2238 }
2239
2240 status = CAU3_HASH_Finish(base, &hashCtx, output, outputSize);
2241
2242 return status;
2243 }
2244
2245 /*! @brief CAU3 driver wait mechanism. */
cau3_wait(CAU3_Type * base)2246 status_t cau3_wait(CAU3_Type *base)
2247 {
2248 status_t status;
2249
2250 bool error = false;
2251 bool done = false;
2252
2253 /* Wait for 'done' or 'error' flag. */
2254 while ((!error) && (!done))
2255 {
2256 uint32_t temp32 = base->STA;
2257 error = temp32 & kCAU3_StatusErrorIsr;
2258 done = temp32 & kCAU3_StatusDoneIsr;
2259 }
2260
2261 if (error)
2262 {
2263 base->COM = CAU3_COM_ALL_MASK; /* Reset all engine to clear the error flag */
2264 status = kStatus_Fail;
2265 }
2266 else /* 'done' */
2267 {
2268 status = kStatus_Success;
2269
2270 base->CW = kCAU3_ClearDataSize;
2271 /* Clear 'done' interrupt status. This also clears the mode register. */
2272 base->STA = kCAU3_StatusDoneIsr;
2273 }
2274
2275 return status;
2276 }
2277
2278 /*!
2279 * @brief Clears the CAU3 module.
2280 * This function can be used to clear all sensitive data from theCAU3 module, such as private keys. It is called
2281 * internally by the CAU3 driver in case of an error or operation complete.
2282 * @param base CAU3 peripheral base address
2283 * @param pkha Include CAU3 PKHA register clear. If there is no PKHA, the argument is ignored.
2284 */
cau3_clear_all(CAU3_Type * base,bool addPKHA)2285 void cau3_clear_all(CAU3_Type *base, bool addPKHA)
2286 {
2287 base->CW = (uint32_t)kCAU3_ClearAll;
2288 if (addPKHA)
2289 {
2290 cau3_pkha_clear_regabne(base, true, true, true, true);
2291 }
2292 }
2293
2294 /*!
2295 * @brief Reads an unaligned word.
2296 *
2297 * This function creates a 32-bit word from an input array of four bytes.
2298 *
2299 * @param src Input array of four bytes. The array can start at any address in memory.
2300 * @return 32-bit unsigned int created from the input byte array.
2301 */
cau3_get_word_from_unaligned(const uint8_t * srcAddr)2302 static inline uint32_t cau3_get_word_from_unaligned(const uint8_t *srcAddr)
2303 {
2304 #if (!(defined(__CORTEX_M)) || (defined(__CORTEX_M) && (__CORTEX_M == 0)))
2305 register const uint8_t *src = srcAddr;
2306 /* Cortex M0 does not support misaligned loads */
2307 if ((uint32_t)src & 0x3u)
2308 {
2309 union _align_bytes_t {
2310 uint32_t word;
2311 uint8_t byte[sizeof(uint32_t)];
2312 } my_bytes;
2313
2314 my_bytes.byte[0] = *src;
2315 my_bytes.byte[1] = *(src + 1);
2316 my_bytes.byte[2] = *(src + 2);
2317 my_bytes.byte[3] = *(src + 3);
2318 return my_bytes.word;
2319 }
2320 else
2321 {
2322 /* addr aligned to 0-modulo-4 so it is safe to type cast */
2323 return *((const uint32_t *)src);
2324 }
2325 #elif defined(__CC_ARM)
2326 /* -O3 optimization in Keil Compiler 5 uses LDM instruction here (LDM r4!, {r0})
2327 * which is wrong, because srcAddr might be unaligned.
2328 * LDM on unaligned address causes hard-fault. so use memcpy() */
2329 uint32_t ret;
2330 memcpy(&ret, srcAddr, sizeof(uint32_t));
2331 return ret;
2332 #else
2333 return *((const uint32_t *)srcAddr);
2334 #endif
2335 }
2336
2337 /*******************************************************************************
2338 * PKHA Code static
2339 ******************************************************************************/
2340
cau3_pkha_clear_regabne(CAU3_Type * base,bool A,bool B,bool N,bool E)2341 static status_t cau3_pkha_clear_regabne(CAU3_Type *base, bool A, bool B, bool N, bool E)
2342 {
2343 cau3_mode_t mode;
2344
2345 /* Set the PKHA algorithm and the appropriate function. */
2346 mode = (uint32_t)kCAU3_AlgorithmPKHA | 1U;
2347
2348 /* Set ram area to clear. Clear all. */
2349 if (A)
2350 {
2351 mode |= 1U << 19U;
2352 }
2353 if (B)
2354 {
2355 mode |= 1U << 18U;
2356 }
2357 if (N)
2358 {
2359 mode |= 1U << 16U;
2360 }
2361 if (E)
2362 {
2363 mode |= 1U << 17U;
2364 }
2365
2366 /* Write the mode register to the hardware.
2367 * NOTE: This will begin the operation. */
2368 base->MDPK = mode;
2369
2370 /* Wait for 'done' */
2371 return cau3_wait(base);
2372 }
2373
cau3_pkha_default_parms(cau3_pkha_mode_params_t * params)2374 static void cau3_pkha_default_parms(cau3_pkha_mode_params_t *params)
2375 {
2376 params->func = (cau3_pkha_func_t)0;
2377 params->arithType = kCAU3_PKHA_IntegerArith;
2378 params->montFormIn = kCAU3_PKHA_NormalValue;
2379 params->montFormOut = kCAU3_PKHA_NormalValue;
2380 params->srcReg = kCAU3_PKHA_RegAll;
2381 params->srcQuad = kCAU3_PKHA_Quad0;
2382 params->dstReg = kCAU3_PKHA_RegAll;
2383 params->dstQuad = kCAU3_PKHA_Quad0;
2384 params->equalTime = kCAU3_PKHA_NoTimingEqualized;
2385 params->r2modn = kCAU3_PKHA_CalcR2;
2386 }
2387
cau3_pkha_write_word(CAU3_Type * base,cau3_pkha_reg_area_t reg,uint8_t index,uint32_t data)2388 static void cau3_pkha_write_word(CAU3_Type *base, cau3_pkha_reg_area_t reg, uint8_t index, uint32_t data)
2389 {
2390 __IO uint32_t *pka = base->PKA0;
2391 __IO uint32_t *pkb = base->PKB0;
2392 __IO uint32_t *pkn = base->PKN0;
2393
2394 switch (reg)
2395 {
2396 case kCAU3_PKHA_RegA:
2397 pka[index] = data;
2398 break;
2399
2400 case kCAU3_PKHA_RegB:
2401 pkb[index] = data;
2402 break;
2403
2404 case kCAU3_PKHA_RegN:
2405 pkn[index] = data;
2406 break;
2407
2408 case kCAU3_PKHA_RegE:
2409 base->PKE[index] = data;
2410 break;
2411
2412 default:
2413 break;
2414 }
2415 }
2416
cau3_pkha_read_word(CAU3_Type * base,cau3_pkha_reg_area_t reg,uint8_t index)2417 static uint32_t cau3_pkha_read_word(CAU3_Type *base, cau3_pkha_reg_area_t reg, uint8_t index)
2418 {
2419 uint32_t retval;
2420 __IO uint32_t *pka = base->PKA0;
2421 __IO uint32_t *pkb = base->PKB0;
2422 __IO uint32_t *pkn = base->PKN0;
2423
2424 switch (reg)
2425 {
2426 case kCAU3_PKHA_RegA:
2427 retval = pka[index];
2428 break;
2429
2430 case kCAU3_PKHA_RegB:
2431 retval = pkb[index];
2432 break;
2433
2434 case kCAU3_PKHA_RegN:
2435 retval = pkn[index];
2436 break;
2437
2438 default:
2439 retval = 0;
2440 break;
2441 }
2442 return retval;
2443 }
2444
cau3_pkha_write_reg(CAU3_Type * base,cau3_pkha_reg_area_t reg,uint8_t quad,const uint8_t * data,size_t dataSize)2445 static status_t cau3_pkha_write_reg(
2446 CAU3_Type *base, cau3_pkha_reg_area_t reg, uint8_t quad, const uint8_t *data, size_t dataSize)
2447 {
2448 /* Select the word-based start index for each quadrant of 128 bytes. */
2449 uint8_t startIndex = (quad * 32u);
2450 uint32_t outWord;
2451
2452 while (dataSize > 0)
2453 {
2454 if (dataSize >= sizeof(uint32_t))
2455 {
2456 cau3_pkha_write_word(base, reg, startIndex++, cau3_get_word_from_unaligned(data));
2457 dataSize -= sizeof(uint32_t);
2458 data += sizeof(uint32_t);
2459 }
2460 else /* (dataSize > 0) && (dataSize < 4) */
2461 {
2462 outWord = 0;
2463 cau3_memcpy(&outWord, data, dataSize);
2464 cau3_pkha_write_word(base, reg, startIndex, outWord);
2465 dataSize = 0;
2466 }
2467 }
2468
2469 return kStatus_Success;
2470 }
2471
cau3_pkha_read_reg(CAU3_Type * base,cau3_pkha_reg_area_t reg,uint8_t quad,uint8_t * data,size_t dataSize)2472 static void cau3_pkha_read_reg(CAU3_Type *base, cau3_pkha_reg_area_t reg, uint8_t quad, uint8_t *data, size_t dataSize)
2473 {
2474 /* Select the word-based start index for each quadrant of 128 bytes. */
2475 uint8_t startIndex = (quad * 32u);
2476 size_t calcSize;
2477 uint32_t word;
2478
2479 while (dataSize > 0)
2480 {
2481 word = cau3_pkha_read_word(base, reg, startIndex++);
2482
2483 calcSize = (dataSize >= sizeof(uint32_t)) ? sizeof(uint32_t) : dataSize;
2484 cau3_memcpy(data, &word, calcSize);
2485
2486 data += calcSize;
2487 dataSize -= calcSize;
2488 }
2489 }
2490
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)2491 static void cau3_pkha_init_data(CAU3_Type *base,
2492 const uint8_t *A,
2493 size_t sizeA,
2494 const uint8_t *B,
2495 size_t sizeB,
2496 const uint8_t *N,
2497 size_t sizeN,
2498 const uint8_t *E,
2499 size_t sizeE)
2500 {
2501 uint32_t clearMask = kCAU3_ClearMode; /* clear Mode Register */
2502
2503 /* Clear internal register states. */
2504 if (sizeA)
2505 {
2506 clearMask |= kCAU3_ClearPkhaSizeA;
2507 }
2508 if (sizeB)
2509 {
2510 clearMask |= kCAU3_ClearPkhaSizeB;
2511 }
2512 if (sizeN)
2513 {
2514 clearMask |= kCAU3_ClearPkhaSizeN;
2515 }
2516 if (sizeE)
2517 {
2518 clearMask |= kCAU3_ClearPkhaSizeE;
2519 }
2520
2521 base->CW = clearMask;
2522 base->STA = kCAU3_StatusDoneIsr;
2523 cau3_pkha_clear_regabne(base, A, B, N, E);
2524
2525 /* Write register sizes. */
2526 /* Write modulus (N) and A and B register arguments. */
2527 if (sizeN)
2528 {
2529 base->PKNSZ = sizeN;
2530 if (N)
2531 {
2532 cau3_pkha_write_reg(base, kCAU3_PKHA_RegN, 0, N, sizeN);
2533 }
2534 }
2535
2536 if (sizeA)
2537 {
2538 base->PKASZ = sizeA;
2539 if (A)
2540 {
2541 cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 0, A, sizeA);
2542 }
2543 }
2544
2545 if (sizeB)
2546 {
2547 base->PKBSZ = sizeB;
2548 if (B)
2549 {
2550 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 0, B, sizeB);
2551 }
2552 }
2553
2554 if (sizeE)
2555 {
2556 base->PKESZ = sizeE;
2557 if (E)
2558 {
2559 cau3_pkha_write_reg(base, kCAU3_PKHA_RegE, 0, E, sizeE);
2560 }
2561 }
2562 }
2563
cau3_pkha_mode_set_src_reg_copy(cau3_mode_t * outMode,cau3_pkha_reg_area_t reg)2564 static void cau3_pkha_mode_set_src_reg_copy(cau3_mode_t *outMode, cau3_pkha_reg_area_t reg)
2565 {
2566 int i = 0;
2567
2568 do
2569 {
2570 reg = (cau3_pkha_reg_area_t)(((uint32_t)reg) >> 1u);
2571 i++;
2572 } while (reg);
2573
2574 i = 4 - i;
2575 /* Source register must not be E. */
2576 if (i != 2)
2577 {
2578 *outMode |= ((uint32_t)i << 17u);
2579 }
2580 }
2581
cau3_pkha_mode_set_dst_reg_copy(cau3_mode_t * outMode,cau3_pkha_reg_area_t reg)2582 static void cau3_pkha_mode_set_dst_reg_copy(cau3_mode_t *outMode, cau3_pkha_reg_area_t reg)
2583 {
2584 int i = 0;
2585
2586 do
2587 {
2588 reg = (cau3_pkha_reg_area_t)(((uint32_t)reg) >> 1u);
2589 i++;
2590 } while (reg);
2591
2592 i = 4 - i;
2593 *outMode |= ((uint32_t)i << 10u);
2594 }
2595
cau3_pkha_mode_set_src_seg_copy(cau3_mode_t * outMode,const cau3_pkha_quad_area_t quad)2596 static void cau3_pkha_mode_set_src_seg_copy(cau3_mode_t *outMode, const cau3_pkha_quad_area_t quad)
2597 {
2598 *outMode |= ((uint32_t)quad << 8u);
2599 }
2600
cau3_pkha_mode_set_dst_seg_copy(cau3_mode_t * outMode,const cau3_pkha_quad_area_t quad)2601 static void cau3_pkha_mode_set_dst_seg_copy(cau3_mode_t *outMode, const cau3_pkha_quad_area_t quad)
2602 {
2603 *outMode |= ((uint32_t)quad << 6u);
2604 }
2605
2606 /*!
2607 * @brief Starts the PKHA operation.
2608 *
2609 * This function starts an operation configured by the params parameter.
2610 *
2611 * @param base CAU3 peripheral base address
2612 * @param params Configuration structure containing all settings required for PKHA operation.
2613 */
cau3_pkha_init_mode(CAU3_Type * base,const cau3_pkha_mode_params_t * params)2614 static status_t cau3_pkha_init_mode(CAU3_Type *base, const cau3_pkha_mode_params_t *params)
2615 {
2616 cau3_mode_t modeReg;
2617 status_t retval;
2618
2619 /* Set the PKHA algorithm and the appropriate function. */
2620 modeReg = kCAU3_AlgorithmPKHA;
2621 modeReg |= (uint32_t)params->func;
2622
2623 if ((params->func == kCAU3_PKHA_CopyMemSizeN) || (params->func == kCAU3_PKHA_CopyMemSizeSrc))
2624 {
2625 /* Set source and destination registers and quads. */
2626 cau3_pkha_mode_set_src_reg_copy(&modeReg, params->srcReg);
2627 cau3_pkha_mode_set_dst_reg_copy(&modeReg, params->dstReg);
2628 cau3_pkha_mode_set_src_seg_copy(&modeReg, params->srcQuad);
2629 cau3_pkha_mode_set_dst_seg_copy(&modeReg, params->dstQuad);
2630 }
2631 else
2632 {
2633 /* Set the arithmetic type - integer or binary polynomial (F2m). */
2634 modeReg |= ((uint32_t)params->arithType << 17u);
2635
2636 /* Set to use Montgomery form of inputs and/or outputs. */
2637 modeReg |= ((uint32_t)params->montFormIn << 19u);
2638 modeReg |= ((uint32_t)params->montFormOut << 18u);
2639
2640 /* Set to use pre-computed R2modN */
2641 modeReg |= ((uint32_t)params->r2modn << 16u);
2642 }
2643
2644 modeReg |= ((uint32_t)params->equalTime << 10u);
2645
2646 /* Write the mode register to the hardware.
2647 * NOTE: This will begin the operation. */
2648 base->MDPK = modeReg;
2649
2650 retval = cau3_wait(base);
2651 return (retval);
2652 }
2653
cau3_pkha_modR2(CAU3_Type * base,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,cau3_pkha_f2m_t arithType)2654 static status_t cau3_pkha_modR2(
2655 CAU3_Type *base, const uint8_t *N, size_t sizeN, uint8_t *result, size_t *resultSize, cau3_pkha_f2m_t arithType)
2656 {
2657 status_t status;
2658 cau3_pkha_mode_params_t params;
2659
2660 cau3_pkha_default_parms(¶ms);
2661 params.func = kCAU3_PKHA_ArithModR2;
2662 params.arithType = arithType;
2663
2664 cau3_pkha_init_data(base, NULL, 0, NULL, 0, N, sizeN, NULL, 0);
2665 status = cau3_pkha_init_mode(base, ¶ms);
2666
2667 if (status == kStatus_Success)
2668 {
2669 /* Read the result and size from register B0. */
2670 if (resultSize && result)
2671 {
2672 *resultSize = base->PKBSZ;
2673 /* Read the data from the result register into place. */
2674 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
2675 }
2676 }
2677
2678 return status;
2679 }
2680
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)2681 static status_t cau3_pkha_modmul(CAU3_Type *base,
2682 const uint8_t *A,
2683 size_t sizeA,
2684 const uint8_t *B,
2685 size_t sizeB,
2686 const uint8_t *N,
2687 size_t sizeN,
2688 uint8_t *result,
2689 size_t *resultSize,
2690 cau3_pkha_f2m_t arithType,
2691 cau3_pkha_montgomery_form_t montIn,
2692 cau3_pkha_montgomery_form_t montOut,
2693 cau3_pkha_timing_t equalTime)
2694 {
2695 cau3_pkha_mode_params_t params;
2696 status_t status;
2697
2698 if (arithType == kCAU3_PKHA_IntegerArith)
2699 {
2700 if (CAU3_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
2701 {
2702 return (kStatus_InvalidArgument);
2703 }
2704
2705 if (CAU3_PKHA_CompareBigNum(B, sizeB, N, sizeN) >= 0)
2706 {
2707 return (kStatus_InvalidArgument);
2708 }
2709 }
2710
2711 cau3_pkha_default_parms(¶ms);
2712 params.func = kCAU3_PKHA_ArithModMul;
2713 params.arithType = arithType;
2714 params.montFormIn = montIn;
2715 params.montFormOut = montOut;
2716 params.equalTime = equalTime;
2717
2718 cau3_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0);
2719 status = cau3_pkha_init_mode(base, ¶ms);
2720
2721 if (status == kStatus_Success)
2722 {
2723 /* Read the result and size from register B0. */
2724 if (resultSize && result)
2725 {
2726 *resultSize = base->PKBSZ;
2727 /* Read the data from the result register into place. */
2728 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
2729 }
2730 }
2731
2732 return status;
2733 }
2734
2735 /*******************************************************************************
2736 * PKHA Code public
2737 ******************************************************************************/
CAU3_PKHA_CompareBigNum(const uint8_t * a,size_t sizeA,const uint8_t * b,size_t sizeB)2738 int CAU3_PKHA_CompareBigNum(const uint8_t *a, size_t sizeA, const uint8_t *b, size_t sizeB)
2739 {
2740 int retval = 0;
2741
2742 /* skip zero msbytes - integer a */
2743 while ((sizeA) && (0u == a[sizeA - 1]))
2744 {
2745 sizeA--;
2746 }
2747
2748 /* skip zero msbytes - integer b */
2749 while ((sizeB) && (0u == b[sizeB - 1]))
2750 {
2751 sizeB--;
2752 }
2753
2754 if (sizeA > sizeB)
2755 {
2756 retval = 1;
2757 } /* int a has more non-zero bytes, thus it is bigger than b */
2758 else if (sizeA < sizeB)
2759 {
2760 retval = -1;
2761 } /* int b has more non-zero bytes, thus it is bigger than a */
2762 else if (sizeA == 0)
2763 {
2764 retval = 0;
2765 } /* sizeA = sizeB = 0 */
2766 else
2767 {
2768 int n;
2769 int i;
2770 int val;
2771 uint32_t equal;
2772
2773 n = sizeA - 1;
2774 i = 0;
2775 equal = 0;
2776
2777 while (n >= 0)
2778 {
2779 uint32_t chXor = a[i] ^ b[i];
2780
2781 equal |= chXor;
2782 val = (int)chXor * (a[i] - b[i]);
2783
2784 if (val < 0)
2785 {
2786 retval = -1;
2787 }
2788
2789 if (val > 0)
2790 {
2791 retval = 1;
2792 }
2793
2794 if (val == 0)
2795 {
2796 val = 1;
2797 }
2798
2799 if (val)
2800 {
2801 i++;
2802 n--;
2803 }
2804 }
2805
2806 if (0 == equal)
2807 {
2808 retval = 0;
2809 }
2810 }
2811 return (retval);
2812 }
2813
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)2814 status_t CAU3_PKHA_NormalToMontgomery(CAU3_Type *base,
2815 const uint8_t *N,
2816 size_t sizeN,
2817 uint8_t *A,
2818 size_t *sizeA,
2819 uint8_t *B,
2820 size_t *sizeB,
2821 uint8_t *R2,
2822 size_t *sizeR2,
2823 cau3_pkha_timing_t equalTime,
2824 cau3_pkha_f2m_t arithType)
2825 {
2826 status_t status;
2827
2828 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2829 status = cau3_lock_semaphore(base);
2830 if (kStatus_Success != status)
2831 {
2832 cau3_release_semaphore(base);
2833 return status;
2834 }
2835 #endif
2836
2837 /* need to convert our Integer inputs into Montgomery format */
2838 if (N && sizeN && R2 && sizeR2)
2839 {
2840 /* 1. R2 = MOD_R2(N) */
2841 status = cau3_pkha_modR2(base, N, sizeN, R2, sizeR2, arithType);
2842 if (status != kStatus_Success)
2843 {
2844 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2845 cau3_release_semaphore(base);
2846 #endif
2847 return status;
2848 }
2849
2850 /* 2. A(Montgomery) = MOD_MUL_IM_OM(A, R2, N) */
2851 if (A && sizeA)
2852 {
2853 status = cau3_pkha_modmul(base, A, *sizeA, R2, *sizeR2, N, sizeN, A, sizeA, arithType,
2854 kCAU3_PKHA_MontgomeryFormat, kCAU3_PKHA_MontgomeryFormat, equalTime);
2855 if (status != kStatus_Success)
2856 {
2857 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2858 cau3_release_semaphore(base);
2859 #endif
2860 return status;
2861 }
2862 }
2863
2864 /* 2. B(Montgomery) = MOD_MUL_IM_OM(B, R2, N) */
2865 if (B && sizeB)
2866 {
2867 status = cau3_pkha_modmul(base, B, *sizeB, R2, *sizeR2, N, sizeN, B, sizeB, arithType,
2868 kCAU3_PKHA_MontgomeryFormat, kCAU3_PKHA_MontgomeryFormat, equalTime);
2869 if (status != kStatus_Success)
2870 {
2871 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2872 cau3_release_semaphore(base);
2873 #endif
2874 return status;
2875 }
2876 }
2877
2878 cau3_clear_all(base, true);
2879 }
2880 else
2881 {
2882 status = kStatus_InvalidArgument;
2883 }
2884
2885 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2886 cau3_release_semaphore(base);
2887 #endif
2888 return status;
2889 }
2890
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)2891 status_t CAU3_PKHA_MontgomeryToNormal(CAU3_Type *base,
2892 const uint8_t *N,
2893 size_t sizeN,
2894 uint8_t *A,
2895 size_t *sizeA,
2896 uint8_t *B,
2897 size_t *sizeB,
2898 cau3_pkha_timing_t equalTime,
2899 cau3_pkha_f2m_t arithType)
2900 {
2901 uint8_t one = 1;
2902 status_t status = kStatus_InvalidArgument;
2903
2904 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2905 status = cau3_lock_semaphore(base);
2906 if (kStatus_Success != status)
2907 {
2908 cau3_release_semaphore(base);
2909 return status;
2910 }
2911 #endif
2912
2913 /* A = MOD_MUL_IM_OM(A(Montgomery), 1, N) */
2914 if (A && sizeA)
2915 {
2916 status = cau3_pkha_modmul(base, A, *sizeA, &one, sizeof(one), N, sizeN, A, sizeA, arithType,
2917 kCAU3_PKHA_MontgomeryFormat, kCAU3_PKHA_MontgomeryFormat, equalTime);
2918 if (kStatus_Success != status)
2919 {
2920 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2921 cau3_release_semaphore(base);
2922 #endif
2923 return status;
2924 }
2925 }
2926
2927 /* B = MOD_MUL_IM_OM(B(Montgomery), 1, N) */
2928 if (B && sizeB)
2929 {
2930 status = cau3_pkha_modmul(base, B, *sizeB, &one, sizeof(one), N, sizeN, B, sizeB, arithType,
2931 kCAU3_PKHA_MontgomeryFormat, kCAU3_PKHA_MontgomeryFormat, equalTime);
2932 if (kStatus_Success != status)
2933 {
2934 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2935 cau3_release_semaphore(base);
2936 #endif
2937 return status;
2938 }
2939 }
2940
2941 cau3_clear_all(base, true);
2942 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2943 cau3_release_semaphore(base);
2944 #endif
2945 return status;
2946 }
2947
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)2948 status_t CAU3_PKHA_ModAdd(CAU3_Type *base,
2949 const uint8_t *A,
2950 size_t sizeA,
2951 const uint8_t *B,
2952 size_t sizeB,
2953 const uint8_t *N,
2954 size_t sizeN,
2955 uint8_t *result,
2956 size_t *resultSize,
2957 cau3_pkha_f2m_t arithType)
2958 {
2959 cau3_pkha_mode_params_t params;
2960 status_t status;
2961
2962 if (arithType == kCAU3_PKHA_IntegerArith)
2963 {
2964 if (CAU3_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
2965 {
2966 return (kStatus_InvalidArgument);
2967 }
2968
2969 if (CAU3_PKHA_CompareBigNum(B, sizeB, N, sizeN) >= 0)
2970 {
2971 return (kStatus_InvalidArgument);
2972 }
2973 }
2974
2975 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
2976 status = cau3_lock_semaphore(base);
2977 if (kStatus_Success != status)
2978 {
2979 cau3_release_semaphore(base);
2980 return status;
2981 }
2982 #endif
2983
2984 cau3_pkha_default_parms(¶ms);
2985 params.func = kCAU3_PKHA_ArithModAdd;
2986 params.arithType = arithType;
2987
2988 cau3_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0);
2989 status = cau3_pkha_init_mode(base, ¶ms);
2990
2991 if (status == kStatus_Success)
2992 {
2993 /* Read the result and size from register B0. */
2994 if (resultSize && result)
2995 {
2996 *resultSize = base->PKBSZ;
2997 /* Read the data from the result register into place. */
2998 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
2999 }
3000 }
3001
3002 cau3_clear_all(base, true);
3003 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3004 cau3_release_semaphore(base);
3005 #endif
3006 return status;
3007 }
3008
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)3009 status_t CAU3_PKHA_ModSub1(CAU3_Type *base,
3010 const uint8_t *A,
3011 size_t sizeA,
3012 const uint8_t *B,
3013 size_t sizeB,
3014 const uint8_t *N,
3015 size_t sizeN,
3016 uint8_t *result,
3017 size_t *resultSize)
3018 {
3019 cau3_pkha_mode_params_t params;
3020 status_t status;
3021
3022 if (CAU3_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
3023 {
3024 return (kStatus_InvalidArgument);
3025 }
3026
3027 if (CAU3_PKHA_CompareBigNum(B, sizeB, N, sizeN) >= 0)
3028 {
3029 return (kStatus_InvalidArgument);
3030 }
3031
3032 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3033 status = cau3_lock_semaphore(base);
3034 if (kStatus_Success != status)
3035 {
3036 cau3_release_semaphore(base);
3037 return status;
3038 }
3039 #endif
3040
3041 cau3_pkha_default_parms(¶ms);
3042 params.func = kCAU3_PKHA_ArithModSub1;
3043 cau3_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0);
3044
3045 status = cau3_pkha_init_mode(base, ¶ms);
3046
3047 if (status == kStatus_Success)
3048 {
3049 /* Read the result and size from register B0. */
3050 if (resultSize && result)
3051 {
3052 *resultSize = base->PKBSZ;
3053 /* Read the data from the result register into place. */
3054 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
3055 }
3056 }
3057
3058 cau3_clear_all(base, true);
3059 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3060 cau3_release_semaphore(base);
3061 #endif
3062 return status;
3063 }
3064
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)3065 status_t CAU3_PKHA_ModSub2(CAU3_Type *base,
3066 const uint8_t *A,
3067 size_t sizeA,
3068 const uint8_t *B,
3069 size_t sizeB,
3070 const uint8_t *N,
3071 size_t sizeN,
3072 uint8_t *result,
3073 size_t *resultSize)
3074 {
3075 cau3_pkha_mode_params_t params;
3076 status_t status;
3077
3078 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3079 status = cau3_lock_semaphore(base);
3080 if (kStatus_Success != status)
3081 {
3082 cau3_release_semaphore(base);
3083 return status;
3084 }
3085 #endif
3086
3087 cau3_pkha_default_parms(¶ms);
3088 params.func = kCAU3_PKHA_ArithModSub2;
3089
3090 cau3_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0);
3091 status = cau3_pkha_init_mode(base, ¶ms);
3092
3093 if (status == kStatus_Success)
3094 {
3095 /* Read the result and size from register B0. */
3096 if (resultSize && result)
3097 {
3098 *resultSize = base->PKBSZ;
3099 /* Read the data from the result register into place. */
3100 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
3101 }
3102 }
3103
3104 cau3_clear_all(base, true);
3105 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3106 cau3_release_semaphore(base);
3107 #endif
3108 return status;
3109 }
3110
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)3111 status_t CAU3_PKHA_ModMul(CAU3_Type *base,
3112 const uint8_t *A,
3113 size_t sizeA,
3114 const uint8_t *B,
3115 size_t sizeB,
3116 const uint8_t *N,
3117 size_t sizeN,
3118 uint8_t *result,
3119 size_t *resultSize,
3120 cau3_pkha_f2m_t arithType,
3121 cau3_pkha_montgomery_form_t montIn,
3122 cau3_pkha_montgomery_form_t montOut,
3123 cau3_pkha_timing_t equalTime)
3124 {
3125 status_t status;
3126
3127 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3128 status = cau3_lock_semaphore(base);
3129 if (kStatus_Success != status)
3130 {
3131 cau3_release_semaphore(base);
3132 return status;
3133 }
3134 #endif
3135
3136 status =
3137 cau3_pkha_modmul(base, A, sizeA, B, sizeB, N, sizeN, result, resultSize, arithType, montIn, montOut, equalTime);
3138
3139 cau3_clear_all(base, true);
3140 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3141 cau3_release_semaphore(base);
3142 #endif
3143 return status;
3144 }
3145
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)3146 status_t CAU3_PKHA_ModExp(CAU3_Type *base,
3147 const uint8_t *A,
3148 size_t sizeA,
3149 const uint8_t *N,
3150 size_t sizeN,
3151 const uint8_t *E,
3152 size_t sizeE,
3153 uint8_t *result,
3154 size_t *resultSize,
3155 cau3_pkha_f2m_t arithType,
3156 cau3_pkha_montgomery_form_t montIn,
3157 cau3_pkha_timing_t equalTime)
3158 {
3159 cau3_pkha_mode_params_t params;
3160 status_t status;
3161
3162 if (arithType == kCAU3_PKHA_IntegerArith)
3163 {
3164 if (CAU3_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
3165 {
3166 return (kStatus_InvalidArgument);
3167 }
3168 }
3169
3170 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3171 status = cau3_lock_semaphore(base);
3172 if (kStatus_Success != status)
3173 {
3174 cau3_release_semaphore(base);
3175 return status;
3176 }
3177 #endif
3178
3179 cau3_pkha_default_parms(¶ms);
3180 params.func = kCAU3_PKHA_ArithModExp;
3181 params.arithType = arithType;
3182 params.montFormIn = montIn;
3183 params.equalTime = equalTime;
3184
3185 cau3_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, E, sizeE);
3186 status = cau3_pkha_init_mode(base, ¶ms);
3187
3188 if (status == kStatus_Success)
3189 {
3190 /* Read the result and size from register B0. */
3191 if (resultSize && result)
3192 {
3193 *resultSize = base->PKBSZ;
3194 /* Read the data from the result register into place. */
3195 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
3196 }
3197 }
3198
3199 cau3_clear_all(base, true);
3200 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3201 cau3_release_semaphore(base);
3202 #endif
3203 return status;
3204 }
3205
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)3206 status_t CAU3_PKHA_ModSqrt(CAU3_Type *base,
3207 const uint8_t *A,
3208 size_t sizeA,
3209 const uint8_t *N,
3210 size_t sizeN,
3211 uint8_t *result,
3212 size_t *resultSize)
3213 {
3214 cau3_pkha_mode_params_t params;
3215 status_t status;
3216
3217 /* A < N */
3218 if (CAU3_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
3219 {
3220 return (kStatus_InvalidArgument);
3221 }
3222
3223 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3224 status = cau3_lock_semaphore(base);
3225 if (kStatus_Success != status)
3226 {
3227 cau3_release_semaphore(base);
3228 return status;
3229 }
3230 #endif
3231
3232 cau3_pkha_default_parms(¶ms);
3233 params.func = kCAU3_PKHA_ArithModSqrt;
3234
3235 cau3_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, NULL, 0);
3236 status = cau3_pkha_init_mode(base, ¶ms);
3237
3238 if (status == kStatus_Success)
3239 {
3240 /* Read the result and size from register B0. */
3241 if (resultSize && result)
3242 {
3243 *resultSize = base->PKBSZ;
3244 /* Read the data from the result register into place. */
3245 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
3246 }
3247 }
3248
3249 cau3_clear_all(base, true);
3250 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3251 cau3_release_semaphore(base);
3252 #endif
3253 return status;
3254 }
3255
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)3256 status_t CAU3_PKHA_ModRed(CAU3_Type *base,
3257 const uint8_t *A,
3258 size_t sizeA,
3259 const uint8_t *N,
3260 size_t sizeN,
3261 uint8_t *result,
3262 size_t *resultSize,
3263 cau3_pkha_f2m_t arithType)
3264 {
3265 cau3_pkha_mode_params_t params;
3266 status_t status;
3267
3268 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3269 status = cau3_lock_semaphore(base);
3270 if (kStatus_Success != status)
3271 {
3272 cau3_release_semaphore(base);
3273 return status;
3274 }
3275 #endif
3276
3277 cau3_pkha_default_parms(¶ms);
3278 params.func = kCAU3_PKHA_ArithModRed;
3279 params.arithType = arithType;
3280
3281 cau3_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, NULL, 0);
3282 status = cau3_pkha_init_mode(base, ¶ms);
3283
3284 if (status == kStatus_Success)
3285 {
3286 /* Read the result and size from register B0. */
3287 if (resultSize && result)
3288 {
3289 *resultSize = base->PKBSZ;
3290 /* Read the data from the result register into place. */
3291 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
3292 }
3293 }
3294
3295 cau3_clear_all(base, true);
3296 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3297 cau3_release_semaphore(base);
3298 #endif
3299 return status;
3300 }
3301
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)3302 status_t CAU3_PKHA_ModInv(CAU3_Type *base,
3303 const uint8_t *A,
3304 size_t sizeA,
3305 const uint8_t *N,
3306 size_t sizeN,
3307 uint8_t *result,
3308 size_t *resultSize,
3309 cau3_pkha_f2m_t arithType)
3310 {
3311 cau3_pkha_mode_params_t params;
3312 status_t status;
3313
3314 /* A must be less than N -> CAU3_PKHA_CompareBigNum() must return -1 */
3315 if (arithType == kCAU3_PKHA_IntegerArith)
3316 {
3317 if (CAU3_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
3318 {
3319 return (kStatus_InvalidArgument);
3320 }
3321 }
3322
3323 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3324 status = cau3_lock_semaphore(base);
3325 if (kStatus_Success != status)
3326 {
3327 cau3_release_semaphore(base);
3328 return status;
3329 }
3330 #endif
3331
3332 cau3_pkha_default_parms(¶ms);
3333 params.func = kCAU3_PKHA_ArithModInv;
3334 params.arithType = arithType;
3335
3336 cau3_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, NULL, 0);
3337 status = cau3_pkha_init_mode(base, ¶ms);
3338
3339 if (status == kStatus_Success)
3340 {
3341 /* Read the result and size from register B0. */
3342 if (resultSize && result)
3343 {
3344 *resultSize = base->PKBSZ;
3345 /* Read the data from the result register into place. */
3346 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
3347 }
3348 }
3349
3350 cau3_clear_all(base, true);
3351 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3352 cau3_release_semaphore(base);
3353 #endif
3354 return status;
3355 }
3356
CAU3_PKHA_ModR2(CAU3_Type * base,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,cau3_pkha_f2m_t arithType)3357 status_t CAU3_PKHA_ModR2(
3358 CAU3_Type *base, const uint8_t *N, size_t sizeN, uint8_t *result, size_t *resultSize, cau3_pkha_f2m_t arithType)
3359 {
3360 status_t status;
3361 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3362 status = cau3_lock_semaphore(base);
3363 if (kStatus_Success != status)
3364 {
3365 cau3_release_semaphore(base);
3366 return status;
3367 }
3368 #endif
3369 status = cau3_pkha_modR2(base, N, sizeN, result, resultSize, arithType);
3370 cau3_clear_all(base, true);
3371 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3372 cau3_release_semaphore(base);
3373 #endif
3374 return status;
3375 }
3376
CAU3_PKHA_ModRR(CAU3_Type * base,const uint8_t * P,size_t sizeP,size_t sizeE,uint8_t * result,size_t * resultSize)3377 status_t CAU3_PKHA_ModRR(
3378 CAU3_Type *base, const uint8_t *P, size_t sizeP, size_t sizeE, uint8_t *result, size_t *resultSize)
3379 {
3380 status_t status;
3381 cau3_pkha_mode_params_t params;
3382
3383 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3384 status = cau3_lock_semaphore(base);
3385 if (kStatus_Success != status)
3386 {
3387 cau3_release_semaphore(base);
3388 return status;
3389 }
3390 #endif
3391
3392 cau3_pkha_default_parms(¶ms);
3393 params.func = kCAU3_PKHA_ArithModRR;
3394
3395 cau3_pkha_init_data(base, NULL, 0, NULL, 0, P, sizeP, NULL, sizeE);
3396 status = cau3_pkha_init_mode(base, ¶ms);
3397
3398 if (status == kStatus_Success)
3399 {
3400 /* Read the result and size from register B0. */
3401 if (resultSize && result)
3402 {
3403 *resultSize = base->PKBSZ;
3404 /* Read the data from the result register into place. */
3405 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
3406 }
3407 }
3408
3409 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3410 cau3_release_semaphore(base);
3411 #endif
3412 return status;
3413 }
3414
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)3415 status_t CAU3_PKHA_ModGcd(CAU3_Type *base,
3416 const uint8_t *A,
3417 size_t sizeA,
3418 const uint8_t *N,
3419 size_t sizeN,
3420 uint8_t *result,
3421 size_t *resultSize,
3422 cau3_pkha_f2m_t arithType)
3423 {
3424 cau3_pkha_mode_params_t params;
3425 status_t status;
3426
3427 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3428 status = cau3_lock_semaphore(base);
3429 if (kStatus_Success != status)
3430 {
3431 cau3_release_semaphore(base);
3432 return status;
3433 }
3434 #endif
3435
3436 cau3_pkha_default_parms(¶ms);
3437 params.func = kCAU3_PKHA_ArithGcd;
3438 params.arithType = arithType;
3439
3440 cau3_pkha_init_data(base, A, sizeA, NULL, 0, N, sizeN, NULL, 0);
3441 status = cau3_pkha_init_mode(base, ¶ms);
3442
3443 if (status == kStatus_Success)
3444 {
3445 /* Read the result and size from register B0. */
3446 if (resultSize && result)
3447 {
3448 *resultSize = base->PKBSZ;
3449 /* Read the data from the result register into place. */
3450 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, result, *resultSize);
3451 }
3452 }
3453
3454 cau3_clear_all(base, true);
3455 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3456 cau3_release_semaphore(base);
3457 #endif
3458 return status;
3459 }
3460
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)3461 status_t CAU3_PKHA_PrimalityTest(CAU3_Type *base,
3462 const uint8_t *A,
3463 size_t sizeA,
3464 const uint8_t *B,
3465 size_t sizeB,
3466 const uint8_t *N,
3467 size_t sizeN,
3468 bool *res)
3469 {
3470 uint8_t result;
3471 cau3_pkha_mode_params_t params;
3472 status_t status;
3473
3474 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3475 status = cau3_lock_semaphore(base);
3476 if (kStatus_Success != status)
3477 {
3478 cau3_release_semaphore(base);
3479 return status;
3480 }
3481 #endif
3482
3483 cau3_pkha_default_parms(¶ms);
3484 params.func = kCAU3_PKHA_ArithPrimalityTest;
3485 cau3_pkha_init_data(base, A, sizeA, B, sizeB, N, sizeN, NULL, 0);
3486 status = cau3_pkha_init_mode(base, ¶ms);
3487
3488 if (status == kStatus_Success)
3489 {
3490 /* Read the data from the result register into place. */
3491 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 0, &result, 1);
3492
3493 *res = (bool)result;
3494 }
3495
3496 cau3_clear_all(base, true);
3497 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3498 cau3_release_semaphore(base);
3499 #endif
3500 return status;
3501 }
3502
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)3503 status_t CAU3_PKHA_ECC_PointAdd(CAU3_Type *base,
3504 const cau3_pkha_ecc_point_t *A,
3505 const cau3_pkha_ecc_point_t *B,
3506 const uint8_t *N,
3507 const uint8_t *R2modN,
3508 const uint8_t *aCurveParam,
3509 const uint8_t *bCurveParam,
3510 size_t size,
3511 cau3_pkha_f2m_t arithType,
3512 cau3_pkha_ecc_point_t *result)
3513 {
3514 cau3_pkha_mode_params_t params;
3515 uint32_t clearMask;
3516 status_t status;
3517
3518 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3519 status = cau3_lock_semaphore(base);
3520 if (kStatus_Success != status)
3521 {
3522 cau3_release_semaphore(base);
3523 return status;
3524 }
3525 #endif
3526
3527 cau3_pkha_default_parms(¶ms);
3528 params.func = kCAU3_PKHA_ArithEccAdd;
3529 params.arithType = arithType;
3530 params.r2modn = R2modN ? kCAU3_PKHA_InputR2 : kCAU3_PKHA_CalcR2;
3531
3532 clearMask = kCAU3_ClearMode;
3533
3534 /* Clear internal register states. */
3535 clearMask |= kCAU3_ClearPkhaSizeA;
3536 clearMask |= kCAU3_ClearPkhaSizeB;
3537 clearMask |= kCAU3_ClearPkhaSizeN;
3538 clearMask |= kCAU3_ClearPkhaSizeE;
3539
3540 base->CW = clearMask;
3541 base->STA = kCAU3_StatusDoneIsr;
3542 cau3_pkha_clear_regabne(base, true, true, true, false);
3543
3544 /* sizeN should be less than 64 bytes. */
3545 base->PKNSZ = size;
3546 cau3_pkha_write_reg(base, kCAU3_PKHA_RegN, 0, N, size);
3547
3548 base->PKASZ = size;
3549 cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 0, A->X, size);
3550 cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 1, A->Y, size);
3551 cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 3, aCurveParam, size);
3552
3553 base->PKBSZ = size;
3554 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 0, bCurveParam, size);
3555 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 1, B->X, size);
3556 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 2, B->Y, size);
3557 if (R2modN)
3558 {
3559 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 3, R2modN, size);
3560 }
3561
3562 status = cau3_pkha_init_mode(base, ¶ms);
3563
3564 if (status == kStatus_Success)
3565 {
3566 /* Read the data from the result register into place. */
3567 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 1, result->X, size);
3568 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 2, result->Y, size);
3569 }
3570
3571 cau3_clear_all(base, true);
3572 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3573 cau3_release_semaphore(base);
3574 #endif
3575 return status;
3576 }
3577
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)3578 status_t CAU3_PKHA_ECC_PointDouble(CAU3_Type *base,
3579 const cau3_pkha_ecc_point_t *B,
3580 const uint8_t *N,
3581 const uint8_t *aCurveParam,
3582 const uint8_t *bCurveParam,
3583 size_t size,
3584 cau3_pkha_f2m_t arithType,
3585 cau3_pkha_ecc_point_t *result)
3586 {
3587 cau3_pkha_mode_params_t params;
3588 uint32_t clearMask;
3589 status_t status;
3590
3591 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3592 status = cau3_lock_semaphore(base);
3593 if (kStatus_Success != status)
3594 {
3595 cau3_release_semaphore(base);
3596 return status;
3597 }
3598 #endif
3599
3600 cau3_pkha_default_parms(¶ms);
3601 params.func = kCAU3_PKHA_ArithEccDouble;
3602 params.arithType = arithType;
3603
3604 clearMask = kCAU3_ClearMode;
3605
3606 /* Clear internal register states. */
3607 clearMask |= kCAU3_ClearPkhaSizeA;
3608 clearMask |= kCAU3_ClearPkhaSizeB;
3609 clearMask |= kCAU3_ClearPkhaSizeN;
3610 clearMask |= kCAU3_ClearPkhaSizeE;
3611
3612 base->CW = clearMask;
3613 base->STA = kCAU3_StatusDoneIsr;
3614 cau3_pkha_clear_regabne(base, true, true, true, false);
3615
3616 /* sizeN should be less than 64 bytes. */
3617 base->PKNSZ = size;
3618 cau3_pkha_write_reg(base, kCAU3_PKHA_RegN, 0, N, size);
3619
3620 base->PKASZ = size;
3621 cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 3, aCurveParam, size);
3622
3623 base->PKBSZ = size;
3624 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 0, bCurveParam, size);
3625 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 1, B->X, size);
3626 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 2, B->Y, size);
3627 status = cau3_pkha_init_mode(base, ¶ms);
3628
3629 if (status == kStatus_Success)
3630 {
3631 /* Read the data from the result register into place. */
3632 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 1, result->X, size);
3633 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 2, result->Y, size);
3634 }
3635
3636 cau3_clear_all(base, true);
3637 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3638 cau3_release_semaphore(base);
3639 #endif
3640 return status;
3641 }
3642
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)3643 status_t CAU3_PKHA_ECC_PointMul(CAU3_Type *base,
3644 const cau3_pkha_ecc_point_t *A,
3645 const uint8_t *E,
3646 size_t sizeE,
3647 const uint8_t *N,
3648 const uint8_t *R2modN,
3649 const uint8_t *aCurveParam,
3650 const uint8_t *bCurveParam,
3651 size_t size,
3652 cau3_pkha_timing_t equalTime,
3653 cau3_pkha_f2m_t arithType,
3654 cau3_pkha_ecc_point_t *result)
3655 {
3656 cau3_pkha_mode_params_t params;
3657 uint32_t clearMask;
3658 status_t status;
3659
3660 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3661 status = cau3_lock_semaphore(base);
3662 if (kStatus_Success != status)
3663 {
3664 cau3_release_semaphore(base);
3665 return status;
3666 }
3667 #endif
3668
3669 cau3_pkha_default_parms(¶ms);
3670 params.func = kCAU3_PKHA_ArithEccMul;
3671 params.equalTime = equalTime;
3672 params.arithType = arithType;
3673 params.r2modn = R2modN ? kCAU3_PKHA_InputR2 : kCAU3_PKHA_CalcR2;
3674
3675 clearMask = kCAU3_ClearMode;
3676
3677 /* Clear internal register states. */
3678 clearMask |= kCAU3_ClearPkhaSizeA;
3679 clearMask |= kCAU3_ClearPkhaSizeB;
3680 clearMask |= kCAU3_ClearPkhaSizeN;
3681 clearMask |= kCAU3_ClearPkhaSizeE;
3682
3683 base->CW = clearMask;
3684 base->STA = kCAU3_StatusDoneIsr;
3685 cau3_pkha_clear_regabne(base, true, true, true, true);
3686
3687 /* sizeN should be less than 64 bytes. */
3688 base->PKNSZ = size;
3689 cau3_pkha_write_reg(base, kCAU3_PKHA_RegN, 0, N, size);
3690
3691 base->PKESZ = sizeE;
3692 cau3_pkha_write_reg(base, kCAU3_PKHA_RegE, 0, E, sizeE);
3693
3694 base->PKASZ = size;
3695 cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 0, A->X, size);
3696 cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 1, A->Y, size);
3697 cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 3, aCurveParam, size);
3698
3699 base->PKBSZ = size;
3700 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 0, bCurveParam, size);
3701 if (R2modN)
3702 {
3703 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 1, R2modN, size);
3704 }
3705
3706 status = cau3_pkha_init_mode(base, ¶ms);
3707
3708 if (status == kStatus_Success)
3709 {
3710 /* Read the data from the result register into place. */
3711 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 1, result->X, size);
3712 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 2, result->Y, size);
3713 }
3714
3715 cau3_clear_all(base, true);
3716 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3717 cau3_release_semaphore(base);
3718 #endif
3719 return status;
3720 }
3721
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)3722 status_t CAU3_PKHA_ECM_PointMul(CAU3_Type *base,
3723 const uint8_t *E,
3724 size_t sizeE,
3725 const uint8_t *inputCoordinate,
3726 const uint8_t *A24,
3727 const uint8_t *N,
3728 const uint8_t *R2modN,
3729 size_t size,
3730 cau3_pkha_timing_t equalTime,
3731 uint8_t *outputCoordinate)
3732 {
3733 cau3_pkha_mode_params_t params;
3734 uint32_t clearMask;
3735 status_t status;
3736
3737 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3738 status = cau3_lock_semaphore(base);
3739 if (kStatus_Success != status)
3740 {
3741 cau3_release_semaphore(base);
3742 return status;
3743 }
3744 #endif
3745
3746 cau3_pkha_default_parms(¶ms);
3747 params.func = kCAU3_PKHA_ArithEcmMul;
3748 params.equalTime = equalTime;
3749 params.r2modn = R2modN ? kCAU3_PKHA_InputR2 : kCAU3_PKHA_CalcR2;
3750
3751 clearMask = kCAU3_ClearMode;
3752
3753 /* Clear internal register states. */
3754 clearMask |= kCAU3_ClearPkhaSizeA;
3755 clearMask |= kCAU3_ClearPkhaSizeB;
3756 clearMask |= kCAU3_ClearPkhaSizeN;
3757 clearMask |= kCAU3_ClearPkhaSizeE;
3758
3759 base->CW = clearMask;
3760 base->STA = kCAU3_StatusDoneIsr;
3761 cau3_pkha_clear_regabne(base, true, true, true, true);
3762
3763 base->PKNSZ = size;
3764 cau3_pkha_write_reg(base, kCAU3_PKHA_RegN, 0, N, size);
3765
3766 base->PKESZ = sizeE;
3767 cau3_pkha_write_reg(base, kCAU3_PKHA_RegE, 0, E, sizeE);
3768
3769 base->PKASZ = size;
3770 cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 0, inputCoordinate, size);
3771 cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 3, A24, size);
3772
3773 if (R2modN)
3774 {
3775 base->PKBSZ = size;
3776 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 1, R2modN, size);
3777 }
3778
3779 status = cau3_pkha_init_mode(base, ¶ms);
3780
3781 if (status == kStatus_Success)
3782 {
3783 /* Read the data from the result register into place. */
3784 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 1, outputCoordinate, size);
3785 }
3786
3787 cau3_clear_all(base, true);
3788 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3789 cau3_release_semaphore(base);
3790 #endif
3791 return status;
3792 }
3793
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)3794 status_t CAU3_PKHA_ECT_PointMul(CAU3_Type *base,
3795 const cau3_pkha_ecc_point_t *A,
3796 const uint8_t *E,
3797 size_t sizeE,
3798 const uint8_t *N,
3799 const uint8_t *R2modN,
3800 const uint8_t *aCurveParam,
3801 const uint8_t *dCurveParam,
3802 size_t size,
3803 cau3_pkha_timing_t equalTime,
3804 cau3_pkha_ecc_point_t *result)
3805 {
3806 cau3_pkha_mode_params_t params;
3807 uint32_t clearMask;
3808 status_t status;
3809
3810 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3811 status = cau3_lock_semaphore(base);
3812 if (kStatus_Success != status)
3813 {
3814 cau3_release_semaphore(base);
3815 return status;
3816 }
3817 #endif
3818
3819 cau3_pkha_default_parms(¶ms);
3820 params.func = kCAU3_PKHA_ArithEctMul;
3821 params.equalTime = equalTime;
3822 params.r2modn = R2modN ? kCAU3_PKHA_InputR2 : kCAU3_PKHA_CalcR2;
3823
3824 clearMask = kCAU3_ClearMode;
3825
3826 /* Clear internal register states. */
3827 clearMask |= kCAU3_ClearPkhaSizeA;
3828 clearMask |= kCAU3_ClearPkhaSizeB;
3829 clearMask |= kCAU3_ClearPkhaSizeN;
3830 clearMask |= kCAU3_ClearPkhaSizeE;
3831
3832 base->CW = clearMask;
3833 base->STA = kCAU3_StatusDoneIsr;
3834 cau3_pkha_clear_regabne(base, true, true, true, true);
3835
3836 base->PKNSZ = size;
3837 cau3_pkha_write_reg(base, kCAU3_PKHA_RegN, 0, N, size);
3838
3839 base->PKESZ = sizeE;
3840 cau3_pkha_write_reg(base, kCAU3_PKHA_RegE, 0, E, sizeE);
3841
3842 base->PKASZ = size;
3843 cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 0, A->X, size);
3844 cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 1, A->Y, size);
3845 cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 3, aCurveParam, size);
3846
3847 base->PKBSZ = size;
3848 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 0, dCurveParam, size);
3849 if (R2modN)
3850 {
3851 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 1, R2modN, size);
3852 }
3853
3854 status = cau3_pkha_init_mode(base, ¶ms);
3855
3856 if (status == kStatus_Success)
3857 {
3858 /* Read the data from the result register into place. */
3859 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 1, result->X, size);
3860 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 2, result->Y, size);
3861 }
3862
3863 cau3_clear_all(base, true);
3864 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3865 cau3_release_semaphore(base);
3866 #endif
3867 return status;
3868 }
3869
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)3870 status_t CAU3_PKHA_ECT_PointAdd(CAU3_Type *base,
3871 const cau3_pkha_ecc_point_t *A,
3872 const cau3_pkha_ecc_point_t *B,
3873 const uint8_t *N,
3874 const uint8_t *R2modN,
3875 const uint8_t *aCurveParam,
3876 const uint8_t *dCurveParam,
3877 size_t size,
3878 cau3_pkha_ecc_point_t *result)
3879 {
3880 cau3_pkha_mode_params_t params;
3881 uint32_t clearMask;
3882 status_t status;
3883
3884 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3885 status = cau3_lock_semaphore(base);
3886 if (kStatus_Success != status)
3887 {
3888 cau3_release_semaphore(base);
3889 return status;
3890 }
3891 #endif
3892
3893 cau3_pkha_default_parms(¶ms);
3894 params.func = kCAU3_PKHA_ArithEctAdd;
3895 params.r2modn = R2modN ? kCAU3_PKHA_InputR2 : kCAU3_PKHA_CalcR2;
3896
3897 clearMask = kCAU3_ClearMode;
3898
3899 /* Clear internal register states. */
3900 clearMask |= kCAU3_ClearPkhaSizeA;
3901 clearMask |= kCAU3_ClearPkhaSizeB;
3902 clearMask |= kCAU3_ClearPkhaSizeN;
3903 clearMask |= kCAU3_ClearPkhaSizeE;
3904
3905 base->CW = clearMask;
3906 base->STA = kCAU3_StatusDoneIsr;
3907 cau3_pkha_clear_regabne(base, true, true, true, false);
3908
3909 /* sizeN should be less than 64 bytes. */
3910 base->PKNSZ = size;
3911 cau3_pkha_write_reg(base, kCAU3_PKHA_RegN, 0, N, size);
3912
3913 base->PKASZ = size;
3914 cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 0, A->X, size);
3915 cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 1, A->Y, size);
3916 cau3_pkha_write_reg(base, kCAU3_PKHA_RegA, 3, aCurveParam, size);
3917
3918 base->PKBSZ = size;
3919 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 0, dCurveParam, size);
3920 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 1, B->X, size);
3921 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 2, B->Y, size);
3922 if (R2modN)
3923 {
3924 cau3_pkha_write_reg(base, kCAU3_PKHA_RegB, 3, R2modN, size);
3925 }
3926
3927 status = cau3_pkha_init_mode(base, ¶ms);
3928
3929 if (status == kStatus_Success)
3930 {
3931 /* Read the data from the result register into place. */
3932 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 1, result->X, size);
3933 cau3_pkha_read_reg(base, kCAU3_PKHA_RegB, 2, result->Y, size);
3934 }
3935
3936 cau3_clear_all(base, true);
3937 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3938 cau3_release_semaphore(base);
3939 #endif
3940 return status;
3941 }
3942
CAU3_TDES_CheckParity(CAU3_Type * base,cau3_key_slot_t keySlot)3943 status_t CAU3_TDES_CheckParity(CAU3_Type *base, cau3_key_slot_t keySlot)
3944 {
3945 status_t completionStatus;
3946 cau3_task_done_t taskDone;
3947
3948 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3949 completionStatus = cau3_lock_semaphore(base);
3950 if (kStatus_Success != completionStatus)
3951 {
3952 cau3_release_semaphore(base);
3953 return completionStatus;
3954 }
3955 #endif
3956
3957 taskDone = kCAU3_TaskDonePoll;
3958
3959 /* execute the cau3 "3des_check_parity" task */
3960 base->CC_R[17] = keySlot; /* keySlot */
3961 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
3962 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
3963 base->CC_PC = CAU3_TASK_3DES_CHECK_PARITY; /* call cau_3des_chk_parity() */
3964 base->CC_CMD = taskDone; /* trigger cau3 execution */
3965
3966 /* process the cau3 task completion signal specified by taskDone */
3967 completionStatus = cau3_process_task_completion(base, taskDone);
3968 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3969 cau3_release_semaphore(base);
3970 #endif
3971 return (completionStatus);
3972 }
3973
CAU3_TDES_SetKey(CAU3_Type * base,cau3_handle_t * handle,const uint8_t * key,size_t keySize)3974 status_t CAU3_TDES_SetKey(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *key, size_t keySize)
3975 {
3976 /* only work with aligned key[] */
3977 if (0x3U & (uintptr_t)key)
3978 {
3979 return kStatus_InvalidArgument;
3980 }
3981
3982 /* keySize must be 24. */
3983 if (keySize != 24U)
3984 {
3985 return kStatus_InvalidArgument;
3986 }
3987
3988 return cau3_load_key(base, key, keySize, handle->keySlot, handle->taskDone);
3989 }
3990
CAU3_TDES_Encrypt(CAU3_Type * base,cau3_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext)3991 status_t CAU3_TDES_Encrypt(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext)
3992 {
3993 status_t completionStatus;
3994
3995 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
3996 completionStatus = cau3_lock_semaphore(base);
3997 if (kStatus_Success != completionStatus)
3998 {
3999 cau3_release_semaphore(base);
4000 return completionStatus;
4001 }
4002 #endif
4003
4004 /* execute the cau3 "3des_encrypt_ecb" task */
4005 base->CC_R[16] = (uintptr_t)plaintext; /* pPlainText */
4006 base->CC_R[17] = handle->keySlot; /* keySlot */
4007 base->CC_R[19] = (uintptr_t)ciphertext; /* pCipherText */
4008 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
4009 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
4010 base->CC_PC = CAU3_TASK_3DES_ENCRYPT; /* call cau_3des_encrypt() */
4011 base->CC_CMD = handle->taskDone; /* trigger cau3 execution */
4012
4013 /* process the cau3 task completion signal specified by taskDone */
4014 completionStatus = cau3_process_task_completion(base, handle->taskDone);
4015 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
4016 cau3_release_semaphore(base);
4017 #endif
4018 return (completionStatus);
4019 }
4020
CAU3_TDES_Decrypt(CAU3_Type * base,cau3_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext)4021 status_t CAU3_TDES_Decrypt(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext)
4022 {
4023 status_t completionStatus;
4024
4025 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
4026 completionStatus = cau3_lock_semaphore(base);
4027 if (kStatus_Success != completionStatus)
4028 {
4029 cau3_release_semaphore(base);
4030 return completionStatus;
4031 }
4032 #endif
4033
4034 /* execute the cau3 "3des_decrypt_ecb" task */
4035 base->CC_R[16] = (uintptr_t)ciphertext; /* pCipherText */
4036 base->CC_R[17] = handle->keySlot; /* keySlot */
4037 base->CC_R[19] = (uintptr_t)plaintext; /* pPlainText */
4038 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
4039 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
4040 base->CC_PC = CAU3_TASK_3DES_DECRYPT; /* call cau_3des_decrypt() */
4041 base->CC_CMD = handle->taskDone; /* trigger cau3 execution */
4042
4043 /* process the cau3 task completion signal specified by taskDone */
4044 completionStatus = cau3_process_task_completion(base, handle->taskDone);
4045 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
4046 cau3_release_semaphore(base);
4047 #endif
4048 return (completionStatus);
4049 }
4050
CAU3_CHACHA20_POLY1305_SetKey(CAU3_Type * base,cau3_handle_t * handle,const uint8_t * key,size_t keySize)4051 status_t CAU3_CHACHA20_POLY1305_SetKey(CAU3_Type *base, cau3_handle_t *handle, const uint8_t *key, size_t keySize)
4052 {
4053 /* only work with aligned key[] */
4054 if (0x3U & (uintptr_t)key)
4055 {
4056 return kStatus_InvalidArgument;
4057 }
4058
4059 /* keySize must be 32. */
4060 if (keySize != 32U)
4061 {
4062 return kStatus_InvalidArgument;
4063 }
4064
4065 union {
4066 uint8_t b[32];
4067 uint32_t w[8];
4068 } tempKey;
4069
4070 for (int i = 0; i < ARRAY_SIZE(tempKey.w); i++)
4071 {
4072 tempKey.w[i] = __REV(((const uint32_t *)(uintptr_t)key)[i]);
4073 }
4074
4075 return cau3_load_key(base, tempKey.b, keySize, handle->keySlot, handle->taskDone);
4076 }
4077
cau3_load_nonce(CAU3_Type * base,const uint8_t * nonce,cau3_key_slot_t keySlot)4078 static status_t cau3_load_nonce(CAU3_Type *base, const uint8_t *nonce, cau3_key_slot_t keySlot)
4079 {
4080 #if defined(__GNUC__)
4081 #pragma GCC diagnostic push
4082 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
4083 #endif
4084
4085 union {
4086 uint8_t b[16];
4087 uint32_t w[4];
4088 } tempIv;
4089
4090 memset(&tempIv, 0, sizeof(tempIv));
4091
4092 /* set nonce to keySlot */
4093 cau3_memcpy(tempIv.b, nonce, 12);
4094 /* swap bytes */
4095 tempIv.w[0] = __REV(tempIv.w[0]);
4096 tempIv.w[1] = __REV(tempIv.w[1]);
4097 tempIv.w[2] = __REV(tempIv.w[2]);
4098
4099 return CAU3_LoadKeyInitVector(base, tempIv.b, keySlot, kCAU3_TaskDonePoll);
4100 #if defined(__GNUC__)
4101 #pragma GCC diagnostic pop
4102 #endif
4103 }
4104
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)4105 status_t CAU3_CHACHA20_POLY1305_Encrypt(CAU3_Type *base,
4106 cau3_handle_t *handle,
4107 const uint8_t *plaintext,
4108 uint8_t *ciphertext,
4109 size_t size,
4110 const uint8_t *aad,
4111 size_t aadLen,
4112 const uint8_t *nonce,
4113 uint8_t *tag)
4114 {
4115 status_t completionStatus;
4116
4117 completionStatus = cau3_load_nonce(base, nonce, handle->keySlot);
4118 if (kStatus_Success != completionStatus)
4119 {
4120 return completionStatus;
4121 }
4122
4123 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
4124 completionStatus = cau3_lock_semaphore(base);
4125 if (kStatus_Success != completionStatus)
4126 {
4127 cau3_release_semaphore(base);
4128 return completionStatus;
4129 }
4130 #endif
4131
4132 base->CC_R[17] = handle->keySlot; /* key/iv slot */
4133 base->CC_R[18] = (uintptr_t)aad; /* AAD pointer */
4134 base->CC_R[19] = aadLen; /* AAD length (bytes) */
4135 base->CC_R[20] = (uintptr_t)plaintext; /* Plaintext pointer */
4136 base->CC_R[21] = size; /* Plaintext length */
4137 base->CC_R[22] = (uintptr_t)ciphertext; /* Ciphertext pointer */
4138 base->CC_R[23] = (uintptr_t)tag; /* Tag pointer */
4139 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
4140 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
4141 base->CC_PC = CAU3_TASK_CHA_POLY_ENCRYPT; /* ChaChaPoly encrypt vector */
4142 base->CC_CMD = handle->taskDone; /* trigger cau3 execution */
4143
4144 /* process the cau3 task completion signal specified by taskDone */
4145 completionStatus = cau3_process_task_completion(base, handle->taskDone);
4146 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
4147 cau3_release_semaphore(base);
4148 #endif
4149 return (completionStatus);
4150 }
4151
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)4152 status_t CAU3_CHACHA20_POLY1305_Decrypt(CAU3_Type *base,
4153 cau3_handle_t *handle,
4154 const uint8_t *ciphertext,
4155 uint8_t *plaintext,
4156 size_t size,
4157 const uint8_t *aad,
4158 size_t aadLen,
4159 const uint8_t *nonce,
4160 const uint8_t *tag)
4161 {
4162 status_t completionStatus;
4163
4164 completionStatus = cau3_load_nonce(base, nonce, handle->keySlot);
4165 if (kStatus_Success != completionStatus)
4166 {
4167 return completionStatus;
4168 }
4169
4170 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
4171 completionStatus = cau3_lock_semaphore(base);
4172 if (kStatus_Success != completionStatus)
4173 {
4174 cau3_release_semaphore(base);
4175 return completionStatus;
4176 }
4177 #endif
4178
4179 base->CC_R[17] = handle->keySlot; /* key/iv slot */
4180 base->CC_R[18] = (uintptr_t)aad; /* AAD pointer */
4181 base->CC_R[19] = aadLen; /* AAD length (bytes) */
4182 base->CC_R[20] = (uintptr_t)ciphertext; /* Ciphertext pointer */
4183 base->CC_R[21] = size; /* Cyphertext length */
4184 base->CC_R[22] = (uintptr_t)plaintext; /* Plaintext pointer */
4185 base->CC_R[23] = (uintptr_t)tag; /* Tag pointer */
4186 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
4187 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
4188 base->CC_PC = CAU3_TASK_CHA_POLY_DECRYPT; /* ChaChaPoly decrypt vector */
4189 base->CC_CMD = handle->taskDone; /* trigger cau3 execution */
4190
4191 /* process the cau3 task completion signal specified by taskDone */
4192 completionStatus = cau3_process_task_completion(base, handle->taskDone);
4193 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
4194 cau3_release_semaphore(base);
4195 #endif
4196 return (completionStatus);
4197 }
4198
CAU3_KeyBlobUnwrap(CAU3_Type * base,cau3_key_slot_t keySlot,const uint8_t * keyBlob,uint32_t numberOfBlocks,cau3_key_slot_t dstContext)4199 status_t CAU3_KeyBlobUnwrap(CAU3_Type *base,
4200 cau3_key_slot_t keySlot,
4201 const uint8_t *keyBlob,
4202 uint32_t numberOfBlocks,
4203 cau3_key_slot_t dstContext)
4204 {
4205 status_t completionStatus;
4206 cau3_task_done_t taskDone;
4207
4208 if (0x3U & (uintptr_t)keyBlob)
4209 {
4210 return kStatus_InvalidArgument;
4211 }
4212
4213 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
4214 completionStatus = cau3_lock_semaphore(base);
4215 if (kStatus_Success != completionStatus)
4216 {
4217 cau3_release_semaphore(base);
4218 return completionStatus;
4219 }
4220 #endif
4221
4222 taskDone = kCAU3_TaskDonePoll;
4223
4224 /* execute the cau3 "key blob unwrap" task */
4225 base->CC_R[16] = (uintptr_t)keyBlob; /* pKeyBlob */
4226 base->CC_R[17] = keySlot; /* keySlot */
4227 base->CC_R[18] = numberOfBlocks; /* numberOfBlocks */
4228 base->CC_R[19] = dstContext; /* destination key context */
4229 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
4230 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
4231 base->CC_PC = CAU3_TASK_KEY_BLOB_UNWRAP; /* call cau_key_blob_unwrap() */
4232 base->CC_CMD = taskDone; /* trigger cau3 execution */
4233
4234 /* process the cau3 task completion signal specified by taskDone */
4235 completionStatus = cau3_process_task_completion(base, taskDone);
4236 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
4237 cau3_release_semaphore(base);
4238 #endif
4239 return (completionStatus);
4240 }
4241
CAU3_RPAtableInit(CAU3_Type * base,cau3_task_done_t taskDone)4242 status_t CAU3_RPAtableInit(CAU3_Type *base, cau3_task_done_t taskDone)
4243 {
4244 status_t completionStatus;
4245
4246 base->CC_R[16] = 1U; /* initialize the RPA table */
4247 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
4248 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
4249 base->CC_PC = CAU3_TASK_RPA_TABLE_SIZE; /* call cau_rpa_insert_key() */
4250 base->CC_CMD = taskDone; /* trigger cau3 execution */
4251
4252 /* process the cau3 task completion signal specified by taskDone */
4253 completionStatus = cau3_process_task_completion(base, taskDone);
4254 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
4255 cau3_release_semaphore(base);
4256 #endif
4257 return (completionStatus);
4258 }
4259
CAU3_RPAtableSize(CAU3_Type * base,uint32_t * result)4260 status_t CAU3_RPAtableSize(CAU3_Type *base, uint32_t *result)
4261 {
4262 status_t completionStatus;
4263
4264 /* execute the cau3 "rpa table size" task */
4265 base->CC_R[16] = 0U; /* do not initialize the RPA table */
4266 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
4267 base->CC_PC = CAU3_TASK_RPA_TABLE_SIZE; /* call cau_rpa_table_size */
4268
4269 /* this is a simple/fast task, hence the task completion signal can be polled */
4270 base->CC_CMD = kCAU3_TaskDonePoll;
4271 completionStatus = cau3_process_task_completion(base, kCAU3_TaskDonePoll);
4272 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
4273 cau3_release_semaphore(base);
4274 #endif
4275 *result = ((completionStatus == kStatus_Success) ? (uint32_t)base->CC_R[17] : 0);
4276
4277 return (completionStatus);
4278 }
4279
CAU3_RPAtableInsertKey(CAU3_Type * base,const uint32_t * cauKey,cau3_task_done_t taskDone)4280 status_t CAU3_RPAtableInsertKey(CAU3_Type *base,
4281 const uint32_t *cauKey,
4282 cau3_task_done_t taskDone)
4283 {
4284 status_t completionStatus;
4285
4286 base->CC_R[16] = (uintptr_t)cauKey; /* pointer to the key */
4287 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
4288 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
4289 base->CC_PC = CAU3_TASK_RPA_INSERT_KEY; /* call cau_rpa_insert_key() */
4290 base->CC_CMD = taskDone; /* trigger cau3 execution */
4291
4292 /* process the cau3 task completion signal specified by taskDone */
4293 completionStatus = cau3_process_task_completion(base, taskDone);
4294 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
4295 cau3_release_semaphore(base);
4296 #endif
4297 return (completionStatus);
4298
4299 }
4300
CAU3_RPAtableRemoveKey(CAU3_Type * base,uint32_t irkIx,cau3_task_done_t taskDone)4301 status_t CAU3_RPAtableRemoveKey(CAU3_Type *base, uint32_t irkIx, cau3_task_done_t taskDone)
4302 {
4303 status_t completionStatus;
4304
4305 base->CC_R[16] = irkIx; /* IRK index */
4306 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
4307 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
4308 base->CC_PC = CAU3_TASK_RPA_REMOVE_KEY; /* call cau_rpa_remove_key() */
4309 base->CC_CMD = taskDone; /* trigger cau3 execution */
4310
4311 /* process the cau3 task completion signal specified by taskDone */
4312 completionStatus = cau3_process_task_completion(base, taskDone);
4313 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
4314 cau3_release_semaphore(base);
4315 #endif
4316 return (completionStatus);
4317 }
4318
CAU3_RPAtableSearch(CAU3_Type * base,const uint32_t prand,const uint32_t hash,uint32_t * result,cau3_task_done_t taskDone)4319 status_t CAU3_RPAtableSearch(CAU3_Type *base,
4320 const uint32_t prand,
4321 const uint32_t hash,
4322 uint32_t *result,
4323 cau3_task_done_t taskDone)
4324 {
4325 status_t completionStatus;
4326
4327 base->CC_R[16] = prand; /* PRAND value */
4328 base->CC_R[17] = hash; /* hash value */
4329 base->CC_R30 = CAU3_DMEM_STK_BASE; /* initialize stack pointer (sp) */
4330 base->CC_R31 = 0U; /* set LR = 0 to signal a host task */
4331 base->CC_PC = CAU3_TASK_RPA_TABLE_SEARCH; /* call cau_rpa_search() */
4332 base->CC_CMD = taskDone; /* trigger cau3 execution */
4333
4334 /* process the cau3 task completion signal specified by taskDone */
4335 completionStatus = cau3_process_task_completion(base, taskDone);
4336 #if defined(FSL_CAU3_USE_HW_SEMA) && (FSL_CAU3_USE_HW_SEMA > 0)
4337 cau3_release_semaphore(base);
4338 #endif
4339 *result = ((completionStatus == kStatus_Success) ? (uint32_t)base->CC_R[18] : 0xFF);
4340
4341 return (completionStatus);
4342 }
4343