ra4_crypto_pkc.c
Go to the documentation of this file.
1 /**
2  * @file ra4_crypto_pkc.c
3  * @brief RA4 public-key hardware accelerator
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.5.2
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "hw_sce_private.h"
36 #include "hw_sce_ra_private.h"
37 #include "hw_sce_rsa_private.h"
38 #include "hw_sce_ecc_private.h"
39 #include "core/crypto.h"
42 #include "pkc/rsa.h"
43 #include "ecc/ec.h"
44 #include "ecc/ec_misc.h"
45 #include "ecc/ecdsa.h"
46 #include "debug.h"
47 
48 //Check crypto library configuration
49 #if (RA4_CRYPTO_PKC_SUPPORT == ENABLED)
50 
51 //Global variables
52 static Ra4RsaArgs rsaArgs;
53 static Ra4EcArgs ecArgs;
54 
55 #if (MPI_SUPPORT == ENABLED)
56 
57 /**
58  * @brief Modular exponentiation (fast calculation)
59  * @param[out] r Resulting integer R = A ^ E mod P
60  * @param[in] a Pointer to a multiple precision integer
61  * @param[in] e Exponent
62  * @param[in] p Modulus
63  * @return Error code
64  **/
65 
66 error_t mpiExpModFast(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
67 {
68  error_t error;
69  fsp_err_t status;
70  size_t aLen;
71  size_t eLen;
72  size_t pLen;
73 
74  //Get the length of the integer, in bytes
75  aLen = mpiGetByteLength(a);
76  //Get the length of the exponent, in bytes
77  eLen = mpiGetByteLength(e);
78  //Get the length of the modulus, in bytes
79  pLen = mpiGetByteLength(p);
80 
81  //The accelerator supports operand lengths up to 4096 bits
82  if(aLen <= 512 && eLen <= 4 && pLen <= 512)
83  {
84  size_t n;
85  sce_oem_cmd_t command;
86 
87  //Select appropriate scalar length
88  if(aLen <= 128 && pLen <= 128)
89  {
90  command = SCE_OEM_CMD_RSA1024_PUBLIC;
91  n = 128;
92  }
93  else if(aLen <= 256 && pLen <= 256)
94  {
95  command = SCE_OEM_CMD_RSA2048_PUBLIC;
96  n = 256;
97  }
98  else if(aLen <= 384 && pLen <= 384)
99  {
100  command = SCE_OEM_CMD_RSA3072_PUBLIC;
101  n = 384;
102  }
103  else
104  {
105  command = SCE_OEM_CMD_RSA4096_PUBLIC;
106  n = 512;
107  }
108 
109  //Acquire exclusive access to the SCE module
111 
112  //Format message representative
113  mpiWriteRaw(a, (uint8_t *) rsaArgs.m, n);
114 
115  //Format public key
116  mpiWriteRaw(p, (uint8_t *) rsaArgs.key, n);
117  mpiWriteRaw(e, (uint8_t *) rsaArgs.key + n, 4);
118 
119  //Install the plaintext public key and get the wrapped key
120  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
121  command, NULL, NULL, (uint8_t *) rsaArgs.key, rsaArgs.wrappedKey);
122 
123  //Check status code
124  if(status == FSP_SUCCESS)
125  {
126  //Perform RSA encryption
127  if(n == 128)
128  {
129  status = HW_SCE_Rsa1024ModularExponentEncryptSub(rsaArgs.wrappedKey,
130  rsaArgs.m, rsaArgs.c);
131  }
132  else if(n == 256)
133  {
134  status = HW_SCE_Rsa2048ModularExponentEncryptSub(rsaArgs.wrappedKey,
135  rsaArgs.m, rsaArgs.c);
136  }
137  else if(n == 384)
138  {
139  status = HW_SCE_Rsa3072ModularExponentEncryptSub(rsaArgs.wrappedKey,
140  rsaArgs.m, rsaArgs.c);
141  }
142  else if(n == 512)
143  {
144  status = HW_SCE_Rsa4096ModularExponentEncryptSub(rsaArgs.wrappedKey,
145  rsaArgs.m, rsaArgs.c);
146  }
147  else
148  {
149  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
150  }
151  }
152 
153  //Check status code
154  if(status == FSP_SUCCESS)
155  {
156  //Copy the ciphertext representative
157  error = mpiReadRaw(r, (uint8_t *) rsaArgs.c, n);
158  }
159  else
160  {
161  //Report an error
162  error = ERROR_FAILURE;
163  }
164 
165  //Release exclusive access to the SCE module
167  }
168  else
169  {
170  //Perform modular exponentiation (r = a ^ e mod p)
171  error = mpiExpModRegular(r, a, e, p);
172  }
173 
174  //Return status code
175  return error;
176 }
177 
178 
179 /**
180  * @brief Modular exponentiation (regular calculation)
181  * @param[out] r Resulting integer R = A ^ E mod P
182  * @param[in] a Pointer to a multiple precision integer
183  * @param[in] e Exponent
184  * @param[in] p Modulus
185  * @return Error code
186  **/
187 
188 error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
189 {
190  error_t error;
191  fsp_err_t status;
192  size_t aLen;
193  size_t eLen;
194  size_t pLen;
195 
196  //Get the length of the integer, in bytes
197  aLen = mpiGetByteLength(a);
198  //Get the length of the exponent, in bytes
199  eLen = mpiGetByteLength(e);
200  //Get the length of the modulus, in bytes
201  pLen = mpiGetByteLength(p);
202 
203  //The accelerator supports operand lengths up to 2048 bits
204  if(aLen <= 256 && eLen <= 256 && pLen <= 256)
205  {
206  size_t n;
207  sce_oem_cmd_t command;
208 
209  //Select appropriate scalar length
210  if(aLen <= 128 && eLen <= 128 && pLen <= 128)
211  {
212  command = SCE_OEM_CMD_RSA1024_PRIVATE;
213  n = 128;
214  }
215  else
216  {
217  command = SCE_OEM_CMD_RSA2048_PRIVATE;
218  n = 256;
219  }
220 
221  //Acquire exclusive access to the SCE module
223 
224  //Format ciphertext representative
225  mpiWriteRaw(a, (uint8_t *) rsaArgs.c, n);
226 
227  //Format private key
228  mpiWriteRaw(p, (uint8_t *) rsaArgs.key, n);
229  mpiWriteRaw(e, (uint8_t *) rsaArgs.key + n, n);
230 
231  //Install the plaintext private key and get the wrapped key
232  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
233  command, NULL, NULL, (uint8_t *) rsaArgs.key, rsaArgs.wrappedKey);
234 
235  //Check status code
236  if(status == FSP_SUCCESS)
237  {
238  //Perform RSA decryption
239  if(n == 128)
240  {
241  status = HW_SCE_Rsa1024ModularExponentDecryptSub(rsaArgs.wrappedKey,
242  rsaArgs.c, rsaArgs.m);
243  }
244  else if(n == 256)
245  {
246  status = HW_SCE_Rsa2048ModularExponentDecryptSub(rsaArgs.wrappedKey,
247  rsaArgs.c, rsaArgs.m);
248  }
249  else
250  {
251  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
252  }
253  }
254 
255  //Check status code
256  if(status == FSP_SUCCESS)
257  {
258  //Copy the message representative
259  error = mpiReadRaw(r, (uint8_t *) rsaArgs.m, n);
260  }
261  else
262  {
263  //Report an error
264  error = ERROR_FAILURE;
265  }
266 
267  //Release exclusive access to the SCE module
269  }
270  else
271  {
272  //Perform modular exponentiation (r = a ^ e mod p)
273  error = mpiExpMod(r, a, e, p);
274  }
275 
276  //Return status code
277  return error;
278 }
279 
280 #endif
281 #if (RSA_SUPPORT == ENABLED)
282 
283 /**
284  * @brief RSA decryption primitive
285  *
286  * The RSA decryption primitive recovers the message representative from
287  * the ciphertext representative under the control of a private key
288  *
289  * @param[in] key RSA private key
290  * @param[in] c Ciphertext representative
291  * @param[out] m Message representative
292  * @return Error code
293  **/
294 
295 error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
296 {
297  error_t error;
298  size_t nLen;
299  size_t dLen;
300  size_t pLen;
301  size_t qLen;
302  size_t dpLen;
303  size_t dqLen;
304  size_t qinvLen;
305 
306  //Get the length of the private key
307  nLen = mpiGetByteLength(&key->n);
308  dLen = mpiGetByteLength(&key->d);
309  pLen = mpiGetByteLength(&key->p);
310  qLen = mpiGetByteLength(&key->q);
311  dpLen = mpiGetByteLength(&key->dp);
312  dqLen = mpiGetByteLength(&key->dq);
313  qinvLen = mpiGetByteLength(&key->qinv);
314 
315  //Sanity check
316  if(nLen == 0)
318 
319  //The ciphertext representative c shall be between 0 and n - 1
320  if(mpiCompInt(c, 0) < 0 || mpiComp(c, &key->n) >= 0)
321  return ERROR_OUT_OF_RANGE;
322 
323  //Check the length of the private key
324  if(nLen <= 256 && dLen <= 256)
325  {
326  //Let m = c ^ d mod n
327  error = mpiExpModRegular(m, c, &key->d, &key->n);
328  }
329  else if(nLen > 0 && pLen > 0 && qLen > 0 && dpLen > 0 && dqLen > 0 &&
330  qinvLen > 0)
331  {
332  Mpi m1;
333  Mpi m2;
334  Mpi h;
335 
336  //Initialize multiple-precision integers
337  mpiInit(&m1);
338  mpiInit(&m2);
339  mpiInit(&h);
340 
341  //Compute m1 = c ^ dP mod p
342  error = mpiMod(&m1, c, &key->p);
343 
344  if(!error)
345  {
346  error = mpiExpModRegular(&m1, &m1, &key->dp, &key->p);
347  }
348 
349  //Compute m2 = c ^ dQ mod q
350  if(!error)
351  {
352  error = mpiMod(&m2, c, &key->q);
353  }
354 
355  if(!error)
356  {
357  error = mpiExpModRegular(&m2, &m2, &key->dq, &key->q);
358  }
359 
360  //Let h = (m1 - m2) * qInv mod p
361  if(!error)
362  {
363  error = mpiSub(&h, &m1, &m2);
364  }
365 
366  if(!error)
367  {
368  error = mpiMulMod(&h, &h, &key->qinv, &key->p);
369  }
370 
371  //Let m = m2 + q * h
372  if(!error)
373  {
374  error = mpiMul(m, &key->q, &h);
375  }
376 
377  if(!error)
378  {
379  error = mpiAdd(m, m, &m2);
380  }
381 
382  //Free previously allocated memory
383  mpiFree(&m1);
384  mpiFree(&m2);
385  mpiFree(&h);
386  }
387  else if(nLen > 0 && dLen > 0)
388  {
389  //Let m = c ^ d mod n
390  error = mpiExpModRegular(m, c, &key->d, &key->n);
391  }
392  else
393  {
394  //Report an error
395  error = ERROR_INVALID_PARAMETER;
396  }
397 
398  //Return status code
399  return error;
400 }
401 
402 #endif
403 #if (EC_SUPPORT == ENABLED)
404 
405 /**
406  * @brief Scalar multiplication (fast calculation)
407  * @param[in] curve Elliptic curve parameters
408  * @param[out] r Resulting point R = d.S
409  * @param[in] d An integer d such as 0 <= d < p
410  * @param[in] s EC point
411  * @return Error code
412  **/
413 
414 error_t ecMulFast(const EcCurve *curve, EcPoint3 *r, const uint32_t *d,
415  const EcPoint3 *s)
416 {
417  //Compute R = d.S
418  return ecMulRegular(curve, r, d, s);
419 }
420 
421 
422 /**
423  * @brief Scalar multiplication (regular calculation)
424  * @param[in] curve Elliptic curve parameters
425  * @param[out] r Resulting point R = d.S
426  * @param[in] d An integer d such as 0 <= d < q
427  * @param[in] s EC point
428  * @return Error code
429  **/
430 
431 error_t ecMulRegular(const EcCurve *curve, EcPoint3 *r, const uint32_t *d,
432  const EcPoint3 *s)
433 {
434  error_t error;
435  fsp_err_t status;
436  size_t n;
437  uint32_t curveType;
438  uint32_t command;
439  sce_oem_cmd_t oemCommand;
440 
441  //Check elliptic curve parameters
442  if(osStrcmp(curve->name, "secp256k1") == 0)
443  {
444  curveType = SCE_ECC_CURVE_TYPE_KOBLITZ;
445  oemCommand = SCE_OEM_CMD_ECC_SECP256K1_PRIVATE;
446  command = 0;
447  n = 32;
448  }
449  else if(osStrcmp(curve->name, "secp256r1") == 0)
450  {
451  curveType = SCE_ECC_CURVE_TYPE_NIST;
452  oemCommand = SCE_OEM_CMD_ECC_P256_PRIVATE;
453  command = 0;
454  n = 32;
455  }
456  else if(osStrcmp(curve->name, "secp384r1") == 0)
457  {
458  curveType = SCE_ECC_CURVE_TYPE_NIST;
459  oemCommand = SCE_OEM_CMD_ECC_P384_PRIVATE;
460  command = 0;
461  n = 48;
462  }
463  else if(osStrcmp(curve->name, "brainpoolP256r1") == 0)
464  {
465  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
466  oemCommand = SCE_OEM_CMD_ECC_P256R1_PRIVATE;
467  command = 0;
468  n = 32;
469  }
470  else if(osStrcmp(curve->name, "brainpoolP384r1") == 0)
471  {
472  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
473  oemCommand = SCE_OEM_CMD_ECC_P384R1_PRIVATE;
474  command = 0;
475  n = 48;
476  }
477  else
478  {
479  return ERROR_FAILURE;
480  }
481 
482  //Acquire exclusive access to the SCE module
484 
485  //Set scalar value
486  ecScalarExport(d, n / 4, (uint8_t *) ecArgs.d, n,
488 
489  //Set input point
490  ecScalarExport(s->x, n / 4, (uint8_t *) ecArgs.g, n,
492 
493  ecScalarExport(s->y, n / 4, (uint8_t *) ecArgs.g + n, n,
495 
496  //Install the plaintext private key and get the wrapped key
497  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
498  oemCommand, NULL, NULL, (uint8_t *) ecArgs.d, ecArgs.wrappedKey);
499 
500  //Check status code
501  if(status == FSP_SUCCESS)
502  {
503  //Perform scalar multiplication
504  if(curve->fieldSize == 256)
505  {
506  status = HW_SCE_Ecc256ScalarMultiplicationSub(&curveType,
507  &command, ecArgs.wrappedKey, ecArgs.g, ecArgs.q);
508  }
509  else if(curve->fieldSize == 384)
510  {
511  status = HW_SCE_Ecc384ScalarMultiplicationSub(&curveType,
512  ecArgs.wrappedKey, ecArgs.g, ecArgs.q);
513  }
514  else
515  {
516  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
517  }
518  }
519 
520  //Check status code
521  if(status == FSP_SUCCESS)
522  {
523  //Copy the x-coordinate of the result
524  error = ecScalarImport(r->x, EC_MAX_MODULUS_SIZE, (uint8_t *) ecArgs.q,
526 
527  //Check status code
528  if(!error)
529  {
530  //Copy the y-coordinate of the result
532  (uint8_t *) ecArgs.q + n, n, EC_SCALAR_FORMAT_BIG_ENDIAN);
533  }
534 
535  //Check status code
536  if(!error)
537  {
538  //Set the z-coordinate of the result
540  }
541  }
542  else
543  {
544  //Report an error
545  error = ERROR_FAILURE;
546  }
547 
548  //Release exclusive access to the SCE module
550 
551  //Return status code
552  return error;
553 }
554 
555 #endif
556 #if (ECDSA_SUPPORT == ENABLED)
557 
558 /**
559  * @brief ECDSA signature generation
560  * @param[in] prngAlgo PRNG algorithm
561  * @param[in] prngContext Pointer to the PRNG context
562  * @param[in] privateKey Signer's EC private key
563  * @param[in] digest Digest of the message to be signed
564  * @param[in] digestLen Length in octets of the digest
565  * @param[out] signature (R, S) integer pair
566  * @return Error code
567  **/
568 
569 error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext,
570  const EcPrivateKey *privateKey, const uint8_t *digest, size_t digestLen,
571  EcdsaSignature *signature)
572 {
573  error_t error;
574  fsp_err_t status;
575  size_t n;
576  size_t orderLen;
577  uint32_t curveType;
578  uint32_t command;
579  sce_oem_cmd_t oemCommand;
580  const EcCurve *curve;
581 
582  //Check parameters
583  if(privateKey == NULL || digest == NULL || signature == NULL)
585 
586  //Invalid elliptic curve?
587  if(privateKey->curve == NULL)
589 
590  //Get elliptic curve parameters
591  curve = privateKey->curve;
592 
593  //Get the length of the order, in bytes
594  orderLen = (curve->orderSize + 7) / 8;
595 
596  //Check elliptic curve parameters
597  if(osStrcmp(curve->name, "secp256k1") == 0)
598  {
599  curveType = SCE_ECC_CURVE_TYPE_KOBLITZ;
600  oemCommand = SCE_OEM_CMD_ECC_SECP256K1_PRIVATE;
601  command = 0;
602  n = 32;
603  }
604  else if(osStrcmp(curve->name, "secp256r1") == 0)
605  {
606  curveType = SCE_ECC_CURVE_TYPE_NIST;
607  oemCommand = SCE_OEM_CMD_ECC_P256_PRIVATE;
608  command = 0;
609  n = 32;
610  }
611  else if(osStrcmp(curve->name, "secp384r1") == 0)
612  {
613  curveType = SCE_ECC_CURVE_TYPE_NIST;
614  oemCommand = SCE_OEM_CMD_ECC_P384_PRIVATE;
615  command = 0;
616  n = 48;
617  }
618  else if(osStrcmp(curve->name, "brainpoolP256r1") == 0)
619  {
620  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
621  oemCommand = SCE_OEM_CMD_ECC_P256R1_PRIVATE;
622  command = 0;
623  n = 32;
624  }
625  else if(osStrcmp(curve->name, "brainpoolP384r1") == 0)
626  {
627  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
628  oemCommand = SCE_OEM_CMD_ECC_P384R1_PRIVATE;
629  command = 0;
630  n = 48;
631  }
632  else
633  {
634  return ERROR_FAILURE;
635  }
636 
637  //Keep the leftmost bits of the hash value
638  digestLen = MIN(digestLen, orderLen);
639 
640  //Acquire exclusive access to the SCE module
642 
643  //Pad the digest with leading zeroes if necessary
644  osMemset(ecArgs.digest, 0, n);
645  osMemcpy((uint8_t *) ecArgs.digest + n - digestLen, digest, digestLen);
646 
647  //Set private key
648  ecScalarExport(privateKey->d, n / 4, (uint8_t *) ecArgs.d, n,
650 
651  //Install the plaintext private key and get the wrapped key
652  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
653  oemCommand, NULL, NULL, (uint8_t *) ecArgs.d, ecArgs.wrappedKey);
654 
655  //Check status code
656  if(status == FSP_SUCCESS)
657  {
658  //Generate ECDSA signature
659  if(curve->fieldSize == 256)
660  {
661  status = HW_SCE_EcdsaSignatureGenerateSub(&curveType, &command,
662  ecArgs.wrappedKey, ecArgs.digest, ecArgs.signature);
663  }
664  else if(curve->fieldSize == 384)
665  {
666  status = HW_SCE_EcdsaP384SignatureGenerateSub(&curveType,
667  ecArgs.wrappedKey, ecArgs.digest, ecArgs.signature);
668  }
669  else
670  {
671  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
672  }
673  }
674 
675  //Check status code
676  if(status == FSP_SUCCESS)
677  {
678  //Save elliptic curve parameters
679  signature->curve = curve;
680 
681  //Copy integer R
682  error = ecScalarImport(signature->r, EC_MAX_ORDER_SIZE,
683  (uint8_t *) ecArgs.signature, n, EC_SCALAR_FORMAT_BIG_ENDIAN);
684 
685  //Check status code
686  if(!error)
687  {
688  //Copy integer S
689  error = ecScalarImport(signature->s, EC_MAX_ORDER_SIZE,
690  (uint8_t *) ecArgs.signature + n, n, EC_SCALAR_FORMAT_BIG_ENDIAN);
691  }
692  }
693  else
694  {
695  //Report an error
696  error = ERROR_FAILURE;
697  }
698 
699  //Release exclusive access to the SCE module
701 
702  //Return status code
703  return error;
704 }
705 
706 
707 /**
708  * @brief ECDSA signature verification
709  * @param[in] publicKey Signer's EC public key
710  * @param[in] digest Digest of the message whose signature is to be verified
711  * @param[in] digestLen Length in octets of the digest
712  * @param[in] signature (R, S) integer pair
713  * @return Error code
714  **/
715 
717  const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
718 {
719  fsp_err_t status;
720  size_t n;
721  size_t orderLen;
722  uint32_t curveType;
723  uint32_t command;
724  sce_oem_cmd_t oemCommand;
725  const EcCurve *curve;
726 
727  //Check parameters
728  if(publicKey == NULL || digest == NULL || signature == NULL)
730 
731  //Invalid elliptic curve?
732  if(publicKey->curve == NULL)
734 
735  //Verify that the public key is on the curve
736  if(!ecIsPointAffine(publicKey->curve, &publicKey->q))
737  {
739  }
740 
741  //The verifier shall check that 0 < r < q
742  if(ecScalarCompInt(signature->r, 0, EC_MAX_ORDER_SIZE) <= 0 ||
743  ecScalarComp(signature->r, publicKey->curve->q, EC_MAX_ORDER_SIZE) >= 0)
744  {
745  //If the condition is violated, the signature shall be rejected as invalid
747  }
748 
749  //The verifier shall check that 0 < s < q
750  if(ecScalarCompInt(signature->s, 0, EC_MAX_ORDER_SIZE) <= 0 ||
751  ecScalarComp(signature->s, publicKey->curve->q, EC_MAX_ORDER_SIZE) >= 0)
752  {
753  //If the condition is violated, the signature shall be rejected as invalid
755  }
756 
757  //Get elliptic curve parameters
758  curve = publicKey->curve;
759 
760  //Get the length of the order, in bytes
761  orderLen = (curve->orderSize + 7) / 8;
762 
763  //Check elliptic curve parameters
764  if(osStrcmp(curve->name, "secp256k1") == 0)
765  {
766  curveType = SCE_ECC_CURVE_TYPE_KOBLITZ;
767  oemCommand = SCE_OEM_CMD_ECC_SECP256K1_PUBLIC;
768  command = 0;
769  n = 32;
770  }
771  else if(osStrcmp(curve->name, "secp256r1") == 0)
772  {
773  curveType = SCE_ECC_CURVE_TYPE_NIST;
774  oemCommand = SCE_OEM_CMD_ECC_P256_PUBLIC;
775  command = 0;
776  n = 32;
777  }
778  else if(osStrcmp(curve->name, "secp384r1") == 0)
779  {
780  curveType = SCE_ECC_CURVE_TYPE_NIST;
781  oemCommand = SCE_OEM_CMD_ECC_P384_PUBLIC;
782  command = 0;
783  n = 48;
784  }
785  else if(osStrcmp(curve->name, "brainpoolP256r1") == 0)
786  {
787  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
788  oemCommand = SCE_OEM_CMD_ECC_P256R1_PUBLIC;
789  command = 0;
790  n = 32;
791  }
792  else if(osStrcmp(curve->name, "brainpoolP384r1") == 0)
793  {
794  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
795  oemCommand = SCE_OEM_CMD_ECC_P384R1_PUBLIC;
796  command = 0;
797  n = 48;
798  }
799  else
800  {
801  return ERROR_FAILURE;
802  }
803 
804  //Keep the leftmost bits of the hash value
805  digestLen = MIN(digestLen, orderLen);
806 
807  //Acquire exclusive access to the SCE module
809 
810  //Pad the digest with leading zeroes if necessary
811  osMemset(ecArgs.digest, 0, n);
812  osMemcpy((uint8_t *) ecArgs.digest + n - digestLen, digest, digestLen);
813 
814  //Set public key
815  ecScalarExport(publicKey->q.x, n / 4, (uint8_t *) ecArgs.q, n,
817 
818  ecScalarExport(publicKey->q.y, n / 4, (uint8_t *) ecArgs.q + n, n,
820 
821  //Set signature
822  ecScalarExport(signature->r, n / 4, (uint8_t *) ecArgs.signature, n,
824 
825  ecScalarExport(signature->s, n / 4, (uint8_t *) ecArgs.signature + n, n,
827 
828  //Install the plaintext public key and get the wrapped key
829  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
830  oemCommand, NULL, NULL, (uint8_t *) ecArgs.q, ecArgs.wrappedKey);
831 
832  //Check status code
833  if(status == FSP_SUCCESS)
834  {
835  //Verify ECDSA signature
836  if(curve->fieldSize == 256)
837  {
838  status = HW_SCE_EcdsaSignatureVerificationSub(&curveType, &command,
839  ecArgs.wrappedKey, ecArgs.digest, ecArgs.signature);
840  }
841  else if(curve->fieldSize == 384)
842  {
843  status = HW_SCE_EcdsaP384SignatureVerificationSub(&curveType,
844  ecArgs.wrappedKey, ecArgs.digest, ecArgs.signature);
845  }
846  else
847  {
848  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
849  }
850  }
851 
852  //Release exclusive access to the SCE module
854 
855  //Return status code
856  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_INVALID_SIGNATURE;
857 }
858 
859 #endif
860 #endif
error_t ecScalarImport(uint32_t *r, uint_t n, const uint8_t *input, size_t length, EcScalarFormat format)
Octet string to integer conversion.
Definition: ec_misc.c:54
ECDSA signature.
Definition: ecdsa.h:63
error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const EcPrivateKey *privateKey, const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
ECDSA signature generation.
@ ERROR_OUT_OF_RANGE
Definition: error.h:138
uint32_t g[24]
uint32_t digest[12]
Mpi p
First factor.
Definition: rsa.h:72
uint8_t a
Definition: ndp.h:411
error_t ecScalarExport(const uint32_t *a, uint_t n, uint8_t *output, size_t length, EcScalarFormat format)
Integer to octet string conversion.
Definition: ec_misc.c:150
Arbitrary precision integer.
Definition: mpi.h:102
#define PrngAlgo
Definition: crypto.h:980
ECDSA (Elliptic Curve Digital Signature Algorithm)
uint8_t p
Definition: ndp.h:300
const EcCurve * curve
Elliptic curve parameters.
Definition: ecdsa.h:64
const EcCurve * curve
Elliptic curve parameters.
Definition: ec.h:433
#define EC_MAX_ORDER_SIZE
Definition: ec.h:315
Mpi n
Modulus.
Definition: rsa.h:69
RA4 public-key hardware accelerator.
#define mpiWriteRaw(a, data, length)
Definition: crypto_legacy.h:36
#define osStrcmp(s1, s2)
Definition: os_port.h:174
uint32_t y[EC_MAX_MODULUS_SIZE]
y-coordinate
Definition: ec.h:400
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:48
error_t mpiExpModFast(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (fast calculation)
Mpi d
Private exponent.
Definition: rsa.h:71
#define mpiReadRaw(r, data, length)
Definition: crypto_legacy.h:35
RSA primitive arguments.
uint8_t r
Definition: ndp.h:346
uint32_t m[128]
error_t mpiMod(Mpi *r, const Mpi *a, const Mpi *p)
Modulo operation.
Definition: mpi.c:1587
@ ERROR_INVALID_ELLIPTIC_CURVE
Definition: error.h:134
error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision multiplication.
uint8_t h
Definition: ndp.h:302
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
error_t mpiSub(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision subtraction.
Definition: mpi.c:969
error_t
Error codes.
Definition: error.h:43
error_t mpiAdd(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision addition.
Definition: mpi.c:891
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
void ecScalarSetInt(uint32_t *a, uint32_t b, uint_t n)
Set integer value.
Definition: ec_misc.c:505
Mpi q
Second factor.
Definition: rsa.h:73
Helper routines for ECC.
OsMutex ra4CryptoMutex
Definition: ra4_crypto.c:41
uint32_t r[EC_MAX_ORDER_SIZE]
Integer R.
Definition: ecdsa.h:65
error_t ecMulRegular(const EcCurve *curve, EcPoint3 *r, const uint32_t *d, const EcPoint3 *s)
Scalar multiplication (regular calculation)
General definitions for cryptographic algorithms.
RSA public-key cryptography standard.
EC primitive arguments.
EC private key.
Definition: ec.h:432
#define MIN(a, b)
Definition: os_port.h:63
Mpi qinv
CRT coefficient.
Definition: rsa.h:76
Mpi dq
Second factor's CRT exponent.
Definition: rsa.h:75
EC public key.
Definition: ec.h:421
__weak_func bool_t ecIsPointAffine(const EcCurve *curve, const EcPoint *s)
Check whether the affine point S is on the curve.
Definition: ec.c:840
uint32_t q[24]
uint32_t c[128]
RA4 hardware cryptographic accelerator (SCE5 / SCE9)
uint32_t d[12]
uint32_t d[EC_MAX_ORDER_SIZE]
Private key.
Definition: ec.h:434
int_t ecScalarCompInt(const uint32_t *a, uint32_t b, uint_t n)
Compare integers.
Definition: ec_misc.c:374
uint8_t m
Definition: ndp.h:304
uint8_t n
RSA private key.
Definition: rsa.h:68
@ EC_SCALAR_FORMAT_BIG_ENDIAN
Definition: ec_misc.h:51
error_t ecdsaVerifySignature(const EcPublicKey *publicKey, const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
ECDSA signature verification.
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
EC point (projective coordinates)
Definition: ec.h:409
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
EcPoint q
Public key.
Definition: ec.h:423
uint32_t wrappedKey[100]
uint32_t s[EC_MAX_ORDER_SIZE]
Integer S.
Definition: ecdsa.h:66
uint8_t s
Definition: igmp_common.h:234
uint32_t key[256]
error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
RSA decryption primitive.
#define EcCurve
Definition: ec.h:346
uint32_t wrappedKey[300]
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:358
Mpi dp
First factor's CRT exponent.
Definition: rsa.h:74
error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (regular calculation)
int_t ecScalarComp(const uint32_t *a, const uint32_t *b, uint_t n)
Compare integers.
Definition: ec_misc.c:337
error_t ecMulFast(const EcCurve *curve, EcPoint3 *r, const uint32_t *d, const EcPoint3 *s)
Scalar multiplication (fast calculation)
int_t mpiCompInt(const Mpi *a, mpi_sword_t b)
Compare a multiple precision integer with an integer.
Definition: mpi.c:429
uint32_t x[EC_MAX_MODULUS_SIZE]
x-coordinate
Definition: ec.h:399
#define osMemset(p, value, length)
Definition: os_port.h:138
error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular multiplication.
ECC (Elliptic Curve Cryptography)
@ ERROR_INVALID_SIGNATURE
Definition: error.h:228
const EcCurve * curve
Elliptic curve parameters.
Definition: ec.h:422
error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation.
#define EC_MAX_MODULUS_SIZE
Definition: ec.h:284
@ NO_ERROR
Success.
Definition: error.h:44
uint8_t c
Definition: ndp.h:514
Debugging facilities.
uint32_t signature[24]
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:215
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:64