1 /***************************************************************************//**
2 * \file cy_crypto_core_aes_v1.c
3 * \version 2.120
4 *
5 * \brief
6 *  This file provides the source code fro the API for the AES method
7 *  in the Crypto driver.
8 *
9 ********************************************************************************
10 * \copyright
11 * Copyright (c) (2020-2022), Cypress Semiconductor Corporation (an Infineon company) or
12 * an affiliate of Cypress Semiconductor Corporation.
13 * SPDX-License-Identifier: Apache-2.0
14 *
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 *    http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *******************************************************************************/
27 
28 #include "cy_device.h"
29 
30 #if defined(CY_IP_MXCRYPTO)
31 
32 #include "cy_crypto_core_aes_v1.h"
33 
34 #if defined(CY_CRYPTO_CFG_HW_V1_ENABLE)
35 
36 #if defined(__cplusplus)
37 extern "C" {
38 #endif
39 
40 #if (CPUSS_CRYPTO_AES == 1) && defined(CY_CRYPTO_CFG_AES_C)
41 
42 #include "cy_crypto_core_hw_v1.h"
43 #include "cy_crypto_core_mem_v1.h"
44 #include "cy_syslib.h"
45 
46 static void Cy_Crypto_Core_V1_Aes_InvKey(CRYPTO_Type *base, cy_stc_crypto_aes_state_t const *aesState);
47 
48 /*******************************************************************************
49 * Function Name: Cy_Crypto_Core_V1_Aes_ProcessBlock
50 ****************************************************************************//**
51 *
52 * Performs the AES block cipher.
53 *
54 * \param base
55 * The pointer to the CRYPTO instance.
56 *
57 * \param aesState
58 * The pointer to the AES state structure allocated by the user. The user
59 * must not modify anything in this structure.
60 *
61 * \param dirMode
62 * One of CRYPTO_ENCRYPT or CRYPTO_DECRYPT.
63 *
64 * \param dstBlock
65 * The pointer to the cipher text.
66 *
67 * \param srcBlock
68 * The pointer to the plain text. Must be 4-Byte aligned!
69 *
70 *******************************************************************************/
Cy_Crypto_Core_V1_Aes_ProcessBlock(CRYPTO_Type * base,cy_stc_crypto_aes_state_t const * aesState,cy_en_crypto_dir_mode_t dirMode,uint32_t * dstBlock,uint32_t const * srcBlock)71 void Cy_Crypto_Core_V1_Aes_ProcessBlock(CRYPTO_Type *base,
72                             cy_stc_crypto_aes_state_t const *aesState,
73                             cy_en_crypto_dir_mode_t dirMode,
74                             uint32_t *dstBlock,
75                             uint32_t const *srcBlock)
76 {
77     /* Set the key mode: 128, 192 or 256 Bit */
78     REG_CRYPTO_AES_CTL(base) = (uint32_t)(_VAL2FLD(CRYPTO_AES_CTL_KEY_SIZE, (uint32_t)(aesState->keyLength)));
79 
80     Cy_Crypto_SetReg3Instr(base,
81                            (CY_CRYPTO_DECRYPT == dirMode) ? (uint32_t)aesState->buffers->keyInv : (uint32_t)aesState->buffers->key,
82                            (uint32_t)srcBlock,
83                            (uint32_t)dstBlock);
84 
85     Cy_Crypto_Run3ParamInstr(base,
86                             (CY_CRYPTO_DECRYPT == dirMode) ? CY_CRYPTO_V1_AES_BLOCK_INV_OPC : CY_CRYPTO_V1_AES_BLOCK_OPC,
87                             CY_CRYPTO_RSRC0_SHIFT,
88                             CY_CRYPTO_RSRC4_SHIFT,
89                             CY_CRYPTO_RSRC12_SHIFT);
90 
91     /* Wait until the AES instruction is complete */
92     while (0uL != _FLD2VAL(CRYPTO_STATUS_AES_BUSY, REG_CRYPTO_STATUS(base)))
93     {
94     }
95 }
96 
97 /*******************************************************************************
98 * Function Name: Cy_Crypto_Core_V1_Aes_Xor
99 ****************************************************************************//**
100 *
101 * Perform the XOR of two 16-Byte memory structures.
102 * All addresses must be 4-Byte aligned!
103 *
104 * \param base
105 * The pointer to the CRYPTO instance.
106 *
107 * \param aesState
108 * The pointer to the AES state structure allocated by the user. The user
109 * must not modify anything in this structure.
110 *
111 * \param dstBlock
112 * The pointer to the memory structure with the XOR results.
113 *
114 * \param src0Block
115 * The pointer to the first memory structure. Must be 4-Byte aligned!
116 *
117 * \param src1Block
118 * The pointer to the second memory structure. Must be 4-Byte aligned!
119 *
120 *******************************************************************************/
Cy_Crypto_Core_V1_Aes_Xor(CRYPTO_Type * base,cy_stc_crypto_aes_state_t const * aesState,uint32_t * dstBlock,uint32_t const * src0Block,uint32_t const * src1Block)121 void Cy_Crypto_Core_V1_Aes_Xor(CRYPTO_Type *base,
122                             cy_stc_crypto_aes_state_t const *aesState,
123                             uint32_t *dstBlock,
124                             uint32_t const *src0Block,
125                             uint32_t const *src1Block)
126 {
127     /* Set the key mode: 128, 192 or 256 Bit */
128     REG_CRYPTO_AES_CTL(base) = (uint32_t)(_VAL2FLD(CRYPTO_AES_CTL_KEY_SIZE, (uint32_t)(aesState->keyLength)));
129 
130     Cy_Crypto_SetReg3Instr(base,
131                            (uint32_t)src0Block,
132                            (uint32_t)src1Block,
133                            (uint32_t)dstBlock);
134 
135     /* Issue the AES_XOR instruction */
136     Cy_Crypto_Run3ParamInstr(base,
137                              CY_CRYPTO_V1_AES_XOR_OPC,
138                              CY_CRYPTO_RSRC0_SHIFT,
139                              CY_CRYPTO_RSRC4_SHIFT,
140                              CY_CRYPTO_RSRC8_SHIFT);
141 
142     /* Wait until the AES instruction is complete */
143     while(0uL != _FLD2VAL(CRYPTO_STATUS_AES_BUSY, REG_CRYPTO_STATUS(base)))
144     {
145     }
146 }
147 
148 /*******************************************************************************
149 * Function Name: Cy_Crypto_Core_V1_Aes_InvKey
150 ****************************************************************************//**
151 *
152 * Calculates an inverse block cipher key from the block cipher key.
153 *
154 * \param base
155 * The pointer to the CRYPTO instance.
156 *
157 * \param aesState
158 * The pointer to the AES state structure allocated by the user. The user
159 * must not modify anything in this structure.
160 *
161 *******************************************************************************/
Cy_Crypto_Core_V1_Aes_InvKey(CRYPTO_Type * base,cy_stc_crypto_aes_state_t const * aesState)162 static void Cy_Crypto_Core_V1_Aes_InvKey(CRYPTO_Type *base, cy_stc_crypto_aes_state_t const *aesState)
163 {
164     /* Set the key mode: 128, 192 or 256 Bit */
165     REG_CRYPTO_AES_CTL(base) = (uint32_t)(_VAL2FLD(CRYPTO_AES_CTL_KEY_SIZE, (uint32_t)(aesState->keyLength)));
166 
167     /* Issue the AES_KEY instruction to prepare the key for decrypt operation */
168     Cy_Crypto_SetReg2Instr(base, (uint32_t)aesState->buffers->key, (uint32_t)aesState->buffers->keyInv);
169 
170     Cy_Crypto_Run2ParamInstr(base,
171                              CY_CRYPTO_V1_AES_KEY_OPC,
172                              CY_CRYPTO_RSRC0_SHIFT,
173                              CY_CRYPTO_RSRC8_SHIFT);
174 
175     /* Wait until the AES instruction is complete */
176     while(0uL != _FLD2VAL(CRYPTO_STATUS_AES_BUSY, REG_CRYPTO_STATUS(base)))
177     {
178     }
179 }
180 
181 /*******************************************************************************
182 * Function Name: Cy_Crypto_Core_V1_Aes_Init
183 ****************************************************************************//**
184 *
185 * Sets AES mode and prepares an inverse key.
186 *
187 * \param base
188 * The pointer to the CRYPTO instance.
189 *
190 * \param key
191 * The pointer to the encryption/decryption key.
192 *
193 * \param keyLength
194 * \ref cy_en_crypto_aes_key_length_t
195 *
196 * \param aesState
197 * The pointer to the AES state structure allocated by the user. The user
198 * must not modify anything in this structure.
199 *
200 * \param aesBuffers
201 * The pointer to the memory buffers storage.
202 *
203 * \return
204 * \ref cy_en_crypto_status_t
205 *
206 *******************************************************************************/
Cy_Crypto_Core_V1_Aes_Init(CRYPTO_Type * base,uint8_t const * key,cy_en_crypto_aes_key_length_t keyLength,cy_stc_crypto_aes_state_t * aesState,cy_stc_crypto_aes_buffers_t * aesBuffers)207 cy_en_crypto_status_t Cy_Crypto_Core_V1_Aes_Init(CRYPTO_Type *base,
208                                                  uint8_t const *key,
209                                                  cy_en_crypto_aes_key_length_t keyLength,
210                                                  cy_stc_crypto_aes_state_t *aesState,
211                                                  cy_stc_crypto_aes_buffers_t *aesBuffers)
212 {
213     uint16_t keySize = CY_CRYPTO_AES_128_KEY_SIZE + ((uint16_t)keyLength * 8u);
214 
215     aesState->keyLength = keyLength;
216     aesState->buffers = aesBuffers;
217 
218     Cy_Crypto_Core_V1_MemCpy(base, (uint8_t *)(aesState->buffers->key), key, keySize);
219 
220     Cy_Crypto_Core_V1_Aes_InvKey(base, aesState);
221 
222     return (CY_CRYPTO_SUCCESS);
223 }
224 
225 /*******************************************************************************
226 * Function Name: Cy_Crypto_Core_V1_Aes_Free
227 ****************************************************************************//**
228 *
229 * Clears AES operation context.
230 *
231 * \param base
232 * The pointer to the CRYPTO instance.
233 *
234 * \param aesState
235 * The pointer to the AES state structure allocated by the user. The user
236 * must not modify anything in this structure.
237 *
238 * \return
239 * \ref cy_en_crypto_status_t
240 *
241 *******************************************************************************/
Cy_Crypto_Core_V1_Aes_Free(CRYPTO_Type * base,cy_stc_crypto_aes_state_t * aesState)242 cy_en_crypto_status_t Cy_Crypto_Core_V1_Aes_Free(CRYPTO_Type *base, cy_stc_crypto_aes_state_t *aesState)
243 {
244     Cy_Crypto_Core_V1_MemSet(base, (void *)aesState->buffers, 0u, ((uint16_t)sizeof(cy_stc_crypto_aes_buffers_t)));
245     Cy_Crypto_Core_V1_MemSet(base, (void *)aesState, 0u, ((uint16_t)sizeof(cy_stc_crypto_aes_state_t)));
246 
247     return (CY_CRYPTO_SUCCESS);
248 }
249 
250 /*******************************************************************************
251 * Function Name: Cy_Crypto_Core_V1_Aes_Ecb
252 ****************************************************************************//**
253 *
254 * Performs an AES operation on one block.
255 *
256 * \param base
257 * The pointer to the CRYPTO instance.
258 *
259 * \param dirMode
260 * Can be \ref CY_CRYPTO_ENCRYPT or \ref CY_CRYPTO_DECRYPT
261 * (\ref cy_en_crypto_dir_mode_t).
262 *
263 * \param dst
264 * The pointer to a destination cipher block.
265 *
266 * \param src
267 * The pointer to a source block.
268 *
269 * \param aesState
270 * The pointer to the AES state structure allocated by the user. The user
271 * must not modify anything in this structure.
272 *
273 * \return
274 * \ref cy_en_crypto_status_t
275 *
276 *******************************************************************************/
Cy_Crypto_Core_V1_Aes_Ecb(CRYPTO_Type * base,cy_en_crypto_dir_mode_t dirMode,uint8_t * dst,uint8_t const * src,cy_stc_crypto_aes_state_t * aesState)277 cy_en_crypto_status_t Cy_Crypto_Core_V1_Aes_Ecb(CRYPTO_Type *base,
278                                             cy_en_crypto_dir_mode_t dirMode,
279                                             uint8_t *dst,
280                                             uint8_t const *src,
281                                             cy_stc_crypto_aes_state_t *aesState)
282 {
283     cy_stc_crypto_aes_buffers_t *aesBuffers = (cy_stc_crypto_aes_buffers_t*)aesState->buffers;
284 
285     Cy_Crypto_Core_V1_MemCpy(base, &aesBuffers->block0, src, CY_CRYPTO_AES_BLOCK_SIZE);
286 
287     Cy_Crypto_Core_V1_Aes_ProcessBlock(base, aesState, dirMode, (uint32_t*)&aesBuffers->block1, (uint32_t*)&aesBuffers->block0);
288 
289     Cy_Crypto_Core_V1_MemCpy(base, dst, &aesBuffers->block1, CY_CRYPTO_AES_BLOCK_SIZE);
290 
291     return (CY_CRYPTO_SUCCESS);
292 }
293 
294 #if defined(CY_CRYPTO_CFG_CIPHER_MODE_CBC)
295 /*******************************************************************************
296 * Function Name: Cy_Crypto_Core_V1_Aes_Cbc
297 ****************************************************************************//**
298 *
299 * Performs AES operation on a plain text with Cipher Block Chaining (CBC).
300 *
301 * \param base
302 * The pointer to the CRYPTO instance.
303 *
304 * \param dirMode
305 * Can be \ref CY_CRYPTO_ENCRYPT or \ref CY_CRYPTO_DECRYPT
306 * (\ref cy_en_crypto_dir_mode_t)
307 *
308 * \param srcSize
309 * The size of the source plain text.
310 *
311 * \param ivPtr
312 * The pointer to the initial vector.
313 *
314 * \param dst
315 * The pointer to a destination cipher text.
316 *
317 * \param src
318 * The pointer to a source plain text.
319 *
320 * \param aesState
321 * The pointer to the AES state structure allocated by the user. The user
322 * must not modify anything in this structure.
323 *
324 * \return
325 * \ref cy_en_crypto_status_t
326 *
327 *******************************************************************************/
Cy_Crypto_Core_V1_Aes_Cbc(CRYPTO_Type * base,cy_en_crypto_dir_mode_t dirMode,uint32_t srcSize,uint8_t * ivPtr,uint8_t * dst,uint8_t const * src,cy_stc_crypto_aes_state_t * aesState)328 cy_en_crypto_status_t Cy_Crypto_Core_V1_Aes_Cbc(CRYPTO_Type *base,
329                                             cy_en_crypto_dir_mode_t dirMode,
330                                             uint32_t srcSize,
331                                             uint8_t *ivPtr,
332                                             uint8_t *dst,
333                                             uint8_t const *src,
334                                             cy_stc_crypto_aes_state_t *aesState)
335 {
336     uint32_t size = srcSize;
337 
338     cy_stc_crypto_aes_buffers_t *aesBuffers = (cy_stc_crypto_aes_buffers_t*)aesState->buffers;
339     uint32_t *srcBuff  = (uint32_t*)(&aesBuffers->block0);
340     uint32_t *dstBuff  = (uint32_t*)(&aesBuffers->block1);
341     uint32_t *tempBuff = (uint32_t*)(&aesBuffers->block2);
342 
343     cy_en_crypto_status_t tmpResult = CY_CRYPTO_SIZE_NOT_X16;
344 
345     /* Check whether the data size is multiple of CY_CRYPTO_AES_BLOCK_SIZE */
346     if (0UL == (uint32_t)(size & (CY_CRYPTO_AES_BLOCK_SIZE - 1U)))
347     {
348         /* Copy the Initialization Vector to the local buffer because it changes during calculation */
349         Cy_Crypto_Core_V1_MemCpy(base, tempBuff, ivPtr, CY_CRYPTO_AES_BLOCK_SIZE);
350 
351         if (CY_CRYPTO_DECRYPT == dirMode)
352         {
353             while (size != 0UL)
354             {
355                 /* source message block */
356                 Cy_Crypto_Core_V1_MemCpy(base, srcBuff, src, CY_CRYPTO_AES_BLOCK_SIZE);
357 
358                 Cy_Crypto_Core_V1_Aes_ProcessBlock(base, aesState, dirMode, dstBuff, srcBuff);
359                 Cy_Crypto_Core_V1_Aes_Xor(base, aesState, dstBuff, tempBuff, dstBuff);
360 
361                 /* temporary cipher block */
362                 Cy_Crypto_Core_V1_MemCpy(base, tempBuff, srcBuff, CY_CRYPTO_AES_BLOCK_SIZE);
363 
364                 /* destination cipher text block */
365                 Cy_Crypto_Core_V1_MemCpy(base, dst, dstBuff, CY_CRYPTO_AES_BLOCK_SIZE);
366 
367                 src  += CY_CRYPTO_AES_BLOCK_SIZE;
368                 dst  += CY_CRYPTO_AES_BLOCK_SIZE;
369                 size -= CY_CRYPTO_AES_BLOCK_SIZE;
370             }
371         }
372         else
373         {
374             while (size != 0UL)
375             {
376                 /* source message block */
377                 Cy_Crypto_Core_V1_MemCpy(base, srcBuff, src, CY_CRYPTO_AES_BLOCK_SIZE);
378 
379                 Cy_Crypto_Core_V1_Aes_Xor(base, aesState, tempBuff, srcBuff, tempBuff);
380                 Cy_Crypto_Core_V1_Aes_ProcessBlock(base, aesState, dirMode, dstBuff, tempBuff);
381 
382                 /* temporary cipher block */
383                 Cy_Crypto_Core_V1_MemCpy(base, tempBuff, dstBuff, CY_CRYPTO_AES_BLOCK_SIZE);
384 
385                 /* destination cipher text block */
386                 Cy_Crypto_Core_V1_MemCpy(base, dst, dstBuff, CY_CRYPTO_AES_BLOCK_SIZE);
387 
388                 src  += CY_CRYPTO_AES_BLOCK_SIZE;
389                 dst  += CY_CRYPTO_AES_BLOCK_SIZE;
390                 size -= CY_CRYPTO_AES_BLOCK_SIZE;
391             }
392         }
393 
394         /* Copy the cipher block to the Initialization Vector */
395         Cy_Crypto_Core_V1_MemCpy(base, ivPtr, tempBuff, CY_CRYPTO_AES_BLOCK_SIZE);
396 
397         tmpResult = CY_CRYPTO_SUCCESS;
398     }
399 
400     return (tmpResult);
401 }
402 #endif /* defined(CY_CRYPTO_CFG_CIPHER_MODE_CBC) */
403 
404 #if defined(CY_CRYPTO_CFG_CIPHER_MODE_CFB)
405 /*******************************************************************************
406 * Function Name: Cy_Crypto_Core_V1_Aes_Cfb
407 ********************************************************************************
408 *
409 * Performs AES operation on a plain text with the Cipher Feedback Block method (CFB).
410 *
411 * \param base
412 * The pointer to the CRYPTO instance.
413 *
414 * \param dirMode
415 * Can be \ref CY_CRYPTO_ENCRYPT or \ref CY_CRYPTO_DECRYPT
416 * (\ref cy_en_crypto_dir_mode_t)
417 *
418 * \param srcSize
419 * The size of the source plain text.
420 *
421 * \param ivPtr
422 * The pointer to the initial vector.
423 *
424 * \param dst
425 * The pointer to a destination cipher text.
426 *
427 * \param src
428 * The pointer to a source plain text.
429 *
430 * \param aesState
431 * The pointer to the AES state structure allocated by the user. The user must
432 * must not modify anything in this structure.
433 *
434 * \return
435 * \ref cy_en_crypto_status_t
436 *
437 *******************************************************************************/
Cy_Crypto_Core_V1_Aes_Cfb(CRYPTO_Type * base,cy_en_crypto_dir_mode_t dirMode,uint32_t srcSize,uint8_t * ivPtr,uint8_t * dst,uint8_t const * src,cy_stc_crypto_aes_state_t * aesState)438 cy_en_crypto_status_t Cy_Crypto_Core_V1_Aes_Cfb(CRYPTO_Type *base,
439                                              cy_en_crypto_dir_mode_t dirMode,
440                                              uint32_t srcSize,
441                                              uint8_t *ivPtr,
442                                              uint8_t *dst,
443                                              uint8_t const *src,
444                                              cy_stc_crypto_aes_state_t *aesState)
445 {
446     uint32_t size = srcSize;
447     cy_en_crypto_status_t tmpResult = CY_CRYPTO_SIZE_NOT_X16;
448 
449     cy_stc_crypto_aes_buffers_t *aesBuffers = (cy_stc_crypto_aes_buffers_t*)aesState->buffers;
450 
451     uint32_t *srcBuff = (uint32_t*)(aesBuffers->block0);
452     uint32_t *dstBuff = (uint32_t*)(aesBuffers->block1);
453 
454     uint32_t *encBuff = dstBuff;   /* Default operation is ENCRYPT */
455 
456     /* Check whether the data size is multiple of CY_CRYPTO_AES_BLOCK_SIZE */
457     if (0UL == (size & (CY_CRYPTO_AES_BLOCK_SIZE - 1U)))
458     {
459         if (CY_CRYPTO_DECRYPT == dirMode)
460         {
461             encBuff = srcBuff;
462         }
463 
464         /* Copies the Initialization Vector to the local encode buffer. */
465         Cy_Crypto_Core_V1_MemCpy(base, encBuff, ivPtr, CY_CRYPTO_AES_BLOCK_SIZE);
466 
467         while (size != 0UL)
468         {
469             /* In this mode, (CFB) is always an encryption! */
470             Cy_Crypto_Core_V1_Aes_ProcessBlock(base, aesState, CY_CRYPTO_ENCRYPT, dstBuff, encBuff);
471 
472             /* source message block */
473             Cy_Crypto_Core_V1_MemCpy(base, srcBuff, src, CY_CRYPTO_AES_BLOCK_SIZE);
474 
475             Cy_Crypto_Core_V1_Aes_Xor(base, aesState, dstBuff, srcBuff, dstBuff);
476 
477             /* destination cipher text block */
478             Cy_Crypto_Core_V1_MemCpy(base, dst, dstBuff, CY_CRYPTO_AES_BLOCK_SIZE);
479 
480             src  += CY_CRYPTO_AES_BLOCK_SIZE;
481             dst  += CY_CRYPTO_AES_BLOCK_SIZE;
482 
483             size -= CY_CRYPTO_AES_BLOCK_SIZE;
484         }
485 
486         /* Copies the local encode buffer to the Initialization Vector. */
487         Cy_Crypto_Core_V1_MemCpy(base, ivPtr, encBuff, CY_CRYPTO_AES_BLOCK_SIZE);
488 
489         tmpResult = CY_CRYPTO_SUCCESS;
490     }
491 
492     return (tmpResult);
493 }
494 #endif /* defined(CY_CRYPTO_CFG_CIPHER_MODE_CFB) */
495 
496 #if defined(CY_CRYPTO_CFG_CIPHER_MODE_CTR)
497 /*******************************************************************************
498 * Function Name: Cy_Crypto_Core_V1_Aes_Ctr
499 ********************************************************************************
500 *
501 * Performs an AES operation on a plain text using the counter method (CTR).
502 *
503 * \param base
504 * The pointer to the CRYPTO instance.
505 *
506 * \param srcSize
507 * The size of a source plain text.
508 *
509 * \param srcOffset
510 * The size of an offset within the current block stream for resuming within the
511 * current cipher stream.
512 *
513 * \param ivPtr
514 * The 128-bit initial vector that contains a 64-bit nonce and 64-bit counter.
515 *
516 * \param streamBlock
517 * The saved stream-block for resuming. Is over-written by the function.
518 *
519 * \param dst
520 * The pointer to a destination cipher text.
521 *
522 * \param src
523 * The pointer to a source plain text. Must be 4-Byte aligned.
524 *
525 * \param aesState
526 * The pointer to the AES state structure allocated by the user. The user must
527 * must not modify anything in this structure.
528 *
529 * \return
530 * \ref cy_en_crypto_status_t
531 *
532 *******************************************************************************/
533 #define CY_CRYPTO_AES_CTR_CNT_POS          (0x02U)
Cy_Crypto_Core_V1_Aes_Ctr(CRYPTO_Type * base,uint32_t srcSize,uint32_t * srcOffset,uint8_t * ivPtr,uint8_t * streamBlock,uint8_t * dst,uint8_t const * src,cy_stc_crypto_aes_state_t * aesState)534 cy_en_crypto_status_t Cy_Crypto_Core_V1_Aes_Ctr(CRYPTO_Type *base,
535                                             uint32_t srcSize,
536                                             uint32_t *srcOffset,
537                                             uint8_t  *ivPtr,
538                                             uint8_t  *streamBlock,
539                                             uint8_t  *dst,
540                                             uint8_t  const *src,
541                                             cy_stc_crypto_aes_state_t *aesState)
542 {
543     uint32_t i;
544     uint32_t cnt;
545     uint64_t counter;
546     uint32_t blockCounter[CY_CRYPTO_AES_BLOCK_SIZE_U32] = { 0UL };
547 
548     cy_stc_crypto_aes_buffers_t *aesBuffers = (cy_stc_crypto_aes_buffers_t*)aesState->buffers;
549     uint32_t *srcBuff      = (uint32_t*)(&aesBuffers->block0);
550     uint32_t *dstBuff      = (uint32_t*)(&aesBuffers->block1);
551     uint32_t *streamBuff   = (uint32_t*)(&aesBuffers->block2);
552 
553     (void)streamBlock; /* Suppress warning */
554 
555     Cy_Crypto_Core_V1_MemCpy(base, blockCounter, ivPtr, CY_CRYPTO_AES_BLOCK_SIZE);
556 
557     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 11.3','Intentional pointer type conversion');
558     counter = CY_SWAP_ENDIAN64(*(uint64_t*)(blockCounter + CY_CRYPTO_AES_CTR_CNT_POS));
559 
560     cnt = (uint32_t)(srcSize / CY_CRYPTO_AES_BLOCK_SIZE);
561 
562     for (i = 0UL; i < cnt; i++)
563     {
564         /* source message block */
565         Cy_Crypto_Core_V1_MemCpy(base, srcBuff, src, CY_CRYPTO_AES_BLOCK_SIZE);
566 
567         /* In this mode, (CTR) is always an encryption! */
568         Cy_Crypto_Core_V1_Aes_ProcessBlock(base, aesState, CY_CRYPTO_ENCRYPT, streamBuff, blockCounter);
569 
570         /* Increment the block counter, at least 64Bits (from 128) is the counter part */
571         counter++;
572         CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 11.3','Intentional pointer type conversion');
573         *(uint64_t*)(blockCounter + CY_CRYPTO_AES_CTR_CNT_POS) = CY_SWAP_ENDIAN64(counter);
574 
575         Cy_Crypto_Core_V1_Aes_Xor(base, aesState, dstBuff, srcBuff, streamBuff);
576 
577         /* destination cipher text block */
578         Cy_Crypto_Core_V1_MemCpy(base, dst, dstBuff, CY_CRYPTO_AES_BLOCK_SIZE);
579 
580         src += CY_CRYPTO_AES_BLOCK_SIZE;
581         dst += CY_CRYPTO_AES_BLOCK_SIZE;
582     }
583 
584     Cy_Crypto_Core_V1_MemCpy(base, ivPtr, blockCounter, CY_CRYPTO_AES_BLOCK_SIZE);
585 
586     /* Save the reminder of the last non-complete block */
587     *srcOffset = (uint32_t)(srcSize % CY_CRYPTO_AES_BLOCK_SIZE);
588 
589     return (CY_CRYPTO_SUCCESS);
590 }
591 #endif /* defined(CY_CRYPTO_CFG_CIPHER_MODE_CTR) */
592 
593 #endif /* (CPUSS_CRYPTO_AES == 1) && defined(CY_CRYPTO_CFG_AES_C) */
594 
595 #if defined(__cplusplus)
596 }
597 #endif
598 
599 #endif /* defined(CY_CRYPTO_CFG_HW_V1_ENABLE) */
600 
601 #endif /* defined(CY_IP_MXCRYPTO) */
602 
603 
604 /* [] END OF FILE */
605