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