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