stm32wlxx_crypto_pkc.c
Go to the documentation of this file.
1 /**
2  * @file stm32wlxx_crypto_pkc.c
3  * @brief STM32WL public-key hardware accelerator (PKA)
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 "stm32wlxx.h"
36 #include "stm32wlxx_hal.h"
37 #include "core/crypto.h"
40 #include "pkc/rsa.h"
41 #include "ecc/ec.h"
42 #include "ecc/ecdsa.h"
43 #include "ecc/curve25519.h"
44 #include "ecc/curve448.h"
45 #include "debug.h"
46 
47 //Check crypto library configuration
48 #if (STM32WLXX_CRYPTO_PKC_SUPPORT == ENABLED)
49 
50 
51 /**
52  * @brief PKA module initialization
53  * @return Error code
54  **/
55 
57 {
58  //Enable PKA peripheral clock
59  __HAL_RCC_PKA_CLK_ENABLE();
60 
61  //Reset the PKA peripheral
62  PKA->CR = 0;
63 
64  //Enable the PKA peripheral
65  while((PKA->CR & PKA_CR_EN) == 0)
66  {
67  PKA->CR = PKA_CR_EN;
68  }
69 
70  //Clear flags
71  PKA->CLRFR = PKA_CLRFR_ADDRERRFC | PKA_CLRFR_RAMERRFC | PKA_CLRFR_PROCENDFC;
72 
73  //Successful processing
74  return NO_ERROR;
75 }
76 
77 
78 /**
79  * @brief Import byte array
80  * @param[in] src Pointer to the byte array
81  * @param[in] srcLen Length of the array to be copied, in bytes
82  * @param[in] destLen Length of the operand, in bits
83  * @param[in] offset PKA ram offset
84  **/
85 
86 void pkaImportArray(const uint8_t *src, size_t srcLen, uint_t destLen,
87  uint_t offset)
88 {
89  uint_t i;
90  uint_t j;
91  uint32_t temp;
92 
93  //Retrieve the length of the operand, in words
94  destLen = (destLen + 31) / 32;
95 
96  //Copy the array to the PKA RAM
97  for(i = 0, j = 0; i < srcLen; i++)
98  {
99  switch(i % 4)
100  {
101  case 0:
102  temp = src[srcLen - i - 1];
103  break;
104  case 1:
105  temp |= src[srcLen - i - 1] << 8;
106  break;
107  case 2:
108  temp |= src[srcLen - i - 1] << 16;
109  break;
110  default:
111  temp |= src[srcLen - i - 1] << 24;
112  PKA->RAM[offset + j] = temp;
113  j++;
114  break;
115  }
116  }
117 
118  //Pad the operand with zeroes
119  for(; i < (destLen * 4); i++)
120  {
121  switch(i % 4)
122  {
123  case 0:
124  temp = 0;
125  break;
126  case 3:
127  PKA->RAM[offset + j] = temp;
128  j++;
129  break;
130  default:
131  break;
132  }
133  }
134 
135  //An additional word with all bits equal to zero must be added
136  PKA->RAM[offset + j] = 0;
137 }
138 
139 
140 /**
141  * @brief Import multiple-precision integer
142  * @param[in] a Pointer to the multiple-precision integer
143  * @param[in] length Length of the operand, in bits
144  * @param[in] offset PKA ram offset
145  **/
146 
147 void pkaImportMpi(const Mpi *a, uint_t length, uint_t offset)
148 {
149  uint_t i;
150  uint_t n;
151 
152  //Retrieve the length of the operand, in words
153  length = (length + 31) / 32;
154 
155  //Get the actual length of the multiple-precision integer, in words
156  n = mpiGetLength(a);
157 
158  //Copy the multiple-precision integer to the PKA RAM
159  for(i = 0; i < n && i < length; i++)
160  {
161  PKA->RAM[offset + i] = a->data[i];
162  }
163 
164  //Pad the operand with zeroes
165  for(; i < length; i++)
166  {
167  PKA->RAM[offset + i] = 0;
168  }
169 
170  //An additional word with all bits equal to zero must be added
171  PKA->RAM[offset + i] = 0;
172 }
173 
174 
175 /**
176  * @brief Export multiple-precision integer
177  * @param[out] r Pointer to the multiple-precision integer
178  * @param[in] length Length of the operand, in bits
179  * @param[in] offset PKA ram offset
180  * @return Error code
181  **/
182 
184 {
185  error_t error;
186  uint_t i;
187 
188  //Retrieve the length of the operand, in words
189  length = (length + 31) / 32;
190 
191  //Skip trailing zeroes
192  while(length > 0 && PKA->RAM[offset + length - 1] == 0)
193  {
194  length--;
195  }
196 
197  //Ajust the size of the multiple precision integer
198  error = mpiGrow(r, length);
199 
200  //Check status code
201  if(!error)
202  {
203  //Copy the multiple-precision integer from the PKA RAM
204  for(i = 0; i < length; i++)
205  {
206  r->data[i] = PKA->RAM[offset + i];
207  }
208 
209  //Pad the resulting value with zeroes
210  for(; i < r->size; i++)
211  {
212  r->data[i] = 0;
213  }
214 
215  //Set the sign
216  r->sign = 1;
217  }
218 
219  //Return status code
220  return error;
221 }
222 
223 
224 /**
225  * @brief Modular exponentiation
226  * @param[out] r Resulting integer R = A ^ E mod P
227  * @param[in] a Pointer to a multiple precision integer
228  * @param[in] e Exponent
229  * @param[in] p Modulus
230  * @return Error code
231  **/
232 
233 error_t pkaModExp(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
234 {
235  error_t error;
236  uint_t modLen;
237  uint_t expLen;
238  uint32_t temp;
239 
240  //Retrieve the length of the modulus, in bits
241  modLen = mpiGetBitLength(p);
242  //Retrieve the length of the exponent, in bits
243  expLen = mpiGetBitLength(e);
244 
245  //Check the length of the operands
246  if(modLen <= PKA_MAX_ROS && expLen <= PKA_MAX_ROS)
247  {
248  //Reduce the operand first
249  error = mpiMod(r, a, p);
250 
251  //Check status code
252  if(!error)
253  {
254  //Acquire exclusive access to the PKA module
256 
257  //Specify the length of the operand, in bits
258  PKA->RAM[PKA_MODULAR_EXP_IN_OP_NB_BITS] = modLen;
259  //Specify the length of the exponent, in bits
260  PKA->RAM[PKA_MODULAR_EXP_IN_EXP_NB_BITS] = expLen;
261 
262  //Load input arguments into the PKA internal RAM
263  pkaImportMpi(r, modLen, PKA_MODULAR_EXP_IN_EXPONENT_BASE);
264  pkaImportMpi(e, expLen, PKA_MODULAR_EXP_IN_EXPONENT);
265  pkaImportMpi(p, modLen, PKA_MODULAR_EXP_IN_MODULUS);
266 
267  //Disable interrupts
268  PKA->CR &= ~(PKA_CR_ADDRERRIE | PKA_CR_RAMERRIE | PKA_CR_PROCENDIE);
269 
270  //Write in the MODE field of PKA_CR register, specifying the operation
271  //which is to be executed
272  temp = PKA->CR & ~PKA_CR_MODE;
273  PKA->CR = temp | (PKA_CR_MODE_MODULAR_EXP << PKA_CR_MODE_Pos);
274 
275  //Then assert the START bit in PKA_CR register
276  PKA->CR |= PKA_CR_START;
277 
278  //Wait until the PROCENDF bit in the PKA_SR register is set to 1,
279  //indicating that the computation is complete
280  while((PKA->SR & PKA_SR_PROCENDF) == 0)
281  {
282  }
283 
284  //Read the result data from the PKA internal RAM
285  error = pkaExportMpi(r, modLen, PKA_MODULAR_EXP_OUT_SM_ALGO_ACC1);
286 
287  //Then clear PROCENDF bit by setting PROCENDFC bit in PKA_CLRFR
288  PKA->CLRFR = PKA_CLRFR_PROCENDFC;
289 
290  //Release exclusive access to the PKA module
292  }
293  }
294  else
295  {
296  //Perform modular exponentiation
297  error = mpiExpMod(r, a, e, p);
298  }
299 
300  //Return status code
301  return error;
302 }
303 
304 
305 /**
306  * @brief Modular exponentiation with CRT
307  * @param[in] key RSA public key
308  * @param[in] m Message representative
309  * @param[out] c Ciphertext representative
310  * @return Error code
311  **/
312 
313 error_t pkaRsaCrtExp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
314 {
315  error_t error;
316  uint_t nLen;
317  uint_t pLen;
318  uint_t qLen;
319  uint_t dpLen;
320  uint_t dqLen;
321  uint_t qinvLen;
322  uint32_t temp;
323 
324  //Retrieve the length of the private key
325  nLen = mpiGetBitLength(&key->n);
326  pLen = mpiGetBitLength(&key->p);
327  qLen = mpiGetBitLength(&key->q);
328  dpLen = mpiGetBitLength(&key->dp);
329  dqLen = mpiGetBitLength(&key->dq);
330  qinvLen = mpiGetBitLength(&key->qinv);
331 
332  //Check the length of the operands
333  if(nLen <= PKA_MAX_ROS && pLen <= (nLen / 2) && qLen <= (nLen / 2) &&
334  dpLen <= (nLen / 2) && dqLen <= (nLen / 2) && qinvLen <= (nLen / 2))
335  {
336  //Acquire exclusive access to the PKA module
338 
339  //Specify the length of the operand, in bits
340  PKA->RAM[PKA_RSA_CRT_EXP_IN_MOD_NB_BITS] = nLen;
341 
342  //Load input arguments into the PKA internal RAM
343  pkaImportMpi(&key->p, nLen / 2, PKA_RSA_CRT_EXP_IN_PRIME_P);
344  pkaImportMpi(&key->q, nLen / 2, PKA_RSA_CRT_EXP_IN_PRIME_Q);
345  pkaImportMpi(&key->dp, nLen / 2, PKA_RSA_CRT_EXP_IN_DP_CRT);
346  pkaImportMpi(&key->dq, nLen / 2, PKA_RSA_CRT_EXP_IN_DQ_CRT);
347  pkaImportMpi(&key->qinv, nLen / 2, PKA_RSA_CRT_EXP_IN_QINV_CRT);
348  pkaImportMpi(c, nLen, PKA_RSA_CRT_EXP_IN_EXPONENT_BASE);
349 
350  //Disable interrupts
351  PKA->CR &= ~(PKA_CR_ADDRERRIE | PKA_CR_RAMERRIE | PKA_CR_PROCENDIE);
352 
353  //Write in the MODE field of PKA_CR register, specifying the operation
354  //which is to be executed
355  temp = PKA->CR & ~PKA_CR_MODE;
356  PKA->CR = temp | (PKA_CR_MODE_RSA_CRT_EXP << PKA_CR_MODE_Pos);
357 
358  //Then assert the START bit in PKA_CR register
359  PKA->CR |= PKA_CR_START;
360 
361  //Wait until the PROCENDF bit in the PKA_SR register is set to 1,
362  //indicating that the computation is complete
363  while((PKA->SR & PKA_SR_PROCENDF) == 0)
364  {
365  }
366 
367  //Read the result data from the PKA internal RAM
368  error = pkaExportMpi(m, nLen, PKA_RSA_CRT_EXP_OUT_RESULT);
369 
370  //Then clear PROCENDF bit by setting PROCENDFC bit in PKA_CLRFR
371  PKA->CLRFR = PKA_CLRFR_PROCENDFC;
372 
373  //Release exclusive access to the PKA module
375  }
376  else
377  {
378  Mpi m1;
379  Mpi m2;
380  Mpi h;
381 
382  //Initialize multiple-precision integers
383  mpiInit(&m1);
384  mpiInit(&m2);
385  mpiInit(&h);
386 
387  //Compute m1 = c ^ dP mod p
388  error = pkaModExp(&m1, c, &key->dp, &key->p);
389 
390  //Check status code
391  if(!error)
392  {
393  //Compute m2 = c ^ dQ mod q
394  error = pkaModExp(&m2, c, &key->dq, &key->q);
395  }
396 
397  //Check status code
398  if(!error)
399  {
400  //Let h = (m1 - m2) * qInv mod p
401  error = mpiSub(&h, &m1, &m2);
402  }
403 
404  //Check status code
405  if(!error)
406  {
407  error = mpiMulMod(&h, &h, &key->qinv, &key->p);
408  }
409 
410  //Check status code
411  if(!error)
412  {
413  //Let m = m2 + q * h
414  error = mpiMul(m, &key->q, &h);
415  }
416 
417  //Check status code
418  if(!error)
419  {
420  error = mpiAdd(m, m, &m2);
421  }
422 
423  //Free previously allocated memory
424  mpiFree(&m1);
425  mpiFree(&m2);
426  mpiFree(&h);
427  }
428 
429  //Return status code
430  return error;
431 }
432 
433 
434 /**
435  * @brief RSA encryption primitive
436  * @param[in] key RSA public key
437  * @param[in] m Message representative
438  * @param[out] c Ciphertext representative
439  * @return Error code
440  **/
441 
442 error_t rsaep(const RsaPublicKey *key, const Mpi *m, Mpi *c)
443 {
444  size_t nLen;
445  size_t eLen;
446 
447  //Retrieve the length of the public key
448  nLen = mpiGetLength(&key->n);
449  eLen = mpiGetLength(&key->e);
450 
451  //Sanity check
452  if(nLen == 0 || eLen == 0)
454 
455  //The message representative m shall be between 0 and n - 1
456  if(mpiCompInt(m, 0) < 0 || mpiComp(m, &key->n) >= 0)
457  return ERROR_OUT_OF_RANGE;
458 
459  //Perform modular exponentiation (c = m ^ e mod n)
460  return pkaModExp(c, m, &key->e, &key->n);
461 }
462 
463 
464 /**
465  * @brief RSA decryption primitive
466  * @param[in] key RSA private key
467  * @param[in] c Ciphertext representative
468  * @param[out] m Message representative
469  * @return Error code
470  **/
471 
472 error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
473 {
474  error_t error;
475 
476  //The ciphertext representative c shall be between 0 and n - 1
477  if(mpiCompInt(c, 0) < 0 || mpiComp(c, &key->n) >= 0)
478  return ERROR_OUT_OF_RANGE;
479 
480  //Use the Chinese remainder algorithm?
481  if(mpiGetLength(&key->n) > 0 && mpiGetLength(&key->p) > 0 &&
482  mpiGetLength(&key->q) > 0 && mpiGetLength(&key->dp) > 0 &&
483  mpiGetLength(&key->dq) > 0 && mpiGetLength(&key->qinv) > 0)
484  {
485  //Perform modular exponentiation (with CRT)
486  error = pkaRsaCrtExp(key, c, m);
487  }
488  else if(mpiGetLength(&key->n) > 0 && mpiGetLength(&key->d) > 0)
489  {
490  //Perform modular exponentiation (without CRT)
491  error = pkaModExp(m, c, &key->d, &key->n);
492  }
493  else
494  {
495  //Invalid parameters
496  error = ERROR_INVALID_PARAMETER;
497  }
498 
499  //Return status code
500  return error;
501 }
502 
503 
504 /**
505  * @brief Scalar multiplication
506  * @param[in] params EC domain parameters
507  * @param[out] r Resulting point R = d.S
508  * @param[in] d An integer d such as 0 <= d < p
509  * @param[in] s EC point
510  * @return Error code
511  **/
512 
513 error_t ecMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d,
514  const EcPoint *s)
515 {
516  error_t error;
517  uint_t modLen;
518  uint_t scalarLen;
519  uint32_t temp;
520 
521  //Retrieve the length of the modulus, in bits
522  modLen = mpiGetBitLength(&params->p);
523  //Retrieve the length of the scalar, in bits
524  scalarLen = mpiGetBitLength(d);
525 
526  //Check the length of the operands
527  if(modLen <= PKA_MAX_EOS && scalarLen <= PKA_MAX_EOS)
528  {
529  //Acquire exclusive access to the PKA module
531 
532  //Specify the length of the modulus, in bits
533  PKA->RAM[PKA_ECC_SCALAR_MUL_IN_OP_NB_BITS] = modLen;
534  //Specify the length of the scalar, in bits
535  PKA->RAM[PKA_ECC_SCALAR_MUL_IN_EXP_NB_BITS] = scalarLen;
536  //Set the sign of the coefficient A
537  PKA->RAM[PKA_ECC_SCALAR_MUL_IN_A_COEFF_SIGN] = 0;
538 
539  //Load input arguments into the PKA internal RAM
540  pkaImportMpi(&params->p, modLen, PKA_ECC_SCALAR_MUL_IN_MOD_GF);
541  pkaImportMpi(&params->a, modLen, PKA_ECC_SCALAR_MUL_IN_A_COEFF);
542  pkaImportMpi(d, scalarLen, PKA_ECC_SCALAR_MUL_IN_K);
543  pkaImportMpi(&s->x, modLen, PKA_ECC_SCALAR_MUL_IN_INITIAL_POINT_X);
544  pkaImportMpi(&s->y, modLen, PKA_ECC_SCALAR_MUL_IN_INITIAL_POINT_Y);
545 
546  //Disable interrupts
547  PKA->CR &= ~(PKA_CR_ADDRERRIE | PKA_CR_RAMERRIE | PKA_CR_PROCENDIE);
548 
549  //Write in the MODE field of PKA_CR register, specifying the operation
550  //which is to be executed
551  temp = PKA->CR & ~PKA_CR_MODE;
552  PKA->CR = temp | (PKA_CR_MODE_ECC_MUL << PKA_CR_MODE_Pos);
553 
554  //Then assert the START bit in PKA_CR register
555  PKA->CR |= PKA_CR_START;
556 
557  //Wait until the PROCENDF bit in the PKA_SR register is set to 1,
558  //indicating that the computation is complete
559  while((PKA->SR & PKA_SR_PROCENDF) == 0)
560  {
561  }
562 
563  //Copy the x-coordinate of the result
564  error = pkaExportMpi(&r->x, modLen, PKA_ECC_SCALAR_MUL_OUT_RESULT_X);
565 
566  //Check status code
567  if(!error)
568  {
569  //Copy the y-coordinate of the result
570  error = pkaExportMpi(&r->y, modLen, PKA_ECC_SCALAR_MUL_OUT_RESULT_Y);
571  }
572 
573  //Check status code
574  if(!error)
575  {
576  //Set the z-coordinate of the result
577  error = mpiSetValue(&r->z, 1);
578  }
579 
580  //Then clear PROCENDF bit by setting PROCENDFC bit in PKA_CLRFR
581  PKA->CLRFR = PKA_CLRFR_PROCENDFC;
582 
583  //Release exclusive access to the PKA module
585  }
586  else
587  {
588  //Report an error
589  error = ERROR_FAILURE;
590  }
591 
592  //Return status code
593  return error;
594 }
595 
596 
597 /**
598  * @brief ECDSA signature generation
599  * @param[in] prngAlgo PRNG algorithm
600  * @param[in] prngContext Pointer to the PRNG context
601  * @param[in] params EC domain parameters
602  * @param[in] privateKey Signer's EC private key
603  * @param[in] digest Digest of the message to be signed
604  * @param[in] digestLen Length in octets of the digest
605  * @param[out] signature (R, S) integer pair
606  * @return Error code
607  **/
608 
609 error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext,
610  const EcDomainParameters *params, const EcPrivateKey *privateKey,
611  const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
612 {
613  error_t error;
614  size_t modLen;
615  size_t orderLen;
616  uint32_t temp;
617  Mpi k;
618 
619  //Check parameters
620  if(params == NULL || privateKey == NULL || digest == NULL || signature == NULL)
622 
623  //Retrieve the length of the modulus, in bits
624  modLen = mpiGetBitLength(&params->p);
625  //Retrieve the length of the base point order, in bits
626  orderLen = mpiGetBitLength(&params->q);
627 
628  //Check the length of the operands
629  if(modLen > PKA_MAX_EOS || orderLen > PKA_MAX_EOS)
630  return ERROR_FAILURE;
631 
632  //Initialize multiple precision integers
633  mpiInit(&k);
634 
635  //Generate a random number k such as 0 < k < q - 1
636  error = mpiRandRange(&k, &params->q, prngAlgo, prngContext);
637 
638  //Check status code
639  if(!error)
640  {
641  //Acquire exclusive access to the PKA module
643 
644  //Specify the length of the modulus, in bits
645  PKA->RAM[PKA_ECDSA_SIGN_IN_MOD_NB_BITS] = modLen;
646  //Specify the length of the base point order, in bits
647  PKA->RAM[PKA_ECDSA_SIGN_IN_ORDER_NB_BITS] = orderLen;
648  //Set the sign of the coefficient A
649  PKA->RAM[PKA_ECDSA_SIGN_IN_A_COEFF_SIGN] = 0;
650 
651  //Load input arguments into the PKA internal RAM
652  pkaImportMpi(&params->p, modLen, PKA_ECDSA_SIGN_IN_MOD_GF);
653  pkaImportMpi(&params->a, modLen, PKA_ECDSA_SIGN_IN_A_COEFF);
654  pkaImportMpi(&params->g.x, modLen, PKA_ECDSA_SIGN_IN_INITIAL_POINT_X);
655  pkaImportMpi(&params->g.y, modLen, PKA_ECDSA_SIGN_IN_INITIAL_POINT_Y);
656  pkaImportMpi(&params->q, orderLen, PKA_ECDSA_SIGN_IN_ORDER_N);
657  pkaImportMpi(&privateKey->d, orderLen, PKA_ECDSA_SIGN_IN_PRIVATE_KEY_D);
658  pkaImportMpi(&k, orderLen, PKA_ECDSA_SIGN_IN_K);
659 
660  //Keep the leftmost bits of the hash value
661  digestLen = MIN(digestLen, (orderLen + 7) / 8);
662  //Load the hash value into the PKA internal RAM
663  pkaImportArray(digest, digestLen, orderLen, PKA_ECDSA_SIGN_IN_HASH_E);
664 
665  //Clear error code
666  PKA->RAM[PKA_ECDSA_SIGN_OUT_ERROR] = PKA_STATUS_INVALID;
667 
668  //Disable interrupts
669  PKA->CR &= ~(PKA_CR_ADDRERRIE | PKA_CR_RAMERRIE | PKA_CR_PROCENDIE);
670 
671  //Write in the MODE field of PKA_CR register, specifying the operation
672  //which is to be executed
673  temp = PKA->CR & ~PKA_CR_MODE;
674  PKA->CR = temp | (PKA_CR_MODE_ECDSA_SIGN << PKA_CR_MODE_Pos);
675 
676  //Then assert the START bit in PKA_CR register
677  PKA->CR |= PKA_CR_START;
678 
679  //Wait until the PROCENDF bit in the PKA_SR register is set to 1,
680  //indicating that the computation is complete
681  while((PKA->SR & PKA_SR_PROCENDF) == 0)
682  {
683  }
684 
685  //Successful computation?
686  if(PKA->RAM[PKA_ECDSA_SIGN_OUT_ERROR] == PKA_STATUS_SUCCESS)
687  {
688  error = NO_ERROR;
689  }
690  else
691  {
692  error = ERROR_FAILURE;
693  }
694 
695  //Check status code
696  if(!error)
697  {
698  //Copy integer R
699  error = pkaExportMpi(&signature->r, orderLen, PKA_ECDSA_SIGN_OUT_SIGNATURE_R);
700  }
701 
702  //Check status code
703  if(!error)
704  {
705  //Copy integer S
706  error = pkaExportMpi(&signature->s, orderLen, PKA_ECDSA_SIGN_OUT_SIGNATURE_S);
707  }
708 
709  //Then clear PROCENDF bit by setting PROCENDFC bit in PKA_CLRFR
710  PKA->CLRFR = PKA_CLRFR_PROCENDFC;
711 
712  //Release exclusive access to the PKA module
714  }
715 
716  //Release multiple precision integer
717  mpiFree(&k);
718 
719  //Return status code
720  return error;
721 }
722 
723 
724 /**
725  * @brief ECDSA signature verification
726  * @param[in] params EC domain parameters
727  * @param[in] publicKey Signer's EC public key
728  * @param[in] digest Digest of the message whose signature is to be verified
729  * @param[in] digestLen Length in octets of the digest
730  * @param[in] signature (R, S) integer pair
731  * @return Error code
732  **/
733 
735  const EcPublicKey *publicKey, const uint8_t *digest, size_t digestLen,
736  const EcdsaSignature *signature)
737 {
738  error_t error;
739  size_t modLen;
740  size_t orderLen;
741  uint32_t temp;
742 
743  //Check parameters
744  if(params == NULL || publicKey == NULL || digest == NULL || signature == NULL)
746 
747  //The verifier shall check that 0 < r < q
748  if(mpiCompInt(&signature->r, 0) <= 0 ||
749  mpiComp(&signature->r, &params->q) >= 0)
750  {
751  //If the condition is violated, the signature shall be rejected as invalid
753  }
754 
755  //The verifier shall check that 0 < s < q
756  if(mpiCompInt(&signature->s, 0) <= 0 ||
757  mpiComp(&signature->s, &params->q) >= 0)
758  {
759  //If the condition is violated, the signature shall be rejected as invalid
761  }
762 
763  //Retrieve the length of the modulus, in bits
764  modLen = mpiGetBitLength(&params->p);
765  //Retrieve the length of the base point order, in bits
766  orderLen = mpiGetBitLength(&params->q);
767 
768  //Check the length of the operands
769  if(modLen > PKA_MAX_EOS || orderLen > PKA_MAX_EOS)
770  return ERROR_FAILURE;
771 
772  //Acquire exclusive access to the PKA module
774 
775  //Specify the length of the modulus, in bits
776  PKA->RAM[PKA_ECDSA_VERIF_IN_MOD_NB_BITS] = modLen;
777  //Specify the length of the base point order, in bits
778  PKA->RAM[PKA_ECDSA_VERIF_IN_ORDER_NB_BITS] = orderLen;
779  //Set the sign of the coefficient A
780  PKA->RAM[PKA_ECDSA_VERIF_IN_A_COEFF_SIGN] = 0;
781 
782  //Load input arguments into the PKA internal RAM
783  pkaImportMpi(&params->p, modLen, PKA_ECDSA_VERIF_IN_MOD_GF);
784  pkaImportMpi(&params->a, modLen, PKA_ECDSA_VERIF_IN_A_COEFF);
785  pkaImportMpi(&params->g.x, modLen, PKA_ECDSA_VERIF_IN_INITIAL_POINT_X);
786  pkaImportMpi(&params->g.y, modLen, PKA_ECDSA_VERIF_IN_INITIAL_POINT_Y);
787  pkaImportMpi(&params->q, orderLen, PKA_ECDSA_VERIF_IN_ORDER_N);
788  pkaImportMpi(&publicKey->q.x, modLen, PKA_ECDSA_VERIF_IN_PUBLIC_KEY_POINT_X);
789  pkaImportMpi(&publicKey->q.y, modLen, PKA_ECDSA_VERIF_IN_PUBLIC_KEY_POINT_Y);
790  pkaImportMpi(&signature->r, orderLen, PKA_ECDSA_VERIF_IN_SIGNATURE_R);
791  pkaImportMpi(&signature->s, orderLen, PKA_ECDSA_VERIF_IN_SIGNATURE_S);
792 
793  //Keep the leftmost bits of the hash value
794  digestLen = MIN(digestLen, (orderLen + 7) / 8);
795  //Load the hash value into the PKA internal RAM
796  pkaImportArray(digest, digestLen, orderLen, PKA_ECDSA_VERIF_IN_HASH_E);
797 
798  //Clear result
799  PKA->RAM[PKA_ECDSA_VERIF_OUT_RESULT] = PKA_STATUS_INVALID;
800 
801  //Disable interrupts
802  PKA->CR &= ~(PKA_CR_ADDRERRIE | PKA_CR_RAMERRIE | PKA_CR_PROCENDIE);
803 
804  //Write in the MODE field of PKA_CR register, specifying the operation
805  //which is to be executed
806  temp = PKA->CR & ~PKA_CR_MODE;
807  PKA->CR = temp | (PKA_CR_MODE_ECDSA_VERIFY << PKA_CR_MODE_Pos);
808 
809  //Then assert the START bit in PKA_CR register
810  PKA->CR |= PKA_CR_START;
811 
812  //Wait until the PROCENDF bit in the PKA_SR register is set to 1,
813  //indicating that the computation is complete
814  while((PKA->SR & PKA_SR_PROCENDF) == 0)
815  {
816  }
817 
818  //Test if the ECDSA signature is valid
819  if(PKA->RAM[PKA_ECDSA_VERIF_OUT_RESULT] == PKA_STATUS_SUCCESS)
820  {
821  error = NO_ERROR;
822  }
823  else
824  {
825  error = ERROR_INVALID_SIGNATURE;
826  }
827 
828  //Then clear PROCENDF bit by setting PROCENDFC bit in PKA_CLRFR
829  PKA->CLRFR = PKA_CLRFR_PROCENDFC;
830 
831  //Release exclusive access to the PKA module
833 
834  //Return status code
835  return error;
836 }
837 
838 
839 #if (X25519_SUPPORT == ENABLED || ED25519_SUPPORT == ENABLED)
840 
841 /**
842  * @brief Modular multiplication
843  * @param[out] r Resulting integer R = (A * B) mod p
844  * @param[in] a An integer such as 0 <= A < p
845  * @param[in] b An integer such as 0 <= B < p
846  **/
847 
848 void curve25519Mul(uint32_t *r, const uint32_t *a, const uint32_t *b)
849 {
850  uint_t i;
851  uint64_t temp;
852  uint32_t u[16];
853 
854  //Acquire exclusive access to the PKA module
856 
857  //Specify the length of the operands, in bits
858  PKA->RAM[PKA_ARITHMETIC_MUL_NB_BITS] = 255;
859 
860  //Load the first operand into the PKA internal RAM
861  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1] = a[0];
862  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 1] = a[1];
863  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 2] = a[2];
864  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 3] = a[3];
865  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 4] = a[4];
866  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 5] = a[5];
867  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 6] = a[6];
868  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 7] = a[7];
869 
870  //An additional word with all bits equal to zero must be added
871  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 8] = 0;
872 
873  //Load the second operand into the PKA internal RAM
874  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2] = b[0];
875  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 1] = b[1];
876  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 2] = b[2];
877  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 3] = b[3];
878  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 4] = b[4];
879  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 5] = b[5];
880  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 6] = b[6];
881  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 7] = b[7];
882 
883  //An additional word with all bits equal to zero must be added
884  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 8] = 0;
885 
886  //Disable interrupts
887  PKA->CR &= ~(PKA_CR_ADDRERRIE | PKA_CR_RAMERRIE | PKA_CR_PROCENDIE);
888 
889  //Write in the MODE field of PKA_CR register, specifying the operation
890  //which is to be executed
891  temp = PKA->CR & ~PKA_CR_MODE;
892  PKA->CR = temp | (PKA_CR_MODE_ARITHMETIC_MUL << PKA_CR_MODE_Pos);
893 
894  //Then assert the START bit in PKA_CR register
895  PKA->CR |= PKA_CR_START;
896 
897  //Wait until the PROCENDF bit in the PKA_SR register is set to 1,
898  //indicating that the computation is complete
899  while((PKA->SR & PKA_SR_PROCENDF) == 0)
900  {
901  }
902 
903  //Read the result data from the PKA internal RAM
904  u[0] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT];
905  u[1] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 1];
906  u[2] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 2];
907  u[3] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 3];
908  u[4] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 4];
909  u[5] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 5];
910  u[6] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 6];
911  u[7] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 7];
912  u[8] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 8];
913  u[9] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 9];
914  u[10] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 10];
915  u[11] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 11];
916  u[12] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 12];
917  u[13] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 13];
918  u[14] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 14];
919  u[15] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 15];
920 
921  //Then clear PROCENDF bit by setting PROCENDFC bit in PKA_CLRFR
922  PKA->CLRFR = PKA_CLRFR_PROCENDFC;
923 
924  //Release exclusive access to the PKA module
926 
927  //Reduce bit 255 (2^255 = 19 mod p)
928  temp = (u[7] >> 31) * 19;
929  //Mask the most significant bit
930  u[7] &= 0x7FFFFFFF;
931 
932  //Perform fast modular reduction (first pass)
933  for(i = 0; i < 8; i++)
934  {
935  temp += u[i];
936  temp += (uint64_t) u[i + 8] * 38;
937  u[i] = temp & 0xFFFFFFFF;
938  temp >>= 32;
939  }
940 
941  //Reduce bit 256 (2^256 = 38 mod p)
942  temp *= 38;
943  //Reduce bit 255 (2^255 = 19 mod p)
944  temp += (u[7] >> 31) * 19;
945  //Mask the most significant bit
946  u[7] &= 0x7FFFFFFF;
947 
948  //Perform fast modular reduction (second pass)
949  for(i = 0; i < 8; i++)
950  {
951  temp += u[i];
952  u[i] = temp & 0xFFFFFFFF;
953  temp >>= 32;
954  }
955 
956  //Reduce non-canonical values
957  curve25519Red(r, u);
958 }
959 
960 #endif
961 #if (X448_SUPPORT == ENABLED || ED448_SUPPORT == ENABLED)
962 
963 /**
964  * @brief Modular multiplication
965  * @param[out] r Resulting integer R = (A * B) mod p
966  * @param[in] a An integer such as 0 <= A < p
967  * @param[in] b An integer such as 0 <= B < p
968  **/
969 
970 void curve448Mul(uint32_t *r, const uint32_t *a, const uint32_t *b)
971 {
972  uint_t i;
973  uint64_t c;
974  uint64_t temp;
975  uint32_t u[28];
976 
977  //Acquire exclusive access to the PKA module
979 
980  //Specify the length of the operands, in bits
981  PKA->RAM[PKA_ARITHMETIC_MUL_NB_BITS] = 448;
982 
983  //Load the first operand into the PKA internal RAM
984  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1] = a[0];
985  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 1] = a[1];
986  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 2] = a[2];
987  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 3] = a[3];
988  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 4] = a[4];
989  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 5] = a[5];
990  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 6] = a[6];
991  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 7] = a[7];
992  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 8] = a[8];
993  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 9] = a[9];
994  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 10] = a[10];
995  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 11] = a[11];
996  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 12] = a[12];
997  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 13] = a[13];
998 
999  //An additional word with all bits equal to zero must be added
1000  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP1 + 14] = 0;
1001 
1002  //Load the second operand into the PKA internal RAM
1003  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2] = b[0];
1004  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 1] = b[1];
1005  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 2] = b[2];
1006  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 3] = b[3];
1007  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 4] = b[4];
1008  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 5] = b[5];
1009  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 6] = b[6];
1010  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 7] = b[7];
1011  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 8] = b[8];
1012  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 9] = b[9];
1013  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 10] = b[10];
1014  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 11] = b[11];
1015  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 12] = b[12];
1016  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 13] = b[13];
1017 
1018  //An additional word with all bits equal to zero must be added
1019  PKA->RAM[PKA_ARITHMETIC_MUL_IN_OP2 + 14] = 0;
1020 
1021  //Disable interrupts
1022  PKA->CR &= ~(PKA_CR_ADDRERRIE | PKA_CR_RAMERRIE | PKA_CR_PROCENDIE);
1023 
1024  //Write in the MODE field of PKA_CR register, specifying the operation
1025  //which is to be executed
1026  temp = PKA->CR & ~PKA_CR_MODE;
1027  PKA->CR = temp | (PKA_CR_MODE_ARITHMETIC_MUL << PKA_CR_MODE_Pos);
1028 
1029  //Then assert the START bit in PKA_CR register
1030  PKA->CR |= PKA_CR_START;
1031 
1032  //Wait until the PROCENDF bit in the PKA_SR register is set to 1,
1033  //indicating that the computation is complete
1034  while((PKA->SR & PKA_SR_PROCENDF) == 0)
1035  {
1036  }
1037 
1038  //Read the result data from the PKA internal RAM
1039  u[0] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT];
1040  u[1] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 1];
1041  u[2] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 2];
1042  u[3] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 3];
1043  u[4] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 4];
1044  u[5] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 5];
1045  u[6] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 6];
1046  u[7] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 7];
1047  u[8] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 8];
1048  u[9] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 9];
1049  u[10] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 10];
1050  u[11] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 11];
1051  u[12] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 12];
1052  u[13] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 13];
1053  u[14] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 14];
1054  u[15] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 15];
1055  u[16] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 16];
1056  u[17] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 17];
1057  u[18] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 18];
1058  u[19] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 19];
1059  u[20] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 20];
1060  u[21] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 21];
1061  u[22] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 22];
1062  u[23] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 23];
1063  u[24] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 24];
1064  u[25] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 25];
1065  u[26] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 26];
1066  u[27] = PKA->RAM[PKA_ARITHMETIC_MUL_OUT_RESULT + 27];
1067 
1068  //Then clear PROCENDF bit by setting PROCENDFC bit in PKA_CLRFR
1069  PKA->CLRFR = PKA_CLRFR_PROCENDFC;
1070 
1071  //Release exclusive access to the PKA module
1073 
1074  //Perform fast modular reduction (first pass)
1075  for(temp = 0, i = 0; i < 7; i++)
1076  {
1077  temp += u[i];
1078  temp += u[i + 14];
1079  temp += u[i + 21];
1080  u[i] = temp & 0xFFFFFFFF;
1081  temp >>= 32;
1082  }
1083 
1084  for(i = 7; i < 14; i++)
1085  {
1086  temp += u[i];
1087  temp += u[i + 7];
1088  temp += u[i + 14];
1089  temp += u[i + 14];
1090  u[i] = temp & 0xFFFFFFFF;
1091  temp >>= 32;
1092  }
1093 
1094  //Perform fast modular reduction (second pass)
1095  for(c = temp, i = 0; i < 7; i++)
1096  {
1097  temp += u[i];
1098  u[i] = temp & 0xFFFFFFFF;
1099  temp >>= 32;
1100  }
1101 
1102  for(temp += c, i = 7; i < 14; i++)
1103  {
1104  temp += u[i];
1105  u[i] = temp & 0xFFFFFFFF;
1106  temp >>= 32;
1107  }
1108 
1109  //Reduce non-canonical values
1110  curve448Red(r, u, (uint32_t) temp);
1111 }
1112 
1113 #endif
1114 #endif
unsigned int uint_t
Definition: compiler_port.h:50
General definitions for cryptographic algorithms.
#define PrngAlgo
Definition: crypto.h:917
void curve25519Red(uint32_t *r, const uint32_t *a)
Modular reduction.
Definition: curve25519.c:352
Curve25519 elliptic curve (constant-time implementation)
void curve448Red(uint32_t *r, const uint32_t *a, uint32_t h)
Modular reduction.
Definition: curve448.c:368
Curve448 elliptic curve (constant-time implementation)
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.
uint8_t u
Definition: lldp_ext_med.h:213
error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular multiplication.
error_t mpiRandRange(Mpi *r, const Mpi *p, const PrngAlgo *prngAlgo, void *prngContext)
Generate a random value in the range 1 to p-1.
Definition: mpi.c:564
error_t mpiSetValue(Mpi *r, int_t a)
Set the value of a multiple precision integer.
Definition: mpi.c:484
uint_t mpiGetLength(const Mpi *a)
Get the actual length in words.
Definition: mpi.c:168
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:234
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
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
error_t mpiGrow(Mpi *r, uint_t size)
Adjust the size of multiple precision integer.
Definition: mpi.c:94
uint8_t b
Definition: nbns_common.h:104
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 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.
#define PKA_MAX_ROS
#define PKA_CR_MODE_RSA_CRT_EXP
#define PKA_STATUS_INVALID
#define PKA_CR_MODE_ECC_MUL
#define PKA_CR_MODE_ECDSA_VERIFY
#define PKA_MAX_EOS
#define PKA_CR_MODE_ECDSA_SIGN
#define PKA_CR_MODE_MODULAR_EXP
#define PKA_CR_MODE_ARITHMETIC_MUL
#define PKA_STATUS_SUCCESS
OsMutex stm32wlxxCryptoMutex
STM32WL hardware cryptographic accelerator.
error_t pkaRsaCrtExp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
Modular exponentiation with CRT.
void pkaImportMpi(const Mpi *a, uint_t length, uint_t offset)
Import multiple-precision integer.
void pkaImportArray(const uint8_t *src, size_t srcLen, uint_t destLen, uint_t offset)
Import byte array.
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.
void curve448Mul(uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular multiplication.
error_t rsaep(const RsaPublicKey *key, const Mpi *m, Mpi *c)
RSA encryption primitive.
void curve25519Mul(uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular multiplication.
error_t pkaExportMpi(Mpi *r, uint_t length, uint_t offset)
Export multiple-precision integer.
error_t pkaModExp(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation.
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 pkaInit(void)
PKA module initialization.
STM32WL public-key hardware accelerator (PKA)
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
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
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
RSA public key.
Definition: rsa.h:57
Mpi e
Public exponent.
Definition: rsa.h:59
Mpi n
Modulus.
Definition: rsa.h:58
uint8_t length
Definition: tcp.h:368