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