s7g2_crypto_pkc.c
Go to the documentation of this file.
1 /**
2  * @file s7g2_crypto_pkc.c
3  * @brief Synergy S7G2 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_rsa_private.h"
37 #include "hw_sce_ecc_private.h"
38 #include "core/crypto.h"
41 #include "pkc/rsa.h"
42 #include "ecc/ec.h"
43 #include "ecc/ecdsa.h"
44 #include "debug.h"
45 
46 //Check crypto library configuration
47 #if (S7G2_CRYPTO_PKC_SUPPORT == ENABLED)
48 
49 //Global variables
50 static Ra6RsaArgs rsaArgs;
51 static Ra6EcArgs ecArgs;
52 
53 
54 /**
55  * @brief Modular exponentiation (fast calculation)
56  * @param[out] r Resulting integer R = A ^ E mod P
57  * @param[in] a Pointer to a multiple precision integer
58  * @param[in] e Exponent
59  * @param[in] p Modulus
60  * @return Error code
61  **/
62 
63 error_t mpiExpModFast(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
64 {
65  error_t error;
66  ssp_err_t status;
67  size_t n;
68  size_t aLen;
69  size_t eLen;
70  size_t pLen;
71 
72  //Retrieve the length of the integer, in bytes
73  aLen = mpiGetByteLength(a);
74  //Retrieve the length of the exponent, in bytes
75  eLen = mpiGetByteLength(e);
76  //Retrieve the length of the modulus, in bytes
77  pLen = mpiGetByteLength(p);
78 
79  //The accelerator supports operand lengths up to 2048 bits
80  if((aLen <= 128 && eLen <= 4 && pLen <= 128) ||
81  (aLen <= 256 && eLen <= 4 && pLen <= 256))
82  {
83  //Select appropriate scalar length
84  n = (pLen <= 128) ? 128 : 256;
85 
86  //Acquire exclusive access to the SCE7 module
88 
89  //Format message representative
90  mpiWriteRaw(a, (uint8_t *) rsaArgs.m, n);
91 
92  //Format public key
93  mpiWriteRaw(p, (uint8_t *) rsaArgs.n, n);
94  mpiWriteRaw(e, (uint8_t *) rsaArgs.e, 4);
95 
96  //Perform RSA encryption
97  if(n == 128)
98  {
99  status = HW_SCE_RSA_1024PublicEncrypt(0, rsaArgs.m, rsaArgs.e,
100  rsaArgs.n, rsaArgs.c);
101  }
102  else if(n == 256)
103  {
104  status = HW_SCE_RSA_2048PublicEncrypt(0, rsaArgs.m, rsaArgs.e,
105  rsaArgs.n, rsaArgs.c);
106  }
107  else
108  {
109  status = SSP_ERR_CRYPTO_NOT_IMPLEMENTED;
110  }
111 
112  //Check status code
113  if(status == SSP_SUCCESS)
114  {
115  //Copy the ciphertext representative
116  error = mpiReadRaw(r, (uint8_t *) rsaArgs.c, n);
117  }
118  else
119  {
120  //Report an error
121  error = ERROR_FAILURE;
122  }
123 
124  //Release exclusive access to the SCE7 module
126  }
127  else
128  {
129  //Perform modular exponentiation (r = a ^ e mod p)
130  error = mpiExpModRegular(r, a, e, p);
131  }
132 
133  //Return status code
134  return error;
135 }
136 
137 
138 /**
139  * @brief Modular exponentiation (regular calculation)
140  * @param[out] r Resulting integer R = A ^ E mod P
141  * @param[in] a Pointer to a multiple precision integer
142  * @param[in] e Exponent
143  * @param[in] p Modulus
144  * @return Error code
145  **/
146 
147 error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
148 {
149  error_t error;
150  ssp_err_t status;
151  size_t n;
152  size_t aLen;
153  size_t eLen;
154  size_t pLen;
155 
156  //Retrieve the length of the integer, in bytes
157  aLen = mpiGetByteLength(a);
158  //Retrieve the length of the exponent, in bytes
159  eLen = mpiGetByteLength(e);
160  //Retrieve the length of the modulus, in bytes
161  pLen = mpiGetByteLength(p);
162 
163  //The accelerator supports operand lengths up to 2048 bits
164  if((aLen <= 128 && eLen <= 128 && pLen <= 128) ||
165  (aLen <= 256 && eLen <= 256 && pLen <= 256))
166  {
167  //Select appropriate scalar length
168  n = (pLen <= 128) ? 128 : 256;
169 
170  //Acquire exclusive access to the SCE7 module
172 
173  //Format ciphertext representative
174  mpiWriteRaw(a, (uint8_t *) rsaArgs.c, n);
175 
176  //Format private key
177  mpiWriteRaw(p, (uint8_t *) rsaArgs.n, n);
178  mpiWriteRaw(e, (uint8_t *) rsaArgs.d, n);
179 
180  //Perform RSA decryption
181  if(n == 128)
182  {
183  status = HW_SCE_RSA_1024PrivateKeyDecrypt(0, rsaArgs.c, rsaArgs.d,
184  rsaArgs.n, rsaArgs.m);
185  }
186  else if(n == 256)
187  {
188  status = HW_SCE_RSA_2048PrivateKeyDecrypt(0, rsaArgs.c, rsaArgs.d,
189  rsaArgs.n, rsaArgs.m);
190  }
191  else
192  {
193  status = SSP_ERR_CRYPTO_NOT_IMPLEMENTED;
194  }
195 
196  //Check status code
197  if(status == SSP_SUCCESS)
198  {
199  //Copy the message representative
200  error = mpiReadRaw(r, (uint8_t *) rsaArgs.m, n);
201  }
202  else
203  {
204  //Report an error
205  error = ERROR_FAILURE;
206  }
207 
208  //Release exclusive access to the SCE7 module
210  }
211  else
212  {
213  //Perform modular exponentiation (r = a ^ e mod p)
214  error = mpiExpMod(r, a, e, p);
215  }
216 
217  //Return status code
218  return error;
219 }
220 
221 
222 /**
223  * @brief RSA private key generation
224  * @param[in] prngAlgo PRNG algorithm
225  * @param[in] prngContext Pointer to the PRNG context
226  * @param[in] k Required bit length of the modulus n (must be 1024 or 2048)
227  * @param[in] e Public exponent (must be 65537)
228  * @param[out] privateKey RSA private key
229  * @return Error code
230  **/
231 
232 error_t rsaGeneratePrivateKey(const PrngAlgo *prngAlgo, void *prngContext,
233  size_t k, uint_t e, RsaPrivateKey *privateKey)
234 {
235  error_t error;
236  ssp_err_t status;
237  size_t n;
238 
239  //Check parameters
240  if(e != 65537 || privateKey == NULL)
242 
243  //Acquire exclusive access to the SCE7 module
245 
246  //Check the length of the modulus
247  if(k == 1024)
248  {
249  //Generate a 1024-bit RSA private key
250  status = HW_SCE_RSA_1024KeyGenerate(UINT32_MAX, rsaArgs.d, rsaArgs.n,
251  rsaArgs.params);
252  }
253  else if(k == 2048)
254  {
255  //Generate a 2048-bit RSA private key
256  status = HW_SCE_RSA_2048KeyGenerate(UINT32_MAX, rsaArgs.d, rsaArgs.n,
257  rsaArgs.params);
258  }
259  else
260  {
261  //Report an error
262  status = SSP_ERR_CRYPTO_NOT_IMPLEMENTED;
263  }
264 
265  //Check status code
266  if(status == SSP_SUCCESS)
267  {
268  //Compute the length of the modulus, in bytes
269  k = k / 8;
270  //Compute the length of the CRT factors, in bytes
271  n = k / 2;
272 
273  //The value of the public exponent is fixed to 65537
274  error = mpiSetValue(&privateKey->e, e);
275 
276  //Check status code
277  if(!error)
278  {
279  //Copy the private exponent
280  error = mpiReadRaw(&privateKey->d, (uint8_t *) rsaArgs.d, k);
281  }
282 
283  //Check status code
284  if(!error)
285  {
286  //Copy the modulus
287  error = mpiReadRaw(&privateKey->n, (uint8_t *) rsaArgs.n, k);
288  }
289 
290  //Check status code
291  if(!error)
292  {
293  //Copy the first factor
294  error = mpiReadRaw(&privateKey->p,
295  (uint8_t *) rsaArgs.params + n * 3, n);
296  }
297 
298  //Check status code
299  if(!error)
300  {
301  //Copy the second factor
302  error = mpiReadRaw(&privateKey->q,
303  (uint8_t *) rsaArgs.params + n, n);
304  }
305 
306  //Check status code
307  if(!error)
308  {
309  //Copy the first factor's CRT exponent
310  error = mpiReadRaw(&privateKey->dp,
311  (uint8_t *) rsaArgs.params + n * 2, n);
312  }
313 
314  //Check status code
315  if(!error)
316  {
317  //Copy the second factor's CRT exponent
318  error = mpiReadRaw(&privateKey->dq,
319  (uint8_t *) rsaArgs.params, n);
320  }
321 
322  //Check status code
323  if(!error)
324  {
325  //Copy the CRT coefficient
326  error = mpiReadRaw(&privateKey->qinv,
327  (uint8_t *) rsaArgs.params + n * 4, n);
328  }
329  }
330  else
331  {
332  //Report an error
333  error = ERROR_FAILURE;
334  }
335 
336  //Release exclusive access to the SCE7 module
338 
339  //Return status code
340  return error;
341 }
342 
343 
344 /**
345  * @brief RSA decryption primitive
346  *
347  * The RSA decryption primitive recovers the message representative from
348  * the ciphertext representative under the control of a private key
349  *
350  * @param[in] key RSA private key
351  * @param[in] c Ciphertext representative
352  * @param[out] m Message representative
353  * @return Error code
354  **/
355 
356 error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
357 {
358  error_t error;
359  size_t n;
360  size_t nLen;
361  size_t dLen;
362  size_t pLen;
363  size_t qLen;
364  size_t dpLen;
365  size_t dqLen;
366  size_t qinvLen;
367 
368  //Retrieve the length of the private key
369  nLen = mpiGetByteLength(&key->n);
370  dLen = mpiGetByteLength(&key->d);
371  pLen = mpiGetByteLength(&key->p);
372  qLen = mpiGetByteLength(&key->q);
373  dpLen = mpiGetByteLength(&key->dp);
374  dqLen = mpiGetByteLength(&key->dq);
375  qinvLen = mpiGetByteLength(&key->qinv);
376 
377  //Sanity check
378  if(nLen == 0)
380 
381  //The ciphertext representative c shall be between 0 and n - 1
382  if(mpiCompInt(c, 0) < 0 || mpiComp(c, &key->n) >= 0)
383  return ERROR_OUT_OF_RANGE;
384 
385  //Check the length of the private key
386  if(nLen <= 128 && dLen <= 128)
387  {
388  //Let m = c ^ d mod n
389  error = mpiExpModRegular(m, c, &key->d, &key->n);
390  }
391  else if(nLen > 0 && pLen > 0 && qLen > 0 && dpLen > 0 && dqLen > 0 &&
392  qinvLen > 0)
393  {
394  Mpi m1;
395  Mpi m2;
396  Mpi h;
397 
398  //Initialize multiple-precision integers
399  mpiInit(&m1);
400  mpiInit(&m2);
401  mpiInit(&h);
402 
403  //Compute m1 = c ^ dP mod p
404  error = mpiMod(&m1, c, &key->p);
405 
406  if(!error)
407  {
408  error = mpiExpModRegular(&m1, &m1, &key->dp, &key->p);
409  }
410 
411  //Compute m2 = c ^ dQ mod q
412  if(!error)
413  {
414  error = mpiMod(&m2, c, &key->q);
415  }
416 
417  if(!error)
418  {
419  error = mpiExpModRegular(&m2, &m2, &key->dq, &key->q);
420  }
421 
422  //Let h = (m1 - m2) * qInv mod p
423  if(!error)
424  {
425  error = mpiSub(&h, &m1, &m2);
426  }
427 
428  if(!error)
429  {
430  error = mpiMulMod(&h, &h, &key->qinv, &key->p);
431  }
432 
433  //Let m = m2 + q * h
434  if(!error)
435  {
436  error = mpiMul(m, &key->q, &h);
437  }
438 
439  if(!error)
440  {
441  error = mpiAdd(m, m, &m2);
442  }
443 
444  //Free previously allocated memory
445  mpiFree(&m1);
446  mpiFree(&m2);
447  mpiFree(&h);
448  }
449  else if(nLen > 0 && dLen > 0)
450  {
451  //Let m = c ^ d mod n
452  error = mpiExpModRegular(m, c, &key->d, &key->n);
453  }
454  else
455  {
456  //Report an error
457  error = ERROR_INVALID_PARAMETER;
458  }
459 
460  //Return status code
461  return error;
462 }
463 
464 
465 /**
466  * @brief Scalar multiplication
467  * @param[in] params EC domain parameters
468  * @param[out] r Resulting point R = d.S
469  * @param[in] d An integer d such as 0 <= d < p
470  * @param[in] s EC point
471  * @return Error code
472  **/
473 
474 error_t ecMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d,
475  const EcPoint *s)
476 {
477  error_t error;
478  ssp_err_t status;
479  size_t n;
480  size_t modLen;
481 
482  //Retrieve the length of the modulus, in bytes
483  modLen = mpiGetByteLength(&params->p);
484 
485  //Compute the length of the scalar
486  if(modLen <= 24)
487  {
488  n = 24;
489  }
490  else if(modLen <= 28)
491  {
492  n = 28;
493  }
494  else if(modLen <= 32)
495  {
496  n = 32;
497  }
498  else if(modLen <= 48)
499  {
500  n = 48;
501  }
502  else
503  {
504  return ERROR_FAILURE;
505  }
506 
507  //Acquire exclusive access to the SCE7 module
509 
510  //Set domain parameters
511  mpiWriteRaw(&params->a, (uint8_t *) ecArgs.params, n);
512  mpiWriteRaw(&params->b, (uint8_t *) ecArgs.params + n, n);
513  mpiWriteRaw(&params->p, (uint8_t *) ecArgs.params + n * 2, n);
514  mpiWriteRaw(&params->q, (uint8_t *) ecArgs.params + n * 3, n);
515 
516  //Set scalar value
517  mpiWriteRaw(d, (uint8_t *) ecArgs.d, n);
518 
519  //Set input point
520  mpiWriteRaw(&s->x, (uint8_t *) ecArgs.g, n);
521  mpiWriteRaw(&s->y, (uint8_t *) ecArgs.g + n, n);
522 
523  //Perform scalar multiplication
524  if(n == 24)
525  {
526  status = HW_SCE_ECC_192ScalarMultiplication(ecArgs.params, ecArgs.d,
527  ecArgs.g, ecArgs.q);
528  }
529  else if(n == 28)
530  {
531  status = HW_SCE_ECC_224ScalarMultiplication(ecArgs.params, ecArgs.d,
532  ecArgs.g, ecArgs.q);
533  }
534  else if(n == 32)
535  {
536  status = HW_SCE_ECC_256ScalarMultiplication(ecArgs.params, ecArgs.d,
537  ecArgs.g, ecArgs.q);
538  }
539  else if(n == 48)
540  {
541  status = HW_SCE_ECC_384ScalarMultiplication(ecArgs.params, ecArgs.d,
542  ecArgs.g, ecArgs.q);
543  }
544  else
545  {
546  status = SSP_ERR_CRYPTO_NOT_IMPLEMENTED;
547  }
548 
549  //Check status code
550  if(status == SSP_SUCCESS)
551  {
552  //Copy the x-coordinate of the result
553  error = mpiReadRaw(&r->x, (uint8_t *) ecArgs.q, n);
554 
555  //Check status code
556  if(!error)
557  {
558  //Copy the y-coordinate of the result
559  error = mpiReadRaw(&r->y, (uint8_t *) ecArgs.q + n, n);
560  }
561 
562  //Check status code
563  if(!error)
564  {
565  //Set the z-coordinate of the result
566  error = mpiSetValue(&r->z, 1);
567  }
568  }
569  else
570  {
571  //Report an error
572  error = ERROR_FAILURE;
573  }
574 
575  //Release exclusive access to the SCE7 module
577 
578  //Return status code
579  return error;
580 }
581 
582 
583 /**
584  * @brief EC key pair generation
585  * @param[in] prngAlgo PRNG algorithm
586  * @param[in] prngContext Pointer to the PRNG context
587  * @param[in] params EC domain parameters
588  * @param[out] privateKey EC private key
589  * @param[out] publicKey EC public key
590  * @return Error code
591  **/
592 
593 error_t ecGenerateKeyPair(const PrngAlgo *prngAlgo, void *prngContext,
594  const EcDomainParameters *params, EcPrivateKey *privateKey,
595  EcPublicKey *publicKey)
596 {
597  error_t error;
598  ssp_err_t status;
599  size_t n;
600  size_t modLen;
601 
602  //Retrieve the length of the modulus, in bytes
603  modLen = mpiGetByteLength(&params->p);
604 
605  //Compute the length of the scalar
606  if(modLen <= 24)
607  {
608  n = 24;
609  }
610  else if(modLen <= 28)
611  {
612  n = 28;
613  }
614  else if(modLen <= 32)
615  {
616  n = 32;
617  }
618  else if(modLen <= 48)
619  {
620  n = 48;
621  }
622  else
623  {
624  return ERROR_FAILURE;
625  }
626 
627  //Acquire exclusive access to the SCE7 module
629 
630  //Set domain parameters
631  mpiWriteRaw(&params->a, (uint8_t *) ecArgs.params, n);
632  mpiWriteRaw(&params->b, (uint8_t *) ecArgs.params + n, n);
633  mpiWriteRaw(&params->p, (uint8_t *) ecArgs.params + n * 2, n);
634  mpiWriteRaw(&params->q, (uint8_t *) ecArgs.params + n * 3, n);
635 
636  //Set base point
637  mpiWriteRaw(&params->g.x, (uint8_t *) ecArgs.g, n);
638  mpiWriteRaw(&params->g.y, (uint8_t *) ecArgs.g + n, n);
639 
640  //Generate an EC key pair
641  if(n == 24)
642  {
643  status = HW_SCE_ECC_192GenerateKey(ecArgs.params, ecArgs.g, ecArgs.d,
644  ecArgs.q);
645  }
646  else if(n == 28)
647  {
648  status = HW_SCE_ECC_224GenerateKey(ecArgs.params, ecArgs.g, ecArgs.d,
649  ecArgs.q);
650  }
651  else if(n == 32)
652  {
653  status = HW_SCE_ECC_256GenerateKey(ecArgs.params, ecArgs.g, ecArgs.d,
654  ecArgs.q);
655  }
656  else if(n == 48)
657  {
658  status = HW_SCE_ECC_384GenerateKey(ecArgs.params, ecArgs.g, ecArgs.d,
659  ecArgs.q);
660  }
661  else
662  {
663  status = SSP_ERR_CRYPTO_NOT_IMPLEMENTED;
664  }
665 
666  //Check status code
667  if(status == SSP_SUCCESS)
668  {
669  //Copy the private key
670  error = mpiReadRaw(&privateKey->d, (uint8_t *) ecArgs.d, n);
671 
672  //Check status code
673  if(!error)
674  {
675  //Copy the x-coordinate of the public key
676  error = mpiReadRaw(&publicKey->q.x, (uint8_t *) ecArgs.q, n);
677  }
678 
679  //Check status code
680  if(!error)
681  {
682  //Copy the y-coordinate of the public key
683  error = mpiReadRaw(&publicKey->q.y, (uint8_t *) ecArgs.q + n, n);
684  }
685  }
686  else
687  {
688  //Report an error
689  error = ERROR_FAILURE;
690  }
691 
692  //Release exclusive access to the SCE7 module
694 
695  //Return status code
696  return error;
697 }
698 
699 
700 /**
701  * @brief ECDSA signature generation
702  * @param[in] prngAlgo PRNG algorithm
703  * @param[in] prngContext Pointer to the PRNG context
704  * @param[in] params EC domain parameters
705  * @param[in] privateKey Signer's EC private key
706  * @param[in] digest Digest of the message to be signed
707  * @param[in] digestLen Length in octets of the digest
708  * @param[out] signature (R, S) integer pair
709  * @return Error code
710  **/
711 
712 error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext,
713  const EcDomainParameters *params, const EcPrivateKey *privateKey,
714  const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
715 {
716  error_t error;
717  ssp_err_t status;
718  size_t n;
719  size_t orderLen;
720  size_t modLen;
721 
722  //Check parameters
723  if(params == NULL || privateKey == NULL || digest == NULL || signature == NULL)
725 
726  //Retrieve the length of the base point order, in bytes
727  orderLen = mpiGetByteLength(&params->q);
728  //Retrieve the length of the modulus, in bytes
729  modLen = mpiGetByteLength(&params->p);
730 
731  //Check elliptic curve parameters
732  if(modLen <= 24)
733  {
734  n = 24;
735  }
736  else if(modLen <= 28)
737  {
738  n = 28;
739  }
740  else if(modLen <= 32)
741  {
742  n = 32;
743  }
744  else if(modLen <= 48)
745  {
746  n = 48;
747  }
748  else
749  {
750  return ERROR_FAILURE;
751  }
752 
753  //Keep the leftmost bits of the hash value
754  digestLen = MIN(digestLen, orderLen);
755 
756  //Acquire exclusive access to the SCE7 module
758 
759  //Pad the digest with leading zeroes if necessary
760  osMemset(ecArgs.digest, 0, n);
761  osMemcpy((uint8_t *) ecArgs.digest + n - digestLen, digest, digestLen);
762 
763  //Set domain parameters
764  mpiWriteRaw(&params->a, (uint8_t *) ecArgs.params, n);
765  mpiWriteRaw(&params->b, (uint8_t *) ecArgs.params + n, n);
766  mpiWriteRaw(&params->p, (uint8_t *) ecArgs.params + n * 2, n);
767  mpiWriteRaw(&params->q, (uint8_t *) ecArgs.params + n * 3, n);
768 
769  //Set base point
770  mpiWriteRaw(&params->g.x, (uint8_t *) ecArgs.g, n);
771  mpiWriteRaw(&params->g.y, (uint8_t *) ecArgs.g + n, n);
772 
773  //Set private key
774  mpiWriteRaw(&privateKey->d, (uint8_t *) ecArgs.d, n);
775 
776  //Generate ECDSA signature
777  if(n == 24)
778  {
779  status = HW_SCE_ECC_192GenerateSign(ecArgs.params, ecArgs.g, ecArgs.d,
780  ecArgs.digest, ecArgs.r, ecArgs.s);
781  }
782  else if(n == 28)
783  {
784  status = HW_SCE_ECC_224GenerateSign(ecArgs.params, ecArgs.g, ecArgs.d,
785  ecArgs.digest, ecArgs.r, ecArgs.s);
786  }
787  else if(n == 32)
788  {
789  status = HW_SCE_ECC_256GenerateSign(ecArgs.params, ecArgs.g, ecArgs.d,
790  ecArgs.digest, ecArgs.r, ecArgs.s);
791  }
792  else if(n == 48)
793  {
794  status = HW_SCE_ECC_384GenerateSign(ecArgs.params, ecArgs.g, ecArgs.d,
795  ecArgs.digest, ecArgs.r, ecArgs.s);
796  }
797  else
798  {
799  status = SSP_ERR_CRYPTO_NOT_IMPLEMENTED;
800  }
801 
802  //Check status code
803  if(status == SSP_SUCCESS)
804  {
805  //Copy integer R
806  error = mpiReadRaw(&signature->r, (uint8_t *) ecArgs.r, n);
807 
808  //Check status code
809  if(!error)
810  {
811  //Copy integer S
812  error = mpiReadRaw(&signature->s, (uint8_t *) ecArgs.s, n);
813  }
814  }
815  else
816  {
817  //Report an error
818  error = ERROR_FAILURE;
819  }
820 
821  //Release exclusive access to the SCE7 module
823 
824  //Return status code
825  return error;
826 }
827 
828 
829 /**
830  * @brief ECDSA signature verification
831  * @param[in] params EC domain parameters
832  * @param[in] publicKey Signer's EC public key
833  * @param[in] digest Digest of the message whose signature is to be verified
834  * @param[in] digestLen Length in octets of the digest
835  * @param[in] signature (R, S) integer pair
836  * @return Error code
837  **/
838 
840  const EcPublicKey *publicKey, const uint8_t *digest, size_t digestLen,
841  const EcdsaSignature *signature)
842 {
843  ssp_err_t status;
844  size_t n;
845  size_t orderLen;
846  size_t modLen;
847 
848  //Check parameters
849  if(params == NULL || publicKey == NULL || digest == NULL || signature == NULL)
851 
852  //The verifier shall check that 0 < r < q
853  if(mpiCompInt(&signature->r, 0) <= 0 ||
854  mpiComp(&signature->r, &params->q) >= 0)
855  {
856  //If the condition is violated, the signature shall be rejected as invalid
858  }
859 
860  //The verifier shall check that 0 < s < q
861  if(mpiCompInt(&signature->s, 0) <= 0 ||
862  mpiComp(&signature->s, &params->q) >= 0)
863  {
864  //If the condition is violated, the signature shall be rejected as invalid
866  }
867 
868  //Retrieve the length of the base point order, in bytes
869  orderLen = mpiGetByteLength(&params->q);
870  //Retrieve the length of the modulus, in bytes
871  modLen = mpiGetByteLength(&params->p);
872 
873  //Check elliptic curve parameters
874  if(modLen <= 24)
875  {
876  n = 24;
877  }
878  else if(modLen <= 28)
879  {
880  n = 28;
881  }
882  else if(modLen <= 32)
883  {
884  n = 32;
885  }
886  else if(modLen <= 48)
887  {
888  n = 48;
889  }
890  else
891  {
892  return ERROR_FAILURE;
893  }
894 
895  //Keep the leftmost bits of the hash value
896  digestLen = MIN(digestLen, orderLen);
897 
898  //Acquire exclusive access to the SCE7 module
900 
901  //Pad the digest with leading zeroes if necessary
902  osMemset(ecArgs.digest, 0, n);
903  osMemcpy((uint8_t *) ecArgs.digest + n - digestLen, digest, digestLen);
904 
905  //Set domain parameters
906  mpiWriteRaw(&params->a, (uint8_t *) ecArgs.params, n);
907  mpiWriteRaw(&params->b, (uint8_t *) ecArgs.params + n, n);
908  mpiWriteRaw(&params->p, (uint8_t *) ecArgs.params + n * 2, n);
909  mpiWriteRaw(&params->q, (uint8_t *) ecArgs.params + n * 3, n);
910 
911  //Set base point
912  mpiWriteRaw(&params->g.x, (uint8_t *) ecArgs.g, n);
913  mpiWriteRaw(&params->g.y, (uint8_t *) ecArgs.g + n, n);
914 
915  //Set public key
916  mpiWriteRaw(&publicKey->q.x, (uint8_t *) ecArgs.q, n);
917  mpiWriteRaw(&publicKey->q.y, (uint8_t *) ecArgs.q + n, n);
918 
919  //Set signature
920  mpiWriteRaw(&signature->r, (uint8_t *) ecArgs.r, n);
921  mpiWriteRaw(&signature->s, (uint8_t *) ecArgs.s, n);
922 
923  //Verify ECDSA signature
924  if(n == 24)
925  {
926  status = HW_SCE_ECC_192VerifySign(ecArgs.params, ecArgs.g, ecArgs.q,
927  ecArgs.digest, ecArgs.r, ecArgs.s);
928  }
929  else if(n == 28)
930  {
931  status = HW_SCE_ECC_224VerifySign(ecArgs.params, ecArgs.g, ecArgs.q,
932  ecArgs.digest, ecArgs.r, ecArgs.s);
933  }
934  else if(n == 32)
935  {
936  status = HW_SCE_ECC_256VerifySign(ecArgs.params, ecArgs.g, ecArgs.q,
937  ecArgs.digest, ecArgs.r, ecArgs.s);
938  }
939  else if(n == 48)
940  {
941  status = HW_SCE_ECC_384VerifySign(ecArgs.params, ecArgs.g, ecArgs.q,
942  ecArgs.digest, ecArgs.r, ecArgs.s);
943  }
944  else
945  {
946  status = SSP_ERR_CRYPTO_NOT_IMPLEMENTED;
947  }
948 
949  //Release exclusive access to the SCE7 module
951 
952  //Return status code
953  return (status == SSP_SUCCESS) ? NO_ERROR : ERROR_INVALID_SIGNATURE;
954 }
955 
956 #endif
unsigned int uint_t
Definition: compiler_port.h:50
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 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.
RSA public-key cryptography standard.
OsMutex s7g2CryptoMutex
Definition: s7g2_crypto.c:41
Synergy S7G2 hardware cryptographic accelerator (SCE7)
error_t ecGenerateKeyPair(const PrngAlgo *prngAlgo, void *prngContext, const EcDomainParameters *params, EcPrivateKey *privateKey, EcPublicKey *publicKey)
EC key pair generation.
error_t rsaGeneratePrivateKey(const PrngAlgo *prngAlgo, void *prngContext, size_t k, uint_t e, RsaPrivateKey *privateKey)
RSA private key generation.
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)
Synergy S7G2 public-key hardware accelerator.
EC domain parameters.
Definition: ec.h:76
Mpi p
Prime.
Definition: ec.h:79
EcPoint g
Base point G.
Definition: ec.h:82
Mpi q
Order of the point G.
Definition: ec.h:83
Mpi a
Curve parameter a.
Definition: ec.h:80
Mpi b
Curve parameter b.
Definition: ec.h:81
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 params[48]
uint32_t g[24]
uint32_t q[24]
uint32_t digest[12]
uint32_t s[12]
uint32_t r[12]
uint32_t d[12]
RSA primitive arguments.
uint32_t d[64]
uint32_t m[128]
uint32_t params[160]
uint32_t c[128]
uint32_t n[64]
uint32_t e[1]
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 e
Public exponent.
Definition: rsa.h:70
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