1 /***************************************************************************//**
2 * \file cy_crypto_core_rsa.c
3 * \version 2.120
4 *
5 * \brief
6 *  This file provides the source code to the API to calculate
7 *  a signature by the RSA method in the Crypto block 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 #if defined(__cplusplus)
33 extern "C" {
34 #endif
35 
36 #include "cy_crypto_core_rsa.h"
37 
38 #if (CPUSS_CRYPTO_VU == 1) && defined(CY_CRYPTO_CFG_RSA_C)
39 
40 #include "cy_crypto_core_vu.h"
41 #include "cy_crypto_core_mem.h"
42 #include "cy_syslib.h"
43 #include <string.h>
44 
45 /* Functions prototypes */
46 static cy_en_crypto_status_t Cy_Crypto_Core_Rsa_MontCoeff(CRYPTO_Type *base, uint32_t modDerReg, uint32_t modReg, uint32_t size);
47 static cy_en_crypto_status_t Cy_Crypto_Core_Rsa_BarrettGetU(CRYPTO_Type *base, uint32_t barrettUReg, uint32_t modReg, uint32_t size);
48 static cy_en_crypto_status_t Cy_Crypto_Core_Rsa_MontTransform(CRYPTO_Type *base, uint32_t z, uint32_t a, uint32_t barrett, uint32_t mod, uint32_t size);
49 static cy_en_crypto_status_t Cy_Crypto_Core_Rsa_MontMul(CRYPTO_Type *base, uint32_t z, uint32_t a, uint32_t b, uint32_t montModDer, uint32_t mod, uint32_t size);
50 
51 static cy_en_crypto_status_t Cy_Crypto_Core_Rsa_expModByMont(CRYPTO_Type *base,
52                                      uint32_t y,
53                                      uint32_t x,
54                                      uint32_t e,
55                                      uint32_t n,
56                                      uint32_t barretCoef,
57                                      uint32_t inverseModulo,
58                                      uint32_t rBar,
59                                      uint32_t size);
60 
61 #if (defined(CY_CRYPTO_CFG_RSA_VERIFY_ENABLED) || defined(CY_CRYPTO_CFG_RSA_SIGN_ENABLED))
62     /* Encodings for hash functions */
63 
64     #define CY_CRYPTO_SHA1_PADDING_SIZE        (15u)
65     #define CY_CRYPTO_SHA256_512_PADDING_SIZE  (19u)
66 
67     #if (CPUSS_CRYPTO_SHA1 == 1) && defined(CY_CRYPTO_CFG_SHA1_ENABLED)
68     static const uint8_t sha1EncStr[CY_CRYPTO_SHA1_PADDING_SIZE] =
69     {
70         0x30u, 0x21u, 0x30u, 0x09u, 0x06u, 0x05u, 0x2Bu, 0x0Eu,
71         0x03u, 0x02u, 0x1Au, 0x05u, 0x00u, 0x04u, 0x14u
72     };
73     #endif /* (CPUSS_CRYPTO_SHA1 == 1) && defined(CY_CRYPTO_CFG_SHA1_ENABLED) */
74 
75     #if (CPUSS_CRYPTO_SHA256 == 1) && defined(CY_CRYPTO_CFG_SHA2_256_ENABLED)
76     static const uint8_t sha224EncStr[CY_CRYPTO_SHA256_512_PADDING_SIZE] =
77     {
78         0x30u, 0x2Du, 0x30u, 0x0Du, 0x06u, 0x09u, 0x60u, 0x86u,
79         0x48u, 0x01u, 0x65u, 0x03u, 0x04u, 0x02u, 0x04u, 0x05u,
80         0x00u, 0x04u, 0x1Cu
81     };
82 
83     static const uint8_t sha256EncStr[CY_CRYPTO_SHA256_512_PADDING_SIZE] =
84     {
85         0x30u, 0x31u, 0x30u, 0x0Du, 0x06u, 0x09u, 0x60u, 0x86u,
86         0x48u, 0x01u, 0x65u, 0x03u, 0x04u, 0x02u, 0x01u, 0x05u,
87         0x00u, 0x04u, 0x20u
88     };
89     #endif /* (CPUSS_CRYPTO_SHA256 == 1) && defined(CY_CRYPTO_CFG_SHA2_256_ENABLED) */
90 
91     #if (CPUSS_CRYPTO_SHA512 == 1) && defined(CY_CRYPTO_CFG_SHA2_512_ENABLED)
92     static const uint8_t sha384EncStr[CY_CRYPTO_SHA256_512_PADDING_SIZE] =
93     {
94         0x30u, 0x41u, 0x30u, 0x0Du, 0x06u, 0x09u, 0x60u, 0x86u,
95         0x48u, 0x01u, 0x65u, 0x03u, 0x04u, 0x02u, 0x02u, 0x05u,
96         0x00u, 0x04u, 0x30u
97     };
98 
99     static const uint8_t sha512EncStr[CY_CRYPTO_SHA256_512_PADDING_SIZE] =
100     {
101         0x30u, 0x51u, 0x30u, 0x0Du, 0x06u, 0x09u, 0x60u, 0x86u,
102         0x48u, 0x01u, 0x65u, 0x03u, 0x04u, 0x02u, 0x03u, 0x05u,
103         0x00u, 0x04u, 0x40u
104     };
105 
106     static const uint8_t sha512_224EncStr[CY_CRYPTO_SHA256_512_PADDING_SIZE] =
107     {
108         0x30u, 0x2Du, 0x30u, 0x0Du, 0x06u, 0x09u, 0x60u, 0x86u,
109         0x48u, 0x01u, 0x65u, 0x03u, 0x04u, 0x02u, 0x05u, 0x05u,
110         0x00u, 0x04u, 0x1Cu
111     };
112 
113     static const uint8_t sha512_256EncStr[CY_CRYPTO_SHA256_512_PADDING_SIZE] =
114     {
115         0x30u, 0x31u, 0x30u, 0x0Du, 0x06u, 0x09u, 0x60u, 0x86u,
116         0x48u, 0x01u, 0x65u, 0x03u, 0x04u, 0x02u, 0x06u, 0x05u,
117         0x00u, 0x04u, 0x20u
118     };
119     #endif /* (CPUSS_CRYPTO_SHA512 == 1) && defined(CY_CRYPTO_CFG_SHA2_512_ENABLED) */
120 #endif /* (defined(CY_CRYPTO_CFG_RSA_VERIFY_ENABLED) || defined(CY_CRYPTO_CFG_RSA_SIGN_ENABLED)) */
121 
122 
123 #if defined(CY_CRYPTO_CFG_RSA_VERIFY_ENABLED)
124 
125 
126 /**
127 * \addtogroup group_crypto_lld_asymmetric_functions
128 * \{
129 */
130 
131 /*******************************************************************************
132 * Function Name: Cy_Crypto_Core_Rsa_Verify
133 ****************************************************************************//**
134 *
135 * RSA verification with checks for content, paddings and signature format.
136 * SHA digest of the message and decrypted message should be calculated before.
137 * Supports only PKCS1-v1_5 format, inside of this format supported padding
138 * using only SHA, cases with MD2 and MD5 are not supported.
139 * PKCS1-v1_5 described here, page 31:
140 * http://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf
141 *
142 * For CAT1C & CAT1D devices when D-Cache is enabled parameter decryptedSignature must align and end in 32 byte boundary.
143 *
144 * Returns the verification result \ref cy_en_crypto_rsa_ver_result_t.
145 *
146 * \param base
147 * The pointer to the CRYPTO instance.
148 *
149 * \param verResult
150 * The pointer to the verification result \ref cy_en_crypto_rsa_ver_result_t.
151 *
152 * \param digestType
153 * SHA mode used for hash calculation \ref cy_en_crypto_sha_mode_t.
154 *
155 * \param digest
156 * The pointer to the hash of the message or the message whose signature is to be verified.
157 *
158 * \param decryptedSignature
159 * The pointer to the decrypted signature to be verified.
160 *
161 * \param decryptedSignatureLength
162 * The length of the decrypted signature to be verified (in bytes)
163 *
164 * \return
165 * \ref cy_en_crypto_status_t
166 *
167 * \funcusage
168 * \snippet crypto/snippet/main.c snippet_myCryptoCoreRsaVerUse
169 *
170 *******************************************************************************/
Cy_Crypto_Core_Rsa_Verify(CRYPTO_Type * base,cy_en_crypto_rsa_ver_result_t * verResult,cy_en_crypto_sha_mode_t digestType,uint8_t const * digest,uint8_t const * decryptedSignature,uint32_t decryptedSignatureLength)171 cy_en_crypto_status_t Cy_Crypto_Core_Rsa_Verify(CRYPTO_Type *base,
172                             cy_en_crypto_rsa_ver_result_t *verResult,
173                             cy_en_crypto_sha_mode_t digestType,
174                             uint8_t const *digest,
175                             uint8_t const *decryptedSignature,
176                             uint32_t decryptedSignatureLength)
177 {
178     if(digestType == CY_CRYPTO_MODE_SHA_NONE)
179     {
180         return CY_CRYPTO_BAD_PARAMS;
181     }
182 
183     return Cy_Crypto_Core_Rsa_Verify_Ext(base,
184                                 verResult,
185                                 digestType,
186                                 digest,
187                                 0,
188                                 decryptedSignature,
189                                 decryptedSignatureLength);
190 }
191 /*******************************************************************************
192 * Function Name: Cy_Crypto_Core_Rsa_Verify_Ext
193 ****************************************************************************//**
194 *
195 * RSA verification with checks for content, paddings and signature format.
196 * SHA digest of the message and decrypted message should be calculated before.
197 * Supports only PKCS1-v1_5 format, inside of this format supported padding
198 * using only SHA, cases with MD2 and MD5 are not supported.
199 * PKCS1-v1_5 described here, page 31:
200 * http://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf
201 *
202 * For CAT1C & CAT1D devices when D-Cache is enabled parameter decryptedSignature must align and end in 32 byte boundary.
203 *
204 * Returns the verification result \ref cy_en_crypto_rsa_ver_result_t.
205 *
206 * \param base
207 * The pointer to the CRYPTO instance.
208 *
209 * \param verResult
210 * The pointer to the verification result \ref cy_en_crypto_rsa_ver_result_t.
211 *
212 * \param digestType
213 * SHA mode used for hash calculation \ref cy_en_crypto_sha_mode_t.
214 *
215 * \param digest
216 * The pointer to the hash of the message or the message whose signature is to be verified.
217 *
218 * \param digestLength
219 * The length of the message whose signature is to be verified and is applicable for CY_CRYPTO_MODE_SHA_NONE mode.
220 *
221 * \param decryptedSignature
222 * The pointer to the decrypted signature to be verified.
223 *
224 * \param decryptedSignatureLength
225 * The length of the decrypted signature to be verified (in bytes)
226 *
227 * \return
228 * \ref cy_en_crypto_status_t
229 *
230 * \funcusage
231 * \snippet crypto/snippet/main.c snippet_myCryptoCoreRsaVerUse
232 *
233 *******************************************************************************/
Cy_Crypto_Core_Rsa_Verify_Ext(CRYPTO_Type * base,cy_en_crypto_rsa_ver_result_t * verResult,cy_en_crypto_sha_mode_t digestType,uint8_t const * digest,uint32_t digestLength,uint8_t const * decryptedSignature,uint32_t decryptedSignatureLength)234 cy_en_crypto_status_t Cy_Crypto_Core_Rsa_Verify_Ext(CRYPTO_Type *base,
235                             cy_en_crypto_rsa_ver_result_t *verResult,
236                             cy_en_crypto_sha_mode_t digestType,
237                             uint8_t const *digest,
238                             uint32_t digestLength,
239                             uint8_t const *decryptedSignature,
240                             uint32_t decryptedSignatureLength)
241 {
242     cy_en_crypto_status_t tmpResult = CY_CRYPTO_SUCCESS;
243     uint32_t encodingArrSize = 0u;
244     uint32_t locDigestSize = 0u;
245     uint32_t i;
246     uint32_t psLength;
247     uint32_t cmpRes = 0u;
248     uint8_t *digestRemap;
249     uint8_t *decryptedSignatureRemap;
250     uint8_t *decryptedSignatureIn;
251     uint8_t *encodingArr = NULL;
252     uint8_t *encodingArrRemap = NULL;
253 
254     if( (NULL == verResult) || ((NULL == digest) && (digestLength != 0UL))  || (NULL == decryptedSignature) )
255     {
256         tmpResult =  CY_CRYPTO_BAD_PARAMS;
257     }
258 
259     digestRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(digest);
260     decryptedSignatureRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(decryptedSignature);
261     decryptedSignatureIn = (uint8_t *)decryptedSignature;
262 
263     if(tmpResult == CY_CRYPTO_SUCCESS)
264     {
265         switch (digestType)
266         {
267 
268         #if (CPUSS_CRYPTO_SHA1 == 1) && defined(CY_CRYPTO_CFG_SHA1_ENABLED)
269         case CY_CRYPTO_MODE_SHA1:
270             encodingArr  = (uint8_t *)sha1EncStr;
271             encodingArrSize = sizeof(sha1EncStr);
272             locDigestSize      = CY_CRYPTO_SHA1_DIGEST_SIZE;
273             break;
274         #endif /* (CPUSS_CRYPTO_SHA1 == 1) && defined(CY_CRYPTO_CFG_SHA1_ENABLED) */
275 
276         #if (CPUSS_CRYPTO_SHA256 == 1) && defined(CY_CRYPTO_CFG_SHA2_256_ENABLED)
277         case CY_CRYPTO_MODE_SHA224:
278             encodingArr  = (uint8_t *)sha224EncStr;
279             encodingArrSize = sizeof(sha224EncStr);
280             locDigestSize      = CY_CRYPTO_SHA224_DIGEST_SIZE;
281             break;
282 
283         case CY_CRYPTO_MODE_SHA256:
284             encodingArr  = (uint8_t *)sha256EncStr;
285             encodingArrSize = sizeof(sha256EncStr);
286             locDigestSize      = CY_CRYPTO_SHA256_DIGEST_SIZE;
287             break;
288         #endif /* (CPUSS_CRYPTO_SHA256 == 1) && defined(CY_CRYPTO_CFG_SHA2_256_ENABLED) */
289 
290         #if (CPUSS_CRYPTO_SHA512 == 1) && defined(CY_CRYPTO_CFG_SHA2_512_ENABLED)
291         case CY_CRYPTO_MODE_SHA384:
292             encodingArr  = (uint8_t *)sha384EncStr;
293             encodingArrSize = sizeof(sha384EncStr);
294             locDigestSize      = CY_CRYPTO_SHA384_DIGEST_SIZE;
295             break;
296 
297         case CY_CRYPTO_MODE_SHA512:
298             encodingArr  = (uint8_t *)sha512EncStr;
299             encodingArrSize = sizeof(sha512EncStr);
300             locDigestSize      = CY_CRYPTO_SHA512_DIGEST_SIZE;
301             break;
302 
303         case CY_CRYPTO_MODE_SHA512_224:
304             encodingArr  = (uint8_t *)sha512_224EncStr;
305             encodingArrSize = sizeof(sha512_224EncStr);
306             locDigestSize      = CY_CRYPTO_SHA512_224_DIGEST_SIZE;
307             break;
308 
309         case CY_CRYPTO_MODE_SHA512_256:
310             encodingArr  = (uint8_t *)sha512_256EncStr;
311             encodingArrSize = sizeof(sha512_256EncStr);
312             locDigestSize      = CY_CRYPTO_SHA512_256_DIGEST_SIZE;
313             break;
314         #endif /* (CPUSS_CRYPTO_SHA512 == 1) && defined(CY_CRYPTO_CFG_SHA2_512_ENABLED) */
315         case CY_CRYPTO_MODE_SHA_NONE:
316             encodingArr  = NULL;
317             encodingArrSize = 0;
318             locDigestSize  = digestLength;
319             break;
320         default:
321         /* Unknown Digest Type */
322             break;
323         }
324 
325         /* Fail by default */
326         *verResult = CY_CRYPTO_RSA_VERIFY_FAIL;
327 
328         encodingArrRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(encodingArr);
329 
330         if (CY_CRYPTO_MODE_SHA_NONE != digestType)
331         {
332             /* Check size of decrypted message */
333             if (decryptedSignatureLength < (encodingArrSize + locDigestSize + 11u))
334             {
335                 cmpRes = 1u;  /* further checking is not needed */
336             }
337 
338         }
339 
340 
341         psLength = decryptedSignatureLength - locDigestSize - encodingArrSize - 3u;
342 
343         /* Check whether the begin of message is 0x00, 0x01 and after PS string (before T string) is 0x00 byte.*/
344         if ( (0u != cmpRes) ||
345             (0x00u != *(decryptedSignatureIn)) ||
346             (0x01u != *(decryptedSignatureIn + 1)) ||
347             (0x00u != *(decryptedSignatureIn + psLength + 2u)) )
348         {
349             cmpRes = 1u;  /* Further checking is not needed */
350         }
351 
352         /* Check FFs */
353         if (0u == cmpRes )
354         {
355             for (i = 0u; i < psLength; i++)
356             {
357                 if (0xFFu != *(decryptedSignatureIn + 2u + i))
358                 {
359                     cmpRes = 1u;  /* Further checking is not needed */
360                     break;
361                 }
362             }
363         }
364 
365     #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
366 
367             /* Flush the cache */
368             SCB_CleanDCache_by_Addr((volatile void *)(decryptedSignatureIn),(int32_t)decryptedSignatureLength);
369     #endif
370 
371         if ((CY_CRYPTO_MODE_SHA_NONE != digestType) && (0u == cmpRes))
372         {
373 
374             cmpRes = Cy_Crypto_Core_MemCmp(base, (void const *)encodingArrRemap,
375                             (void const *)(decryptedSignatureRemap + psLength + 3u),
376                             (uint16_t)encodingArrSize);
377         }
378 
379         /* Check the digest */
380         if (0u == cmpRes)
381         {
382 
383             cmpRes = Cy_Crypto_Core_MemCmp(base, (void const *)digestRemap,
384                             (void const *)(decryptedSignatureRemap + (decryptedSignatureLength - locDigestSize)),
385                             (uint16_t)locDigestSize);
386         }
387 
388         if (0u == cmpRes )
389         {
390             *verResult = CY_CRYPTO_RSA_VERIFY_SUCCESS;
391         }
392     }
393 
394     return (tmpResult);
395 }
396 
397 /** \} group_crypto_lld_asymmetric_functions */
398 #endif /* defined(CY_CRYPTO_CFG_RSA_VERIFY_ENABLED) */
399 
400 
401 
402 #if defined(CY_CRYPTO_CFG_RSA_SIGN_ENABLED)
403 /*******************************************************************************
404 * Function Name: Cy_Crypto_Core_Rsa_Sign
405 ****************************************************************************//**
406 *
407 * The functions forms the PKCS1-v1_5 padding of the message needed for signature generation.
408 * \ref Cy_Crypto_Core_Rsa_Proc should be called after for generating the signature.
409 * Supports only PKCS1-v1_5 format, inside of this format supported padding
410 * using only SHA, cases with MD2 and MD5 are not supported.
411 * PKCS1-v1_5 described here, page 31:
412 * http://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf
413 *
414 * For CAT1C & CAT1D devices when D-Cache is enabled parameter digest & signature must align and end in 32 byte boundary.
415 *
416 *
417 * \param base
418 * The pointer to the CRYPTO instance.
419 *
420 * \param digestType
421 * SHA mode used for hash calculation \ref cy_en_crypto_sha_mode_t.
422 *
423 * \param digest
424 * The pointer to the hash of the message or the message whose signature is to be generated.
425 *
426 * \param digestLength
427 * The length of the message whose signature to be generated and is applicable for CY_CRYPTO_MODE_SHA_NONE mode.
428 *
429 * \param signature
430 * The pointer to the signature buffer.
431 *
432 * \param signatureLength
433 * The length of the signature buffer.
434 *
435 * \return
436 * \ref cy_en_crypto_status_t
437 *
438 *******************************************************************************/
Cy_Crypto_Core_Rsa_Sign(CRYPTO_Type * base,cy_en_crypto_sha_mode_t digestType,uint8_t const * digest,uint32_t digestLength,uint8_t * signature,uint32_t signatureLength)439 cy_en_crypto_status_t Cy_Crypto_Core_Rsa_Sign(CRYPTO_Type *base,
440                             cy_en_crypto_sha_mode_t digestType,
441                             uint8_t const *digest,
442                             uint32_t digestLength,
443                             uint8_t *signature,
444                             uint32_t signatureLength)
445 {
446     cy_en_crypto_status_t tmpResult = CY_CRYPTO_SUCCESS;
447     uint8_t  *encodingArr = NULL;
448     uint32_t encodingArrSize = 0u;
449     uint32_t locDigestSize = 0u;
450     uint32_t psLength;
451     uint8_t* digestRemap;
452     uint8_t* signatureRemap;
453     uint8_t  *encodingArrRemap = NULL;
454     uint8_t* signaturePtr;
455     uint32_t oidSize = 0u;
456 
457     if( ((NULL == digest) && (digestLength != 0UL))  || (NULL == signature) )
458     {
459         tmpResult = CY_CRYPTO_BAD_PARAMS;
460     }
461 
462     digestRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(digest);
463     signatureRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(signature);
464     signaturePtr = signature;
465 
466     if(tmpResult == CY_CRYPTO_SUCCESS)
467     {
468         switch (digestType)
469         {
470 
471         #if (CPUSS_CRYPTO_SHA1 == 1) && defined(CY_CRYPTO_CFG_SHA1_ENABLED)
472         case CY_CRYPTO_MODE_SHA1:
473             encodingArr  = (uint8_t *)sha1EncStr;
474             encodingArrSize = sizeof(sha1EncStr);
475             locDigestSize      = CY_CRYPTO_SHA1_DIGEST_SIZE;
476             break;
477         #endif /* (CPUSS_CRYPTO_SHA1 == 1) && defined(CY_CRYPTO_CFG_SHA1_ENABLED) */
478 
479         #if (CPUSS_CRYPTO_SHA256 == 1) && defined(CY_CRYPTO_CFG_SHA2_256_ENABLED)
480         case CY_CRYPTO_MODE_SHA224:
481             encodingArr  = (uint8_t *)sha224EncStr;
482             encodingArrSize = sizeof(sha224EncStr);
483             locDigestSize      = CY_CRYPTO_SHA224_DIGEST_SIZE;
484             break;
485 
486         case CY_CRYPTO_MODE_SHA256:
487             encodingArr  = (uint8_t *)sha256EncStr;
488             encodingArrSize = sizeof(sha256EncStr);
489             locDigestSize      = CY_CRYPTO_SHA256_DIGEST_SIZE;
490             break;
491         #endif /* (CPUSS_CRYPTO_SHA256 == 1) && defined(CY_CRYPTO_CFG_SHA2_256_ENABLED) */
492 
493         #if (CPUSS_CRYPTO_SHA512 == 1) && defined(CY_CRYPTO_CFG_SHA2_512_ENABLED)
494         case CY_CRYPTO_MODE_SHA384:
495             encodingArr  = (uint8_t *)sha384EncStr;
496             encodingArrSize = sizeof(sha384EncStr);
497             locDigestSize      = CY_CRYPTO_SHA384_DIGEST_SIZE;
498             break;
499 
500         case CY_CRYPTO_MODE_SHA512:
501             encodingArr  = (uint8_t *)sha512EncStr;
502             encodingArrSize = sizeof(sha512EncStr);
503             locDigestSize      = CY_CRYPTO_SHA512_DIGEST_SIZE;
504             break;
505 
506         case CY_CRYPTO_MODE_SHA512_224:
507             encodingArr  = (uint8_t *)sha512_224EncStr;
508             encodingArrSize = sizeof(sha512_224EncStr);
509             locDigestSize      = CY_CRYPTO_SHA512_224_DIGEST_SIZE;
510             break;
511 
512         case CY_CRYPTO_MODE_SHA512_256:
513             encodingArr  = (uint8_t *)sha512_256EncStr;
514             encodingArrSize = sizeof(sha512_256EncStr);
515             locDigestSize      = CY_CRYPTO_SHA512_256_DIGEST_SIZE;
516             break;
517         #endif /* (CPUSS_CRYPTO_SHA512 == 1) && defined(CY_CRYPTO_CFG_SHA2_512_ENABLED) */
518         case CY_CRYPTO_MODE_SHA_NONE:
519             encodingArr  = NULL;
520             encodingArrSize = 0;
521             locDigestSize  = digestLength;
522             break;
523         default:
524         /* Unknown Digest Type */
525             break;
526         }
527 
528         if(NULL != encodingArr)
529         {
530             oidSize = encodingArr[5u];
531         }
532 
533         encodingArrRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(encodingArr);
534 
535         if(CY_CRYPTO_MODE_SHA_NONE == digestType)
536         {
537             // 3bytes for signature header & padding delimiter and 8 bytes for minimal padding.
538             if(signatureLength < locDigestSize + 3u + 8u)
539             {
540                 return CY_CRYPTO_BAD_PARAMS;
541             }
542         }
543         else
544         {
545             if(signatureLength < 10u + locDigestSize + oidSize +3u +8u)
546             {
547                 return CY_CRYPTO_BAD_PARAMS;
548             }
549 
550             if(locDigestSize != digestLength)
551             {
552                 return CY_CRYPTO_BAD_PARAMS;
553             }
554         }
555 
556 
557         psLength = signatureLength - locDigestSize - encodingArrSize - 3u;
558 
559         /* Set the beginning of message to 0x00, 0x01*/
560         *signaturePtr++ = 0x00u;
561         *signaturePtr++ = 0x01u;
562 
563     #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
564             /* Flush the cache */
565             SCB_CleanDCache_by_Addr((volatile void *)(signature),(int32_t)signatureLength);
566             SCB_CleanDCache_by_Addr((volatile void *)(digest),(int32_t)digestLength);
567 
568     #endif
569 
570         signatureRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(signaturePtr);
571 
572         Cy_Crypto_Core_MemSet(base, signatureRemap, 0xFF, (uint16_t)psLength);
573         signaturePtr += psLength;
574 
575 
576     #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
577             /* Flush the cache */
578             SCB_InvalidateDCache_by_Addr((volatile void *)(signature),(int32_t)signatureLength);
579     #endif
580         /* After PS string (before T string) Set to 0x00 byte.*/
581         *signaturePtr++ = 0x00;
582 
583     #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
584             /* Flush the cache */
585             SCB_CleanDCache_by_Addr((volatile void *)(signature),(int32_t)signatureLength);
586 
587     #endif
588         if (CY_CRYPTO_MODE_SHA_NONE != digestType)
589         {
590             signatureRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(signaturePtr);
591             Cy_Crypto_Core_MemCpy(base, signatureRemap, encodingArrRemap, (uint16_t)encodingArrSize);
592             signaturePtr += encodingArrSize;
593         }
594 
595         signatureRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(signaturePtr);
596         Cy_Crypto_Core_MemCpy(base, (void *)signatureRemap, (void const *)digestRemap, (uint16_t)locDigestSize);
597 
598     #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
599             /* Flush the cache */
600             SCB_InvalidateDCache_by_Addr((volatile void *)(signature),(int32_t)signatureLength);
601     #endif
602     }
603 
604     return (tmpResult);
605 }
606 
607 #endif
608 
609 
610 /*******************************************************************************
611 * Function Name: Cy_Crypto_Core_Rsa_MontCoeff
612 ****************************************************************************//**
613 *
614 * Calculation of Montgomery coefficients for Montgomery multiplication in GF(p).
615 *
616 * Reference: "Montgomery Multiplication", H. S. Warren, Jr., July 2012
617 * Reference: http://www.hackersdelight.org/MontgomeryMultiplication.pdf
618 *
619 * GCD method is used, reference:
620 * https://en.wikipedia.org/wiki/Binary_GCD_algorithm
621 *
622 * Inputs: modulus n, k = number of bits in n;
623 * Outputs: R^-1 and n' which allows equation: R*R^-1 - n*n' = 1,
624 * where R = 1 << size.
625 *
626 * \param base
627 * The pointer to the CRYPTO instance.
628 *
629 * \param modDerReg
630 * Register index for Montgomery coefficient value.
631 *
632 * \param modReg
633 * Register index for modulo value.
634 *
635 * \param size
636 * Modulo size in bits.
637 *
638 * \return
639 * \ref cy_en_crypto_status_t
640 *******************************************************************************/
Cy_Crypto_Core_Rsa_MontCoeff(CRYPTO_Type * base,uint32_t modDerReg,uint32_t modReg,uint32_t size)641 static cy_en_crypto_status_t Cy_Crypto_Core_Rsa_MontCoeff(CRYPTO_Type *base, uint32_t modDerReg, uint32_t modReg, uint32_t size)
642 {
643     uint32_t myMod  = 9u;
644     uint32_t tmp    = 10u;
645     uint32_t ra      = 11u;
646     uint32_t rb      = 12u;
647     uint32_t ru      = 13u;
648     uint32_t rv      = 14u;
649     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
650 
651     uint32_t status;
652     uint32_t aZero;
653     uint32_t uEven;
654 
655     CY_CRYPTO_VU_PUSH_REG    (base);
656 
657     CY_CRYPTO_VU_LD_REG      (base, rv,     modDerReg);
658     CY_CRYPTO_VU_LD_REG      (base, myMod, modReg);
659 
660     tmpResult = CY_CRYPTO_VU_ALLOC_MEM   (base, ra, size);
661     if(CY_CRYPTO_SUCCESS != tmpResult)
662     {
663         return tmpResult;
664     }
665 
666     tmpResult = CY_CRYPTO_VU_ALLOC_MEM   (base, rb, size);
667     if(CY_CRYPTO_SUCCESS != tmpResult)
668     {
669         return tmpResult;
670     }
671 
672     tmpResult = CY_CRYPTO_VU_ALLOC_MEM   (base, ru, size);
673     if(CY_CRYPTO_SUCCESS != tmpResult)
674     {
675         return tmpResult;
676     }
677 
678     CY_CRYPTO_VU_SET_TO_ONE  (base, ru);
679     CY_CRYPTO_VU_SET_TO_ZERO (base, rv);
680 
681     CY_CRYPTO_VU_SET_TO_ZERO (base, ra);
682     CY_CRYPTO_VU_SET_REG     (base, tmp, (size - 1u), 1u);
683 
684     CY_CRYPTO_VU_SET_BIT     (base, ra, tmp);
685     CY_CRYPTO_VU_MOV         (base, rb, myMod);
686 
687     while (true)
688     {
689         Cy_Crypto_Core_Vu_WaitForComplete(base);
690 
691         CY_CRYPTO_VU_TST(base, ra);
692 
693         status = Cy_Crypto_Core_Vu_StatusRead(base);
694         aZero = status &  CY_CRYPTO_VU_STATUS_ZERO_BIT;
695 
696         if (aZero != 0u)
697         {
698             break;
699         }
700 
701         CY_CRYPTO_VU_LSR1(base, ra, ra);
702 
703         CY_CRYPTO_VU_TST(base, ru);
704         status = Cy_Crypto_Core_Vu_StatusRead(base);
705         uEven = status & CY_CRYPTO_VU_STATUS_EVEN_BIT;
706 
707         if (uEven != 0u)
708         {
709             CY_CRYPTO_VU_LSR1(base, ru, ru);
710             CY_CRYPTO_VU_LSR1(base, rv, rv);
711         }
712         else
713         {
714             CY_CRYPTO_VU_ADD(base, ru, ru, rb);
715             CY_CRYPTO_VU_LSR1_WITH_CARRY(base, ru, ru);
716             CY_CRYPTO_VU_LSR1(base, rv, rv);
717             CY_CRYPTO_VU_SET_BIT(base, rv, tmp);
718         }
719     }
720 
721     CY_CRYPTO_VU_FREE_MEM(base, CY_CRYPTO_VU_REG_BIT(ra) | CY_CRYPTO_VU_REG_BIT(rb) | CY_CRYPTO_VU_REG_BIT(ru));
722 
723     CY_CRYPTO_VU_POP_REG(base);
724 
725     return CY_CRYPTO_SUCCESS;
726 }
727 
728 /*******************************************************************************
729 * Function Name: Cy_Crypto_Core_Rsa_BarrettGetU
730 ****************************************************************************//**
731 *
732 * Calculation of Barrett coefficient for Barrett reduction in GF(p).
733 *
734 * The function reduces the size of the Barrett coefficient by removing leading '0' bits.
735 * This improves the performance of the Barrett reduction (faster multiplication).
736 * (1 << bit_size) > mod > (1 << (bit_size-1))
737 *
738 * barrett = (1 << (2 * size)) / mod      NO!!! leading '1' Barrett bit.
739 *
740 * \param base
741 * The pointer to the CRYPTO instance.
742 *
743 * \param barrettUReg
744 * Register index for Barrett reduction value.
745 *
746 * \param modReg
747 * Register index for modulo value.
748 *
749 * \param size
750 * The modulo size in bits.
751 *
752 * \return
753 * \ref cy_en_crypto_status_t
754 *******************************************************************************/
Cy_Crypto_Core_Rsa_BarrettGetU(CRYPTO_Type * base,uint32_t barrettUReg,uint32_t modReg,uint32_t size)755 static cy_en_crypto_status_t Cy_Crypto_Core_Rsa_BarrettGetU(CRYPTO_Type *base, uint32_t barrettUReg, uint32_t modReg, uint32_t size)
756 {
757     uint32_t dividend = 0u;
758     uint32_t t        = 1u;
759     uint32_t temp     = 2u;
760     uint32_t sh       = 3u;
761     int32_t i;
762     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
763 
764     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, dividend, size + 1u);
765     if(CY_CRYPTO_SUCCESS != tmpResult)
766     {
767         return tmpResult;
768     }
769 
770     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t,        size + 1u);
771     if(CY_CRYPTO_SUCCESS != tmpResult)
772     {
773         return tmpResult;
774     }
775 
776     tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, temp,     size + 1u);
777     if(CY_CRYPTO_SUCCESS != tmpResult)
778     {
779         return tmpResult;
780     }
781 
782     /* (1 << size) - there is probably a more efficient way to initialize this */
783     CY_CRYPTO_VU_SET_REG     (base, sh, size, 1u);
784     CY_CRYPTO_VU_SET_TO_ZERO (base, dividend);
785     CY_CRYPTO_VU_SET_BIT     (base, dividend, sh);
786 
787     CY_CRYPTO_VU_MOV (base, temp, dividend);
788 
789     CY_CRYPTO_VU_SET_TO_ZERO (base, barrettUReg);
790 
791     for (i = (int32_t)size; i >= 0; i--)
792     {
793         /* C = (a >= b) */
794         CY_CRYPTO_VU_SUB           (base, t, dividend, modReg);
795         CY_CRYPTO_VU_COND_SWAP_REG (base, CY_CRYPTO_VU_COND_CS, dividend, t);
796         CY_CRYPTO_VU_COND_XOR      (base, CY_CRYPTO_VU_COND_CS, barrettUReg, barrettUReg, temp);
797         CY_CRYPTO_VU_LSL1          (base, dividend, dividend);
798         CY_CRYPTO_VU_LSR1          (base, temp, temp);
799     }
800 
801     CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(dividend) | CY_CRYPTO_VU_REG_BIT(temp) | CY_CRYPTO_VU_REG_BIT(t));
802 
803     return CY_CRYPTO_SUCCESS;
804 }
805 
806 /*******************************************************************************
807 * Function Name: Cy_Crypto_Core_Rsa_MontTransform
808 ****************************************************************************//**
809 *
810 * \brief Conversion to Montgomery representation.
811 *
812 * z = (a << size) % mod
813 *
814 * \param base
815 * The pointer to the CRYPTO instance.
816 *
817 * \param z
818 * Register index for Montgomery representation value.
819 *
820 * \param a
821 * Register index for regular representation value.
822 *
823 * \param barrett
824 * Register index for Barrett reduction value.
825 *
826 * \param mod
827 * Register index for modulo value.
828 *
829 * \param size
830 * Bit size.
831 *
832 * \return
833 * \ref cy_en_crypto_status_t
834 *******************************************************************************/
Cy_Crypto_Core_Rsa_MontTransform(CRYPTO_Type * base,uint32_t z,uint32_t a,uint32_t barrett,uint32_t mod,uint32_t size)835 static cy_en_crypto_status_t Cy_Crypto_Core_Rsa_MontTransform(CRYPTO_Type *base, uint32_t z, uint32_t a, uint32_t barrett, uint32_t mod, uint32_t size)
836 {
837     uint32_t sh      = 0u;
838     uint32_t t1Plus2 = 1u;
839     uint32_t t2Plus2 = 0u;
840     uint32_t tDouble = 2u;
841     uint32_t aDouble = 3u;
842     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
843 
844     tmpResult = CY_CRYPTO_VU_ALLOC_MEM      (base, tDouble, 2u * size);
845     if(CY_CRYPTO_SUCCESS != tmpResult)
846     {
847         return tmpResult;
848     }
849 
850     tmpResult = CY_CRYPTO_VU_ALLOC_MEM      (base, aDouble, 2u * size);
851     if(CY_CRYPTO_SUCCESS != tmpResult)
852     {
853         return tmpResult;
854     }
855 
856     CY_CRYPTO_VU_SET_REG        (base, sh, size, 1u);
857 
858     CY_CRYPTO_VU_UMUL           (base, tDouble, a, barrett);
859     CY_CRYPTO_VU_LSR            (base, aDouble, tDouble, sh);
860 
861     CY_CRYPTO_VU_UMUL           (base, tDouble, aDouble, mod);
862 
863     CY_CRYPTO_VU_LSL            (base, aDouble, a, sh);
864 
865     tmpResult = CY_CRYPTO_VU_ALLOC_MEM      (base, t2Plus2, size + 2u);
866     if(CY_CRYPTO_SUCCESS != tmpResult)
867     {
868         return tmpResult;
869     }
870 
871     CY_CRYPTO_VU_SUB            (base, t2Plus2, aDouble, tDouble);
872 
873     CY_CRYPTO_VU_FREE_MEM       (base, CY_CRYPTO_VU_REG_BIT(aDouble) | CY_CRYPTO_VU_REG_BIT(tDouble));
874 
875     tmpResult = CY_CRYPTO_VU_ALLOC_MEM      (base, t1Plus2, size + 2u);
876     if(CY_CRYPTO_SUCCESS != tmpResult)
877     {
878         return tmpResult;
879     }
880 
881     /* Check CARRY = (a >= b) */
882     CY_CRYPTO_VU_SUB            (base, t1Plus2, t2Plus2, mod);
883     CY_CRYPTO_VU_COND_SWAP_REG  (base, CY_CRYPTO_VU_COND_CC, t1Plus2, t2Plus2);
884 
885     /* Check CARRY = (a >= b) */
886     CY_CRYPTO_VU_SUB            (base, t2Plus2, t1Plus2, mod);
887     CY_CRYPTO_VU_COND_MOV       (base, CY_CRYPTO_VU_COND_CC, z, t1Plus2);
888     CY_CRYPTO_VU_COND_MOV       (base, CY_CRYPTO_VU_COND_CS, z, t2Plus2);
889 
890     CY_CRYPTO_VU_FREE_MEM       (base, CY_CRYPTO_VU_REG_BIT(t2Plus2) | CY_CRYPTO_VU_REG_BIT(t1Plus2));
891 
892     return CY_CRYPTO_SUCCESS;
893 }
894 
895 /*******************************************************************************
896 * Function Name: Cy_Crypto_Core_Rsa_MontMul
897 ****************************************************************************//**
898 *
899 * Montgomery multiplication in GF(p).
900 *
901 * z = a * b * r % mod
902 *
903 * t = mont_a * mont_b
904 * u = t * montModDer    "only lower 32 bits are needed"
905 * u = u * mod
906 * u = u + t
907 * u = u >> size
908 * u = IF (u >= mod) u = u - mod
909 *
910 * \param base
911 * The pointer to the CRYPTO instance.
912 *
913 * \param z
914 * Register index for product value.
915 *
916 * \param a
917 * Register index for multiplicand value.
918 *
919 * \param b
920 * Register index for multiplier value.
921 *
922 * \param montModDer
923 * Register index for Montgomery coefficient value.
924 *
925 * \param mod
926 * Register index for modulo value.
927 *
928 * \param size
929 * Bit size.
930 *
931 * \return
932 * \ref cy_en_crypto_status_t
933 *******************************************************************************/
Cy_Crypto_Core_Rsa_MontMul(CRYPTO_Type * base,uint32_t z,uint32_t a,uint32_t b,uint32_t montModDer,uint32_t mod,uint32_t size)934 static cy_en_crypto_status_t Cy_Crypto_Core_Rsa_MontMul(CRYPTO_Type *base,
935                                 uint32_t z, uint32_t a, uint32_t b,
936                                 uint32_t montModDer, uint32_t mod, uint32_t size)
937 {
938     uint32_t sh       = 0u;
939     uint32_t t        = 1u;
940     uint32_t uDouble = 2u;
941     uint32_t tDouble = 3u;
942     uint32_t status = 4u;
943     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
944 
945     tmpResult = CY_CRYPTO_VU_ALLOC_MEM  (base, t,       size + 1u);
946     if(CY_CRYPTO_SUCCESS != tmpResult)
947     {
948         return tmpResult;
949     }
950     tmpResult = CY_CRYPTO_VU_ALLOC_MEM  (base, uDouble, 2u * size);
951     if(CY_CRYPTO_SUCCESS != tmpResult)
952     {
953         return tmpResult;
954     }
955     tmpResult = CY_CRYPTO_VU_ALLOC_MEM  (base, tDouble, 2u * size);
956     if(CY_CRYPTO_SUCCESS != tmpResult)
957     {
958         return tmpResult;
959     }
960 
961     CY_CRYPTO_VU_SET_REG    (base, sh, size, 1u);
962 
963     CY_CRYPTO_VU_UMUL       (base, tDouble, a, b);
964 
965     /* Only the lower 32 bits are needed. */
966     CY_CRYPTO_VU_UMUL       (base, t, tDouble, montModDer);
967 
968     /* Clear the MSB bit (cut to size length) */
969     CY_CRYPTO_VU_LSL1(base, t, t);
970     CY_CRYPTO_VU_LSR1(base, t, t);
971 
972     CY_CRYPTO_VU_UMUL       (base, uDouble, t, mod);
973 
974     CY_CRYPTO_VU_ADD        (base, uDouble, uDouble, tDouble);
975 
976     CY_CRYPTO_VU_MOV_STATUS_TO_REG (base, status);
977 
978     CY_CRYPTO_VU_LSR          (base, uDouble, uDouble, sh);
979 
980     CY_CRYPTO_VU_SET_TO_ZERO  (base, t);
981     CY_CRYPTO_VU_SET_REG      (base, sh, 0u,    1u);
982     CY_CRYPTO_VU_SET_BIT      (base, t,  sh);
983     CY_CRYPTO_VU_SET_REG      (base, sh, size, 1u);
984     CY_CRYPTO_VU_LSL          (base, t,  t,    sh);
985 
986     CY_CRYPTO_VU_MOV_REG_TO_STATUS (base, status);
987     Cy_Crypto_Core_Vu_WaitForComplete(base);
988 
989     CY_CRYPTO_VU_XOR (base, tDouble, uDouble, t);
990     CY_CRYPTO_VU_COND_SWAP_REG (base, CY_CRYPTO_VU_COND_CS, uDouble, tDouble);
991 
992     /* C = (a >= b) */
993     CY_CRYPTO_VU_SUB (base, tDouble, uDouble, mod);
994     CY_CRYPTO_VU_COND_SWAP_REG (base, CY_CRYPTO_VU_COND_CS, uDouble, tDouble);
995 
996     CY_CRYPTO_VU_MOV (base, z, uDouble);
997 
998     CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(tDouble) | CY_CRYPTO_VU_REG_BIT(uDouble) | CY_CRYPTO_VU_REG_BIT(t));
999 
1000     return CY_CRYPTO_SUCCESS;
1001 }
1002 
1003 /*******************************************************************************
1004 * Function Name: Cy_Crypto_Core_Rsa_expModByMont
1005 ****************************************************************************//**
1006 *
1007 * Perform y = x^e mod n using Montgomery reduction technique to speed-up
1008 * calculation. Suitable for cases with short e.
1009 *
1010 * \param base
1011 * The pointer to the CRYPTO instance.
1012 *
1013 * \param y
1014 * Register index for calculated value.
1015 *
1016 * \param x
1017 * Register index for multiplicand value.
1018 *
1019 * \param e
1020 * Register index for exponent value.
1021 *
1022 * \param n
1023 * Register index for modulo value.
1024 *
1025 * \param barretCoef
1026 * Barrett coefficient.
1027 *
1028 * \param inverseModulo
1029 * Binary inverse of the modulo.
1030 *
1031 * \param rBar
1032 * Values of (2^moduloLength mod modulo).
1033 *
1034 * \param size
1035 * The modulo size in bits.
1036 *
1037 * \return status code. See \ref cy_en_crypto_status_t.
1038 *******************************************************************************/
Cy_Crypto_Core_Rsa_expModByMont(CRYPTO_Type * base,uint32_t y,uint32_t x,uint32_t e,uint32_t n,uint32_t barretCoef,uint32_t inverseModulo,uint32_t rBar,uint32_t size)1039 static cy_en_crypto_status_t Cy_Crypto_Core_Rsa_expModByMont(CRYPTO_Type *base,
1040                                      uint32_t y,
1041                                      uint32_t x,
1042                                      uint32_t e,
1043                                      uint32_t n,
1044                                      uint32_t barretCoef,
1045                                      uint32_t inverseModulo,
1046                                      uint32_t rBar,
1047                                      uint32_t size)
1048 {
1049     int32_t  i;
1050     uint32_t j;
1051     uint32_t status;
1052     uint32_t carry;
1053     uint32_t clsame;
1054 
1055     uint32_t myY      = 5u;
1056     uint32_t myX      = 6u;
1057     uint32_t myE      = 7u;
1058     uint32_t myN      = 8u;
1059     uint32_t myReg0   = 9u;
1060     uint32_t nPrime   = 10u;
1061     uint32_t temp     = 11u;
1062     uint32_t barrett  = 12u;
1063     uint32_t xBar     = 13u;
1064     uint32_t REG      = 14u;
1065     cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1066 
1067     CY_CRYPTO_VU_PUSH_REG(base);
1068 
1069     CY_CRYPTO_VU_LD_REG(base, myX, x);
1070     CY_CRYPTO_VU_LD_REG(base, myY, y);
1071     CY_CRYPTO_VU_LD_REG(base, myE, e);
1072     CY_CRYPTO_VU_LD_REG(base, myN, n);
1073     CY_CRYPTO_VU_LD_REG(base, nPrime,  inverseModulo);
1074     CY_CRYPTO_VU_LD_REG(base, barrett, barretCoef);
1075 
1076     CY_CRYPTO_VU_MOV(base, myY, rBar);
1077 
1078     tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, myReg0,    size);
1079     if(CY_CRYPTO_SUCCESS != tmpResult)
1080     {
1081         return tmpResult;
1082     }
1083 
1084     tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, xBar,      size);
1085     if(CY_CRYPTO_SUCCESS != tmpResult)
1086     {
1087         return tmpResult;
1088     }
1089 
1090     tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, temp,      size);
1091     if(CY_CRYPTO_SUCCESS != tmpResult)
1092     {
1093         return tmpResult;
1094     }
1095 
1096     tmpResult = Cy_Crypto_Core_Rsa_MontTransform(base, xBar, myX, barrett, myN, size);
1097     if(CY_CRYPTO_SUCCESS != tmpResult)
1098     {
1099         return tmpResult;
1100     }
1101     CY_CRYPTO_VU_MOV(base, temp, myE);
1102     CY_CRYPTO_VU_SET_TO_ZERO(base, myReg0);
1103 
1104     CY_CRYPTO_VU_CLSAME(base, REG, temp, myReg0);
1105 
1106     /* This is needed, otherwise clsame is wrong */
1107     Cy_Crypto_Core_Vu_WaitForComplete(base);
1108 
1109     clsame = Cy_Crypto_Core_Vu_RegDataPtrRead(base, REG);
1110 
1111     j = ((uint32_t)Cy_Crypto_Core_Vu_RegSizeRead(base, temp) + 1u) - clsame;
1112 
1113     CY_CRYPTO_VU_SET_REG(base, REG, clsame, 1u);
1114     CY_CRYPTO_VU_LSL(base, temp, temp, REG);
1115 
1116     for (i = (int32_t)j; i > 0; i--)
1117     {
1118         /* j is number of bits in exponent e */
1119         CY_CRYPTO_VU_LSL1(base, temp, temp);
1120         status = Cy_Crypto_Core_Vu_StatusRead(base);
1121         carry = status & CY_CRYPTO_VU_STATUS_CARRY_BIT;
1122 
1123         if (carry != 0u)
1124         {
1125             /* myY = myY * xBar */
1126             tmpResult = Cy_Crypto_Core_Rsa_MontMul(base, myY, myY, xBar, nPrime, myN, size);
1127             if(CY_CRYPTO_SUCCESS != tmpResult)
1128             {
1129                 return tmpResult;
1130             }
1131             Cy_Crypto_Core_Vu_WaitForComplete(base);
1132 
1133             /* xBar = xBar ^ 2 */
1134             tmpResult = Cy_Crypto_Core_Rsa_MontMul(base, xBar, xBar, xBar, nPrime, myN, size);
1135             if(CY_CRYPTO_SUCCESS != tmpResult)
1136             {
1137                 return tmpResult;
1138             }
1139             Cy_Crypto_Core_Vu_WaitForComplete(base);
1140         }
1141         else
1142         {
1143             /* xBar = myY * xBar */
1144             tmpResult = Cy_Crypto_Core_Rsa_MontMul(base, xBar, myY, xBar, nPrime, myN, size);
1145             if(CY_CRYPTO_SUCCESS != tmpResult)
1146             {
1147                 return tmpResult;
1148             }
1149             Cy_Crypto_Core_Vu_WaitForComplete(base);
1150 
1151             /* myY = myY ^ 2 */
1152             tmpResult = Cy_Crypto_Core_Rsa_MontMul(base, myY, myY, myY, nPrime, myN, size);
1153             if(CY_CRYPTO_SUCCESS != tmpResult)
1154             {
1155                 return tmpResult;
1156             }
1157 
1158             Cy_Crypto_Core_Vu_WaitForComplete(base);
1159         }
1160     }
1161 
1162     CY_CRYPTO_VU_SET_TO_ONE(base, myReg0);
1163 
1164     tmpResult = Cy_Crypto_Core_Rsa_MontMul(base, myY, myY, myReg0, nPrime , myN, size);
1165 
1166     if(CY_CRYPTO_SUCCESS != tmpResult)
1167     {
1168         return tmpResult;
1169     }
1170 
1171     CY_CRYPTO_VU_FREE_MEM(base, CY_CRYPTO_VU_REG_BIT(myReg0) | CY_CRYPTO_VU_REG_BIT(xBar) | CY_CRYPTO_VU_REG_BIT(temp));
1172     CY_CRYPTO_VU_POP_REG(base);
1173 
1174     Cy_Crypto_Core_Vu_WaitForComplete(base);
1175 
1176     return CY_CRYPTO_SUCCESS;
1177 }
1178 
1179 /**
1180 * \addtogroup group_crypto_lld_asymmetric_functions
1181 * \{
1182 */
1183 
1184 /*******************************************************************************
1185 * Function Name: Cy_Crypto_Core_Rsa_Proc
1186 ****************************************************************************//**
1187 *
1188 * RSA process algorithm based on the Montgomery algorithm
1189 * using Barrett reduction
1190 *
1191 * For CAT1C & CAT1D devices when D-Cache is enabled parameters message, processedMessage and
1192 * key(pubExpPtr, moduloPtr, barretCoefPtr, inverseModuloPtr and  rBarPtr) must align and end in 32 byte boundary.
1193 *
1194 * https://en.wikipedia.org/wiki/RSA_%28cryptosystem%29
1195 *
1196 * \param base
1197 * The pointer to the CRYPTO instance.
1198 *
1199 * \param key
1200 * The pointer to the \ref cy_stc_crypto_rsa_pub_key_t structure that stores
1201 * public key.
1202 *
1203 * \param message
1204 * The pointer to the message to be processed.
1205 *
1206 * \param messageSize
1207 * The length of the message to be processed.
1208 *
1209 * \param processedMessage
1210 * The pointer to processed message.
1211 *
1212 * \return
1213 * \ref cy_en_crypto_status_t
1214 *
1215 * \funcusage
1216 * \snippet crypto/snippet/main.c snippet_myCryptoCoreRsaVerUse
1217 *
1218 *******************************************************************************/
Cy_Crypto_Core_Rsa_Proc(CRYPTO_Type * base,cy_stc_crypto_rsa_pub_key_t const * key,uint8_t const * message,uint32_t messageSize,uint8_t * processedMessage)1219 cy_en_crypto_status_t Cy_Crypto_Core_Rsa_Proc(CRYPTO_Type *base,
1220                                               cy_stc_crypto_rsa_pub_key_t const *key,
1221                                               uint8_t const *message,
1222                                               uint32_t messageSize,
1223                                               uint8_t *processedMessage)
1224 {
1225     cy_en_crypto_status_t tmpResult = CY_CRYPTO_SUCCESS;
1226 
1227     uint8_t* messageRemap;
1228     uint8_t* processedMessageRemap;
1229 
1230     messageRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(message);
1231     processedMessageRemap = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(processedMessage);
1232 
1233     uint8_t *expPtrRemap         = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(key->pubExpPtr);
1234     uint32_t expBitLength        = key->pubExpLength;
1235     uint8_t *nPtrRemap           = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(key->moduloPtr);
1236     uint32_t nBitLength          = key->moduloLength;
1237     uint8_t *barretCoefRemap     = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(key->barretCoefPtr);
1238     uint8_t *inverseModuloRemap  = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(key->inverseModuloPtr);
1239     uint8_t *rBarRemap           = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(key->rBarPtr);
1240 
1241     uint32_t yReg                = 5u;
1242     uint32_t xReg                = 6u;
1243     uint32_t eReg                = 7u;
1244     uint32_t modReg              = 8u;
1245     uint32_t inverseModuloReg    = 9u;
1246     uint32_t barrettReg          = 10u;
1247     uint32_t rBarReg             = 11u;
1248     uint16_t vu_mem_size         = 0U;
1249     void *vu_mem_address         = NULL;
1250 
1251 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
1252 
1253     /* Flush the cache */
1254     SCB_CleanDCache_by_Addr((volatile void *)key->pubExpPtr,(int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(expBitLength));
1255     SCB_CleanDCache_by_Addr((volatile void *)key->moduloPtr,(int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(nBitLength));
1256     SCB_CleanDCache_by_Addr((volatile void *)message,(int32_t)messageSize);
1257 #endif
1258 
1259     vu_mem_address = Cy_Crypto_Core_GetVuMemoryAddress(base);
1260     vu_mem_size = (uint16_t)Cy_Crypto_Core_GetVuMemorySize(base);
1261 
1262     /* Clear all Crypto Buffer before operations */
1263     Cy_Crypto_Core_MemSet(base, (void*)vu_mem_address, 0x00u, vu_mem_size);
1264 
1265     tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, yReg,             nBitLength);
1266     if(CY_CRYPTO_SUCCESS != tmpResult)
1267     {
1268         return tmpResult;
1269     }
1270 
1271     tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, xReg,             nBitLength);
1272     if(CY_CRYPTO_SUCCESS != tmpResult)
1273     {
1274         return tmpResult;
1275     }
1276 
1277     tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, eReg,             nBitLength);
1278     if(CY_CRYPTO_SUCCESS != tmpResult)
1279     {
1280         return tmpResult;
1281     }
1282 
1283     tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, modReg,           nBitLength);
1284     if(CY_CRYPTO_SUCCESS != tmpResult)
1285     {
1286         return tmpResult;
1287     }
1288 
1289     tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, barrettReg,       nBitLength + (uint32_t)1u);
1290     if(CY_CRYPTO_SUCCESS != tmpResult)
1291     {
1292         return tmpResult;
1293     }
1294 
1295     tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, rBarReg,          nBitLength);
1296     if(CY_CRYPTO_SUCCESS != tmpResult)
1297     {
1298         return tmpResult;
1299     }
1300 
1301     tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, inverseModuloReg, nBitLength);
1302     if(CY_CRYPTO_SUCCESS != tmpResult)
1303     {
1304         return tmpResult;
1305     }
1306 
1307     Cy_Crypto_Core_Vu_SetMemValue(base, modReg, nPtrRemap,   nBitLength);
1308     Cy_Crypto_Core_Vu_SetMemValue(base, eReg,   expPtrRemap, expBitLength);
1309     Cy_Crypto_Core_Vu_SetMemValue(base, xReg,   (uint8_t const *)messageRemap, messageSize * (uint32_t)8u);
1310 
1311     /* Check coefficients */
1312     if (barretCoefRemap == NULL)
1313     {
1314 
1315         tmpResult = Cy_Crypto_Core_Rsa_BarrettGetU(base, barrettReg, modReg, nBitLength);
1316         if(CY_CRYPTO_SUCCESS != tmpResult)
1317         {
1318             return tmpResult;
1319         }
1320         Cy_Crypto_Core_Vu_WaitForComplete(base);
1321     }
1322     else
1323     {
1324 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
1325 
1326         /* Flush the cache */
1327         CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to int32_t.');
1328         SCB_CleanDCache_by_Addr((volatile void *)key->barretCoefPtr,(int32_t)(CY_CRYPTO_BYTE_SIZE_OF_BITS(nBitLength) + (uint32_t)1u));
1329 #endif
1330         Cy_Crypto_Core_Vu_SetMemValue(base, barrettReg, barretCoefRemap, nBitLength + (uint32_t)1u);
1331     }
1332 
1333     if (rBarRemap == NULL)
1334     {
1335         /* inverseModuloReg used here as temp variable */
1336         CY_CRYPTO_VU_SET_TO_ONE(base, inverseModuloReg);
1337         tmpResult = Cy_Crypto_Core_Rsa_MontTransform(base, rBarReg, inverseModuloReg, barrettReg, modReg, nBitLength);
1338 
1339         if(CY_CRYPTO_SUCCESS != tmpResult)
1340         {
1341             return tmpResult;
1342         }
1343 
1344         Cy_Crypto_Core_Vu_WaitForComplete(base);
1345     }
1346     else
1347     {
1348 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
1349 
1350         /* Flush the cache */
1351         SCB_CleanDCache_by_Addr((volatile void *)key->rBarPtr,(int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(nBitLength));
1352 #endif
1353         Cy_Crypto_Core_Vu_SetMemValue(base, rBarReg, rBarRemap, nBitLength);
1354     }
1355 
1356     if (inverseModuloRemap == NULL)
1357     {
1358         tmpResult = Cy_Crypto_Core_Rsa_MontCoeff(base, inverseModuloReg, modReg, nBitLength);
1359         if(CY_CRYPTO_SUCCESS != tmpResult)
1360         {
1361             return tmpResult;
1362         }
1363         Cy_Crypto_Core_Vu_WaitForComplete(base);
1364     }
1365     else
1366     {
1367 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
1368 
1369         /* Flush the cache */
1370         SCB_CleanDCache_by_Addr((volatile void *)key->inverseModuloPtr,(int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(nBitLength));
1371 #endif
1372         Cy_Crypto_Core_Vu_SetMemValue(base, inverseModuloReg, inverseModuloRemap, nBitLength);
1373     }
1374 
1375     tmpResult = Cy_Crypto_Core_Rsa_expModByMont(base,
1376                                     yReg,
1377                                     xReg,
1378                                     eReg,
1379                                     modReg,
1380                                     barrettReg,
1381                                     inverseModuloReg,
1382                                     rBarReg,
1383                                     nBitLength);
1384 
1385     if(CY_CRYPTO_SUCCESS != tmpResult)
1386     {
1387         return tmpResult;
1388     }
1389     Cy_Crypto_Core_Vu_WaitForComplete(base);
1390 
1391     /* Copy the tmpResult to output buffer */
1392     Cy_Crypto_Core_Vu_GetMemValue(base, (uint8_t*)processedMessageRemap, yReg, nBitLength);
1393 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
1394 
1395         SCB_InvalidateDCache_by_Addr(processedMessage, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(nBitLength));
1396 #endif
1397 
1398     CY_CRYPTO_VU_FREE_MEM(base, CY_CRYPTO_VU_REG_BIT(yReg) | CY_CRYPTO_VU_REG_BIT(xReg) |
1399                                 CY_CRYPTO_VU_REG_BIT(eReg) | CY_CRYPTO_VU_REG_BIT(modReg) |
1400                                 CY_CRYPTO_VU_REG_BIT(inverseModuloReg) |
1401                                 CY_CRYPTO_VU_REG_BIT(barrettReg) | CY_CRYPTO_VU_REG_BIT(rBarReg));
1402 
1403     Cy_Crypto_Core_Vu_WaitForComplete(base);
1404 
1405     return (tmpResult);
1406 }
1407 
1408 /*******************************************************************************
1409 * Function Name: Cy_Crypto_Core_Rsa_Coef
1410 ****************************************************************************//**
1411 *
1412 * Calculation constant coefficients to to speed-up Montgomery algorithm.
1413 * These coefficients are:
1414 *                         coefficient for Barrett reduction,
1415 *                         binary inverse of the modulo,
1416 *                         result of (2^moduloLength mod modulo)
1417 *
1418 * For CAT1C & CAT1D(CM55) devices when D-Cache is enabled parameters key(moduloPtr, barretCoefPtr, inverseModuloPtr and  rBarPtr) must align and end in 32 byte boundary.
1419 *
1420 * \param base
1421 * The pointer to the CRYPTO instance.
1422 *
1423 * \param key
1424 * The pointer to the \ref cy_stc_crypto_rsa_pub_key_t structure that stores a
1425 * public key.
1426 *
1427 * \return
1428 * \ref cy_en_crypto_status_t
1429 *
1430 *******************************************************************************/
Cy_Crypto_Core_Rsa_Coef(CRYPTO_Type * base,cy_stc_crypto_rsa_pub_key_t const * key)1431 cy_en_crypto_status_t Cy_Crypto_Core_Rsa_Coef(CRYPTO_Type *base,
1432                                               cy_stc_crypto_rsa_pub_key_t const *key)
1433 {
1434     cy_en_crypto_status_t tmpResult = CY_CRYPTO_SUCCESS;
1435 
1436     uint8_t *nPtrRemap               = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(key->moduloPtr);
1437     uint32_t nBitLength              = key->moduloLength;
1438     uint8_t *barretCoefRemap         = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(key->barretCoefPtr);
1439     uint8_t *inverseModuloRemap      = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(key->inverseModuloPtr);
1440     uint8_t *rBarRemap               = (uint8_t *)CY_REMAP_ADDRESS_FOR_CRYPTO(key->rBarPtr);
1441 
1442     uint32_t modReg              = 11u;
1443     uint32_t inverseModuloReg    = 12u;
1444     uint32_t barrettReg          = 13u;
1445     uint32_t rBarReg             = 14u;
1446     uint16_t vu_mem_size         = 0U;
1447     void *vu_mem_address         = NULL;
1448 
1449 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
1450 
1451     /* Flush the cache */
1452     SCB_CleanDCache_by_Addr((volatile void *)key->moduloPtr,(int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(nBitLength));
1453 #endif
1454 
1455     vu_mem_address = Cy_Crypto_Core_GetVuMemoryAddress(base);
1456     vu_mem_size = (uint16_t)Cy_Crypto_Core_GetVuMemorySize(base);
1457 
1458     /* Clear all Crypto Buffer before operations */
1459     Cy_Crypto_Core_MemSet(base, (void*)vu_mem_address, 0x00u, vu_mem_size);
1460 
1461     tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, modReg,           nBitLength);
1462     if(CY_CRYPTO_SUCCESS != tmpResult)
1463     {
1464         return tmpResult;
1465     }
1466 
1467     tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, barrettReg,       nBitLength + 1u);
1468     if(CY_CRYPTO_SUCCESS != tmpResult)
1469     {
1470         return tmpResult;
1471     }
1472 
1473     tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, inverseModuloReg, nBitLength);
1474     if(CY_CRYPTO_SUCCESS != tmpResult)
1475     {
1476         return tmpResult;
1477     }
1478 
1479     tmpResult = CY_CRYPTO_VU_ALLOC_MEM(base, rBarReg,          nBitLength);
1480     if(CY_CRYPTO_SUCCESS != tmpResult)
1481     {
1482         return tmpResult;
1483     }
1484 
1485     /* Copy modulo to Crypto SRAM */
1486     Cy_Crypto_Core_Vu_SetMemValue(base, modReg, nPtrRemap, nBitLength);
1487 
1488     tmpResult = Cy_Crypto_Core_Rsa_BarrettGetU(base, barrettReg, modReg, nBitLength);
1489     if(CY_CRYPTO_SUCCESS != tmpResult)
1490     {
1491         return tmpResult;
1492     }
1493 
1494     Cy_Crypto_Core_Vu_WaitForComplete(base);
1495 
1496     /* Copy calculated Barrett coefficient */
1497     Cy_Crypto_Core_Vu_GetMemValue(base, barretCoefRemap, barrettReg, nBitLength + 1u);
1498 
1499     /* inverseModuloReg used here as temp variable */
1500     CY_CRYPTO_VU_SET_TO_ONE(base, inverseModuloReg);
1501     tmpResult = Cy_Crypto_Core_Rsa_MontTransform(base, rBarReg, inverseModuloReg, barrettReg, modReg, nBitLength);
1502     if(CY_CRYPTO_SUCCESS != tmpResult)
1503     {
1504         return tmpResult;
1505     }
1506     Cy_Crypto_Core_Vu_WaitForComplete(base);
1507 
1508     /* Copy calculated r-bar = (1 << size) mod modulo */
1509     Cy_Crypto_Core_Vu_GetMemValue(base, rBarRemap, rBarReg, nBitLength);
1510 
1511     tmpResult = Cy_Crypto_Core_Rsa_MontCoeff(base, inverseModuloReg, modReg, nBitLength);
1512     if(CY_CRYPTO_SUCCESS != tmpResult)
1513     {
1514         return tmpResult;
1515     }
1516     /* Copy calculated inverse modulo */
1517     Cy_Crypto_Core_Vu_GetMemValue(base, inverseModuloRemap, inverseModuloReg, nBitLength);
1518 
1519     CY_CRYPTO_VU_FREE_MEM(base, CY_CRYPTO_VU_REG_BIT(modReg) | CY_CRYPTO_VU_REG_BIT(inverseModuloReg) | CY_CRYPTO_VU_REG_BIT(barrettReg) | CY_CRYPTO_VU_REG_BIT(rBarReg));
1520 
1521     Cy_Crypto_Core_Vu_WaitForComplete(base);
1522 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
1523 
1524     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to int32_t.');
1525     SCB_InvalidateDCache_by_Addr(key->barretCoefPtr, (int32_t)(CY_CRYPTO_BYTE_SIZE_OF_BITS(nBitLength)+1u));
1526     SCB_InvalidateDCache_by_Addr(key->inverseModuloPtr, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(nBitLength));
1527     SCB_InvalidateDCache_by_Addr(key->rBarPtr, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(nBitLength));
1528 #endif
1529 
1530     return (tmpResult);
1531 }
1532 
1533 /** \} group_crypto_lld_asymmetric_functions */
1534 
1535 #endif /* (CPUSS_CRYPTO_VU == 1) && defined(CY_CRYPTO_CFG_RSA_C) */
1536 
1537 #if defined(__cplusplus)
1538 }
1539 #endif
1540 
1541 #endif /* CY_IP_MXCRYPTO */
1542 
1543 
1544 /* [] END OF FILE */
1545