ra6_crypto_pkc.c
Go to the documentation of this file.
1 /**
2  * @file ra6_crypto_pkc.c
3  * @brief RA6 public-key hardware accelerator
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 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.4.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/ecdsa.h"
45 #include "debug.h"
46 
47 //Check crypto library configuration
48 #if (RA6_CRYPTO_PKC_SUPPORT == ENABLED)
49 
50 //Global variables
51 static Ra6RsaArgs rsaArgs;
52 static Ra6EcArgs ecArgs;
53 
54 
55 /**
56  * @brief Modular exponentiation (fast calculation)
57  * @param[out] r Resulting integer R = A ^ E mod P
58  * @param[in] a Pointer to a multiple precision integer
59  * @param[in] e Exponent
60  * @param[in] p Modulus
61  * @return Error code
62  **/
63 
64 error_t mpiExpModFast(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
65 {
66  error_t error;
67  fsp_err_t status;
68  size_t n;
69  size_t aLen;
70  size_t eLen;
71  size_t pLen;
72 
73  //Retrieve the length of the integer, in bytes
74  aLen = mpiGetByteLength(a);
75  //Retrieve the length of the exponent, in bytes
76  eLen = mpiGetByteLength(e);
77  //Retrieve the length of the modulus, in bytes
78  pLen = mpiGetByteLength(p);
79 
80 #if (BSP_FEATURE_CRYPTO_HAS_SCE9 != 0)
81  //The SCE9 accelerator supports operand lengths up to 4096 bits
82  if((aLen <= 256 && eLen <= 4 && pLen <= 256) ||
83  (aLen <= 384 && eLen <= 4 && pLen <= 384) ||
84  (aLen <= 512 && eLen <= 4 && pLen <= 512))
85  {
86  sce_oem_cmd_t command;
87 
88  //Select appropriate scalar length
89  if(pLen <= 256)
90  {
91  command = SCE_OEM_CMD_RSA2048_PUBLIC;
92  n = 256;
93  }
94  else if(pLen <= 384)
95  {
96  command = SCE_OEM_CMD_RSA3072_PUBLIC;
97  n = 384;
98  }
99  else
100  {
101  command = SCE_OEM_CMD_RSA4096_PUBLIC;
102  n = 512;
103  }
104 
105  //Acquire exclusive access to the SCE module
107 
108  //Format message representative
109  mpiWriteRaw(a, (uint8_t *) rsaArgs.m, n);
110 
111  //Format public key
112  mpiWriteRaw(p, (uint8_t *) rsaArgs.key, n);
113  mpiWriteRaw(e, (uint8_t *) rsaArgs.key + n, 4);
114 
115  //Install the plaintext public key and get the wrapped key
116  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
117  command, NULL, NULL, (uint8_t *) rsaArgs.key, rsaArgs.wrappedKey);
118 
119  //Check status code
120  if(status == FSP_SUCCESS)
121  {
122  //Perform RSA encryption
123  if(n == 256)
124  {
125  status = HW_SCE_Rsa2048ModularExponentEncryptSub(rsaArgs.wrappedKey,
126  rsaArgs.m, rsaArgs.c);
127  }
128  else if(n == 384)
129  {
130  status = HW_SCE_Rsa3072ModularExponentEncryptSub(rsaArgs.wrappedKey,
131  rsaArgs.m, rsaArgs.c);
132  }
133  else if(n == 512)
134  {
135  status = HW_SCE_Rsa4096ModularExponentEncryptSub(rsaArgs.wrappedKey,
136  rsaArgs.m, rsaArgs.c);
137  }
138  else
139  {
140  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
141  }
142  }
143 
144  //Check status code
145  if(status == FSP_SUCCESS)
146  {
147  //Copy the ciphertext representative
148  error = mpiReadRaw(r, (uint8_t *) rsaArgs.c, n);
149  }
150  else
151  {
152  //Report an error
153  error = ERROR_FAILURE;
154  }
155 
156  //Release exclusive access to the SCE module
158  }
159 #else
160  //The SCE7 accelerator supports operand lengths up to 2048 bits
161  if(aLen <= 256 && eLen <= 4 && pLen <= 256)
162  {
163  //Acquire exclusive access to the SCE module
165 
166  //Format message representative
167  mpiWriteRaw(a, (uint8_t *) rsaArgs.m, 256);
168 
169  //Format public key
170  mpiWriteRaw(p, (uint8_t *) rsaArgs.key, 256);
171  mpiWriteRaw(e, (uint8_t *) rsaArgs.key + 256, 4);
172 
173  //Install the plaintext public key and get the wrapped key
174  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
175  SCE_OEM_CMD_RSA2048_PUBLIC, NULL, NULL, (uint8_t *) rsaArgs.key,
176  rsaArgs.wrappedKey);
177 
178  //Check status code
179  if(status == FSP_SUCCESS)
180  {
181  //Perform RSA encryption
182  status = HW_SCE_Rsa2048ModularExponentEncryptSub(rsaArgs.wrappedKey,
183  rsaArgs.m, rsaArgs.c);
184  }
185 
186  //Check status code
187  if(status == FSP_SUCCESS)
188  {
189  //Copy the ciphertext representative
190  error = mpiReadRaw(r, (uint8_t *) rsaArgs.c, 256);
191  }
192  else
193  {
194  //Report an error
195  error = ERROR_FAILURE;
196  }
197 
198  //Release exclusive access to the SCE module
200  }
201 #endif
202  else
203  {
204  //Perform modular exponentiation (r = a ^ e mod p)
205  error = mpiExpModRegular(r, a, e, p);
206  }
207 
208  //Return status code
209  return error;
210 }
211 
212 
213 /**
214  * @brief Modular exponentiation (regular calculation)
215  * @param[out] r Resulting integer R = A ^ E mod P
216  * @param[in] a Pointer to a multiple precision integer
217  * @param[in] e Exponent
218  * @param[in] p Modulus
219  * @return Error code
220  **/
221 
222 error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
223 {
224  error_t error;
225  fsp_err_t status;
226  size_t aLen;
227  size_t eLen;
228  size_t pLen;
229 
230  //Retrieve the length of the integer, in bytes
231  aLen = mpiGetByteLength(a);
232  //Retrieve the length of the exponent, in bytes
233  eLen = mpiGetByteLength(e);
234  //Retrieve the length of the modulus, in bytes
235  pLen = mpiGetByteLength(p);
236 
237  //The accelerator supports operand lengths up to 2048 bits
238  if(aLen <= 256 && eLen <= 256 && pLen <= 256)
239  {
240  //Acquire exclusive access to the SCE module
242 
243  //Format ciphertext representative
244  mpiWriteRaw(a, (uint8_t *) rsaArgs.c, 256);
245 
246  //Format private key
247  mpiWriteRaw(p, (uint8_t *) rsaArgs.key, 256);
248  mpiWriteRaw(e, (uint8_t *) rsaArgs.key + 256, 256);
249 
250  //Install the plaintext private key and get the wrapped key
251  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
252  SCE_OEM_CMD_RSA2048_PRIVATE, NULL, NULL, (uint8_t *) rsaArgs.key,
253  rsaArgs.wrappedKey);
254 
255  //Check status code
256  if(status == FSP_SUCCESS)
257  {
258  //Perform RSA decryption
259  status = HW_SCE_Rsa2048ModularExponentDecryptSub(rsaArgs.wrappedKey,
260  rsaArgs.c, rsaArgs.m);
261  }
262 
263  //Check status code
264  if(status == FSP_SUCCESS)
265  {
266  //Copy the message representative
267  error = mpiReadRaw(r, (uint8_t *) rsaArgs.m, 256);
268  }
269  else
270  {
271  //Report an error
272  error = ERROR_FAILURE;
273  }
274 
275  //Release exclusive access to the SCE module
277  }
278  else
279  {
280  //Perform modular exponentiation (r = a ^ e mod p)
281  error = mpiExpMod(r, a, e, p);
282  }
283 
284  //Return status code
285  return error;
286 }
287 
288 
289 /**
290  * @brief RSA decryption primitive
291  *
292  * The RSA decryption primitive recovers the message representative from
293  * the ciphertext representative under the control of a private key
294  *
295  * @param[in] key RSA private key
296  * @param[in] c Ciphertext representative
297  * @param[out] m Message representative
298  * @return Error code
299  **/
300 
301 error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
302 {
303  error_t error;
304  size_t nLen;
305  size_t dLen;
306  size_t pLen;
307  size_t qLen;
308  size_t dpLen;
309  size_t dqLen;
310  size_t qinvLen;
311 
312  //Retrieve the length of the private key
313  nLen = mpiGetByteLength(&key->n);
314  dLen = mpiGetByteLength(&key->d);
315  pLen = mpiGetByteLength(&key->p);
316  qLen = mpiGetByteLength(&key->q);
317  dpLen = mpiGetByteLength(&key->dp);
318  dqLen = mpiGetByteLength(&key->dq);
319  qinvLen = mpiGetByteLength(&key->qinv);
320 
321  //Sanity check
322  if(nLen == 0)
324 
325  //The ciphertext representative c shall be between 0 and n - 1
326  if(mpiCompInt(c, 0) < 0 || mpiComp(c, &key->n) >= 0)
327  return ERROR_OUT_OF_RANGE;
328 
329  //Check the length of the private key
330  if(nLen <= 256 && dLen <= 256)
331  {
332  //Let m = c ^ d mod n
333  error = mpiExpModRegular(m, c, &key->d, &key->n);
334  }
335  else if(nLen > 0 && pLen > 0 && qLen > 0 && dpLen > 0 && dqLen > 0 &&
336  qinvLen > 0)
337  {
338  Mpi m1;
339  Mpi m2;
340  Mpi h;
341 
342  //Initialize multiple-precision integers
343  mpiInit(&m1);
344  mpiInit(&m2);
345  mpiInit(&h);
346 
347  //Compute m1 = c ^ dP mod p
348  error = mpiMod(&m1, c, &key->p);
349 
350  if(!error)
351  {
352  error = mpiExpModRegular(&m1, &m1, &key->dp, &key->p);
353  }
354 
355  //Compute m2 = c ^ dQ mod q
356  if(!error)
357  {
358  error = mpiMod(&m2, c, &key->q);
359  }
360 
361  if(!error)
362  {
363  error = mpiExpModRegular(&m2, &m2, &key->dq, &key->q);
364  }
365 
366  //Let h = (m1 - m2) * qInv mod p
367  if(!error)
368  {
369  error = mpiSub(&h, &m1, &m2);
370  }
371 
372  if(!error)
373  {
374  error = mpiMulMod(&h, &h, &key->qinv, &key->p);
375  }
376 
377  //Let m = m2 + q * h
378  if(!error)
379  {
380  error = mpiMul(m, &key->q, &h);
381  }
382 
383  if(!error)
384  {
385  error = mpiAdd(m, m, &m2);
386  }
387 
388  //Free previously allocated memory
389  mpiFree(&m1);
390  mpiFree(&m2);
391  mpiFree(&h);
392  }
393  else if(nLen > 0 && dLen > 0)
394  {
395  //Let m = c ^ d mod n
396  error = mpiExpModRegular(m, c, &key->d, &key->n);
397  }
398  else
399  {
400  //Report an error
401  error = ERROR_INVALID_PARAMETER;
402  }
403 
404  //Return status code
405  return error;
406 }
407 
408 
409 /**
410  * @brief Scalar multiplication
411  * @param[in] params EC domain parameters
412  * @param[out] r Resulting point R = d.S
413  * @param[in] d An integer d such as 0 <= d < p
414  * @param[in] s EC point
415  * @return Error code
416  **/
417 
418 error_t ecMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d,
419  const EcPoint *s)
420 {
421  error_t error;
422  fsp_err_t status;
423  size_t n;
424  uint32_t curveType;
425  uint32_t command;
426  sce_oem_cmd_t oemCommand;
427 
428  //Check elliptic curve parameters
429  if(!osStrcmp(params->name, "secp256k1"))
430  {
431  curveType = SCE_ECC_CURVE_TYPE_KOBLITZ;
432  oemCommand = SCE_OEM_CMD_ECC_SECP256K1_PRIVATE;
433  command = 0;
434  n = 32;
435  }
436  else if(!osStrcmp(params->name, "secp256r1"))
437  {
438  curveType = SCE_ECC_CURVE_TYPE_NIST;
439  oemCommand = SCE_OEM_CMD_ECC_P256_PRIVATE;
440  command = 0;
441  n = 32;
442  }
443  else if(!osStrcmp(params->name, "secp384r1"))
444  {
445  curveType = SCE_ECC_CURVE_TYPE_NIST;
446  oemCommand = SCE_OEM_CMD_ECC_P384_PRIVATE;
447  command = 0;
448  n = 48;
449  }
450  else if(!osStrcmp(params->name, "brainpoolP256r1"))
451  {
452  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
453  oemCommand = SCE_OEM_CMD_ECC_P256R1_PRIVATE;
454  command = 0;
455  n = 32;
456  }
457  else if(!osStrcmp(params->name, "brainpoolP384r1"))
458  {
459  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
460  oemCommand = SCE_OEM_CMD_ECC_P384R1_PRIVATE;
461  command = 0;
462  n = 48;
463  }
464  else
465  {
466  return ERROR_FAILURE;
467  }
468 
469  //Acquire exclusive access to the SCE module
471 
472  //Set scalar value
473  mpiWriteRaw(d, (uint8_t *) ecArgs.d, n);
474 
475  //Set input point
476  mpiWriteRaw(&s->x, (uint8_t *) ecArgs.g, n);
477  mpiWriteRaw(&s->y, (uint8_t *) ecArgs.g + n, n);
478 
479  //Install the plaintext private key and get the wrapped key
480  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
481  oemCommand, NULL, NULL, (uint8_t *) ecArgs.d, ecArgs.wrappedKey);
482 
483  //Check status code
484  if(status == FSP_SUCCESS)
485  {
486  //Perform scalar multiplication
487  if(n == 32)
488  {
489  status = HW_SCE_Ecc256ScalarMultiplicationSub(&curveType,
490  &command, ecArgs.wrappedKey, ecArgs.g, ecArgs.q);
491  }
492  else if(n == 48)
493  {
494  status = HW_SCE_Ecc384ScalarMultiplicationSub(&curveType,
495  ecArgs.wrappedKey, ecArgs.g, ecArgs.q);
496  }
497  else
498  {
499  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
500  }
501  }
502 
503  //Check status code
504  if(status == FSP_SUCCESS)
505  {
506  //Copy the x-coordinate of the result
507  error = mpiReadRaw(&r->x, (uint8_t *) ecArgs.q, n);
508 
509  //Check status code
510  if(!error)
511  {
512  //Copy the y-coordinate of the result
513  error = mpiReadRaw(&r->y, (uint8_t *) ecArgs.q + n, n);
514  }
515 
516  //Check status code
517  if(!error)
518  {
519  //Set the z-coordinate of the result
520  error = mpiSetValue(&r->z, 1);
521  }
522  }
523  else
524  {
525  //Report an error
526  error = ERROR_FAILURE;
527  }
528 
529  //Release exclusive access to the SCE module
531 
532  //Return status code
533  return error;
534 }
535 
536 
537 /**
538  * @brief ECDSA signature generation
539  * @param[in] prngAlgo PRNG algorithm
540  * @param[in] prngContext Pointer to the PRNG context
541  * @param[in] params EC domain parameters
542  * @param[in] privateKey Signer's EC private key
543  * @param[in] digest Digest of the message to be signed
544  * @param[in] digestLen Length in octets of the digest
545  * @param[out] signature (R, S) integer pair
546  * @return Error code
547  **/
548 
549 error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext,
550  const EcDomainParameters *params, const EcPrivateKey *privateKey,
551  const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
552 {
553  error_t error;
554  fsp_err_t status;
555  size_t n;
556  size_t orderLen;
557  uint32_t curveType;
558  uint32_t command;
559  sce_oem_cmd_t oemCommand;
560 
561  //Check parameters
562  if(params == NULL || privateKey == NULL || digest == NULL || signature == NULL)
564 
565  //Retrieve the length of the base point order, in bytes
566  orderLen = mpiGetByteLength(&params->q);
567 
568  //Check elliptic curve parameters
569  if(!osStrcmp(params->name, "secp256k1"))
570  {
571  curveType = SCE_ECC_CURVE_TYPE_KOBLITZ;
572  oemCommand = SCE_OEM_CMD_ECC_SECP256K1_PRIVATE;
573  command = 0;
574  n = 32;
575  }
576  else if(!osStrcmp(params->name, "secp256r1"))
577  {
578  curveType = SCE_ECC_CURVE_TYPE_NIST;
579  oemCommand = SCE_OEM_CMD_ECC_P256_PRIVATE;
580  command = 0;
581  n = 32;
582  }
583  else if(!osStrcmp(params->name, "secp384r1"))
584  {
585  curveType = SCE_ECC_CURVE_TYPE_NIST;
586  oemCommand = SCE_OEM_CMD_ECC_P384_PRIVATE;
587  command = 0;
588  n = 48;
589  }
590  else if(!osStrcmp(params->name, "brainpoolP256r1"))
591  {
592  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
593  oemCommand = SCE_OEM_CMD_ECC_P256R1_PRIVATE;
594  command = 0;
595  n = 32;
596  }
597  else if(!osStrcmp(params->name, "brainpoolP384r1"))
598  {
599  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
600  oemCommand = SCE_OEM_CMD_ECC_P384R1_PRIVATE;
601  command = 0;
602  n = 48;
603  }
604  else
605  {
606  return ERROR_FAILURE;
607  }
608 
609  //Keep the leftmost bits of the hash value
610  digestLen = MIN(digestLen, orderLen);
611 
612  //Acquire exclusive access to the SCE module
614 
615  //Pad the digest with leading zeroes if necessary
616  osMemset(ecArgs.digest, 0, n);
617  osMemcpy((uint8_t *) ecArgs.digest + n - digestLen, digest, digestLen);
618 
619  //Set private key
620  mpiWriteRaw(&privateKey->d, (uint8_t *) ecArgs.d, n);
621 
622  //Install the plaintext private key and get the wrapped key
623  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
624  oemCommand, NULL, NULL, (uint8_t *) ecArgs.d, ecArgs.wrappedKey);
625 
626  //Check status code
627  if(status == FSP_SUCCESS)
628  {
629  //Verify ECDSA signature
630  if(n == 32)
631  {
632  status = HW_SCE_EcdsaSignatureGenerateSub(&curveType, &command,
633  ecArgs.wrappedKey, ecArgs.digest, ecArgs.signature);
634  }
635  else if(n == 48)
636  {
637  status = HW_SCE_EcdsaP384SignatureGenerateSub(&curveType,
638  ecArgs.wrappedKey, ecArgs.digest, ecArgs.signature);
639  }
640  else
641  {
642  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
643  }
644  }
645 
646  //Check status code
647  if(status == FSP_SUCCESS)
648  {
649  //Copy integer R
650  error = mpiReadRaw(&signature->r, (uint8_t *) ecArgs.signature, n);
651 
652  //Check status code
653  if(!error)
654  {
655  //Copy integer S
656  error = mpiReadRaw(&signature->s, (uint8_t *) ecArgs.signature + n, n);
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] params EC domain parameters
676  * @param[in] publicKey Signer's EC public key
677  * @param[in] digest Digest of the message whose signature is to be verified
678  * @param[in] digestLen Length in octets of the digest
679  * @param[in] signature (R, S) integer pair
680  * @return Error code
681  **/
682 
684  const EcPublicKey *publicKey, const uint8_t *digest, size_t digestLen,
685  const EcdsaSignature *signature)
686 {
687  fsp_err_t status;
688  size_t n;
689  size_t orderLen;
690  uint32_t curveType;
691  uint32_t command;
692  sce_oem_cmd_t oemCommand;
693 
694  //Check parameters
695  if(params == NULL || publicKey == NULL || digest == NULL || signature == NULL)
697 
698  //The verifier shall check that 0 < r < q
699  if(mpiCompInt(&signature->r, 0) <= 0 ||
700  mpiComp(&signature->r, &params->q) >= 0)
701  {
702  //If the condition is violated, the signature shall be rejected as invalid
704  }
705 
706  //The verifier shall check that 0 < s < q
707  if(mpiCompInt(&signature->s, 0) <= 0 ||
708  mpiComp(&signature->s, &params->q) >= 0)
709  {
710  //If the condition is violated, the signature shall be rejected as invalid
712  }
713 
714  //Retrieve the length of the base point order, in bytes
715  orderLen = mpiGetByteLength(&params->q);
716 
717  //Check elliptic curve parameters
718  if(!osStrcmp(params->name, "secp256k1"))
719  {
720  curveType = SCE_ECC_CURVE_TYPE_KOBLITZ;
721  oemCommand = SCE_OEM_CMD_ECC_SECP256K1_PUBLIC;
722  command = 0;
723  n = 32;
724  }
725  else if(!osStrcmp(params->name, "secp256r1"))
726  {
727  curveType = SCE_ECC_CURVE_TYPE_NIST;
728  oemCommand = SCE_OEM_CMD_ECC_P256_PUBLIC;
729  command = 0;
730  n = 32;
731  }
732  else if(!osStrcmp(params->name, "secp384r1"))
733  {
734  curveType = SCE_ECC_CURVE_TYPE_NIST;
735  oemCommand = SCE_OEM_CMD_ECC_P384_PUBLIC;
736  command = 0;
737  n = 48;
738  }
739  else if(!osStrcmp(params->name, "brainpoolP256r1"))
740  {
741  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
742  oemCommand = SCE_OEM_CMD_ECC_P256R1_PUBLIC;
743  command = 0;
744  n = 32;
745  }
746  else if(!osStrcmp(params->name, "brainpoolP384r1"))
747  {
748  curveType = SCE_ECC_CURVE_TYPE_BRAINPOOL;
749  oemCommand = SCE_OEM_CMD_ECC_P384R1_PUBLIC;
750  command = 0;
751  n = 48;
752  }
753  else
754  {
755  return ERROR_FAILURE;
756  }
757 
758  //Keep the leftmost bits of the hash value
759  digestLen = MIN(digestLen, orderLen);
760 
761  //Acquire exclusive access to the SCE module
763 
764  //Pad the digest with leading zeroes if necessary
765  osMemset(ecArgs.digest, 0, n);
766  osMemcpy((uint8_t *) ecArgs.digest + n - digestLen, digest, digestLen);
767 
768  //Set public key
769  mpiWriteRaw(&publicKey->q.x, (uint8_t *) ecArgs.q, n);
770  mpiWriteRaw(&publicKey->q.y, (uint8_t *) ecArgs.q + n, n);
771 
772  //Set signature
773  mpiWriteRaw(&signature->r, (uint8_t *) ecArgs.signature, n);
774  mpiWriteRaw(&signature->s, (uint8_t *) ecArgs.signature + n, n);
775 
776  //Install the plaintext public key and get the wrapped key
777  status = HW_SCE_GenerateOemKeyIndexPrivate(SCE_OEM_KEY_TYPE_PLAIN,
778  oemCommand, NULL, NULL, (uint8_t *) ecArgs.q, ecArgs.wrappedKey);
779 
780  //Check status code
781  if(status == FSP_SUCCESS)
782  {
783  //Verify ECDSA signature
784  if(n == 32)
785  {
786  status = HW_SCE_EcdsaSignatureVerificationSub(&curveType, &command,
787  ecArgs.wrappedKey, ecArgs.digest, ecArgs.signature);
788  }
789  else if(n == 48)
790  {
791  status = HW_SCE_EcdsaP384SignatureVerificationSub(&curveType,
792  ecArgs.wrappedKey, ecArgs.digest, ecArgs.signature);
793  }
794  else
795  {
796  status = FSP_ERR_CRYPTO_NOT_IMPLEMENTED;
797  }
798  }
799 
800  //Release exclusive access to the SCE module
802 
803  //Return status code
804  return (status == FSP_SUCCESS) ? NO_ERROR : ERROR_INVALID_SIGNATURE;
805 }
806 
807 #endif
General definitions for cryptographic algorithms.
#define PrngAlgo
Definition: crypto.h:917
#define mpiReadRaw(r, data, length)
Definition: crypto_legacy.h:35
#define mpiWriteRaw(a, data, length)
Definition: crypto_legacy.h:36
Debugging facilities.
uint8_t n
ECC (Elliptic Curve Cryptography)
ECDSA (Elliptic Curve Digital Signature Algorithm)
error_t
Error codes.
Definition: error.h:43
@ ERROR_INVALID_SIGNATURE
Definition: error.h:226
@ ERROR_OUT_OF_RANGE
Definition: error.h:137
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision multiplication.
error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation.
error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular multiplication.
error_t mpiSetValue(Mpi *r, int_t a)
Set the value of a multiple precision integer.
Definition: mpi.c:484
error_t mpiSub(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision subtraction.
Definition: mpi.c:864
int_t mpiCompInt(const Mpi *a, int_t b)
Compare a multiple precision integer with an integer.
Definition: mpi.c:382
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:338
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:48
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:195
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:64
error_t mpiAdd(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision addition.
Definition: mpi.c:787
error_t mpiMod(Mpi *r, const Mpi *a, const Mpi *p)
Modulo operation.
Definition: mpi.c:1444
uint8_t h
Definition: ndp.h:302
uint8_t c
Definition: ndp.h:514
uint8_t r
Definition: ndp.h:346
uint8_t s
Definition: ndp.h:345
uint8_t p
Definition: ndp.h:300
uint8_t m
Definition: ndp.h:304
uint8_t a
Definition: ndp.h:411
#define osMemset(p, value, length)
Definition: os_port.h:135
#define osStrcmp(s1, s2)
Definition: os_port.h:171
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define MIN(a, b)
Definition: os_port.h:63
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
OsMutex ra6CryptoMutex
Definition: ra6_crypto.c:41
RA6 hardware cryptographic accelerator (SCE7 / SCE9)
error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (regular calculation)
error_t ecMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d, const EcPoint *s)
Scalar multiplication.
error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
RSA decryption primitive.
error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const EcDomainParameters *params, const EcPrivateKey *privateKey, const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
ECDSA signature generation.
error_t ecdsaVerifySignature(const EcDomainParameters *params, const EcPublicKey *publicKey, const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
ECDSA signature verification.
error_t mpiExpModFast(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (fast calculation)
RA6 public-key hardware accelerator.
RSA public-key cryptography standard.
EC domain parameters.
Definition: ec.h:76
const char_t * name
Curve name.
Definition: ec.h:77
Mpi q
Order of the point G.
Definition: ec.h:83
EC point.
Definition: ec.h:64
Mpi y
y-coordinate
Definition: ec.h:66
Mpi x
x-coordinate
Definition: ec.h:65
EC private key.
Definition: ec.h:104
Mpi d
Private key.
Definition: ec.h:105
EC public key.
Definition: ec.h:94
EcPoint q
Public key.
Definition: ec.h:95
ECDSA signature.
Definition: ecdsa.h:49
Arbitrary precision integer.
Definition: mpi.h:80
EC primitive arguments.
uint32_t signature[24]
uint32_t g[24]
uint32_t q[24]
uint32_t digest[12]
uint32_t wrappedKey[100]
uint32_t d[12]
RSA primitive arguments.
uint32_t wrappedKey[300]
uint32_t m[128]
uint32_t c[128]
uint32_t key[256]
RSA private key.
Definition: rsa.h:68
Mpi p
First factor.
Definition: rsa.h:72
Mpi dq
Second factor's CRT exponent.
Definition: rsa.h:75
Mpi q
Second factor.
Definition: rsa.h:73
Mpi d
Private exponent.
Definition: rsa.h:71
Mpi dp
First factor's CRT exponent.
Definition: rsa.h:74
Mpi qinv
CRT coefficient.
Definition: rsa.h:76
Mpi n
Modulus.
Definition: rsa.h:69