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(&params);
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, &params);
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(&params);
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, &params);
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(&params);
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, &params);
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(&params);
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, &params);
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(&params);
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, &params);
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(&params);
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, &params);
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(&params);
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, &params);
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(&params);
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, &params);
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(&params);
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, &params);
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(&params);
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, &params);
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(&params);
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, &params);
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(&params);
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, &params);
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(&params);
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, &params);
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(&params);
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, &params);
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(&params);
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, &params);
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(&params);
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, &params);
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(&params);
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, &params);
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(&params);
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, &params);
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