1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2023 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_caam.h"
10 #include "fsl_clock.h"
11 
12 #if defined(FSL_FEATURE_HAS_L1CACHE) || defined(__DCACHE_PRESENT)
13 #include "fsl_cache.h"
14 
15 #if defined(CACHE_MODE_WRITE_THROUGH) && CACHE_MODE_WRITE_THROUGH
16 #define CAAM_OUT_INVALIDATE (1u)
17 #else
18 #warning "DCACHE must be set to write-trough mode to safely invalidate cache!!"
19 #endif /* CACHE_MODE_WRITE_THROUGH */
20 
21 #endif /* defined(FSL_FEATURE_HAS_L1CACHE) || defined(__DCACHE_PRESENT) */
22 
23 /*******************************************************************************
24  * Definitions
25  ******************************************************************************/
26 
27 /* Component ID definition, used by tools. */
28 #ifndef FSL_COMPONENT_ID
29 #define FSL_COMPONENT_ID "platform.drivers.caam"
30 #endif
31 
32 /*! Compile time sizeof() check */
33 #define BUILD_ASSURE(condition, msg) extern int msg[1 - 2 * (!(condition))] __attribute__((unused))
34 
35 /*! AESA XCBC-MAC or CMAC request CLASS 1 (default) or CLASS 2 CHA */
36 #ifndef CAAM_AES_MAC_CLASS
37 #define CAAM_AES_MAC_CLASS_1 0x02000000u
38 #define CAAM_AES_MAC_CLASS_2 0x04000000u
39 #define CAAM_AES_MAC_CLASS   CAAM_AES_MAC_CLASS_1
40 #endif
41 
42 /*! IRBAR and ORBAR job ring registers are 64-bit. these macros access least significant address 32-bit word. */
43 #define IRBAR0 *(((volatile uint32_t *)(uint32_t) & (base->JOBRING[0].IRBAR_JR)) + 1)
44 #define ORBAR0 *(((volatile uint32_t *)(uint32_t) & (base->JOBRING[0].ORBAR_JR)) + 1)
45 #define IRBAR1 *(((volatile uint32_t *)(uint32_t) & (base->JOBRING[1].IRBAR_JR)) + 1)
46 #define ORBAR1 *(((volatile uint32_t *)(uint32_t) & (base->JOBRING[1].ORBAR_JR)) + 1)
47 #define IRBAR2 *(((volatile uint32_t *)(uint32_t) & (base->JOBRING[2].IRBAR_JR)) + 1)
48 #define ORBAR2 *(((volatile uint32_t *)(uint32_t) & (base->JOBRING[2].ORBAR_JR)) + 1)
49 #define IRBAR3 *(((volatile uint32_t *)(uint32_t) & (base->JOBRING[3].IRBAR_JR)) + 1)
50 #define ORBAR3 *(((volatile uint32_t *)(uint32_t) & (base->JOBRING[3].ORBAR_JR)) + 1)
51 
52 /*! Job Descriptor defines */
53 #define DESC_SIZE_MASK         0x0000003Fu
54 #define DESC_KEY_SIZE_MASK     0x3FFu
55 #define DESC_PAYLOAD_SIZE_MASK 0x0000FFFFu
56 #define DESC_LC1_MASK          0x00020000u
57 #define DESC_TAG_SIZE_MASK     0xFFu
58 #define DESC_HALT              0xA0C00000u
59 #define DESC_JUMP_2            0xA0000002u
60 #define DESC_JUMP_4            0xA0000004u
61 #define DESC_JUMP_6            0xA0000006u
62 #define DESC_BLACKKEY_NOMMEN   0x4u
63 #define SEC_MEM                0x8u
64 
65 typedef enum _caam_algorithm
66 {
67     kCAAM_AlgorithmAES    = 0x10u << 16,
68     kCAAM_AlgorithmDES    = 0x20u << 16,
69     kCAAM_Algorithm3DES   = 0x21u << 16,
70     kCAAM_AlgorithmSHA1   = 0x41u << 16,
71     kCAAM_AlgorithmSHA224 = 0x42u << 16,
72     kCAAM_AlgorithmSHA256 = 0x43u << 16,
73     kCAAM_AlgorithmSHA384 = 0x44u << 16,
74     kCAAM_AlgorithmSHA512 = 0x45u << 16,
75     kCAAM_AlgorithmCRC    = 0x90u << 16,
76 } caam_algorithm_t;
77 
78 typedef enum _caam_aai_symmetric_alg
79 {
80     kCAAM_ModeCTR     = 0x00U << 4,
81     kCAAM_ModeCBC     = 0x10U << 4,
82     kCAAM_ModeECB     = 0x20U << 4,
83     kCAAM_ModeCFB     = 0x30U << 4,
84     kCAAM_ModeOFB     = 0x40U << 4,
85     kCAAM_ModeCMAC    = 0x60U << 4,
86     kCAAM_ModeXCBCMAC = 0x70U << 4,
87     kCAAM_ModeCCM     = 0x80U << 4,
88     kCAAM_ModeGCM     = 0x90U << 4,
89 } caam_aai_symmetric_alg_t;
90 
91 typedef enum _caam_aai_hmac_alg
92 {
93     kCAAM_HmacModeNonDerivedKey = 0x01U << 4,
94     kCAAM_HmacModeDerivedKey    = 0x04U << 4,
95     kCAAM_SmacMode              = 0x02U << 4,
96 } caam_aai_hmac_alg_t;
97 
98 typedef enum _caam_algorithm_state
99 {
100     kCAAM_AlgStateUpdate    = 0u,
101     kCAAM_AlgStateInit      = 1u,
102     kCAAM_AlgStateFinal     = 2u,
103     kCAAM_AlgStateInitFinal = 3u,
104 } caam_algorithm_state_t;
105 
106 /*******************************************************************************
107  * HASH Definitions
108  ******************************************************************************/
109 enum _caam_sha_digest_len
110 {
111     kCAAM_RunLenSha1   = 28u,
112     kCAAM_OutLenSha1   = 20u,
113     kCAAM_RunLenSha224 = 40u,
114     kCAAM_OutLenSha224 = 28u,
115     kCAAM_RunLenSha256 = 40u,
116     kCAAM_OutLenSha256 = 32u,
117     kCAAM_RunLenSha384 = 64u,
118     kCAAM_OutLenSha384 = 48u,
119     kCAAM_RunLenSha512 = 64u,
120     kCAAM_OutLenSha512 = 64u,
121 };
122 
123 /*! Internal states of the HASH creation process */
124 typedef enum _caam_hash_algo_state
125 {
126     kCAAM_HashInit = 1u, /*!< Key in the HASH context is the input key. */
127     kCAAM_HashUpdate,    /*!< HASH context has algorithm specific context: MAC, K2 and K3 (XCBC-MAC), MAC and L (CMAC),
128                              running digest (MDHA). Key in the HASH context is the derived key. */
129 } caam_hash_algo_state_t;
130 
131 /*! 64-byte block represented as byte array or 16 32-bit words */
132 typedef union _caam_hash_block
133 {
134     uint32_t w[CAAM_HASH_BLOCK_SIZE / 4]; /*!< array of 32-bit words */
135     uint8_t b[CAAM_HASH_BLOCK_SIZE];      /*!< byte array */
136 } caam_hash_block_t;
137 
138 /*! Definitions of indexes into hash context array */
139 typedef enum _caam_hash_ctx_indexes
140 {
141     kCAAM_HashCtxKeyStartIdx = 12, /*!< context word array index where key is stored */
142     kCAAM_HashCtxKeySize     = 45, /*!< context word array index where key size is stored */
143     kCAAM_HashCtxNumWords = 46, /*!< number of context array 32-bit words /!\ Modification by WA: try to add HMAC with
144                                    derived key that is 64 byte long */
145 } caam_hash_ctx_indexes;
146 
147 typedef struct _caam_hash_ctx_internal
148 {
149     caam_hash_block_t blk; /*!< memory buffer. only full 64-byte blocks are written to CAAM during hash updates */
150     uint32_t word[kCAAM_HashCtxNumWords]; /*!< CAAM module context that needs to be saved/restored between CAAM jobs */
151     uint32_t blksz;                       /*!< number of valid bytes in memory buffer */
152     CAAM_Type *base;                      /*!< CAAM peripheral base address */
153     caam_handle_t *handle;                /*!< CAAM handle (specifies jobRing and optional callback function) */
154     caam_hash_algo_t algo; /*!< selected algorithm from the set of supported algorithms in caam_hash_algo_t */
155     caam_hash_algo_state_t fsm_state; /*!< finite machine state of the hash software process */
156 } caam_hash_ctx_internal_t;
157 
158 /*! Definitions of indexes into hash job descriptor */
159 enum _caam_hash_sgt_index
160 {
161     kCAAM_HashDescriptorSgtIdx = 14u, /*!< Index of the hash job descriptor[] where the two entry SGT starts. */
162 };
163 
164 /*! One entry in the SGT */
165 typedef struct _caam_sgt_entry
166 {
167     /* 64-bit address. */
168     uint32_t address_h;
169     uint32_t address_l;
170     uint32_t length;
171     uint32_t offset;
172 } caam_sgt_entry_t;
173 
174 /*! Definitions SGT entry type */
175 typedef enum _caam_hash_sgt_entry_type
176 {
177     kCAAM_HashSgtEntryNotLast = 0u, /*!< Do not set the Final Bit in SGT entries */
178     kCAAM_HashSgtEntryLast    = 1u, /*!< Sets Final Bit in the last SGT entry */
179 } caam_hash_sgt_entry_type_t;
180 
181 /*! Two entry SGT, embedded in the hash job descriptor */
182 typedef caam_sgt_entry_t caam_hash_internal_sgt_t[2];
183 
184 /*! Definitions of SGT type */
185 typedef enum _caam_hash_sgt_type
186 {
187     kCAAM_HashSgtInternal = 0u, /*!< Two entry SGT is copied into the hash job descriptor. */
188     kCAAM_HashSgtExternal = 1u, /*!< Use external SGT. */
189 } caam_hash_sgt_type_t;
190 
191 enum _caam_hash_non_blocking_sgt_entries
192 {
193     kCAAM_HashSgtMaxCtxEntries =
194         (sizeof(caam_hash_block_t) + sizeof(uint32_t) * kCAAM_HashCtxKeyStartIdx) / sizeof(caam_sgt_entry_t),
195 };
196 
197 typedef struct _caam_crc_ctx_internal
198 {
199     caam_hash_block_t blk; /*!< memory buffer. only full 64-byte blocks are written to CAAM during hash updates */
200     uint32_t word[kCAAM_HashCtxNumWords]; /*!< CAAM module context that needs to be saved/restored between CAAM jobs */
201     uint32_t blksz;                       /*!< number of valid bytes in memory buffer */
202     CAAM_Type *base;                      /*!< CAAM peripheral base address */
203     caam_handle_t *handle;                /*!< CAAM handle (specifies jobRing and optional callback function) */
204     caam_crc_algo_t algo;       /*!< selected algorithm from the set of supported algorithms in caam_hash_algo_t */
205     caam_aai_crc_alg_t crcmode; /*!< Specifies how CRC engine manipulates input and output data */
206     caam_hash_algo_state_t fsm_state; /*!< finite machine state of the hash software process */
207 } caam_crc_ctx_internal_t;
208 
209 /*******************************************************************************
210  * Variables
211  ******************************************************************************/
212 static caam_job_ring_interface_t *s_jr0 = NULL; /*!< Pointer to job ring interface 0. */
213 static uint32_t s_jrIndex0              = 0;    /*!< Current index in the input job ring 0. */
214 
215 static caam_job_ring_interface_t *s_jr1 = NULL; /*!< Pointer to job ring interface 1. */
216 static uint32_t s_jrIndex1              = 0;    /*!< Current index in the input job ring 1. */
217 
218 static caam_job_ring_interface_t *s_jr2 = NULL; /*!< Pointer to job ring interface 2. */
219 static uint32_t s_jrIndex2              = 0;    /*!< Current index in the input job ring 2. */
220 
221 static caam_job_ring_interface_t *s_jr3 = NULL; /*!< Pointer to job ring interface 3. */
222 static uint32_t s_jrIndex3              = 0;    /*!< Current index in the input job ring 3. */
223 
224 AT_NONCACHEABLE_SECTION(static caam_rng_config_t rngConfig);
225 AT_NONCACHEABLE_SECTION(static caam_desc_rng_t rngGenSeckey);
226 AT_NONCACHEABLE_SECTION(static caam_desc_rng_t rngInstantiate);
227 AT_NONCACHEABLE_SECTION(static caam_desc_rng_t descBuf);
228 /*******************************************************************************
229  * Code
230  ******************************************************************************/
231 
232 /*******************************************************************************
233  * CAAM Common code static
234  ******************************************************************************/
235 
236 /* Macros and functions computing data offset for descriptors */
237 #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET)
238 #include "fsl_memory.h"
239 
240 #ifndef FSL_MEM_M4_TCM_OFFSET
241 #define CAAM_OFFSET 0U
242 #else
243 #define CAAM_OFFSET FSL_MEM_M4_TCM_OFFSET
244 #endif
245 
ADD_OFFSET(uint32_t addr)246 static uint32_t ADD_OFFSET(uint32_t addr)
247 {
248     if (addr > FSL_MEM_M4_TCM_END)
249     {
250         return addr;
251     }
252     else if (addr < FSL_MEM_M4_TCM_BEGIN)
253     {
254         return addr;
255     }
256     else
257     {
258         return addr + CAAM_OFFSET;
259     }
260 }
261 
262 #else  /* !defined(FLS_FEATURE_CAAM_OFFSET) */
ADD_OFFSET(uint32_t addr)263 static uint32_t ADD_OFFSET(uint32_t addr)
264 {
265     return addr;
266 }
267 #endif /* FLS_FEATURE_CAAM_OFFSET */
268 
269 #if 0
270 /* for build without string.h memcpy() */
271 static void caam_memcpy(void *dst, const void *src, size_t size)
272 {
273     register uint8_t *to = (uint8_t *)(uintptr_t)dst;
274     register const uint8_t *from = (const uint8_t *)(uintptr_t)src;
275 
276     /* if it is possible to move data with 32-bit aligned access, do it so */
277     if ((size >= sizeof(uint32_t)) && (0u == ((uintptr_t)dst & 0x3u)) && (0u == ((uintptr_t)src & 0x3u)))
278     {
279         register uint32_t *to32 = (uint32_t *)(uintptr_t)dst;
280         register const uint32_t *from32 = (const uint32_t *)(uintptr_t)src;
281         while (size >= sizeof(uint32_t))
282         {
283             *to32 = *from32;
284             size -= sizeof(uint32_t);
285             to32++;
286             from32++;
287         }
288 
289         to = (uint8_t *)(uintptr_t)to32;
290         from = (const uint8_t *)(uintptr_t)from32;
291     }
292 
293     while (size)
294     {
295         *to = *from;
296         size--;
297         to++;
298         from++;
299     }
300 }
301 #else
302 #include <string.h>
303 #define caam_memcpy memcpy
304 #endif
305 
caam_job_ring_set_base_address_and_size(CAAM_Type * base,caam_job_ring_t jr,uint32_t * inputRingBase,size_t inputRingSize,uint32_t * outputRingBase,uint32_t outputRingSize)306 static void caam_job_ring_set_base_address_and_size(CAAM_Type *base,
307                                                     caam_job_ring_t jr,
308                                                     uint32_t *inputRingBase,
309                                                     size_t inputRingSize,
310                                                     uint32_t *outputRingBase,
311                                                     uint32_t outputRingSize)
312 {
313     if (kCAAM_JobRing0 == jr)
314     {
315         IRBAR0                   = ADD_OFFSET((uint32_t)inputRingBase);
316         base->JOBRING[0].IRSR_JR = inputRingSize;
317         ORBAR0                   = ADD_OFFSET((uint32_t)outputRingBase);
318         base->JOBRING[0].ORSR_JR = outputRingSize;
319     }
320 
321     if (kCAAM_JobRing1 == jr)
322     {
323         IRBAR1                   = (uintptr_t)ADD_OFFSET((uint32_t)inputRingBase);
324         base->JOBRING[1].IRSR_JR = inputRingSize;
325         ORBAR1                   = (uintptr_t)ADD_OFFSET((uint32_t)outputRingBase);
326         base->JOBRING[1].ORSR_JR = outputRingSize;
327     }
328 
329     if (kCAAM_JobRing2 == jr)
330     {
331         IRBAR2                   = (uintptr_t)ADD_OFFSET((uint32_t)inputRingBase);
332         base->JOBRING[2].IRSR_JR = inputRingSize;
333         ORBAR2                   = (uintptr_t)ADD_OFFSET((uint32_t)outputRingBase);
334         base->JOBRING[2].ORSR_JR = outputRingSize;
335     }
336 
337     if (kCAAM_JobRing3 == jr)
338     {
339         IRBAR3                   = (uintptr_t)ADD_OFFSET((uint32_t)inputRingBase);
340         base->JOBRING[3].IRSR_JR = inputRingSize;
341         ORBAR3                   = (uintptr_t)ADD_OFFSET((uint32_t)outputRingBase);
342         base->JOBRING[3].ORSR_JR = outputRingSize;
343     }
344 }
345 
caam_input_ring_set_jobs_added(CAAM_Type * base,caam_job_ring_t jr,uint32_t numJobsAdded)346 static inline void caam_input_ring_set_jobs_added(CAAM_Type *base, caam_job_ring_t jr, uint32_t numJobsAdded)
347 {
348     /* Data and Instruction Synchronization Barrier to make sure */
349     /* that the descriptor will be loaded into CAAM in time*/
350     __ISB();
351     __DSB();
352 
353     if (kCAAM_JobRing0 == jr)
354     {
355         base->JOBRING[0].IRJAR_JR = numJobsAdded;
356     }
357 
358     if (kCAAM_JobRing1 == jr)
359     {
360         base->JOBRING[1].IRJAR_JR = numJobsAdded;
361     }
362 
363     if (kCAAM_JobRing2 == jr)
364     {
365         base->JOBRING[2].IRJAR_JR = numJobsAdded;
366     }
367 
368     if (kCAAM_JobRing3 == jr)
369     {
370         base->JOBRING[3].IRJAR_JR = numJobsAdded;
371     }
372 }
373 
caam_output_ring_set_jobs_removed(CAAM_Type * base,caam_job_ring_t jr,uint32_t numJobsRemoved)374 static inline void caam_output_ring_set_jobs_removed(CAAM_Type *base, caam_job_ring_t jr, uint32_t numJobsRemoved)
375 {
376     if (kCAAM_JobRing0 == jr)
377     {
378         base->JOBRING[0].ORJRR_JR = numJobsRemoved;
379     }
380 
381     if (kCAAM_JobRing1 == jr)
382     {
383         base->JOBRING[1].ORJRR_JR = numJobsRemoved;
384     }
385 
386     if (kCAAM_JobRing2 == jr)
387     {
388         base->JOBRING[2].ORJRR_JR = numJobsRemoved;
389     }
390 
391     if (kCAAM_JobRing3 == jr)
392     {
393         base->JOBRING[3].ORJRR_JR = numJobsRemoved;
394     }
395 }
396 
caam_output_ring_get_slots_full(CAAM_Type * base,caam_job_ring_t jr)397 static uint32_t caam_output_ring_get_slots_full(CAAM_Type *base, caam_job_ring_t jr)
398 {
399     uint32_t retVal = 0;
400 
401     if (kCAAM_JobRing0 == jr)
402     {
403         retVal = base->JOBRING[0].ORSFR_JR;
404     }
405 
406     if (kCAAM_JobRing1 == jr)
407     {
408         retVal = base->JOBRING[1].ORSFR_JR;
409     }
410 
411     if (kCAAM_JobRing2 == jr)
412     {
413         retVal = base->JOBRING[2].ORSFR_JR;
414     }
415 
416     if (kCAAM_JobRing3 == jr)
417     {
418         retVal = base->JOBRING[3].ORSFR_JR;
419     }
420 
421     return retVal;
422 }
423 
424 /*!
425  * @brief Tests the correct key size.
426  *
427  * This function tests the correct key size.
428  * @param keySize Input key length in bytes.
429  * @return True if the key length is supported, false if not.
430  */
431 bool caam_check_key_size(const uint32_t keySize);
caam_check_key_size(const uint32_t keySize)432 bool caam_check_key_size(const uint32_t keySize)
433 {
434     return ((keySize == 16u) || ((keySize == 24u)) || ((keySize == 32u)));
435 }
436 
437 /*!
438  * @brief Maps HMAC algo to its underlying hashing algorithm.
439  *
440  * @param algo The algorithm to be mapped.
441  * @return The underlying hashing algorithm for HMAC algo. Non-HMAC algo
442  * will return the same algorithm as the input.
443  */
hmac2hash_algo(caam_hash_algo_t algo)444 static caam_hash_algo_t hmac2hash_algo(caam_hash_algo_t algo)
445 {
446     caam_hash_algo_t mappedAlgo;
447 
448     switch (algo)
449     {
450         case kCAAM_HmacSha1:
451             mappedAlgo = kCAAM_Sha1;
452             break;
453         case kCAAM_HmacSha224:
454             mappedAlgo = kCAAM_Sha224;
455             break;
456         case kCAAM_HmacSha256:
457             mappedAlgo = kCAAM_Sha256;
458             break;
459         case kCAAM_HmacSha384:
460             mappedAlgo = kCAAM_Sha384;
461             break;
462         case kCAAM_HmacSha512:
463             mappedAlgo = kCAAM_Sha512;
464             break;
465         default:
466             /* Other algorithms stay the same. */
467             mappedAlgo = algo;
468             break;
469     }
470 
471     return mappedAlgo;
472 }
473 
474 /*!
475  * @brief Checks if an HMAC key is not oversized, and if it is, it gets hashed.
476  *
477  * @param base CAAM peripheral base address
478  * @param handle Handle used for this request.
479  * @param algo Underlaying algorithm to use for MAC computation.
480  * @param inputKey The key to be checked
481  * @param inputKeySize Size of input key in bytes
482  * @param[out] outputKey Output buffer for the key which can hold a digest of specified algo
483  * @param[out] outputKeySize Output parameter storing the size of the output key in bytes
484  * @return Status of the one call hash operation.
485  */
hmac_prehash_key(CAAM_Type * base,caam_handle_t * handle,caam_hash_algo_t algo,const uint8_t * inputKey,size_t inputKeySize,uint8_t * outputKey,size_t * outputKeySize)486 static status_t hmac_prehash_key(CAAM_Type *base,
487                                  caam_handle_t *handle,
488                                  caam_hash_algo_t algo,
489                                  const uint8_t *inputKey,
490                                  size_t inputKeySize,
491                                  uint8_t *outputKey,
492                                  size_t *outputKeySize)
493 {
494     status_t status = kStatus_Success;
495 
496     if ((((algo == kCAAM_HmacSha256) || (algo == kCAAM_HmacSha1) || (algo == kCAAM_HmacSha224)) &&
497          inputKeySize > 64u) ||
498         (((algo == kCAAM_HmacSha384) || (algo == kCAAM_HmacSha512)) && inputKeySize > 128u))
499     {
500         /* Key is too large - as per FIPS 198-1, hash it down first with the selected hash */
501         const caam_hash_algo_t mappedAlgo = hmac2hash_algo(algo);
502         status = CAAM_HASH(base, handle, mappedAlgo, inputKey, inputKeySize, NULL, 0, outputKey, outputKeySize);
503     }
504     else
505     {
506         /* Key size is within limits */
507         (void)caam_memcpy(outputKey, inputKey, inputKeySize);
508         *outputKeySize = inputKeySize;
509     }
510 
511     return status;
512 }
513 
caam_in_job_ring_add(CAAM_Type * base,caam_job_ring_t jobRing,uint32_t * descaddr)514 static status_t caam_in_job_ring_add(CAAM_Type *base, caam_job_ring_t jobRing, uint32_t *descaddr)
515 {
516     /* adding new job to the s_inJobRing[] must be atomic
517      * as this is global variable
518      */
519     uint32_t currPriMask = DisableGlobalIRQ();
520 
521     if (kCAAM_JobRing0 == jobRing)
522     {
523         s_jr0->inputJobRing[s_jrIndex0] = (ADD_OFFSET((uint32_t)descaddr));
524         s_jrIndex0++;
525         if (s_jrIndex0 >= ARRAY_SIZE(s_jr0->inputJobRing))
526         {
527             s_jrIndex0 = 0;
528         }
529     }
530     else if (kCAAM_JobRing1 == jobRing)
531     {
532         s_jr1->inputJobRing[s_jrIndex1] = ADD_OFFSET((uint32_t)descaddr);
533         s_jrIndex1++;
534         if (s_jrIndex1 >= ARRAY_SIZE(s_jr1->inputJobRing))
535         {
536             s_jrIndex1 = 0;
537         }
538     }
539     else if (kCAAM_JobRing2 == jobRing)
540     {
541         s_jr2->inputJobRing[s_jrIndex2] = ADD_OFFSET((uint32_t)descaddr);
542         s_jrIndex2++;
543         if (s_jrIndex2 >= ARRAY_SIZE(s_jr2->inputJobRing))
544         {
545             s_jrIndex2 = 0;
546         }
547     }
548     else if (kCAAM_JobRing3 == jobRing)
549     {
550         s_jr3->inputJobRing[s_jrIndex3] = ADD_OFFSET((uint32_t)descaddr);
551         s_jrIndex3++;
552         if (s_jrIndex3 >= ARRAY_SIZE(s_jr3->inputJobRing))
553         {
554             s_jrIndex3 = 0;
555         }
556     }
557     else
558     {
559         EnableGlobalIRQ(currPriMask);
560         return kStatus_InvalidArgument;
561     }
562 
563     caam_input_ring_set_jobs_added(base, jobRing, 1);
564 
565     /* Enable IRQ */
566     EnableGlobalIRQ(currPriMask);
567 
568     return kStatus_Success;
569 }
570 
571 /* this function shall be only called inside CAAM driver critical section
572  * because it accesses global variables.
573  */
caam_out_job_ring_remove(CAAM_Type * base,caam_job_ring_t jobRing,int outIndex)574 static status_t caam_out_job_ring_remove(CAAM_Type *base, caam_job_ring_t jobRing, int outIndex)
575 {
576     if (kCAAM_JobRing0 == jobRing)
577     {
578         s_jr0->outputJobRing[outIndex++] = 0; /* clear descriptor address */
579         s_jr0->outputJobRing[outIndex]   = 0; /* clear status */
580     }
581     else if (kCAAM_JobRing1 == jobRing)
582     {
583         s_jr1->outputJobRing[outIndex++] = 0; /* clear descriptor address */
584         s_jr1->outputJobRing[outIndex]   = 0; /* clear status */
585     }
586     else if (kCAAM_JobRing2 == jobRing)
587     {
588         s_jr2->outputJobRing[outIndex++] = 0; /* clear descriptor address */
589         s_jr2->outputJobRing[outIndex]   = 0; /* clear status */
590     }
591     else if (kCAAM_JobRing3 == jobRing)
592     {
593         s_jr3->outputJobRing[outIndex++] = 0; /* clear descriptor address */
594         s_jr3->outputJobRing[outIndex]   = 0; /* clear status */
595     }
596     else
597     {
598         /* Intentional empty */
599     }
600 
601     caam_output_ring_set_jobs_removed(base, jobRing, 1);
602     return 0;
603 }
604 
caam_out_job_ring_test_and_remove(CAAM_Type * base,caam_job_ring_t jobRing,uint32_t * descriptor,bool * wait,bool * found)605 static status_t caam_out_job_ring_test_and_remove(
606     CAAM_Type *base, caam_job_ring_t jobRing, uint32_t *descriptor, bool *wait, bool *found)
607 {
608     uint32_t currPriMask = DisableGlobalIRQ();
609     uint32_t i;
610     status_t status;
611 
612     *found = false;
613     *wait  = true;
614     status = kStatus_Success;
615     uint32_t *jr;
616     uint32_t jrEntries;
617 
618     if (jobRing == kCAAM_JobRing0)
619     {
620         jr        = s_jr0->outputJobRing;
621         jrEntries = ARRAY_SIZE(s_jr0->outputJobRing);
622     }
623     else if (jobRing == kCAAM_JobRing1)
624     {
625         jr        = s_jr1->outputJobRing;
626         jrEntries = ARRAY_SIZE(s_jr1->outputJobRing);
627     }
628     else if (jobRing == kCAAM_JobRing2)
629     {
630         jr        = s_jr2->outputJobRing;
631         jrEntries = ARRAY_SIZE(s_jr2->outputJobRing);
632     }
633     else if (jobRing == kCAAM_JobRing3)
634     {
635         jr        = s_jr3->outputJobRing;
636         jrEntries = ARRAY_SIZE(s_jr3->outputJobRing);
637     }
638     else
639     {
640         return kStatus_InvalidArgument;
641     }
642 
643     /* check if an interrupt or other thread consumed the result that we just saw */
644     if ((caam_output_ring_get_slots_full(base, jobRing)) != 0U)
645     {
646         /* check if our descriptor is in the output job ring
647          * look from the beginning of the out job ring
648          */
649         i = 0;
650 
651         while ((!*found) && (i < jrEntries))
652         {
653             if (jr[i] == (uint32_t)descriptor)
654             {
655                 *found = true;
656                 *wait  = false;
657                 /* check for error in status word */
658                 if ((jr[i + 1U]) != 0U)
659                 {
660                     /* printf("Error 0x%lx\r\n", jr[i + 1]); */
661 
662                     /* for JMP/HALT commands with User specified status, return the user status, just to allow the
663                      * software to test for user status termination status words */
664                     /* This is used by PKHA PrimalityTest to report a candidate is believed not being prime */
665                     if (0x30000000u == (jr[i + 1U] & 0xff000000u))
666                     {
667                         status = (int32_t)jr[i + 1U];
668                     }
669                     else
670                     {
671                         status = kStatus_Fail;
672                     }
673                 }
674                 (void)caam_out_job_ring_remove(base, jobRing, (int)i);
675             }
676             else
677             {
678                 /* try next result */
679                 i += 2u;
680             }
681         }
682     }
683     EnableGlobalIRQ(currPriMask);
684     return status;
685 }
686 
687 typedef union _caam_xcm_block_t
688 {
689     uint32_t w[4]; /*!< CAAM context register is 16 bytes written as four 32-bit words */
690     uint8_t b[16]; /*!< 16 octets block for CCM B0 and CTR0 and for GCM */
691 } caam_xcm_block_t;
692 
swap_bytes(uint32_t in)693 static uint32_t swap_bytes(uint32_t in)
694 {
695     return (((in & 0x000000ffu) << 24) | ((in & 0x0000ff00u) << 8) | ((in & 0x00ff0000u) >> 8) |
696             ((in & 0xff000000u) >> 24));
697 }
698 
699 /*!
700  * @brief AES GCM check validity of input arguments.
701  *
702  * This function checks the validity of input arguments.
703  *
704  * @param base LTC peripheral base address.
705  * @param src Source address (plaintext or ciphertext).
706  * @param iv Initialization vector address.
707  * @param aad Additional authenticated data address.
708  * @param dst Destination address (plaintext or ciphertext).
709  * @param inputSize Size of input (same size as output) data in bytes.
710  * @param ivSize Size of Initialization vector in bytes.
711  * @param aadSize Size of additional data in bytes.
712  * @param tagSize Size of the GCM tag in bytes.
713  */
caam_aes_gcm_check_input_args(CAAM_Type * base,const uint8_t * src,const uint8_t * iv,const uint8_t * aad,uint8_t * dst,size_t inputSize,size_t ivSize,size_t aadSize,size_t tagSize)714 static status_t caam_aes_gcm_check_input_args(CAAM_Type *base,
715                                               const uint8_t *src,
716                                               const uint8_t *iv,
717                                               const uint8_t *aad,
718                                               uint8_t *dst,
719                                               size_t inputSize,
720                                               size_t ivSize,
721                                               size_t aadSize,
722                                               size_t tagSize)
723 {
724     if (base == NULL)
725     {
726         return kStatus_InvalidArgument;
727     }
728 
729     /* tag can be NULL to skip tag processing */
730     if (((ivSize != 0U) && (iv == NULL)) || ((aadSize != 0U) && (aad == NULL)) ||
731         ((inputSize != 0U) && ((src == NULL) || (dst == NULL))))
732     {
733         return kStatus_InvalidArgument;
734     }
735 
736     /* octet length of tag (tagSize) must be element of 4,8,12,13,14,15,16 */
737     if (((tagSize > 16u) || (tagSize < 12u)) && (tagSize != 4u) && (tagSize != 8u))
738     {
739         return kStatus_InvalidArgument;
740     }
741 
742     /* no IV AAD DATA makes no sense */
743     if (0U == (inputSize + ivSize + aadSize))
744     {
745         return kStatus_InvalidArgument;
746     }
747 
748     /* check length of input strings. This is more strict than the GCM specificaiton due to 32-bit architecture.
749      * The API interface would work on 64-bit architecture as well, but as it has not been tested, let it limit to
750      * 32-bits.
751      */
752     if (!((ivSize >= 1u) && (sizeof(size_t) <= 4u)))
753     {
754         return kStatus_InvalidArgument;
755     }
756 
757     return kStatus_Success;
758 }
759 
760 static const uint32_t templateAesGcm[] = {
761     /* 00 */ 0xB0800000u, /* HEADER */
762     /* 01 */ 0x02000000u, /* KEY */
763     /* 02 */ 0x00000000u, /* place: key address */
764 
765     /* 03 */ 0x82100908u, /* OPERATION: AES GCM Decrypt Finalize */
766 
767     /* 04 */ 0x12830004u, /* LOAD Class 1 ICV Size Register by IMM data */
768     /* 05 */ 0x00000000u, /* place: received ICV size */
769 
770     /* 06 */ 0x22210000u, /* FIFO LOAD IV (flush) */
771     /* 07 */ 0x00000000u, /* place: IV address */
772 
773     /* 08 */ 0x22310000u, /* FIFO LOAD AAD (flush) */
774     /* 09 */ 0x00000000u, /* place: AAD address */
775 
776     /* 10 */ 0x22530000u, /* FIFO LOAD message */
777     /* 11 */ 0x00000000u, /* place: message address */
778     /* 12 */ 0x00000000u, /* place: message size */
779 
780     /* 13 */ 0x60700000u, /* FIFO STORE Message */
781     /* 14 */ 0x00000000u, /* place: destination address */
782     /* 15 */ 0x00000000u, /* place: destination size */
783 
784     /* 16 */ 0xA3001201u, /* JMP always to next command. Load/store checkpoint. Class 1 done checkpoint. */
785 
786                           /* For encryption, write the computed and encrypted MAC to user buffer */
787     /* For decryption, compare the computed tag with the received tag, CICV-only job. */
788     /* 17 */ 0x10880004u, /* LOAD Immediate to Clear Written Register. */
789     /* 18 */ 0x08000004u, /* value for Clear Written Register: C1D and C1DS bits are set */
790     /* 19 */ 0x12820004u, /* LOAD Immediate to C1DS Register. */
791     /* 20 */ 0x00000000u, /* zero data size */
792     /* 21 */ 0x12830004u, /* LOAD Class 1 ICV Size Register by IMM data */
793     /* 22 */ 0x00000000u, /* place: received ICV size */
794     /* 23 */ 0x82100902u, /* OPERATION: AES GCM Decrypt Update ICV_TEST */
795     /* 24 */ 0x223B0000u, /* FIFO LOAD ICV */
796     /* 25 */ 0x00000000u, /* place: received ICV address */
797 };
798 
799 status_t caam_aes_gcm_non_blocking(CAAM_Type *base,
800                                    caam_handle_t *handle,
801                                    caam_desc_aes_gcm_t descriptor,
802                                    const uint8_t *input,
803                                    uint8_t *output,
804                                    size_t size,
805                                    const uint8_t *iv,
806                                    size_t ivSize,
807                                    const uint8_t *aad,
808                                    size_t aadSize,
809                                    const uint8_t *key,
810                                    size_t keySize,
811                                    uint32_t tag,
812                                    size_t tagSize,
813                                    int encrypt);
814 
caam_aes_gcm_non_blocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_aes_gcm_t descriptor,const uint8_t * input,uint8_t * output,size_t size,const uint8_t * iv,size_t ivSize,const uint8_t * aad,size_t aadSize,const uint8_t * key,size_t keySize,uint32_t tag,size_t tagSize,int encrypt)815 status_t caam_aes_gcm_non_blocking(CAAM_Type *base,
816                                    caam_handle_t *handle,
817                                    caam_desc_aes_gcm_t descriptor,
818                                    const uint8_t *input,
819                                    uint8_t *output,
820                                    size_t size,
821                                    const uint8_t *iv,
822                                    size_t ivSize,
823                                    const uint8_t *aad,
824                                    size_t aadSize,
825                                    const uint8_t *key,
826                                    size_t keySize,
827                                    uint32_t tag,
828                                    size_t tagSize,
829                                    int encrypt)
830 {
831     BUILD_ASSURE(sizeof(templateAesGcm) <= sizeof(caam_desc_aes_gcm_t), caam_desc_aes_gcm_t_size);
832     status_t status;
833 
834     status = caam_aes_gcm_check_input_args(base, input, iv, aad, output, size, ivSize, aadSize, tagSize);
835     if (status != kStatus_Success)
836     {
837         return status;
838     }
839 
840     /* get template descriptor and it's size */
841     uint32_t descriptorSize = ARRAY_SIZE(templateAesGcm);
842     (void)caam_memcpy(descriptor, templateAesGcm, sizeof(templateAesGcm));
843 
844     /* add descriptor size */
845     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
846 
847     /* key address and key size */
848     descriptor[1] |= (keySize & DESC_KEY_SIZE_MASK);
849     descriptor[2] = ADD_OFFSET((uint32_t)key);
850 
851     /* Encrypt decrypt */
852     if (0 != encrypt)
853     {
854         descriptor[3] |= 1u; /* ENC */
855     }
856 
857     /* ICV Size */
858     descriptor[5] = tagSize;
859 
860     bool ivLast  = (aadSize == 0U) && (size == 0U);
861     bool aadLast = (size == 0U);
862 
863     /* IV address and size */
864     descriptor[6] |= (ivSize & DESC_PAYLOAD_SIZE_MASK);
865     descriptor[7] = ADD_OFFSET((uint32_t)iv);
866     if (ivLast)
867     {
868         descriptor[6] |= DESC_LC1_MASK; /* LC1 */
869     }
870 
871     /* AAD address and size */
872     descriptor[8] |= (aadSize & DESC_PAYLOAD_SIZE_MASK);
873     descriptor[9] = ADD_OFFSET((uint32_t)aad);
874     if ((!ivLast) && aadLast)
875     {
876         descriptor[8] |= DESC_LC1_MASK; /* LC1 */
877     }
878 
879     /* Message source address and size */
880     descriptor[11] = ADD_OFFSET((uint32_t)input);
881     descriptor[12] = size;
882 
883     /* Message destination address and size */
884     descriptor[14] = ADD_OFFSET((uint32_t)output);
885     descriptor[15] = size;
886 
887     if (tag != 0U)
888     {
889         if (encrypt == 0)
890         {
891             descriptor[22] = tagSize;
892             descriptor[24] |= (tagSize & DESC_TAG_SIZE_MASK);
893             descriptor[25] = ADD_OFFSET((uint32_t)tag);
894         }
895         else
896         {
897             /* For encryption change the command to FIFO STORE, as tag data needs to be put into tag output */
898             descriptor[16] = 0x52200000u | (tagSize & DESC_TAG_SIZE_MASK); /* STORE from Class 1 context to tag */
899             descriptor[17] = ADD_OFFSET((uint32_t)tag);                    /* place: tag address */
900             ;
901             descriptor[18] = DESC_HALT;                                    /* always halt with status 0x0 (normal) */
902         }
903     }
904     else
905     {
906         /* tag is NULL, skip tag processing */
907         descriptor[16] = DESC_HALT; /* always halt with status 0x0 (normal) */
908     }
909 
910     /* add operation specified by descriptor to CAAM Job Ring */
911     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
912 }
913 
caam_aes_ccm_check_input_args(CAAM_Type * base,const uint8_t * src,const uint8_t * iv,const uint8_t * key,uint8_t * dst,size_t size,size_t ivSize,size_t aadSize,size_t keySize,size_t tagSize)914 static status_t caam_aes_ccm_check_input_args(CAAM_Type *base,
915                                               const uint8_t *src,
916                                               const uint8_t *iv,
917                                               const uint8_t *key,
918                                               uint8_t *dst,
919                                               size_t size,
920                                               size_t ivSize,
921                                               size_t aadSize,
922                                               size_t keySize,
923                                               size_t tagSize)
924 {
925     if (base == NULL)
926     {
927         return kStatus_InvalidArgument;
928     }
929 
930     /* tag can be NULL to skip tag processing */
931     /* payload may also be empty, in which case the specification degenerates to an authentication mode on the
932      * associated data. */
933     if (((src == NULL) && (0u != size)) || (iv == NULL) || (key == NULL) || ((dst == NULL) && (0u != size)))
934     {
935         return kStatus_InvalidArgument;
936     }
937 
938     /* size of Nonce (ivSize) must be element of 7,8,9,10,11,12,13 */
939     if ((ivSize < 7u) || (ivSize > 13u))
940     {
941         return kStatus_InvalidArgument;
942     }
943     /* octet length of MAC (tagSize) must be element of 4,6,8,10,12,14,16 for tag processing or zero to skip tag
944      * processing */
945     if (((tagSize > 0U) && (tagSize < 4u)) || (tagSize > 16u) || ((tagSize & 1u) != 0U))
946     {
947         return kStatus_InvalidArgument;
948     }
949 
950     /* check if keySize is supported */
951     if (!caam_check_key_size(keySize))
952     {
953         return kStatus_InvalidArgument;
954     }
955 
956     /* AESA does not support more AAD than this */
957     if (aadSize >= 65280u)
958     {
959         return kStatus_InvalidArgument;
960     }
961     return kStatus_Success;
962 }
963 
caam_aes_ccm_context_init(uint32_t inputSize,const uint8_t * iv,uint32_t ivSize,uint32_t aadSize,uint32_t tagSize,void * b0,void * ctr0)964 static void caam_aes_ccm_context_init(
965     uint32_t inputSize, const uint8_t *iv, uint32_t ivSize, uint32_t aadSize, uint32_t tagSize, void *b0, void *ctr0)
966 {
967     caam_xcm_block_t blk;
968     caam_xcm_block_t blkZero = {{0x0u, 0x0u, 0x0u, 0x0u}};
969 
970     uint8_t q; /* octet length of binary representation of the octet length of the payload. computed as (15 - n), where
971               n is length of nonce(=ivSize) */
972     uint8_t flags_field; /* flags field in B0 and CTR0 */
973 
974     /* compute B0 */
975     (void)caam_memcpy(&blk, &blkZero, sizeof(blk));
976     /* tagSize - size of output MAC */
977     q           = 15U - (uint8_t)ivSize;
978     flags_field = (uint8_t)(8U * ((tagSize - 2U) / 2U) + q - 1U); /* 8*M' + L' */
979     if (aadSize != 0U)
980     {
981         flags_field |= 0x40U;                 /* Adata */
982     }
983     blk.b[0] = flags_field;                   /* flags field */
984     blk.w[3] = swap_bytes(inputSize);         /* message size, most significant byte first */
985     (void)caam_memcpy(&blk.b[1], iv, ivSize); /* nonce field */
986 
987     /* Write B0 data to the context register.
988      */
989     (void)caam_memcpy(b0, (void *)&blk.b[0], 16);
990 
991     /* Write CTR0 to the context register.
992      */
993     (void)caam_memcpy(&blk, &blkZero, sizeof(blk)); /* ctr(0) field = zero */
994     blk.b[0] = q - 1U;                              /* flags field */
995     (void)caam_memcpy(&blk.b[1], iv, ivSize);       /* nonce field */
996     (void)caam_memcpy(ctr0, (void *)&blk.b[0], 16);
997 }
998 
999 static const uint32_t templateAesCcm[] = {
1000     /* 00 */ 0xB0800000u, /* HEADER */
1001     /* 01 */ 0x02000000u, /* KEY */
1002     /* 02 */ 0x00000000u, /* place: key address */
1003 
1004     /* 03 */ 0x12A00010u, /* LOAD 16 immediate bytes of B0 to Class 1 Context Register. Offset 0 bytes. */
1005     /* 04 */ 0x00000000u, /* place: B0[0-3] */
1006     /* 05 */ 0x00000000u, /* place: B0[4-7] */
1007     /* 06 */ 0x00000000u, /* place: B0[8-11] */
1008     /* 07 */ 0x00000000u, /* place: B0[12-15] */
1009 
1010     /* 08 */ 0x12A01010u, /* LOAD 16 immediate bytes of CTR0 to Class 1 Context Register. Offset 16 bytes. */
1011     /* 09 */ 0x00000000u, /* place: CTR0[0-3] */
1012     /* 10 */ 0x00000000u, /* place: CTR0[4-7] */
1013     /* 11 */ 0x00000000u, /* place: CTR0[8-11] */
1014     /* 12 */ 0x00000000u, /* place: CTR0[12-15] */
1015 
1016     /* 13 */ 0x8210080Cu, /* OPERATION: AES CCM Decrypt Initialize/Finalize */
1017 
1018     /* 14 */ 0x22B00004u, /* FIFO LOAD additional authentication data. Immediate 32-bit word with aadSize encoded */
1019     /* 15 */ 0x00000000u, /* place: encoded aadSize followed by first byte(s) of authentication data */
1020     /* 16 */ 0x22310000u, /* FIFO LOAD additional authentication data. Flush as this is last data of AAD type. */
1021     /* 17 */ 0x00000000u, /* place: AAD address */
1022 
1023     /* 18 */ 0x22530000u, /* FIFO LOAD message */
1024     /* 19 */ 0x00000000u, /* place: message address */
1025     /* 20 */ 0x00000000u, /* place: message size */
1026 
1027     /* 21 */ 0x60700000u, /* FIFO STORE Message */
1028     /* 22 */ 0x00000000u, /* place: destination address */
1029     /* 23 */ 0x00000000u, /* place: destination size */
1030 
1031                           /* For encryption, write the computed and encrypted MAC to user buffer */
1032     /* 24 */ 0x52202000u, /* STORE from Class 1 context to tag */
1033     /* 25 */ 0x00000000u, /* place: tag address */
1034 
1035     /* For decryption, compare the computed tag with the received tag */
1036 
1037 };
1038 
1039 status_t caam_aes_ccm_non_blocking(CAAM_Type *base,
1040                                    caam_handle_t *handle,
1041                                    caam_desc_aes_ccm_t descriptor,
1042                                    const uint8_t *input,
1043                                    uint8_t *output,
1044                                    size_t size,
1045                                    const uint8_t *iv,
1046                                    size_t ivSize,
1047                                    const uint8_t *aad,
1048                                    size_t aadSize,
1049                                    const uint8_t *key,
1050                                    size_t keySize,
1051                                    uint32_t tag,
1052                                    size_t tagSize,
1053                                    int encrypt);
1054 
caam_aes_ccm_non_blocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_aes_ccm_t descriptor,const uint8_t * input,uint8_t * output,size_t size,const uint8_t * iv,size_t ivSize,const uint8_t * aad,size_t aadSize,const uint8_t * key,size_t keySize,uint32_t tag,size_t tagSize,int encrypt)1055 status_t caam_aes_ccm_non_blocking(CAAM_Type *base,
1056                                    caam_handle_t *handle,
1057                                    caam_desc_aes_ccm_t descriptor,
1058                                    const uint8_t *input,
1059                                    uint8_t *output,
1060                                    size_t size,
1061                                    const uint8_t *iv,
1062                                    size_t ivSize,
1063                                    const uint8_t *aad,
1064                                    size_t aadSize,
1065                                    const uint8_t *key,
1066                                    size_t keySize,
1067                                    uint32_t tag,
1068                                    size_t tagSize,
1069                                    int encrypt)
1070 {
1071     BUILD_ASSURE(sizeof(templateAesCcm) <= sizeof(caam_desc_aes_ccm_t), caam_desc_aes_ccm_t_size);
1072     status_t status;
1073 
1074     /* get template descriptor and it's size */
1075     uint32_t descriptorSize = ARRAY_SIZE(templateAesCcm);
1076     (void)caam_memcpy(descriptor, templateAesCcm, sizeof(templateAesCcm));
1077 
1078     status = caam_aes_ccm_check_input_args(base, input, iv, key, output, size, ivSize, aadSize, keySize, tagSize);
1079     if (status != kStatus_Success)
1080     {
1081         return status;
1082     }
1083 
1084     /* add descriptor size */
1085     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
1086 
1087     /* key address and key size */
1088     descriptor[1] |= (keySize & DESC_KEY_SIZE_MASK);
1089     descriptor[2] = ADD_OFFSET((uint32_t)key);
1090 
1091     /* B0 and CTR0 */
1092     caam_aes_ccm_context_init(size, iv, ivSize, aadSize, tagSize, &descriptor[4], &descriptor[9]);
1093 
1094     /* Encrypt decrypt */
1095     if (encrypt != 0)
1096     {
1097         descriptor[13] |= 1u; /* ENC */
1098     }
1099     else if (tag != 0U)
1100     {
1101         /* If we decrypt message with tag, then desc[18] is not last FIFO LOAD because FIFO LOAD is used for TAG */
1102         /* So desc[18] is changed from 0x22530000u to 0x22510000u*/
1103         descriptor[18] = 0x22510000u;
1104         descriptor[13] |= 2u; /* ICV_TEST */
1105     }
1106     else
1107     {
1108         /* decrypt with tag NULL (skip tag processing). nothing needs to be changed in descriptor[13] for this case */
1109     }
1110 
1111     /* AAD address and size */
1112     /* encoding is two octets, msbyte first */
1113     if (aadSize != 0U)
1114     {
1115         uint32_t swapped = swap_bytes(aadSize);
1116         uint32_t sz;
1117         (void)caam_memcpy(&descriptor[15], (uint32_t *)(uintptr_t)(((uint8_t *)&swapped) + sizeof(uint16_t)),
1118                           sizeof(uint16_t));
1119         sz = aadSize > 2u ? 2u : aadSize;                             /* limit aad to the end of 16 bytes blk */
1120         (void)caam_memcpy(((uint8_t *)&descriptor[15]) + 2, aad, sz); /* fill B1 with aad */
1121         /* track consumed AAD. sz bytes have been moved to fifo. */
1122         aadSize -= sz;
1123         aad += sz;
1124 
1125         if (aadSize == 0U)
1126         {
1127             /* in case aadSize is 1 or 2, we add Flush bit to the command and skip FIFO LOAD AAD */
1128             descriptor[14] |= 0x00010000U; /* Flush (last AAD data) */
1129             descriptor[16] = DESC_JUMP_2;  /* jump to current index + 2 (=18) */
1130         }
1131         else
1132         {
1133             descriptor[16] |= (aadSize & DESC_PAYLOAD_SIZE_MASK);
1134             descriptor[17] = ADD_OFFSET((uint32_t)aad);
1135         }
1136     }
1137     else
1138     {
1139         /* no AAD, jump directly to message */
1140         descriptor[14] = DESC_JUMP_4; /* jump to current index + 4 (=18) */
1141     }
1142 
1143     /* Message source address and size */
1144     descriptor[19] = ADD_OFFSET((uint32_t)input);
1145     descriptor[20] = size;
1146 
1147     /* Message destination address and size */
1148     descriptor[22] = ADD_OFFSET((uint32_t)output);
1149     descriptor[23] = size;
1150 
1151     if (tag != 0U)
1152     {
1153         /* For decryption change the command to FIFO LOAD, as tag data needs to be put into input FIFO */
1154         if (encrypt == 0)
1155         {
1156             /* FIFO LOAD ICV */
1157             descriptor[24] = 0x223B0000u;
1158         }
1159         descriptor[24] |= (tagSize & DESC_TAG_SIZE_MASK);
1160         descriptor[25] = ADD_OFFSET((uint32_t)tag);
1161     }
1162     else
1163     {
1164         /* tag is NULL, skip tag processing */
1165         descriptor[24] = DESC_HALT; /* always halt with status 0x0 (normal) */
1166     }
1167 
1168     /* add operation specified by descriptor to CAAM Job Ring */
1169     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
1170 }
1171 
1172 /*!
1173  * brief Encrypts AES and tags using CCM block mode.
1174  *
1175  * Puts AES CCM encrypt and tag descriptor to CAAM input job ring.
1176  *
1177  * param base CAAM peripheral base address
1178  * param handle Handle used for this request. Specifies jobRing.
1179  * param[out] descriptor Memory for the CAAM descriptor.
1180  * param plaintext Input plain text to encrypt
1181  * param[out] ciphertext Output cipher text.
1182  * param size Size of input and output data in bytes. Zero means authentication only.
1183  * param iv Nonce
1184  * param ivSize Length of the Nonce in bytes. Must be 7, 8, 9, 10, 11, 12, or 13.
1185  * param aad Input additional authentication data. Can be NULL if aadSize is zero.
1186  * param aadSize Input size in bytes of AAD. Zero means data mode only (authentication skipped).
1187  * param key Input key to use for encryption
1188  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
1189  * param[out] tag Generated output tag. Set to NULL to skip tag processing.
1190  * param tagSize Input size of the tag to generate, in bytes. Must be 4, 6, 8, 10, 12, 14, or 16.
1191  * return Status from job descriptor push
1192  */
CAAM_AES_EncryptTagCcmNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_aes_ccm_t descriptor,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t * iv,size_t ivSize,const uint8_t * aad,size_t aadSize,const uint8_t * key,size_t keySize,uint8_t * tag,size_t tagSize)1193 status_t CAAM_AES_EncryptTagCcmNonBlocking(CAAM_Type *base,
1194                                            caam_handle_t *handle,
1195                                            caam_desc_aes_ccm_t descriptor,
1196                                            const uint8_t *plaintext,
1197                                            uint8_t *ciphertext,
1198                                            size_t size,
1199                                            const uint8_t *iv,
1200                                            size_t ivSize,
1201                                            const uint8_t *aad,
1202                                            size_t aadSize,
1203                                            const uint8_t *key,
1204                                            size_t keySize,
1205                                            uint8_t *tag,
1206                                            size_t tagSize)
1207 {
1208     return caam_aes_ccm_non_blocking(base, handle, descriptor, plaintext, ciphertext, size, iv, ivSize, aad, aadSize,
1209                                      key, keySize, (uint32_t)tag, tagSize, 1);
1210 }
1211 
1212 /*!
1213  * brief Decrypts AES and authenticates using CCM block mode.
1214  *
1215  * Puts AES CCM decrypt and check tag descriptor to CAAM input job ring.
1216  *
1217  * param base CAAM peripheral base address
1218  * param handle Handle used for this request. Specifies jobRing.
1219  * param[out] descriptor Memory for the CAAM descriptor.
1220  * param ciphertext Input cipher text to decrypt
1221  * param[out] plaintext Output plain text.
1222  * param size Size of input and output data in bytes. Zero means authentication data only.
1223  * param iv Nonce
1224  * param ivSize Length of the Nonce in bytes. Must be 7, 8, 9, 10, 11, 12, or 13.
1225  * param aad Input additional authentication data. Can be NULL if aadSize is zero.
1226  * param aadSize Input size in bytes of AAD. Zero means data mode only (authentication data skipped).
1227  * param key Input key to use for decryption
1228  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
1229  * param tag Received tag. Set to NULL to skip tag processing.
1230  * param tagSize Input size of the received tag to compare with the computed tag, in bytes. Must be 4, 6, 8, 10, 12,
1231  *                14, or 16.
1232  * return Status from job descriptor push
1233  */
1234 
CAAM_AES_DecryptTagCcmNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_aes_ccm_t descriptor,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t * iv,size_t ivSize,const uint8_t * aad,size_t aadSize,const uint8_t * key,size_t keySize,const uint8_t * tag,size_t tagSize)1235 status_t CAAM_AES_DecryptTagCcmNonBlocking(CAAM_Type *base,
1236                                            caam_handle_t *handle,
1237                                            caam_desc_aes_ccm_t descriptor,
1238                                            const uint8_t *ciphertext,
1239                                            uint8_t *plaintext,
1240                                            size_t size,
1241                                            const uint8_t *iv,
1242                                            size_t ivSize,
1243                                            const uint8_t *aad,
1244                                            size_t aadSize,
1245                                            const uint8_t *key,
1246                                            size_t keySize,
1247                                            const uint8_t *tag,
1248                                            size_t tagSize)
1249 {
1250     return caam_aes_ccm_non_blocking(base, handle, descriptor, ciphertext, plaintext, size, iv, ivSize, aad, aadSize,
1251                                      key, keySize, (uint32_t)tag, tagSize, 0);
1252 }
1253 
1254 static const uint32_t templateAesCtr[] = {
1255     /* 00 */ 0xB0800000u, /* HEADER */
1256     /* 01 */ 0x02000000u, /* KEY */
1257     /* 02 */ 0x00000000u, /* place: key address */
1258     /* 03 */ 0x12201010u, /* LOAD 16 bytes of CTR0 to Class 1 Context Register. Offset 16 bytes. */
1259     /* 04 */ 0x00000000u, /* place: CTR0 address */
1260 
1261     /* 05 */ 0x82100000u, /* OPERATION: AES CTR (de)crypt in Update mode */
1262     /* 06 */ 0x22530000u, /* FIFO LOAD Message */
1263     /* 07 */ 0x00000000u, /* place: source address */
1264     /* 08 */ 0x00000000u, /* place: source size */
1265     /* 09 */ 0x60700000u, /* FIFO STORE Message */
1266     /* 10 */ 0x00000000u, /* place: destination address */
1267     /* 11 */ 0x00000000u, /* place: destination size */
1268 
1269     /* 12 */ 0xA2000001u, /* JMP always to next command. Done checkpoint (wait for Class 1 Done) */
1270     /* 13 */ 0x10880004u, /* LOAD Immediate to Clear Written Register. */
1271     /* 14 */ 0x08000004u, /* value for Clear Written Register: C1D and C1DS bits are set */
1272     /* 15 */ 0x22930010u, /* FIFO LOAD Message Immediate 16 bytes */
1273     /* 16 */ 0x00000000u, /* all zeroes 0-3 */
1274 
1275     /* 17 */ 0x00000000u, /* all zeroes 4-7 */
1276     /* 18 */ 0x00000000u, /* all zeroes 8-11 */
1277     /* 19 */ 0x00000000u, /* all zeroes 12-15 */
1278     /* 20 */ 0x60300010u, /* FIFO STORE Message 16 bytes */
1279     /* 21 */ 0x00000000u, /* place: counterlast[] block address */
1280 
1281     /* 22 */ 0x82100000u, /* OPERATION: AES CTR (de)crypt in Update mode */
1282     /* 23 */ 0x52201010u, /* STORE 16 bytes of CTRi from Class 1 Context Register offset 16 bytes. */
1283     /* 24 */ 0x00000000u, /* place: CTRi address */
1284 };
1285 
1286 /*!
1287  * brief Encrypts or decrypts AES using CTR block mode.
1288  *
1289  * Encrypts or decrypts AES using CTR block mode.
1290  * AES CTR mode uses only forward AES cipher and same algorithm for encryption and decryption.
1291  * The only difference between encryption and decryption is that, for encryption, the input argument
1292  * is plain text and the output argument is cipher text. For decryption, the input argument is cipher text
1293  * and the output argument is plain text.
1294  *
1295  * Puts AES CTR crypt descriptor to CAAM input job ring.
1296  *
1297  * param base CAAM peripheral base address
1298  * param handle Handle used for this request. Specifies jobRing.
1299  * param[out] descriptor Memory for the CAAM descriptor.
1300  * param input Input data for CTR block mode
1301  * param[out] output Output data for CTR block mode
1302  * param size Size of input and output data in bytes
1303  * param[in,out] counter Input counter (updates on return)
1304  * param key Input key to use for forward AES cipher
1305  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
1306  * param[out] counterlast Output cipher of last counter, for chained CTR calls. NULL can be passed if chained calls are
1307  * not used.
1308  * param[out] szLeft Output number of bytes in left unused in counterlast block. NULL can be passed if chained calls
1309  * are not used.
1310  * return Status from job descriptor push
1311  */
CAAM_AES_CryptCtrNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_aes_ctr_t descriptor,const uint8_t * input,uint8_t * output,size_t size,uint8_t * counter,const uint8_t * key,size_t keySize,uint8_t * counterlast,size_t * szLeft)1312 status_t CAAM_AES_CryptCtrNonBlocking(CAAM_Type *base,
1313                                       caam_handle_t *handle,
1314                                       caam_desc_aes_ctr_t descriptor,
1315                                       const uint8_t *input,
1316                                       uint8_t *output,
1317                                       size_t size,
1318                                       uint8_t *counter,
1319                                       const uint8_t *key,
1320                                       size_t keySize,
1321                                       uint8_t *counterlast,
1322                                       size_t *szLeft)
1323 {
1324     BUILD_ASSURE(sizeof(templateAesCtr) <= sizeof(caam_desc_aes_ctr_t), caam_desc_aes_ctr_t_size);
1325     uint32_t descriptorSize;
1326 
1327     if (!caam_check_key_size(keySize))
1328     {
1329         return kStatus_InvalidArgument;
1330     }
1331 
1332     /* get template descriptor and it's size */
1333     descriptorSize = ARRAY_SIZE(templateAesCtr);
1334     (void)caam_memcpy(descriptor, templateAesCtr, sizeof(templateAesCtr));
1335 
1336     /* add descriptor size */
1337     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
1338 
1339     /* key address and key size */
1340     descriptor[1] |= (keySize & DESC_KEY_SIZE_MASK);
1341     descriptor[2] = ADD_OFFSET((uint32_t)key);
1342 
1343     /* descriptor[3] configures 16 bytes length for CTR0 in templateAesCtr */
1344     descriptor[4] = ADD_OFFSET((uint32_t)counter);
1345 
1346     /* source address and size */
1347     descriptor[7] = ADD_OFFSET((uint32_t)input);
1348     descriptor[8] = size;
1349 
1350     /* destination address and size */
1351     descriptor[10] = ADD_OFFSET((uint32_t)output);
1352     descriptor[11] = size;
1353 
1354     /* AES CTR Crypt OPERATION in descriptor[5]
1355      * Algorithm State (AS) in template is Update (0h)
1356      * Only in case we are chaining the AES CTR calls (counterlast[] != NULL),
1357      * we have to change the algorithm state to Finalize (2h)
1358      * and so the CTRi for the last message block is not written to Class 1 Context.
1359      * This allows us to repeat AES CTR of the last CTRi, with destination to counterlast[],
1360      * and with using all zeroes in message data, the counterlast[] gets ECB of the last CTRi.
1361      */
1362 
1363     /* if counterlast or szLeft is NULL, the caller is not interested in AES of last counter
1364      * Thus, we can skip the counterlast processing
1365      * and only read the last CTRi from context.
1366      * So, we replace descriptor[11] with a jump command to STORE
1367      */
1368     if ((counterlast == NULL) || (szLeft == NULL))
1369     {
1370         /*  To create an unconditional jump, use TEST TYPE = 00 (all specified conditions true) and
1371             clear all TEST CONDITION bits because the tested condition is considered to be true if
1372             no test condition bits are set. */
1373         descriptor[12] = 0xA000000Bu; /* jump to current index + 11 (=23) */
1374     }
1375     else
1376     {
1377         uint32_t lastSize;
1378 
1379         descriptor[5] |= 0x08u; /* finalize */
1380         descriptor[21] = ADD_OFFSET((uint32_t)counterlast);
1381 
1382         lastSize = size % 16u;
1383         if (lastSize != 0U)
1384         {
1385             *szLeft = 16u - lastSize;
1386         }
1387         else
1388         {
1389             *szLeft = 0;
1390             /* descriptor[12] = 0xA000000Bu; */ /* jump to current index + 11 (=23) */
1391         }
1392     }
1393 
1394     /* read last CTRi from AES back to caller */
1395     descriptor[24] = ADD_OFFSET((uint32_t)counter);
1396 
1397     /* add operation specified by descriptor to CAAM Job Ring */
1398     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
1399 }
1400 
1401 static const uint32_t templateAesEcb[] = {
1402     /* 00 */ 0xB0800000u, /* HEADER */
1403     /* 01 */ 0x02000000u, /* KEY */
1404     /* 02 */ 0x00000000u, /* place: key address */
1405     /* 03 */ 0x22530000u, /* FIFO LOAD Message with EXT size */
1406     /* 04 */ 0x00000000u, /* place: source address */
1407     /* 05 */ 0x00000000u, /* place: source size */
1408     /* 06 */ 0x60700000u, /* FIFO STORE Message with EXT size */
1409     /* 07 */ 0x00000000u, /* place: destination address */
1410     /* 08 */ 0x00000000u, /* place: destination size */
1411     /* 09 */ 0x82100200u, /* OPERATION: AES ECB Decrypt */
1412 };
1413 
1414 /*!
1415  * brief Encrypts AES using the ECB block mode.
1416  *
1417  * Puts AES ECB encrypt descriptor to CAAM input job ring.
1418  *
1419  * param base CAAM peripheral base address
1420  * param plaintext Input plain text to encrypt
1421  * param[out] descriptor Memory for the CAAM descriptor.
1422  * param[out] ciphertext Output cipher text
1423  * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
1424  * param key Input key to use for encryption
1425  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
1426  * return Status from job descriptor push
1427  */
CAAM_AES_EncryptEcbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_aes_ecb_t descriptor,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t * key,size_t keySize)1428 status_t CAAM_AES_EncryptEcbNonBlocking(CAAM_Type *base,
1429                                         caam_handle_t *handle,
1430                                         caam_desc_aes_ecb_t descriptor,
1431                                         const uint8_t *plaintext,
1432                                         uint8_t *ciphertext,
1433                                         size_t size,
1434                                         const uint8_t *key,
1435                                         size_t keySize)
1436 {
1437     BUILD_ASSURE(sizeof(templateAesEcb) <= sizeof(caam_desc_aes_ecb_t), caam_desc_aes_ecb_t_size);
1438     uint32_t descriptorSize;
1439 
1440     if (!caam_check_key_size(keySize))
1441     {
1442         return kStatus_InvalidArgument;
1443     }
1444     /* ECB mode, size must be non-zero 16-byte multiple */
1445     if (0U != (size % 16u))
1446     {
1447         return kStatus_InvalidArgument;
1448     }
1449 
1450     descriptorSize = ARRAY_SIZE(templateAesEcb);
1451     (void)caam_memcpy(descriptor, templateAesEcb, sizeof(templateAesEcb));
1452     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
1453     descriptor[1] |= (keySize & DESC_KEY_SIZE_MASK);
1454     descriptor[2] = (uint32_t)ADD_OFFSET((uint32_t)key);
1455     /* descriptor[3] FIFO LOAD copied from template */
1456     descriptor[4] = (uint32_t)ADD_OFFSET((uint32_t)plaintext);
1457     descriptor[5] = size; /* FIFO LOAD EXT size */
1458                           /* descriptor[6] FIFO STORE copied from template */
1459     descriptor[7] = (uint32_t)ADD_OFFSET((uint32_t)ciphertext);
1460     descriptor[8] = size; /* FIFO STORE EXT size */
1461     descriptor[9] |= 1u;  /* add ENC bit to specify Encrypt OPERATION */
1462 
1463     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
1464 }
1465 
1466 /*!
1467  * brief Decrypts AES using ECB block mode.
1468  *
1469  * Puts AES ECB decrypt descriptor to CAAM input job ring.
1470  *
1471  * param base CAAM peripheral base address
1472  * param handle Handle used for this request. Specifies jobRing.
1473  * param[out] descriptor Memory for the CAAM descriptor.
1474  * param ciphertext Input cipher text to decrypt
1475  * param[out] plaintext Output plain text
1476  * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
1477  * param key Input key.
1478  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
1479  * return Status from job descriptor push
1480  */
CAAM_AES_DecryptEcbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_aes_ecb_t descriptor,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t * key,size_t keySize)1481 status_t CAAM_AES_DecryptEcbNonBlocking(CAAM_Type *base,
1482                                         caam_handle_t *handle,
1483                                         caam_desc_aes_ecb_t descriptor,
1484                                         const uint8_t *ciphertext,
1485                                         uint8_t *plaintext,
1486                                         size_t size,
1487                                         const uint8_t *key,
1488                                         size_t keySize)
1489 {
1490     uint32_t descriptorSize;
1491 
1492     if (!caam_check_key_size(keySize))
1493     {
1494         return kStatus_InvalidArgument;
1495     }
1496     /* ECB mode, size must be non-zero 16-byte multiple */
1497     if (0U != (size % 16u))
1498     {
1499         return kStatus_InvalidArgument;
1500     }
1501 
1502     descriptorSize = ARRAY_SIZE(templateAesEcb);
1503     (void)caam_memcpy(descriptor, templateAesEcb, sizeof(templateAesEcb));
1504     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
1505     descriptor[1] |= (keySize & DESC_KEY_SIZE_MASK);
1506     descriptor[2] = (uint32_t)ADD_OFFSET((uint32_t)key);
1507     /* descriptor[3] FIFO LOAD copied from template */
1508     descriptor[4] = (uint32_t)ADD_OFFSET((uint32_t)ciphertext);
1509     descriptor[5] = size;
1510     /* descriptor[6] FIFO STORE copied from template */
1511     descriptor[7] = (uint32_t)ADD_OFFSET((uint32_t)plaintext);
1512     descriptor[8] = size; /* FIFO STORE EXT size */
1513 
1514     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
1515 }
1516 
1517 static const uint32_t templateAesCbc[] = {
1518     /* 00 */ 0xB0800000u, /* HEADER */
1519     /* 01 */ 0x02000000u, /* KEY */
1520     /* 02 */ 0x00000000u, /* place: key address */
1521     /* 03 */ 0x12200010u, /* LOAD 16 bytes of iv to Class 1 Context Register */
1522     /* 04 */ 0x00000000u, /* place: iv address */
1523     /* 05 */ 0x22530000u, /* FIFO LOAD Message */
1524     /* 06 */ 0x00000000u, /* place: source address */
1525     /* 07 */ 0x00000000u, /* place: source size */
1526     /* 08 */ 0x60700000u, /* FIFO STORE Message */
1527     /* 09 */ 0x00000000u, /* place: destination address */
1528     /* 10 */ 0x00000000u, /* place: destination size */
1529     /* 11 */ 0x82100100u, /* OPERATION: AES CBC Decrypt */
1530 };
1531 
1532 /*!
1533  * brief Encrypts AES using CBC block mode.
1534  *
1535  * Puts AES CBC encrypt descriptor to CAAM input job ring.
1536  *
1537  * param base CAAM peripheral base address
1538  * param handle Handle used for this request. Specifies jobRing.
1539  * param[out] descriptor Memory for the CAAM descriptor.
1540  * param plaintext Input plain text to encrypt
1541  * param[out] ciphertext Output cipher text
1542  * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
1543  * param iv Input initial vector to combine with the first input block.
1544  * param key Input key to use for encryption
1545  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
1546  * return Status from job descriptor push
1547  */
CAAM_AES_EncryptCbcNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_aes_cbc_t descriptor,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t * iv,const uint8_t * key,size_t keySize)1548 status_t CAAM_AES_EncryptCbcNonBlocking(CAAM_Type *base,
1549                                         caam_handle_t *handle,
1550                                         caam_desc_aes_cbc_t descriptor,
1551                                         const uint8_t *plaintext,
1552                                         uint8_t *ciphertext,
1553                                         size_t size,
1554                                         const uint8_t *iv,
1555                                         const uint8_t *key,
1556                                         size_t keySize)
1557 {
1558     BUILD_ASSURE(sizeof(templateAesCbc) <= sizeof(caam_desc_aes_cbc_t), caam_desc_aes_cbc_t_size);
1559     uint32_t descriptorSize;
1560 
1561     if (!caam_check_key_size(keySize))
1562     {
1563         return kStatus_InvalidArgument;
1564     }
1565 
1566     /* CBC mode, size must be non-zero 16-byte multiple */
1567     if (0U != (size % 16u))
1568     {
1569         return kStatus_InvalidArgument;
1570     }
1571 
1572     /* get template descriptor and it's size */
1573     descriptorSize = ARRAY_SIZE(templateAesCbc);
1574     (void)caam_memcpy(descriptor, templateAesCbc, sizeof(templateAesCbc));
1575 
1576     /* add descriptor size */
1577     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
1578 
1579     /* key address and key size */
1580     descriptor[1] |= (keySize & DESC_KEY_SIZE_MASK);
1581     descriptor[2] = (uint32_t)ADD_OFFSET((uint32_t)key);
1582 
1583     /* descriptor[3] configures 16 bytes length for IV in templateAesCbc */
1584     descriptor[4] = (uint32_t)ADD_OFFSET((uint32_t)iv);
1585 
1586     /* source address and size */
1587     descriptor[6] = (uint32_t)ADD_OFFSET((uint32_t)plaintext);
1588     descriptor[7] = size;
1589 
1590     /* destination address and size */
1591     descriptor[9]  = (uint32_t)ADD_OFFSET((uint32_t)ciphertext);
1592     descriptor[10] = size;
1593 
1594     /* AES CBC */
1595     descriptor[11] |= 1u; /* add ENC bit to specify Encrypt OPERATION */
1596 
1597     /* add operation specified by descriptor to CAAM Job Ring */
1598     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
1599 }
1600 
1601 /*!
1602  * brief Decrypts AES using CBC block mode.
1603  *
1604  * Puts AES CBC decrypt descriptor to CAAM input job ring.
1605  *
1606  * param base CAAM peripheral base address
1607  * param handle Handle used for this request. Specifies jobRing.
1608  * param[out] descriptor Memory for the CAAM descriptor.
1609  * param ciphertext Input cipher text to decrypt
1610  * param[out] plaintext Output plain text
1611  * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
1612  * param iv Input initial vector to combine with the first input block.
1613  * param key Input key to use for decryption
1614  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
1615  * return Status from job descriptor push
1616  */
CAAM_AES_DecryptCbcNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_aes_cbc_t descriptor,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t * iv,const uint8_t * key,size_t keySize)1617 status_t CAAM_AES_DecryptCbcNonBlocking(CAAM_Type *base,
1618                                         caam_handle_t *handle,
1619                                         caam_desc_aes_cbc_t descriptor,
1620                                         const uint8_t *ciphertext,
1621                                         uint8_t *plaintext,
1622                                         size_t size,
1623                                         const uint8_t *iv,
1624                                         const uint8_t *key,
1625                                         size_t keySize)
1626 {
1627     uint32_t descriptorSize;
1628 
1629     if (!caam_check_key_size(keySize))
1630     {
1631         return kStatus_InvalidArgument;
1632     }
1633 
1634     /* CBC mode, size must be non-zero 16-byte multiple */
1635     if (0U != (size % 16u))
1636     {
1637         return kStatus_InvalidArgument;
1638     }
1639 
1640     /* get template descriptor and it's size */
1641     descriptorSize = ARRAY_SIZE(templateAesCbc);
1642     (void)caam_memcpy(descriptor, templateAesCbc, sizeof(templateAesCbc));
1643 
1644     /* add descriptor size */
1645     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
1646 
1647     /* key address and key size */
1648     descriptor[1] |= (keySize & DESC_KEY_SIZE_MASK);
1649     descriptor[2] = ADD_OFFSET((uint32_t)key);
1650 
1651     /* descriptor[3] configures 16 bytes length for IV in templateAesCbc */
1652     descriptor[4] = ADD_OFFSET((uint32_t)iv);
1653 
1654     /* source address and size */
1655     descriptor[6] = ADD_OFFSET((uint32_t)ciphertext);
1656     descriptor[7] = size;
1657 
1658     /* destination address and size */
1659     descriptor[9]  = ADD_OFFSET((uint32_t)plaintext);
1660     descriptor[10] = size;
1661 
1662     /* AES CBC Decrypt OPERATION in descriptor[11] */
1663 
1664     /* add operation specified by descriptor to CAAM Job Ring */
1665     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
1666 }
1667 
1668 /*!
1669  * brief Encrypts AES and tags using GCM block mode.
1670  *
1671  * Encrypts AES and optionally tags using GCM block mode. If plaintext is NULL, only the GHASH is calculated and output
1672  * in the 'tag' field.
1673  * Puts AES GCM encrypt and tag descriptor to CAAM input job ring.
1674  *
1675  * param base CAAM peripheral base address
1676  * param handle Handle used for this request. Specifies jobRing.
1677  * param[out] descriptor Memory for the CAAM descriptor.
1678  * param plaintext Input plain text to encrypt
1679  * param[out] ciphertext Output cipher text.
1680  * param size Size of input and output data in bytes
1681  * param iv Input initial vector
1682  * param ivSize Size of the IV
1683  * param aad Input additional authentication data
1684  * param aadSize Input size in bytes of AAD
1685  * param key Input key to use for encryption
1686  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
1687  * param[out] tag Output hash tag. Set to NULL to skip tag processing.
1688  * param tagSize Input size of the tag to generate, in bytes. Must be 4,8,12,13,14,15 or 16.
1689  * return Status from job descriptor push
1690  */
CAAM_AES_EncryptTagGcmNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_aes_gcm_t descriptor,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t * iv,size_t ivSize,const uint8_t * aad,size_t aadSize,const uint8_t * key,size_t keySize,uint8_t * tag,size_t tagSize)1691 status_t CAAM_AES_EncryptTagGcmNonBlocking(CAAM_Type *base,
1692                                            caam_handle_t *handle,
1693                                            caam_desc_aes_gcm_t descriptor,
1694                                            const uint8_t *plaintext,
1695                                            uint8_t *ciphertext,
1696                                            size_t size,
1697                                            const uint8_t *iv,
1698                                            size_t ivSize,
1699                                            const uint8_t *aad,
1700                                            size_t aadSize,
1701                                            const uint8_t *key,
1702                                            size_t keySize,
1703                                            uint8_t *tag,
1704                                            size_t tagSize)
1705 {
1706     return caam_aes_gcm_non_blocking(base, handle, descriptor, plaintext, ciphertext, size, iv, ivSize, aad, aadSize,
1707                                      key, keySize, (uint32_t)tag, tagSize, 1);
1708 }
1709 
1710 /*!
1711  * brief Decrypts AES and authenticates using GCM block mode.
1712  *
1713  * Decrypts AES and optionally authenticates using GCM block mode. If ciphertext is NULL, only the GHASH is calculated
1714  * and compared with the received GHASH in 'tag' field.
1715  * Puts AES GCM decrypt and check tag descriptor to CAAM input job ring.
1716  *
1717  * param base CAAM peripheral base address
1718  * param handle Handle used for this request. Specifies jobRing.
1719  * param[out] descriptor Memory for the CAAM descriptor.
1720  * param ciphertext Input cipher text to decrypt
1721  * param[out] plaintext Output plain text.
1722  * param size Size of input and output data in bytes
1723  * param iv Input initial vector
1724  * param ivSize Size of the IV
1725  * param aad Input additional authentication data
1726  * param aadSize Input size in bytes of AAD
1727  * param key Input key to use for encryption
1728  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
1729  * param tag Input hash tag to compare. Set to NULL to skip tag processing.
1730  * param tagSize Input size of the tag, in bytes. Must be 4, 8, 12, 13, 14, 15, or 16.
1731  * return Status from job descriptor push
1732  */
CAAM_AES_DecryptTagGcmNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_aes_gcm_t descriptor,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t * iv,size_t ivSize,const uint8_t * aad,size_t aadSize,const uint8_t * key,size_t keySize,const uint8_t * tag,size_t tagSize)1733 status_t CAAM_AES_DecryptTagGcmNonBlocking(CAAM_Type *base,
1734                                            caam_handle_t *handle,
1735                                            caam_desc_aes_gcm_t descriptor,
1736                                            const uint8_t *ciphertext,
1737                                            uint8_t *plaintext,
1738                                            size_t size,
1739                                            const uint8_t *iv,
1740                                            size_t ivSize,
1741                                            const uint8_t *aad,
1742                                            size_t aadSize,
1743                                            const uint8_t *key,
1744                                            size_t keySize,
1745                                            const uint8_t *tag,
1746                                            size_t tagSize)
1747 {
1748     return caam_aes_gcm_non_blocking(base, handle, descriptor, ciphertext, plaintext, size, iv, ivSize, aad, aadSize,
1749                                      key, keySize, (uint32_t)tag, tagSize, 0);
1750 }
1751 
1752 /*!
1753  * brief Gets the default configuration structure.
1754  *
1755  * This function initializes the CAAM configuration structure to a default value. The default
1756  * values are as follows.
1757  *   caamConfig->rngSampleMode = kCAAM_RNG_SampleModeVonNeumann;
1758  *   caamConfig->rngRingOscDiv = kCAAM_RNG_RingOscDiv4;
1759  *
1760  * param[out] config Pointer to configuration structure.
1761  */
CAAM_GetDefaultConfig(caam_config_t * config)1762 void CAAM_GetDefaultConfig(caam_config_t *config)
1763 {
1764     /* Initializes the configure structure to zero. */
1765     (void)memset(config, 0, sizeof(*config));
1766 
1767     caam_config_t userConfig = {
1768         {NULL, NULL, NULL, NULL},   kCAAM_RNG_SampleModeVonNeumann, kCAAM_RNG_RingOscDiv4, true, true, true, true,
1769         kCAAM_NormalOperationBlobs,
1770     };
1771 
1772     *config = userConfig;
1773 }
1774 
1775 /*!
1776  * brief Initializes the CAAM driver.
1777  *
1778  * This function initializes the CAAM driver, including CAAM's internal RNG.
1779  * param base CAAM peripheral base address
1780  * param config Pointer to configuration structure.
1781  * return kStatus_Success the CAAM Init has completed with zero termination status word
1782  * return kStatus_Fail the CAAM Init has completed with non-zero termination status word
1783  */
CAAM_Init(CAAM_Type * base,const caam_config_t * config)1784 status_t CAAM_Init(CAAM_Type *base, const caam_config_t *config)
1785 {
1786 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
1787     CLOCK_EnableClock(kCLOCK_Caam);
1788 #endif
1789     status_t status = kStatus_Fail;
1790 
1791     base->MCFGR = 0x80000000u; /* reset */
1792     base->MCFGR = 0x90000000u; /* reset DMA */
1793     base->MCFGR = 0x00082300u; /* (reset value) */
1794 
1795     /* job ring interface 0 is mandatory */
1796     assert(config->jobRingInterface[0]);
1797     if (NULL == config->jobRingInterface[0])
1798     {
1799         return kStatus_Fail; /* return if user wishes to use the job ring but does not configure it. */
1800     }
1801 
1802     /* Job Rings Configuration
1803      * number of entries in both input and output ring is equal.
1804      * Note the size of an entry is different. an entry in the input ring is a 32-bit word.
1805      * an entry in the output ring is two 32-bit words. (descriptor pointer followed by termination status word)
1806      */
1807     s_jr0 = config->jobRingInterface[0];
1808     (void)memset(s_jr0, 0, sizeof(*s_jr0));
1809     s_jrIndex0 = 0;
1810     caam_job_ring_set_base_address_and_size(base, kCAAM_JobRing0, s_jr0->inputJobRing, ARRAY_SIZE(s_jr0->inputJobRing),
1811                                             s_jr0->outputJobRing, ARRAY_SIZE(s_jr0->outputJobRing) / 2U);
1812 
1813     if (config->jobRingInterface[1] != NULL)
1814     {
1815         s_jr1 = config->jobRingInterface[1];
1816         (void)memset(s_jr1, 0, sizeof(*s_jr1));
1817         s_jrIndex1 = 0;
1818         caam_job_ring_set_base_address_and_size(base, kCAAM_JobRing1, s_jr1->inputJobRing,
1819                                                 ARRAY_SIZE(s_jr1->inputJobRing), s_jr1->outputJobRing,
1820                                                 ARRAY_SIZE(s_jr1->outputJobRing) / 2U);
1821     }
1822 
1823     if (config->jobRingInterface[2] != NULL)
1824     {
1825         s_jr2 = config->jobRingInterface[2];
1826         (void)memset(s_jr2, 0, sizeof(*s_jr2));
1827         s_jrIndex2 = 0;
1828         caam_job_ring_set_base_address_and_size(base, kCAAM_JobRing2, s_jr2->inputJobRing,
1829                                                 ARRAY_SIZE(s_jr2->inputJobRing), s_jr2->outputJobRing,
1830                                                 ARRAY_SIZE(s_jr2->outputJobRing) / 2U);
1831     }
1832 
1833     if (config->jobRingInterface[3] != NULL)
1834     {
1835         s_jr3 = config->jobRingInterface[3];
1836         (void)memset(s_jr3, 0, sizeof(*s_jr3));
1837         s_jrIndex3 = 0;
1838         caam_job_ring_set_base_address_and_size(base, kCAAM_JobRing3, s_jr3->inputJobRing,
1839                                                 ARRAY_SIZE(s_jr3->inputJobRing), s_jr3->outputJobRing,
1840                                                 ARRAY_SIZE(s_jr3->outputJobRing) / 2U);
1841     }
1842 
1843     /*
1844      * Instantiate RNG in normal (non-deterministic) mode and load the JDKEK, TDKEK and TDSK registers
1845      * this step is required for example
1846      * for FIFO STORE command to be able to store Key register as Black key
1847      * for example during AES XCBC-MAC context switch (need to store derived key K1 to memory)
1848      */
1849     (void)CAAM_RNG_GetDefaultConfig(&rngConfig);
1850 
1851     /* reset RNG */
1852     base->RTMCTL = CAAM_RTMCTL_PRGM_MASK | CAAM_RTMCTL_ERR_MASK | CAAM_RTMCTL_RST_DEF_MASK |
1853                    CAAM_RTMCTL_SAMP_MODE(kCAAM_RNG_SampleModeRaw);
1854     base->RTMCTL = CAAM_RTMCTL_ERR_MASK | CAAM_RTMCTL_SAMP_MODE(config->rngSampleMode) |
1855                    CAAM_RTMCTL_OSC_DIV(config->rngRingOscDiv);
1856 
1857     caam_handle_t handle;
1858     handle.jobRing = kCAAM_JobRing0;
1859 
1860     /* Check if Instantiated State Handle 0 or 1 has been instantiated */
1861     if ((base->RDSTA & (CAAM_RDSTA_IF0_MASK | CAAM_RDSTA_IF1_MASK)) == 0U)
1862     {
1863         status = CAAM_RNG_Init(base, &handle, kCAAM_RngStateHandle0, &rngConfig);
1864         if (status != kStatus_Success)
1865         {
1866             return status;
1867         }
1868     }
1869     else
1870     {
1871         status = kStatus_Success;
1872     }
1873 
1874     /* Check if JDKEK, TDKEK and TDSK are already generated, generate if not */
1875     /* Note: second secure keys generate per one PoR will generate Secure Key error */
1876     if ((base->JDKEKR[0U] == 0U) && (base->TDKEKR[0U] == 0U) && (base->TDSKR[0U] == 0U))
1877     {
1878         /* Note: Secure key is cleared only during POR reset */
1879         status = CAAM_RNG_GenerateSecureKey(base, &handle, NULL);
1880         if (status != kStatus_Success)
1881         {
1882             return status;
1883         }
1884     }
1885     else
1886     {
1887         status = kStatus_Success;
1888     }
1889 
1890     /* set RANDDPAR bit for the AESA to reseed its DPA mask using data from kCAAM_RngStateHandle0 */
1891     /* also set other bits to 1 for security */
1892     base->SCFGR =
1893 #if defined(FSL_FEATURE_CAAM_HAS_RANDDPAR) && (FSL_FEATURE_CAAM_HAS_RANDDPAR > 0)
1894         CAAM_SCFGR_RANDDPAR(config->scfgrRandomDpaResistance) |
1895 #endif /* FSL_FEATURE_CAAM_HAS_RANDDPAR */
1896 #if defined(FSL_FEATURE_CAAM_HAS_RDB) && (FSL_FEATURE_CAAM_HAS_RDB > 0)
1897         CAAM_SCFGR_RDB(config->scfgrEnableRandomDataBuffer) |
1898 #endif /* FSL_FEATURE_CAAM_HAS_RDB */
1899         CAAM_SCFGR_LCK_TRNG(config->scfgrLockTrngProgramMode) | CAAM_SCFGR_RNGSH0(config->scfgrRandomRngStateHandle0) |
1900         CAAM_SCFGR_PRIBLOB(config->scfgrPriblob);
1901 
1902     return status;
1903 }
1904 
1905 /*!
1906  * brief Wait for a CAAM job to complete.
1907  *
1908  * This function polls CAAM output ring for a specific job.
1909  *
1910  * The CAAM job ring is specified by the jobRing field in the caam_handle_t structure.
1911  * The job to be waited is specified by it's descriptor address.
1912  *
1913  * This function has two modes, determined by the mode argument.
1914  * In blocking mode, the function polls the specified jobRing until the descriptor
1915  * is available in the CAAM output job ring.
1916  * In non-blocking mode, it polls the output ring once and returns status
1917  * immediately.
1918  *
1919  * The function can be called from multiple threads or interrupt service routines,
1920  * as internally it uses global critical section (global interrupt disable enable)
1921  * to protect it's operation against concurrent accesses.
1922  * The global interrupt is disabled only when the descriptor is found
1923  * in the output ring, for a very short time, to remove the descriptor from the output ring
1924  * safely.
1925  *
1926  * param base CAAM peripheral base address
1927  * param handle Data structure with CAAM jobRing used for this request
1928  * param descriptor
1929  * param mode Blocking and non-blocking mode. Zero is blocking. Non-zero is non-blocking.
1930  * return kStatus_Success the CAAM job has completed with zero job termination status word
1931  * return kStatus_Fail the CAAM job has completed with non-zero job termination status word
1932  * return kStatus_Again In non-blocking mode, the job is not ready in the CAAM Output Ring
1933  */
CAAM_Wait(CAAM_Type * base,caam_handle_t * handle,uint32_t * descriptor,caam_wait_mode_t mode)1934 status_t CAAM_Wait(CAAM_Type *base, caam_handle_t *handle, uint32_t *descriptor, caam_wait_mode_t mode)
1935 {
1936     /* poll output ring for the specified job descriptor */
1937     status_t status;
1938     bool wait;
1939     bool found;
1940 
1941     wait   = true;
1942     status = kStatus_Success;
1943     found  = false;
1944 
1945     while (wait)
1946     {
1947         /* any result available on this job ring? */
1948         if ((caam_output_ring_get_slots_full(base, handle->jobRing)) != 0U)
1949         {
1950             status = caam_out_job_ring_test_and_remove(base, handle->jobRing,
1951                                                        (uint32_t *)ADD_OFFSET((uint32_t)descriptor), &wait, &found);
1952         }
1953 
1954         /* non-blocking mode polls output ring once */
1955         if (mode == kCAAM_Nonblocking)
1956         {
1957             wait = false; /* exit the while() */
1958             if (!found)
1959             {
1960                 status = kStatus_CAAM_Again; /* job not in the tested ring */
1961             }
1962         }
1963     }
1964     return status;
1965 }
1966 
1967 /*!
1968  * brief Deinitializes the CAAM driver.
1969  * This function deinitializes the CAAM driver.
1970  * param base CAAM peripheral base address
1971  * return kStatus_Success the CAAM Deinit has completed with zero termination status word
1972  * return kStatus_Fail the CAAM Deinit has completed with non-zero termination status word
1973  */
CAAM_Deinit(CAAM_Type * base)1974 status_t CAAM_Deinit(CAAM_Type *base)
1975 {
1976     caam_handle_t handle;
1977     handle.jobRing  = kCAAM_JobRing0;
1978     status_t status = kStatus_Fail;
1979     status          = CAAM_RNG_Deinit(base, &handle, kCAAM_RngStateHandle0);
1980     if (status != kStatus_Success)
1981     {
1982         return status;
1983     }
1984 
1985     base->JOBRING[0].JRCR_JR = CAAM_JRCR_JR_RESET_MASK;
1986     base->JOBRING[0].JRCR_JR = CAAM_JRCR_JR_RESET_MASK;
1987     base->JOBRING[1].JRCR_JR = CAAM_JRCR_JR_RESET_MASK;
1988     base->JOBRING[1].JRCR_JR = CAAM_JRCR_JR_RESET_MASK;
1989     base->DRR                = CAAM_DRR_RST0_MASK;
1990     base->MCFGR              = CAAM_MCFGR_SWRST_MASK;                           /* reset */
1991     base->MCFGR              = CAAM_MCFGR_SWRST_MASK | CAAM_MCFGR_DMA_RST_MASK; /* reset DMA */
1992     base->MCFGR              = 0x00082300u;                                     /* (reset value) */
1993 
1994     while (0U == (base->RTMCTL & CAAM_RTMCTL_TSTOP_OK_MASK))
1995     {
1996     }
1997 
1998     /* reset RNG */
1999     base->RTMCTL = CAAM_RTMCTL_PRGM_MASK | CAAM_RTMCTL_ERR_MASK | CAAM_RTMCTL_RST_DEF_MASK |
2000                    CAAM_RTMCTL_SAMP_MODE(kCAAM_RNG_SampleModeRaw);
2001 
2002 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
2003     CLOCK_DisableClock(kCLOCK_Caam);
2004 #endif
2005 
2006     return status;
2007 }
2008 
2009 /*!
2010  * brief External Key Transfer.
2011  *
2012  * This function loads the given key source to an CAAM external destination via a private interface,
2013  * such as Inline Encryption Engine IEE Private Key bus.
2014  *
2015  * The CAAM job ring is specified by the jobRing field in the caam_handle_t structure.
2016  *
2017  * This function is blocking.
2018  *
2019  * param base CAAM peripheral base address
2020  * param handle Data structure with CAAM jobRing used for this request.
2021  * param keySource The source from which the key will be obtained.
2022  * param keySize Size of the key in bytes.
2023  * return kStatus_Success the CAAM job has completed with zero job termination status word
2024  * return kStatus_Fail the CAAM job has completed with non-zero job termination status word
2025  */
CAAM_ExternalKeyTransfer(CAAM_Type * base,caam_handle_t * handle,caam_ext_key_xfr_source_t keySource,size_t keySize)2026 status_t CAAM_ExternalKeyTransfer(CAAM_Type *base,
2027                                   caam_handle_t *handle,
2028                                   caam_ext_key_xfr_source_t keySource,
2029                                   size_t keySize)
2030 {
2031     caam_desc_aes_ecb_t descBuf = {0};
2032     status_t status;
2033 
2034     descBuf[0] = 0xB0800002u; /* HEADER */
2035     descBuf[1] = 0x40000000u; /* EXT KEY XFR command. */
2036 
2037     switch (keySource)
2038     {
2039         case kCAAM_ExtKeyXfr_KeyRegisterClass1:
2040         case kCAAM_ExtKeyXfr_KeyRegisterClass2:
2041         case kCAAM_ExtKeyXfr_PkhaRamE:
2042             descBuf[1] |= ((uint32_t)keySource << 16) | keySize;
2043             status = kStatus_Success;
2044             break;
2045 
2046         default:
2047             status = kStatus_InvalidArgument;
2048             break;
2049     }
2050 
2051     if (status != kStatus_Success)
2052     {
2053         return status;
2054     }
2055 
2056     /* schedule the job and block wait for result */
2057     do
2058     {
2059         status = caam_in_job_ring_add(base, handle->jobRing, &descBuf[0]);
2060     } while (status != kStatus_Success);
2061 
2062     return CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
2063 }
2064 
2065 /*!
2066  * brief Encrypts AES using the ECB block mode.
2067  *
2068  * Encrypts AES using the ECB block mode.
2069  *
2070  * param base CAAM peripheral base address
2071  * param plaintext Input plain text to encrypt
2072  * param[out] ciphertext Output cipher text
2073  * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
2074  * param key Input key to use for encryption
2075  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
2076  * return Status from encrypt operation
2077  */
CAAM_AES_EncryptEcb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t * key,size_t keySize)2078 status_t CAAM_AES_EncryptEcb(CAAM_Type *base,
2079                              caam_handle_t *handle,
2080                              const uint8_t *plaintext,
2081                              uint8_t *ciphertext,
2082                              size_t size,
2083                              const uint8_t *key,
2084                              size_t keySize)
2085 {
2086     caam_desc_aes_ecb_t descBuf;
2087     status_t status;
2088 
2089     do
2090     {
2091         status = CAAM_AES_EncryptEcbNonBlocking(base, handle, descBuf, plaintext, ciphertext, size, key, keySize);
2092     } while (status == kStatus_CAAM_Again);
2093 
2094     if (status != 0)
2095     {
2096         return status;
2097     }
2098 
2099     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
2100 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
2101     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
2102     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
2103     DCACHE_InvalidateByRange((uint32_t)ciphertext, size);
2104 #endif /* CAAM_OUT_INVALIDATE */
2105     return status;
2106 }
2107 
2108 /*!
2109  * brief Decrypts AES using ECB block mode.
2110  *
2111  * Decrypts AES using ECB block mode.
2112  *
2113  * param base CAAM peripheral base address
2114  * param handle Handle used for this request. Specifies jobRing.
2115  * param ciphertext Input cipher text to decrypt
2116  * param[out] plaintext Output plain text
2117  * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
2118  * param key Input key.
2119  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
2120  * return Status from decrypt operation
2121  */
CAAM_AES_DecryptEcb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t * key,size_t keySize)2122 status_t CAAM_AES_DecryptEcb(CAAM_Type *base,
2123                              caam_handle_t *handle,
2124                              const uint8_t *ciphertext,
2125                              uint8_t *plaintext,
2126                              size_t size,
2127                              const uint8_t *key,
2128                              size_t keySize)
2129 {
2130     caam_desc_aes_ecb_t descBuf;
2131     status_t status;
2132 
2133     do
2134     {
2135         status = CAAM_AES_DecryptEcbNonBlocking(base, handle, descBuf, ciphertext, plaintext, size, key, keySize);
2136     } while (status == kStatus_CAAM_Again);
2137 
2138     if (status != 0)
2139     {
2140         return status;
2141     }
2142 
2143     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
2144 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
2145     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
2146     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
2147     DCACHE_InvalidateByRange((uint32_t)plaintext, size);
2148 #endif /* CAAM_OUT_INVALIDATE */
2149     return status;
2150 }
2151 
2152 /*!
2153  * brief Encrypts AES using CBC block mode.
2154  *
2155  * param base CAAM peripheral base address
2156  * param handle Handle used for this request. Specifies jobRing.
2157  * param plaintext Input plain text to encrypt
2158  * param[out] ciphertext Output cipher text
2159  * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
2160  * param iv Input initial vector to combine with the first input block.
2161  * param key Input key to use for encryption
2162  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
2163  * return Status from encrypt operation
2164  */
CAAM_AES_EncryptCbc(CAAM_Type * base,caam_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[16],const uint8_t * key,size_t keySize)2165 status_t CAAM_AES_EncryptCbc(CAAM_Type *base,
2166                              caam_handle_t *handle,
2167                              const uint8_t *plaintext,
2168                              uint8_t *ciphertext,
2169                              size_t size,
2170                              const uint8_t iv[16],
2171                              const uint8_t *key,
2172                              size_t keySize)
2173 {
2174     caam_desc_aes_cbc_t descBuf;
2175     status_t status;
2176 
2177     do
2178     {
2179         status = CAAM_AES_EncryptCbcNonBlocking(base, handle, descBuf, plaintext, ciphertext, size, iv, key, keySize);
2180     } while (status == kStatus_CAAM_Again);
2181 
2182     if (status != 0)
2183     {
2184         return status;
2185     }
2186 
2187     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
2188 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
2189     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
2190     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
2191     DCACHE_InvalidateByRange((uint32_t)ciphertext, size);
2192 #endif /* CAAM_OUT_INVALIDATE */
2193     return status;
2194 }
2195 
2196 /*!
2197  * brief Decrypts AES using CBC block mode.
2198  *
2199  * param base CAAM peripheral base address
2200  * param handle Handle used for this request. Specifies jobRing.
2201  * param ciphertext Input cipher text to decrypt
2202  * param[out] plaintext Output plain text
2203  * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
2204  * param iv Input initial vector to combine with the first input block.
2205  * param key Input key to use for decryption
2206  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
2207  * return Status from decrypt operation
2208  */
CAAM_AES_DecryptCbc(CAAM_Type * base,caam_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[16],const uint8_t * key,size_t keySize)2209 status_t CAAM_AES_DecryptCbc(CAAM_Type *base,
2210                              caam_handle_t *handle,
2211                              const uint8_t *ciphertext,
2212                              uint8_t *plaintext,
2213                              size_t size,
2214                              const uint8_t iv[16],
2215                              const uint8_t *key,
2216                              size_t keySize)
2217 {
2218     caam_desc_aes_cbc_t descBuf;
2219     status_t status;
2220 
2221     do
2222     {
2223         status = CAAM_AES_DecryptCbcNonBlocking(base, handle, descBuf, ciphertext, plaintext, size, iv, key, keySize);
2224     } while (status == kStatus_CAAM_Again);
2225 
2226     if (status != 0)
2227     {
2228         return status;
2229     }
2230 
2231     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
2232 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
2233     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
2234     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
2235     DCACHE_InvalidateByRange((uint32_t)plaintext, size);
2236 #endif /* CAAM_OUT_INVALIDATE */
2237     return status;
2238 }
2239 
2240 /*!
2241  * brief Encrypts or decrypts AES using CTR block mode.
2242  *
2243  * Encrypts or decrypts AES using CTR block mode.
2244  * AES CTR mode uses only forward AES cipher and same algorithm for encryption and decryption.
2245  * The only difference between encryption and decryption is that, for encryption, the input argument
2246  * is plain text and the output argument is cipher text. For decryption, the input argument is cipher text
2247  * and the output argument is plain text.
2248  *
2249  * param base CAAM peripheral base address
2250  * param handle Handle used for this request. Specifies jobRing.
2251  * param input Input data for CTR block mode
2252  * param[out] output Output data for CTR block mode
2253  * param size Size of input and output data in bytes
2254  * param[in,out] counter Input counter (updates on return)
2255  * param key Input key to use for forward AES cipher
2256  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
2257  * param[out] counterlast Output cipher of last counter, for chained CTR calls. NULL can be passed if chained calls are
2258  * not used.
2259  * param[out] szLeft Output number of bytes in left unused in counterlast block. NULL can be passed if chained calls
2260  * are not used.
2261  * return Status from encrypt operation
2262  */
CAAM_AES_CryptCtr(CAAM_Type * base,caam_handle_t * handle,const uint8_t * input,uint8_t * output,size_t size,uint8_t counter[16],const uint8_t * key,size_t keySize,uint8_t counterlast[16],size_t * szLeft)2263 status_t CAAM_AES_CryptCtr(CAAM_Type *base,
2264                            caam_handle_t *handle,
2265                            const uint8_t *input,
2266                            uint8_t *output,
2267                            size_t size,
2268                            uint8_t counter[16],
2269                            const uint8_t *key,
2270                            size_t keySize,
2271                            uint8_t counterlast[16],
2272                            size_t *szLeft)
2273 {
2274     caam_desc_aes_ctr_t descBuf;
2275     status_t status;
2276 
2277     do
2278     {
2279         status = CAAM_AES_CryptCtrNonBlocking(base, handle, descBuf, input, output, size, counter, key, keySize,
2280                                               counterlast, szLeft);
2281     } while (status == kStatus_CAAM_Again);
2282 
2283     if (status != 0)
2284     {
2285         return status;
2286     }
2287 
2288     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
2289 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
2290     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
2291     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
2292     DCACHE_InvalidateByRange((uint32_t)output, size);
2293     DCACHE_InvalidateByRange((uint32_t)counter, 16u);
2294     DCACHE_InvalidateByRange((uint32_t)szLeft, sizeof(szLeft));
2295     if (counterlast != NULL)
2296     {
2297         DCACHE_InvalidateByRange((uint32_t)counterlast, 16u);
2298     }
2299 #endif /* CAAM_OUT_INVALIDATE */
2300     return status;
2301 }
2302 
2303 /*!
2304  * brief Encrypts AES and tags using CCM block mode.
2305  *
2306  * Encrypts AES and optionally tags using CCM block mode.
2307  *
2308  * param base CAAM peripheral base address
2309  * param handle Handle used for this request. Specifies jobRing.
2310  * param plaintext Input plain text to encrypt
2311  * param[out] ciphertext Output cipher text.
2312  * param size Size of input and output data in bytes. Zero means authentication only.
2313  * param iv Nonce
2314  * param ivSize Length of the Nonce in bytes. Must be 7, 8, 9, 10, 11, 12, or 13.
2315  * param aad Input additional authentication data. Can be NULL if aadSize is zero.
2316  * param aadSize Input size in bytes of AAD. Zero means data mode only (authentication skipped).
2317  * param key Input key to use for encryption
2318  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
2319  * param[out] tag Generated output tag. Set to NULL to skip tag processing.
2320  * param tagSize Input size of the tag to generate, in bytes. Must be 4, 6, 8, 10, 12, 14, or 16.
2321  * return Status from encrypt operation
2322  */
CAAM_AES_EncryptTagCcm(CAAM_Type * base,caam_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t * iv,size_t ivSize,const uint8_t * aad,size_t aadSize,const uint8_t * key,size_t keySize,uint8_t * tag,size_t tagSize)2323 status_t CAAM_AES_EncryptTagCcm(CAAM_Type *base,
2324                                 caam_handle_t *handle,
2325                                 const uint8_t *plaintext,
2326                                 uint8_t *ciphertext,
2327                                 size_t size,
2328                                 const uint8_t *iv,
2329                                 size_t ivSize,
2330                                 const uint8_t *aad,
2331                                 size_t aadSize,
2332                                 const uint8_t *key,
2333                                 size_t keySize,
2334                                 uint8_t *tag,
2335                                 size_t tagSize)
2336 {
2337     caam_desc_aes_ccm_t descBuf;
2338     status_t status;
2339 
2340     do
2341     {
2342         status = CAAM_AES_EncryptTagCcmNonBlocking(base, handle, descBuf, plaintext, ciphertext, size, iv, ivSize, aad,
2343                                                    aadSize, key, keySize, tag, tagSize);
2344     } while (status == kStatus_CAAM_Again);
2345 
2346     if (status != 0)
2347     {
2348         return status;
2349     }
2350 
2351     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
2352 
2353 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
2354     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
2355     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
2356     DCACHE_InvalidateByRange((uint32_t)ciphertext, size);
2357     DCACHE_InvalidateByRange((uint32_t)tag, tagSize);
2358 #endif /* CAAM_OUT_INVALIDATE */
2359     return status;
2360 }
2361 
2362 /*!
2363  * brief Decrypts AES and authenticates using CCM block mode.
2364  *
2365  * Decrypts AES and optionally authenticates using CCM block mode.
2366  *
2367  * param base CAAM peripheral base address
2368  * param handle Handle used for this request. Specifies jobRing.
2369  * param ciphertext Input cipher text to decrypt
2370  * param[out] plaintext Output plain text.
2371  * param size Size of input and output data in bytes. Zero means authentication data only.
2372  * param iv Nonce
2373  * param ivSize Length of the Nonce in bytes. Must be 7, 8, 9, 10, 11, 12, or 13.
2374  * param aad Input additional authentication data. Can be NULL if aadSize is zero.
2375  * param aadSize Input size in bytes of AAD. Zero means data mode only (authentication data skipped).
2376  * param key Input key to use for decryption
2377  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
2378  * param tag Received tag. Set to NULL to skip tag processing.
2379  * param tagSize Input size of the received tag to compare with the computed tag, in bytes. Must be 4, 6, 8, 10, 12,
2380  *                14, or 16.
2381  * return Status from decrypt operation
2382  */
CAAM_AES_DecryptTagCcm(CAAM_Type * base,caam_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t * iv,size_t ivSize,const uint8_t * aad,size_t aadSize,const uint8_t * key,size_t keySize,const uint8_t * tag,size_t tagSize)2383 status_t CAAM_AES_DecryptTagCcm(CAAM_Type *base,
2384                                 caam_handle_t *handle,
2385                                 const uint8_t *ciphertext,
2386                                 uint8_t *plaintext,
2387                                 size_t size,
2388                                 const uint8_t *iv,
2389                                 size_t ivSize,
2390                                 const uint8_t *aad,
2391                                 size_t aadSize,
2392                                 const uint8_t *key,
2393                                 size_t keySize,
2394                                 const uint8_t *tag,
2395                                 size_t tagSize)
2396 {
2397     caam_desc_aes_ccm_t descBuf;
2398     status_t status;
2399 
2400     do
2401     {
2402         status = CAAM_AES_DecryptTagCcmNonBlocking(base, handle, descBuf, ciphertext, plaintext, size, iv, ivSize, aad,
2403                                                    aadSize, key, keySize, tag, tagSize);
2404     } while (status == kStatus_CAAM_Again);
2405 
2406     if (status != 0)
2407     {
2408         return status;
2409     }
2410     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
2411 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
2412     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
2413     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
2414     DCACHE_InvalidateByRange((uint32_t)plaintext, size);
2415 #endif /* CAAM_OUT_INVALIDATE */
2416     return status;
2417 }
2418 
2419 /*!
2420  * brief Encrypts AES and tags using GCM block mode.
2421  *
2422  * Encrypts AES and optionally tags using GCM block mode. If plaintext is NULL, only the GHASH is calculated and output
2423  * in the 'tag' field.
2424  *
2425  * param base CAAM peripheral base address
2426  * param handle Handle used for this request. Specifies jobRing.
2427  * param plaintext Input plain text to encrypt
2428  * param[out] ciphertext Output cipher text.
2429  * param size Size of input and output data in bytes
2430  * param iv Input initial vector
2431  * param ivSize Size of the IV
2432  * param aad Input additional authentication data
2433  * param aadSize Input size in bytes of AAD
2434  * param key Input key to use for encryption
2435  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
2436  * param[out] tag Output hash tag. Set to NULL to skip tag processing.
2437  * param tagSize Input size of the tag to generate, in bytes. Must be 4,8,12,13,14,15 or 16.
2438  * return Status from encrypt operation
2439  */
CAAM_AES_EncryptTagGcm(CAAM_Type * base,caam_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t * iv,size_t ivSize,const uint8_t * aad,size_t aadSize,const uint8_t * key,size_t keySize,uint8_t * tag,size_t tagSize)2440 status_t CAAM_AES_EncryptTagGcm(CAAM_Type *base,
2441                                 caam_handle_t *handle,
2442                                 const uint8_t *plaintext,
2443                                 uint8_t *ciphertext,
2444                                 size_t size,
2445                                 const uint8_t *iv,
2446                                 size_t ivSize,
2447                                 const uint8_t *aad,
2448                                 size_t aadSize,
2449                                 const uint8_t *key,
2450                                 size_t keySize,
2451                                 uint8_t *tag,
2452                                 size_t tagSize)
2453 {
2454     caam_desc_aes_gcm_t descBuf;
2455     status_t status;
2456 
2457     do
2458     {
2459         status = CAAM_AES_EncryptTagGcmNonBlocking(base, handle, descBuf, plaintext, ciphertext, size, iv, ivSize, aad,
2460                                                    aadSize, key, keySize, tag, tagSize);
2461     } while (status == kStatus_CAAM_Again);
2462 
2463     if (status != 0)
2464     {
2465         return status;
2466     }
2467 
2468     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
2469 
2470 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
2471     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
2472     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
2473     DCACHE_InvalidateByRange((uint32_t)ciphertext, size);
2474     if (tag != NULL)
2475     {
2476         DCACHE_InvalidateByRange((uint32_t)tag, tagSize);
2477     }
2478 #endif /* CAAM_OUT_INVALIDATE */
2479     return status;
2480 }
2481 
2482 /*!
2483  * brief Decrypts AES and authenticates using GCM block mode.
2484  *
2485  * Decrypts AES and optionally authenticates using GCM block mode. If ciphertext is NULL, only the GHASH is calculated
2486  * and compared with the received GHASH in 'tag' field.
2487  *
2488  * param base CAAM peripheral base address
2489  * param handle Handle used for this request. Specifies jobRing.
2490  * param ciphertext Input cipher text to decrypt
2491  * param[out] plaintext Output plain text.
2492  * param size Size of input and output data in bytes
2493  * param iv Input initial vector
2494  * param ivSize Size of the IV
2495  * param aad Input additional authentication data
2496  * param aadSize Input size in bytes of AAD
2497  * param key Input key to use for encryption
2498  * param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
2499  * param tag Input hash tag to compare. Set to NULL to skip tag processing.
2500  * param tagSize Input size of the tag, in bytes. Must be 4, 8, 12, 13, 14, 15, or 16.
2501  * return Status from decrypt operation
2502  */
CAAM_AES_DecryptTagGcm(CAAM_Type * base,caam_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t * iv,size_t ivSize,const uint8_t * aad,size_t aadSize,const uint8_t * key,size_t keySize,const uint8_t * tag,size_t tagSize)2503 status_t CAAM_AES_DecryptTagGcm(CAAM_Type *base,
2504                                 caam_handle_t *handle,
2505                                 const uint8_t *ciphertext,
2506                                 uint8_t *plaintext,
2507                                 size_t size,
2508                                 const uint8_t *iv,
2509                                 size_t ivSize,
2510                                 const uint8_t *aad,
2511                                 size_t aadSize,
2512                                 const uint8_t *key,
2513                                 size_t keySize,
2514                                 const uint8_t *tag,
2515                                 size_t tagSize)
2516 {
2517     caam_desc_aes_gcm_t descBuf;
2518     status_t status;
2519 
2520     do
2521     {
2522         status = CAAM_AES_DecryptTagGcmNonBlocking(base, handle, descBuf, ciphertext, plaintext, size, iv, ivSize, aad,
2523                                                    aadSize, key, keySize, tag, tagSize);
2524     } while (status == kStatus_CAAM_Again);
2525 
2526     if (status != 0)
2527     {
2528         return status;
2529     }
2530     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
2531 
2532 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
2533     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
2534     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
2535     DCACHE_InvalidateByRange((uint32_t)plaintext, size);
2536 #endif /* CAAM_OUT_INVALIDATE */
2537     return status;
2538 }
2539 
2540 /*******************************************************************************
2541  * HASH Code static
2542  ******************************************************************************/
caam_hash_check_input_alg(caam_hash_algo_t algo)2543 static status_t caam_hash_check_input_alg(caam_hash_algo_t algo)
2544 {
2545     if ((algo != kCAAM_XcbcMac) && (algo != kCAAM_Cmac) && (algo != kCAAM_Sha1) && (algo != kCAAM_Sha224) &&
2546         (algo != kCAAM_Sha256) && (algo != kCAAM_Sha384) && (algo != kCAAM_Sha512) && (algo != kCAAM_HmacSha1) &&
2547         (algo != kCAAM_HmacSha224) && (algo != kCAAM_HmacSha256) && (algo != kCAAM_HmacSha384) &&
2548         (algo != kCAAM_HmacSha512))
2549     {
2550         return kStatus_InvalidArgument;
2551     }
2552     return kStatus_Success;
2553 }
2554 
caam_hash_alg_is_cmac(caam_hash_algo_t algo)2555 static inline bool caam_hash_alg_is_cmac(caam_hash_algo_t algo)
2556 {
2557     return ((algo == kCAAM_XcbcMac) || (algo == kCAAM_Cmac));
2558 }
2559 
caam_hash_alg_is_hmac(caam_hash_algo_t algo)2560 static inline bool caam_hash_alg_is_hmac(caam_hash_algo_t algo)
2561 {
2562     return ((algo == kCAAM_HmacSha1) || (algo == kCAAM_HmacSha224) || (algo == kCAAM_HmacSha256) ||
2563             (algo == kCAAM_HmacSha384) || (algo == kCAAM_HmacSha512));
2564 }
2565 
caam_hash_alg_is_sha(caam_hash_algo_t algo)2566 static inline bool caam_hash_alg_is_sha(caam_hash_algo_t algo)
2567 {
2568     return ((algo == kCAAM_Sha1) || (algo == kCAAM_Sha224) || (algo == kCAAM_Sha256) || (algo == kCAAM_Sha384) ||
2569             (algo == kCAAM_Sha512));
2570 }
2571 
caam_hash_check_input_args(CAAM_Type * base,caam_hash_ctx_t * ctx,caam_hash_algo_t algo,const uint8_t * key,uint32_t keySize)2572 static status_t caam_hash_check_input_args(
2573     CAAM_Type *base, caam_hash_ctx_t *ctx, caam_hash_algo_t algo, const uint8_t *key, uint32_t keySize)
2574 {
2575     /* Check validity of input algorithm */
2576     if (kStatus_Success != caam_hash_check_input_alg(algo))
2577     {
2578         return kStatus_InvalidArgument;
2579     }
2580 
2581     if ((NULL == ctx) || (NULL == base))
2582     {
2583         return kStatus_InvalidArgument;
2584     }
2585 
2586     if (caam_hash_alg_is_cmac(algo))
2587     {
2588         if ((NULL == key) || (!caam_check_key_size(keySize)))
2589         {
2590             return kStatus_InvalidArgument;
2591         }
2592     }
2593 
2594     if (caam_hash_alg_is_hmac(algo))
2595     {
2596         if (NULL == key)
2597         {
2598             return kStatus_InvalidArgument;
2599         }
2600     }
2601 
2602     return kStatus_Success;
2603 }
2604 
caam_hash_check_context(caam_hash_ctx_internal_t * ctxInternal,const uint8_t * data)2605 static status_t caam_hash_check_context(caam_hash_ctx_internal_t *ctxInternal, const uint8_t *data)
2606 {
2607     if ((NULL == data) || (NULL == ctxInternal) || (NULL == ctxInternal->base) ||
2608         (kStatus_Success != caam_hash_check_input_alg(ctxInternal->algo)))
2609     {
2610         return kStatus_InvalidArgument;
2611     }
2612     return kStatus_Success;
2613 }
2614 
caam_hash_algo2mode(caam_hash_algo_t algo,uint32_t algState,uint32_t * algOutSize)2615 static uint32_t caam_hash_algo2mode(caam_hash_algo_t algo, uint32_t algState, uint32_t *algOutSize)
2616 {
2617     uint32_t modeReg  = 0u;
2618     uint32_t outSize  = 0u;
2619     uint32_t HmacMode = 0u;
2620 
2621     if (((algState >> 2u) == (uint32_t)kCAAM_AlgStateInit) || ((algState >> 2u) == (uint32_t)kCAAM_AlgStateInitFinal))
2622     {
2623         HmacMode = (uint32_t)kCAAM_HmacModeNonDerivedKey;
2624     }
2625     else
2626     {
2627         HmacMode = (uint32_t)kCAAM_HmacModeDerivedKey;
2628     }
2629 
2630     /* Set CAAM algorithm */
2631     switch (algo)
2632     {
2633         case kCAAM_XcbcMac:
2634             modeReg = (uint32_t)kCAAM_AlgorithmAES | (uint32_t)kCAAM_ModeXCBCMAC;
2635             outSize = 16u;
2636             break;
2637         case kCAAM_Cmac:
2638             modeReg = (uint32_t)kCAAM_AlgorithmAES | (uint32_t)kCAAM_ModeCMAC;
2639             outSize = 16u;
2640             break;
2641         case kCAAM_Sha1:
2642             modeReg = (uint32_t)kCAAM_AlgorithmSHA1;
2643             outSize = (uint32_t)kCAAM_OutLenSha1;
2644             break;
2645         case kCAAM_Sha224:
2646             modeReg = (uint32_t)kCAAM_AlgorithmSHA224;
2647             outSize = (uint32_t)kCAAM_OutLenSha224;
2648             break;
2649         case kCAAM_Sha256:
2650             modeReg = (uint32_t)kCAAM_AlgorithmSHA256;
2651             outSize = (uint32_t)kCAAM_OutLenSha256;
2652             break;
2653         case kCAAM_Sha384:
2654             modeReg = (uint32_t)kCAAM_AlgorithmSHA384;
2655             outSize = (uint32_t)kCAAM_OutLenSha384;
2656             break;
2657         case kCAAM_Sha512:
2658             modeReg = (uint32_t)kCAAM_AlgorithmSHA512;
2659             outSize = (uint32_t)kCAAM_OutLenSha512;
2660             break;
2661         case kCAAM_HmacSha1:
2662             modeReg = (uint32_t)kCAAM_AlgorithmSHA1 | (uint32_t)HmacMode;
2663             outSize = (uint32_t)kCAAM_OutLenSha1;
2664             break;
2665         case kCAAM_HmacSha224:
2666             modeReg = (uint32_t)kCAAM_AlgorithmSHA224 | (uint32_t)HmacMode;
2667             outSize = (uint32_t)kCAAM_OutLenSha224;
2668             break;
2669         case kCAAM_HmacSha256:
2670             modeReg = (uint32_t)kCAAM_AlgorithmSHA256 | (uint32_t)HmacMode;
2671             outSize = (uint32_t)kCAAM_OutLenSha256;
2672             break;
2673         case kCAAM_HmacSha384:
2674             modeReg = (uint32_t)kCAAM_AlgorithmSHA384 | (uint32_t)HmacMode;
2675             outSize = (uint32_t)kCAAM_OutLenSha384;
2676             break;
2677         case kCAAM_HmacSha512:
2678             modeReg = (uint32_t)kCAAM_AlgorithmSHA512 | (uint32_t)HmacMode;
2679             outSize = (uint32_t)kCAAM_OutLenSha512;
2680             break;
2681         default:
2682             /* All the cases have been listed above, the default clause should not be reached. */
2683             break;
2684     }
2685 
2686     modeReg |= algState;
2687     if (algOutSize != NULL)
2688     {
2689         *algOutSize = outSize;
2690     }
2691 
2692     return modeReg;
2693 }
2694 
caam_hash_algo2ctx_size(caam_hash_algo_t algo,uint32_t how)2695 static uint32_t caam_hash_algo2ctx_size(caam_hash_algo_t algo, uint32_t how)
2696 {
2697     uint32_t ctxSize = 0u;
2698 
2699     /* Size of context in bytes for context switching */
2700     switch (algo)
2701     {
2702         case kCAAM_XcbcMac:
2703             if (how == 0U)
2704             {
2705                 ctxSize = 48u; /* add K3 and K2 */
2706             }
2707             else
2708             {
2709                 ctxSize = 16u; /* only running or final MAC during UPDATE or FINALIZE or INITIALIZE/FINALIZE */
2710             }
2711             break;
2712         case kCAAM_Cmac:
2713             if (how == 0U)
2714             {
2715                 ctxSize = 32u; /* add L */
2716             }
2717             else
2718             {
2719                 ctxSize = 16u; /* only running or final MAC during UPDATE or FINALIZE or INITIALIZE/FINALIZE */
2720             }
2721             break;
2722         /* MDHA use of the Context Register
2723         The Context Register stores the current digest and running message length. The running
2724         message length will be 8 bytes immediately following the active digest. The digest size is
2725         defined as follows:
2726         MD5: 16 bytes
2727         SHA-1: 20 bytes
2728         SHA-224: 28 bytes final digest; 32 bytes running digest
2729         SHA-256: 32 bytes
2730         SHA-384: 48 bytes final digest; 64 bytes running digest
2731         SHA-512: 64 bytes */
2732         case kCAAM_Sha1:
2733             ctxSize = 28u; /* 8 + 20 */
2734             break;
2735         case kCAAM_Sha224:
2736         case kCAAM_Sha256:
2737             ctxSize = 40u; /* 8 + 32 */
2738             break;
2739         case kCAAM_Sha384:
2740         case kCAAM_Sha512:
2741             ctxSize = 72u; /* 8 + 64 */
2742             break;
2743         /* Add the context of HMAC: in Init mode the HMAC context includes the derived key
2744         in other cases HMAC_SHA_XXX contex's size is the same as the SHA_XXX context's size */
2745         case kCAAM_HmacSha1:
2746             if (how == 0u)
2747             {
2748                 ctxSize = 76u; /* 8 + 20 + (sizeof(derivedKey) = 48)*/
2749             }
2750             else
2751             {
2752                 ctxSize = 28u; /* 8 + 20 */
2753             }
2754             break;
2755         case kCAAM_HmacSha224:
2756         case kCAAM_HmacSha256:
2757             if (how == 0u)
2758             {
2759                 ctxSize = 104u; /* 8 + 32 + (sizeof(derivedKey) = 64)*/
2760             }
2761             else
2762             {
2763                 ctxSize = 40u; /* 8 + 32 */
2764             }
2765             break;
2766         case kCAAM_HmacSha384:
2767         case kCAAM_HmacSha512:
2768             if (how == 0u)
2769             {
2770                 ctxSize = 200u; /* 8 + 64 + (sizeof(derivedKey) = 128)*/
2771             }
2772             else
2773             {
2774                 ctxSize = 72u; /* 8 + 64 */
2775             }
2776             break;
2777         default:
2778             /* All the cases have been listed above, the default clause should not be reached. */
2779             break;
2780     }
2781     return ctxSize;
2782 }
2783 
2784 static const uint32_t templateHash[] = {
2785     /* 00 */ 0xB0800000u, /* HEADER */
2786     /* 01 */ 0x00000000u, /* KEY */
2787     /* 02 */ 0x00000000u, /* place: key address */
2788     /* 03 */ 0x10200000u, /* LOAD bytes to Class Context Register. Offset 0 bytes. */
2789     /* 04 */ 0x00000000u, /* place: context address */
2790 
2791     /* 05 */ 0x80000000u, /* OPERATION (place either AES MAC or MDHA SHA) */
2792     /* 06 */ 0x21570000u, /* FIFO LOAD Class Message via SGT and EXT length */
2793     /* 07 */ 0x00000000u, /* place: SGT address */
2794     /* 08 */ 0x00000000u, /* place: FIFO LOAD EXT Length size */
2795     /* 09 */ 0x50200000u, /* STORE bytes from Class Context Register offset 0 bytes. */
2796     /* 10 */ 0x00000000u, /* place: context address */
2797 
2798     /* 11 */ 0x60240000u, /* FIFO STORE from KEY to memory. */
2799     /* 12 */ 0x00000000u, /* place: derived key address ECB encrypted */
2800     /* 13 */ 0xA0C00000u, /* halt always with status 0 */
2801 
2802     /* 14 */ 0x00000000u, /* SGT entry 0 word 0 */
2803     /* 15 */ 0x00000000u, /* SGT entry 0 word 1 */
2804     /* 16 */ 0x00000000u, /* SGT entry 0 word 2 */
2805     /* 17 */ 0x00000000u, /* SGT entry 0 word 3 */
2806 
2807     /* 18 */ 0x00000000u, /* SGT entry 1 word 0 */
2808     /* 19 */ 0x00000000u, /* SGT entry 1 word 1 */
2809     /* 20 */ 0x00000000u, /* SGT entry 1 word 2 */
2810     /* 21 */ 0x00000000u, /* SGT entry 1 word 3 */
2811 };
2812 
2813 /*!
2814  * @brief Add data chunk to SGT table. Append after uncomplete block in ctxInternal if there is any.
2815  *
2816  * @param ctxInternal uncomplete block in the hash context - to be inserted before new data chunk
2817  * @param input new data chunk to insert
2818  * @param inputSize size in bytes of new data chunk to insert
2819  * @param numRemain number of bytes that remain in the last uncomplete block
2820  * @param algState in FINALIZE or INITIALIZE/FINALIZE we add also last uncomplete block bytes
2821  * @param sgt address of the SGT
2822  * @param last last call to this function adds Final Bit
2823  */
caam_hash_sgt_insert(caam_hash_ctx_internal_t * ctxInternal,const uint8_t * input,size_t inputSize,size_t * numRemain,caam_algorithm_state_t algState,caam_sgt_entry_t * sgt,caam_hash_sgt_entry_type_t last)2824 static uint32_t caam_hash_sgt_insert(caam_hash_ctx_internal_t *ctxInternal,
2825                                      const uint8_t *input,
2826                                      size_t inputSize,
2827                                      size_t *numRemain,
2828                                      caam_algorithm_state_t algState,
2829                                      caam_sgt_entry_t *sgt,
2830                                      caam_hash_sgt_entry_type_t last)
2831 {
2832     /* configure SGT
2833      * *64 bytes multiple in kCAAM_HashInit or kCAAM_HashUpdate
2834      * *arbitrary amount of data in kCAAM_HashInitFinal or kCAAM_HashFinal
2835      * min 1 and max 2 SGT entries
2836      * 1) if there is any data in the context buffer, use it as one entry
2837      * 2) input as one entry
2838      */
2839     uint32_t numBlocks;
2840     uint32_t remain;
2841     uint32_t num;
2842     uint32_t currSgtEntry;
2843 
2844     uint32_t ctxBlksz   = (ctxInternal != NULL) ? ctxInternal->blksz : 0U;
2845     uint32_t ctxBlkAddr = (ctxInternal != NULL) ? (uint32_t)&ctxInternal->blk.b[0] : 0U;
2846 
2847     currSgtEntry = 0;
2848     numBlocks    = (inputSize + ctxBlksz) / CAAM_HASH_BLOCK_SIZE;
2849     remain       = (inputSize + ctxBlksz) % CAAM_HASH_BLOCK_SIZE;
2850 
2851     /* number of bytes for processing
2852      * only full block multiple in INITIALIZE or UPDATE
2853      * any size in INITIALIZE/FINALIZE or FINALIZE
2854      */
2855     num = (CAAM_HASH_BLOCK_SIZE * numBlocks);
2856     if ((algState == kCAAM_AlgStateInitFinal) || (algState == kCAAM_AlgStateFinal))
2857     {
2858         num += remain; /* add also uncomplete bytes from last block in one of FINALIZE states */
2859         remain = 0;
2860     }
2861     if (numRemain != NULL)
2862     {
2863         *numRemain = remain;
2864     }
2865 
2866     if ((ctxBlksz != 0U) || (0U == ctxBlksz + inputSize))
2867     {
2868         sgt[currSgtEntry].address_l = ADD_OFFSET(ctxBlkAddr);
2869         sgt[currSgtEntry].length    = ctxBlksz;
2870         if ((kCAAM_HashSgtEntryLast == last) && (0U == inputSize))
2871         {
2872             sgt[currSgtEntry].length |= 0x40000000u; /* Final SG entry */
2873         }
2874         currSgtEntry++;
2875     }
2876 
2877     if (inputSize != 0U)
2878     {
2879         /* number of bytes for processing
2880          * only full block multiple in INITIALIZE or UPDATE
2881          * any size in INITIALIZE/FINALIZE or FINALIZE
2882          */
2883         sgt[currSgtEntry].address_l = ADD_OFFSET((uint32_t)input);
2884         sgt[currSgtEntry].length    = inputSize - remain;
2885         if (kCAAM_HashSgtEntryLast == last)
2886         {
2887             sgt[currSgtEntry].length |= 0x40000000u; /* Final SG entry */
2888             sgt[currSgtEntry].offset = 0x80000000u;
2889         }
2890     }
2891     return num; /* no of bytes processed in total by these 1 or 2 SGT entries */
2892 }
2893 
2894 /*!
2895  * @brief Create job descriptor for the HASH request and schedule at CAAM job ring
2896  *
2897  *
2898  */
caam_hash_schedule_input_data(CAAM_Type * base,caam_handle_t * handle,caam_hash_algo_t algo,caam_sgt_entry_t * sgt,uint32_t dataSize,caam_hash_sgt_type_t sgtType,caam_algorithm_state_t algState,caam_desc_hash_t descriptor,size_t * outputSize,void * output,void * context,uint32_t keyAddr,uint32_t keySize)2899 static status_t caam_hash_schedule_input_data(CAAM_Type *base,
2900                                               caam_handle_t *handle,
2901                                               caam_hash_algo_t algo,
2902                                               caam_sgt_entry_t *sgt,
2903                                               uint32_t dataSize,
2904                                               caam_hash_sgt_type_t sgtType,
2905                                               caam_algorithm_state_t algState,
2906                                               caam_desc_hash_t descriptor,
2907                                               size_t *outputSize,
2908                                               void *output,
2909                                               void *context,
2910                                               uint32_t keyAddr,
2911                                               uint32_t keySize)
2912 {
2913     BUILD_ASSURE(sizeof(templateHash) <= sizeof(caam_desc_hash_t), caam_desc_hash_t_size);
2914     uint32_t descriptorSize = ARRAY_SIZE(templateHash);
2915     uint32_t algOutSize     = 0;
2916 
2917     bool isSha = caam_hash_alg_is_sha(algo); /* MDHA engine */
2918                                              /* how many bytes to read from context register
2919                                               * we need caam_hash_algo2ctx_size() to return
2920                                               * full context size (to be used for context restore in descriptor[3])
2921                                               */
2922     bool isHmac = caam_hash_alg_is_hmac(algo);
2923 
2924     uint32_t caamCtxSz = caam_hash_algo2ctx_size(algo, 0 /* full context */);
2925 
2926     (void)caam_memcpy(descriptor, templateHash, sizeof(templateHash));
2927 
2928     uint32_t hashClass = (isSha || isHmac) ? 0x04000000u : CAAM_AES_MAC_CLASS;
2929 
2930     /* add class to all commands that need it */
2931     descriptor[1] |= hashClass;
2932     descriptor[3] |= hashClass;
2933     descriptor[5] |= hashClass;
2934     descriptor[6] |= hashClass;
2935     descriptor[9] |= hashClass;
2936     descriptor[11] |= hashClass;
2937 
2938     /* add descriptor size */
2939     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
2940 
2941     /* kCAAM_AlgStateInit or kCAAM_AlgStateInitFinal needs to skip context load as there is no context */
2942     if ((algState == kCAAM_AlgStateInit) || (algState == kCAAM_AlgStateInitFinal))
2943     {
2944         if (isSha)
2945         {
2946             /* HEADER can jump directly to MDHA operation */
2947             descriptor[0] |= 0x00050000U; /* JUMP to descriptor[5] */
2948         }
2949         else
2950         {
2951             if (isHmac)
2952             {
2953                 // Key can be stored in plaintext
2954                 descriptor[1] |= 1UL << 14;
2955             }
2956 
2957             /* load KEY, then directly to AESA MAC operation */
2958             descriptor[1] |= (keySize & DESC_KEY_SIZE_MASK);
2959             descriptor[2] = ADD_OFFSET(keyAddr);
2960             descriptor[3] = DESC_JUMP_2; /* JUMP to descriptor[5] */
2961         }
2962     }
2963     else
2964     {
2965         if (isSha)
2966         {
2967             /* MDHA SHA in Update state skips loading the KEY, as MDHA SHA has no configurable key
2968              * HEADER can jump directly to context restore
2969              */
2970             descriptor[0] |= 0x00030000U;      /* JUMP to descriptor[3] */
2971             /* descriptor[1] = 0xA0000002u; */ /* JUMP to descriptor[3] */
2972         }
2973         else
2974         {
2975             /* load KEY */
2976             descriptor[1] |= (keySize & DESC_KEY_SIZE_MASK);
2977             descriptor[2] = ADD_OFFSET(keyAddr);
2978 
2979             /* XCBC-MAC K1 derived key has been ECB encrypted (black key)
2980              * so it needs decrypt
2981              */
2982             if (kCAAM_XcbcMac == algo)
2983             {
2984                 descriptor[1] |= (uint32_t)1u << 22; /* ENC */
2985             }
2986         }
2987 
2988         /* context restore */
2989         descriptor[3] |= caamCtxSz;
2990         descriptor[4] = ADD_OFFSET((uint32_t)(uint32_t *)context);
2991     }
2992 
2993     /* OPERATION:
2994      * alg MDHA or AESA
2995      * mode INITIALIZE or UPDATE or FINALIZE or INITIALIZE/FINALIZE in algState argument
2996      */
2997 
2998     /* ALGORITHM OPERATION | CLASS | alg | aai | algState */
2999     descriptor[5] |= caam_hash_algo2mode(algo, (uint32_t)algState << 2, &algOutSize);
3000 
3001     /* configure SGT */
3002     descriptor[8] = dataSize;
3003     if (kCAAM_HashSgtInternal == sgtType)
3004     {
3005         descriptor[7] = ADD_OFFSET(
3006             (uint32_t)&descriptor[(uint32_t)kCAAM_HashDescriptorSgtIdx]); /* use SGT embedded in the job descriptor */
3007         (void)caam_memcpy(&descriptor[(uint32_t)kCAAM_HashDescriptorSgtIdx], (const uint32_t *)(uintptr_t)sgt,
3008                           sizeof(caam_hash_internal_sgt_t));
3009     }
3010     else
3011     {
3012         descriptor[7] = ADD_OFFSET((uint32_t)sgt);
3013     }
3014 
3015     /* save context: context switch init or running or result */
3016     if ((kCAAM_AlgStateFinal == algState) || (kCAAM_AlgStateInitFinal == algState))
3017     {
3018         if (outputSize != NULL)
3019         {
3020             *outputSize = algOutSize;
3021         }
3022         caamCtxSz = algOutSize;
3023     }
3024     else
3025     {
3026         uint32_t how = (algState == kCAAM_AlgStateInit) ? 0U : 1U; /* context switch needs full, then running */
3027         caamCtxSz    = caam_hash_algo2ctx_size(algo, how);
3028     }
3029     descriptor[9] |= caamCtxSz;
3030     if ((kCAAM_AlgStateFinal == algState) || (kCAAM_AlgStateInitFinal == algState))
3031     {
3032         /* final result write to output */
3033         descriptor[10] = ADD_OFFSET((uint32_t)(uint32_t *)output);
3034     }
3035     else
3036     {
3037         /* context switch write to ctxInternal */
3038         descriptor[10] = ADD_OFFSET((uint32_t)(uint32_t *)context);
3039     }
3040 
3041     /* save the derived key K1 in XCBC-MAC. only if context switch. */
3042     if ((kCAAM_AlgStateInit == algState) && (kCAAM_XcbcMac == algo))
3043     {
3044         descriptor[11] |= (keySize & DESC_KEY_SIZE_MASK);
3045         descriptor[12] = ADD_OFFSET((uint32_t)&keyAddr);
3046     }
3047     else if ((kCAAM_AlgStateInit == algState) && (kCAAM_HmacSha256 == algo))
3048     {
3049         /* save the HMAC derived key. Only if context switch */
3050         /* Derived key is 64 byte long */
3051 
3052         descriptor[11] = 0x60260000u | (64u & DESC_KEY_SIZE_MASK);
3053         descriptor[12] = ADD_OFFSET((uint32_t)&keyAddr);
3054     }
3055     else
3056     {
3057         descriptor[11] = ADD_OFFSET(descriptor[13]); /* always halt with status 0x0 (normal) */
3058     }
3059 
3060     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
3061 }
3062 
3063 /*!
3064  * @brief Add uncomplete block (ctxInternal), then append new data (to current hash).
3065  *
3066  *
3067  */
caam_hash_append_data(caam_hash_ctx_internal_t * ctxInternal,const uint8_t * input,size_t inputSize,caam_algorithm_state_t algState,caam_desc_hash_t descriptor,size_t * numRemain,void * output,size_t * outputSize)3068 static status_t caam_hash_append_data(caam_hash_ctx_internal_t *ctxInternal,
3069                                       const uint8_t *input,
3070                                       size_t inputSize,
3071                                       caam_algorithm_state_t algState,
3072                                       caam_desc_hash_t descriptor,
3073                                       size_t *numRemain,
3074                                       void *output,
3075                                       size_t *outputSize)
3076 {
3077     caam_hash_internal_sgt_t sgt;
3078     (void)memset(&sgt, 0, sizeof(sgt));
3079     size_t num = caam_hash_sgt_insert(ctxInternal, input, inputSize, numRemain, algState, sgt, kCAAM_HashSgtEntryLast);
3080     return caam_hash_schedule_input_data(ctxInternal->base, ctxInternal->handle, ctxInternal->algo, sgt, num,
3081                                          kCAAM_HashSgtInternal, algState, descriptor, outputSize, output,
3082                                          &ctxInternal->word[0], (uint32_t)&ctxInternal->word[kCAAM_HashCtxKeyStartIdx],
3083                                          ctxInternal->word[kCAAM_HashCtxKeySize]);
3084 }
3085 
3086 /*******************************************************************************
3087  * HASH Code public
3088  ******************************************************************************/
3089 
3090 /*!
3091  * brief Initialize HASH context
3092  *
3093  * This function initializes the HASH.
3094  * Key shall be supplied if the underlaying algoritm is AES XCBC-MAC or CMAC.
3095  * Key shall be NULL if the underlaying algoritm is SHA.
3096  *
3097  * For XCBC-MAC, the key length must be 16. For CMAC, the key length can be
3098  * the AES key lengths supported by AES engine. For MDHA the key length argument
3099  * is ignored.
3100  *
3101  * This functions is used to initialize the context for both blocking and non-blocking
3102  * CAAM_HASH API.
3103  * For blocking CAAM HASH API, the HASH context contains all information required for context switch,
3104  * such as running hash or MAC. For non-blocking CAAM HASH API, the HASH context is used
3105  * to hold SGT. Therefore, the HASH context cannot be shared between blocking and non-blocking HASH API.
3106  * With one HASH context, either use only blocking HASH API or only non-blocking HASH API.
3107  *
3108  *
3109  * param base CAAM peripheral base address
3110  * param handle Handle used for this request.
3111  * param[out] ctx Output hash context
3112  * param algo Underlaying algorithm to use for hash computation.
3113  * param key Input key (NULL if underlaying algorithm is SHA)
3114  * param keySize Size of input key in bytes
3115  * return Status of initialization
3116  */
CAAM_HASH_Init(CAAM_Type * base,caam_handle_t * handle,caam_hash_ctx_t * ctx,caam_hash_algo_t algo,const uint8_t * key,size_t keySize)3117 status_t CAAM_HASH_Init(CAAM_Type *base,
3118                         caam_handle_t *handle,
3119                         caam_hash_ctx_t *ctx,
3120                         caam_hash_algo_t algo,
3121                         const uint8_t *key,
3122                         size_t keySize)
3123 {
3124     status_t ret;
3125     caam_hash_ctx_internal_t *ctxInternal;
3126     uint32_t i;
3127 
3128     ret = caam_hash_check_input_args(base, ctx, algo, key, keySize);
3129     if (ret != kStatus_Success)
3130     {
3131         return ret;
3132     }
3133 
3134     /* set algorithm in context struct for later use */
3135     ctxInternal       = (caam_hash_ctx_internal_t *)(uint32_t)ctx;
3136     ctxInternal->algo = algo;
3137     for (i = 0U; i < (uint32_t)kCAAM_HashCtxNumWords; i++)
3138     {
3139         ctxInternal->word[i] = 0u;
3140     }
3141 
3142     /* Steps required only when using AESA for CMAC or MDHA for HMAC */
3143     if (caam_hash_alg_is_cmac(algo) || caam_hash_alg_is_hmac(algo))
3144     {
3145         /* store input key and key length in context struct for later use */
3146         ctxInternal->word[kCAAM_HashCtxKeySize] = keySize;
3147         (void)caam_memcpy(&ctxInternal->word[kCAAM_HashCtxKeyStartIdx], (const uint32_t *)(uintptr_t)key, keySize);
3148     }
3149 
3150     ctxInternal->blksz = 0u;
3151     for (i = 0; i < ARRAY_SIZE(ctxInternal->blk.w); i++)
3152     {
3153         ctxInternal->blk.w[i] = 0u;
3154     }
3155     ctxInternal->fsm_state = kCAAM_HashInit;
3156     ctxInternal->base      = base;
3157     ctxInternal->handle    = handle;
3158 
3159     return kStatus_Success;
3160 }
3161 
3162 /*!
3163  * brief Add data to current HASH
3164  *
3165  * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be
3166  * hashed. The functions blocks. If it returns kStatus_Success, the running hash or mac
3167  * has been updated (CAAM has processed the input data), so the memory at input pointer
3168  * can be released back to system. The context is updated with the running hash or mac
3169  * and with all necessary information to support possible context switch.
3170  *
3171  * param[in,out] ctx HASH context
3172  * param input Input data
3173  * param inputSize Size of input data in bytes
3174  * return Status of the hash update operation
3175  */
CAAM_HASH_Update(caam_hash_ctx_t * ctx,const uint8_t * input,size_t inputSize)3176 status_t CAAM_HASH_Update(caam_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize)
3177 {
3178     caam_desc_hash_t descBuf;
3179     status_t status;
3180     caam_hash_ctx_internal_t *ctxInternal;
3181     bool isUpdateState;
3182     size_t numRemain = 0;
3183 
3184     /* compile time check for the correct structure size */
3185     BUILD_ASSURE(sizeof(caam_hash_ctx_internal_t) <= sizeof(caam_hash_ctx_t), caam_hash_ctx_internal_t_size);
3186 
3187     if (0U == inputSize)
3188     {
3189         return kStatus_Success;
3190     }
3191 
3192     /* we do caam_memcpy() input stream, up to buffer size
3193      * of 64 bytes. then if I have more I have to
3194      * 1) load Class 2 context
3195      * 2) schedule CAAM job with INITIALIZE or UPDATE mode (simple if only 64 bytes block is processed. SG table for 2
3196      * and more)
3197      * 3) in step 2 process all full 64 bytes blocks
3198      * 4) copy last not-full buffer size data to buffer.
3199      * 5) save Class 2 context
3200      */
3201     ctxInternal = (caam_hash_ctx_internal_t *)(uint32_t)ctx;
3202     status      = caam_hash_check_context(ctxInternal, input);
3203     if (kStatus_Success != status)
3204     {
3205         return status;
3206     }
3207 
3208     /* if we are still less than 64 bytes, keep only in context */
3209     if ((ctxInternal->blksz + inputSize) <= CAAM_HASH_BLOCK_SIZE)
3210     {
3211         (void)caam_memcpy((&ctxInternal->blk.b[0]) + ctxInternal->blksz, input, inputSize);
3212         ctxInternal->blksz += inputSize;
3213         return status;
3214     }
3215     else
3216     {
3217         isUpdateState = ctxInternal->fsm_state == kCAAM_HashUpdate;
3218         if (!isUpdateState)
3219         {
3220             /* Step 2: schedule CAAM job in INITIALIZE mode.
3221              */
3222             ctxInternal->fsm_state = kCAAM_HashUpdate;
3223             /* skip load context as there is no running context yet. */
3224             status = caam_hash_append_data(ctxInternal, input, inputSize, kCAAM_AlgStateInit, descBuf, &numRemain, NULL,
3225                                            NULL);
3226         }
3227     }
3228 
3229     if (kStatus_Success != status)
3230     {
3231         return status;
3232     }
3233 
3234     if (isUpdateState)
3235     {
3236         /* Step 2: schedule CAAM job in UPDATE mode.
3237          */
3238 
3239         /* process input data and save CAAM context to context structure */
3240         status =
3241             caam_hash_append_data(ctxInternal, input, inputSize, kCAAM_AlgStateUpdate, descBuf, &numRemain, NULL, NULL);
3242         if (status != kStatus_Success)
3243         {
3244             return status;
3245         }
3246     }
3247 
3248     /* blocking wait */
3249     status = CAAM_Wait(ctxInternal->base, ctxInternal->handle, descBuf, kCAAM_Blocking);
3250     if (status != kStatus_Success)
3251     {
3252         return status;
3253     }
3254 
3255 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
3256     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
3257     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
3258     DCACHE_InvalidateByRange((uint32_t)&ctxInternal->word[0u], (uint32_t)kCAAM_HashCtxNumWords * sizeof(uint32_t));
3259 #endif /* CAAM_OUT_INVALIDATE */
3260 
3261     /* after job is complete, copy numRemain bytes at the end of the input[] to the context */
3262     (void)caam_memcpy((&ctxInternal->blk.b[0]), input + inputSize - numRemain, numRemain);
3263     ctxInternal->blksz = numRemain;
3264 
3265     return status;
3266 }
3267 
3268 /*!
3269  * brief Add input address and size to input data table
3270  *
3271  * Add data input pointer to a table maintained internally in the context.
3272  * Each call of this function creates one entry in the table.
3273  * The entry consists of the input pointer and inputSize.
3274  * All entries created by one or multiple calls of this function can be processed
3275  * in one call to CAAM_HASH_FinishNonBlocking() function.
3276  * Individual entries can point to non-continuous data in the memory.
3277  * The processing will occur in the order in which the CAAM_HASH_UpdateNonBlocking()
3278  * have been called.
3279  *
3280  * Memory pointers will be later accessed by CAAM (at time of CAAM_HASH_FinishNonBlocking()),
3281  * so the memory must stay valid
3282  * until CAAM_HASH_FinishNonBlocking() has been called and CAAM completes the processing.
3283  *
3284  * param[in,out] ctx HASH context
3285  * param input Input data
3286  * param inputSize Size of input data in bytes
3287  * return Status of the hash update operation
3288  */
CAAM_HASH_UpdateNonBlocking(caam_hash_ctx_t * ctx,const uint8_t * input,size_t inputSize)3289 status_t CAAM_HASH_UpdateNonBlocking(caam_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize)
3290 {
3291     status_t status;
3292 
3293     caam_hash_ctx_internal_t *ctxInternal;
3294 
3295     if (0U == inputSize)
3296     {
3297         return kStatus_Success;
3298     }
3299 
3300     /* runtime input validity check */
3301     ctxInternal = (caam_hash_ctx_internal_t *)(uint32_t)ctx;
3302     status      = caam_hash_check_context(ctxInternal, input);
3303     if (kStatus_Success != status)
3304     {
3305         return status;
3306     }
3307 
3308     /* Add input data chunk to SGT */
3309     uint32_t currSgtEntry = ctxInternal->blksz;
3310     if (currSgtEntry >= (uint32_t)kCAAM_HashSgtMaxCtxEntries)
3311     {
3312         return kStatus_InvalidArgument;
3313     }
3314 
3315     caam_sgt_entry_t *sgt = &((caam_sgt_entry_t *)(uint32_t)ctxInternal)[currSgtEntry];
3316     (void)caam_hash_sgt_insert(NULL, input, inputSize, NULL, kCAAM_AlgStateInitFinal, sgt,
3317                                kCAAM_HashSgtEntryNotLast /* not last. we don't know if this is the last chunk */);
3318     if (inputSize != 0U)
3319     {
3320         ctxInternal->blksz++;
3321     }
3322 
3323     return status;
3324 }
3325 
3326 /*!
3327  * brief Finalize hashing
3328  *
3329  * Outputs the final hash (computed by CAAM_HASH_Update()) and erases the context.
3330  *
3331  * param[in,out] ctx Input hash context
3332  * param[out] output Output hash data
3333  * param[out] outputSize Output parameter storing the size of the output hash in bytes
3334  * return Status of the hash finish operation
3335  */
CAAM_HASH_Finish(caam_hash_ctx_t * ctx,uint8_t * output,size_t * outputSize)3336 status_t CAAM_HASH_Finish(caam_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize)
3337 {
3338     status_t status;
3339     caam_hash_ctx_internal_t *ctxInternal;
3340     caam_desc_hash_t descBuf;
3341     caam_algorithm_state_t algState;
3342     size_t outputSizeTmp;
3343 
3344     /* runtime input validity check */
3345     ctxInternal = (caam_hash_ctx_internal_t *)(uint32_t)ctx;
3346     status      = caam_hash_check_context(ctxInternal, output);
3347     if (kStatus_Success != status)
3348     {
3349         return status;
3350     }
3351 
3352     /* determine algorithm state to configure
3353      * based on prior processing.
3354      * If at least one full block has been processed during HASH_Update() then the state in ctxInternal
3355      * will be set to kCAAM_HashUpdate and so we will configure FINALIZE algorithm state.
3356      * Otherwise there is data only in the ctxInternal that we can process in INITIALIZE/FINALIZE.
3357      */
3358     if (ctxInternal->fsm_state == kCAAM_HashInit)
3359     {
3360         algState = kCAAM_AlgStateInitFinal;
3361     }
3362     else
3363     {
3364         algState = kCAAM_AlgStateFinal;
3365     }
3366 
3367     status = caam_hash_append_data(
3368         ctxInternal, NULL, 0, /* we process only blksz bytes in ctxInternal, so giving NULL and zero size here */
3369         algState, descBuf, NULL, output, &outputSizeTmp);
3370     if (kStatus_Success != status)
3371     {
3372         return status;
3373     }
3374 
3375     /* blocking wait */
3376     status = CAAM_Wait(ctxInternal->base, ctxInternal->handle, descBuf, kCAAM_Blocking);
3377 
3378 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
3379     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
3380     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
3381     DCACHE_InvalidateByRange((uint32_t)output, outputSizeTmp);
3382 #endif /* CAAM_OUT_INVALIDATE */
3383 
3384     if (outputSize != NULL)
3385     {
3386         *outputSize = outputSizeTmp;
3387     }
3388 
3389     (void)memset(ctx, 0, sizeof(caam_hash_ctx_t));
3390     return status;
3391 }
3392 
3393 /*!
3394  * brief Finalize hashing
3395  *
3396  * The actual algorithm is computed with all input data, the memory pointers
3397  * are accessed by CAAM after the function returns.
3398  * The input data chunks have been specified by prior calls to CAAM_HASH_UpdateNonBlocking().
3399  * The function schedules the request at CAAM, then returns.
3400  * After a while, when the CAAM completes processing of the input data chunks,
3401  * the result is written to the output[] array, outputSize is written and the context
3402  * is cleared.
3403  *
3404  * param[in,out] ctx Input hash context
3405  * param[out] descriptor Memory for the CAAM descriptor.
3406  * param[out] output Output hash data
3407  * param[out] outputSize Output parameter storing the size of the output hash in bytes
3408  * return Status of the hash finish operation
3409  */
CAAM_HASH_FinishNonBlocking(caam_hash_ctx_t * ctx,caam_desc_hash_t descriptor,uint8_t * output,size_t * outputSize)3410 status_t CAAM_HASH_FinishNonBlocking(caam_hash_ctx_t *ctx,
3411                                      caam_desc_hash_t descriptor,
3412                                      uint8_t *output,
3413                                      size_t *outputSize)
3414 {
3415     status_t status;
3416     caam_hash_ctx_internal_t *ctxInternal;
3417 
3418     /* runtime input validity check */
3419     ctxInternal = (caam_hash_ctx_internal_t *)(uint32_t)ctx;
3420     status      = caam_hash_check_context(ctxInternal, output);
3421     if (kStatus_Success != status)
3422     {
3423         return status;
3424     }
3425 
3426     uint32_t currSgtEntry = ctxInternal->blksz;
3427     if (currSgtEntry > (uint32_t)kCAAM_HashSgtMaxCtxEntries)
3428     {
3429         return kStatus_InvalidArgument;
3430     }
3431 
3432     caam_sgt_entry_t *sgt = &((caam_sgt_entry_t *)(uint32_t)ctxInternal)[0];
3433 
3434     /* mark currSgtEntry with Final Bit */
3435     uint32_t i;
3436     uint32_t totalLength = 0;
3437     for (i = 0; i < currSgtEntry; i++)
3438     {
3439         totalLength += sgt[i].length;
3440     }
3441     sgt[currSgtEntry].length |= 0x40000000u; /* Final SG entry */
3442 
3443     status = caam_hash_schedule_input_data(ctxInternal->base, ctxInternal->handle, ctxInternal->algo, sgt, totalLength,
3444                                            kCAAM_HashSgtExternal, kCAAM_AlgStateInitFinal, descriptor, outputSize,
3445                                            output, NULL, (uint32_t)&ctxInternal->word[kCAAM_HashCtxKeyStartIdx],
3446                                            ctxInternal->word[kCAAM_HashCtxKeySize]);
3447     return status;
3448 }
3449 
3450 /*!
3451  * brief Create HASH on given data
3452  *
3453  * Perform the full keyed XCBC-MAC/CMAC or SHA in one function call.
3454  *
3455  * Key shall be supplied if the underlaying algoritm is AES XCBC-MAC or CMAC.
3456  * Key shall be NULL if the underlaying algoritm is SHA.
3457  *
3458  * For XCBC-MAC, the key length must be 16. For CMAC, the key length can be
3459  * the AES key lengths supported by AES engine. For MDHA the key length argument
3460  * is ignored.
3461  *
3462  * The function is blocking.
3463  *
3464  * param base CAAM peripheral base address
3465  * param handle Handle used for this request.
3466  * param algo Underlaying algorithm to use for hash computation.
3467  * param input Input data
3468  * param inputSize Size of input data in bytes
3469  * param key Input key (NULL if underlaying algorithm is SHA)
3470  * param keySize Size of input key in bytes
3471  * param[out] output Output hash data
3472  * param[out] outputSize Output parameter storing the size of the output hash in bytes
3473  * return Status of the one call hash operation.
3474  */
CAAM_HASH(CAAM_Type * base,caam_handle_t * handle,caam_hash_algo_t algo,const uint8_t * input,size_t inputSize,const uint8_t * key,size_t keySize,uint8_t * output,size_t * outputSize)3475 status_t CAAM_HASH(CAAM_Type *base,
3476                    caam_handle_t *handle,
3477                    caam_hash_algo_t algo,
3478                    const uint8_t *input,
3479                    size_t inputSize,
3480                    const uint8_t *key,
3481                    size_t keySize,
3482                    uint8_t *output,
3483                    size_t *outputSize)
3484 {
3485     status_t status;
3486     caam_desc_hash_t descBuf;
3487 
3488     status = CAAM_HASH_NonBlocking(base, handle, descBuf, algo, input, inputSize, key, keySize, output, outputSize);
3489     if (kStatus_Success != status)
3490     {
3491         return status;
3492     }
3493 
3494     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
3495 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
3496     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
3497     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
3498     DCACHE_InvalidateByRange((uint32_t)output, *outputSize);
3499 #endif /* CAAM_OUT_INVALIDATE */
3500     return status;
3501 }
3502 
3503 /*!
3504  * brief Create HASH on given data
3505  *
3506  * Perform the full keyed XCBC-MAC/CMAC or SHA in one function call.
3507  *
3508  * Key shall be supplied if the underlaying algoritm is AES XCBC-MAC or CMAC.
3509  * Key shall be NULL if the underlaying algoritm is SHA.
3510  *
3511  * For XCBC-MAC, the key length must be 16. For CMAC, the key length can be
3512  * the AES key lengths supported by AES engine. For MDHA the key length argument
3513  * is ignored.
3514  *
3515  * The function is non-blocking. The request is scheduled at CAAM.
3516  *
3517  * param base CAAM peripheral base address
3518  * param handle Handle used for this request.
3519  * param[out] descriptor Memory for the CAAM descriptor.
3520  * param algo Underlaying algorithm to use for hash computation.
3521  * param input Input data
3522  * param inputSize Size of input data in bytes
3523  * param key Input key (NULL if underlaying algorithm is SHA)
3524  * param keySize Size of input key in bytes
3525  * param[out] output Output hash data
3526  * param[out] outputSize Output parameter storing the size of the output hash in bytes
3527  * return Status of the one call hash operation.
3528  */
CAAM_HASH_NonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_hash_t descriptor,caam_hash_algo_t algo,const uint8_t * input,size_t inputSize,const uint8_t * key,size_t keySize,uint8_t * output,size_t * outputSize)3529 status_t CAAM_HASH_NonBlocking(CAAM_Type *base,
3530                                caam_handle_t *handle,
3531                                caam_desc_hash_t descriptor,
3532                                caam_hash_algo_t algo,
3533                                const uint8_t *input,
3534                                size_t inputSize,
3535                                const uint8_t *key,
3536                                size_t keySize,
3537                                uint8_t *output,
3538                                size_t *outputSize)
3539 {
3540     status_t status;
3541     caam_algorithm_state_t algState;
3542     caam_hash_internal_sgt_t sgt;
3543 
3544     (void)memset(&sgt, 0, sizeof(sgt));
3545 
3546     algState     = kCAAM_AlgStateInitFinal;
3547     uint32_t num = caam_hash_sgt_insert(NULL,             /* no ctxInternal data to pre-pend before input data chunk */
3548                                         input, inputSize, /* data and size in bytes */
3549                                         NULL, /* all data is processed during kCAAM_AlgStateInitFinal, nothing remain */
3550                                         algState, sgt, kCAAM_HashSgtEntryLast); /* sgt table, entry 0 word 0 */
3551 
3552     /* schedule the request at CAAM */
3553     status = caam_hash_schedule_input_data(base, handle, algo, sgt, num, kCAAM_HashSgtInternal, algState, descriptor,
3554                                            outputSize, output, NULL, (uint32_t)key, keySize);
3555     return status;
3556 }
3557 
3558 /*******************************************************************************
3559  * HMAC
3560  ******************************************************************************/
3561 
3562 /*!
3563  * brief Initialize HMAC context
3564  *
3565  * This function initializes the HMAC.
3566  *
3567  * For XCBC-MAC, the key length must be 16. For CMAC, the key length can be
3568  * the AES key lengths supported by AES engine. For MDHA the key length argument
3569  * is ignored.
3570  *
3571  * This functions is used to initialize the context for both blocking and non-blocking
3572  * CAAM_HMAC API.
3573  *
3574  * param base CAAM peripheral base address
3575  * param handle Handle used for this request.
3576  * param[out] ctx Output HMAC context
3577  * param algo Underlaying algorithm to use for HMAC computation.
3578  * param key Input key
3579  * param keySize Size of input key in bytes
3580  * return Status of initialization
3581  */
CAAM_HMAC_Init(CAAM_Type * base,caam_handle_t * handle,caam_hash_ctx_t * ctx,caam_hash_algo_t algo,const uint8_t * key,size_t keySize)3582 status_t CAAM_HMAC_Init(CAAM_Type *base,
3583                         caam_handle_t *handle,
3584                         caam_hash_ctx_t *ctx,
3585                         caam_hash_algo_t algo,
3586                         const uint8_t *key,
3587                         size_t keySize)
3588 {
3589     return CAAM_HASH_Init(base, handle, ctx, algo, key, keySize);
3590 }
3591 
3592 /*!
3593  * brief Create Message Authentication Code (MAC) on given data
3594  *
3595  * Perform the full keyed XCBC-MAC/CMAC, or HMAC-SHA in one function call.
3596  *
3597  * Key shall be supplied if the underlaying algoritm is AES XCBC-MAC, CMAC, or SHA HMAC.
3598  *
3599  * For XCBC-MAC, the key length must be 16. For CMAC, the key length can be
3600  * the AES key lengths supported by AES engine. For HMAC, the key can have
3601  * any size.
3602  *
3603  * The function is blocking.
3604  *
3605  * param base CAAM peripheral base address
3606  * param handle Handle used for this request.
3607  * param algo Underlaying algorithm to use for MAC computation.
3608  * param input Input data
3609  * param inputSize Size of input data in bytes
3610  * param key Input key
3611  * param keySize Size of input key in bytes
3612  * param[out] output Output MAC data
3613  * param[out] outputSize Output parameter storing the size of the output MAC in bytes
3614  * return Status of the one call hash operation.
3615  */
CAAM_HMAC(CAAM_Type * base,caam_handle_t * handle,caam_hash_algo_t algo,const uint8_t * input,size_t inputSize,const uint8_t * key,size_t keySize,uint8_t * output,size_t * outputSize)3616 status_t CAAM_HMAC(CAAM_Type *base,
3617                    caam_handle_t *handle,
3618                    caam_hash_algo_t algo,
3619                    const uint8_t *input,
3620                    size_t inputSize,
3621                    const uint8_t *key,
3622                    size_t keySize,
3623                    uint8_t *output,
3624                    size_t *outputSize)
3625 {
3626     status_t status;
3627     /* Dummy HASH context for input checking */
3628     caam_hash_ctx_t ctxDummy;
3629 
3630     if (!caam_hash_alg_is_hmac(algo))
3631     {
3632         /* Not an HMAC algorithm */
3633         return kStatus_InvalidArgument;
3634     }
3635 
3636     status = caam_hash_check_input_args(base, &ctxDummy, algo, key, keySize);
3637     if (kStatus_Success != status)
3638     {
3639         return status;
3640     }
3641 
3642     /* Make space for the largest possible key size */
3643     uint8_t updatedKey[CAAM_SHA_BLOCK_SIZE] = {0};
3644     size_t updatedKeySize                   = 0;
3645 
3646     (void)memset(updatedKey, 0, sizeof(updatedKey));
3647 
3648     status = hmac_prehash_key(base, handle, algo, key, keySize, updatedKey, &updatedKeySize);
3649     if (kStatus_Success != status)
3650     {
3651         return status;
3652     }
3653 
3654     status = CAAM_HASH(base, handle, algo, input, inputSize, updatedKey, updatedKeySize, output, outputSize);
3655     return status;
3656 }
3657 
3658 /*!
3659  * brief Create Message Authentication Code (MAC) on given data
3660  *
3661  * Perform the full keyed XCBC-MAC/CMAC, or HMAC-SHA in one function call.
3662  *
3663  * Key shall be supplied if the underlaying algoritm is AES XCBC-MAC, CMAC, or SHA HMAC.
3664  *
3665  * For XCBC-MAC, the key length must be 16. For CMAC, the key length can be
3666  * the AES key lengths supported by AES engine. For HMAC, the key can have
3667  * any size, however the function will block if the supplied key is bigger than
3668  * the block size of the underlying hashing algorithm (e.g. >64 bytes for SHA256).
3669  *
3670  * The function is not blocking with the exception of supplying large key sizes.
3671  * In that case the function will block until the large key is hashed down with the
3672  * supplied hashing algorithm (as per FIPS 198-1), after which operation is resumed
3673  * to calling non-blocking HMAC.
3674  *
3675  * param base CAAM peripheral base address
3676  * param handle Handle used for this request.
3677  * param algo Underlaying algorithm to use for MAC computation.
3678  * param input Input data
3679  * param inputSize Size of input data in bytes
3680  * param key Input key
3681  * param keySize Size of input key in bytes
3682  * param[out] output Output MAC data
3683  * param[out] outputSize Output parameter storing the size of the output MAC in bytes
3684  * return Status of the one call hash operation.
3685  */
CAAM_HMAC_NonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_hash_t descriptor,caam_hash_algo_t algo,const uint8_t * input,size_t inputSize,const uint8_t * key,size_t keySize,uint8_t * output,size_t * outputSize)3686 status_t CAAM_HMAC_NonBlocking(CAAM_Type *base,
3687                                caam_handle_t *handle,
3688                                caam_desc_hash_t descriptor,
3689                                caam_hash_algo_t algo,
3690                                const uint8_t *input,
3691                                size_t inputSize,
3692                                const uint8_t *key,
3693                                size_t keySize,
3694                                uint8_t *output,
3695                                size_t *outputSize)
3696 {
3697     status_t status;
3698     /* Dummy HASH context for input checking */
3699     caam_hash_ctx_t ctxDummy;
3700 
3701     if (!caam_hash_alg_is_hmac(algo))
3702     {
3703         /* Not an HMAC algorithm */
3704         return kStatus_InvalidArgument;
3705     }
3706 
3707     status = caam_hash_check_input_args(base, &ctxDummy, algo, key, keySize);
3708     if (kStatus_Success != status)
3709     {
3710         return status;
3711     }
3712 
3713     /* Make space for the largest possible key size */
3714     uint8_t updatedKey[CAAM_SHA_BLOCK_SIZE] = {0};
3715     size_t updatedKeySize                   = 0;
3716 
3717     (void)memset(updatedKey, 0, sizeof(updatedKey));
3718 
3719     status = hmac_prehash_key(base, handle, algo, key, keySize, updatedKey, &updatedKeySize);
3720     if (kStatus_Success != status)
3721     {
3722         return status;
3723     }
3724 
3725     status = CAAM_HASH_NonBlocking(base, handle, descriptor, algo, input, inputSize, updatedKey, updatedKeySize, output,
3726                                    outputSize);
3727     return status;
3728 }
3729 
3730 /*******************************************************************************
3731  * CRC Code static
3732  ******************************************************************************/
caam_crc_check_input_alg(caam_crc_algo_t algo)3733 static status_t caam_crc_check_input_alg(caam_crc_algo_t algo)
3734 {
3735     if ((algo != kCAAM_CrcIEEE) && (algo != kCAAM_CrciSCSI) && (algo != kCAAM_CrcCUSTPOLY))
3736     {
3737         return kStatus_InvalidArgument;
3738     }
3739     return kStatus_Success;
3740 }
3741 
caam_crc_alg_is_customcrc(caam_crc_algo_t algo)3742 static inline bool caam_crc_alg_is_customcrc(caam_crc_algo_t algo)
3743 {
3744     return (algo == kCAAM_CrcCUSTPOLY);
3745 }
3746 
caam_crc_check_input_args(CAAM_Type * base,caam_hash_ctx_t * ctx,caam_crc_algo_t algo,const uint8_t * polynomial,size_t polynomialSize)3747 static status_t caam_crc_check_input_args(
3748     CAAM_Type *base, caam_hash_ctx_t *ctx, caam_crc_algo_t algo, const uint8_t *polynomial, size_t polynomialSize)
3749 {
3750     /* Check validity of input algorithm */
3751     if (kStatus_Success != caam_crc_check_input_alg(algo))
3752     {
3753         return kStatus_InvalidArgument;
3754     }
3755 
3756     if ((NULL == ctx) || (NULL == base))
3757     {
3758         return kStatus_InvalidArgument;
3759     }
3760 
3761     if (caam_crc_alg_is_customcrc(algo))
3762     {
3763         if ((NULL == polynomial) && ((polynomialSize > 4u) || (polynomialSize < 1u)))
3764         {
3765             return kStatus_InvalidArgument;
3766         }
3767     }
3768 
3769     return kStatus_Success;
3770 }
3771 
caam_crc_check_context(caam_crc_ctx_internal_t * ctxInternal,const uint8_t * data)3772 static status_t caam_crc_check_context(caam_crc_ctx_internal_t *ctxInternal, const uint8_t *data)
3773 {
3774     if ((NULL == data) || (NULL == ctxInternal) || (NULL == ctxInternal->base) ||
3775         (kStatus_Success != caam_crc_check_input_alg(ctxInternal->algo)))
3776     {
3777         return kStatus_InvalidArgument;
3778     }
3779     return kStatus_Success;
3780 }
3781 
caam_crc_algo2mode(caam_crc_algo_t algo,uint32_t crcMode,uint32_t algState)3782 static uint32_t caam_crc_algo2mode(caam_crc_algo_t algo, uint32_t crcMode, uint32_t algState)
3783 {
3784     uint32_t modeReg = 0u;
3785 
3786     /* Set CAAM algorithm */
3787     switch (algo)
3788     {
3789         case kCAAM_CrcIEEE:
3790             modeReg = (uint32_t)kCAAM_AlgorithmCRC | (uint32_t)kCAAM_CRC_ModeIEEE802;
3791             break;
3792         case kCAAM_CrciSCSI:
3793             modeReg = (uint32_t)kCAAM_AlgorithmCRC | (uint32_t)kCAAM_CRC_ModeIETF3385;
3794             break;
3795         case kCAAM_CrcCUSTPOLY:
3796             modeReg = (uint32_t)kCAAM_AlgorithmCRC | crcMode | (uint32_t)kCAAM_CRC_ModeCUSTPOLY;
3797             break;
3798         default:
3799             /* All the cases have been listed above, the default clause should not be reached. */
3800             break;
3801     }
3802 
3803     modeReg |= algState;
3804 
3805     return modeReg;
3806 }
3807 
3808 /*!
3809  * @brief Add data chunk to SGT table. Append after uncomplete block in ctxInternal if there is any.
3810  *
3811  * @param ctxInternal uncomplete block in the crc context - to be inserted before new data chunk
3812  * @param input new data chunk to insert
3813  * @param inputSize size in bytes of new data chunk to insert
3814  * @param numRemain number of bytes that remain in the last uncomplete block
3815  * @param algState in FINALIZE or INITIALIZE/FINALIZE we add also last uncomplete block bytes
3816  * @param sgt address of the SGT
3817  * @param last last call to this function adds Final Bit
3818  */
caam_crc_sgt_insert(caam_crc_ctx_internal_t * ctxInternal,const uint8_t * input,size_t inputSize,size_t * numRemain,caam_algorithm_state_t algState,caam_sgt_entry_t * sgt,caam_hash_sgt_entry_type_t last)3819 static uint32_t caam_crc_sgt_insert(caam_crc_ctx_internal_t *ctxInternal,
3820                                     const uint8_t *input,
3821                                     size_t inputSize,
3822                                     size_t *numRemain,
3823                                     caam_algorithm_state_t algState,
3824                                     caam_sgt_entry_t *sgt,
3825                                     caam_hash_sgt_entry_type_t last)
3826 {
3827     /* configure SGT
3828      * *64 bytes multiple in kCAAM_HashInit or kCAAM_HashUpdate
3829      * *arbitrary amount of data in kCAAM_HashInitFinal or kCAAM_HashFinal
3830      * min 1 and max 2 SGT entries
3831      * 1) if there is any data in the context buffer, use it as one entry
3832      * 2) input as one entry
3833      */
3834     uint32_t numBlocks;
3835     uint32_t remain;
3836     uint32_t num;
3837     uint32_t currSgtEntry;
3838 
3839     uint32_t ctxBlksz   = (ctxInternal != NULL) ? ctxInternal->blksz : 0U;
3840     uint32_t ctxBlkAddr = (ctxInternal != NULL) ? (uint32_t)&ctxInternal->blk.b[0] : 0U;
3841 
3842     currSgtEntry = 0;
3843     numBlocks    = (inputSize + ctxBlksz) / CAAM_HASH_BLOCK_SIZE;
3844     remain       = (inputSize + ctxBlksz) % CAAM_HASH_BLOCK_SIZE;
3845 
3846     /* number of bytes for processing
3847      * only full block multiple in INITIALIZE or UPDATE
3848      * any size in INITIALIZE/FINALIZE or FINALIZE
3849      */
3850     num = (CAAM_HASH_BLOCK_SIZE * numBlocks);
3851     if ((algState == kCAAM_AlgStateInitFinal) || (algState == kCAAM_AlgStateFinal))
3852     {
3853         num += remain; /* add also uncomplete bytes from last block in one of FINALIZE states */
3854         remain = 0;
3855     }
3856     if (numRemain != NULL)
3857     {
3858         *numRemain = remain;
3859     }
3860 
3861     if ((ctxBlksz != 0U) || (0U == ctxBlksz + inputSize))
3862     {
3863         sgt[currSgtEntry].address_l = ADD_OFFSET(ctxBlkAddr);
3864         sgt[currSgtEntry].length    = ctxBlksz;
3865         if ((kCAAM_HashSgtEntryLast == last) && (0U == inputSize))
3866         {
3867             sgt[currSgtEntry].length |= 0x40000000u; /* Final SG entry */
3868         }
3869         currSgtEntry++;
3870     }
3871 
3872     if (inputSize != 0U)
3873     {
3874         /* number of bytes for processing
3875          * only full block multiple in INITIALIZE or UPDATE
3876          * any size in INITIALIZE/FINALIZE or FINALIZE
3877          */
3878         sgt[currSgtEntry].address_l = ADD_OFFSET((uint32_t)input);
3879         sgt[currSgtEntry].length    = inputSize - remain;
3880         if (kCAAM_HashSgtEntryLast == last)
3881         {
3882             sgt[currSgtEntry].length |= 0x40000000u; /* Final SG entry */
3883             sgt[currSgtEntry].offset = 0x80000000u;
3884         }
3885     }
3886     return num; /* no of bytes processed in total by these 1 or 2 SGT entries */
3887 }
3888 
3889 /*!
3890  * @brief Create job descriptor for the CRC request and schedule at CAAM job ring
3891  *
3892  *
3893  */
caam_crc_schedule_input_data(CAAM_Type * base,caam_handle_t * handle,caam_crc_algo_t algo,caam_aai_crc_alg_t crcMode,caam_sgt_entry_t * sgt,uint32_t dataSize,caam_hash_sgt_type_t sgtType,caam_algorithm_state_t algState,caam_desc_hash_t descriptor,size_t * outputSize,void * output,void * context,uint32_t polynomialAddr,uint32_t polynomialSize)3894 static status_t caam_crc_schedule_input_data(CAAM_Type *base,
3895                                              caam_handle_t *handle,
3896                                              caam_crc_algo_t algo,
3897                                              caam_aai_crc_alg_t crcMode,
3898                                              caam_sgt_entry_t *sgt,
3899                                              uint32_t dataSize,
3900                                              caam_hash_sgt_type_t sgtType,
3901                                              caam_algorithm_state_t algState,
3902                                              caam_desc_hash_t descriptor,
3903                                              size_t *outputSize,
3904                                              void *output,
3905                                              void *context,
3906                                              uint32_t polynomialAddr,
3907                                              uint32_t polynomialSize)
3908 {
3909     uint32_t descriptorSize = ARRAY_SIZE(templateHash);
3910     uint32_t algOutSize     = 4u;
3911 
3912     bool isCustomCRC = caam_crc_alg_is_customcrc(algo);
3913 
3914     /* MDHA use of the Context Register
3915         The Context Register stores the current digest and running message length. The running
3916         message length will be 8 bytes immediately following the active digest. The digest size is
3917         defined as follows:
3918  CRC: 4 bytes so caamCtxSz = 8 +4 */
3919     uint32_t caamCtxSz = 12u;
3920 
3921     (void)caam_memcpy(descriptor, templateHash, sizeof(templateHash));
3922 
3923     /* CRC is Class 2 CHA */
3924 
3925     /* add class to all commands that need it */
3926     descriptor[1] |= 0x04000000u;
3927     descriptor[3] |= 0x04000000u;
3928     descriptor[5] |= 0x04000000u;
3929     descriptor[6] |= 0x04000000u;
3930     descriptor[9] |= 0x04000000u;
3931     descriptor[11] |= 0x04000000u;
3932 
3933     /* add descriptor size */
3934     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
3935 
3936     /* kCAAM_AlgStateInit or kCAAM_AlgStateInitFinal needs to skip context load as there is no context */
3937     if ((algState == kCAAM_AlgStateInit) || (algState == kCAAM_AlgStateInitFinal))
3938     {
3939         if (!isCustomCRC)
3940         {
3941             /* HEADER can jump directly to MDHA operation */
3942             descriptor[0] |= 0x00050000U; /* JUMP to descriptor[5] */
3943         }
3944         else
3945         {
3946             /* load Polynomial, then directly to CRC operation */
3947             descriptor[1] |= (polynomialSize & DESC_KEY_SIZE_MASK);
3948             descriptor[2] = ADD_OFFSET(polynomialAddr);
3949             descriptor[3] = DESC_JUMP_2; /* JUMP to descriptor[5] */
3950         }
3951     }
3952     else
3953     {
3954         if (!isCustomCRC)
3955         {
3956             /* CRC without custom polynomial in Update state skips loading the Polynomial
3957              * HEADER can jump directly to context restore
3958              */
3959             descriptor[0] |= 0x00030000U; /* JUMP to descriptor[3] */
3960         }
3961         else
3962         {
3963             /* load Polynomial */
3964             descriptor[1] |= (polynomialSize & DESC_KEY_SIZE_MASK);
3965             descriptor[2] = ADD_OFFSET(polynomialAddr);
3966         }
3967 
3968         /* context restore */
3969         descriptor[3] |= caamCtxSz;
3970         descriptor[4] = ADD_OFFSET((uint32_t)(uint32_t *)context);
3971     }
3972 
3973     /* OPERATION:
3974      * alg MDHA
3975      * mode INITIALIZE or UPDATE or FINALIZE or INITIALIZE/FINALIZE in algState argument
3976      */
3977 
3978     /* ALGORITHM OPERATION | CLASS | alg | aai | algState */
3979     descriptor[5] |= caam_crc_algo2mode(algo, (uint32_t)crcMode, (uint32_t)algState << 2);
3980 
3981     /* configure SGT */
3982     descriptor[8] = dataSize;
3983     if (kCAAM_HashSgtInternal == sgtType)
3984     {
3985         descriptor[7] = ADD_OFFSET(
3986             (uint32_t)&descriptor[(uint32_t)kCAAM_HashDescriptorSgtIdx]); /* use SGT embedded in the job descriptor */
3987         (void)caam_memcpy(&descriptor[(uint32_t)kCAAM_HashDescriptorSgtIdx], (const uint32_t *)(uintptr_t)sgt,
3988                           sizeof(caam_hash_internal_sgt_t));
3989     }
3990     else
3991     {
3992         descriptor[7] = ADD_OFFSET((uint32_t)sgt);
3993     }
3994 
3995     /* save context: context switch init or running or result */
3996     if ((kCAAM_AlgStateFinal == algState) || (kCAAM_AlgStateInitFinal == algState))
3997     {
3998         if (outputSize != NULL)
3999         {
4000             if (algOutSize < *outputSize)
4001             {
4002                 *outputSize = algOutSize;
4003             }
4004             else
4005             {
4006                 algOutSize = *outputSize;
4007             }
4008         }
4009         caamCtxSz = algOutSize;
4010     }
4011     else
4012     {
4013         caamCtxSz = 12u;
4014     }
4015     descriptor[9] |= caamCtxSz;
4016     if ((kCAAM_AlgStateFinal == algState) || (kCAAM_AlgStateInitFinal == algState))
4017     {
4018         /* final result write to output */
4019         descriptor[10] = ADD_OFFSET((uint32_t)(uint32_t *)output);
4020     }
4021     else
4022     {
4023         /* context switch write to ctxInternal */
4024         descriptor[10] = ADD_OFFSET((uint32_t)(uint32_t *)context);
4025     }
4026 
4027     descriptor[11] = ADD_OFFSET(descriptor[13]); /* always halt with status 0x0 (normal) */
4028 
4029     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
4030 }
4031 
4032 /*!
4033  * @brief Add uncomplete block (ctxInternal), then append new data (to current crc calculation).
4034  *
4035  *
4036  */
caam_crc_append_data(caam_crc_ctx_internal_t * ctxInternal,const uint8_t * input,size_t inputSize,caam_algorithm_state_t algState,caam_desc_hash_t descriptor,size_t * numRemain,void * output,size_t * outputSize)4037 static status_t caam_crc_append_data(caam_crc_ctx_internal_t *ctxInternal,
4038                                      const uint8_t *input,
4039                                      size_t inputSize,
4040                                      caam_algorithm_state_t algState,
4041                                      caam_desc_hash_t descriptor,
4042                                      size_t *numRemain,
4043                                      void *output,
4044                                      size_t *outputSize)
4045 {
4046     caam_hash_internal_sgt_t sgt;
4047     (void)memset(&sgt, 0, sizeof(sgt));
4048     size_t num = caam_crc_sgt_insert(ctxInternal, input, inputSize, numRemain, algState, sgt, kCAAM_HashSgtEntryLast);
4049     return caam_crc_schedule_input_data(ctxInternal->base, ctxInternal->handle, ctxInternal->algo, ctxInternal->crcmode,
4050                                         sgt, num, kCAAM_HashSgtInternal, algState, descriptor, outputSize, output,
4051                                         &ctxInternal->word[0], (uint32_t)&ctxInternal->word[kCAAM_HashCtxKeyStartIdx],
4052                                         ctxInternal->word[kCAAM_HashCtxKeySize]);
4053 }
4054 
4055 /*******************************************************************************
4056  * CRC Code public
4057  ******************************************************************************/
4058 
4059 /*!
4060  * brief Initialize CRC context
4061  *
4062  * This function initializes the CRC context.
4063  * polynomial shall be supplied if the underlaying algoritm is kCAAM_CrcCUSTPOLY.
4064  * polynomial shall be NULL if the underlaying algoritm is kCAAM_CrcIEEE or kCAAM_CrciSCSI.
4065  *
4066  * This functions is used to initialize the context for CAAM_CRC API
4067  *
4068  * param base CAAM peripheral base address
4069  * param handle Handle used for this request.
4070  * param[out] ctx Output crc context
4071  * param algo Underlaying algorithm to use for CRC computation
4072  * param polynomial CRC polynomial (NULL if underlaying algorithm is kCAAM_CrcIEEE or kCAAM_CrciSCSI)
4073  * param polynomialSize Size of polynomial in bytes (0u if underlaying algorithm is kCAAM_CrcIEEE or kCAAM_CrciSCSI)
4074  * param mode Specify how CRC engine manipulates its input and output data
4075  * return Status of initialization
4076  */
CAAM_CRC_Init(CAAM_Type * base,caam_handle_t * handle,caam_crc_ctx_t * ctx,caam_crc_algo_t algo,const uint8_t * polynomial,size_t polynomialSize,caam_aai_crc_alg_t mode)4077 status_t CAAM_CRC_Init(CAAM_Type *base,
4078                        caam_handle_t *handle,
4079                        caam_crc_ctx_t *ctx,
4080                        caam_crc_algo_t algo,
4081                        const uint8_t *polynomial,
4082                        size_t polynomialSize,
4083                        caam_aai_crc_alg_t mode)
4084 {
4085     status_t ret = kStatus_Fail;
4086     caam_crc_ctx_internal_t *ctxInternal;
4087     uint32_t i;
4088 
4089     ret = caam_crc_check_input_args(base, ctx, algo, polynomial, polynomialSize);
4090     if (ret != kStatus_Success)
4091     {
4092         return ret;
4093     }
4094 
4095     /* set algorithm in context struct for later use */
4096     ctxInternal          = (caam_crc_ctx_internal_t *)(uint32_t)ctx;
4097     ctxInternal->algo    = algo;
4098     ctxInternal->crcmode = mode;
4099     for (i = 0U; i < (uint32_t)kCAAM_HashCtxNumWords; i++)
4100     {
4101         ctxInternal->word[i] = 0u;
4102     }
4103 
4104     /* Steps required only using CRC engine with custom polynomial */
4105     if (caam_crc_alg_is_customcrc(algo))
4106     {
4107         /* store polynomial and polynomial length in context struct for later use */
4108         ctxInternal->word[kCAAM_HashCtxKeySize] = polynomialSize;
4109         (void)caam_memcpy(&ctxInternal->word[kCAAM_HashCtxKeyStartIdx], (const uint32_t *)(uintptr_t)polynomial,
4110                           polynomialSize);
4111     }
4112 
4113     ctxInternal->blksz = 0u;
4114     for (i = 0; i < ARRAY_SIZE(ctxInternal->blk.w); i++)
4115     {
4116         ctxInternal->blk.w[i] = 0u;
4117     }
4118     ctxInternal->fsm_state = kCAAM_HashInit;
4119     ctxInternal->base      = base;
4120     ctxInternal->handle    = handle;
4121 
4122     return kStatus_Success;
4123 }
4124 
4125 /*!
4126  * brief Add data to current CRC
4127  *
4128  * Add data to current CRC. This can be called repeatedly. The functions blocks. If it returns kStatus_Success, the
4129  * running CRC has been updated (CAAM has processed the input data), so the memory at input pointer can be released back
4130  * to system. The context is updated with the running CRC and with all necessary information to support possible context
4131  * switch.
4132  *
4133  * param[in,out] ctx CRC context
4134  * param input Input data
4135  * param inputSize Size of input data in bytes
4136  * return Status of the crc update operation
4137  */
CAAM_CRC_Update(caam_crc_ctx_t * ctx,const uint8_t * input,size_t inputSize)4138 status_t CAAM_CRC_Update(caam_crc_ctx_t *ctx, const uint8_t *input, size_t inputSize)
4139 {
4140     caam_desc_hash_t descBuf;
4141     status_t status;
4142     caam_crc_ctx_internal_t *ctxInternal;
4143     bool isUpdateState;
4144     size_t numRemain = 0;
4145 
4146     /* compile time check for the correct structure size */
4147     BUILD_ASSURE(sizeof(caam_crc_ctx_internal_t) <= sizeof(caam_crc_ctx_t), caam_crc_ctx_internal_t_size);
4148 
4149     if (0U == inputSize)
4150     {
4151         return kStatus_Success;
4152     }
4153 
4154     /* we do caam_memcpy() input stream, up to buffer size
4155      * of 64 bytes. then if I have more I have to
4156      * 1) load Class 2 context
4157      * 2) schedule CAAM job with INITIALIZE or UPDATE mode (simple if only 64 bytes block is processed. SG table for 2
4158      * and more)
4159      * 3) in step 2 process all full 64 bytes blocks
4160      * 4) copy last not-full buffer size data to buffer.
4161      * 5) save Class 2 context
4162      */
4163     ctxInternal = (caam_crc_ctx_internal_t *)(uint32_t)ctx;
4164     status      = caam_crc_check_context(ctxInternal, input);
4165     if (kStatus_Success != status)
4166     {
4167         return status;
4168     }
4169 
4170     /* if we are still less than 64 bytes, keep only in context */
4171     if ((ctxInternal->blksz + inputSize) <= CAAM_HASH_BLOCK_SIZE)
4172     {
4173         (void)caam_memcpy((&ctxInternal->blk.b[0]) + ctxInternal->blksz, input, inputSize);
4174         ctxInternal->blksz += inputSize;
4175         return status;
4176     }
4177     else
4178     {
4179         isUpdateState = ctxInternal->fsm_state == kCAAM_HashUpdate;
4180         if (!isUpdateState)
4181         {
4182             /* Step 2: schedule CAAM job in INITIALIZE mode.
4183              */
4184             ctxInternal->fsm_state = kCAAM_HashUpdate;
4185             /* skip load context as there is no running context yet. */
4186             status = caam_crc_append_data(ctxInternal, input, inputSize, kCAAM_AlgStateInit, descBuf, &numRemain, NULL,
4187                                           NULL);
4188         }
4189     }
4190 
4191     if (kStatus_Success != status)
4192     {
4193         return status;
4194     }
4195 
4196     if (isUpdateState)
4197     {
4198         /* Step 2: schedule CAAM job in UPDATE mode.
4199          */
4200 
4201         /* process input data and save CAAM context to context structure */
4202         status =
4203             caam_crc_append_data(ctxInternal, input, inputSize, kCAAM_AlgStateUpdate, descBuf, &numRemain, NULL, NULL);
4204         if (status != kStatus_Success)
4205         {
4206             return status;
4207         }
4208     }
4209 
4210     /* blocking wait */
4211     status = CAAM_Wait(ctxInternal->base, ctxInternal->handle, descBuf, kCAAM_Blocking);
4212     if (status != kStatus_Success)
4213     {
4214         return status;
4215     }
4216 
4217 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
4218     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
4219     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
4220     DCACHE_InvalidateByRange((uint32_t)&ctxInternal->word[0u], (uint32_t)kCAAM_HashCtxNumWords * sizeof(uint32_t));
4221 #endif /* CAAM_OUT_INVALIDATE */
4222 
4223     /* after job is complete, copy numRemain bytes at the end of the input[] to the context */
4224     (void)caam_memcpy((&ctxInternal->blk.b[0]), input + inputSize - numRemain, numRemain);
4225     ctxInternal->blksz = numRemain;
4226 
4227     return status;
4228 }
4229 
4230 /*!
4231  * brief Finalize CRC
4232  *
4233  * Outputs the final CRC (computed by CAAM_CRC_Update()) and erases the context.
4234  *
4235  * param[in,out] ctx Input crc context
4236  * param[out] output Output crc data
4237  * param[out] outputSize Output parameter storing the size of the output crc in bytes
4238  * return Status of the crc finish operation
4239  */
CAAM_CRC_Finish(caam_crc_ctx_t * ctx,uint8_t * output,size_t * outputSize)4240 status_t CAAM_CRC_Finish(caam_crc_ctx_t *ctx, uint8_t *output, size_t *outputSize)
4241 {
4242     status_t status;
4243     caam_crc_ctx_internal_t *ctxInternal;
4244     caam_desc_hash_t descBuf;
4245     caam_algorithm_state_t algState;
4246 
4247     /* runtime input validity check */
4248     ctxInternal = (caam_crc_ctx_internal_t *)(uint32_t)ctx;
4249     status      = caam_crc_check_context(ctxInternal, output);
4250     if (kStatus_Success != status)
4251     {
4252         return status;
4253     }
4254 
4255     /* determine algorithm state to configure
4256      * based on prior processing.
4257      * If at least one full block has been processed during HASH_Update() then the state in ctxInternal
4258      * will be set to kCAAM_HashUpdate and so we will configure FINALIZE algorithm state.
4259      * Otherwise there is data only in the ctxInternal that we can process in INITIALIZE/FINALIZE.
4260      */
4261     if (ctxInternal->fsm_state == kCAAM_HashInit)
4262     {
4263         algState = kCAAM_AlgStateInitFinal;
4264     }
4265     else
4266     {
4267         algState = kCAAM_AlgStateFinal;
4268     }
4269 
4270     status = caam_crc_append_data(ctxInternal, NULL,
4271                                   0, /* we process only blksz bytes in ctxInternal, so giving NULL and zero size here */
4272                                   algState, descBuf, NULL, output, outputSize);
4273     if (kStatus_Success != status)
4274     {
4275         return status;
4276     }
4277 
4278     /* blocking wait */
4279     status = CAAM_Wait(ctxInternal->base, ctxInternal->handle, descBuf, kCAAM_Blocking);
4280 
4281 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
4282     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
4283     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
4284     DCACHE_InvalidateByRange((uint32_t)output, 32u);
4285 #endif /* CAAM_OUT_INVALIDATE */
4286 
4287     (void)memset(ctx, 0, sizeof(caam_crc_ctx_t));
4288     return status;
4289 }
4290 
4291 /*!
4292  * brief Create CRC on given data
4293  *
4294  * Perform CRC in one function call.
4295  *
4296  * Polynomial shall be supplied if underlaying algorithm is kCAAM_CrcCUSTPOLY.
4297  * Polynomial shall be NULL if underlaying algorithm is kCAAM_CrcIEEE or kCAAM_CrciSCSI.
4298  *
4299  *
4300  * The function is blocking.
4301  *
4302  * param base CAAM peripheral base address
4303  * param handle Handle used for this request.
4304  * param algo Underlaying algorithm to use for crc computation.
4305  * param mode Specify how CRC engine manipulates its input and output data.
4306  * param input Input data
4307  * param inputSize Size of input data in bytes
4308  * param polynomial CRC polynomial (NULL if underlaying algorithm is kCAAM_CrcIEEE or kCAAM_CrciSCSI)
4309  * param polynomialSize Size of input polynomial in bytes (0U if underlaying algorithm is kCAAM_CrcIEEE or
4310  * kCAAM_CrciSCSI) param[out] output Output crc data param[out] outputSize Output parameter storing the size of the
4311  * output crc in bytes return Status of the one call crc operation.
4312  */
CAAM_CRC(CAAM_Type * base,caam_handle_t * handle,caam_crc_algo_t algo,caam_aai_crc_alg_t mode,const uint8_t * input,size_t inputSize,const uint8_t * polynomial,size_t polynomialSize,uint8_t * output,size_t * outputSize)4313 status_t CAAM_CRC(CAAM_Type *base,
4314                   caam_handle_t *handle,
4315                   caam_crc_algo_t algo,
4316                   caam_aai_crc_alg_t mode,
4317                   const uint8_t *input,
4318                   size_t inputSize,
4319                   const uint8_t *polynomial,
4320                   size_t polynomialSize,
4321                   uint8_t *output,
4322                   size_t *outputSize)
4323 {
4324     status_t status;
4325     caam_desc_hash_t descBuf;
4326 
4327     status = CAAM_CRC_NonBlocking(base, handle, descBuf, algo, mode, input, inputSize, polynomial, polynomialSize,
4328                                   output, outputSize);
4329     if (kStatus_Success != status)
4330     {
4331         return status;
4332     }
4333 
4334     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
4335 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
4336     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
4337     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
4338     DCACHE_InvalidateByRange((uint32_t)output, *outputSize);
4339 #endif /* CAAM_OUT_INVALIDATE */
4340     return status;
4341 }
4342 
4343 /*!
4344  * brief Create CRC on given data
4345  *
4346  * Perform CRC in one function call.
4347  *
4348  * Polynomial shall be supplied if underlaying algorithm is kCAAM_CrcCUSTPOLY.
4349  * Polynomial shall be NULL if underlaying algorithm is kCAAM_CrcIEEE or kCAAM_CrciSCSI.
4350  *
4351  * The function is non-blocking. The request is scheduled at CAAM.
4352  *
4353  * param base CAAM peripheral base address
4354  * param handle Handle used for this request.
4355  * param[out] descriptor Memory for the CAAM descriptor.
4356  * param algo Underlaying algorithm to use for crc computation.
4357  * param mode Specify how CRC engine manipulates its input and output data.
4358  * param input Input data
4359  * param inputSize Size of input data in bytes
4360  * param polynomial CRC polynomial (NULL if underlaying algorithm is kCAAM_CrcIEEE or kCAAM_CrciSCSI)
4361  * param polynomialSize Size of polynomial in bytes (0U if underlaying algorithm is kCAAM_CrcIEEE or kCAAM_CrciSCSI)
4362  * param[out] output Output crc data
4363  * param[out] outputSize Output parameter storing the size of the output crc in bytes
4364  * return Status of the one call crc operation.
4365  */
CAAM_CRC_NonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_hash_t descriptor,caam_crc_algo_t algo,caam_aai_crc_alg_t mode,const uint8_t * input,size_t inputSize,const uint8_t * polynomial,size_t polynomialSize,uint8_t * output,size_t * outputSize)4366 status_t CAAM_CRC_NonBlocking(CAAM_Type *base,
4367                               caam_handle_t *handle,
4368                               caam_desc_hash_t descriptor,
4369                               caam_crc_algo_t algo,
4370                               caam_aai_crc_alg_t mode,
4371                               const uint8_t *input,
4372                               size_t inputSize,
4373                               const uint8_t *polynomial,
4374                               size_t polynomialSize,
4375                               uint8_t *output,
4376                               size_t *outputSize)
4377 {
4378     status_t status;
4379     caam_algorithm_state_t algState;
4380     caam_hash_internal_sgt_t sgt;
4381 
4382     (void)memset(&sgt, 0, sizeof(sgt));
4383 
4384     algState     = kCAAM_AlgStateInitFinal;
4385     uint32_t num = caam_hash_sgt_insert(NULL,             /* no ctxInternal data to pre-pend before input data chunk */
4386                                         input, inputSize, /* data and size in bytes */
4387                                         NULL, /* all data is processed during kCAAM_AlgStateInitFinal, nothing remain */
4388                                         algState, sgt, kCAAM_HashSgtEntryLast); /* sgt table, entry 0 word 0 */
4389 
4390     /* schedule the request at CAAM */
4391     status = caam_crc_schedule_input_data(base, handle, algo, mode, sgt, num, kCAAM_HashSgtInternal, algState,
4392                                           descriptor, outputSize, output, NULL, (uint32_t)polynomial, polynomialSize);
4393     return status;
4394 }
4395 /*******************************************************************************
4396  * RNG Code public
4397  ******************************************************************************/
4398 
4399 /*!
4400  * brief Initializes user configuration structure to default.
4401  *
4402  * This function initializes the configure structure to default value. the default
4403  * value are:
4404  * code
4405  *     config->autoReseedInterval = 0;
4406  *     config->personalString = NULL;
4407  * endcode
4408  *
4409  * param config   User configuration structure.
4410  * return status of the request
4411  */
CAAM_RNG_GetDefaultConfig(caam_rng_config_t * config)4412 status_t CAAM_RNG_GetDefaultConfig(caam_rng_config_t *config)
4413 {
4414     status_t status;
4415 
4416     if (config != NULL)
4417     {
4418         config->autoReseedInterval = 0; /* zero means hardware default of 10.000.000 will be used */
4419         config->personalString     = NULL;
4420         status                     = kStatus_Success;
4421     }
4422     else
4423     {
4424         status = kStatus_InvalidArgument;
4425     }
4426 
4427     return status;
4428 }
4429 
4430 /*!
4431  * brief Instantiate the CAAM RNG state handle
4432  *
4433  * This function instantiates CAAM RNG state handle.
4434  * The function is blocking and returns after CAAM has processed the request.
4435  *
4436  * param base CAAM peripheral base address
4437  * param handle CAAM jobRing used for this request
4438  * param stateHandle RNG state handle to instantiate
4439  * param config Pointer to configuration structure.
4440  * return Status of the request
4441  */
CAAM_RNG_Init(CAAM_Type * base,caam_handle_t * handle,caam_rng_state_handle_t stateHandle,const caam_rng_config_t * config)4442 status_t CAAM_RNG_Init(CAAM_Type *base,
4443                        caam_handle_t *handle,
4444                        caam_rng_state_handle_t stateHandle,
4445                        const caam_rng_config_t *config)
4446 {
4447     status_t status;
4448 
4449     /* create job descriptor */
4450     rngInstantiate[0]              = 0xB0800006u;
4451     rngInstantiate[1]              = 0x12200020u; /* LOAD 32 bytes of  to Class 1 Context Register. Offset 0 bytes. */
4452     rngInstantiate[2]              = (uint32_t)ADD_OFFSET((uint32_t)config->personalString);
4453     rngInstantiate[3]              = 0x12820004u; /* LOAD Immediate 4 bytes to Class 1 Data Size Register. */
4454     rngInstantiate[4]              = config->autoReseedInterval; /* value for the Class 1 Data Size Register */
4455     rngInstantiate[5]              = 0x82500006u;                /* RNG instantiate state handle:
4456                                                                   *   TST=0 for normal non-deterministic mode
4457                                                                   *   PR=1 for prediction resistance
4458                                                                   */
4459 
4460     if (kCAAM_RngStateHandle1 == stateHandle)
4461     {
4462         rngInstantiate[5] |= 1u << 4;
4463     }
4464 
4465     /* default auto reseed interval */
4466     if (config->autoReseedInterval == 0U)
4467     {
4468         rngInstantiate[3] = DESC_JUMP_2; /* jump to current index + 2 (=5) */
4469     }
4470 
4471     /* optional personalization string present */
4472     if ((config->personalString) != NULL)
4473     {
4474         rngInstantiate[5] |= (uint32_t)1u << 10; /* set PS bit in ALG OPERATION (AS=01 Instantiate) */
4475     }
4476     else
4477     {
4478         rngInstantiate[1] = DESC_JUMP_2; /* jump to current index + 2 (=3) */
4479     }
4480 
4481     /* schedule the job and block wait for result */
4482     do
4483     {
4484         status = caam_in_job_ring_add(base, handle->jobRing, &rngInstantiate[0]);
4485     } while (status != kStatus_Success);
4486 
4487     status = CAAM_Wait(base, handle, &rngInstantiate[0], kCAAM_Blocking);
4488 
4489     return status;
4490 }
4491 
4492 /*!
4493  * brief Uninstantiate the CAAM RNG state handle
4494  *
4495  * This function uninstantiates CAAM RNG state handle.
4496  * The function is blocking and returns after CAAM has processed the request.
4497  *
4498  * param base CAAM peripheral base address
4499  * param handle jobRing used for this request.
4500  * param stateHandle RNG state handle to uninstantiate
4501  * return Status of the request
4502  */
CAAM_RNG_Deinit(CAAM_Type * base,caam_handle_t * handle,caam_rng_state_handle_t stateHandle)4503 status_t CAAM_RNG_Deinit(CAAM_Type *base, caam_handle_t *handle, caam_rng_state_handle_t stateHandle)
4504 {
4505     status_t status;
4506 
4507     /* create job descriptor */
4508     caam_desc_rng_t rngUninstantiate = {0};
4509     rngUninstantiate[0]              = 0xB0800002u; /* HEADER */
4510     rngUninstantiate[1] = 0x8250000Cu; /* ALG OPERATION: RNG uninstantiate state handle (AS=11 Uninstantiate) */
4511 
4512     if (kCAAM_RngStateHandle1 == stateHandle)
4513     {
4514         rngUninstantiate[1] |= 1u << 4;
4515     }
4516 
4517     /* schedule the job and block wait for result */
4518     do
4519     {
4520         status = caam_in_job_ring_add(base, handle->jobRing, &rngUninstantiate[0]);
4521     } while (status != kStatus_Success);
4522 
4523     status = CAAM_Wait(base, handle, &rngUninstantiate[0], kCAAM_Blocking);
4524 
4525     return status;
4526 }
4527 
4528 /*!
4529  * brief Generate Secure Key
4530  *
4531  * This function generates random data writes it to Secure Key registers.
4532  * The function is blocking and returns after CAAM has processed the request.
4533  * RNG state handle 0 is always used.
4534  *
4535  * param base CAAM peripheral base address
4536  * param handle jobRing used for this request
4537  * param additionalEntropy NULL or Pointer to optional 256-bit additional entropy.
4538  * return Status of the request
4539  */
CAAM_RNG_GenerateSecureKey(CAAM_Type * base,caam_handle_t * handle,caam_rng_generic256_t additionalEntropy)4540 status_t CAAM_RNG_GenerateSecureKey(CAAM_Type *base, caam_handle_t *handle, caam_rng_generic256_t additionalEntropy)
4541 {
4542     status_t status;
4543 
4544     /* create job descriptor */
4545     rngGenSeckey[0]              = 0xB0800004u; /* HEADER */
4546     rngGenSeckey[1]              = 0x12200020u; /* LOAD 32 bytes of  to Class 1 Context Register. Offset 0 bytes. */
4547     rngGenSeckey[2]              = ADD_OFFSET((uint32_t)additionalEntropy);
4548     rngGenSeckey[3]              = 0x82501000u; /* set SK bit in ALG OPERATION (AS=00 Generate) */
4549 
4550     /* optional additional input included */
4551     if ((additionalEntropy) != NULL)
4552     {
4553         rngGenSeckey[3] |= (uint32_t)1u << 11; /* set AI bit in ALG OPERATION */
4554     }
4555     else
4556     {
4557         rngGenSeckey[1] = DESC_JUMP_2; /* jump to current index + 2 (=3) */
4558     }
4559 
4560     /* schedule the job and block wait for result */
4561     do
4562     {
4563         status = caam_in_job_ring_add(base, handle->jobRing, &rngGenSeckey[0]);
4564     } while (status != kStatus_Success);
4565 
4566     status = CAAM_Wait(base, handle, &rngGenSeckey[0], kCAAM_Blocking);
4567     return status;
4568 }
4569 
4570 /*!
4571  * brief Reseed the CAAM RNG state handle
4572  *
4573  * This function reseeds the CAAM RNG state handle.
4574  * For a state handle in nondeterministic mode, the DRNG is seeded with 384 bits of
4575  * entropy from the TRNG and an optional 256-bit additional input from the descriptor
4576  * via the Class 1 Context Register.
4577  *
4578  * The function is blocking and returns after CAAM has processed the request.
4579  *
4580  * param base CAAM peripheral base address
4581  * param handle jobRing used for this request
4582  * param stateHandle RNG state handle to reseed
4583  * param additionalEntropy NULL or Pointer to optional 256-bit additional entropy.
4584  * return Status of the request
4585  */
CAAM_RNG_Reseed(CAAM_Type * base,caam_handle_t * handle,caam_rng_state_handle_t stateHandle,caam_rng_generic256_t additionalEntropy)4586 status_t CAAM_RNG_Reseed(CAAM_Type *base,
4587                          caam_handle_t *handle,
4588                          caam_rng_state_handle_t stateHandle,
4589                          caam_rng_generic256_t additionalEntropy)
4590 {
4591     status_t status;
4592 
4593     /* create job descriptor */
4594     caam_desc_rng_t rngReseed = {0};
4595     rngReseed[0]              = 0xB0800004u; /* HEADER */
4596     rngReseed[1]              = 0x12200020u; /* LOAD 32 bytes of  to Class 1 Context Register. Offset 0 bytes. */
4597     rngReseed[2]              = ADD_OFFSET((uint32_t)additionalEntropy);
4598     rngReseed[3]              = 0x8250000Au; /* ALG OPERATION: RNG reseed state handle (AS=10 Reseed) */
4599 
4600     /* optional additional input included */
4601     if ((additionalEntropy) != NULL)
4602     {
4603         rngReseed[3] |= (uint32_t)1u << 11; /* set AI bit in ALG OPERATION */
4604     }
4605     else
4606     {
4607         rngReseed[1] = DESC_JUMP_2; /* jump to current index + 2 (=3) */
4608     }
4609 
4610     /* select state handle */
4611     if (kCAAM_RngStateHandle1 == stateHandle)
4612     {
4613         rngReseed[3] |= 1u << 4;
4614     }
4615 
4616     /* schedule the job and block wait for result */
4617     do
4618     {
4619         status = caam_in_job_ring_add(base, handle->jobRing, &rngReseed[0]);
4620     } while (status != kStatus_Success);
4621 
4622     status = CAAM_Wait(base, handle, &rngReseed[0], kCAAM_Blocking);
4623     return status;
4624 }
4625 
4626 /*!
4627  * brief Get random data
4628  *
4629  * This function gets random data from CAAM RNG.
4630  *
4631  * The function is blocking and returns after CAAM has generated the requested data or an error occurred.
4632  *
4633  * param base CAAM peripheral base address
4634  * param handle jobRing used for this request
4635  * param stateHandle RNG state handle used to generate random data
4636  * param[out] data Pointer address used to store random data
4637  * param dataSize Size of the buffer pointed by the data parameter
4638  * param dataType Type of random data to be generated
4639  * param additionalEntropy NULL or Pointer to optional 256-bit additional entropy.
4640  * return Status of the request
4641  */
CAAM_RNG_GetRandomData(CAAM_Type * base,caam_handle_t * handle,caam_rng_state_handle_t stateHandle,uint8_t * data,size_t dataSize,caam_rng_random_type_t dataType,caam_rng_generic256_t additionalEntropy)4642 status_t CAAM_RNG_GetRandomData(CAAM_Type *base,
4643                                 caam_handle_t *handle,
4644                                 caam_rng_state_handle_t stateHandle,
4645                                 uint8_t *data,
4646                                 size_t dataSize,
4647                                 caam_rng_random_type_t dataType,
4648                                 caam_rng_generic256_t additionalEntropy)
4649 {
4650     status_t status;
4651 
4652     do
4653     {
4654         status = CAAM_RNG_GetRandomDataNonBlocking(base, handle, stateHandle, descBuf, data, dataSize, dataType,
4655                                                    additionalEntropy);
4656     } while (status == kStatus_CAAM_Again);
4657 
4658     if (kStatus_Success != status)
4659     {
4660         return status;
4661     }
4662 
4663     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
4664 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
4665     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
4666     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
4667     DCACHE_InvalidateByRange((uint32_t)data, dataSize);
4668 #endif /* CAAM_OUT_INVALIDATE */
4669     return status;
4670 }
4671 
4672 static const uint32_t templateRng[] = {
4673     /* 00 */ 0xB0800000u, /* HEADER */
4674     /* 01 */ 0x12200020u, /* LOAD 32 bytes of  to Class 1 Context Register. Offset 0 bytes. */
4675     /* 02 */ 0x00000000u, /* place: additional input address */
4676     /* 03 */ 0x12820004u, /* LOAD Class 1 Data Size Register by IMM data */
4677     /* 04 */ 0x00000000u, /* place: data size to generate */
4678     /* 05 */ 0x82500000u, /* RNG generate */
4679     /* 06 */ 0x60700000u, /* FIFO STORE message */
4680     /* 07 */ 0x00000000u, /* place: destination address */
4681     /* 08 */ 0x00000000u, /* place: destination size */
4682 };
4683 
4684 /*!
4685  * brief Request random data
4686  *
4687  * This function schedules the request for random data from CAAM RNG.
4688  * Memory at memory pointers will be accessed by CAAM shortly after this function
4689  * returns, according to actual CAAM schedule.
4690  *
4691  * param base CAAM peripheral base address
4692  * param handle RNG handle used for this request
4693  * param stateHandle RNG state handle used to generate random data
4694  * param[out] descriptor memory for CAAM commands
4695  * param[out] data Pointer address used to store random data
4696  * param dataSize Size of the buffer pointed by the data parameter, in bytes.
4697  * param dataType Type of random data to be generated.
4698  * param additionalEntropy NULL or Pointer to optional 256-bit additional entropy.
4699  * return status of the request
4700  */
CAAM_RNG_GetRandomDataNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_rng_state_handle_t stateHandle,caam_desc_rng_t descriptor,void * data,size_t dataSize,caam_rng_random_type_t dataType,caam_rng_generic256_t additionalEntropy)4701 status_t CAAM_RNG_GetRandomDataNonBlocking(CAAM_Type *base,
4702                                            caam_handle_t *handle,
4703                                            caam_rng_state_handle_t stateHandle,
4704                                            caam_desc_rng_t descriptor,
4705                                            void *data,
4706                                            size_t dataSize,
4707                                            caam_rng_random_type_t dataType,
4708                                            caam_rng_generic256_t additionalEntropy)
4709 {
4710     /* create job descriptor */
4711     BUILD_ASSURE(sizeof(templateRng) <= sizeof(caam_desc_rng_t), caam_desc_rng_t_size);
4712     uint32_t descriptorSize = ARRAY_SIZE(templateRng);
4713 
4714     (void)caam_memcpy(descriptor, templateRng, sizeof(templateRng));
4715     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
4716 
4717     /* optional additional input included */
4718     if (additionalEntropy != NULL)
4719     {
4720         descriptor[2] = ADD_OFFSET((uint32_t)additionalEntropy);
4721         descriptor[5] |= (uint32_t)1U << 11; /* set AI bit in ALG OPERATION */
4722         descriptor[5] |= (uint32_t)1U << 1;  /* set PR bit in ALG OPERATION (entropy seed) */
4723     }
4724     else
4725     {
4726         descriptor[0] |= (uint32_t)3u << 16; /* start at index 3 */
4727     }
4728 
4729     descriptor[4] = dataSize; /* Generate OPERATION */
4730     descriptor[7] = ADD_OFFSET((uint32_t)(uint32_t *)data);
4731     descriptor[8] = dataSize; /* FIFO STORE */
4732 
4733     /* select state handle */
4734     if (kCAAM_RngStateHandle1 == stateHandle)
4735     {
4736         descriptor[5] |= 1u << 4;
4737     }
4738 
4739     /* configure type of data */
4740     if (dataType == kCAAM_RngDataNonZero)
4741     {
4742         descriptor[5] |= (uint32_t)1u << 8; /* set NZB bit in ALG OPERATION */
4743     }
4744 
4745     if (dataType == kCAAM_RngDataOddParity)
4746     {
4747         descriptor[5] |= (uint32_t)1u << 9; /* set OBP bit in ALG OPERATION */
4748     }
4749 
4750     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
4751 }
4752 
4753 /*******************************************************************************
4754  * BLACK Code public
4755  ******************************************************************************/
4756 static const uint32_t templateBlack[] = {
4757     /* 00 */ 0xB0800000u, /* HEADER */
4758     /* 01 */ 0x02000000u, /* KEY command of  to Class 1 Context Register. */
4759     /* 02 */ 0x00000000u, /* place: a pointer to the key to be loaded */
4760     /* 03 */ 0x62000000u, /* FIFO STORE message */
4761     /* 04 */ 0x00000000u, /* place: destination address */
4762 };
4763 
4764 /*!
4765  * brief Construct a black key
4766  *
4767  * This function constructs a job descriptor capable of performing
4768  * a key blackening operation on a plaintext secure memory resident object.
4769  *
4770  * param base CAAM peripheral base address
4771  * param handle Handle used for this request. Specifies jobRing.
4772  * param data Pointer address used to pointed the plaintext.
4773  * param dataSize Size of the buffer pointed by the data parameter
4774  * param fifostType Type of AES-CBC or AEC-CCM to encrypt plaintext
4775  * param[out] blackdata Pointer address uses to pointed the black key
4776  * return Status of the request
4777  */
4778 
CAAM_BLACK_GetKeyBlacken(CAAM_Type * base,caam_handle_t * handle,const uint8_t * data,size_t dataSize,caam_fifost_type_t fifostType,uint8_t * blackdata)4779 status_t CAAM_BLACK_GetKeyBlacken(CAAM_Type *base,
4780                                   caam_handle_t *handle,
4781                                   const uint8_t *data,
4782                                   size_t dataSize,
4783                                   caam_fifost_type_t fifostType,
4784                                   uint8_t *blackdata)
4785 {
4786     status_t status = kStatus_Fail;
4787 
4788     caam_desc_key_black_t descriptor;
4789 
4790     /* create job descriptor */
4791     BUILD_ASSURE(sizeof(templateBlack) <= sizeof(caam_desc_key_black_t), caam_desc_key_black_t_size);
4792     uint32_t descriptorSize = ARRAY_SIZE(templateBlack);
4793 
4794     (void)caam_memcpy(descriptor, templateBlack, sizeof(templateBlack));
4795     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
4796     /* optional additional input included */
4797     descriptor[1] |= dataSize;
4798     descriptor[2] = ADD_OFFSET((uint32_t)data);
4799 
4800     descriptor[3] |= ((uint32_t)fifostType << 16) | (dataSize & DESC_PAYLOAD_SIZE_MASK);
4801     descriptor[4] = ADD_OFFSET((uint32_t)blackdata);
4802 
4803     do
4804     {
4805         status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
4806     } while (status == kStatus_CAAM_Again);
4807 
4808     if (kStatus_Success != status)
4809     {
4810         return status;
4811     }
4812 
4813     status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
4814 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
4815     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
4816     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
4817     DCACHE_InvalidateByRange((uint32_t)blackdata, dataSize);
4818 #endif /* CAAM_OUT_INVALIDATE */
4819     return status;
4820 }
4821 
4822 /*******************************************************************************
4823  * Key blob Code public
4824  ******************************************************************************/
4825 
4826 static const uint32_t templateBlob[] = {
4827     /* 00 */ 0xB0800000u, /* HEADER */
4828     /* 01 */ 0x04000000u, /* KEY command to Class 2 Context Register, 64/128bits RNG KEY. */
4829     /* 02 */ 0x00000000u, /* place: a pointer to the key to be loaded */
4830     /* 03 */ 0xF0000000u, /* SEQ IN PTR command to load plain data or key blob depending on operation */
4831     /* 04 */ 0x00000000u, /* place: a pointer to plain data/ key blob to be loaded */
4832     /* 05 */ 0xF8000000u, /* SEQ OUT PTR command to store blob datas */
4833     /* 06 */ 0x00000000u, /* place: a pointer to blob data or plain data to be stored depending on operation*/
4834     /* 07 */ 0x800D0000u, /* OPERATION:Encrypt/Decrypt BLOB  */
4835 };
4836 
4837 /*!
4838  * brief Construct a encrypted Red Blob
4839  *
4840  * This function constructs a job descriptor capable of performing
4841  * a encrypted blob operation on a plaintext object.
4842  *
4843  * param base CAAM peripheral base address
4844  * param handle Handle used for this request. Specifies jobRing.
4845  * param keyModifier Address of the random key modifier generated by RNG
4846  * param keyModifierSize Size of keyModifier buffer in bytes
4847  * param data Data adress
4848  * param dataSize Size of the buffer pointed by the data parameter
4849  * param[out] blob_data Output blob data adress
4850  * return Status of the request
4851  */
CAAM_RedBlob_Encapsule(CAAM_Type * base,caam_handle_t * handle,const uint8_t * keyModifier,size_t keyModifierSize,const uint8_t * data,size_t dataSize,uint8_t * blob_data)4852 status_t CAAM_RedBlob_Encapsule(CAAM_Type *base,
4853                                 caam_handle_t *handle,
4854                                 const uint8_t *keyModifier,
4855                                 size_t keyModifierSize,
4856                                 const uint8_t *data,
4857                                 size_t dataSize,
4858                                 uint8_t *blob_data)
4859 {
4860     status_t status = kStatus_Fail;
4861 
4862     caam_desc_gen_enc_blob_t descriptor;
4863     size_t blob_size;
4864 
4865     /* output blob will have 32 bytes key blob in beginning and 16 bytes MAC identifier at end of data blob */
4866     blob_size = 32u + dataSize + 16u;
4867 
4868     /* Key modifier size must 8 bytes long when used Secure memory or 16bytes long when General memory is used*/
4869     if ((keyModifierSize != 8u) && (keyModifierSize != 16u))
4870     {
4871         return kStatus_InvalidArgument;
4872     }
4873 
4874     /* create job descriptor */
4875     BUILD_ASSURE(sizeof(templateBlob) <= sizeof(caam_desc_gen_enc_blob_t), caam_desc_gen_enc_blob_t_size);
4876     uint32_t descriptorSize = ARRAY_SIZE(templateBlob);
4877     (void)caam_memcpy(descriptor, templateBlob, sizeof(templateBlob));
4878     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
4879 #if defined(KEYBLOB_USE_SECURE_MEMORY)
4880     descriptor[1] |= 8u;                               // KEY command to Class 2 Context Register,  64bits RNG KEY.
4881 #else
4882     descriptor[1] |= 16u;                  // KEY command to Class 2 Context Register, 128bits RNG KEY.
4883 #endif                                                 /* (KEYBLOB_USE_SECURE_MEMORY) */
4884     descriptor[2] = ADD_OFFSET((uint32_t)keyModifier); // Key modifier adress
4885     descriptor[3] |= dataSize;                         // SEQ IN PTR command to load plain data
4886     descriptor[4] = ADD_OFFSET((uint32_t)data);        // Plain data adress
4887     descriptor[5] |= blob_size;                        // SEQ OUT PTR Set outputing key blob
4888     descriptor[6] = ADD_OFFSET((uint32_t)blob_data);   // Key blob adress
4889 #if defined(KEYBLOB_USE_SECURE_MEMORY)
4890     descriptor[7] |= (7UL << 24) | SEC_MEM;            // OPERATION:Encrypt Red Blob in secure memory
4891 #else
4892     descriptor[7] |= (7UL << 24);          // OPERATION:Encrypt Red Blob in normal memory
4893 #endif                                                 /* (KEYBLOB_USE_SECURE_MEMORY) */
4894 
4895     // schedule the job and block wait for result
4896     do
4897     {
4898         status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
4899     } while (status == kStatus_CAAM_Again);
4900 
4901     if (kStatus_Success != status)
4902     {
4903         return status;
4904     }
4905 
4906     status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
4907 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
4908     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
4909     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
4910     DCACHE_InvalidateByRange((uint32_t)blob_data, blob_size);
4911 #endif /* CAAM_OUT_INVALIDATE */
4912     return status;
4913 }
4914 
4915 /*! brief Decrypt red blob
4916  *
4917  * This function constructs a job descriptor capable of performing
4918  * decrypting red blob.
4919  *
4920  * param base CAAM peripheral base address
4921  * param handle Handle used for this request. Specifies jobRing.
4922  * param keyModifier Address of the random key modifier generated by RNG
4923  * param keyModifierSize Size of keyModifier buffer in bytes
4924  * param blob_data Address of blob data
4925  * param[out] data Output data adress.
4926  * param dataSize Size of the buffer pointed by the data parameter in bytes
4927  * return Status of the request
4928  */
4929 
CAAM_RedBlob_Decapsule(CAAM_Type * base,caam_handle_t * handle,const uint8_t * keyModifier,size_t keyModifierSize,const uint8_t * blob_data,uint8_t * data,size_t dataSize)4930 status_t CAAM_RedBlob_Decapsule(CAAM_Type *base,
4931                                 caam_handle_t *handle,
4932                                 const uint8_t *keyModifier,
4933                                 size_t keyModifierSize,
4934                                 const uint8_t *blob_data,
4935                                 uint8_t *data,
4936                                 size_t dataSize)
4937 {
4938     status_t status = kStatus_Fail;
4939 
4940     size_t blob_size;
4941     caam_desc_gen_dep_blob_t descriptor;
4942 
4943     /* blob have 32 bytes key blob in beginning and 16 bytes MAC identifier at end of data blob */
4944     blob_size = 32u + dataSize + 16u;
4945 
4946     /* Key modifier size must 8 bytes long when used Secure memory or 16bytes long when General memory is used*/
4947     if ((keyModifierSize != 8u) && (keyModifierSize != 16u))
4948     {
4949         return kStatus_InvalidArgument;
4950     }
4951 
4952     /* create job descriptor */
4953 
4954     uint32_t descriptorSize = ARRAY_SIZE(templateBlob);
4955 
4956     (void)caam_memcpy(descriptor, templateBlob, sizeof(templateBlob));
4957     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
4958 #if defined(KEYBLOB_USE_SECURE_MEMORY)
4959     descriptor[1] |= 8u;                               // KEY command to Class 2 Context Register, 64bits RNG KEY.
4960 #else
4961     descriptor[1] |= 16u;                  // KEY command to Class 2 Context Register, 128bits RNG KEY.
4962 #endif                                                 /* (KEYBLOB_USE_SECURE_MEMORY) */
4963     descriptor[2] = ADD_OFFSET((uint32_t)keyModifier); // Key modifier adress
4964     descriptor[3] |= blob_size;                        // SEQ IN PTR command to load blob data
4965     descriptor[4] = ADD_OFFSET((uint32_t)blob_data);   // Key blob adress
4966     descriptor[5] |= dataSize;                         // SEQ OUT PTR command to load plain data
4967     descriptor[6] = ADD_OFFSET((uint32_t)data);        // Plain data adress
4968 #if defined(KEYBLOB_USE_SECURE_MEMORY)
4969     descriptor[7] |= (6UL << 24) | SEC_MEM;            // OPERATION:Decrypt red blob in secure memory
4970 #else
4971     descriptor[7] |= (6UL << 24);          // OPERATION:Decrypt red blob in normal memory
4972 #endif                                                 /* (KEYBLOB_USE_SECURE_MEMORY) */
4973     // schedule the job and block wait for result
4974     do
4975     {
4976         status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
4977     } while (status == kStatus_CAAM_Again);
4978 
4979     if (kStatus_Success != status)
4980     {
4981         return status;
4982     }
4983 
4984     status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
4985 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
4986     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
4987     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
4988     DCACHE_InvalidateByRange((uint32_t)data, dataSize);
4989 #endif /* CAAM_OUT_INVALIDATE */
4990     return status;
4991 }
4992 
4993 /*!
4994  * brief Construct a encrypted  Black Blob
4995  *
4996  * This function constructs a job descriptor capable of performing
4997  * a encrypted blob operation on a plaintext object.
4998  *
4999  * param base CAAM peripheral base address
5000  * param handle Handle used for this request. Specifies jobRing.
5001  * param keyModifier Address of the random key modifier generated by RNG
5002  * param keyModifierSize Size of keyModifier buffer in bytes
5003  * param data Data adress
5004  * param dataSize Size of the buffer pointed by the data parameter
5005  * param[out] blob_data Output blob data adress
5006  * param blackKeyType  Type of black key see enum caam_desc_type_t for more info
5007  * return Status of the request
5008  */
CAAM_BlackBlob_Encapsule(CAAM_Type * base,caam_handle_t * handle,const uint8_t * keyModifier,size_t keyModifierSize,const uint8_t * data,size_t dataSize,uint8_t * blob_data,caam_desc_type_t blackKeyType)5009 status_t CAAM_BlackBlob_Encapsule(CAAM_Type *base,
5010                                   caam_handle_t *handle,
5011                                   const uint8_t *keyModifier,
5012                                   size_t keyModifierSize,
5013                                   const uint8_t *data,
5014                                   size_t dataSize,
5015                                   uint8_t *blob_data,
5016                                   caam_desc_type_t blackKeyType)
5017 {
5018     status_t status = kStatus_Fail;
5019 
5020     caam_desc_gen_enc_blob_t descriptor;
5021     size_t blob_size;
5022 
5023     /* output blob will have 32 bytes key blob in beginning and 16 bytes MAC identifier at end of data blob */
5024     blob_size = 32u + dataSize + 16u;
5025 
5026     /* Key modifier size must 8 bytes long when used Secure memory or 16bytes long when General memory is used*/
5027     if ((keyModifierSize != 8u) && (keyModifierSize != 16u))
5028     {
5029         return kStatus_InvalidArgument;
5030     }
5031 
5032     /* create job descriptor */
5033     uint32_t descriptorSize = ARRAY_SIZE(templateBlob);
5034 
5035     (void)caam_memcpy(descriptor, templateBlob, sizeof(templateBlob));
5036     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
5037 #if defined(KEYBLOB_USE_SECURE_MEMORY)
5038     descriptor[1] |= 8u;                               // KEY command to Class 2 Context Register, 64bits RNG KEY.
5039 #else
5040     descriptor[1] |= 16u;                  // KEY command to Class 2 Context Register, 128bits RNG KEY.
5041 #endif                                                 /* (KEYBLOB_USE_SECURE_MEMORY) */
5042     descriptor[2] = ADD_OFFSET((uint32_t)keyModifier); // Key modifier adress
5043     descriptor[3] |= dataSize;                         // SEQ IN PTR command to load plain data
5044     descriptor[4] = ADD_OFFSET((uint32_t)data);        // Plain data adress
5045     descriptor[5] |= blob_size;                        // Key blob adress
5046     descriptor[6] = ADD_OFFSET((uint32_t)blob_data);   // Key blob adress
5047 #if defined(KEYBLOB_USE_SECURE_MEMORY)
5048     descriptor[7] |= (7UL << 24) | ((uint32_t)blackKeyType << 8) | DESC_BLACKKEY_NOMMEN |
5049                      SEC_MEM; // OPERATION:Encrypt black blob in secure memory
5050 #else
5051     descriptor[7] |= (7UL << 24) | ((uint32_t)blackKeyType << 8) |
5052                      DESC_BLACKKEY_NOMMEN; // OPERATION:Encrypt black blob in normal memory
5053 #endif                        /* (KEYBLOB_USE_SECURE_MEMORY) */
5054 
5055     // schedule the job and block wait for result
5056     do
5057     {
5058         status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
5059     } while (status == kStatus_CAAM_Again);
5060 
5061     if (kStatus_Success != status)
5062     {
5063         return status;
5064     }
5065 
5066     status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
5067 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
5068     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
5069     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
5070     DCACHE_InvalidateByRange((uint32_t)blob_data, blob_size);
5071 #endif /* CAAM_OUT_INVALIDATE */
5072     return status;
5073 }
5074 
5075 /*! brief Construct a decrypted black blob
5076  *
5077  * This function constructs a job descriptor capable of performing
5078  * decrypting black blob.
5079  *
5080  * param base CAAM peripheral base address
5081  * param handle Handle used for this request. Specifies jobRing.
5082  * param keyModifier Address of the random key modifier generated by RNG
5083  * param keyModifierSize Size of keyModifier buffer in bytes
5084  * param blob_data Address of blob data
5085  * param[out] data Output data adress.
5086  * param dataSize Size of the buffer pointed by the data parameter in bytes
5087  * param blackKeyType   Type of black key see enum caam_desc_type_t for more info
5088  * return Status of the request
5089  */
5090 
CAAM_BlackBlob_Decapsule(CAAM_Type * base,caam_handle_t * handle,const uint8_t * keyModifier,size_t keyModifierSize,const uint8_t * blob_data,uint8_t * data,size_t dataSize,caam_desc_type_t blackKeyType)5091 status_t CAAM_BlackBlob_Decapsule(CAAM_Type *base,
5092                                   caam_handle_t *handle,
5093                                   const uint8_t *keyModifier,
5094                                   size_t keyModifierSize,
5095                                   const uint8_t *blob_data,
5096                                   uint8_t *data,
5097                                   size_t dataSize,
5098                                   caam_desc_type_t blackKeyType)
5099 {
5100     status_t status = kStatus_Fail;
5101 
5102     caam_desc_gen_dep_blob_t descriptor;
5103     size_t blob_size;
5104 
5105     /* blob have 32 bytes key blob in beginning and 16 bytes MAC identifier at end of data blob */
5106     blob_size = 32u + dataSize + 16u;
5107 
5108     /* Key modifier size must 8 bytes long when used Secure memory or 16bytes long when General memory is used*/
5109     if ((keyModifierSize != 8u) && (keyModifierSize != 16u))
5110     {
5111         return kStatus_InvalidArgument;
5112     }
5113 
5114     /* create job descriptor */
5115     BUILD_ASSURE(sizeof(templateBlob) <= sizeof(caam_desc_gen_dep_blob_t), caam_desc_gen_dep_blob_t_size);
5116     uint32_t descriptorSize = ARRAY_SIZE(templateBlob);
5117 
5118     (void)caam_memcpy(descriptor, templateBlob, sizeof(templateBlob));
5119     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
5120 #if defined(KEYBLOB_USE_SECURE_MEMORY)
5121     descriptor[1] |= 8u;                               // KEY command to Class 2 Context Register, 64bits RNG KEY.
5122 #else
5123     descriptor[1] |= 16u;                  // KEY command to Class 2 Context Register, 128bits RNG KEY.
5124 #endif                                                 /* (KEYBLOB_USE_SECURE_MEMORY) */
5125     descriptor[2] = ADD_OFFSET((uint32_t)keyModifier); // Key modifier adress
5126     descriptor[3] |= blob_size;                        // SEQ IN PTR command to load blob data
5127     descriptor[4] = ADD_OFFSET((uint32_t)blob_data);   // Key blob adress
5128     descriptor[5] |= dataSize;
5129     descriptor[6] = ADD_OFFSET((uint32_t)data);        // Plain data adress
5130 #if defined(KEYBLOB_USE_SECURE_MEMORY)
5131     descriptor[7] |= (6UL << 24) | ((uint32_t)blackKeyType << 8) | DESC_BLACKKEY_NOMMEN |
5132                      SEC_MEM; // OPERATION:Decrypt black blob in secure memory
5133 #else
5134     descriptor[7] |= (6UL << 24) | ((uint32_t)blackKeyType << 8) |
5135                      DESC_BLACKKEY_NOMMEN; // OPERATION:Decrypt black blob in normal memory
5136 #endif                        /* (KEYBLOB_USE_SECURE_MEMORY) */
5137     // schedule the job and block wait for result
5138     do
5139     {
5140         status = caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
5141     } while (status == kStatus_CAAM_Again);
5142 
5143     if (kStatus_Success != status)
5144     {
5145         return status;
5146     }
5147 
5148     status = CAAM_Wait(base, handle, descriptor, kCAAM_Blocking);
5149 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
5150     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
5151     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
5152     DCACHE_InvalidateByRange((uint32_t)data, dataSize);
5153 #endif /* CAAM_OUT_INVALIDATE */
5154     return status;
5155 }
5156 
5157 /*******************************************************************************
5158  * DES Code public
5159  ******************************************************************************/
5160 static const uint32_t templateCipherDes[] = {
5161     /* 00 */ 0xB0800000u, /* HEADER */
5162     /* 01 */ 0x02800000u, /* KEY Class 1 IMM */
5163     /* 02 */ 0x00000000u, /* IMM key1 0-3 */
5164     /* 03 */ 0x00000000u, /* IMM key1 4-8 */
5165     /* 04 */ 0x00000000u, /* IMM key2 0-3 */
5166     /* 05 */ 0x00000000u, /* IMM key2 4-8 */
5167     /* 06 */ 0x00000000u, /* IMM key3 0-3 */
5168     /* 07 */ 0x00000000u, /* IMM key3 4-8 */
5169     /* 08 */ 0x12200008u, /* LOAD 8 bytes of iv to Class 1 Context Register */
5170     /* 09 */ 0x00000000u, /* place: iv address */
5171     /* 10 */ 0x22130000u, /* FIFO LOAD Message */
5172     /* 11 */ 0x00000000u, /* place: source address */
5173     /* 12 */ 0x60300000u, /* FIFO STORE Message */
5174     /* 13 */ 0x00000000u, /* place: destination address */
5175     /* 14 */ 0x82200000u, /* OPERATION: DES Decrypt, AS = zeroes, AAI = zeroes (CTR) */
5176 };
5177 
5178 /*!
5179  * brief Encrypts DES using ECB block mode.
5180  *
5181  * Encrypts DES using ECB block mode.
5182  *
5183  * param base CAAM peripheral base address
5184  * param handle Handle used for this request. Specifies jobRing.
5185  * param plaintext Input plaintext to encrypt
5186  * param[out] ciphertext Output ciphertext
5187  * param size Size of input and output data in bytes. Must be multiple of 8 bytes.
5188  * param key Input key to use for encryption
5189  * return Status from encrypt/decrypt operation
5190  */
CAAM_DES_EncryptEcb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t key[CAAM_DES_KEY_SIZE])5191 status_t CAAM_DES_EncryptEcb(CAAM_Type *base,
5192                              caam_handle_t *handle,
5193                              const uint8_t *plaintext,
5194                              uint8_t *ciphertext,
5195                              size_t size,
5196                              const uint8_t key[CAAM_DES_KEY_SIZE])
5197 {
5198     caam_desc_cipher_des_t descBuf;
5199     status_t status;
5200 
5201     status = CAAM_DES_EncryptEcbNonBlocking(base, handle, descBuf, plaintext, ciphertext, size, key);
5202     if (status != 0)
5203     {
5204         return status;
5205     }
5206     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
5207 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
5208     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
5209     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
5210     DCACHE_InvalidateByRange((uint32_t)ciphertext, size);
5211 #endif /* CAAM_OUT_INVALIDATE */
5212     return status;
5213 }
5214 
5215 /*!
5216  * brief Encrypts DES using ECB block mode.
5217  *
5218  * Encrypts DES using ECB block mode.
5219  *
5220  * param base CAAM peripheral base address
5221  * param handle Handle used for this request. Specifies jobRing.
5222  * param[out] descriptor memory for CAAM commands
5223  * param plaintext Input plaintext to encrypt
5224  * param[out] ciphertext Output ciphertext
5225  * param size Size of input and output data in bytes. Must be multiple of 8 bytes.
5226  * param key Input key to use for encryption
5227  * return Status from descriptor push
5228  */
CAAM_DES_EncryptEcbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t key[CAAM_DES_KEY_SIZE])5229 status_t CAAM_DES_EncryptEcbNonBlocking(CAAM_Type *base,
5230                                         caam_handle_t *handle,
5231                                         caam_desc_cipher_des_t descriptor,
5232                                         const uint8_t *plaintext,
5233                                         uint8_t *ciphertext,
5234                                         size_t size,
5235                                         const uint8_t key[CAAM_DES_KEY_SIZE])
5236 {
5237     BUILD_ASSURE(sizeof(caam_desc_cipher_des_t) >= sizeof(templateCipherDes), caam_desc_cipher_des_t_size);
5238     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
5239 
5240     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
5241      * Data lenght limit is 2^16 bytes = 65 536 bytes.
5242      * Note: You can still call several times instead
5243      */
5244     if (size > 0xFFFFUL)
5245     {
5246         return kStatus_CAAM_DataOverflow;
5247     }
5248 
5249     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
5250     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
5251     descriptor[1] |= CAAM_DES_KEY_SIZE;
5252     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key, CAAM_DES_KEY_SIZE);
5253     descriptor[4] = DESC_JUMP_6; /* ECB has no context, jump to currIdx+6 = 10 (FIFO LOAD) */
5254     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
5255     descriptor[11] = ADD_OFFSET((uint32_t)plaintext);
5256     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
5257     descriptor[13] = ADD_OFFSET((uint32_t)ciphertext);
5258     descriptor[14] |= 0x201u; /* add ENC bit to specify Encrypt OPERATION, AAI = 20h */
5259 
5260     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
5261 }
5262 
5263 /*!
5264  * brief Decrypts DES using ECB block mode.
5265  *
5266  * Decrypts DES using ECB block mode.
5267  *
5268  * param base CAAM peripheral base address
5269  * param handle Handle used for this request. Specifies jobRing.
5270  * param ciphertext Input ciphertext to decrypt
5271  * param[out] plaintext Output plaintext
5272  * param size Size of input and output data in bytes. Must be multiple of 8 bytes.
5273  * param key Input key to use for decryption
5274  * return Status from encrypt/decrypt operation
5275  */
CAAM_DES_DecryptEcb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t key[CAAM_DES_KEY_SIZE])5276 status_t CAAM_DES_DecryptEcb(CAAM_Type *base,
5277                              caam_handle_t *handle,
5278                              const uint8_t *ciphertext,
5279                              uint8_t *plaintext,
5280                              size_t size,
5281                              const uint8_t key[CAAM_DES_KEY_SIZE])
5282 {
5283     caam_desc_cipher_des_t descBuf;
5284     status_t status;
5285 
5286     status = CAAM_DES_DecryptEcbNonBlocking(base, handle, descBuf, ciphertext, plaintext, size, key);
5287     if (status != 0)
5288     {
5289         return status;
5290     }
5291     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
5292 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
5293     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
5294     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
5295     DCACHE_InvalidateByRange((uint32_t)plaintext, size);
5296 #endif /* CAAM_OUT_INVALIDATE */
5297     return status;
5298 }
5299 
5300 /*!
5301  * brief Decrypts DES using ECB block mode.
5302  *
5303  * Decrypts DES using ECB block mode.
5304  *
5305  * param base CAAM peripheral base address
5306  * param handle Handle used for this request. Specifies jobRing.
5307  * param[out] descriptor memory for CAAM commands
5308  * param ciphertext Input ciphertext to decrypt
5309  * param[out] plaintext Output plaintext
5310  * param size Size of input and output data in bytes. Must be multiple of 8 bytes.
5311  * param key Input key to use for decryption
5312  * return Status from descriptor push
5313  */
CAAM_DES_DecryptEcbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t key[CAAM_DES_KEY_SIZE])5314 status_t CAAM_DES_DecryptEcbNonBlocking(CAAM_Type *base,
5315                                         caam_handle_t *handle,
5316                                         caam_desc_cipher_des_t descriptor,
5317                                         const uint8_t *ciphertext,
5318                                         uint8_t *plaintext,
5319                                         size_t size,
5320                                         const uint8_t key[CAAM_DES_KEY_SIZE])
5321 {
5322     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
5323 
5324     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
5325      * Data lenght limit is 2^16 bytes = 65 536 bytes.
5326      * Note: You can still call several times instead
5327      */
5328     if (size > 0xFFFFUL)
5329     {
5330         return kStatus_CAAM_DataOverflow;
5331     }
5332 
5333     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
5334     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
5335     descriptor[1] |= CAAM_DES_KEY_SIZE;
5336     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key, CAAM_DES_KEY_SIZE);
5337     descriptor[4] = DESC_JUMP_6; /* ECB has no context, jump to currIdx+6 = 10 (FIFO LOAD) */
5338     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
5339     descriptor[11] = ADD_OFFSET((uint32_t)ciphertext);
5340     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
5341     descriptor[13] = ADD_OFFSET((uint32_t)plaintext);
5342     descriptor[14] |= (uint32_t)kCAAM_ModeECB; /* AAI = 20h */
5343 
5344     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
5345 }
5346 
5347 /*!
5348  * brief Encrypts DES using CBC block mode.
5349  *
5350  * Encrypts DES using CBC block mode.
5351  *
5352  * param base CAAM peripheral base address
5353  * param handle Handle used for this request. Specifies jobRing.
5354  * param plaintext Input plaintext to encrypt
5355  * param[out] ciphertext Ouput ciphertext
5356  * param size Size of input and output data in bytes
5357  * param iv Input initial vector to combine with the first plaintext block.
5358  *           The iv does not need to be secret, but it must be unpredictable.
5359  * param key Input key to use for encryption
5360  * return Status from encrypt/decrypt operation
5361  */
CAAM_DES_EncryptCbc(CAAM_Type * base,caam_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key[CAAM_DES_KEY_SIZE])5362 status_t CAAM_DES_EncryptCbc(CAAM_Type *base,
5363                              caam_handle_t *handle,
5364                              const uint8_t *plaintext,
5365                              uint8_t *ciphertext,
5366                              size_t size,
5367                              const uint8_t iv[CAAM_DES_IV_SIZE],
5368                              const uint8_t key[CAAM_DES_KEY_SIZE])
5369 {
5370     status_t status;
5371     caam_desc_cipher_des_t descBuf;
5372 
5373     do
5374     {
5375         status = CAAM_DES_EncryptCbcNonBlocking(base, handle, descBuf, plaintext, ciphertext, size, iv, key);
5376     } while (status == kStatus_CAAM_Again);
5377 
5378     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
5379 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
5380     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
5381     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
5382     DCACHE_InvalidateByRange((uint32_t)ciphertext, size);
5383 #endif /* CAAM_OUT_INVALIDATE */
5384     return status;
5385 }
5386 
5387 /*!
5388  * brief Encrypts DES using CBC block mode.
5389  *
5390  * Encrypts DES using CBC block mode.
5391  *
5392  * param base CAAM peripheral base address
5393  * param handle Handle used for this request. Specifies jobRing.
5394  * param[out] descriptor memory for CAAM commands
5395  * param plaintext Input plaintext to encrypt
5396  * param[out] ciphertext Ouput ciphertext
5397  * param size Size of input and output data in bytes
5398  * param iv Input initial vector to combine with the first plaintext block.
5399  *           The iv does not need to be secret, but it must be unpredictable.
5400  * param key Input key to use for encryption
5401  * return Status from descriptor push
5402  */
CAAM_DES_EncryptCbcNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key[CAAM_DES_KEY_SIZE])5403 status_t CAAM_DES_EncryptCbcNonBlocking(CAAM_Type *base,
5404                                         caam_handle_t *handle,
5405                                         caam_desc_cipher_des_t descriptor,
5406                                         const uint8_t *plaintext,
5407                                         uint8_t *ciphertext,
5408                                         size_t size,
5409                                         const uint8_t iv[CAAM_DES_IV_SIZE],
5410                                         const uint8_t key[CAAM_DES_KEY_SIZE])
5411 {
5412     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
5413 
5414     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
5415      * Data lenght limit is 2^16 bytes = 65 536 bytes.
5416      * Note: You can still call several times instead
5417      */
5418     if (size > 0xFFFFUL)
5419     {
5420         return kStatus_CAAM_DataOverflow;
5421     }
5422 
5423     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
5424     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
5425     descriptor[1] |= CAAM_DES_KEY_SIZE;
5426     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key, CAAM_DES_KEY_SIZE);
5427     descriptor[4] = DESC_JUMP_4; /* context, jump to currIdx+4 = 8 (LOAD) */
5428     descriptor[9] = ADD_OFFSET((uint32_t)iv);
5429     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
5430     descriptor[11] = ADD_OFFSET((uint32_t)plaintext);
5431     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
5432     descriptor[13] = ADD_OFFSET((uint32_t)ciphertext);
5433     descriptor[14] |= (uint32_t)kCAAM_ModeCBC; /* AAI = 10h */
5434     descriptor[14] |= 1u;                      /* add ENC bit to specify Encrypt OPERATION */
5435     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
5436 }
5437 
5438 /*!
5439  * brief Decrypts DES using CBC block mode.
5440  *
5441  * Decrypts DES using CBC block mode.
5442  *
5443  * param base CAAM peripheral base address
5444  * param handle Handle used for this request. Specifies jobRing.
5445  * param ciphertext Input ciphertext to decrypt
5446  * param[out] plaintext Output plaintext
5447  * param size Size of input data in bytes
5448  * param iv Input initial vector to combine with the first plaintext block.
5449  *           The iv does not need to be secret, but it must be unpredictable.
5450  * param key Input key to use for decryption
5451  * return Status from encrypt/decrypt operation
5452  */
CAAM_DES_DecryptCbc(CAAM_Type * base,caam_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key[CAAM_DES_KEY_SIZE])5453 status_t CAAM_DES_DecryptCbc(CAAM_Type *base,
5454                              caam_handle_t *handle,
5455                              const uint8_t *ciphertext,
5456                              uint8_t *plaintext,
5457                              size_t size,
5458                              const uint8_t iv[CAAM_DES_IV_SIZE],
5459                              const uint8_t key[CAAM_DES_KEY_SIZE])
5460 {
5461     status_t status;
5462     caam_desc_cipher_des_t descBuf;
5463 
5464     do
5465     {
5466         status = CAAM_DES_DecryptCbcNonBlocking(base, handle, descBuf, ciphertext, plaintext, size, iv, key);
5467     } while (status == kStatus_CAAM_Again);
5468 
5469     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
5470 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
5471     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
5472     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
5473     DCACHE_InvalidateByRange((uint32_t)plaintext, size);
5474 #endif /* CAAM_OUT_INVALIDATE */
5475     return status;
5476 }
5477 
5478 /*!
5479  * brief Decrypts DES using CBC block mode.
5480  *
5481  * Decrypts DES using CBC block mode.
5482  *
5483  * param base CAAM peripheral base address
5484  * param handle Handle used for this request. Specifies jobRing.
5485  * param[out] descriptor memory for CAAM commands
5486  * param ciphertext Input ciphertext to decrypt
5487  * param[out] plaintext Output plaintext
5488  * param size Size of input data in bytes
5489  * param iv Input initial vector to combine with the first plaintext block.
5490  *           The iv does not need to be secret, but it must be unpredictable.
5491  * param key Input key to use for decryption
5492  * return Status from descriptor push
5493  */
CAAM_DES_DecryptCbcNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key[CAAM_DES_KEY_SIZE])5494 status_t CAAM_DES_DecryptCbcNonBlocking(CAAM_Type *base,
5495                                         caam_handle_t *handle,
5496                                         caam_desc_cipher_des_t descriptor,
5497                                         const uint8_t *ciphertext,
5498                                         uint8_t *plaintext,
5499                                         size_t size,
5500                                         const uint8_t iv[CAAM_DES_IV_SIZE],
5501                                         const uint8_t key[CAAM_DES_KEY_SIZE])
5502 {
5503     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
5504 
5505     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
5506      * Data lenght limit is 2^16 bytes = 65 536 bytes.
5507      * Note: You can still call several times instead
5508      */
5509     if (size > 0xFFFFUL)
5510     {
5511         return kStatus_CAAM_DataOverflow;
5512     }
5513 
5514     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
5515     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
5516     descriptor[1] |= CAAM_DES_KEY_SIZE;
5517     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key, CAAM_DES_KEY_SIZE);
5518     descriptor[4] = DESC_JUMP_4; /* context, jump to currIdx+4 = 8 (LOAD) */
5519     descriptor[9] = ADD_OFFSET((uint32_t)iv);
5520     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
5521     descriptor[11] = ADD_OFFSET((uint32_t)ciphertext);
5522     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
5523     descriptor[13] = ADD_OFFSET((uint32_t)plaintext);
5524     descriptor[14] |= (uint32_t)kCAAM_ModeCBC; /* AAI = 10h */
5525 
5526     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
5527 }
5528 
5529 /*!
5530  * brief Encrypts DES using CFB block mode.
5531  *
5532  * Encrypts DES using CFB block mode.
5533  *
5534  * param base CAAM peripheral base address
5535  * param handle Handle used for this request. Specifies jobRing.
5536  * param plaintext Input plaintext to encrypt
5537  * param size Size of input data in bytes
5538  * param iv Input initial block.
5539  * param key Input key to use for encryption
5540  * param[out] ciphertext Output ciphertext
5541  * return Status from encrypt/decrypt operation
5542  */
CAAM_DES_EncryptCfb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key[CAAM_DES_KEY_SIZE])5543 status_t CAAM_DES_EncryptCfb(CAAM_Type *base,
5544                              caam_handle_t *handle,
5545                              const uint8_t *plaintext,
5546                              uint8_t *ciphertext,
5547                              size_t size,
5548                              const uint8_t iv[CAAM_DES_IV_SIZE],
5549                              const uint8_t key[CAAM_DES_KEY_SIZE])
5550 {
5551     status_t status;
5552     caam_desc_cipher_des_t descBuf;
5553 
5554     do
5555     {
5556         status = CAAM_DES_EncryptCfbNonBlocking(base, handle, descBuf, plaintext, ciphertext, size, iv, key);
5557     } while (status == kStatus_CAAM_Again);
5558 
5559     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
5560 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
5561     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
5562     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
5563     DCACHE_InvalidateByRange((uint32_t)ciphertext, size);
5564 #endif /* CAAM_OUT_INVALIDATE */
5565     return status;
5566 }
5567 
5568 /*!
5569  * brief Encrypts DES using CFB block mode.
5570  *
5571  * Encrypts DES using CFB block mode.
5572  *
5573  * param base CAAM peripheral base address
5574  * param handle Handle used for this request. Specifies jobRing.
5575  * param[out] descriptor memory for CAAM commands
5576  * param plaintext Input plaintext to encrypt
5577  * param size Size of input data in bytes
5578  * param iv Input initial block.
5579  * param key Input key to use for encryption
5580  * param[out] ciphertext Output ciphertext
5581  * return Status from descriptor push
5582  */
CAAM_DES_EncryptCfbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key[CAAM_DES_KEY_SIZE])5583 status_t CAAM_DES_EncryptCfbNonBlocking(CAAM_Type *base,
5584                                         caam_handle_t *handle,
5585                                         caam_desc_cipher_des_t descriptor,
5586                                         const uint8_t *plaintext,
5587                                         uint8_t *ciphertext,
5588                                         size_t size,
5589                                         const uint8_t iv[CAAM_DES_IV_SIZE],
5590                                         const uint8_t key[CAAM_DES_KEY_SIZE])
5591 {
5592     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
5593 
5594     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
5595      * Data lenght limit is 2^16 bytes = 65 536 bytes.
5596      * Note: You can still call several times instead
5597      */
5598     if (size > 0xFFFFUL)
5599     {
5600         return kStatus_CAAM_DataOverflow;
5601     }
5602 
5603     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
5604     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
5605     descriptor[1] |= CAAM_DES_KEY_SIZE;
5606     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key, CAAM_DES_KEY_SIZE);
5607     descriptor[4] = DESC_JUMP_4; /* context, jump to currIdx+4 = 8 (LOAD) */
5608     descriptor[9] = ADD_OFFSET((uint32_t)iv);
5609     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
5610     descriptor[11] = ADD_OFFSET((uint32_t)plaintext);
5611     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
5612     descriptor[13] = ADD_OFFSET((uint32_t)ciphertext);
5613     descriptor[14] |= (uint32_t)kCAAM_ModeCFB; /* AAI = 30h = CFB */
5614     descriptor[14] |= 1u;                      /* add ENC bit to specify Encrypt OPERATION */
5615     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
5616 }
5617 
5618 /*!
5619  * brief Decrypts DES using CFB block mode.
5620  *
5621  * Decrypts DES using CFB block mode.
5622  *
5623  * param base CAAM peripheral base address
5624  * param handle Handle used for this request. Specifies jobRing.
5625  * param ciphertext Input ciphertext to decrypt
5626  * param[out] plaintext Output plaintext
5627  * param size Size of input and output data in bytes
5628  * param iv Input initial block.
5629  * param key Input key to use for decryption
5630  * return Status from encrypt/decrypt operation
5631  */
CAAM_DES_DecryptCfb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key[CAAM_DES_KEY_SIZE])5632 status_t CAAM_DES_DecryptCfb(CAAM_Type *base,
5633                              caam_handle_t *handle,
5634                              const uint8_t *ciphertext,
5635                              uint8_t *plaintext,
5636                              size_t size,
5637                              const uint8_t iv[CAAM_DES_IV_SIZE],
5638                              const uint8_t key[CAAM_DES_KEY_SIZE])
5639 {
5640     status_t status;
5641     caam_desc_cipher_des_t descBuf;
5642 
5643     do
5644     {
5645         status = CAAM_DES_DecryptCfbNonBlocking(base, handle, descBuf, ciphertext, plaintext, size, iv, key);
5646     } while (status == kStatus_CAAM_Again);
5647 
5648     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
5649 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
5650     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
5651     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
5652     DCACHE_InvalidateByRange((uint32_t)plaintext, size);
5653 #endif /* CAAM_OUT_INVALIDATE */
5654     return status;
5655 }
5656 
5657 /*!
5658  * brief Decrypts DES using CFB block mode.
5659  *
5660  * Decrypts DES using CFB block mode.
5661  *
5662  * param base CAAM peripheral base address
5663  * param handle Handle used for this request. Specifies jobRing.
5664  * param[out] descriptor memory for CAAM commands
5665  * param ciphertext Input ciphertext to decrypt
5666  * param[out] plaintext Output plaintext
5667  * param size Size of input and output data in bytes
5668  * param iv Input initial block.
5669  * param key Input key to use for decryption
5670  * return Status from descriptor push
5671  */
CAAM_DES_DecryptCfbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key[CAAM_DES_KEY_SIZE])5672 status_t CAAM_DES_DecryptCfbNonBlocking(CAAM_Type *base,
5673                                         caam_handle_t *handle,
5674                                         caam_desc_cipher_des_t descriptor,
5675                                         const uint8_t *ciphertext,
5676                                         uint8_t *plaintext,
5677                                         size_t size,
5678                                         const uint8_t iv[CAAM_DES_IV_SIZE],
5679                                         const uint8_t key[CAAM_DES_KEY_SIZE])
5680 {
5681     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
5682 
5683     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
5684      * Data lenght limit is 2^16 bytes = 65 536 bytes.
5685      * Note: You can still call several times instead
5686      */
5687     if (size > 0xFFFFUL)
5688     {
5689         return kStatus_CAAM_DataOverflow;
5690     }
5691 
5692     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
5693     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
5694     descriptor[1] |= CAAM_DES_KEY_SIZE;
5695     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key, CAAM_DES_KEY_SIZE);
5696     descriptor[4] = DESC_JUMP_4; /* context, jump to currIdx+4 = 8 (LOAD) */
5697     descriptor[9] = ADD_OFFSET((uint32_t)iv);
5698     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
5699     descriptor[11] = ADD_OFFSET((uint32_t)ciphertext);
5700     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
5701     descriptor[13] = ADD_OFFSET((uint32_t)plaintext);
5702     descriptor[14] |= (uint32_t)kCAAM_ModeCFB; /* AAI = 30h = CFB */
5703 
5704     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
5705 }
5706 
5707 /*!
5708  * brief Encrypts DES using OFB block mode.
5709  *
5710  * Encrypts DES using OFB block mode.
5711  *
5712  * param base CAAM peripheral base address
5713  * param handle Handle used for this request. Specifies jobRing.
5714  * param plaintext Input plaintext to encrypt
5715  * param[out] ciphertext Output ciphertext
5716  * param size Size of input and output data in bytes
5717  * param iv Input unique input vector. The OFB mode requires that the IV be unique
5718  *           for each execution of the mode under the given key.
5719  * param key Input key to use for encryption
5720  * return Status from encrypt/decrypt operation
5721  */
CAAM_DES_EncryptOfb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key[CAAM_DES_KEY_SIZE])5722 status_t CAAM_DES_EncryptOfb(CAAM_Type *base,
5723                              caam_handle_t *handle,
5724                              const uint8_t *plaintext,
5725                              uint8_t *ciphertext,
5726                              size_t size,
5727                              const uint8_t iv[CAAM_DES_IV_SIZE],
5728                              const uint8_t key[CAAM_DES_KEY_SIZE])
5729 {
5730     status_t status;
5731     caam_desc_cipher_des_t descBuf;
5732 
5733     do
5734     {
5735         status = CAAM_DES_EncryptOfbNonBlocking(base, handle, descBuf, plaintext, ciphertext, size, iv, key);
5736     } while (status == kStatus_CAAM_Again);
5737 
5738     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
5739 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
5740     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
5741     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
5742     DCACHE_InvalidateByRange((uint32_t)ciphertext, size);
5743 #endif /* CAAM_OUT_INVALIDATE */
5744     return status;
5745 }
5746 
5747 /*!
5748  * brief Encrypts DES using OFB block mode.
5749  *
5750  * Encrypts DES using OFB block mode.
5751  *
5752  * param base CAAM peripheral base address
5753  * param handle Handle used for this request. Specifies jobRing.
5754  * param[out] descriptor memory for CAAM commands
5755  * param plaintext Input plaintext to encrypt
5756  * param[out] ciphertext Output ciphertext
5757  * param size Size of input and output data in bytes
5758  * param iv Input unique input vector. The OFB mode requires that the IV be unique
5759  *           for each execution of the mode under the given key.
5760  * param key Input key to use for encryption
5761  * return Status from descriptor push
5762  */
CAAM_DES_EncryptOfbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key[CAAM_DES_KEY_SIZE])5763 status_t CAAM_DES_EncryptOfbNonBlocking(CAAM_Type *base,
5764                                         caam_handle_t *handle,
5765                                         caam_desc_cipher_des_t descriptor,
5766                                         const uint8_t *plaintext,
5767                                         uint8_t *ciphertext,
5768                                         size_t size,
5769                                         const uint8_t iv[CAAM_DES_IV_SIZE],
5770                                         const uint8_t key[CAAM_DES_KEY_SIZE])
5771 {
5772     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
5773 
5774     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
5775      * Data lenght limit is 2^16 bytes = 65 536 bytes.
5776      * Note: You can still call several times instead
5777      */
5778     if (size > 0xFFFFUL)
5779     {
5780         return kStatus_CAAM_DataOverflow;
5781     }
5782 
5783     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
5784     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
5785     descriptor[1] |= CAAM_DES_KEY_SIZE;
5786     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key, CAAM_DES_KEY_SIZE);
5787     descriptor[4] = DESC_JUMP_4; /* context, jump to currIdx+4 = 8 (LOAD) */
5788     descriptor[9] = ADD_OFFSET((uint32_t)iv);
5789     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
5790     descriptor[11] = ADD_OFFSET((uint32_t)plaintext);
5791     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
5792     descriptor[13] = ADD_OFFSET((uint32_t)ciphertext);
5793     descriptor[14] |= (uint32_t)kCAAM_ModeOFB; /* AAI = 40h = OFB */
5794     descriptor[14] |= 1u;                      /* add ENC bit to specify Encrypt OPERATION */
5795     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
5796 }
5797 
5798 /*!
5799  * brief Decrypts DES using OFB block mode.
5800  *
5801  * Decrypts DES using OFB block mode.
5802  *
5803  * param base CAAM peripheral base address
5804  * param handle Handle used for this request. Specifies jobRing.
5805  * param ciphertext Input ciphertext to decrypt
5806  * param[out] plaintext Output plaintext
5807  * param size Size of input and output data in bytes. Must be multiple of 8 bytes.
5808  * param iv Input unique input vector. The OFB mode requires that the IV be unique
5809  *           for each execution of the mode under the given key.
5810  * param key Input key to use for decryption
5811  * return Status from encrypt/decrypt operation
5812  */
CAAM_DES_DecryptOfb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key[CAAM_DES_KEY_SIZE])5813 status_t CAAM_DES_DecryptOfb(CAAM_Type *base,
5814                              caam_handle_t *handle,
5815                              const uint8_t *ciphertext,
5816                              uint8_t *plaintext,
5817                              size_t size,
5818                              const uint8_t iv[CAAM_DES_IV_SIZE],
5819                              const uint8_t key[CAAM_DES_KEY_SIZE])
5820 {
5821     status_t status;
5822     caam_desc_cipher_des_t descBuf;
5823 
5824     do
5825     {
5826         status = CAAM_DES_DecryptOfbNonBlocking(base, handle, descBuf, ciphertext, plaintext, size, iv, key);
5827     } while (status == kStatus_CAAM_Again);
5828 
5829     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
5830 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
5831     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
5832     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
5833     DCACHE_InvalidateByRange((uint32_t)plaintext, size);
5834 #endif /* CAAM_OUT_INVALIDATE */
5835     return status;
5836 }
5837 
5838 /*!
5839  * brief Decrypts DES using OFB block mode.
5840  *
5841  * Decrypts DES using OFB block mode.
5842  *
5843  * param base CAAM peripheral base address
5844  * param handle Handle used for this request. Specifies jobRing.
5845  * param[out] descriptor memory for CAAM commands
5846  * param ciphertext Input ciphertext to decrypt
5847  * param[out] plaintext Output plaintext
5848  * param size Size of input and output data in bytes. Must be multiple of 8 bytes.
5849  * param iv Input unique input vector. The OFB mode requires that the IV be unique
5850  *           for each execution of the mode under the given key.
5851  * param key Input key to use for decryption
5852  * return Status from descriptor push
5853  */
CAAM_DES_DecryptOfbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key[CAAM_DES_KEY_SIZE])5854 status_t CAAM_DES_DecryptOfbNonBlocking(CAAM_Type *base,
5855                                         caam_handle_t *handle,
5856                                         caam_desc_cipher_des_t descriptor,
5857                                         const uint8_t *ciphertext,
5858                                         uint8_t *plaintext,
5859                                         size_t size,
5860                                         const uint8_t iv[CAAM_DES_IV_SIZE],
5861                                         const uint8_t key[CAAM_DES_KEY_SIZE])
5862 {
5863     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
5864 
5865     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
5866      * Data lenght limit is 2^16 bytes = 65 536 bytes.
5867      * Note: You can still call several times instead
5868      */
5869     if (size > 0xFFFFUL)
5870     {
5871         return kStatus_CAAM_DataOverflow;
5872     }
5873 
5874     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
5875     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
5876     descriptor[1] |= CAAM_DES_KEY_SIZE;
5877     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key, CAAM_DES_KEY_SIZE);
5878     descriptor[4] = DESC_JUMP_4; /* context, jump to currIdx+4 = 8 (LOAD) */
5879     descriptor[9] = ADD_OFFSET((uint32_t)iv);
5880     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
5881     descriptor[11] = ADD_OFFSET((uint32_t)ciphertext);
5882     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
5883     descriptor[13] = ADD_OFFSET((uint32_t)plaintext);
5884     descriptor[14] |= (uint32_t)kCAAM_ModeOFB; /* AAI = 40h = OFB */
5885 
5886     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
5887 }
5888 
5889 /*!
5890  * brief Encrypts triple DES using ECB block mode with two keys.
5891  *
5892  * Encrypts triple DES using ECB block mode with two keys.
5893  *
5894  * param base CAAM peripheral base address
5895  * param handle Handle used for this request. Specifies jobRing.
5896  * param plaintext Input plaintext to encrypt
5897  * param[out] ciphertext Output ciphertext
5898  * param size Size of input and output data in bytes. Must be multiple of 8 bytes.
5899  * param key1 First input key for key bundle
5900  * param key2 Second input key for key bundle
5901  * return Status from encrypt/decrypt operation
5902  */
CAAM_DES2_EncryptEcb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE])5903 status_t CAAM_DES2_EncryptEcb(CAAM_Type *base,
5904                               caam_handle_t *handle,
5905                               const uint8_t *plaintext,
5906                               uint8_t *ciphertext,
5907                               size_t size,
5908                               const uint8_t key1[CAAM_DES_KEY_SIZE],
5909                               const uint8_t key2[CAAM_DES_KEY_SIZE])
5910 {
5911     caam_desc_cipher_des_t descBuf;
5912     status_t status;
5913 
5914     status = CAAM_DES2_EncryptEcbNonBlocking(base, handle, descBuf, plaintext, ciphertext, size, key1, key2);
5915     if (status != 0)
5916     {
5917         return status;
5918     }
5919     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
5920 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
5921     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
5922     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
5923     DCACHE_InvalidateByRange((uint32_t)ciphertext, size);
5924 #endif /* CAAM_OUT_INVALIDATE */
5925     return status;
5926 }
5927 
5928 /*!
5929  * brief Encrypts triple DES using ECB block mode with two keys.
5930  *
5931  * Encrypts triple DES using ECB block mode with two keys.
5932  *
5933  * param base CAAM peripheral base address
5934  * param handle Handle used for this request. Specifies jobRing.
5935  * param[out] descriptor memory for CAAM commands
5936  * param plaintext Input plaintext to encrypt
5937  * param[out] ciphertext Output ciphertext
5938  * param size Size of input and output data in bytes. Must be multiple of 8 bytes.
5939  * param key1 First input key for key bundle
5940  * param key2 Second input key for key bundle
5941  * return Status from descriptor push
5942  */
CAAM_DES2_EncryptEcbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE])5943 status_t CAAM_DES2_EncryptEcbNonBlocking(CAAM_Type *base,
5944                                          caam_handle_t *handle,
5945                                          caam_desc_cipher_des_t descriptor,
5946                                          const uint8_t *plaintext,
5947                                          uint8_t *ciphertext,
5948                                          size_t size,
5949                                          const uint8_t key1[CAAM_DES_KEY_SIZE],
5950                                          const uint8_t key2[CAAM_DES_KEY_SIZE])
5951 {
5952     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
5953 
5954     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
5955      * Data lenght limit is 2^16 bytes = 65 536 bytes.
5956      * Note: You can still call several times instead
5957      */
5958     if (size > 0xFFFFUL)
5959     {
5960         return kStatus_CAAM_DataOverflow;
5961     }
5962 
5963     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
5964     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
5965     descriptor[1] |= 2U * CAAM_DES_KEY_SIZE;
5966     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key1, CAAM_DES_KEY_SIZE);
5967     (void)caam_memcpy(&descriptor[4], (const uint32_t *)(uintptr_t)key2, CAAM_DES_KEY_SIZE);
5968     descriptor[6] = DESC_JUMP_4; /* ECB has no context, jump to currIdx+4 = 10 (FIFO LOAD) */
5969     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
5970     descriptor[11] = ADD_OFFSET((uint32_t)plaintext);
5971     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
5972     descriptor[13] = ADD_OFFSET((uint32_t)ciphertext);
5973     descriptor[14] |= 0x201u;   /* add ENC bit to specify Encrypt OPERATION, AAI = 20h */
5974     descriptor[14] |= 0x10000U; /* 3DES */
5975 
5976     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
5977 }
5978 
5979 /*!
5980  * brief Decrypts triple DES using ECB block mode with two keys.
5981  *
5982  * Decrypts triple DES using ECB block mode with two keys.
5983  *
5984  * param base CAAM peripheral base address
5985  * param handle Handle used for this request. Specifies jobRing.
5986  * param ciphertext Input ciphertext to decrypt
5987  * param[out] plaintext Output plaintext
5988  * param size Size of input and output data in bytes. Must be multiple of 8 bytes.
5989  * param key1 First input key for key bundle
5990  * param key2 Second input key for key bundle
5991  * return Status from encrypt/decrypt operation
5992  */
CAAM_DES2_DecryptEcb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE])5993 status_t CAAM_DES2_DecryptEcb(CAAM_Type *base,
5994                               caam_handle_t *handle,
5995                               const uint8_t *ciphertext,
5996                               uint8_t *plaintext,
5997                               size_t size,
5998                               const uint8_t key1[CAAM_DES_KEY_SIZE],
5999                               const uint8_t key2[CAAM_DES_KEY_SIZE])
6000 {
6001     caam_desc_cipher_des_t descBuf;
6002     status_t status;
6003 
6004     status = CAAM_DES2_DecryptEcbNonBlocking(base, handle, descBuf, ciphertext, plaintext, size, key1, key2);
6005     if (status != 0)
6006     {
6007         return status;
6008     }
6009     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
6010 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
6011     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
6012     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
6013     DCACHE_InvalidateByRange((uint32_t)plaintext, size);
6014 #endif /* CAAM_OUT_INVALIDATE */
6015     return status;
6016 }
6017 
6018 /*!
6019  * brief Decrypts triple DES using ECB block mode with two keys.
6020  *
6021  * Decrypts triple DES using ECB block mode with two keys.
6022  *
6023  * param base CAAM peripheral base address
6024  * param handle Handle used for this request. Specifies jobRing.
6025  * param[out] descriptor memory for CAAM commands
6026  * param ciphertext Input ciphertext to decrypt
6027  * param[out] plaintext Output plaintext
6028  * param size Size of input and output data in bytes. Must be multiple of 8 bytes.
6029  * param key1 First input key for key bundle
6030  * param key2 Second input key for key bundle
6031  * return Status from descriptor push
6032  */
CAAM_DES2_DecryptEcbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE])6033 status_t CAAM_DES2_DecryptEcbNonBlocking(CAAM_Type *base,
6034                                          caam_handle_t *handle,
6035                                          caam_desc_cipher_des_t descriptor,
6036                                          const uint8_t *ciphertext,
6037                                          uint8_t *plaintext,
6038                                          size_t size,
6039                                          const uint8_t key1[CAAM_DES_KEY_SIZE],
6040                                          const uint8_t key2[CAAM_DES_KEY_SIZE])
6041 {
6042     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
6043 
6044     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
6045      * Data lenght limit is 2^16 bytes = 65 536 bytes.
6046      * Note: You can still call several times instead
6047      */
6048     if (size > 0xFFFFUL)
6049     {
6050         return kStatus_CAAM_DataOverflow;
6051     }
6052 
6053     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
6054     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
6055     descriptor[1] |= 2U * CAAM_DES_KEY_SIZE;
6056     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key1, CAAM_DES_KEY_SIZE);
6057     (void)caam_memcpy(&descriptor[4], (const uint32_t *)(uintptr_t)key2, CAAM_DES_KEY_SIZE);
6058     descriptor[6] = DESC_JUMP_4; /* ECB has no context, jump to currIdx+4 = 10 (FIFO LOAD) */
6059     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
6060     descriptor[11] = ADD_OFFSET((uint32_t)ciphertext);
6061     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
6062     descriptor[13] = ADD_OFFSET((uint32_t)plaintext);
6063     descriptor[14] |= (uint32_t)kCAAM_ModeECB; /* AAI = 20h */
6064     descriptor[14] |= 0x10000U;                /* 3DES */
6065 
6066     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
6067 }
6068 
6069 /*!
6070  * brief Encrypts triple DES using CBC block mode with two keys.
6071  *
6072  * Encrypts triple DES using CBC block mode with two keys.
6073  *
6074  * param base CAAM peripheral base address
6075  * param handle Handle used for this request. Specifies jobRing.
6076  * param plaintext Input plaintext to encrypt
6077  * param[out] ciphertext Output ciphertext
6078  * param size Size of input and output data in bytes
6079  * param iv Input initial vector to combine with the first plaintext block.
6080  *           The iv does not need to be secret, but it must be unpredictable.
6081  * param key1 First input key for key bundle
6082  * param key2 Second input key for key bundle
6083  * return Status from encrypt/decrypt operation
6084  */
CAAM_DES2_EncryptCbc(CAAM_Type * base,caam_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE])6085 status_t CAAM_DES2_EncryptCbc(CAAM_Type *base,
6086                               caam_handle_t *handle,
6087                               const uint8_t *plaintext,
6088                               uint8_t *ciphertext,
6089                               size_t size,
6090                               const uint8_t iv[CAAM_DES_IV_SIZE],
6091                               const uint8_t key1[CAAM_DES_KEY_SIZE],
6092                               const uint8_t key2[CAAM_DES_KEY_SIZE])
6093 {
6094     status_t status;
6095     caam_desc_cipher_des_t descBuf;
6096 
6097     do
6098     {
6099         status = CAAM_DES2_EncryptCbcNonBlocking(base, handle, descBuf, plaintext, ciphertext, size, iv, key1, key2);
6100     } while (status == kStatus_CAAM_Again);
6101 
6102     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
6103 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
6104     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
6105     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
6106     DCACHE_InvalidateByRange((uint32_t)ciphertext, size);
6107 #endif /* CAAM_OUT_INVALIDATE */
6108     return status;
6109 }
6110 
6111 /*!
6112  * brief Encrypts triple DES using CBC block mode with two keys.
6113  *
6114  * Encrypts triple DES using CBC block mode with two keys.
6115  *
6116  * param base CAAM peripheral base address
6117  * param handle Handle used for this request. Specifies jobRing.
6118  * param[out] descriptor memory for CAAM commands
6119  * param plaintext Input plaintext to encrypt
6120  * param[out] ciphertext Output ciphertext
6121  * param size Size of input and output data in bytes
6122  * param iv Input initial vector to combine with the first plaintext block.
6123  *           The iv does not need to be secret, but it must be unpredictable.
6124  * param key1 First input key for key bundle
6125  * param key2 Second input key for key bundle
6126  * return Status from descriptor push
6127  */
CAAM_DES2_EncryptCbcNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE])6128 status_t CAAM_DES2_EncryptCbcNonBlocking(CAAM_Type *base,
6129                                          caam_handle_t *handle,
6130                                          caam_desc_cipher_des_t descriptor,
6131                                          const uint8_t *plaintext,
6132                                          uint8_t *ciphertext,
6133                                          size_t size,
6134                                          const uint8_t iv[CAAM_DES_IV_SIZE],
6135                                          const uint8_t key1[CAAM_DES_KEY_SIZE],
6136                                          const uint8_t key2[CAAM_DES_KEY_SIZE])
6137 {
6138     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
6139 
6140     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
6141      * Data lenght limit is 2^16 bytes = 65 536 bytes.
6142      * Note: You can still call several times instead
6143      */
6144     if (size > 0xFFFFUL)
6145     {
6146         return kStatus_CAAM_DataOverflow;
6147     }
6148 
6149     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
6150     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
6151     descriptor[1] |= 2U * CAAM_DES_KEY_SIZE;
6152     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key1, CAAM_DES_KEY_SIZE);
6153     (void)caam_memcpy(&descriptor[4], (const uint32_t *)(uintptr_t)key2, CAAM_DES_KEY_SIZE);
6154     descriptor[6] = DESC_JUMP_2; /* context, jump to currIdx+2 = 8 (LOAD) */
6155     descriptor[9] = ADD_OFFSET((uint32_t)iv);
6156     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
6157     descriptor[11] = ADD_OFFSET((uint32_t)plaintext);
6158     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
6159     descriptor[13] = ADD_OFFSET((uint32_t)ciphertext);
6160     descriptor[14] |= (uint32_t)kCAAM_ModeCBC; /* AAI = 10h */
6161     descriptor[14] |= 1u;                      /* add ENC bit to specify Encrypt OPERATION */
6162     descriptor[14] |= 0x10000U;                /* 3DES */
6163     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
6164 }
6165 
6166 /*!
6167  * brief Decrypts triple DES using CBC block mode with two keys.
6168  *
6169  * Decrypts triple DES using CBC block mode with two keys.
6170  *
6171  * param base CAAM peripheral base address
6172  * param handle Handle used for this request. Specifies jobRing.
6173  * param ciphertext Input ciphertext to decrypt
6174  * param[out] plaintext Output plaintext
6175  * param size Size of input and output data in bytes
6176  * param iv Input initial vector to combine with the first plaintext block.
6177  *           The iv does not need to be secret, but it must be unpredictable.
6178  * param key1 First input key for key bundle
6179  * param key2 Second input key for key bundle
6180  * return Status from encrypt/decrypt operation
6181  */
CAAM_DES2_DecryptCbc(CAAM_Type * base,caam_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE])6182 status_t CAAM_DES2_DecryptCbc(CAAM_Type *base,
6183                               caam_handle_t *handle,
6184                               const uint8_t *ciphertext,
6185                               uint8_t *plaintext,
6186                               size_t size,
6187                               const uint8_t iv[CAAM_DES_IV_SIZE],
6188                               const uint8_t key1[CAAM_DES_KEY_SIZE],
6189                               const uint8_t key2[CAAM_DES_KEY_SIZE])
6190 {
6191     status_t status;
6192     caam_desc_cipher_des_t descBuf;
6193 
6194     do
6195     {
6196         status = CAAM_DES2_DecryptCbcNonBlocking(base, handle, descBuf, ciphertext, plaintext, size, iv, key1, key2);
6197     } while (status == kStatus_CAAM_Again);
6198 
6199     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
6200 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
6201     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
6202     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
6203     DCACHE_InvalidateByRange((uint32_t)plaintext, size);
6204 #endif /* CAAM_OUT_INVALIDATE */
6205     return status;
6206 }
6207 
6208 /*!
6209  * brief Decrypts triple DES using CBC block mode with two keys.
6210  *
6211  * Decrypts triple DES using CBC block mode with two keys.
6212  *
6213  * param base CAAM peripheral base address
6214  * param handle Handle used for this request. Specifies jobRing.
6215  * param[out] descriptor memory for CAAM commands
6216  * param ciphertext Input ciphertext to decrypt
6217  * param[out] plaintext Output plaintext
6218  * param size Size of input and output data in bytes
6219  * param iv Input initial vector to combine with the first plaintext block.
6220  *           The iv does not need to be secret, but it must be unpredictable.
6221  * param key1 First input key for key bundle
6222  * param key2 Second input key for key bundle
6223  * return Status from descriptor push
6224  */
CAAM_DES2_DecryptCbcNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE])6225 status_t CAAM_DES2_DecryptCbcNonBlocking(CAAM_Type *base,
6226                                          caam_handle_t *handle,
6227                                          caam_desc_cipher_des_t descriptor,
6228                                          const uint8_t *ciphertext,
6229                                          uint8_t *plaintext,
6230                                          size_t size,
6231                                          const uint8_t iv[CAAM_DES_IV_SIZE],
6232                                          const uint8_t key1[CAAM_DES_KEY_SIZE],
6233                                          const uint8_t key2[CAAM_DES_KEY_SIZE])
6234 {
6235     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
6236 
6237     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
6238      * Data lenght limit is 2^16 bytes = 65 536 bytes.
6239      * Note: You can still call several times instead
6240      */
6241     if (size > 0xFFFFUL)
6242     {
6243         return kStatus_CAAM_DataOverflow;
6244     }
6245 
6246     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
6247     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
6248     descriptor[1] |= 2U * CAAM_DES_KEY_SIZE;
6249     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key1, CAAM_DES_KEY_SIZE);
6250     (void)caam_memcpy(&descriptor[4], (const uint32_t *)(uintptr_t)key2, CAAM_DES_KEY_SIZE);
6251     descriptor[6] = DESC_JUMP_2; /* context, jump to currIdx+2 = 8 (LOAD) */
6252     descriptor[9] = ADD_OFFSET((uint32_t)iv);
6253     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
6254     descriptor[11] = ADD_OFFSET((uint32_t)ciphertext);
6255     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
6256     descriptor[13] = ADD_OFFSET((uint32_t)plaintext);
6257     descriptor[14] |= (uint32_t)kCAAM_ModeCBC; /* AAI = 10h */
6258     descriptor[14] |= 0x10000U;                /* 3DES */
6259     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
6260 }
6261 
6262 /*!
6263  * brief Encrypts triple DES using CFB block mode with two keys.
6264  *
6265  * Encrypts triple DES using CFB block mode with two keys.
6266  *
6267  * param base CAAM peripheral base address
6268  * param handle Handle used for this request. Specifies jobRing.
6269  * param plaintext Input plaintext to encrypt
6270  * param[out] ciphertext Output ciphertext
6271  * param size Size of input and output data in bytes
6272  * param iv Input initial block.
6273  * param key1 First input key for key bundle
6274  * param key2 Second input key for key bundle
6275  * return Status from encrypt/decrypt operation
6276  */
CAAM_DES2_EncryptCfb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE])6277 status_t CAAM_DES2_EncryptCfb(CAAM_Type *base,
6278                               caam_handle_t *handle,
6279                               const uint8_t *plaintext,
6280                               uint8_t *ciphertext,
6281                               size_t size,
6282                               const uint8_t iv[CAAM_DES_IV_SIZE],
6283                               const uint8_t key1[CAAM_DES_KEY_SIZE],
6284                               const uint8_t key2[CAAM_DES_KEY_SIZE])
6285 {
6286     status_t status;
6287     caam_desc_cipher_des_t descBuf;
6288 
6289     do
6290     {
6291         status = CAAM_DES2_EncryptCfbNonBlocking(base, handle, descBuf, plaintext, ciphertext, size, iv, key1, key2);
6292     } while (status == kStatus_CAAM_Again);
6293 
6294     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
6295 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
6296     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
6297     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
6298     DCACHE_InvalidateByRange((uint32_t)ciphertext, size);
6299 #endif /* CAAM_OUT_INVALIDATE */
6300     return status;
6301 }
6302 
6303 /*!
6304  * brief Encrypts triple DES using CFB block mode with two keys.
6305  *
6306  * Encrypts triple DES using CFB block mode with two keys.
6307  *
6308  * param base CAAM peripheral base address
6309  * param handle Handle used for this request. Specifies jobRing.
6310  * param[out] descriptor memory for CAAM commands
6311  * param plaintext Input plaintext to encrypt
6312  * param[out] ciphertext Output ciphertext
6313  * param size Size of input and output data in bytes
6314  * param iv Input initial block.
6315  * param key1 First input key for key bundle
6316  * param key2 Second input key for key bundle
6317  * return Status from descriptor push
6318  */
CAAM_DES2_EncryptCfbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE])6319 status_t CAAM_DES2_EncryptCfbNonBlocking(CAAM_Type *base,
6320                                          caam_handle_t *handle,
6321                                          caam_desc_cipher_des_t descriptor,
6322                                          const uint8_t *plaintext,
6323                                          uint8_t *ciphertext,
6324                                          size_t size,
6325                                          const uint8_t iv[CAAM_DES_IV_SIZE],
6326                                          const uint8_t key1[CAAM_DES_KEY_SIZE],
6327                                          const uint8_t key2[CAAM_DES_KEY_SIZE])
6328 {
6329     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
6330 
6331     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
6332      * Data lenght limit is 2^16 bytes = 65 536 bytes.
6333      * Note: You can still call several times instead
6334      */
6335     if (size > 0xFFFFUL)
6336     {
6337         return kStatus_CAAM_DataOverflow;
6338     }
6339 
6340     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
6341     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
6342     descriptor[1] |= 2U * CAAM_DES_KEY_SIZE;
6343     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key1, CAAM_DES_KEY_SIZE);
6344     (void)caam_memcpy(&descriptor[4], (const uint32_t *)(uintptr_t)key2, CAAM_DES_KEY_SIZE);
6345     descriptor[6] = DESC_JUMP_2; /* context, jump to currIdx+2 = 8 (LOAD) */
6346     descriptor[9] = ADD_OFFSET((uint32_t)iv);
6347     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
6348     descriptor[11] = ADD_OFFSET((uint32_t)plaintext);
6349     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
6350     descriptor[13] = ADD_OFFSET((uint32_t)ciphertext);
6351     descriptor[14] |= (uint32_t)kCAAM_ModeCFB; /* AAI = 30h = CFB */
6352     descriptor[14] |= 1u;                      /* add ENC bit to specify Encrypt OPERATION */
6353     descriptor[14] |= 0x10000U;                /* 3DES */
6354     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
6355 }
6356 
6357 /*!
6358  * brief Decrypts triple DES using CFB block mode with two keys.
6359  *
6360  * Decrypts triple DES using CFB block mode with two keys.
6361  *
6362  * param base CAAM peripheral base address
6363  * param handle Handle used for this request. Specifies jobRing.
6364  * param ciphertext Input ciphertext to decrypt
6365  * param[out] plaintext Output plaintext
6366  * param size Size of input and output data in bytes
6367  * param iv Input initial block.
6368  * param key1 First input key for key bundle
6369  * param key2 Second input key for key bundle
6370  * return Status from encrypt/decrypt operation
6371  */
CAAM_DES2_DecryptCfb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE])6372 status_t CAAM_DES2_DecryptCfb(CAAM_Type *base,
6373                               caam_handle_t *handle,
6374                               const uint8_t *ciphertext,
6375                               uint8_t *plaintext,
6376                               size_t size,
6377                               const uint8_t iv[CAAM_DES_IV_SIZE],
6378                               const uint8_t key1[CAAM_DES_KEY_SIZE],
6379                               const uint8_t key2[CAAM_DES_KEY_SIZE])
6380 {
6381     status_t status;
6382     caam_desc_cipher_des_t descBuf;
6383 
6384     do
6385     {
6386         status = CAAM_DES2_DecryptCfbNonBlocking(base, handle, descBuf, ciphertext, plaintext, size, iv, key1, key2);
6387     } while (status == kStatus_CAAM_Again);
6388 
6389     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
6390 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
6391     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
6392     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
6393     DCACHE_InvalidateByRange((uint32_t)plaintext, size);
6394 #endif /* CAAM_OUT_INVALIDATE */
6395     return status;
6396 }
6397 
6398 /*!
6399  * brief Decrypts triple DES using CFB block mode with two keys.
6400  *
6401  * Decrypts triple DES using CFB block mode with two keys.
6402  *
6403  * param base CAAM peripheral base address
6404  * param handle Handle used for this request. Specifies jobRing.
6405  * param[out] descriptor memory for CAAM commands
6406  * param ciphertext Input ciphertext to decrypt
6407  * param[out] plaintext Output plaintext
6408  * param size Size of input and output data in bytes
6409  * param iv Input initial block.
6410  * param key1 First input key for key bundle
6411  * param key2 Second input key for key bundle
6412  * return Status from descriptor push
6413  */
CAAM_DES2_DecryptCfbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE])6414 status_t CAAM_DES2_DecryptCfbNonBlocking(CAAM_Type *base,
6415                                          caam_handle_t *handle,
6416                                          caam_desc_cipher_des_t descriptor,
6417                                          const uint8_t *ciphertext,
6418                                          uint8_t *plaintext,
6419                                          size_t size,
6420                                          const uint8_t iv[CAAM_DES_IV_SIZE],
6421                                          const uint8_t key1[CAAM_DES_KEY_SIZE],
6422                                          const uint8_t key2[CAAM_DES_KEY_SIZE])
6423 {
6424     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
6425 
6426     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
6427      * Data lenght limit is 2^16 bytes = 65 536 bytes.
6428      * Note: You can still call several times instead
6429      */
6430     if (size > 0xFFFFUL)
6431     {
6432         return kStatus_CAAM_DataOverflow;
6433     }
6434 
6435     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
6436     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
6437     descriptor[1] |= 2U * CAAM_DES_KEY_SIZE;
6438     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key1, CAAM_DES_KEY_SIZE);
6439     (void)caam_memcpy(&descriptor[4], (const uint32_t *)(uintptr_t)key2, CAAM_DES_KEY_SIZE);
6440     descriptor[6] = DESC_JUMP_2; /* context, jump to currIdx+2 = 8 (LOAD) */
6441     descriptor[9] = ADD_OFFSET((uint32_t)iv);
6442     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
6443     descriptor[11] = ADD_OFFSET((uint32_t)ciphertext);
6444     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
6445     descriptor[13] = ADD_OFFSET((uint32_t)plaintext);
6446     descriptor[14] |= (uint32_t)kCAAM_ModeCFB; /* AAI = 30h = CFB */
6447     descriptor[14] |= 0x10000U;                /* 3DES */
6448     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
6449 }
6450 
6451 /*!
6452  * brief Encrypts triple DES using OFB block mode with two keys.
6453  *
6454  * Encrypts triple DES using OFB block mode with two keys.
6455  *
6456  * param base CAAM peripheral base address
6457  * param handle Handle used for this request. Specifies jobRing.
6458  * param plaintext Input plaintext to encrypt
6459  * param[out] ciphertext Output ciphertext
6460  * param size Size of input and output data in bytes
6461  * param iv Input unique input vector. The OFB mode requires that the IV be unique
6462  *           for each execution of the mode under the given key.
6463  * param key1 First input key for key bundle
6464  * param key2 Second input key for key bundle
6465  * return Status from encrypt/decrypt operation
6466  */
CAAM_DES2_EncryptOfb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE])6467 status_t CAAM_DES2_EncryptOfb(CAAM_Type *base,
6468                               caam_handle_t *handle,
6469                               const uint8_t *plaintext,
6470                               uint8_t *ciphertext,
6471                               size_t size,
6472                               const uint8_t iv[CAAM_DES_IV_SIZE],
6473                               const uint8_t key1[CAAM_DES_KEY_SIZE],
6474                               const uint8_t key2[CAAM_DES_KEY_SIZE])
6475 {
6476     status_t status;
6477     caam_desc_cipher_des_t descBuf;
6478 
6479     do
6480     {
6481         status = CAAM_DES2_EncryptOfbNonBlocking(base, handle, descBuf, plaintext, ciphertext, size, iv, key1, key2);
6482     } while (status == kStatus_CAAM_Again);
6483 
6484     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
6485 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
6486     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
6487     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
6488     DCACHE_InvalidateByRange((uint32_t)ciphertext, size);
6489 #endif /* CAAM_OUT_INVALIDATE */
6490     return status;
6491 }
6492 
6493 /*!
6494  * brief Encrypts triple DES using OFB block mode with two keys.
6495  *
6496  * Encrypts triple DES using OFB block mode with two keys.
6497  *
6498  * param base CAAM peripheral base address
6499  * param handle Handle used for this request. Specifies jobRing.
6500  * param[out] descriptor memory for CAAM commands
6501  * param plaintext Input plaintext to encrypt
6502  * param[out] ciphertext Output ciphertext
6503  * param size Size of input and output data in bytes
6504  * param iv Input unique input vector. The OFB mode requires that the IV be unique
6505  *           for each execution of the mode under the given key.
6506  * param key1 First input key for key bundle
6507  * param key2 Second input key for key bundle
6508  * return Status from descriptor push
6509  */
CAAM_DES2_EncryptOfbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE])6510 status_t CAAM_DES2_EncryptOfbNonBlocking(CAAM_Type *base,
6511                                          caam_handle_t *handle,
6512                                          caam_desc_cipher_des_t descriptor,
6513                                          const uint8_t *plaintext,
6514                                          uint8_t *ciphertext,
6515                                          size_t size,
6516                                          const uint8_t iv[CAAM_DES_IV_SIZE],
6517                                          const uint8_t key1[CAAM_DES_KEY_SIZE],
6518                                          const uint8_t key2[CAAM_DES_KEY_SIZE])
6519 {
6520     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
6521 
6522     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
6523      * Data lenght limit is 2^16 bytes = 65 536 bytes.
6524      * Note: You can still call several times instead
6525      */
6526     if (size > 0xFFFFUL)
6527     {
6528         return kStatus_CAAM_DataOverflow;
6529     }
6530 
6531     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
6532     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
6533     descriptor[1] |= 2U * CAAM_DES_KEY_SIZE;
6534     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key1, CAAM_DES_KEY_SIZE);
6535     (void)caam_memcpy(&descriptor[4], (const uint32_t *)(uintptr_t)key2, CAAM_DES_KEY_SIZE);
6536     descriptor[6] = DESC_JUMP_2; /* context, jump to currIdx+2 = 8 (LOAD) */
6537     descriptor[9] = ADD_OFFSET((uint32_t)iv);
6538     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
6539     descriptor[11] = ADD_OFFSET((uint32_t)plaintext);
6540     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
6541     descriptor[13] = ADD_OFFSET((uint32_t)ciphertext);
6542     descriptor[14] |= (uint32_t)kCAAM_ModeOFB; /* AAI = 40h = OFB */
6543     descriptor[14] |= 1u;                      /* add ENC bit to specify Encrypt OPERATION */
6544     descriptor[14] |= 0x10000U;                /* 3DES */
6545     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
6546 }
6547 
6548 /*!
6549  * brief Decrypts triple DES using OFB block mode with two keys.
6550  *
6551  * Decrypts triple DES using OFB block mode with two keys.
6552  *
6553  * param base CAAM peripheral base address
6554  * param handle Handle used for this request. Specifies jobRing.
6555  * param ciphertext Input ciphertext to decrypt
6556  * param[out] plaintext Output plaintext
6557  * param size Size of input and output data in bytes
6558  * param iv Input unique input vector. The OFB mode requires that the IV be unique
6559  *           for each execution of the mode under the given key.
6560  * param key1 First input key for key bundle
6561  * param key2 Second input key for key bundle
6562  * return Status from encrypt/decrypt operation
6563  */
CAAM_DES2_DecryptOfb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE])6564 status_t CAAM_DES2_DecryptOfb(CAAM_Type *base,
6565                               caam_handle_t *handle,
6566                               const uint8_t *ciphertext,
6567                               uint8_t *plaintext,
6568                               size_t size,
6569                               const uint8_t iv[CAAM_DES_IV_SIZE],
6570                               const uint8_t key1[CAAM_DES_KEY_SIZE],
6571                               const uint8_t key2[CAAM_DES_KEY_SIZE])
6572 {
6573     status_t status;
6574     caam_desc_cipher_des_t descBuf;
6575 
6576     do
6577     {
6578         status = CAAM_DES2_DecryptOfbNonBlocking(base, handle, descBuf, ciphertext, plaintext, size, iv, key1, key2);
6579     } while (status == kStatus_CAAM_Again);
6580 
6581     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
6582 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
6583     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
6584     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
6585     DCACHE_InvalidateByRange((uint32_t)plaintext, size);
6586 #endif /* CAAM_OUT_INVALIDATE */
6587     return status;
6588 }
6589 
6590 /*!
6591  * brief Decrypts triple DES using OFB block mode with two keys.
6592  *
6593  * Decrypts triple DES using OFB block mode with two keys.
6594  *
6595  * param base CAAM peripheral base address
6596  * param handle Handle used for this request. Specifies jobRing.
6597  * param[out] descriptor memory for CAAM commands
6598  * param ciphertext Input ciphertext to decrypt
6599  * param[out] plaintext Output plaintext
6600  * param size Size of input and output data in bytes
6601  * param iv Input unique input vector. The OFB mode requires that the IV be unique
6602  *           for each execution of the mode under the given key.
6603  * param key1 First input key for key bundle
6604  * param key2 Second input key for key bundle
6605  * return Status from descriptor push
6606  */
CAAM_DES2_DecryptOfbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE])6607 status_t CAAM_DES2_DecryptOfbNonBlocking(CAAM_Type *base,
6608                                          caam_handle_t *handle,
6609                                          caam_desc_cipher_des_t descriptor,
6610                                          const uint8_t *ciphertext,
6611                                          uint8_t *plaintext,
6612                                          size_t size,
6613                                          const uint8_t iv[CAAM_DES_IV_SIZE],
6614                                          const uint8_t key1[CAAM_DES_KEY_SIZE],
6615                                          const uint8_t key2[CAAM_DES_KEY_SIZE])
6616 {
6617     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
6618 
6619     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
6620      * Data lenght limit is 2^16 bytes = 65 536 bytes.
6621      * Note: You can still call several times instead
6622      */
6623     if (size > 0xFFFFUL)
6624     {
6625         return kStatus_CAAM_DataOverflow;
6626     }
6627 
6628     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
6629     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
6630     descriptor[1] |= 2U * CAAM_DES_KEY_SIZE;
6631     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key1, CAAM_DES_KEY_SIZE);
6632     (void)caam_memcpy(&descriptor[4], (const uint32_t *)(uintptr_t)key2, CAAM_DES_KEY_SIZE);
6633     descriptor[6] = DESC_JUMP_2; /* context, jump to currIdx+2 = 8 (LOAD) */
6634     descriptor[9] = ADD_OFFSET((uint32_t)iv);
6635     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
6636     descriptor[11] = ADD_OFFSET((uint32_t)ciphertext);
6637     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
6638     descriptor[13] = ADD_OFFSET((uint32_t)plaintext);
6639     descriptor[14] |= (uint32_t)kCAAM_ModeOFB; /* AAI = 40h = OFB */
6640     descriptor[14] |= 0x10000U;                /* 3DES */
6641     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
6642 }
6643 
6644 /*!
6645  * brief Encrypts triple DES using ECB block mode with three keys.
6646  *
6647  * Encrypts triple DES using ECB block mode with three keys.
6648  *
6649  * param base CAAM peripheral base address
6650  * param handle Handle used for this request. Specifies jobRing.
6651  * param plaintext Input plaintext to encrypt
6652  * param[out] ciphertext Output ciphertext
6653  * param size Size of input and output data in bytes. Must be multiple of 8 bytes.
6654  * param key1 First input key for key bundle
6655  * param key2 Second input key for key bundle
6656  * param key3 Third input key for key bundle
6657  * return Status from encrypt/decrypt operation
6658  */
CAAM_DES3_EncryptEcb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE],const uint8_t key3[CAAM_DES_KEY_SIZE])6659 status_t CAAM_DES3_EncryptEcb(CAAM_Type *base,
6660                               caam_handle_t *handle,
6661                               const uint8_t *plaintext,
6662                               uint8_t *ciphertext,
6663                               size_t size,
6664                               const uint8_t key1[CAAM_DES_KEY_SIZE],
6665                               const uint8_t key2[CAAM_DES_KEY_SIZE],
6666                               const uint8_t key3[CAAM_DES_KEY_SIZE])
6667 {
6668     caam_desc_cipher_des_t descBuf;
6669     status_t status;
6670 
6671     status = CAAM_DES3_EncryptEcbNonBlocking(base, handle, descBuf, plaintext, ciphertext, size, key1, key2, key3);
6672     if (status != 0)
6673     {
6674         return status;
6675     }
6676     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
6677 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
6678     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
6679     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
6680     DCACHE_InvalidateByRange((uint32_t)ciphertext, size);
6681 #endif /* CAAM_OUT_INVALIDATE */
6682     return status;
6683 }
6684 
6685 /*!
6686  * brief Encrypts triple DES using ECB block mode with three keys.
6687  *
6688  * Encrypts triple DES using ECB block mode with three keys.
6689  *
6690  * param base CAAM peripheral base address
6691  * param handle Handle used for this request. Specifies jobRing.
6692  * param[out] descriptor memory for CAAM commands
6693  * param plaintext Input plaintext to encrypt
6694  * param[out] ciphertext Output ciphertext
6695  * param size Size of input and output data in bytes. Must be multiple of 8 bytes.
6696  * param key1 First input key for key bundle
6697  * param key2 Second input key for key bundle
6698  * param key3 Third input key for key bundle
6699  * return Status from descriptor push
6700  */
CAAM_DES3_EncryptEcbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE],const uint8_t key3[CAAM_DES_KEY_SIZE])6701 status_t CAAM_DES3_EncryptEcbNonBlocking(CAAM_Type *base,
6702                                          caam_handle_t *handle,
6703                                          caam_desc_cipher_des_t descriptor,
6704                                          const uint8_t *plaintext,
6705                                          uint8_t *ciphertext,
6706                                          size_t size,
6707                                          const uint8_t key1[CAAM_DES_KEY_SIZE],
6708                                          const uint8_t key2[CAAM_DES_KEY_SIZE],
6709                                          const uint8_t key3[CAAM_DES_KEY_SIZE])
6710 {
6711     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
6712 
6713     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
6714      * Data lenght limit is 2^16 bytes = 65 536 bytes.
6715      * Note: You can still call several times instead
6716      */
6717     if (size > 0xFFFFUL)
6718     {
6719         return kStatus_CAAM_DataOverflow;
6720     }
6721 
6722     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
6723     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
6724     descriptor[1] |= 3U * CAAM_DES_KEY_SIZE;
6725     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key1, CAAM_DES_KEY_SIZE);
6726     (void)caam_memcpy(&descriptor[4], (const uint32_t *)(uintptr_t)key2, CAAM_DES_KEY_SIZE);
6727     (void)caam_memcpy(&descriptor[6], (const uint32_t *)(uintptr_t)key3, CAAM_DES_KEY_SIZE);
6728     descriptor[8] = DESC_JUMP_2; /* ECB has no context, jump to currIdx+2 = 10 (FIFO LOAD) */
6729     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
6730     descriptor[11] = ADD_OFFSET((uint32_t)plaintext);
6731     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
6732     descriptor[13] = ADD_OFFSET((uint32_t)ciphertext);
6733     descriptor[14] |= 0x201u;   /* add ENC bit to specify Encrypt OPERATION, AAI = 20h */
6734     descriptor[14] |= 0x10000U; /* 3DES */
6735 
6736     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
6737 }
6738 
6739 /*!
6740  * brief Decrypts triple DES using ECB block mode with three keys.
6741  *
6742  * Decrypts triple DES using ECB block mode with three keys.
6743  *
6744  * param base CAAM peripheral base address
6745  * param handle Handle used for this request. Specifies jobRing.
6746  * param ciphertext Input ciphertext to decrypt
6747  * param[out] plaintext Output plaintext
6748  * param size Size of input and output data in bytes. Must be multiple of 8 bytes.
6749  * param key1 First input key for key bundle
6750  * param key2 Second input key for key bundle
6751  * param key3 Third input key for key bundle
6752  * return Status from encrypt/decrypt operation
6753  */
CAAM_DES3_DecryptEcb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE],const uint8_t key3[CAAM_DES_KEY_SIZE])6754 status_t CAAM_DES3_DecryptEcb(CAAM_Type *base,
6755                               caam_handle_t *handle,
6756                               const uint8_t *ciphertext,
6757                               uint8_t *plaintext,
6758                               size_t size,
6759                               const uint8_t key1[CAAM_DES_KEY_SIZE],
6760                               const uint8_t key2[CAAM_DES_KEY_SIZE],
6761                               const uint8_t key3[CAAM_DES_KEY_SIZE])
6762 {
6763     caam_desc_cipher_des_t descBuf;
6764     status_t status;
6765 
6766     status = CAAM_DES3_DecryptEcbNonBlocking(base, handle, descBuf, ciphertext, plaintext, size, key1, key2, key3);
6767     if (status != 0)
6768     {
6769         return status;
6770     }
6771     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
6772 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
6773     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
6774     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
6775     DCACHE_InvalidateByRange((uint32_t)plaintext, size);
6776 #endif /* CAAM_OUT_INVALIDATE */
6777     return status;
6778 }
6779 
6780 /*!
6781  * brief Decrypts triple DES using ECB block mode with three keys.
6782  *
6783  * Decrypts triple DES using ECB block mode with three keys.
6784  *
6785  * param base CAAM peripheral base address
6786  * param handle Handle used for this request. Specifies jobRing.
6787  * param[out] descriptor memory for CAAM commands
6788  * param ciphertext Input ciphertext to decrypt
6789  * param[out] plaintext Output plaintext
6790  * param size Size of input and output data in bytes. Must be multiple of 8 bytes.
6791  * param key1 First input key for key bundle
6792  * param key2 Second input key for key bundle
6793  * param key3 Third input key for key bundle
6794  * return Status from descriptor push
6795  */
CAAM_DES3_DecryptEcbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE],const uint8_t key3[CAAM_DES_KEY_SIZE])6796 status_t CAAM_DES3_DecryptEcbNonBlocking(CAAM_Type *base,
6797                                          caam_handle_t *handle,
6798                                          caam_desc_cipher_des_t descriptor,
6799                                          const uint8_t *ciphertext,
6800                                          uint8_t *plaintext,
6801                                          size_t size,
6802                                          const uint8_t key1[CAAM_DES_KEY_SIZE],
6803                                          const uint8_t key2[CAAM_DES_KEY_SIZE],
6804                                          const uint8_t key3[CAAM_DES_KEY_SIZE])
6805 {
6806     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
6807 
6808     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
6809      * Data lenght limit is 2^16 bytes = 65 536 bytes.
6810      * Note: You can still call several times instead
6811      */
6812     if (size > 0xFFFFUL)
6813     {
6814         return kStatus_CAAM_DataOverflow;
6815     }
6816 
6817     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
6818     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
6819     descriptor[1] |= 3U * CAAM_DES_KEY_SIZE;
6820     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key1, CAAM_DES_KEY_SIZE);
6821     (void)caam_memcpy(&descriptor[4], (const uint32_t *)(uintptr_t)key2, CAAM_DES_KEY_SIZE);
6822     (void)caam_memcpy(&descriptor[6], (const uint32_t *)(uintptr_t)key3, CAAM_DES_KEY_SIZE);
6823     descriptor[8] = DESC_JUMP_2; /* ECB has no context, jump to currIdx+2 = 10 (FIFO LOAD) */
6824     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
6825     descriptor[11] = ADD_OFFSET((uint32_t)ciphertext);
6826     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
6827     descriptor[13] = ADD_OFFSET((uint32_t)plaintext);
6828     descriptor[14] |= (uint32_t)kCAAM_ModeECB; /* AAI = 20h */
6829     descriptor[14] |= 0x10000U;                /* 3DES */
6830 
6831     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
6832 }
6833 
6834 /*!
6835  * brief Encrypts triple DES using CBC block mode with three keys.
6836  *
6837  * Encrypts triple DES using CBC block mode with three keys.
6838  *
6839  * param base CAAM peripheral base address
6840  * param handle Handle used for this request. Specifies jobRing.
6841  * param plaintext Input plaintext to encrypt
6842  * param[out] ciphertext Output ciphertext
6843  * param size Size of input data in bytes
6844  * param iv Input initial vector to combine with the first plaintext block.
6845  *           The iv does not need to be secret, but it must be unpredictable.
6846  * param key1 First input key for key bundle
6847  * param key2 Second input key for key bundle
6848  * param key3 Third input key for key bundle
6849  * return Status from encrypt/decrypt operation
6850  */
CAAM_DES3_EncryptCbc(CAAM_Type * base,caam_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE],const uint8_t key3[CAAM_DES_KEY_SIZE])6851 status_t CAAM_DES3_EncryptCbc(CAAM_Type *base,
6852                               caam_handle_t *handle,
6853                               const uint8_t *plaintext,
6854                               uint8_t *ciphertext,
6855                               size_t size,
6856                               const uint8_t iv[CAAM_DES_IV_SIZE],
6857                               const uint8_t key1[CAAM_DES_KEY_SIZE],
6858                               const uint8_t key2[CAAM_DES_KEY_SIZE],
6859                               const uint8_t key3[CAAM_DES_KEY_SIZE])
6860 {
6861     status_t status;
6862     caam_desc_cipher_des_t descBuf;
6863 
6864     do
6865     {
6866         status =
6867             CAAM_DES3_EncryptCbcNonBlocking(base, handle, descBuf, plaintext, ciphertext, size, iv, key1, key2, key3);
6868     } while (status == kStatus_CAAM_Again);
6869 
6870     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
6871 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
6872     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
6873     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
6874     DCACHE_InvalidateByRange((uint32_t)ciphertext, size);
6875 #endif /* CAAM_OUT_INVALIDATE */
6876     return status;
6877 }
6878 
6879 /*!
6880  * brief Encrypts triple DES using CBC block mode with three keys.
6881  *
6882  * Encrypts triple DES using CBC block mode with three keys.
6883  *
6884  * param base CAAM peripheral base address
6885  * param handle Handle used for this request. Specifies jobRing.
6886  * param[out] descriptor memory for CAAM commands
6887  * param plaintext Input plaintext to encrypt
6888  * param[out] ciphertext Output ciphertext
6889  * param size Size of input data in bytes
6890  * param iv Input initial vector to combine with the first plaintext block.
6891  *           The iv does not need to be secret, but it must be unpredictable.
6892  * param key1 First input key for key bundle
6893  * param key2 Second input key for key bundle
6894  * param key3 Third input key for key bundle
6895  * return Status from descriptor push
6896  */
CAAM_DES3_EncryptCbcNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE],const uint8_t key3[CAAM_DES_KEY_SIZE])6897 status_t CAAM_DES3_EncryptCbcNonBlocking(CAAM_Type *base,
6898                                          caam_handle_t *handle,
6899                                          caam_desc_cipher_des_t descriptor,
6900                                          const uint8_t *plaintext,
6901                                          uint8_t *ciphertext,
6902                                          size_t size,
6903                                          const uint8_t iv[CAAM_DES_IV_SIZE],
6904                                          const uint8_t key1[CAAM_DES_KEY_SIZE],
6905                                          const uint8_t key2[CAAM_DES_KEY_SIZE],
6906                                          const uint8_t key3[CAAM_DES_KEY_SIZE])
6907 {
6908     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
6909 
6910     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
6911      * Data lenght limit is 2^16 bytes = 65 536 bytes.
6912      * Note: You can still call several times instead
6913      */
6914     if (size > 0xFFFFUL)
6915     {
6916         return kStatus_CAAM_DataOverflow;
6917     }
6918 
6919     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
6920     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
6921     descriptor[1] |= 3U * CAAM_DES_KEY_SIZE;
6922     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key1, CAAM_DES_KEY_SIZE);
6923     (void)caam_memcpy(&descriptor[4], (const uint32_t *)(uintptr_t)key2, CAAM_DES_KEY_SIZE);
6924     (void)caam_memcpy(&descriptor[6], (const uint32_t *)(uintptr_t)key3, CAAM_DES_KEY_SIZE);
6925     descriptor[9] = ADD_OFFSET((uint32_t)iv);
6926     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
6927     descriptor[11] = ADD_OFFSET((uint32_t)plaintext);
6928     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
6929     descriptor[13] = ADD_OFFSET((uint32_t)ciphertext);
6930     descriptor[14] |= (uint32_t)kCAAM_ModeCBC; /* AAI = 10h */
6931     descriptor[14] |= 1u;                      /* add ENC bit to specify Encrypt OPERATION */
6932     descriptor[14] |= 0x10000U;                /* 3DES */
6933     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
6934 }
6935 
6936 /*!
6937  * brief Decrypts triple DES using CBC block mode with three keys.
6938  *
6939  * Decrypts triple DES using CBC block mode with three keys.
6940  *
6941  * param base CAAM peripheral base address
6942  * param handle Handle used for this request. Specifies jobRing.
6943  * param ciphertext Input ciphertext to decrypt
6944  * param[out] plaintext Output plaintext
6945  * param size Size of input and output data in bytes
6946  * param iv Input initial vector to combine with the first plaintext block.
6947  *           The iv does not need to be secret, but it must be unpredictable.
6948  * param key1 First input key for key bundle
6949  * param key2 Second input key for key bundle
6950  * param key3 Third input key for key bundle
6951  * return Status from encrypt/decrypt operation
6952  */
CAAM_DES3_DecryptCbc(CAAM_Type * base,caam_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE],const uint8_t key3[CAAM_DES_KEY_SIZE])6953 status_t CAAM_DES3_DecryptCbc(CAAM_Type *base,
6954                               caam_handle_t *handle,
6955                               const uint8_t *ciphertext,
6956                               uint8_t *plaintext,
6957                               size_t size,
6958                               const uint8_t iv[CAAM_DES_IV_SIZE],
6959                               const uint8_t key1[CAAM_DES_KEY_SIZE],
6960                               const uint8_t key2[CAAM_DES_KEY_SIZE],
6961                               const uint8_t key3[CAAM_DES_KEY_SIZE])
6962 {
6963     status_t status;
6964     caam_desc_cipher_des_t descBuf;
6965 
6966     do
6967     {
6968         status =
6969             CAAM_DES3_DecryptCbcNonBlocking(base, handle, descBuf, ciphertext, plaintext, size, iv, key1, key2, key3);
6970     } while (status == kStatus_CAAM_Again);
6971 
6972     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
6973 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
6974     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
6975     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
6976     DCACHE_InvalidateByRange((uint32_t)plaintext, size);
6977 #endif /* CAAM_OUT_INVALIDATE */
6978     return status;
6979 }
6980 
6981 /*!
6982  * brief Decrypts triple DES using CBC block mode with three keys.
6983  *
6984  * Decrypts triple DES using CBC block mode with three keys.
6985  *
6986  * param base CAAM peripheral base address
6987  * param handle Handle used for this request. Specifies jobRing.
6988  * param[out] descriptor memory for CAAM commands
6989  * param ciphertext Input ciphertext to decrypt
6990  * param[out] plaintext Output plaintext
6991  * param size Size of input and output data in bytes
6992  * param iv Input initial vector to combine with the first plaintext block.
6993  *           The iv does not need to be secret, but it must be unpredictable.
6994  * param key1 First input key for key bundle
6995  * param key2 Second input key for key bundle
6996  * param key3 Third input key for key bundle
6997  * return Status from descriptor push
6998  */
CAAM_DES3_DecryptCbcNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE],const uint8_t key3[CAAM_DES_KEY_SIZE])6999 status_t CAAM_DES3_DecryptCbcNonBlocking(CAAM_Type *base,
7000                                          caam_handle_t *handle,
7001                                          caam_desc_cipher_des_t descriptor,
7002                                          const uint8_t *ciphertext,
7003                                          uint8_t *plaintext,
7004                                          size_t size,
7005                                          const uint8_t iv[CAAM_DES_IV_SIZE],
7006                                          const uint8_t key1[CAAM_DES_KEY_SIZE],
7007                                          const uint8_t key2[CAAM_DES_KEY_SIZE],
7008                                          const uint8_t key3[CAAM_DES_KEY_SIZE])
7009 {
7010     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
7011 
7012     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
7013      * Data lenght limit is 2^16 bytes = 65 536 bytes.
7014      * Note: You can still call several times instead
7015      */
7016     if (size > 0xFFFFUL)
7017     {
7018         return kStatus_CAAM_DataOverflow;
7019     }
7020 
7021     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
7022     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
7023     descriptor[1] |= 3U * CAAM_DES_KEY_SIZE;
7024     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key1, CAAM_DES_KEY_SIZE);
7025     (void)caam_memcpy(&descriptor[4], (const uint32_t *)(uintptr_t)key2, CAAM_DES_KEY_SIZE);
7026     (void)caam_memcpy(&descriptor[6], (const uint32_t *)(uintptr_t)key3, CAAM_DES_KEY_SIZE);
7027     descriptor[9] = ADD_OFFSET((uint32_t)iv);
7028     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
7029     descriptor[11] = ADD_OFFSET((uint32_t)ciphertext);
7030     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
7031     descriptor[13] = ADD_OFFSET((uint32_t)plaintext);
7032     descriptor[14] |= (uint32_t)kCAAM_ModeCBC; /* AAI = 10h */
7033     descriptor[14] |= 0x10000U;                /* 3DES */
7034     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
7035 }
7036 
7037 /*!
7038  * brief Encrypts triple DES using CFB block mode with three keys.
7039  *
7040  * Encrypts triple DES using CFB block mode with three keys.
7041  *
7042  * param base CAAM peripheral base address
7043  * param plaintext Input plaintext to encrypt
7044  * param[out] ciphertext Output ciphertext
7045  * param size Size of input and ouput data in bytes
7046  * param iv Input initial block.
7047  * param key1 First input key for key bundle
7048  * param key2 Second input key for key bundle
7049  * param key3 Third input key for key bundle
7050  * return Status from encrypt/decrypt operation
7051  */
CAAM_DES3_EncryptCfb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE],const uint8_t key3[CAAM_DES_KEY_SIZE])7052 status_t CAAM_DES3_EncryptCfb(CAAM_Type *base,
7053                               caam_handle_t *handle,
7054                               const uint8_t *plaintext,
7055                               uint8_t *ciphertext,
7056                               size_t size,
7057                               const uint8_t iv[CAAM_DES_IV_SIZE],
7058                               const uint8_t key1[CAAM_DES_KEY_SIZE],
7059                               const uint8_t key2[CAAM_DES_KEY_SIZE],
7060                               const uint8_t key3[CAAM_DES_KEY_SIZE])
7061 {
7062     status_t status;
7063     caam_desc_cipher_des_t descBuf;
7064 
7065     do
7066     {
7067         status =
7068             CAAM_DES3_EncryptCfbNonBlocking(base, handle, descBuf, plaintext, ciphertext, size, iv, key1, key2, key3);
7069     } while (status == kStatus_CAAM_Again);
7070 
7071     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
7072 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
7073     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
7074     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
7075     DCACHE_InvalidateByRange((uint32_t)ciphertext, size);
7076 #endif /* CAAM_OUT_INVALIDATE */
7077     return status;
7078 }
7079 
7080 /*!
7081  * brief Encrypts triple DES using CFB block mode with three keys.
7082  *
7083  * Encrypts triple DES using CFB block mode with three keys.
7084  *
7085  * param base CAAM peripheral base address
7086  * param handle Handle used for this request. Specifies jobRing.
7087  * param[out] descriptor memory for CAAM commands
7088  * param plaintext Input plaintext to encrypt
7089  * param[out] ciphertext Output ciphertext
7090  * param size Size of input and ouput data in bytes
7091  * param iv Input initial block.
7092  * param key1 First input key for key bundle
7093  * param key2 Second input key for key bundle
7094  * param key3 Third input key for key bundle
7095  * return Status from descriptor push
7096  */
CAAM_DES3_EncryptCfbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE],const uint8_t key3[CAAM_DES_KEY_SIZE])7097 status_t CAAM_DES3_EncryptCfbNonBlocking(CAAM_Type *base,
7098                                          caam_handle_t *handle,
7099                                          caam_desc_cipher_des_t descriptor,
7100                                          const uint8_t *plaintext,
7101                                          uint8_t *ciphertext,
7102                                          size_t size,
7103                                          const uint8_t iv[CAAM_DES_IV_SIZE],
7104                                          const uint8_t key1[CAAM_DES_KEY_SIZE],
7105                                          const uint8_t key2[CAAM_DES_KEY_SIZE],
7106                                          const uint8_t key3[CAAM_DES_KEY_SIZE])
7107 {
7108     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
7109 
7110     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
7111      * Data lenght limit is 2^16 bytes = 65 536 bytes.
7112      * Note: You can still call several times instead
7113      */
7114     if (size > 0xFFFFUL)
7115     {
7116         return kStatus_CAAM_DataOverflow;
7117     }
7118 
7119     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
7120     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
7121     descriptor[1] |= 3U * CAAM_DES_KEY_SIZE;
7122     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key1, CAAM_DES_KEY_SIZE);
7123     (void)caam_memcpy(&descriptor[4], (const uint32_t *)(uintptr_t)key2, CAAM_DES_KEY_SIZE);
7124     (void)caam_memcpy(&descriptor[6], (const uint32_t *)(uintptr_t)key3, CAAM_DES_KEY_SIZE);
7125     descriptor[9] = ADD_OFFSET((uint32_t)iv);
7126     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
7127     descriptor[11] = ADD_OFFSET((uint32_t)plaintext);
7128     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
7129     descriptor[13] = ADD_OFFSET((uint32_t)ciphertext);
7130     descriptor[14] |= (uint32_t)kCAAM_ModeCFB; /* AAI = 30h = CFB */
7131     descriptor[14] |= 1u;                      /* add ENC bit to specify Encrypt OPERATION */
7132     descriptor[14] |= 0x10000U;                /* 3DES */
7133     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
7134 }
7135 
7136 /*!
7137  * brief Decrypts triple DES using CFB block mode with three keys.
7138  *
7139  * Decrypts triple DES using CFB block mode with three keys.
7140  *
7141  * param base CAAM peripheral base address
7142  * param handle Handle used for this request. Specifies jobRing.
7143  * param ciphertext Input ciphertext to decrypt
7144  * param[out] plaintext Output plaintext
7145  * param size Size of input data in bytes
7146  * param iv Input initial block.
7147  * param key1 First input key for key bundle
7148  * param key2 Second input key for key bundle
7149  * param key3 Third input key for key bundle
7150  * return Status from encrypt/decrypt operation
7151  */
CAAM_DES3_DecryptCfb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE],const uint8_t key3[CAAM_DES_KEY_SIZE])7152 status_t CAAM_DES3_DecryptCfb(CAAM_Type *base,
7153                               caam_handle_t *handle,
7154                               const uint8_t *ciphertext,
7155                               uint8_t *plaintext,
7156                               size_t size,
7157                               const uint8_t iv[CAAM_DES_IV_SIZE],
7158                               const uint8_t key1[CAAM_DES_KEY_SIZE],
7159                               const uint8_t key2[CAAM_DES_KEY_SIZE],
7160                               const uint8_t key3[CAAM_DES_KEY_SIZE])
7161 {
7162     status_t status;
7163     caam_desc_cipher_des_t descBuf;
7164 
7165     do
7166     {
7167         status =
7168             CAAM_DES3_DecryptCfbNonBlocking(base, handle, descBuf, ciphertext, plaintext, size, iv, key1, key2, key3);
7169     } while (status == kStatus_CAAM_Again);
7170 
7171     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
7172 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
7173     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
7174     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
7175     DCACHE_InvalidateByRange((uint32_t)plaintext, size);
7176 #endif /* CAAM_OUT_INVALIDATE */
7177     return status;
7178 }
7179 
7180 /*!
7181  * brief Decrypts triple DES using CFB block mode with three keys.
7182  *
7183  * Decrypts triple DES using CFB block mode with three keys.
7184  *
7185  * param base CAAM peripheral base address
7186  * param handle Handle used for this request. Specifies jobRing.
7187  * param[out] descriptor memory for CAAM commands
7188  * param ciphertext Input ciphertext to decrypt
7189  * param[out] plaintext Output plaintext
7190  * param size Size of input data in bytes
7191  * param iv Input initial block.
7192  * param key1 First input key for key bundle
7193  * param key2 Second input key for key bundle
7194  * param key3 Third input key for key bundle
7195  * return Status from descriptor push
7196  */
CAAM_DES3_DecryptCfbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE],const uint8_t key3[CAAM_DES_KEY_SIZE])7197 status_t CAAM_DES3_DecryptCfbNonBlocking(CAAM_Type *base,
7198                                          caam_handle_t *handle,
7199                                          caam_desc_cipher_des_t descriptor,
7200                                          const uint8_t *ciphertext,
7201                                          uint8_t *plaintext,
7202                                          size_t size,
7203                                          const uint8_t iv[CAAM_DES_IV_SIZE],
7204                                          const uint8_t key1[CAAM_DES_KEY_SIZE],
7205                                          const uint8_t key2[CAAM_DES_KEY_SIZE],
7206                                          const uint8_t key3[CAAM_DES_KEY_SIZE])
7207 {
7208     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
7209 
7210     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
7211      * Data lenght limit is 2^16 bytes = 65 536 bytes.
7212      * Note: You can still call several times instead
7213      */
7214     if (size > 0xFFFFUL)
7215     {
7216         return kStatus_CAAM_DataOverflow;
7217     }
7218 
7219     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
7220     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
7221     descriptor[1] |= 3U * CAAM_DES_KEY_SIZE;
7222     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key1, CAAM_DES_KEY_SIZE);
7223     (void)caam_memcpy(&descriptor[4], (const uint32_t *)(uintptr_t)key2, CAAM_DES_KEY_SIZE);
7224     (void)caam_memcpy(&descriptor[6], (const uint32_t *)(uintptr_t)key3, CAAM_DES_KEY_SIZE);
7225     descriptor[9] = ADD_OFFSET((uint32_t)iv);
7226     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
7227     descriptor[11] = ADD_OFFSET((uint32_t)ciphertext);
7228     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
7229     descriptor[13] = ADD_OFFSET((uint32_t)plaintext);
7230     descriptor[14] |= (uint32_t)kCAAM_ModeCFB; /* AAI = 30h = CFB */
7231     descriptor[14] |= 0x10000U;                /* 3DES */
7232     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
7233 }
7234 
7235 /*!
7236  * brief Encrypts triple DES using OFB block mode with three keys.
7237  *
7238  * Encrypts triple DES using OFB block mode with three keys.
7239  *
7240  * param base CAAM peripheral base address
7241  * param plaintext Input plaintext to encrypt
7242  * param[out] ciphertext Output ciphertext
7243  * param size Size of input and output data in bytes
7244  * param iv Input unique input vector. The OFB mode requires that the IV be unique
7245  *           for each execution of the mode under the given key.
7246  * param key1 First input key for key bundle
7247  * param key2 Second input key for key bundle
7248  * param key3 Third input key for key bundle
7249  * return Status from encrypt/decrypt operation
7250  */
CAAM_DES3_EncryptOfb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE],const uint8_t key3[CAAM_DES_KEY_SIZE])7251 status_t CAAM_DES3_EncryptOfb(CAAM_Type *base,
7252                               caam_handle_t *handle,
7253                               const uint8_t *plaintext,
7254                               uint8_t *ciphertext,
7255                               size_t size,
7256                               const uint8_t iv[CAAM_DES_IV_SIZE],
7257                               const uint8_t key1[CAAM_DES_KEY_SIZE],
7258                               const uint8_t key2[CAAM_DES_KEY_SIZE],
7259                               const uint8_t key3[CAAM_DES_KEY_SIZE])
7260 {
7261     status_t status;
7262     caam_desc_cipher_des_t descBuf;
7263 
7264     do
7265     {
7266         status =
7267             CAAM_DES3_EncryptOfbNonBlocking(base, handle, descBuf, plaintext, ciphertext, size, iv, key1, key2, key3);
7268     } while (status == kStatus_CAAM_Again);
7269 
7270     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
7271 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
7272     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
7273     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
7274     DCACHE_InvalidateByRange((uint32_t)ciphertext, size);
7275 #endif /* CAAM_OUT_INVALIDATE */
7276     return status;
7277 }
7278 
7279 /*!
7280  * brief Encrypts triple DES using OFB block mode with three keys.
7281  *
7282  * Encrypts triple DES using OFB block mode with three keys.
7283  *
7284  * param base CAAM peripheral base address
7285  * param handle Handle used for this request. Specifies jobRing.
7286  * param[out] descriptor memory for CAAM commands
7287  * param plaintext Input plaintext to encrypt
7288  * param[out] ciphertext Output ciphertext
7289  * param size Size of input and output data in bytes
7290  * param iv Input unique input vector. The OFB mode requires that the IV be unique
7291  *           for each execution of the mode under the given key.
7292  * param key1 First input key for key bundle
7293  * param key2 Second input key for key bundle
7294  * param key3 Third input key for key bundle
7295  * return Status from descriptor push
7296  */
CAAM_DES3_EncryptOfbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * plaintext,uint8_t * ciphertext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE],const uint8_t key3[CAAM_DES_KEY_SIZE])7297 status_t CAAM_DES3_EncryptOfbNonBlocking(CAAM_Type *base,
7298                                          caam_handle_t *handle,
7299                                          caam_desc_cipher_des_t descriptor,
7300                                          const uint8_t *plaintext,
7301                                          uint8_t *ciphertext,
7302                                          size_t size,
7303                                          const uint8_t iv[CAAM_DES_IV_SIZE],
7304                                          const uint8_t key1[CAAM_DES_KEY_SIZE],
7305                                          const uint8_t key2[CAAM_DES_KEY_SIZE],
7306                                          const uint8_t key3[CAAM_DES_KEY_SIZE])
7307 {
7308     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
7309 
7310     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
7311      * Data lenght limit is 2^16 bytes = 65 536 bytes.
7312      * Note: You can still call several times instead
7313      */
7314     if (size > 0xFFFFUL)
7315     {
7316         return kStatus_CAAM_DataOverflow;
7317     }
7318 
7319     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
7320     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
7321     descriptor[1] |= 3U * CAAM_DES_KEY_SIZE;
7322     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key1, CAAM_DES_KEY_SIZE);
7323     (void)caam_memcpy(&descriptor[4], (const uint32_t *)(uintptr_t)key2, CAAM_DES_KEY_SIZE);
7324     (void)caam_memcpy(&descriptor[6], (const uint32_t *)(uintptr_t)key3, CAAM_DES_KEY_SIZE);
7325     descriptor[9] = ADD_OFFSET((uint32_t)iv);
7326     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
7327     descriptor[11] = ADD_OFFSET((uint32_t)plaintext);
7328     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
7329     descriptor[13] = ADD_OFFSET((uint32_t)ciphertext);
7330     descriptor[14] |= (uint32_t)kCAAM_ModeOFB; /* AAI = 40h = OFB */
7331     descriptor[14] |= 1u;                      /* add ENC bit to specify Encrypt OPERATION */
7332     descriptor[14] |= 0x10000U;                /* 3DES */
7333     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
7334 }
7335 
7336 /*!
7337  * brief Decrypts triple DES using OFB block mode with three keys.
7338  *
7339  * Decrypts triple DES using OFB block mode with three keys.
7340  *
7341  * param base CAAM peripheral base address
7342  * param handle Handle used for this request. Specifies jobRing.
7343  * param ciphertext Input ciphertext to decrypt
7344  * param[out] plaintext Output plaintext
7345  * param size Size of input and output data in bytes
7346  * param iv Input unique input vector. The OFB mode requires that the IV be unique
7347  *           for each execution of the mode under the given key.
7348  * param key1 First input key for key bundle
7349  * param key2 Second input key for key bundle
7350  * param key3 Third input key for key bundle
7351  * return Status from encrypt/decrypt operation
7352  */
CAAM_DES3_DecryptOfb(CAAM_Type * base,caam_handle_t * handle,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE],const uint8_t key3[CAAM_DES_KEY_SIZE])7353 status_t CAAM_DES3_DecryptOfb(CAAM_Type *base,
7354                               caam_handle_t *handle,
7355                               const uint8_t *ciphertext,
7356                               uint8_t *plaintext,
7357                               size_t size,
7358                               const uint8_t iv[CAAM_DES_IV_SIZE],
7359                               const uint8_t key1[CAAM_DES_KEY_SIZE],
7360                               const uint8_t key2[CAAM_DES_KEY_SIZE],
7361                               const uint8_t key3[CAAM_DES_KEY_SIZE])
7362 {
7363     status_t status;
7364     caam_desc_cipher_des_t descBuf;
7365 
7366     do
7367     {
7368         status =
7369             CAAM_DES3_DecryptOfbNonBlocking(base, handle, descBuf, ciphertext, plaintext, size, iv, key1, key2, key3);
7370     } while (status == kStatus_CAAM_Again);
7371 
7372     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
7373 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
7374     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
7375     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
7376     DCACHE_InvalidateByRange((uint32_t)plaintext, size);
7377 #endif /* CAAM_OUT_INVALIDATE */
7378     return status;
7379 }
7380 
7381 /*!
7382  * brief Decrypts triple DES using OFB block mode with three keys.
7383  *
7384  * Decrypts triple DES using OFB block mode with three keys.
7385  *
7386  * param base CAAM peripheral base address
7387  * param handle Handle used for this request. Specifies jobRing.
7388  * param[out] descriptor memory for CAAM commands
7389  * param ciphertext Input ciphertext to decrypt
7390  * param[out] plaintext Output plaintext
7391  * param size Size of input and output data in bytes
7392  * param iv Input unique input vector. The OFB mode requires that the IV be unique
7393  *           for each execution of the mode under the given key.
7394  * param key1 First input key for key bundle
7395  * param key2 Second input key for key bundle
7396  * param key3 Third input key for key bundle
7397  * return Status from descriptor push
7398  */
CAAM_DES3_DecryptOfbNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_cipher_des_t descriptor,const uint8_t * ciphertext,uint8_t * plaintext,size_t size,const uint8_t iv[CAAM_DES_IV_SIZE],const uint8_t key1[CAAM_DES_KEY_SIZE],const uint8_t key2[CAAM_DES_KEY_SIZE],const uint8_t key3[CAAM_DES_KEY_SIZE])7399 status_t CAAM_DES3_DecryptOfbNonBlocking(CAAM_Type *base,
7400                                          caam_handle_t *handle,
7401                                          caam_desc_cipher_des_t descriptor,
7402                                          const uint8_t *ciphertext,
7403                                          uint8_t *plaintext,
7404                                          size_t size,
7405                                          const uint8_t iv[CAAM_DES_IV_SIZE],
7406                                          const uint8_t key1[CAAM_DES_KEY_SIZE],
7407                                          const uint8_t key2[CAAM_DES_KEY_SIZE],
7408                                          const uint8_t key3[CAAM_DES_KEY_SIZE])
7409 {
7410     uint32_t descriptorSize = ARRAY_SIZE(templateCipherDes);
7411 
7412     /* DES do not support EXTENDED lenght in FIFO LOAD/STORE command.
7413      * Data lenght limit is 2^16 bytes = 65 536 bytes.
7414      * Note: You can still call several times instead
7415      */
7416     if (size > 0xFFFFUL)
7417     {
7418         return kStatus_CAAM_DataOverflow;
7419     }
7420 
7421     (void)caam_memcpy(descriptor, templateCipherDes, sizeof(templateCipherDes));
7422     descriptor[0] |= (descriptorSize & DESC_SIZE_MASK);
7423     descriptor[1] |= 3U * CAAM_DES_KEY_SIZE;
7424     (void)caam_memcpy(&descriptor[2], (const uint32_t *)(uintptr_t)key1, CAAM_DES_KEY_SIZE);
7425     (void)caam_memcpy(&descriptor[4], (const uint32_t *)(uintptr_t)key2, CAAM_DES_KEY_SIZE);
7426     (void)caam_memcpy(&descriptor[6], (const uint32_t *)(uintptr_t)key3, CAAM_DES_KEY_SIZE);
7427     descriptor[9] = ADD_OFFSET((uint32_t)iv);
7428     descriptor[10] |= (size & DESC_PAYLOAD_SIZE_MASK);
7429     descriptor[11] = ADD_OFFSET((uint32_t)ciphertext);
7430     descriptor[12] |= (size & DESC_PAYLOAD_SIZE_MASK);
7431     descriptor[13] = ADD_OFFSET((uint32_t)plaintext);
7432     descriptor[14] |= (uint32_t)kCAAM_ModeOFB; /* AAI = 40h = OFB */
7433     descriptor[14] |= 0x10000U;                /* 3DES */
7434     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
7435 }
7436 
7437 #define DESC_HEADER                           0xB0800000u
7438 #define DESC_HEADER_ADD_DESCLEN(cmdWord, len) ((cmdWord) |= (len))
7439 
7440 #define DESC_FLOADA                  0x220C0000u
7441 #define DESC_FLOADB                  0x220D0000u
7442 #define DESC_FLOADN                  0x22080000u
7443 #define DESC_KEY_E_                  0x02010000u
7444 #define DESC_STOREB                  0x600D0000u
7445 #define DESC_STORE_                  0x52110004u
7446 #define DESC_ADD_LEN(cmdWord, len)   ((cmdWord) |= (len))
7447 #define DESC_SET_ADDR(cmdWord, addr) ((cmdWord) = ADD_OFFSET((uint32_t)(addr)))
7448 
7449 #define DESC_FLOADA0 0x22000000u
7450 #define DESC_FLOADA1 0x22010000u
7451 #define DESC_FLOADA3 0x22030000u
7452 #define DESC_FLOADB0 0x22040000u
7453 #define DESC_FLOADB1 0x22050000u
7454 #define DESC_FLOADB2 0x22060000u
7455 #define DESC_FLOADB3 0x22070000u
7456 #define DESC_STOREB1 0x60050000u
7457 #define DESC_STOREB2 0x60060000u
7458 
7459 static const uint32_t templateArithmeticPKHA[] = {
7460     /* 00 */ DESC_HEADER, /* HEADER */
7461     /* 01 */ 0x81800001u, /* OPERATION: PKHA OPERATION: clear memory function. */
7462     /* 02 */ 0xA2000001u, /* JMP always to next command. Done checkpoint (wait for Class 1 Done) */
7463     /* 03 */ DESC_FLOADN, /* FIFO LOAD PKHA N */
7464     /* 04 */ 0x00000000u, /* place: N address */
7465     /* 05 */ DESC_FLOADA, /* FIFO LOAD PKHA A */
7466     /* 06 */ 0x00000000u, /* place: A address */
7467     /* 07 */ DESC_FLOADB, /* FIFO LOAD PKHA B */
7468     /* 08 */ 0x00000000u, /* place: B address */
7469     /* 09 */ DESC_KEY_E_, /* KEY PKHA E */
7470     /* 10 */ 0x00000000u, /* place: E address */
7471     /* 11 */ 0x81800000u, /* OPERATION: PKHA OPERATION: Arithmetic Functions. */
7472     /* 12 */ DESC_STOREB, /* FIFO STORE PKHA B */
7473     /* 13 */ 0x00000000u, /* place: result address */
7474 };
7475 
7476 /*! @brief PKHA functions - arithmetic, copy/clear memory. */
7477 typedef enum _caam_pkha_func_t
7478 {
7479     kCAAM_PKHA_ClearMem           = 1U,
7480     kCAAM_PKHA_ArithModAdd        = 2U,  /*!< (A + B) mod N */
7481     kCAAM_PKHA_ArithModSub1       = 3U,  /*!< (A - B) mod N */
7482     kCAAM_PKHA_ArithModSub2       = 4U,  /*!< (B - A) mod N */
7483     kCAAM_PKHA_ArithModMul        = 5U,  /*!< (A x B) mod N */
7484     kCAAM_PKHA_ArithModExp        = 6U,  /*!< (A^E) mod N */
7485     kCAAM_PKHA_ArithModRed        = 7U,  /*!< (A) mod N */
7486     kCAAM_PKHA_ArithModInv        = 8U,  /*!< (A^-1) mod N */
7487     kCAAM_PKHA_ArithEccAdd        = 9U,  /*!< (P1 + P2) */
7488     kCAAM_PKHA_ArithEccDouble     = 10U, /*!< (P2 + P2) */
7489     kCAAM_PKHA_ArithEccMul        = 11U, /*!< (E x P1) */
7490     kCAAM_PKHA_ArithModR2         = 12U, /*!< (R^2 mod N) */
7491     kCAAM_PKHA_ArithGcd           = 14U, /*!< GCD (A, N) */
7492     kCAAM_PKHA_ArithPrimalityTest = 15U, /*!< Miller-Rabin */
7493     kCAAM_PKHA_CopyMemSizeN       = 16U,
7494     kCAAM_PKHA_CopyMemSizeSrc     = 17U,
7495 } caam_pkha_func_t;
7496 
7497 /*! @brief Register areas for PKHA clear memory operations. */
7498 typedef enum _caam_pkha_reg_area
7499 {
7500     kCAAM_PKHA_RegA   = 8U,
7501     kCAAM_PKHA_RegB   = 4U,
7502     kCAAM_PKHA_RegE   = 2U,
7503     kCAAM_PKHA_RegN   = 1U,
7504     kCAAM_PKHA_RegAll = kCAAM_PKHA_RegA | kCAAM_PKHA_RegB | kCAAM_PKHA_RegE | kCAAM_PKHA_RegN,
7505 } caam_pkha_reg_area_t;
7506 
7507 /*! @brief Quadrant areas for 4096-bit registers for PKHA copy memory
7508  * operations. */
7509 typedef enum _caam_pkha_quad_area_t
7510 {
7511     kCAAM_PKHA_Quad0 = 0U,
7512     kCAAM_PKHA_Quad1 = 1U,
7513     kCAAM_PKHA_Quad2 = 2U,
7514     kCAAM_PKHA_Quad3 = 3U,
7515 } caam_pkha_quad_area_t;
7516 
7517 /*! @brief User-supplied (R^2 mod N) input or CAAM should calculate. */
7518 typedef enum _caam_pkha_r2_t
7519 {
7520     kCAAM_PKHA_CalcR2  = 0U, /*!< Calculate (R^2 mod N) */
7521     kCAAM_PKHA_InputR2 = 1U  /*!< (R^2 mod N) supplied as input */
7522 } caam_pkha_r2_t;
7523 
7524 /*! @brief CAAM PKHA parameters */
7525 typedef struct _caam_pkha_mode_params_t
7526 {
7527     caam_pkha_func_t func;
7528     caam_pkha_f2m_t arithType;
7529     caam_pkha_montgomery_form_t montFormIn;
7530     caam_pkha_montgomery_form_t montFormOut;
7531     caam_pkha_reg_area_t srcReg;
7532     caam_pkha_quad_area_t srcQuad;
7533     caam_pkha_reg_area_t dstReg;
7534     caam_pkha_quad_area_t dstQuad;
7535     caam_pkha_timing_t equalTime;
7536     caam_pkha_r2_t r2modn;
7537 } caam_pkha_mode_params_t;
7538 
caam_pkha_default_parms(caam_pkha_mode_params_t * params)7539 static void caam_pkha_default_parms(caam_pkha_mode_params_t *params)
7540 {
7541     params->func        = (caam_pkha_func_t)0;
7542     params->arithType   = kCAAM_PKHA_IntegerArith;
7543     params->montFormIn  = kCAAM_PKHA_NormalValue;
7544     params->montFormOut = kCAAM_PKHA_NormalValue;
7545     params->srcReg      = kCAAM_PKHA_RegAll;
7546     params->srcQuad     = kCAAM_PKHA_Quad0;
7547     params->dstReg      = kCAAM_PKHA_RegAll;
7548     params->dstQuad     = kCAAM_PKHA_Quad0;
7549     params->equalTime   = kCAAM_PKHA_NoTimingEqualized;
7550     params->r2modn      = kCAAM_PKHA_CalcR2;
7551 }
7552 
caam_pkha_mode_set_src_reg_copy(uint32_t * outMode,caam_pkha_reg_area_t reg)7553 static void caam_pkha_mode_set_src_reg_copy(uint32_t *outMode, caam_pkha_reg_area_t reg)
7554 {
7555     int i = 0;
7556 
7557     do
7558     {
7559         reg = (caam_pkha_reg_area_t)(uint32_t)(((uint32_t)reg) >> 1u);
7560         i++;
7561     } while (0U != (uint32_t)reg);
7562 
7563     i = 4 - i;
7564     /* Source register must not be E. */
7565     if (i != 2)
7566     {
7567         *outMode |= ((uint32_t)i << 17u);
7568     }
7569 }
7570 
caam_pkha_mode_set_dst_reg_copy(uint32_t * outMode,caam_pkha_reg_area_t reg)7571 static void caam_pkha_mode_set_dst_reg_copy(uint32_t *outMode, caam_pkha_reg_area_t reg)
7572 {
7573     int i = 0;
7574 
7575     do
7576     {
7577         reg = (caam_pkha_reg_area_t)(uint32_t)(((uint32_t)reg) >> 1u);
7578         i++;
7579     } while (0U != (uint32_t)reg);
7580 
7581     i = 4 - i;
7582     *outMode |= ((uint32_t)i << 10u);
7583 }
7584 
caam_pkha_mode_set_src_seg_copy(uint32_t * outMode,const caam_pkha_quad_area_t quad)7585 static void caam_pkha_mode_set_src_seg_copy(uint32_t *outMode, const caam_pkha_quad_area_t quad)
7586 {
7587     *outMode |= ((uint32_t)quad << 8u);
7588 }
7589 
caam_pkha_mode_set_dst_seg_copy(uint32_t * outMode,const caam_pkha_quad_area_t quad)7590 static void caam_pkha_mode_set_dst_seg_copy(uint32_t *outMode, const caam_pkha_quad_area_t quad)
7591 {
7592     *outMode |= ((uint32_t)quad << 6u);
7593 }
7594 
caam_pkha_get_mode(const caam_pkha_mode_params_t * params)7595 static uint32_t caam_pkha_get_mode(const caam_pkha_mode_params_t *params)
7596 {
7597     uint32_t modeReg;
7598 
7599     /* Set the PKHA algorithm and the appropriate function. */
7600     modeReg = (uint32_t)params->func;
7601 
7602     if ((params->func == kCAAM_PKHA_CopyMemSizeN) || (params->func == kCAAM_PKHA_CopyMemSizeSrc))
7603     {
7604         /* Set source and destination registers and quads. */
7605         caam_pkha_mode_set_src_reg_copy(&modeReg, params->srcReg);
7606         caam_pkha_mode_set_dst_reg_copy(&modeReg, params->dstReg);
7607         caam_pkha_mode_set_src_seg_copy(&modeReg, params->srcQuad);
7608         caam_pkha_mode_set_dst_seg_copy(&modeReg, params->dstQuad);
7609     }
7610     else
7611     {
7612         /* Set the arithmetic type - integer or binary polynomial (F2m). */
7613         modeReg |= ((uint32_t)params->arithType << 17u);
7614 
7615         /* Set to use Montgomery form of inputs and/or outputs. */
7616         modeReg |= ((uint32_t)params->montFormIn << 19u);
7617         modeReg |= ((uint32_t)params->montFormOut << 18u);
7618 
7619         /* Set to use pre-computed R2modN */
7620         modeReg |= ((uint32_t)params->r2modn << 16u);
7621     }
7622 
7623     modeReg |= ((uint32_t)params->equalTime << 10u);
7624 
7625     return modeReg;
7626 }
7627 
7628 enum _caam_user_specified_status
7629 {
7630     /* the value below is used as LOCAL_OFFSET field for the JMP/HALT command, in which we test the PRM flag */
7631     kCAAM_UserSpecifiedStatus_NotPrime = 0x55u,
7632 
7633     /* the value below is returned in Job termination status word in case PrimalityTest result is NotPrime.
7634      */
7635     kCAAM_StatusNotPrime = 0x30000000u | kCAAM_UserSpecifiedStatus_NotPrime,
7636 };
7637 
caam_pkha_algorithm_operation_command(CAAM_Type * base,caam_handle_t * handle,caam_desc_pkha_t descriptor,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,caam_pkha_mode_params_t * params,uint8_t * result,size_t * resultSize)7638 static status_t caam_pkha_algorithm_operation_command(CAAM_Type *base,
7639                                                       caam_handle_t *handle,
7640                                                       caam_desc_pkha_t descriptor,
7641                                                       const uint8_t *A,
7642                                                       size_t sizeA,
7643                                                       const uint8_t *B,
7644                                                       size_t sizeB,
7645                                                       const uint8_t *N,
7646                                                       size_t sizeN,
7647                                                       const uint8_t *E,
7648                                                       size_t sizeE,
7649                                                       caam_pkha_mode_params_t *params,
7650                                                       uint8_t *result,
7651                                                       size_t *resultSize)
7652 {
7653     uint32_t clearMask      = 0;
7654     uint32_t descriptorSize = ARRAY_SIZE(templateArithmeticPKHA);
7655     BUILD_ASSURE(sizeof(caam_desc_pkha_t) >= sizeof(templateArithmeticPKHA), caam_desc_pkha_t_size_too_low);
7656 
7657     /* initialize descriptor from template */
7658     (void)caam_memcpy(descriptor, templateArithmeticPKHA, sizeof(templateArithmeticPKHA));
7659 
7660     /* add descriptor lenght in bytes to HEADER descriptor command */
7661     DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
7662 
7663     /* input data */
7664     if ((N != NULL) && (sizeN != 0U))
7665     {
7666         clearMask |= (uint32_t)1u << 16; /* add Nram bit to PKHA_MODE_MS */
7667         DESC_ADD_LEN(descriptor[3], sizeN);
7668         DESC_SET_ADDR(descriptor[4], N);
7669     }
7670     else
7671     {
7672         /* jump to descriptor[4] */
7673         descriptor[3] = DESC_JUMP_2; /* jump to current index + 2 (=4) */
7674     }
7675 
7676     if ((A != NULL) && (sizeA != 0U))
7677     {
7678         clearMask |= (uint32_t)1u << 19; /* add Aram bit to PKHA_MODE_MS */
7679         DESC_ADD_LEN(descriptor[5], sizeA);
7680         DESC_SET_ADDR(descriptor[6], A);
7681     }
7682     else
7683     {
7684         /* jump to descriptor[6] */
7685         descriptor[5] = DESC_JUMP_2; /* jump to current index + 2 (=6) */
7686     }
7687 
7688     if ((B != NULL) && (sizeB != 0U))
7689     {
7690         clearMask |= (uint32_t)1u << 18; /* add Bram bit to PKHA_MODE_MS */
7691         DESC_ADD_LEN(descriptor[7], sizeB);
7692         DESC_SET_ADDR(descriptor[8], B);
7693     }
7694     else
7695     {
7696         /* jump to descriptor[8] */
7697         descriptor[7] = DESC_JUMP_2; /* jump to current index + 2 (=8) */
7698     }
7699 
7700     if ((E != NULL) && (sizeE != 0U))
7701     {
7702         clearMask |= (uint32_t)1u << 17; /* add Eram bit to PKHA_MODE_MS */
7703         DESC_ADD_LEN(descriptor[9], sizeE);
7704         DESC_SET_ADDR(descriptor[10], E);
7705     }
7706     else
7707     {
7708         /* jump to descriptor[11] */
7709         descriptor[9] = DESC_JUMP_2; /* jump to current index + 2 (=11) */
7710     }
7711 
7712     /* add registers to clear into the pkha clear memory function */
7713     descriptor[1] |= clearMask;
7714 
7715     /* add functions details for pkha arithmetic functions */
7716     descriptor[11] |= caam_pkha_get_mode(params);
7717 
7718     /* RESULTS */
7719     if ((result != NULL) && (resultSize != NULL))
7720     {
7721         /* We don't know the size of result at this point. But, we know it will be <= modulus. */
7722         DESC_ADD_LEN(descriptor[12], sizeN);
7723         DESC_SET_ADDR(descriptor[13], result);
7724         *resultSize = sizeN;
7725     }
7726     else
7727     {
7728         /* special case for Primality Test - instead of reading result, check PRM bit and return user-specified status
7729          * if it is set. */
7730         /* conditional HALT, return user-specificed status if condition evaluated is true. this condition checks if (PRM
7731          * is false). */
7732         descriptor[12] = 0xA0C12000u;
7733         descriptor[12] |= (uint32_t)kCAAM_UserSpecifiedStatus_NotPrime;
7734 
7735         descriptor[13] = DESC_HALT; /* always halt with status 0x0 (normal) */
7736     }
7737 
7738     /* schedule the job */
7739     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
7740 }
7741 
7742 static const uint32_t templateArithmeticECC[] = {
7743     /* 00 */ DESC_HEADER,  /* HEADER */
7744     /* 01 */ 0x818F0001u,  /* OPERATION: PKHA OPERATION: clear memory function. Clear ABNE. */
7745     /* 02 */ 0xA2000001u,  /* JMP always to next command. Done checkpoint (wait for Class 1 Done) */
7746     /* 03 */ DESC_FLOADN,  /* FIFO LOAD PKHA N */
7747     /* 04 */ 0x00000000u,  /* place: N address */
7748     /* 05 */ DESC_FLOADA0, /* FIFO LOAD A0 */
7749     /* 06 */ 0x00000000u,  /* place: A0 address */
7750     /* 07 */ DESC_FLOADA1, /* FIFO LOAD A1 */
7751     /* 08 */ 0x00000000u,  /* place: A1 address */
7752     /* 09 */ DESC_FLOADA3, /* FIFO LOAD PKHA A3 */
7753     /* 10 */ 0x00000000u,  /* place: A3 address */
7754     /* 11 */ DESC_FLOADB0, /* FIFO LOAD PKHA B0 */
7755     /* 12 */ 0x00000000u,  /* place: B0 address */
7756     /* 13 */ DESC_FLOADB1, /* FIFO LOAD PKHA B1 */
7757     /* 14 */ 0x00000000u,  /* place: B1 address */
7758     /* 15 */ DESC_FLOADB2, /* FIFO LOAD PKHA B2 */
7759     /* 16 */ 0x00000000u,  /* place: B2 address */
7760     /* 17 */ DESC_FLOADB3, /* FIFO LOAD PKHA B3 */
7761     /* 18 */ 0x00000000u,  /* place: B3 address */
7762     /* 19 */ DESC_KEY_E_,  /* KEY PKHA E */
7763     /* 20 */ 0x00000000u,  /* place: E address */
7764     /* 21 */ 0x81800000u,  /* OPERATION: PKHA OPERATION: Arithmetic Functions. */
7765     /* 22 */ DESC_STOREB1, /* FIFO STORE PKHA B1 */
7766     /* 23 */ 0x00000000u,  /* place: result X address */
7767     /* 24 */ DESC_STOREB2, /* FIFO STORE PKHA B2 */
7768     /* 25 */ 0x00000000u,  /* place: result Y address */
7769 };
7770 
caam_pkha_ecc_algorithm_operation_command(CAAM_Type * base,caam_handle_t * handle,caam_desc_pkha_ecc_t descriptor,const caam_pkha_ecc_point_t * A,const caam_pkha_ecc_point_t * B,const uint8_t * E,size_t sizeE,const uint8_t * N,const uint8_t * R2modN_B1,const uint8_t * R2modN_B3,const uint8_t * aCurveParam,const uint8_t * bCurveParam,size_t size,caam_pkha_ecc_point_t * result,caam_pkha_mode_params_t * params)7771 static status_t caam_pkha_ecc_algorithm_operation_command(CAAM_Type *base,
7772                                                           caam_handle_t *handle,
7773                                                           caam_desc_pkha_ecc_t descriptor,
7774                                                           const caam_pkha_ecc_point_t *A,
7775                                                           const caam_pkha_ecc_point_t *B,
7776                                                           const uint8_t *E,
7777                                                           size_t sizeE,
7778                                                           const uint8_t *N,
7779                                                           const uint8_t *R2modN_B1,
7780                                                           const uint8_t *R2modN_B3,
7781                                                           const uint8_t *aCurveParam,
7782                                                           const uint8_t *bCurveParam,
7783                                                           size_t size,
7784                                                           caam_pkha_ecc_point_t *result,
7785                                                           caam_pkha_mode_params_t *params)
7786 {
7787     uint32_t descriptorSize = ARRAY_SIZE(templateArithmeticECC);
7788     BUILD_ASSURE(sizeof(caam_desc_pkha_ecc_t) >= sizeof(templateArithmeticECC), caam_desc_pkha_ecc_t_size_too_low);
7789 
7790     /* initialize descriptor from template */
7791     (void)caam_memcpy(descriptor, templateArithmeticECC, sizeof(templateArithmeticECC));
7792 
7793     /* add descriptor lenght in bytes to HEADER descriptor command */
7794     DESC_HEADER_ADD_DESCLEN(descriptor[0], descriptorSize);
7795 
7796     /* N = modulus */
7797     DESC_ADD_LEN(descriptor[3], size);
7798     DESC_SET_ADDR(descriptor[4], N);
7799 
7800     /* [A0, A1] first point in affine coordinates */
7801     if (A != NULL)
7802     {
7803         DESC_ADD_LEN(descriptor[5], size);
7804         DESC_SET_ADDR(descriptor[6], A->X);
7805         DESC_ADD_LEN(descriptor[7], size);
7806         DESC_SET_ADDR(descriptor[8], A->Y);
7807     }
7808     else
7809     {
7810         /* jump to descriptor[9] */
7811         descriptor[5] = DESC_JUMP_4; /* jump to current index + 4 (=9) */
7812     }
7813 
7814     /* aCurveParam */
7815     DESC_ADD_LEN(descriptor[9], size);
7816     DESC_SET_ADDR(descriptor[10], aCurveParam);
7817 
7818     /* bCurveParam */
7819     DESC_ADD_LEN(descriptor[11], size);
7820     DESC_SET_ADDR(descriptor[12], bCurveParam);
7821 
7822     /* [B1, B2] second point in affine coordinates */
7823     if (B != NULL)
7824     {
7825         DESC_ADD_LEN(descriptor[13], size);
7826         DESC_SET_ADDR(descriptor[14], B->X);
7827         DESC_ADD_LEN(descriptor[15], size);
7828         DESC_SET_ADDR(descriptor[16], B->Y);
7829     }
7830     else if (R2modN_B1 != NULL) /* R2modN for ECC_MOD_MUL goes to B1 */
7831     {
7832         DESC_ADD_LEN(descriptor[13], size);
7833         DESC_SET_ADDR(descriptor[14], R2modN_B1);
7834         /* jump to descriptor[17] */
7835         descriptor[15] = DESC_JUMP_2; /* jump to current index + 2 (=17) */
7836     }
7837     else
7838     {
7839         /* jump to descriptor[17] */
7840         descriptor[13] = DESC_JUMP_4; /* jump to current index + 4 (=17) */
7841     }
7842 
7843     if (R2modN_B3 != NULL)
7844     {
7845         DESC_ADD_LEN(descriptor[17], size);
7846         DESC_SET_ADDR(descriptor[18], R2modN_B3);
7847     }
7848     else
7849     {
7850         /* jump to descriptor[19] */
7851         descriptor[17] = DESC_JUMP_2; /* jump to current index + 2 (=19) */
7852     }
7853 
7854     if ((E != NULL) && (sizeE != 0U))
7855     {
7856         DESC_ADD_LEN(descriptor[19], sizeE);
7857         DESC_SET_ADDR(descriptor[20], E);
7858     }
7859     else
7860     {
7861         /* jump to descriptor[21] */
7862         descriptor[19] = DESC_JUMP_2; /* jump to current index + 2 (=21) */
7863     }
7864 
7865     /* add functions details for pkha arithmetic functions */
7866     descriptor[21] |= caam_pkha_get_mode(params);
7867 
7868     /* store [B1, B2] result point */
7869     DESC_ADD_LEN(descriptor[22], size);
7870     DESC_SET_ADDR(descriptor[23], result->X);
7871     DESC_ADD_LEN(descriptor[24], size);
7872     DESC_SET_ADDR(descriptor[25], result->Y);
7873 
7874     /* schedule the job */
7875     return caam_in_job_ring_add(base, handle->jobRing, &descriptor[0]);
7876 }
7877 
7878 /*!
7879  * addtogroup caam_driver_pkha
7880  * {
7881  */
7882 
CAAM_PKHA_CompareBigNum(const uint8_t * a,size_t sizeA,const uint8_t * b,size_t sizeB)7883 int CAAM_PKHA_CompareBigNum(const uint8_t *a, size_t sizeA, const uint8_t *b, size_t sizeB)
7884 {
7885     int retval = 0;
7886 
7887     /* skip zero msbytes - integer a */
7888     while ((sizeA != 0U) && (0u == a[0]))
7889     {
7890         sizeA--;
7891         a++;
7892     }
7893 
7894     /* skip zero msbytes - integer b */
7895     while ((sizeB != 0U) && (0u == b[0]))
7896     {
7897         sizeB--;
7898         b++;
7899     }
7900 
7901     if (sizeA > sizeB)
7902     {
7903         retval = 1;
7904     } /* int a has more non-zero bytes, thus it is bigger than b */
7905     else if (sizeA < sizeB)
7906     {
7907         retval = -1;
7908     } /* int b has more non-zero bytes, thus it is bigger than a */
7909     else if (sizeA == 0U)
7910     {
7911         retval = 0;
7912     } /* sizeA = sizeB = 0 */
7913     else
7914     {
7915         int n;
7916         uint32_t equal;
7917         int val;
7918 
7919         n     = (int)sizeA - 1;
7920         equal = 0;
7921 
7922         /* compare all bytes - does not leak (in time domain) how many bytes equal */
7923         /* move from lsbyte to msbyte */
7924         while (n >= 0)
7925         {
7926             uint32_t chXor = ((uint32_t)a[n] ^ (uint32_t)b[n]);
7927 
7928             equal |= chXor;
7929             val = (int)chXor * ((int)a[n] - (int)b[n]);
7930 
7931             if (val < 0)
7932             {
7933                 retval = -1;
7934             }
7935 
7936             if (val > 0)
7937             {
7938                 retval = 1;
7939             }
7940 
7941             if (val == 0)
7942             {
7943                 val = 1;
7944             }
7945 
7946             if (val != 0)
7947             {
7948                 n--;
7949             }
7950         }
7951 
7952         if (0U == equal)
7953         {
7954             retval = 0;
7955         }
7956     }
7957     return (retval);
7958 }
7959 
7960 status_t CAAM_PKHA_ModAddNonBlocking(CAAM_Type *base,
7961                                      caam_handle_t *handle,
7962                                      caam_desc_pkha_t descriptor,
7963                                      const uint8_t *A,
7964                                      size_t sizeA,
7965                                      const uint8_t *B,
7966                                      size_t sizeB,
7967                                      const uint8_t *N,
7968                                      size_t sizeN,
7969                                      uint8_t *result,
7970                                      size_t *resultSize,
7971                                      caam_pkha_f2m_t arithType);
7972 
CAAM_PKHA_ModAddNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_pkha_t descriptor,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,caam_pkha_f2m_t arithType)7973 status_t CAAM_PKHA_ModAddNonBlocking(CAAM_Type *base,
7974                                      caam_handle_t *handle,
7975                                      caam_desc_pkha_t descriptor,
7976                                      const uint8_t *A,
7977                                      size_t sizeA,
7978                                      const uint8_t *B,
7979                                      size_t sizeB,
7980                                      const uint8_t *N,
7981                                      size_t sizeN,
7982                                      uint8_t *result,
7983                                      size_t *resultSize,
7984                                      caam_pkha_f2m_t arithType)
7985 {
7986     caam_pkha_mode_params_t params;
7987     status_t status;
7988 
7989     if (arithType == kCAAM_PKHA_IntegerArith)
7990     {
7991         if (CAAM_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
7992         {
7993             return (kStatus_InvalidArgument);
7994         }
7995 
7996         if (CAAM_PKHA_CompareBigNum(B, sizeB, N, sizeN) >= 0)
7997         {
7998             return (kStatus_InvalidArgument);
7999         }
8000     }
8001 
8002     caam_pkha_default_parms(&params);
8003     params.func      = kCAAM_PKHA_ArithModAdd;
8004     params.arithType = arithType;
8005 
8006     status = caam_pkha_algorithm_operation_command(base, handle, descriptor, A, sizeA, B, sizeB, N, sizeN, NULL, 0,
8007                                                    &params, result, resultSize);
8008     return status;
8009 }
8010 
8011 /*!
8012  * brief Performs modular addition - (A + B) mod N.
8013  *
8014  * This function performs modular addition of (A + B) mod N, with either
8015  * integer or binary polynomial (F2m) inputs.  In the F2m form, this function is
8016  * equivalent to a bitwise XOR and it is functionally the same as subtraction.
8017  *
8018  * param base CAAM peripheral base address
8019  * param A first addend (integer or binary polynomial)
8020  * param sizeA Size of A in bytes
8021  * param B second addend (integer or binary polynomial)
8022  * param sizeB Size of B in bytes
8023  * param N modulus.
8024  * param sizeN Size of N in bytes.
8025  * param[out] result Output array to store result of operation
8026  * param[out] resultSize Output size of operation in bytes
8027  * param arithType Type of arithmetic to perform (integer or F2m)
8028  * return Operation status.
8029  */
CAAM_PKHA_ModAdd(CAAM_Type * base,caam_handle_t * handle,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,caam_pkha_f2m_t arithType)8030 status_t CAAM_PKHA_ModAdd(CAAM_Type *base,
8031                           caam_handle_t *handle,
8032                           const uint8_t *A,
8033                           size_t sizeA,
8034                           const uint8_t *B,
8035                           size_t sizeB,
8036                           const uint8_t *N,
8037                           size_t sizeN,
8038                           uint8_t *result,
8039                           size_t *resultSize,
8040                           caam_pkha_f2m_t arithType)
8041 {
8042     caam_desc_pkha_t descBuf;
8043     status_t status;
8044 
8045     do
8046     {
8047         status = CAAM_PKHA_ModAddNonBlocking(base, handle, descBuf, A, sizeA, B, sizeB, N, sizeN, result, resultSize,
8048                                              arithType);
8049     } while (status == kStatus_CAAM_Again);
8050 
8051     if (status != kStatus_Success)
8052     {
8053         return status;
8054     }
8055 
8056     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
8057 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
8058     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
8059     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
8060     DCACHE_InvalidateByRange((uint32_t)result, *resultSize);
8061 #endif /* CAAM_OUT_INVALIDATE */
8062     return status;
8063 }
8064 
8065 status_t CAAM_PKHA_ModSub1NonBlocking(CAAM_Type *base,
8066                                       caam_handle_t *handle,
8067                                       caam_desc_pkha_t descriptor,
8068                                       const uint8_t *A,
8069                                       size_t sizeA,
8070                                       const uint8_t *B,
8071                                       size_t sizeB,
8072                                       const uint8_t *N,
8073                                       size_t sizeN,
8074                                       uint8_t *result,
8075                                       size_t *resultSize);
8076 
CAAM_PKHA_ModSub1NonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_pkha_t descriptor,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)8077 status_t CAAM_PKHA_ModSub1NonBlocking(CAAM_Type *base,
8078                                       caam_handle_t *handle,
8079                                       caam_desc_pkha_t descriptor,
8080                                       const uint8_t *A,
8081                                       size_t sizeA,
8082                                       const uint8_t *B,
8083                                       size_t sizeB,
8084                                       const uint8_t *N,
8085                                       size_t sizeN,
8086                                       uint8_t *result,
8087                                       size_t *resultSize)
8088 {
8089     caam_pkha_mode_params_t params;
8090     status_t status;
8091 
8092     if (CAAM_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
8093     {
8094         return (kStatus_InvalidArgument);
8095     }
8096 
8097     if (CAAM_PKHA_CompareBigNum(B, sizeB, N, sizeN) >= 0)
8098     {
8099         return (kStatus_InvalidArgument);
8100     }
8101 
8102     caam_pkha_default_parms(&params);
8103     params.func = kCAAM_PKHA_ArithModSub1;
8104 
8105     status = caam_pkha_algorithm_operation_command(base, handle, descriptor, A, sizeA, B, sizeB, N, sizeN, NULL, 0,
8106                                                    &params, result, resultSize);
8107     return status;
8108 }
8109 
8110 /*!
8111  * brief Performs modular subtraction - (A - B) mod N.
8112  *
8113  * This function performs modular subtraction of (A - B) mod N with
8114  * integer inputs.
8115  *
8116  * param base CAAM peripheral base address
8117  * param A first addend (integer or binary polynomial)
8118  * param sizeA Size of A in bytes
8119  * param B second addend (integer or binary polynomial)
8120  * param sizeB Size of B in bytes
8121  * param N modulus
8122  * param sizeN Size of N in bytes
8123  * param[out] result Output array to store result of operation
8124  * param[out] resultSize Output size of operation in bytes
8125  * return Operation status.
8126  */
CAAM_PKHA_ModSub1(CAAM_Type * base,caam_handle_t * handle,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)8127 status_t CAAM_PKHA_ModSub1(CAAM_Type *base,
8128                            caam_handle_t *handle,
8129                            const uint8_t *A,
8130                            size_t sizeA,
8131                            const uint8_t *B,
8132                            size_t sizeB,
8133                            const uint8_t *N,
8134                            size_t sizeN,
8135                            uint8_t *result,
8136                            size_t *resultSize)
8137 {
8138     caam_desc_pkha_t descBuf;
8139     status_t status;
8140 
8141     do
8142     {
8143         status = CAAM_PKHA_ModSub1NonBlocking(base, handle, descBuf, A, sizeA, B, sizeB, N, sizeN, result, resultSize);
8144     } while (status == kStatus_CAAM_Again);
8145 
8146     if (status != kStatus_Success)
8147     {
8148         return status;
8149     }
8150 
8151     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
8152 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
8153     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
8154     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
8155     DCACHE_InvalidateByRange((uint32_t)result, *resultSize);
8156 #endif /* CAAM_OUT_INVALIDATE */
8157     return status;
8158 }
8159 
8160 status_t CAAM_PKHA_ModSub2NonBlocking(CAAM_Type *base,
8161                                       caam_handle_t *handle,
8162                                       caam_desc_pkha_t descriptor,
8163                                       const uint8_t *A,
8164                                       size_t sizeA,
8165                                       const uint8_t *B,
8166                                       size_t sizeB,
8167                                       const uint8_t *N,
8168                                       size_t sizeN,
8169                                       uint8_t *result,
8170                                       size_t *resultSize);
8171 
CAAM_PKHA_ModSub2NonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_pkha_t descriptor,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)8172 status_t CAAM_PKHA_ModSub2NonBlocking(CAAM_Type *base,
8173                                       caam_handle_t *handle,
8174                                       caam_desc_pkha_t descriptor,
8175                                       const uint8_t *A,
8176                                       size_t sizeA,
8177                                       const uint8_t *B,
8178                                       size_t sizeB,
8179                                       const uint8_t *N,
8180                                       size_t sizeN,
8181                                       uint8_t *result,
8182                                       size_t *resultSize)
8183 {
8184     caam_pkha_mode_params_t params;
8185     status_t status;
8186 
8187     caam_pkha_default_parms(&params);
8188     params.func = kCAAM_PKHA_ArithModSub2;
8189 
8190     status = caam_pkha_algorithm_operation_command(base, handle, descriptor, A, sizeA, B, sizeB, N, sizeN, NULL, 0,
8191                                                    &params, result, resultSize);
8192     return status;
8193 }
8194 
8195 /*!
8196  * brief Performs modular subtraction - (B - A) mod N.
8197  *
8198  * This function performs modular subtraction of (B - A) mod N,
8199  * with integer inputs.
8200  *
8201  * param base CAAM peripheral base address
8202  * param A first addend (integer or binary polynomial)
8203  * param sizeA Size of A in bytes
8204  * param B second addend (integer or binary polynomial)
8205  * param sizeB Size of B in bytes
8206  * param N modulus
8207  * param sizeN Size of N in bytes
8208  * param[out] result Output array to store result of operation
8209  * param[out] resultSize Output size of operation in bytes
8210  * return Operation status.
8211  */
CAAM_PKHA_ModSub2(CAAM_Type * base,caam_handle_t * handle,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)8212 status_t CAAM_PKHA_ModSub2(CAAM_Type *base,
8213                            caam_handle_t *handle,
8214                            const uint8_t *A,
8215                            size_t sizeA,
8216                            const uint8_t *B,
8217                            size_t sizeB,
8218                            const uint8_t *N,
8219                            size_t sizeN,
8220                            uint8_t *result,
8221                            size_t *resultSize)
8222 {
8223     caam_desc_pkha_t descBuf;
8224     status_t status;
8225 
8226     do
8227     {
8228         status = CAAM_PKHA_ModSub2NonBlocking(base, handle, descBuf, A, sizeA, B, sizeB, N, sizeN, result, resultSize);
8229     } while (status == kStatus_CAAM_Again);
8230 
8231     if (status != kStatus_Success)
8232     {
8233         return status;
8234     }
8235 
8236     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
8237 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
8238     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
8239     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
8240     DCACHE_InvalidateByRange((uint32_t)result, *resultSize);
8241 #endif /* CAAM_OUT_INVALIDATE */
8242     return status;
8243 }
8244 
8245 status_t CAAM_PKHA_ModMulNonBlocking(CAAM_Type *base,
8246                                      caam_handle_t *handle,
8247                                      caam_desc_pkha_t descriptor,
8248                                      const uint8_t *A,
8249                                      size_t sizeA,
8250                                      const uint8_t *B,
8251                                      size_t sizeB,
8252                                      const uint8_t *N,
8253                                      size_t sizeN,
8254                                      uint8_t *result,
8255                                      size_t *resultSize,
8256                                      caam_pkha_f2m_t arithType,
8257                                      caam_pkha_montgomery_form_t montIn,
8258                                      caam_pkha_montgomery_form_t montOut,
8259                                      caam_pkha_timing_t equalTime);
8260 
CAAM_PKHA_ModMulNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_pkha_t descriptor,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,caam_pkha_f2m_t arithType,caam_pkha_montgomery_form_t montIn,caam_pkha_montgomery_form_t montOut,caam_pkha_timing_t equalTime)8261 status_t CAAM_PKHA_ModMulNonBlocking(CAAM_Type *base,
8262                                      caam_handle_t *handle,
8263                                      caam_desc_pkha_t descriptor,
8264                                      const uint8_t *A,
8265                                      size_t sizeA,
8266                                      const uint8_t *B,
8267                                      size_t sizeB,
8268                                      const uint8_t *N,
8269                                      size_t sizeN,
8270                                      uint8_t *result,
8271                                      size_t *resultSize,
8272                                      caam_pkha_f2m_t arithType,
8273                                      caam_pkha_montgomery_form_t montIn,
8274                                      caam_pkha_montgomery_form_t montOut,
8275                                      caam_pkha_timing_t equalTime)
8276 {
8277     caam_pkha_mode_params_t params;
8278     status_t status;
8279 
8280     if (arithType == kCAAM_PKHA_IntegerArith)
8281     {
8282         if (CAAM_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
8283         {
8284             return (kStatus_InvalidArgument);
8285         }
8286 
8287         if (CAAM_PKHA_CompareBigNum(B, sizeB, N, sizeN) >= 0)
8288         {
8289             return (kStatus_InvalidArgument);
8290         }
8291     }
8292 
8293     caam_pkha_default_parms(&params);
8294     params.func        = kCAAM_PKHA_ArithModMul;
8295     params.arithType   = arithType;
8296     params.montFormIn  = montIn;
8297     params.montFormOut = montOut;
8298     params.equalTime   = equalTime;
8299 
8300     status = caam_pkha_algorithm_operation_command(base, handle, descriptor, A, sizeA, B, sizeB, N, sizeN, NULL, 0,
8301                                                    &params, result, resultSize);
8302 
8303     return status;
8304 }
8305 
8306 /*!
8307  * brief Performs modular multiplication - (A x B) mod N.
8308  *
8309  * This function performs modular multiplication with either integer or
8310  * binary polynomial (F2m) inputs.  It can optionally specify whether inputs
8311  * and/or outputs will be in Montgomery form or not.
8312  *
8313  * param base CAAM peripheral base address
8314  * param A first addend (integer or binary polynomial)
8315  * param sizeA Size of A in bytes
8316  * param B second addend (integer or binary polynomial)
8317  * param sizeB Size of B in bytes
8318  * param N modulus.
8319  * param sizeN Size of N in bytes
8320  * param[out] result Output array to store result of operation
8321  * param[out] resultSize Output size of operation in bytes
8322  * param arithType Type of arithmetic to perform (integer or F2m)
8323  * param montIn Format of inputs
8324  * param montOut Format of output
8325  * param equalTime Run the function time equalized or no timing equalization. This argument is ignored for F2m modular
8326  * multiplication.
8327  * return Operation status.
8328  */
CAAM_PKHA_ModMul(CAAM_Type * base,caam_handle_t * handle,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,caam_pkha_f2m_t arithType,caam_pkha_montgomery_form_t montIn,caam_pkha_montgomery_form_t montOut,caam_pkha_timing_t equalTime)8329 status_t CAAM_PKHA_ModMul(CAAM_Type *base,
8330                           caam_handle_t *handle,
8331                           const uint8_t *A,
8332                           size_t sizeA,
8333                           const uint8_t *B,
8334                           size_t sizeB,
8335                           const uint8_t *N,
8336                           size_t sizeN,
8337                           uint8_t *result,
8338                           size_t *resultSize,
8339                           caam_pkha_f2m_t arithType,
8340                           caam_pkha_montgomery_form_t montIn,
8341                           caam_pkha_montgomery_form_t montOut,
8342                           caam_pkha_timing_t equalTime)
8343 {
8344     caam_desc_pkha_t descBuf;
8345     status_t status;
8346 
8347     do
8348     {
8349         status = CAAM_PKHA_ModMulNonBlocking(base, handle, descBuf, A, sizeA, B, sizeB, N, sizeN, result, resultSize,
8350                                              arithType, montIn, montOut, equalTime);
8351     } while (status == kStatus_CAAM_Again);
8352 
8353     if (status != kStatus_Success)
8354     {
8355         return status;
8356     }
8357 
8358     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
8359 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
8360     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
8361     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
8362     DCACHE_InvalidateByRange((uint32_t)result, *resultSize);
8363 #endif /* CAAM_OUT_INVALIDATE */
8364     return status;
8365 }
8366 
8367 status_t CAAM_PKHA_ModR2NonBlocking(CAAM_Type *base,
8368                                     caam_handle_t *handle,
8369                                     caam_desc_pkha_t descriptor,
8370                                     const uint8_t *N,
8371                                     size_t sizeN,
8372                                     uint8_t *result,
8373                                     size_t *resultSize,
8374                                     caam_pkha_f2m_t arithType);
8375 
CAAM_PKHA_ModR2NonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_pkha_t descriptor,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,caam_pkha_f2m_t arithType)8376 status_t CAAM_PKHA_ModR2NonBlocking(CAAM_Type *base,
8377                                     caam_handle_t *handle,
8378                                     caam_desc_pkha_t descriptor,
8379                                     const uint8_t *N,
8380                                     size_t sizeN,
8381                                     uint8_t *result,
8382                                     size_t *resultSize,
8383                                     caam_pkha_f2m_t arithType)
8384 {
8385     status_t status;
8386     caam_pkha_mode_params_t params;
8387 
8388     caam_pkha_default_parms(&params);
8389     params.func      = kCAAM_PKHA_ArithModR2;
8390     params.arithType = arithType;
8391 
8392     status = caam_pkha_algorithm_operation_command(base, handle, descriptor, NULL, 0, NULL, 0, N, sizeN, NULL, 0,
8393                                                    &params, result, resultSize);
8394     return status;
8395 }
8396 
8397 /*!
8398  * brief Computes integer Montgomery factor R^2 mod N.
8399  *
8400  * This function computes a constant to assist in converting operands
8401  * into the Montgomery residue system representation.
8402  *
8403  * param base CAAM peripheral base address
8404  * param N modulus
8405  * param sizeN Size of N in bytes
8406  * param[out] result Output array to store result of operation
8407  * param[out] resultSize Output size of operation in bytes
8408  * param arithType Type of arithmetic to perform (integer or F2m)
8409  * return Operation status.
8410  */
CAAM_PKHA_ModR2(CAAM_Type * base,caam_handle_t * handle,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,caam_pkha_f2m_t arithType)8411 status_t CAAM_PKHA_ModR2(CAAM_Type *base,
8412                          caam_handle_t *handle,
8413                          const uint8_t *N,
8414                          size_t sizeN,
8415                          uint8_t *result,
8416                          size_t *resultSize,
8417                          caam_pkha_f2m_t arithType)
8418 {
8419     caam_desc_pkha_t descBuf;
8420     status_t status;
8421 
8422     do
8423     {
8424         status = CAAM_PKHA_ModR2NonBlocking(base, handle, descBuf, N, sizeN, result, resultSize, arithType);
8425     } while (status == kStatus_CAAM_Again);
8426 
8427     if (status != kStatus_Success)
8428     {
8429         return status;
8430     }
8431 
8432     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
8433 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
8434     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
8435     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
8436     DCACHE_InvalidateByRange((uint32_t)result, *resultSize);
8437 #endif /* CAAM_OUT_INVALIDATE */
8438     return status;
8439 }
8440 
8441 status_t CAAM_PKHA_ModExpNonBlocking(CAAM_Type *base,
8442                                      caam_handle_t *handle,
8443                                      caam_desc_pkha_t descriptor,
8444                                      const uint8_t *A,
8445                                      size_t sizeA,
8446                                      const uint8_t *N,
8447                                      size_t sizeN,
8448                                      const uint8_t *E,
8449                                      size_t sizeE,
8450                                      uint8_t *result,
8451                                      size_t *resultSize,
8452                                      caam_pkha_f2m_t arithType,
8453                                      caam_pkha_montgomery_form_t montIn,
8454                                      caam_pkha_timing_t equalTime);
8455 
CAAM_PKHA_ModExpNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_pkha_t descriptor,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,caam_pkha_f2m_t arithType,caam_pkha_montgomery_form_t montIn,caam_pkha_timing_t equalTime)8456 status_t CAAM_PKHA_ModExpNonBlocking(CAAM_Type *base,
8457                                      caam_handle_t *handle,
8458                                      caam_desc_pkha_t descriptor,
8459                                      const uint8_t *A,
8460                                      size_t sizeA,
8461                                      const uint8_t *N,
8462                                      size_t sizeN,
8463                                      const uint8_t *E,
8464                                      size_t sizeE,
8465                                      uint8_t *result,
8466                                      size_t *resultSize,
8467                                      caam_pkha_f2m_t arithType,
8468                                      caam_pkha_montgomery_form_t montIn,
8469                                      caam_pkha_timing_t equalTime)
8470 {
8471     caam_pkha_mode_params_t params;
8472     status_t status;
8473 
8474     if (arithType == kCAAM_PKHA_IntegerArith)
8475     {
8476         if (CAAM_PKHA_CompareBigNum(A, sizeA, N, sizeN) >= 0)
8477         {
8478             return (kStatus_InvalidArgument);
8479         }
8480     }
8481 
8482     caam_pkha_default_parms(&params);
8483     params.func       = kCAAM_PKHA_ArithModExp;
8484     params.arithType  = arithType;
8485     params.montFormIn = montIn;
8486     params.equalTime  = equalTime;
8487 
8488     status = caam_pkha_algorithm_operation_command(base, handle, descriptor, A, sizeA, NULL, 0, N, sizeN, E, sizeE,
8489                                                    &params, result, resultSize);
8490     return status;
8491 }
8492 
8493 /*!
8494  * brief Performs modular exponentiation - (A^E) mod N.
8495  *
8496  * This function performs modular exponentiation with either integer or
8497  * binary polynomial (F2m) inputs.
8498  *
8499  * param base CAAM peripheral base address
8500  * param A first addend (integer or binary polynomial)
8501  * param sizeA Size of A in bytes
8502  * param N modulus
8503  * param sizeN Size of N in bytes
8504  * param E exponent
8505  * param sizeE Size of E in bytes
8506  * param[out] result Output array to store result of operation
8507  * param[out] resultSize Output size of operation in bytes
8508  * param montIn Format of A input (normal or Montgomery)
8509  * param arithType Type of arithmetic to perform (integer or F2m)
8510  * param equalTime Run the function time equalized or no timing equalization.
8511  * return Operation status.
8512  */
CAAM_PKHA_ModExp(CAAM_Type * base,caam_handle_t * handle,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,caam_pkha_f2m_t arithType,caam_pkha_montgomery_form_t montIn,caam_pkha_timing_t equalTime)8513 status_t CAAM_PKHA_ModExp(CAAM_Type *base,
8514                           caam_handle_t *handle,
8515                           const uint8_t *A,
8516                           size_t sizeA,
8517                           const uint8_t *N,
8518                           size_t sizeN,
8519                           const uint8_t *E,
8520                           size_t sizeE,
8521                           uint8_t *result,
8522                           size_t *resultSize,
8523                           caam_pkha_f2m_t arithType,
8524                           caam_pkha_montgomery_form_t montIn,
8525                           caam_pkha_timing_t equalTime)
8526 {
8527     caam_desc_pkha_t descBuf;
8528     status_t status;
8529 
8530     do
8531     {
8532         status = CAAM_PKHA_ModExpNonBlocking(base, handle, descBuf, A, sizeA, N, sizeN, E, sizeE, result, resultSize,
8533                                              arithType, montIn, equalTime);
8534     } while (status == kStatus_CAAM_Again);
8535 
8536     if (status != kStatus_Success)
8537     {
8538         return status;
8539     }
8540 
8541     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
8542 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
8543     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
8544     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
8545     DCACHE_InvalidateByRange((uint32_t)result, *resultSize);
8546 #endif /* CAAM_OUT_INVALIDATE */
8547     return status;
8548 }
8549 
8550 status_t CAAM_PKHA_ModRedNonBlocking(CAAM_Type *base,
8551                                      caam_handle_t *handle,
8552                                      caam_desc_pkha_t descriptor,
8553                                      const uint8_t *A,
8554                                      size_t sizeA,
8555                                      const uint8_t *N,
8556                                      size_t sizeN,
8557                                      uint8_t *result,
8558                                      size_t *resultSize,
8559                                      caam_pkha_f2m_t arithType);
8560 
CAAM_PKHA_ModRedNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_pkha_t descriptor,const uint8_t * A,size_t sizeA,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,caam_pkha_f2m_t arithType)8561 status_t CAAM_PKHA_ModRedNonBlocking(CAAM_Type *base,
8562                                      caam_handle_t *handle,
8563                                      caam_desc_pkha_t descriptor,
8564                                      const uint8_t *A,
8565                                      size_t sizeA,
8566                                      const uint8_t *N,
8567                                      size_t sizeN,
8568                                      uint8_t *result,
8569                                      size_t *resultSize,
8570                                      caam_pkha_f2m_t arithType)
8571 {
8572     caam_pkha_mode_params_t params;
8573     status_t status;
8574 
8575     caam_pkha_default_parms(&params);
8576     params.func      = kCAAM_PKHA_ArithModRed;
8577     params.arithType = arithType;
8578 
8579     status = caam_pkha_algorithm_operation_command(base, handle, descriptor, A, sizeA, NULL, 0, N, sizeN, NULL, 0,
8580                                                    &params, result, resultSize);
8581     return status;
8582 }
8583 
8584 /*!
8585  * brief Performs modular reduction - (A) mod N.
8586  *
8587  * This function performs modular reduction with either integer or
8588  * binary polynomial (F2m) inputs.
8589  *
8590  * param base CAAM peripheral base address
8591  * param A first addend (integer or binary polynomial)
8592  * param sizeA Size of A in bytes
8593  * param N modulus
8594  * param sizeN Size of N in bytes
8595  * param[out] result Output array to store result of operation
8596  * param[out] resultSize Output size of operation in bytes
8597  * param arithType Type of arithmetic to perform (integer or F2m)
8598  * return Operation status.
8599  */
CAAM_PKHA_ModRed(CAAM_Type * base,caam_handle_t * handle,const uint8_t * A,size_t sizeA,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,caam_pkha_f2m_t arithType)8600 status_t CAAM_PKHA_ModRed(CAAM_Type *base,
8601                           caam_handle_t *handle,
8602                           const uint8_t *A,
8603                           size_t sizeA,
8604                           const uint8_t *N,
8605                           size_t sizeN,
8606                           uint8_t *result,
8607                           size_t *resultSize,
8608                           caam_pkha_f2m_t arithType)
8609 {
8610     caam_desc_pkha_t descBuf;
8611     status_t status;
8612 
8613     do
8614     {
8615         status = CAAM_PKHA_ModRedNonBlocking(base, handle, descBuf, A, sizeA, N, sizeN, result, resultSize, arithType);
8616     } while (status == kStatus_CAAM_Again);
8617 
8618     if (status != kStatus_Success)
8619     {
8620         return status;
8621     }
8622 
8623     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
8624 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
8625     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
8626     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
8627     DCACHE_InvalidateByRange((uint32_t)result, *resultSize);
8628 #endif /* CAAM_OUT_INVALIDATE */
8629     return status;
8630 }
8631 
8632 status_t CAAM_PKHA_ModInvNonBlocking(CAAM_Type *base,
8633                                      caam_handle_t *handle,
8634                                      caam_desc_pkha_t descriptor,
8635                                      const uint8_t *A,
8636                                      size_t sizeA,
8637                                      const uint8_t *N,
8638                                      size_t sizeN,
8639                                      uint8_t *result,
8640                                      size_t *resultSize,
8641                                      caam_pkha_f2m_t arithType);
8642 
CAAM_PKHA_ModInvNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_pkha_t descriptor,const uint8_t * A,size_t sizeA,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,caam_pkha_f2m_t arithType)8643 status_t CAAM_PKHA_ModInvNonBlocking(CAAM_Type *base,
8644                                      caam_handle_t *handle,
8645                                      caam_desc_pkha_t descriptor,
8646                                      const uint8_t *A,
8647                                      size_t sizeA,
8648                                      const uint8_t *N,
8649                                      size_t sizeN,
8650                                      uint8_t *result,
8651                                      size_t *resultSize,
8652                                      caam_pkha_f2m_t arithType)
8653 {
8654     caam_pkha_mode_params_t params;
8655     status_t status;
8656 
8657     caam_pkha_default_parms(&params);
8658     params.func      = kCAAM_PKHA_ArithModInv;
8659     params.arithType = arithType;
8660 
8661     status = caam_pkha_algorithm_operation_command(base, handle, descriptor, A, sizeA, NULL, 0, N, sizeN, NULL, 0,
8662                                                    &params, result, resultSize);
8663     return status;
8664 }
8665 
8666 /*!
8667  * brief Performs modular inversion - (A^-1) mod N.
8668  *
8669  * This function performs modular inversion with either integer or
8670  * binary polynomial (F2m) inputs.
8671  *
8672  * param base CAAM peripheral base address
8673  * param A first addend (integer or binary polynomial)
8674  * param sizeA Size of A in bytes
8675  * param N modulus
8676  * param sizeN Size of N in bytes
8677  * param[out] result Output array to store result of operation
8678  * param[out] resultSize Output size of operation in bytes
8679  * param arithType Type of arithmetic to perform (integer or F2m)
8680  * return Operation status.
8681  */
CAAM_PKHA_ModInv(CAAM_Type * base,caam_handle_t * handle,const uint8_t * A,size_t sizeA,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,caam_pkha_f2m_t arithType)8682 status_t CAAM_PKHA_ModInv(CAAM_Type *base,
8683                           caam_handle_t *handle,
8684                           const uint8_t *A,
8685                           size_t sizeA,
8686                           const uint8_t *N,
8687                           size_t sizeN,
8688                           uint8_t *result,
8689                           size_t *resultSize,
8690                           caam_pkha_f2m_t arithType)
8691 {
8692     caam_desc_pkha_t descBuf;
8693     status_t status;
8694 
8695     do
8696     {
8697         status = CAAM_PKHA_ModInvNonBlocking(base, handle, descBuf, A, sizeA, N, sizeN, result, resultSize, arithType);
8698     } while (status == kStatus_CAAM_Again);
8699 
8700     if (status != kStatus_Success)
8701     {
8702         return status;
8703     }
8704 
8705     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
8706 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
8707     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
8708     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
8709     DCACHE_InvalidateByRange((uint32_t)result, *resultSize);
8710 #endif /* CAAM_OUT_INVALIDATE */
8711     return status;
8712 }
8713 
8714 status_t CAAM_PKHA_ModGcdNonBlocking(CAAM_Type *base,
8715                                      caam_handle_t *handle,
8716                                      caam_desc_pkha_t descriptor,
8717                                      const uint8_t *A,
8718                                      size_t sizeA,
8719                                      const uint8_t *N,
8720                                      size_t sizeN,
8721                                      uint8_t *result,
8722                                      size_t *resultSize,
8723                                      caam_pkha_f2m_t arithType);
8724 
CAAM_PKHA_ModGcdNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_pkha_t descriptor,const uint8_t * A,size_t sizeA,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,caam_pkha_f2m_t arithType)8725 status_t CAAM_PKHA_ModGcdNonBlocking(CAAM_Type *base,
8726                                      caam_handle_t *handle,
8727                                      caam_desc_pkha_t descriptor,
8728                                      const uint8_t *A,
8729                                      size_t sizeA,
8730                                      const uint8_t *N,
8731                                      size_t sizeN,
8732                                      uint8_t *result,
8733                                      size_t *resultSize,
8734                                      caam_pkha_f2m_t arithType)
8735 {
8736     caam_pkha_mode_params_t params;
8737     status_t status;
8738 
8739     caam_pkha_default_parms(&params);
8740     params.func      = kCAAM_PKHA_ArithGcd;
8741     params.arithType = arithType;
8742 
8743     status = caam_pkha_algorithm_operation_command(base, handle, descriptor, A, sizeA, NULL, 0, N, sizeN, NULL, 0,
8744                                                    &params, result, resultSize);
8745     return status;
8746 }
8747 
8748 /*!
8749  * brief Calculates the greatest common divisor - GCD (A, N).
8750  *
8751  * This function calculates the greatest common divisor of two inputs with
8752  * either integer or binary polynomial (F2m) inputs.
8753  *
8754  * param base CAAM peripheral base address
8755  * param A first value (must be smaller than or equal to N)
8756  * param sizeA Size of A in bytes
8757  * param N second value (must be non-zero)
8758  * param sizeN Size of N in bytes
8759  * param[out] result Output array to store result of operation
8760  * param[out] resultSize Output size of operation in bytes
8761  * param arithType Type of arithmetic to perform (integer or F2m)
8762  * return Operation status.
8763  */
CAAM_PKHA_ModGcd(CAAM_Type * base,caam_handle_t * handle,const uint8_t * A,size_t sizeA,const uint8_t * N,size_t sizeN,uint8_t * result,size_t * resultSize,caam_pkha_f2m_t arithType)8764 status_t CAAM_PKHA_ModGcd(CAAM_Type *base,
8765                           caam_handle_t *handle,
8766                           const uint8_t *A,
8767                           size_t sizeA,
8768                           const uint8_t *N,
8769                           size_t sizeN,
8770                           uint8_t *result,
8771                           size_t *resultSize,
8772                           caam_pkha_f2m_t arithType)
8773 {
8774     caam_desc_pkha_t descBuf;
8775     status_t status;
8776 
8777     do
8778     {
8779         status = CAAM_PKHA_ModGcdNonBlocking(base, handle, descBuf, A, sizeA, N, sizeN, result, resultSize, arithType);
8780     } while (status == kStatus_CAAM_Again);
8781 
8782     if (status != kStatus_Success)
8783     {
8784         return status;
8785     }
8786 
8787     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
8788 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
8789     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
8790     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
8791     DCACHE_InvalidateByRange((uint32_t)result, *resultSize);
8792 #endif /* CAAM_OUT_INVALIDATE */
8793     return status;
8794 }
8795 
8796 status_t CAAM_PKHA_PrimalityTestNonBlocking(CAAM_Type *base,
8797                                             caam_handle_t *handle,
8798                                             caam_desc_pkha_t descriptor,
8799                                             const uint8_t *A,
8800                                             size_t sizeA,
8801                                             const uint8_t *B,
8802                                             size_t sizeB,
8803                                             const uint8_t *N,
8804                                             size_t sizeN);
8805 
CAAM_PKHA_PrimalityTestNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_pkha_t descriptor,const uint8_t * A,size_t sizeA,const uint8_t * B,size_t sizeB,const uint8_t * N,size_t sizeN)8806 status_t CAAM_PKHA_PrimalityTestNonBlocking(CAAM_Type *base,
8807                                             caam_handle_t *handle,
8808                                             caam_desc_pkha_t descriptor,
8809                                             const uint8_t *A,
8810                                             size_t sizeA,
8811                                             const uint8_t *B,
8812                                             size_t sizeB,
8813                                             const uint8_t *N,
8814                                             size_t sizeN)
8815 {
8816     caam_pkha_mode_params_t params;
8817     status_t status;
8818 
8819     caam_pkha_default_parms(&params);
8820     params.func = kCAAM_PKHA_ArithPrimalityTest;
8821 
8822     status = caam_pkha_algorithm_operation_command(base, handle, descriptor, A, sizeA, B, sizeB, N, sizeN, NULL, 0,
8823                                                    &params, NULL, NULL);
8824     return status;
8825 }
8826 
8827 /*!
8828  * brief Executes Miller-Rabin primality test.
8829  *
8830  * This function calculates whether or not a candidate prime number is likely
8831  * to be a prime.
8832  *
8833  * param base CAAM peripheral base address
8834  * param A initial random seed
8835  * param sizeA Size of A in bytes
8836  * param B number of trial runs
8837  * param sizeB Size of B in bytes
8838  * param N candidate prime integer
8839  * param sizeN Size of N in bytes
8840  * param[out] res True if the value is likely prime or false otherwise
8841  * return Operation status.
8842  */
CAAM_PKHA_PrimalityTest(CAAM_Type * base,caam_handle_t * handle,const uint8_t * A,size_t sizeA,const uint8_t * B,size_t sizeB,const uint8_t * N,size_t sizeN,bool * res)8843 status_t CAAM_PKHA_PrimalityTest(CAAM_Type *base,
8844                                  caam_handle_t *handle,
8845                                  const uint8_t *A,
8846                                  size_t sizeA,
8847                                  const uint8_t *B,
8848                                  size_t sizeB,
8849                                  const uint8_t *N,
8850                                  size_t sizeN,
8851                                  bool *res)
8852 {
8853     caam_desc_pkha_t descBuf;
8854     status_t status;
8855 
8856     do
8857     {
8858         status = CAAM_PKHA_PrimalityTestNonBlocking(base, handle, descBuf, A, sizeA, B, sizeB, N, sizeN);
8859     } while (status == kStatus_CAAM_Again);
8860 
8861     if (status != kStatus_Success)
8862     {
8863         return status;
8864     }
8865 
8866     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
8867 
8868     if (status == kStatus_Success)
8869     {
8870         /* this return code means that the candidate is believed to be prime. */
8871         *res = true;
8872     }
8873     /* clear DESC INDEX field in the Job termination status word and check if it is our NotPrime user specified status
8874      */
8875     else if (((uint32_t)status & 0xffff00ffu) == (uint32_t)kCAAM_StatusNotPrime)
8876     {
8877         /* change status to Ok to upper layer caller. this return code means that the candidate is believed to not being
8878          * prime. */
8879         status = kStatus_Success;
8880         *res   = false;
8881     }
8882     else
8883     {
8884         *res = false;
8885     }
8886 
8887     return status;
8888 }
8889 
8890 status_t CAAM_PKHA_ECC_PointAddNonBlocking(CAAM_Type *base,
8891                                            caam_handle_t *handle,
8892                                            caam_desc_pkha_ecc_t descriptor,
8893                                            const caam_pkha_ecc_point_t *A,
8894                                            const caam_pkha_ecc_point_t *B,
8895                                            const uint8_t *N,
8896                                            const uint8_t *R2modN,
8897                                            const uint8_t *aCurveParam,
8898                                            const uint8_t *bCurveParam,
8899                                            size_t size,
8900                                            caam_pkha_f2m_t arithType,
8901                                            caam_pkha_ecc_point_t *result);
8902 
CAAM_PKHA_ECC_PointAddNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_pkha_ecc_t descriptor,const caam_pkha_ecc_point_t * A,const caam_pkha_ecc_point_t * B,const uint8_t * N,const uint8_t * R2modN,const uint8_t * aCurveParam,const uint8_t * bCurveParam,size_t size,caam_pkha_f2m_t arithType,caam_pkha_ecc_point_t * result)8903 status_t CAAM_PKHA_ECC_PointAddNonBlocking(CAAM_Type *base,
8904                                            caam_handle_t *handle,
8905                                            caam_desc_pkha_ecc_t descriptor,
8906                                            const caam_pkha_ecc_point_t *A,
8907                                            const caam_pkha_ecc_point_t *B,
8908                                            const uint8_t *N,
8909                                            const uint8_t *R2modN,
8910                                            const uint8_t *aCurveParam,
8911                                            const uint8_t *bCurveParam,
8912                                            size_t size,
8913                                            caam_pkha_f2m_t arithType,
8914                                            caam_pkha_ecc_point_t *result)
8915 {
8916     caam_pkha_mode_params_t params;
8917     status_t status;
8918 
8919     caam_pkha_default_parms(&params);
8920     params.func      = kCAAM_PKHA_ArithEccAdd;
8921     params.arithType = arithType;
8922     params.r2modn    = (R2modN != NULL) ? kCAAM_PKHA_InputR2 : kCAAM_PKHA_CalcR2;
8923 
8924     status = caam_pkha_ecc_algorithm_operation_command(base, handle, descriptor, A, B, NULL, 0, N, NULL, R2modN,
8925                                                        aCurveParam, bCurveParam, size, result, &params);
8926     return status;
8927 }
8928 
8929 /*!
8930  * brief Adds elliptic curve points - A + B.
8931  *
8932  * This function performs ECC point addition over a prime field (Fp) or binary field (F2m) using
8933  * affine coordinates.
8934  *
8935  * param base CAAM peripheral base address
8936  * param A Left-hand point
8937  * param B Right-hand point
8938  * param N Prime modulus of the field
8939  * param R2modN NULL (the function computes R2modN internally) or pointer to pre-computed R2modN (obtained from
8940  *               CAAM_PKHA_ModR2() function).
8941  * param aCurveParam A parameter from curve equation
8942  * param bCurveParam B parameter from curve equation (constant)
8943  * param size Size in bytes of curve points and parameters
8944  * param arithType Type of arithmetic to perform (integer or F2m)
8945  * param[out] result Result point
8946  * return Operation status.
8947  */
CAAM_PKHA_ECC_PointAdd(CAAM_Type * base,caam_handle_t * handle,const caam_pkha_ecc_point_t * A,const caam_pkha_ecc_point_t * B,const uint8_t * N,const uint8_t * R2modN,const uint8_t * aCurveParam,const uint8_t * bCurveParam,size_t size,caam_pkha_f2m_t arithType,caam_pkha_ecc_point_t * result)8948 status_t CAAM_PKHA_ECC_PointAdd(CAAM_Type *base,
8949                                 caam_handle_t *handle,
8950                                 const caam_pkha_ecc_point_t *A,
8951                                 const caam_pkha_ecc_point_t *B,
8952                                 const uint8_t *N,
8953                                 const uint8_t *R2modN,
8954                                 const uint8_t *aCurveParam,
8955                                 const uint8_t *bCurveParam,
8956                                 size_t size,
8957                                 caam_pkha_f2m_t arithType,
8958                                 caam_pkha_ecc_point_t *result)
8959 {
8960     caam_desc_pkha_ecc_t descBuf;
8961     status_t status;
8962 
8963     do
8964     {
8965         status = CAAM_PKHA_ECC_PointAddNonBlocking(base, handle, descBuf, A, B, N, R2modN, aCurveParam, bCurveParam,
8966                                                    size, arithType, result);
8967     } while (status == kStatus_CAAM_Again);
8968 
8969     if (status != kStatus_Success)
8970     {
8971         return status;
8972     }
8973 
8974     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
8975 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
8976     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
8977     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
8978     DCACHE_InvalidateByRange((uint32_t)result->X, size);
8979     DCACHE_InvalidateByRange((uint32_t)result->Y, size);
8980 #endif /* CAAM_OUT_INVALIDATE */
8981     return status;
8982 }
8983 
8984 status_t CAAM_PKHA_ECC_PointDoubleNonBlocking(CAAM_Type *base,
8985                                               caam_handle_t *handle,
8986                                               caam_desc_pkha_ecc_t descriptor,
8987                                               const caam_pkha_ecc_point_t *B,
8988                                               const uint8_t *N,
8989                                               const uint8_t *aCurveParam,
8990                                               const uint8_t *bCurveParam,
8991                                               size_t size,
8992                                               caam_pkha_f2m_t arithType,
8993                                               caam_pkha_ecc_point_t *result);
8994 
CAAM_PKHA_ECC_PointDoubleNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_pkha_ecc_t descriptor,const caam_pkha_ecc_point_t * B,const uint8_t * N,const uint8_t * aCurveParam,const uint8_t * bCurveParam,size_t size,caam_pkha_f2m_t arithType,caam_pkha_ecc_point_t * result)8995 status_t CAAM_PKHA_ECC_PointDoubleNonBlocking(CAAM_Type *base,
8996                                               caam_handle_t *handle,
8997                                               caam_desc_pkha_ecc_t descriptor,
8998                                               const caam_pkha_ecc_point_t *B,
8999                                               const uint8_t *N,
9000                                               const uint8_t *aCurveParam,
9001                                               const uint8_t *bCurveParam,
9002                                               size_t size,
9003                                               caam_pkha_f2m_t arithType,
9004                                               caam_pkha_ecc_point_t *result)
9005 {
9006     caam_pkha_mode_params_t params;
9007     status_t status;
9008 
9009     caam_pkha_default_parms(&params);
9010     params.func      = kCAAM_PKHA_ArithEccDouble;
9011     params.arithType = arithType;
9012 
9013     status = caam_pkha_ecc_algorithm_operation_command(base, handle, descriptor, NULL, B, NULL, 0, N, NULL, NULL,
9014                                                        aCurveParam, bCurveParam, size, result, &params);
9015     return status;
9016 }
9017 
9018 /*!
9019  * brief Doubles elliptic curve points - B + B.
9020  *
9021  * This function performs ECC point doubling over a prime field (Fp) or binary field (F2m) using
9022  * affine coordinates.
9023  *
9024  * param base CAAM peripheral base address
9025  * param B Point to double
9026  * param N Prime modulus of the field
9027  * param aCurveParam A parameter from curve equation
9028  * param bCurveParam B parameter from curve equation (constant)
9029  * param size Size in bytes of curve points and parameters
9030  * param arithType Type of arithmetic to perform (integer or F2m)
9031  * param[out] result Result point
9032  * return Operation status.
9033  */
CAAM_PKHA_ECC_PointDouble(CAAM_Type * base,caam_handle_t * handle,const caam_pkha_ecc_point_t * B,const uint8_t * N,const uint8_t * aCurveParam,const uint8_t * bCurveParam,size_t size,caam_pkha_f2m_t arithType,caam_pkha_ecc_point_t * result)9034 status_t CAAM_PKHA_ECC_PointDouble(CAAM_Type *base,
9035                                    caam_handle_t *handle,
9036                                    const caam_pkha_ecc_point_t *B,
9037                                    const uint8_t *N,
9038                                    const uint8_t *aCurveParam,
9039                                    const uint8_t *bCurveParam,
9040                                    size_t size,
9041                                    caam_pkha_f2m_t arithType,
9042                                    caam_pkha_ecc_point_t *result)
9043 {
9044     caam_desc_pkha_ecc_t descBuf;
9045     status_t status;
9046 
9047     do
9048     {
9049         status = CAAM_PKHA_ECC_PointDoubleNonBlocking(base, handle, descBuf, B, N, aCurveParam, bCurveParam, size,
9050                                                       arithType, result);
9051     } while (status == kStatus_CAAM_Again);
9052 
9053     if (status != kStatus_Success)
9054     {
9055         return status;
9056     }
9057 
9058     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
9059 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
9060     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
9061     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
9062     DCACHE_InvalidateByRange((uint32_t)result->X, size);
9063     DCACHE_InvalidateByRange((uint32_t)result->Y, size);
9064 #endif /* CAAM_OUT_INVALIDATE */
9065     return status;
9066 }
9067 
9068 status_t CAAM_PKHA_ECC_PointMulNonBlocking(CAAM_Type *base,
9069                                            caam_handle_t *handle,
9070                                            caam_desc_pkha_ecc_t descriptor,
9071                                            const caam_pkha_ecc_point_t *A,
9072                                            const uint8_t *E,
9073                                            size_t sizeE,
9074                                            const uint8_t *N,
9075                                            const uint8_t *R2modN,
9076                                            const uint8_t *aCurveParam,
9077                                            const uint8_t *bCurveParam,
9078                                            size_t size,
9079                                            caam_pkha_timing_t equalTime,
9080                                            caam_pkha_f2m_t arithType,
9081                                            caam_pkha_ecc_point_t *result);
9082 
CAAM_PKHA_ECC_PointMulNonBlocking(CAAM_Type * base,caam_handle_t * handle,caam_desc_pkha_ecc_t descriptor,const caam_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,caam_pkha_timing_t equalTime,caam_pkha_f2m_t arithType,caam_pkha_ecc_point_t * result)9083 status_t CAAM_PKHA_ECC_PointMulNonBlocking(CAAM_Type *base,
9084                                            caam_handle_t *handle,
9085                                            caam_desc_pkha_ecc_t descriptor,
9086                                            const caam_pkha_ecc_point_t *A,
9087                                            const uint8_t *E,
9088                                            size_t sizeE,
9089                                            const uint8_t *N,
9090                                            const uint8_t *R2modN,
9091                                            const uint8_t *aCurveParam,
9092                                            const uint8_t *bCurveParam,
9093                                            size_t size,
9094                                            caam_pkha_timing_t equalTime,
9095                                            caam_pkha_f2m_t arithType,
9096                                            caam_pkha_ecc_point_t *result)
9097 {
9098     caam_pkha_mode_params_t params;
9099     status_t status;
9100 
9101     caam_pkha_default_parms(&params);
9102     params.func      = kCAAM_PKHA_ArithEccMul;
9103     params.equalTime = equalTime;
9104     params.arithType = arithType;
9105     params.r2modn    = (R2modN != NULL) ? kCAAM_PKHA_InputR2 : kCAAM_PKHA_CalcR2;
9106 
9107     status = caam_pkha_ecc_algorithm_operation_command(base, handle, descriptor, A, NULL, E, sizeE, N, R2modN, NULL,
9108                                                        aCurveParam, bCurveParam, size, result, &params);
9109     return status;
9110 }
9111 
9112 /*!
9113  * brief Multiplies an elliptic curve point by a scalar - E x (A0, A1).
9114  *
9115  * This function performs ECC point multiplication to multiply an ECC point by
9116  * a scalar integer multiplier over a prime field (Fp) or a binary field (F2m).
9117  *
9118  * param base CAAM peripheral base address
9119  * param A Point as multiplicand
9120  * param E Scalar multiple
9121  * param sizeE The size of E, in bytes
9122  * param N Modulus, a prime number for the Fp field or Irreducible polynomial for F2m field.
9123  * param R2modN NULL (the function computes R2modN internally) or pointer to pre-computed R2modN (obtained from
9124  *        CAAM_PKHA_ModR2() function).
9125  * param aCurveParam A parameter from curve equation
9126  * param bCurveParam B parameter from curve equation (C parameter for operation over F2m).
9127  * param size Size in bytes of curve points and parameters
9128  * param equalTime Run the function time equalized or no timing equalization.
9129  * param arithType Type of arithmetic to perform (integer or F2m)
9130  * param[out] result Result point
9131  * return Operation status.
9132  */
CAAM_PKHA_ECC_PointMul(CAAM_Type * base,caam_handle_t * handle,const caam_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,caam_pkha_timing_t equalTime,caam_pkha_f2m_t arithType,caam_pkha_ecc_point_t * result)9133 status_t CAAM_PKHA_ECC_PointMul(CAAM_Type *base,
9134                                 caam_handle_t *handle,
9135                                 const caam_pkha_ecc_point_t *A,
9136                                 const uint8_t *E,
9137                                 size_t sizeE,
9138                                 const uint8_t *N,
9139                                 const uint8_t *R2modN,
9140                                 const uint8_t *aCurveParam,
9141                                 const uint8_t *bCurveParam,
9142                                 size_t size,
9143                                 caam_pkha_timing_t equalTime,
9144                                 caam_pkha_f2m_t arithType,
9145                                 caam_pkha_ecc_point_t *result)
9146 {
9147     caam_desc_pkha_ecc_t descBuf;
9148     status_t status;
9149 
9150     do
9151     {
9152         status = CAAM_PKHA_ECC_PointMulNonBlocking(base, handle, descBuf, A, E, sizeE, N, R2modN, aCurveParam,
9153                                                    bCurveParam, size, equalTime, arithType, result);
9154     } while (status == kStatus_CAAM_Again);
9155 
9156     if (status != kStatus_Success)
9157     {
9158         return status;
9159     }
9160 
9161     status = CAAM_Wait(base, handle, descBuf, kCAAM_Blocking);
9162 #if defined(CAAM_OUT_INVALIDATE) && (CAAM_OUT_INVALIDATE > 0u)
9163     /* NOTE: DCACHE must be set to write-trough mode to safely invalidate cache!! */
9164     /* Invalidate unaligned data can cause memory corruption in write-back mode   */
9165     DCACHE_InvalidateByRange((uint32_t)result->X, size);
9166     DCACHE_InvalidateByRange((uint32_t)result->Y, size);
9167 #endif /* CAAM_OUT_INVALIDATE */
9168     return status;
9169 }
9170 
9171 /*!
9172  * brief Converts from integer to Montgomery format.
9173  *
9174  * This function computes R2 mod N and optionally converts A or B into Montgomery format of A or B.
9175  *
9176  * param base CAAM peripheral base address
9177  * param N modulus
9178  * param sizeN size of N in bytes
9179  * param[in,out] A The first input in non-Montgomery format. Output Montgomery format of the first input.
9180  * param[in,out] sizeA pointer to size variable. On input it holds size of input A in bytes. On output it holds size of
9181  *                Montgomery format of A in bytes.
9182  * param[in,out] B Second input in non-Montgomery format. Output Montgomery format of the second input.
9183  * param[in,out] sizeB pointer to size variable. On input it holds size of input B in bytes. On output it holds size of
9184  *                Montgomery format of B in bytes.
9185  * param[out] R2 Output Montgomery factor R2 mod N.
9186  * param[out] sizeR2 pointer to size variable. On output it holds size of Montgomery factor R2 mod N in bytes.
9187  * param equalTime Run the function time equalized or no timing equalization.
9188  * param arithType Type of arithmetic to perform (integer or F2m)
9189  * return Operation status.
9190  */
CAAM_PKHA_NormalToMontgomery(CAAM_Type * base,caam_handle_t * handle,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,caam_pkha_timing_t equalTime,caam_pkha_f2m_t arithType)9191 status_t CAAM_PKHA_NormalToMontgomery(CAAM_Type *base,
9192                                       caam_handle_t *handle,
9193                                       const uint8_t *N,
9194                                       size_t sizeN,
9195                                       uint8_t *A,
9196                                       size_t *sizeA,
9197                                       uint8_t *B,
9198                                       size_t *sizeB,
9199                                       uint8_t *R2,
9200                                       size_t *sizeR2,
9201                                       caam_pkha_timing_t equalTime,
9202                                       caam_pkha_f2m_t arithType)
9203 {
9204     status_t status;
9205 
9206     /* need to convert our Integer inputs into Montgomery format */
9207     if ((N != NULL) && (sizeN != 0U) && (R2 != NULL) && (sizeR2 != NULL))
9208     {
9209         /* 1. R2 = MOD_R2(N) */
9210         status = CAAM_PKHA_ModR2(base, handle, N, sizeN, R2, sizeR2, arithType);
9211         if (status != kStatus_Success)
9212         {
9213             return status;
9214         }
9215 
9216         /* 2. A(Montgomery) = MOD_MUL_IM_OM(A, R2, N) */
9217         if ((A != NULL) && (sizeA != NULL))
9218         {
9219             status = CAAM_PKHA_ModMul(base, handle, A, *sizeA, R2, *sizeR2, N, sizeN, A, sizeA, arithType,
9220                                       kCAAM_PKHA_MontgomeryFormat, kCAAM_PKHA_MontgomeryFormat, equalTime);
9221             if (status != kStatus_Success)
9222             {
9223                 return status;
9224             }
9225         }
9226 
9227         /* 2. B(Montgomery) = MOD_MUL_IM_OM(B, R2, N) */
9228         if ((B != NULL) && (sizeB != NULL))
9229         {
9230             status = CAAM_PKHA_ModMul(base, handle, B, *sizeB, R2, *sizeR2, N, sizeN, B, sizeB, arithType,
9231                                       kCAAM_PKHA_MontgomeryFormat, kCAAM_PKHA_MontgomeryFormat, equalTime);
9232             if (status != kStatus_Success)
9233             {
9234                 return status;
9235             }
9236         }
9237     }
9238     else
9239     {
9240         status = kStatus_InvalidArgument;
9241     }
9242 
9243     return status;
9244 }
9245 
9246 /*!
9247  * brief Converts from Montgomery format to int.
9248  *
9249  * This function converts Montgomery format of A or B into int A or B.
9250  *
9251  * param base CAAM peripheral base address
9252  * param N modulus.
9253  * param sizeN size of N modulus in bytes.
9254  * param[in,out] A Input first number in Montgomery format. Output is non-Montgomery format.
9255  * param[in,out] sizeA pointer to size variable. On input it holds size of the input A in bytes. On output it holds
9256  * size of non-Montgomery A in bytes.
9257  * param[in,out] B Input first number in Montgomery format. Output is non-Montgomery format.
9258  * param[in,out] sizeB pointer to size variable. On input it holds size of the input B in bytes. On output it holds
9259  * size of non-Montgomery B in bytes.
9260  * param equalTime Run the function time equalized or no timing equalization.
9261  * param arithType Type of arithmetic to perform (integer or F2m)
9262  * return Operation status.
9263  */
CAAM_PKHA_MontgomeryToNormal(CAAM_Type * base,caam_handle_t * handle,const uint8_t * N,size_t sizeN,uint8_t * A,size_t * sizeA,uint8_t * B,size_t * sizeB,caam_pkha_timing_t equalTime,caam_pkha_f2m_t arithType)9264 status_t CAAM_PKHA_MontgomeryToNormal(CAAM_Type *base,
9265                                       caam_handle_t *handle,
9266                                       const uint8_t *N,
9267                                       size_t sizeN,
9268                                       uint8_t *A,
9269                                       size_t *sizeA,
9270                                       uint8_t *B,
9271                                       size_t *sizeB,
9272                                       caam_pkha_timing_t equalTime,
9273                                       caam_pkha_f2m_t arithType)
9274 {
9275     uint8_t one     = 1;
9276     status_t status = kStatus_InvalidArgument;
9277 
9278     /* A = MOD_MUL_IM_OM(A(Montgomery), 1, N) */
9279     if ((A != NULL) && (sizeA != NULL))
9280     {
9281         status = CAAM_PKHA_ModMul(base, handle, A, *sizeA, &one, sizeof(one), N, sizeN, A, sizeA, arithType,
9282                                   kCAAM_PKHA_MontgomeryFormat, kCAAM_PKHA_MontgomeryFormat, equalTime);
9283         if (kStatus_Success != status)
9284         {
9285             return status;
9286         }
9287     }
9288 
9289     /* B = MOD_MUL_IM_OM(B(Montgomery), 1, N) */
9290     if ((B != NULL) && (sizeB != NULL))
9291     {
9292         status = CAAM_PKHA_ModMul(base, handle, B, *sizeB, &one, sizeof(one), N, sizeN, B, sizeB, arithType,
9293                                   kCAAM_PKHA_MontgomeryFormat, kCAAM_PKHA_MontgomeryFormat, equalTime);
9294         if (kStatus_Success != status)
9295         {
9296             return status;
9297         }
9298     }
9299     return status;
9300 }
9301