m460_crypto_pkc.c
Go to the documentation of this file.
1 /**
2  * @file m460_crypto_pkc.c
3  * @brief M460 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.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "m460.h"
36 #include "core/crypto.h"
39 #include "pkc/rsa.h"
40 #include "ecc/ec.h"
41 #include "ecc/curve25519.h"
42 #include "ecc/curve448.h"
43 #include "debug.h"
44 
45 //Check crypto library configuration
46 #if (M460_CRYPTO_PKC_SUPPORT == ENABLED)
47 #if (MPI_SUPPORT == ENABLED)
48 
49 //Global variables
50 static M460RsaArgs rsaArgs;
51 
52 
53 /**
54  * @brief Import multiple-precision integer
55  * @param[in] dest Pointer to the operand
56  * @param[in] length Length of the operand, in bytes
57  * @param[in] a Pointer to the multiple-precision integer
58  **/
59 
60 void rsaImportMpi(uint32_t *dest, uint_t length, const Mpi *a)
61 {
62  uint_t i;
63  uint_t n;
64 
65  //Retrieve the length of the operand, in words
66  length = (length + 3) / 4;
67 
68  //Get the actual length of the multiple-precision integer, in words
69  n = mpiGetLength(a);
70 
71  //Copy the multiple-precision integer to the CRYPTO peripheral
72  for(i = 0; i < n && i < length; i++)
73  {
74  dest[i] = a->data[i];
75  }
76 
77  //Pad the operand with zeroes
78  for(; i < length; i++)
79  {
80  dest[i] = 0;
81  }
82 }
83 
84 
85 /**
86  * @brief Export multiple-precision integer
87  * @param[in] src Pointer to the operand
88  * @param[in] length Length of the operand, in bytes
89  * @param[out] r Pointer to the multiple-precision integer
90  * @return Error code
91  **/
92 
94 {
95  error_t error;
96  uint_t i;
97 
98  //Retrieve the length of the operand, in words
99  length = (length + 3) / 4;
100 
101  //Skip trailing zeroes
102  while(length > 0 && src[length - 1] == 0)
103  {
104  length--;
105  }
106 
107  //Ajust the size of the multiple precision integer
108  error = mpiGrow(r, length);
109 
110  //Check status code
111  if(!error)
112  {
113  //Copy the multiple-precision integer from the PKA RAM
114  for(i = 0; i < length; i++)
115  {
116  r->data[i] = src[i];
117  }
118 
119  //Pad the resulting value with zeroes
120  for(; i < r->size; i++)
121  {
122  r->data[i] = 0;
123  }
124 
125  //Set the sign
126  r->sign = 1;
127  }
128 
129  //Return status code
130  return error;
131 }
132 
133 
134 /**
135  * @brief Modular exponentiation (fast calculation)
136  * @param[out] r Resulting integer R = A ^ E mod P
137  * @param[in] a Pointer to a multiple precision integer
138  * @param[in] e Exponent
139  * @param[in] p Modulus
140  * @return Error code
141  **/
142 
143 error_t mpiExpModFast(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
144 {
145  error_t error;
146  size_t aLen;
147  size_t eLen;
148  size_t pLen;
149 
150  //Retrieve the length of the integer, in bytes
151  aLen = mpiGetByteLength(a);
152  //Retrieve the length of the exponent, in bytes
153  eLen = mpiGetByteLength(e);
154  //Retrieve the length of the modulus, in bytes
155  pLen = mpiGetByteLength(p);
156 
157  //The accelerator supports operand lengths up to 4096 bits
158  if((aLen <= 128 && eLen <= 128 && pLen == 128) ||
159  (aLen <= 256 && eLen <= 256 && pLen == 256) ||
160  (aLen <= 384 && eLen <= 384 && pLen == 384) ||
161  (aLen <= 512 && eLen <= 512 && pLen == 512))
162  {
163  //Acquire exclusive access to the CRYPTO module
165 
166  //Reset CRYPTO controller
167  SYS->IPRST0 |= SYS_IPRST0_CRPTRST_Msk;
168  SYS->IPRST0 &= ~SYS_IPRST0_CRPTRST_Msk;
169 
170  //Copy the operands
171  rsaImportMpi(rsaArgs.m, pLen, a);
172  rsaImportMpi(rsaArgs.n, pLen, p);
173  rsaImportMpi(rsaArgs.e, pLen, e);
174 
175  //Program DMA source address to register CRYPTO_RSA_SADDR0-2
176  CRPT->RSA_SADDR[0] = (uint32_t) rsaArgs.m;
177  CRPT->RSA_SADDR[1] = (uint32_t) rsaArgs.n;
178  CRPT->RSA_SADDR[2] = (uint32_t) rsaArgs.e;
179 
180  //Program DMA destination address to register CRYPTO_RSA_DADDR
181  CRPT->RSA_DADDR = (uint32_t) rsaArgs.r;
182 
183  //Select appropriate key length
184  CRPT->RSA_CTL = (((pLen / 128) - 1) << CRPT_RSA_CTL_KEYLENG_Pos);
185 
186  //Clear RSA interrupt flag
187  CRPT->INTSTS = CRPT_INTSTS_RSAIF_Msk;
188  //Start operation
189  CRPT->RSA_CTL |= CRPT_RSA_CTL_START_Msk;
190 
191  //Wait for the operation to complete
192  while((CRPT->INTSTS & CRPT_INTSTS_RSAIF_Msk) == 0)
193  {
194  }
195 
196  //Read output data
197  rsaExportMpi(rsaArgs.r, pLen, r);
198 
199  //Release exclusive access to the CRYPTO module
201 
202  //Successful operation
203  error = NO_ERROR;
204  }
205  else
206  {
207  //Perform modular exponentiation (r = a ^ e mod p)
208  error = mpiExpMod(r, a, e, p);
209  }
210 
211  //Return status code
212  return error;
213 }
214 
215 
216 /**
217  * @brief Modular exponentiation (regular calculation)
218  * @param[out] r Resulting integer R = A ^ E mod P
219  * @param[in] a Pointer to a multiple precision integer
220  * @param[in] e Exponent
221  * @param[in] p Modulus
222  * @return Error code
223  **/
224 
225 error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
226 {
227  error_t error;
228  size_t aLen;
229  size_t eLen;
230  size_t pLen;
231 
232  //Retrieve the length of the integer, in bytes
233  aLen = mpiGetByteLength(a);
234  //Retrieve the length of the exponent, in bytes
235  eLen = mpiGetByteLength(e);
236  //Retrieve the length of the modulus, in bytes
237  pLen = mpiGetByteLength(p);
238 
239  //The accelerator supports operand lengths up to 4096 bits
240  if((aLen <= 128 && eLen <= 128 && pLen == 128) ||
241  (aLen <= 256 && eLen <= 256 && pLen == 256) ||
242  (aLen <= 384 && eLen <= 384 && pLen == 384) ||
243  (aLen <= 512 && eLen <= 512 && pLen == 512))
244  {
245  //Acquire exclusive access to the CRYPTO module
247 
248  //Reset CRYPTO controller
249  SYS->IPRST0 |= SYS_IPRST0_CRPTRST_Msk;
250  SYS->IPRST0 &= ~SYS_IPRST0_CRPTRST_Msk;
251 
252  //Copy the operands
253  rsaImportMpi(rsaArgs.m, pLen, a);
254  rsaImportMpi(rsaArgs.n, pLen, p);
255  rsaImportMpi(rsaArgs.e, pLen, e);
256 
257  //Program DMA source address to register CRYPTO_RSA_SADDR0-2
258  CRPT->RSA_SADDR[0] = (uint32_t) rsaArgs.m;
259  CRPT->RSA_SADDR[1] = (uint32_t) rsaArgs.n;
260  CRPT->RSA_SADDR[2] = (uint32_t) rsaArgs.e;
261 
262  //Program DMA destination address to register CRYPTO_RSA_DADDR
263  CRPT->RSA_DADDR = (uint32_t) rsaArgs.r;
264 
265  //Select appropriate key length
266  CRPT->RSA_CTL = (((pLen / 128) - 1) << CRPT_RSA_CTL_KEYLENG_Pos);
267 
268  //Clear RSA interrupt flag
269  CRPT->INTSTS = CRPT_INTSTS_RSAIF_Msk;
270  //Start operation
271  CRPT->RSA_CTL |= CRPT_RSA_CTL_START_Msk;
272 
273  //Wait for the operation to complete
274  while((CRPT->INTSTS & CRPT_INTSTS_RSAIF_Msk) == 0)
275  {
276  }
277 
278  //Read output data
279  rsaExportMpi(rsaArgs.r, pLen, r);
280 
281  //Release exclusive access to the CRYPTO module
283 
284  //Successful operation
285  error = NO_ERROR;
286  }
287  else
288  {
289  //Perform modular exponentiation (r = a ^ e mod p)
290  error = mpiExpMod(r, a, e, p);
291  }
292 
293  //Return status code
294  return error;
295 }
296 
297 #endif
298 #if (RSA_SUPPORT == ENABLED)
299 
300 /**
301  * @brief RSA decryption primitive
302  *
303  * The RSA decryption primitive recovers the message representative from
304  * the ciphertext representative under the control of a private key
305  *
306  * @param[in] key RSA private key
307  * @param[in] c Ciphertext representative
308  * @param[out] m Message representative
309  * @return Error code
310  **/
311 
312 error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
313 {
314  error_t error;
315  size_t nLen;
316  size_t dLen;
317  size_t pLen;
318  size_t qLen;
319  size_t dpLen;
320  size_t dqLen;
321  size_t qinvLen;
322 
323  //Retrieve the length of the private key
324  nLen = mpiGetByteLength(&key->n);
325  dLen = mpiGetByteLength(&key->d);
326  pLen = mpiGetByteLength(&key->p);
327  qLen = mpiGetByteLength(&key->q);
328  dpLen = mpiGetByteLength(&key->dp);
329  dqLen = mpiGetByteLength(&key->dq);
330  qinvLen = mpiGetByteLength(&key->qinv);
331 
332  //Sanity check
333  if(nLen == 0)
335 
336  //The ciphertext representative c shall be between 0 and n - 1
337  if(mpiCompInt(c, 0) < 0 || mpiComp(c, &key->n) >= 0)
338  return ERROR_OUT_OF_RANGE;
339 
340  //Check the length of the private key
341  if((nLen == 128 && dLen <= 128) || (nLen == 384 && dLen <= 384))
342  {
343  //Let m = c ^ d mod n
344  error = mpiExpModRegular(m, c, &key->d, &key->n);
345  }
346  else if(nLen > 0 && pLen > 0 && qLen > 0 && dpLen > 0 && dqLen > 0 &&
347  qinvLen > 0)
348  {
349  Mpi m1;
350  Mpi m2;
351  Mpi h;
352 
353  //Initialize multiple-precision integers
354  mpiInit(&m1);
355  mpiInit(&m2);
356  mpiInit(&h);
357 
358  //Compute m1 = c ^ dP mod p
359  error = mpiMod(&m1, c, &key->p);
360 
361  if(!error)
362  {
363  error = mpiExpModRegular(&m1, &m1, &key->dp, &key->p);
364  }
365 
366  //Compute m2 = c ^ dQ mod q
367  if(!error)
368  {
369  error = mpiMod(&m2, c, &key->q);
370  }
371 
372  if(!error)
373  {
374  error = mpiExpModRegular(&m2, &m2, &key->dq, &key->q);
375  }
376 
377  //Let h = (m1 - m2) * qInv mod p
378  if(!error)
379  {
380  error = mpiSub(&h, &m1, &m2);
381  }
382 
383  if(!error)
384  {
385  error = mpiMulMod(&h, &h, &key->qinv, &key->p);
386  }
387 
388  //Let m = m2 + q * h
389  if(!error)
390  {
391  error = mpiMul(m, &key->q, &h);
392  }
393 
394  if(!error)
395  {
396  error = mpiAdd(m, m, &m2);
397  }
398 
399  //Free previously allocated memory
400  mpiFree(&m1);
401  mpiFree(&m2);
402  mpiFree(&h);
403  }
404  else if(nLen > 0 && dLen > 0)
405  {
406  //Let m = c ^ d mod n
407  error = mpiExpModRegular(m, c, &key->d, &key->n);
408  }
409  else
410  {
411  //Report an error
412  error = ERROR_INVALID_PARAMETER;
413  }
414 
415  //Return status code
416  return error;
417 }
418 
419 #endif
420 #if (EC_SUPPORT == ENABLED)
421 
422 /**
423  * @brief Import multiple-precision integer
424  * @param[in] dest Pointer to the operand
425  * @param[in] length Length of the operand, in bits
426  * @param[in] a Pointer to the multiple-precision integer
427  **/
428 
429 void eccImportMpi(volatile uint32_t *dest, uint_t length, const Mpi *a)
430 {
431  uint_t i;
432  uint_t n;
433 
434  //Retrieve the length of the operand, in words
435  length = (length + 31) / 32;
436 
437  //Get the actual length of the multiple-precision integer, in words
438  n = mpiGetLength(a);
439 
440  //Copy the multiple-precision integer to the CRYPTO peripheral
441  for(i = 0; i < n && i < length; i++)
442  {
443  dest[i] = a->data[i];
444  }
445 
446  //Pad the operand with zeroes
447  for(; i < length; i++)
448  {
449  dest[i] = 0;
450  }
451 }
452 
453 
454 /**
455  * @brief Export multiple-precision integer
456  * @param[in] src Pointer to the operand
457  * @param[in] length Length of the operand, in bits
458  * @param[out] r Pointer to the multiple-precision integer
459  * @return Error code
460  **/
461 
462 error_t eccExportMpi(volatile uint32_t *src, uint_t length, Mpi *r)
463 {
464  error_t error;
465  uint_t i;
466 
467  //Retrieve the length of the operand, in words
468  length = (length + 31) / 32;
469 
470  //Skip trailing zeroes
471  while(length > 0 && src[length - 1] == 0)
472  {
473  length--;
474  }
475 
476  //Ajust the size of the multiple precision integer
477  error = mpiGrow(r, length);
478 
479  //Check status code
480  if(!error)
481  {
482  //Copy the multiple-precision integer from the PKA RAM
483  for(i = 0; i < length; i++)
484  {
485  r->data[i] = src[i];
486  }
487 
488  //Pad the resulting value with zeroes
489  for(; i < r->size; i++)
490  {
491  r->data[i] = 0;
492  }
493 
494  //Set the sign
495  r->sign = 1;
496  }
497 
498  //Return status code
499  return error;
500 }
501 
502 
503 /**
504  * @brief Scalar multiplication
505  * @param[in] params EC domain parameters
506  * @param[out] r Resulting point R = d.S
507  * @param[in] d An integer d such as 0 <= d < p
508  * @param[in] s EC point
509  * @return Error code
510  **/
511 
512 error_t ecMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d,
513  const EcPoint *s)
514 {
515  error_t error;
516  uint_t modLen;
517  uint_t scalarLen;
518 
519  //Retrieve the length of the modulus, in bits
520  modLen = mpiGetBitLength(&params->p);
521  //Retrieve the length of the scalar, in bits
522  scalarLen = mpiGetBitLength(d);
523 
524  //Check the length of the operands
525  if(modLen <= 576 && scalarLen <= 576)
526  {
527  //Acquire exclusive access to the CRYPTO module
529 
530  //Reset CRYPTO controller
531  SYS->IPRST0 |= SYS_IPRST0_CRPTRST_Msk;
532  SYS->IPRST0 &= ~SYS_IPRST0_CRPTRST_Msk;
533 
534  //Load input arguments
535  eccImportMpi(CRPT->ECC_N, modLen, &params->p);
536  eccImportMpi(CRPT->ECC_A, modLen, &params->a);
537  eccImportMpi(CRPT->ECC_B, modLen, &params->b);
538  eccImportMpi(CRPT->ECC_K, scalarLen, d);
539  eccImportMpi(CRPT->ECC_X1, modLen, &s->x);
540  eccImportMpi(CRPT->ECC_Y1, modLen, &s->y);
541  eccImportMpi(CRPT->ECC_X2, modLen, &params->q);
542 
543  //Set up a point multiplication operation
544  CRPT->ECC_CTL = (modLen << CRPT_ECC_CTL_CURVEM_Pos) |
545  CRPT_ECC_CTL_SCAP_Msk | (0 << CRPT_ECC_CTL_ECCOP_Pos) |
546  CRPT_ECC_CTL_FSEL_Msk;
547 
548  //Clear ECC interrupt flag
549  CRPT->INTSTS = CRPT_INTSTS_ECCIF_Msk;
550  //Start operation
551  CRPT->ECC_CTL |= CRPT_ECC_CTL_START_Msk;
552 
553  //Wait for the operation to complete
554  while((CRPT->INTSTS & CRPT_INTSTS_ECCIF_Msk) == 0)
555  {
556  }
557 
558  //Copy the x-coordinate of the result
559  error = eccExportMpi(CRPT->ECC_X1, modLen, &r->x);
560 
561  //Check status code
562  if(!error)
563  {
564  //Copy the y-coordinate of the result
565  error = eccExportMpi(CRPT->ECC_Y1, modLen, &r->y);
566  }
567 
568  //Check status code
569  if(!error)
570  {
571  //Set the z-coordinate of the result
572  error = mpiSetValue(&r->z, 1);
573  }
574 
575  //Release exclusive access to the CRYPTO module
577  }
578  else
579  {
580  //Report an error
581  error = ERROR_FAILURE;
582  }
583 
584  //Return status code
585  return error;
586 }
587 
588 
589 /**
590  * @brief Twin multiplication
591  * @param[in] params EC domain parameters
592  * @param[out] r Resulting point R = d0.S + d1.T
593  * @param[in] d0 An integer d such as 0 <= d0 < p
594  * @param[in] s EC point
595  * @param[in] d1 An integer d such as 0 <= d1 < p
596  * @param[in] t EC point
597  * @return Error code
598  **/
599 
601  const Mpi *d0, const EcPoint *s, const Mpi *d1, const EcPoint *t)
602 {
603  error_t error;
604  EcPoint u;
605 
606  //Initialize EC point
607  ecInit(&u);
608 
609  //Compute d0.S
610  error = ecMult(params, r, d0, s);
611 
612  //Check status code
613  if(!error)
614  {
615  //Compute d1.T
616  error = ecMult(params, &u, d1, t);
617  }
618 
619  //Check status code
620  if(!error)
621  {
622  //Compute d0.S + d1.T
623  error = ecAdd(params, r, r, &u);
624  }
625 
626  //Release EC point
627  ecFree(&u);
628 
629  //Return status code
630  return error;
631 }
632 
633 #endif
634 #if (X25519_SUPPORT == ENABLED || ED25519_SUPPORT == ENABLED)
635 
636 /**
637  * @brief Modular multiplication
638  * @param[out] r Resulting integer R = (A * B) mod p
639  * @param[in] a An integer such as 0 <= A < p
640  * @param[in] b An integer such as 0 <= B < p
641  **/
642 
643 void curve25519Mul(uint32_t *r, const uint32_t *a, const uint32_t *b)
644 {
645  //Acquire exclusive access to the CRYPTO module
647 
648  //Reset CRYPTO controller
649  SYS->IPRST0 |= SYS_IPRST0_CRPTRST_Msk;
650  SYS->IPRST0 &= ~SYS_IPRST0_CRPTRST_Msk;
651 
652  //Copy the first operand
653  CRPT->ECC_X1[0] = a[0];
654  CRPT->ECC_X1[1] = a[1];
655  CRPT->ECC_X1[2] = a[2];
656  CRPT->ECC_X1[3] = a[3];
657  CRPT->ECC_X1[4] = a[4];
658  CRPT->ECC_X1[5] = a[5];
659  CRPT->ECC_X1[6] = a[6];
660  CRPT->ECC_X1[7] = a[7];
661 
662  //Copy the second operand
663  CRPT->ECC_Y1[0] = b[0];
664  CRPT->ECC_Y1[1] = b[1];
665  CRPT->ECC_Y1[2] = b[2];
666  CRPT->ECC_Y1[3] = b[3];
667  CRPT->ECC_Y1[4] = b[4];
668  CRPT->ECC_Y1[5] = b[5];
669  CRPT->ECC_Y1[6] = b[6];
670  CRPT->ECC_Y1[7] = b[7];
671 
672  //Copy the modulus
673  CRPT->ECC_N[0] = 0xFFFFFFED;
674  CRPT->ECC_N[1] = 0xFFFFFFFF;
675  CRPT->ECC_N[2] = 0xFFFFFFFF;
676  CRPT->ECC_N[3] = 0xFFFFFFFF;
677  CRPT->ECC_N[4] = 0xFFFFFFFF;
678  CRPT->ECC_N[5] = 0xFFFFFFFF;
679  CRPT->ECC_N[6] = 0xFFFFFFFF;
680  CRPT->ECC_N[7] = 0x7FFFFFFF;
681 
682  //Set up a modular multiplication operation
683  CRPT->ECC_CTL = (255 << CRPT_ECC_CTL_CURVEM_Pos) | CRPT_ECC_CTL_SCAP_Msk |
684  (1 << CRPT_ECC_CTL_MODOP_Pos) | (1 << CRPT_ECC_CTL_ECCOP_Pos) |
685  CRPT_ECC_CTL_FSEL_Msk;
686 
687  //Clear ECC interrupt flag
688  CRPT->INTSTS = CRPT_INTSTS_ECCIF_Msk;
689  //Start operation
690  CRPT->ECC_CTL |= CRPT_ECC_CTL_START_Msk;
691 
692  //Wait for the operation to complete
693  while((CRPT->INTSTS & CRPT_INTSTS_ECCIF_Msk) == 0)
694  {
695  }
696 
697  //Copy the result
698  r[0] = CRPT->ECC_X1[0];
699  r[1] = CRPT->ECC_X1[1];
700  r[2] = CRPT->ECC_X1[2];
701  r[3] = CRPT->ECC_X1[3];
702  r[4] = CRPT->ECC_X1[4];
703  r[5] = CRPT->ECC_X1[5];
704  r[6] = CRPT->ECC_X1[6];
705  r[7] = CRPT->ECC_X1[7];
706 
707  //Release exclusive access to the CRYPTO module
709 }
710 
711 #endif
712 #if (X448_SUPPORT == ENABLED || ED448_SUPPORT == ENABLED)
713 
714 /**
715  * @brief Modular multiplication
716  * @param[out] r Resulting integer R = (A * B) mod p
717  * @param[in] a An integer such as 0 <= A < p
718  * @param[in] b An integer such as 0 <= B < p
719  **/
720 
721 void curve448Mul(uint32_t *r, const uint32_t *a, const uint32_t *b)
722 {
723  //Acquire exclusive access to the CRYPTO module
725 
726  //Reset CRYPTO controller
727  SYS->IPRST0 |= SYS_IPRST0_CRPTRST_Msk;
728  SYS->IPRST0 &= ~SYS_IPRST0_CRPTRST_Msk;
729 
730  //Copy the first operand
731  CRPT->ECC_X1[0] = a[0];
732  CRPT->ECC_X1[1] = a[1];
733  CRPT->ECC_X1[2] = a[2];
734  CRPT->ECC_X1[3] = a[3];
735  CRPT->ECC_X1[4] = a[4];
736  CRPT->ECC_X1[5] = a[5];
737  CRPT->ECC_X1[6] = a[6];
738  CRPT->ECC_X1[7] = a[7];
739  CRPT->ECC_X1[8] = a[8];
740  CRPT->ECC_X1[9] = a[9];
741  CRPT->ECC_X1[10] = a[10];
742  CRPT->ECC_X1[11] = a[11];
743  CRPT->ECC_X1[12] = a[12];
744  CRPT->ECC_X1[13] = a[13];
745 
746  //Copy the second operand
747  CRPT->ECC_Y1[0] = b[0];
748  CRPT->ECC_Y1[1] = b[1];
749  CRPT->ECC_Y1[2] = b[2];
750  CRPT->ECC_Y1[3] = b[3];
751  CRPT->ECC_Y1[4] = b[4];
752  CRPT->ECC_Y1[5] = b[5];
753  CRPT->ECC_Y1[6] = b[6];
754  CRPT->ECC_Y1[7] = b[7];
755  CRPT->ECC_Y1[8] = b[8];
756  CRPT->ECC_Y1[9] = b[9];
757  CRPT->ECC_Y1[10] = b[10];
758  CRPT->ECC_Y1[11] = b[11];
759  CRPT->ECC_Y1[12] = b[12];
760  CRPT->ECC_Y1[13] = b[13];
761 
762  //Copy the modulus
763  CRPT->ECC_N[0] = 0xFFFFFFFF;
764  CRPT->ECC_N[1] = 0xFFFFFFFF;
765  CRPT->ECC_N[2] = 0xFFFFFFFF;
766  CRPT->ECC_N[3] = 0xFFFFFFFF;
767  CRPT->ECC_N[4] = 0xFFFFFFFF;
768  CRPT->ECC_N[5] = 0xFFFFFFFF;
769  CRPT->ECC_N[6] = 0xFFFFFFFF;
770  CRPT->ECC_N[7] = 0xFFFFFFFE;
771  CRPT->ECC_N[8] = 0xFFFFFFFF;
772  CRPT->ECC_N[9] = 0xFFFFFFFF;
773  CRPT->ECC_N[10] = 0xFFFFFFFF;
774  CRPT->ECC_N[11] = 0xFFFFFFFF;
775  CRPT->ECC_N[12] = 0xFFFFFFFF;
776  CRPT->ECC_N[13] = 0xFFFFFFFF;
777 
778  //Set up a modular multiplication operation
779  CRPT->ECC_CTL = (448 << CRPT_ECC_CTL_CURVEM_Pos) | CRPT_ECC_CTL_SCAP_Msk |
780  (1 << CRPT_ECC_CTL_MODOP_Pos) | (1 << CRPT_ECC_CTL_ECCOP_Pos) |
781  CRPT_ECC_CTL_FSEL_Msk;
782 
783  //Clear ECC interrupt flag
784  CRPT->INTSTS = CRPT_INTSTS_ECCIF_Msk;
785  //Start operation
786  CRPT->ECC_CTL |= CRPT_ECC_CTL_START_Msk;
787 
788  //Wait for the operation to complete
789  while((CRPT->INTSTS & CRPT_INTSTS_ECCIF_Msk) == 0)
790  {
791  }
792 
793  //Copy the result
794  r[0] = CRPT->ECC_X1[0];
795  r[1] = CRPT->ECC_X1[1];
796  r[2] = CRPT->ECC_X1[2];
797  r[3] = CRPT->ECC_X1[3];
798  r[4] = CRPT->ECC_X1[4];
799  r[5] = CRPT->ECC_X1[5];
800  r[6] = CRPT->ECC_X1[6];
801  r[7] = CRPT->ECC_X1[7];
802  r[8] = CRPT->ECC_X1[8];
803  r[9] = CRPT->ECC_X1[9];
804  r[10] = CRPT->ECC_X1[10];
805  r[11] = CRPT->ECC_X1[11];
806  r[12] = CRPT->ECC_X1[12];
807  r[13] = CRPT->ECC_X1[13];
808 
809  //Release exclusive access to the CRYPTO module
811 }
812 
813 #endif
814 #endif
Curve448 elliptic curve (constant-time implementation)
uint8_t b
Definition: nbns_common.h:104
@ ERROR_OUT_OF_RANGE
Definition: error.h:137
Mpi p
Prime.
Definition: ec.h:79
Mpi p
First factor.
Definition: rsa.h:72
uint8_t a
Definition: ndp.h:411
Arbitrary precision integer.
Definition: mpi.h:80
uint32_t m[128]
uint8_t p
Definition: ndp.h:300
uint8_t t
Definition: lldp_ext_med.h:212
error_t eccExportMpi(volatile uint32_t *src, uint_t length, Mpi *r)
Export multiple-precision integer.
void curve25519Mul(uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular multiplication.
Mpi n
Modulus.
Definition: rsa.h:69
error_t mpiSetValue(Mpi *r, int_t a)
Set the value of a multiple precision integer.
Definition: mpi.c:484
error_t ecAdd(const EcDomainParameters *params, EcPoint *r, const EcPoint *s, const EcPoint *t)
Point addition (helper routine)
Definition: ec.c:739
EC domain parameters.
Definition: ec.h:76
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:48
Mpi d
Private exponent.
Definition: rsa.h:71
Mpi a
Curve parameter a.
Definition: ec.h:80
uint8_t r
Definition: ndp.h:346
error_t mpiMod(Mpi *r, const Mpi *a, const Mpi *p)
Modulo operation.
Definition: mpi.c:1444
error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision multiplication.
error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
RSA decryption primitive.
uint8_t h
Definition: ndp.h:302
void eccImportMpi(volatile uint32_t *dest, uint_t length, const Mpi *a)
Import multiple-precision integer.
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t mpiSub(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision subtraction.
Definition: mpi.c:864
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:787
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
error_t mpiExpModFast(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (fast calculation)
Mpi q
Second factor.
Definition: rsa.h:73
void ecInit(EcPoint *r)
Initialize elliptic curve point.
Definition: ec.c:307
void rsaImportMpi(uint32_t *dest, uint_t length, const Mpi *a)
Import multiple-precision integer.
uint32_t e[128]
General definitions for cryptographic algorithms.
RSA public-key cryptography standard.
error_t rsaExportMpi(uint32_t *src, uint_t length, Mpi *r)
Export multiple-precision integer.
uint32_t r[128]
uint8_t u
Definition: lldp_ext_med.h:213
EC point.
Definition: ec.h:64
error_t ecTwinMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d0, const EcPoint *s, const Mpi *d1, const EcPoint *t)
Twin multiplication.
error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (regular calculation)
uint8_t length
Definition: tcp.h:368
error_t ecMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d, const EcPoint *s)
Scalar multiplication.
RSA primitive arguments.
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:234
Mpi qinv
CRT coefficient.
Definition: rsa.h:76
Mpi dq
Second factor's CRT exponent.
Definition: rsa.h:75
uint_t mpiGetLength(const Mpi *a)
Get the actual length in words.
Definition: mpi.c:168
uint32_t n[128]
uint8_t m
Definition: ndp.h:304
uint8_t n
RSA private key.
Definition: rsa.h:68
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
M460 hardware cryptographic accelerator.
Curve25519 elliptic curve (constant-time implementation)
uint8_t s
Definition: igmp_common.h:234
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:338
Mpi dp
First factor's CRT exponent.
Definition: rsa.h:74
Mpi b
Curve parameter b.
Definition: ec.h:81
unsigned int uint_t
Definition: compiler_port.h:50
error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular multiplication.
void ecFree(EcPoint *r)
Release an elliptic curve point.
Definition: ec.c:321
ECC (Elliptic Curve Cryptography)
int_t mpiCompInt(const Mpi *a, int_t b)
Compare a multiple precision integer with an integer.
Definition: mpi.c:382
error_t mpiGrow(Mpi *r, uint_t size)
Adjust the size of multiple precision integer.
Definition: mpi.c:94
OsMutex m460CryptoMutex
Definition: m460_crypto.c:42
void curve448Mul(uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular multiplication.
Mpi q
Order of the point G.
Definition: ec.h:83
error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation.
@ NO_ERROR
Success.
Definition: error.h:44
uint8_t c
Definition: ndp.h:514
Debugging facilities.
M460 public-key hardware accelerator.
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