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.0
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 n;
71  size_t aLen;
72  size_t eLen;
73  size_t pLen;
74 
75  //Get the length of the integer, in bytes
76  aLen = mpiGetByteLength(a);
77  //Get the length of the exponent, in bytes
78  eLen = mpiGetByteLength(e);
79  //Get the length of the modulus, in bytes
80  pLen = mpiGetByteLength(p);
81 
82  //The accelerator supports operand lengths up to 4096 bits
83  if((aLen <= 256 && eLen <= 4 && pLen <= 256) ||
84  (aLen <= 384 && eLen <= 4 && pLen <= 384) ||
85  (aLen <= 512 && eLen <= 4 && pLen <= 512))
86  {
87  sce_oem_cmd_t command;
88 
89  //Select appropriate scalar length
90  if(pLen <= 256)
91  {
92  command = SCE_OEM_CMD_RSA2048_PUBLIC;
93  n = 256;
94  }
95  else if(pLen <= 384)
96  {
97  command = SCE_OEM_CMD_RSA3072_PUBLIC;
98  n = 384;
99  }
100  else
101  {
102  command = SCE_OEM_CMD_RSA4096_PUBLIC;
103  n = 512;
104  }
105 
106  //Acquire exclusive access to the SCE module
108 
109  //Format message representative
110  mpiWriteRaw(a, (uint8_t *) rsaArgs.m, n);
111 
112  //Format public key
113  mpiWriteRaw(p, (uint8_t *) rsaArgs.key, n);
114  mpiWriteRaw(e, (uint8_t *) rsaArgs.key + n, 4);
115 
116  //Install the plaintext public key and get the wrapped key
117  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
118  command, NULL, NULL, (uint8_t *) rsaArgs.key, rsaArgs.wrappedKey);
119 
120  //Check status code
121  if(status == FSP_SUCCESS)
122  {
123  //Perform RSA encryption
124  if(n == 256)
125  {
126  status = HW_SCE_Rsa2048ModularExponentEncryptSub(rsaArgs.wrappedKey,
127  rsaArgs.m, rsaArgs.c);
128  }
129  else if(n == 384)
130  {
131  status = HW_SCE_Rsa3072ModularExponentEncryptSub(rsaArgs.wrappedKey,
132  rsaArgs.m, rsaArgs.c);
133  }
134  else if(n == 512)
135  {
136  status = HW_SCE_Rsa4096ModularExponentEncryptSub(rsaArgs.wrappedKey,
137  rsaArgs.m, rsaArgs.c);
138  }
139  else
140  {
141  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
142  }
143  }
144 
145  //Check status code
146  if(status == FSP_SUCCESS)
147  {
148  //Copy the ciphertext representative
149  error = mpiReadRaw(r, (uint8_t *) rsaArgs.c, n);
150  }
151  else
152  {
153  //Report an error
154  error = ERROR_FAILURE;
155  }
156 
157  //Release exclusive access to the SCE module
159  }
160  else
161  {
162  //Perform modular exponentiation (r = a ^ e mod p)
163  error = mpiExpModRegular(r, a, e, p);
164  }
165 
166  //Return status code
167  return error;
168 }
169 
170 
171 /**
172  * @brief Modular exponentiation (regular calculation)
173  * @param[out] r Resulting integer R = A ^ E mod P
174  * @param[in] a Pointer to a multiple precision integer
175  * @param[in] e Exponent
176  * @param[in] p Modulus
177  * @return Error code
178  **/
179 
180 error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
181 {
182  error_t error;
183  fsp_err_t status;
184  size_t aLen;
185  size_t eLen;
186  size_t pLen;
187 
188  //Get the length of the integer, in bytes
189  aLen = mpiGetByteLength(a);
190  //Get the length of the exponent, in bytes
191  eLen = mpiGetByteLength(e);
192  //Get the length of the modulus, in bytes
193  pLen = mpiGetByteLength(p);
194 
195  //The accelerator supports operand lengths up to 2048 bits
196  if(aLen <= 256 && eLen <= 256 && pLen <= 256)
197  {
198  //Acquire exclusive access to the SCE module
200 
201  //Format ciphertext representative
202  mpiWriteRaw(a, (uint8_t *) rsaArgs.c, 256);
203 
204  //Format private key
205  mpiWriteRaw(p, (uint8_t *) rsaArgs.key, 256);
206  mpiWriteRaw(e, (uint8_t *) rsaArgs.key + 256, 256);
207 
208  //Install the plaintext private key and get the wrapped key
209  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
210  SCE_OEM_CMD_RSA2048_PRIVATE, NULL, NULL, (uint8_t *) rsaArgs.key,
211  rsaArgs.wrappedKey);
212 
213  //Check status code
214  if(status == FSP_SUCCESS)
215  {
216  //Perform RSA decryption
217  status = HW_SCE_Rsa2048ModularExponentDecryptSub(rsaArgs.wrappedKey,
218  rsaArgs.c, rsaArgs.m);
219  }
220 
221  //Check status code
222  if(status == FSP_SUCCESS)
223  {
224  //Copy the message representative
225  error = mpiReadRaw(r, (uint8_t *) rsaArgs.m, 256);
226  }
227  else
228  {
229  //Report an error
230  error = ERROR_FAILURE;
231  }
232 
233  //Release exclusive access to the SCE module
235  }
236  else
237  {
238  //Perform modular exponentiation (r = a ^ e mod p)
239  error = mpiExpMod(r, a, e, p);
240  }
241 
242  //Return status code
243  return error;
244 }
245 
246 #endif
247 #if (RSA_SUPPORT == ENABLED)
248 
249 /**
250  * @brief RSA decryption primitive
251  *
252  * The RSA decryption primitive recovers the message representative from
253  * the ciphertext representative under the control of a private key
254  *
255  * @param[in] key RSA private key
256  * @param[in] c Ciphertext representative
257  * @param[out] m Message representative
258  * @return Error code
259  **/
260 
261 error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
262 {
263  error_t error;
264  size_t nLen;
265  size_t dLen;
266  size_t pLen;
267  size_t qLen;
268  size_t dpLen;
269  size_t dqLen;
270  size_t qinvLen;
271 
272  //Get the length of the private key
273  nLen = mpiGetByteLength(&key->n);
274  dLen = mpiGetByteLength(&key->d);
275  pLen = mpiGetByteLength(&key->p);
276  qLen = mpiGetByteLength(&key->q);
277  dpLen = mpiGetByteLength(&key->dp);
278  dqLen = mpiGetByteLength(&key->dq);
279  qinvLen = mpiGetByteLength(&key->qinv);
280 
281  //Sanity check
282  if(nLen == 0)
284 
285  //The ciphertext representative c shall be between 0 and n - 1
286  if(mpiCompInt(c, 0) < 0 || mpiComp(c, &key->n) >= 0)
287  return ERROR_OUT_OF_RANGE;
288 
289  //Check the length of the private key
290  if(nLen <= 256 && dLen <= 256)
291  {
292  //Let m = c ^ d mod n
293  error = mpiExpModRegular(m, c, &key->d, &key->n);
294  }
295  else if(nLen > 0 && pLen > 0 && qLen > 0 && dpLen > 0 && dqLen > 0 &&
296  qinvLen > 0)
297  {
298  Mpi m1;
299  Mpi m2;
300  Mpi h;
301 
302  //Initialize multiple-precision integers
303  mpiInit(&m1);
304  mpiInit(&m2);
305  mpiInit(&h);
306 
307  //Compute m1 = c ^ dP mod p
308  error = mpiMod(&m1, c, &key->p);
309 
310  if(!error)
311  {
312  error = mpiExpModRegular(&m1, &m1, &key->dp, &key->p);
313  }
314 
315  //Compute m2 = c ^ dQ mod q
316  if(!error)
317  {
318  error = mpiMod(&m2, c, &key->q);
319  }
320 
321  if(!error)
322  {
323  error = mpiExpModRegular(&m2, &m2, &key->dq, &key->q);
324  }
325 
326  //Let h = (m1 - m2) * qInv mod p
327  if(!error)
328  {
329  error = mpiSub(&h, &m1, &m2);
330  }
331 
332  if(!error)
333  {
334  error = mpiMulMod(&h, &h, &key->qinv, &key->p);
335  }
336 
337  //Let m = m2 + q * h
338  if(!error)
339  {
340  error = mpiMul(m, &key->q, &h);
341  }
342 
343  if(!error)
344  {
345  error = mpiAdd(m, m, &m2);
346  }
347 
348  //Free previously allocated memory
349  mpiFree(&m1);
350  mpiFree(&m2);
351  mpiFree(&h);
352  }
353  else if(nLen > 0 && dLen > 0)
354  {
355  //Let m = c ^ d mod n
356  error = mpiExpModRegular(m, c, &key->d, &key->n);
357  }
358  else
359  {
360  //Report an error
361  error = ERROR_INVALID_PARAMETER;
362  }
363 
364  //Return status code
365  return error;
366 }
367 
368 #endif
369 #if (EC_SUPPORT == ENABLED)
370 
371 /**
372  * @brief Scalar multiplication (fast calculation)
373  * @param[in] curve Elliptic curve parameters
374  * @param[out] r Resulting point R = d.S
375  * @param[in] d An integer d such as 0 <= d < p
376  * @param[in] s EC point
377  * @return Error code
378  **/
379 
380 error_t ecMulFast(const EcCurve *curve, EcPoint3 *r, const uint32_t *d,
381  const EcPoint3 *s)
382 {
383  //Compute R = d.S
384  return ecMulRegular(curve, r, d, s);
385 }
386 
387 
388 /**
389  * @brief Scalar multiplication (regular calculation)
390  * @param[in] curve Elliptic curve parameters
391  * @param[out] r Resulting point R = d.S
392  * @param[in] d An integer d such as 0 <= d < q
393  * @param[in] s EC point
394  * @return Error code
395  **/
396 
397 error_t ecMulRegular(const EcCurve *curve, EcPoint3 *r, const uint32_t *d,
398  const EcPoint3 *s)
399 {
400  error_t error;
401  fsp_err_t status;
402  size_t n;
403  uint32_t curveType;
404  uint32_t command;
405  sce_oem_cmd_t oemCommand;
406 
407  //Check elliptic curve parameters
408  if(osStrcmp(curve->name, "secp256k1") == 0)
409  {
410  curveType = SCE_ECC_CURVE_TYPE_KOBLITZ;
411  oemCommand = SCE_OEM_CMD_ECC_SECP256K1_PRIVATE;
412  command = 0;
413  n = 32;
414  }
415  else if(osStrcmp(curve->name, "secp256r1") == 0)
416  {
417  curveType = SCE_ECC_CURVE_TYPE_NIST;
418  oemCommand = SCE_OEM_CMD_ECC_P256_PRIVATE;
419  command = 0;
420  n = 32;
421  }
422  else if(osStrcmp(curve->name, "secp384r1") == 0)
423  {
424  curveType = SCE_ECC_CURVE_TYPE_NIST;
425  oemCommand = SCE_OEM_CMD_ECC_P384_PRIVATE;
426  command = 0;
427  n = 48;
428  }
429  else if(osStrcmp(curve->name, "brainpoolP256r1") == 0)
430  {
431  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
432  oemCommand = SCE_OEM_CMD_ECC_P256R1_PRIVATE;
433  command = 0;
434  n = 32;
435  }
436  else if(osStrcmp(curve->name, "brainpoolP384r1") == 0)
437  {
438  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
439  oemCommand = SCE_OEM_CMD_ECC_P384R1_PRIVATE;
440  command = 0;
441  n = 48;
442  }
443  else
444  {
445  return ERROR_FAILURE;
446  }
447 
448  //Acquire exclusive access to the SCE module
450 
451  //Set scalar value
452  ecScalarExport(d, n / 4, (uint8_t *) ecArgs.d, n,
454 
455  //Set input point
456  ecScalarExport(s->x, n / 4, (uint8_t *) ecArgs.g, n,
458 
459  ecScalarExport(s->y, n / 4, (uint8_t *) ecArgs.g + n, n,
461 
462  //Install the plaintext private key and get the wrapped key
463  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
464  oemCommand, NULL, NULL, (uint8_t *) ecArgs.d, ecArgs.wrappedKey);
465 
466  //Check status code
467  if(status == FSP_SUCCESS)
468  {
469  //Perform scalar multiplication
470  if(curve->fieldSize == 256)
471  {
472  status = HW_SCE_Ecc256ScalarMultiplicationSub(&curveType,
473  &command, ecArgs.wrappedKey, ecArgs.g, ecArgs.q);
474  }
475  else if(curve->fieldSize == 384)
476  {
477  status = HW_SCE_Ecc384ScalarMultiplicationSub(&curveType,
478  ecArgs.wrappedKey, ecArgs.g, ecArgs.q);
479  }
480  else
481  {
482  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
483  }
484  }
485 
486  //Check status code
487  if(status == FSP_SUCCESS)
488  {
489  //Copy the x-coordinate of the result
490  error = ecScalarImport(r->x, EC_MAX_MODULUS_SIZE, (uint8_t *) ecArgs.q,
492 
493  //Check status code
494  if(!error)
495  {
496  //Copy the y-coordinate of the result
498  (uint8_t *) ecArgs.q + n, n, EC_SCALAR_FORMAT_BIG_ENDIAN);
499  }
500 
501  //Check status code
502  if(!error)
503  {
504  //Set the z-coordinate of the result
506  }
507  }
508  else
509  {
510  //Report an error
511  error = ERROR_FAILURE;
512  }
513 
514  //Release exclusive access to the SCE module
516 
517  //Return status code
518  return error;
519 }
520 
521 #endif
522 #if (ECDSA_SUPPORT == ENABLED)
523 
524 /**
525  * @brief ECDSA signature generation
526  * @param[in] prngAlgo PRNG algorithm
527  * @param[in] prngContext Pointer to the PRNG context
528  * @param[in] privateKey Signer's EC private key
529  * @param[in] digest Digest of the message to be signed
530  * @param[in] digestLen Length in octets of the digest
531  * @param[out] signature (R, S) integer pair
532  * @return Error code
533  **/
534 
535 error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext,
536  const EcPrivateKey *privateKey, const uint8_t *digest, size_t digestLen,
537  EcdsaSignature *signature)
538 {
539  error_t error;
540  fsp_err_t status;
541  size_t n;
542  size_t orderLen;
543  uint32_t curveType;
544  uint32_t command;
545  sce_oem_cmd_t oemCommand;
546  const EcCurve *curve;
547 
548  //Check parameters
549  if(privateKey == NULL || digest == NULL || signature == NULL)
551 
552  //Invalid elliptic curve?
553  if(privateKey->curve == NULL)
555 
556  //Get elliptic curve parameters
557  curve = privateKey->curve;
558 
559  //Get the length of the order, in bytes
560  orderLen = (curve->orderSize + 7) / 8;
561 
562  //Check elliptic curve parameters
563  if(osStrcmp(curve->name, "secp256k1") == 0)
564  {
565  curveType = SCE_ECC_CURVE_TYPE_KOBLITZ;
566  oemCommand = SCE_OEM_CMD_ECC_SECP256K1_PRIVATE;
567  command = 0;
568  n = 32;
569  }
570  else if(osStrcmp(curve->name, "secp256r1") == 0)
571  {
572  curveType = SCE_ECC_CURVE_TYPE_NIST;
573  oemCommand = SCE_OEM_CMD_ECC_P256_PRIVATE;
574  command = 0;
575  n = 32;
576  }
577  else if(osStrcmp(curve->name, "secp384r1") == 0)
578  {
579  curveType = SCE_ECC_CURVE_TYPE_NIST;
580  oemCommand = SCE_OEM_CMD_ECC_P384_PRIVATE;
581  command = 0;
582  n = 48;
583  }
584  else if(osStrcmp(curve->name, "brainpoolP256r1") == 0)
585  {
586  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
587  oemCommand = SCE_OEM_CMD_ECC_P256R1_PRIVATE;
588  command = 0;
589  n = 32;
590  }
591  else if(osStrcmp(curve->name, "brainpoolP384r1") == 0)
592  {
593  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
594  oemCommand = SCE_OEM_CMD_ECC_P384R1_PRIVATE;
595  command = 0;
596  n = 48;
597  }
598  else
599  {
600  return ERROR_FAILURE;
601  }
602 
603  //Keep the leftmost bits of the hash value
604  digestLen = MIN(digestLen, orderLen);
605 
606  //Acquire exclusive access to the SCE module
608 
609  //Pad the digest with leading zeroes if necessary
610  osMemset(ecArgs.digest, 0, n);
611  osMemcpy((uint8_t *) ecArgs.digest + n - digestLen, digest, digestLen);
612 
613  //Set private key
614  ecScalarExport(privateKey->d, n / 4, (uint8_t *) ecArgs.d, n,
616 
617  //Install the plaintext private key and get the wrapped key
618  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
619  oemCommand, NULL, NULL, (uint8_t *) ecArgs.d, ecArgs.wrappedKey);
620 
621  //Check status code
622  if(status == FSP_SUCCESS)
623  {
624  //Generate ECDSA signature
625  if(curve->fieldSize == 256)
626  {
627  status = HW_SCE_EcdsaSignatureGenerateSub(&curveType, &command,
628  ecArgs.wrappedKey, ecArgs.digest, ecArgs.signature);
629  }
630  else if(curve->fieldSize == 384)
631  {
632  status = HW_SCE_EcdsaP384SignatureGenerateSub(&curveType,
633  ecArgs.wrappedKey, ecArgs.digest, ecArgs.signature);
634  }
635  else
636  {
637  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
638  }
639  }
640 
641  //Check status code
642  if(status == FSP_SUCCESS)
643  {
644  //Save elliptic curve parameters
645  signature->curve = curve;
646 
647  //Copy integer R
648  error = ecScalarImport(signature->r, EC_MAX_ORDER_SIZE,
649  (uint8_t *) ecArgs.signature, n, EC_SCALAR_FORMAT_BIG_ENDIAN);
650 
651  //Check status code
652  if(!error)
653  {
654  //Copy integer S
655  error = ecScalarImport(signature->s, EC_MAX_ORDER_SIZE,
656  (uint8_t *) ecArgs.signature + n, n, EC_SCALAR_FORMAT_BIG_ENDIAN);
657  }
658  }
659  else
660  {
661  //Report an error
662  error = ERROR_FAILURE;
663  }
664 
665  //Release exclusive access to the SCE module
667 
668  //Return status code
669  return error;
670 }
671 
672 
673 /**
674  * @brief ECDSA signature verification
675  * @param[in] publicKey Signer's EC public key
676  * @param[in] digest Digest of the message whose signature is to be verified
677  * @param[in] digestLen Length in octets of the digest
678  * @param[in] signature (R, S) integer pair
679  * @return Error code
680  **/
681 
683  const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
684 {
685  fsp_err_t status;
686  size_t n;
687  size_t orderLen;
688  uint32_t curveType;
689  uint32_t command;
690  sce_oem_cmd_t oemCommand;
691  const EcCurve *curve;
692 
693  //Check parameters
694  if(publicKey == NULL || digest == NULL || signature == NULL)
696 
697  //Invalid elliptic curve?
698  if(publicKey->curve == NULL)
700 
701  //Verify that the public key is on the curve
702  if(!ecIsPointAffine(publicKey->curve, &publicKey->q))
703  {
705  }
706 
707  //The verifier shall check that 0 < r < q
708  if(ecScalarCompInt(signature->r, 0, EC_MAX_ORDER_SIZE) <= 0 ||
709  ecScalarComp(signature->r, publicKey->curve->q, EC_MAX_ORDER_SIZE) >= 0)
710  {
711  //If the condition is violated, the signature shall be rejected as invalid
713  }
714 
715  //The verifier shall check that 0 < s < q
716  if(ecScalarCompInt(signature->s, 0, EC_MAX_ORDER_SIZE) <= 0 ||
717  ecScalarComp(signature->s, publicKey->curve->q, EC_MAX_ORDER_SIZE) >= 0)
718  {
719  //If the condition is violated, the signature shall be rejected as invalid
721  }
722 
723  //Get elliptic curve parameters
724  curve = publicKey->curve;
725 
726  //Get the length of the order, in bytes
727  orderLen = (curve->orderSize + 7) / 8;
728 
729  //Check elliptic curve parameters
730  if(osStrcmp(curve->name, "secp256k1") == 0)
731  {
732  curveType = SCE_ECC_CURVE_TYPE_KOBLITZ;
733  oemCommand = SCE_OEM_CMD_ECC_SECP256K1_PUBLIC;
734  command = 0;
735  n = 32;
736  }
737  else if(osStrcmp(curve->name, "secp256r1") == 0)
738  {
739  curveType = SCE_ECC_CURVE_TYPE_NIST;
740  oemCommand = SCE_OEM_CMD_ECC_P256_PUBLIC;
741  command = 0;
742  n = 32;
743  }
744  else if(osStrcmp(curve->name, "secp384r1") == 0)
745  {
746  curveType = SCE_ECC_CURVE_TYPE_NIST;
747  oemCommand = SCE_OEM_CMD_ECC_P384_PUBLIC;
748  command = 0;
749  n = 48;
750  }
751  else if(osStrcmp(curve->name, "brainpoolP256r1") == 0)
752  {
753  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
754  oemCommand = SCE_OEM_CMD_ECC_P256R1_PUBLIC;
755  command = 0;
756  n = 32;
757  }
758  else if(osStrcmp(curve->name, "brainpoolP384r1") == 0)
759  {
760  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
761  oemCommand = SCE_OEM_CMD_ECC_P384R1_PUBLIC;
762  command = 0;
763  n = 48;
764  }
765  else
766  {
767  return ERROR_FAILURE;
768  }
769 
770  //Keep the leftmost bits of the hash value
771  digestLen = MIN(digestLen, orderLen);
772 
773  //Acquire exclusive access to the SCE module
775 
776  //Pad the digest with leading zeroes if necessary
777  osMemset(ecArgs.digest, 0, n);
778  osMemcpy((uint8_t *) ecArgs.digest + n - digestLen, digest, digestLen);
779 
780  //Set public key
781  ecScalarExport(publicKey->q.x, n / 4, (uint8_t *) ecArgs.q, n,
783 
784  ecScalarExport(publicKey->q.y, n / 4, (uint8_t *) ecArgs.q + n, n,
786 
787  //Set signature
788  ecScalarExport(signature->r, n / 4, (uint8_t *) ecArgs.signature, n,
790 
791  ecScalarExport(signature->s, n / 4, (uint8_t *) ecArgs.signature + n, n,
793 
794  //Install the plaintext public key and get the wrapped key
795  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
796  oemCommand, NULL, NULL, (uint8_t *) ecArgs.q, ecArgs.wrappedKey);
797 
798  //Check status code
799  if(status == FSP_SUCCESS)
800  {
801  //Verify ECDSA signature
802  if(curve->fieldSize == 256)
803  {
804  status = HW_SCE_EcdsaSignatureVerificationSub(&curveType, &command,
805  ecArgs.wrappedKey, ecArgs.digest, ecArgs.signature);
806  }
807  else if(curve->fieldSize == 384)
808  {
809  status = HW_SCE_EcdsaP384SignatureVerificationSub(&curveType,
810  ecArgs.wrappedKey, ecArgs.digest, ecArgs.signature);
811  }
812  else
813  {
814  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
815  }
816  }
817 
818  //Release exclusive access to the SCE module
820 
821  //Return status code
822  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_INVALID_SIGNATURE;
823 }
824 
825 #endif
826 #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:973
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:798
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