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