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