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