esp32_c6_crypto_pkc.c
Go to the documentation of this file.
1 /**
2  * @file esp32_c6_crypto_pkc.c
3  * @brief ESP32-C6 public-key hardware accelerator
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2025 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.5.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "esp_crypto_lock.h"
36 #include "soc/pcr_reg.h"
37 #include "soc/hwcrypto_reg.h"
38 #include "esp_private/periph_ctrl.h"
41 #include "pkc/rsa.h"
42 #include "ecc/ec.h"
43 #include "ecc/ec_misc.h"
44 #include "debug.h"
45 
46 //Check crypto library configuration
47 #if (ESP32_C6_CRYPTO_PKC_SUPPORT == ENABLED)
48 
49 //Pre-computed values of -1/p[0] mod 2^32
50 #define SECP224R1_PRIME_M 0xFFFFFFFF
51 #define SECP256K1_PRIME_M 0xD2253531
52 #define SECP256R1_PRIME_M 0x00000001
53 #define SECP384R1_PRIME_M 0x00000001
54 #define SECP521R1_PRIME_M 0x00000001
55 #define BRAINPOOLP256R1_PRIME_M 0xCEFD89B9
56 #define BRAINPOOLP384R1_PRIME_M 0xEA9EC825
57 #define BRAINPOOLP512R1_PRIME_M 0x7D89EFC5
58 #define FRP256V1_PRIME_M 0x164E1155
59 #define SM2_PRIME_M 0x00000001
60 #define CURVE25519_PRIME_M 0x286BCA1B
61 #define CURVE448_PRIME_M 0x00000001
62 
63 //Pre-computed values of -1/q[0] mod 2^32
64 #define SECP224R1_ORDER_M 0x6A1FC2EB
65 #define SECP256K1_ORDER_M 0x5588B13F
66 #define SECP256R1_ORDER_M 0xEE00BC4F
67 #define SECP384R1_ORDER_M 0xE88FDC45
68 #define SECP521R1_ORDER_M 0x79A995C7
69 #define BRAINPOOLP256R1_ORDER_M 0xCBB40EE9
70 #define BRAINPOOLP384R1_ORDER_M 0x5CB5BB93
71 #define BRAINPOOLP512R1_ORDER_M 0x0F1B7027
72 #define FRP256V1_ORDER_M 0x4FFF51DF
73 #define SM2_ORDER_M 0x72350975
74 
75 //Pre-computed value of R^2 mod p (secp224r1)
76 const uint32_t SECP224R1_PRIME_R2[7] =
77 {
78  0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000
79 };
80 
81 //Pre-computed value of R^2 mod q (secp224r1)
82 const uint32_t SECP224R1_ORDER_R2[7] =
83 {
84  0x3AD01289, 0x6BDAAE6C, 0x97A54552, 0x6AD09D91, 0xB1E97961, 0x1822BC47, 0xD4BAA4CF
85 };
86 
87 //Pre-computed value of R^2 mod p (secp256k1)
88 const uint32_t SECP256K1_PRIME_R2[8] =
89 {
90  0x000E90A1, 0x000007A2, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
91 };
92 
93 //Pre-computed value of R^2 mod q (secp256k1)
94 const uint32_t SECP256K1_ORDER_R2[8] =
95 {
96  0x67D7D140, 0x896CF214, 0x0E7CF878, 0x741496C2, 0x5BCD07C6, 0xE697F5E4, 0x81C69BC5, 0x9D671CD5
97 };
98 
99 //Pre-computed value of R^2 mod p (secp256r1)
100 const uint32_t SECP256R1_PRIME_R2[8] =
101 {
102  0x00000003, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFB, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0x00000004
103 };
104 
105 //Pre-computed value of R^2 mod q (secp256r1)
106 const uint32_t SECP256R1_ORDER_R2[8] =
107 {
108  0xBE79EEA2, 0x83244C95, 0x49BD6FA6, 0x4699799C, 0x2B6BEC59, 0x2845B239, 0xF3D95620, 0x66E12D94
109 };
110 
111 //Pre-computed value of R^2 mod p (secp384r1)
112 const uint32_t SECP384R1_PRIME_R2[12] =
113 {
114  0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE, 0x00000000, 0x00000002,
115  0x00000001, 0x00000000, 0x00000000, 0x00000000
116 };
117 
118 //Pre-computed value of R^2 mod q (secp384r1)
119 const uint32_t SECP384R1_ORDER_R2[12] =
120 {
121  0x19B409A9, 0x2D319B24, 0xDF1AA419, 0xFF3D81E5, 0xFCB82947, 0xBC3E483A, 0x4AAB1CC5, 0xD40D4917,
122  0x28266895, 0x3FB05B7A, 0x2B39BF21, 0x0C84EE01
123 };
124 
125 //Pre-computed value of R^2 mod p (secp521r1)
126 const uint32_t SECP521R1_PRIME_R2[17] =
127 {
128  0x00000000, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
129  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
130  0x00000000
131 };
132 
133 //Pre-computed value of R^2 mod q (secp521r1)
134 const uint32_t SECP521R1_ORDER_R2[17] =
135 {
136  0x61C64CA7, 0x1163115A, 0x4374A642, 0x18354A56, 0x0791D9DC, 0x5D4DD6D3, 0xD3402705, 0x4FB35B72,
137  0xB7756E3A, 0xCFF3D142, 0xA8E567BC, 0x5BCC6D61, 0x492D0D45, 0x2D8E03D1, 0x8C44383D, 0x5B5A3AFE,
138  0x0000019A
139 };
140 
141 //Pre-computed value of R^2 mod p (brainpoolP256r1)
142 const uint32_t BRAINPOOLP256R1_PRIME_R2[8] =
143 {
144  0xA6465B6C, 0x8CFEDF7B, 0x614D4F4D, 0x5CCE4C26, 0x6B1AC807, 0xA1ECDACD, 0xE5957FA8, 0x4717AA21
145 };
146 
147 //Pre-computed value of R^2 mod q (brainpoolP256r1)
148 const uint32_t BRAINPOOLP256R1_ORDER_R2[8] =
149 {
150  0x3312FCA6, 0xE1D8D8DE, 0x1134E4A0, 0xF35D176A, 0x6C815CB0, 0x9B7F25E7, 0xC3236762, 0x0B25F1B9
151 };
152 
153 //Pre-computed value of R^2 mod p (brainpoolP384r1)
154 const uint32_t BRAINPOOLP384R1_PRIME_R2[12] =
155 {
156  0x40B64BDE, 0x087CEFFF, 0x3D7FD965, 0x53528334, 0xC9940899, 0x8E28F99C, 0x9918D5AF, 0x62140191,
157  0xA57E052C, 0xD5C6EF3B, 0x178DF842, 0x36BF6883
158 };
159 
160 //Pre-computed value of R^2 mod q (brainpoolP384r1)
161 const uint32_t BRAINPOOLP384R1_ORDER_R2[12] =
162 {
163  0xDE771C8E, 0xAC4ED3A2, 0x2F2B6B6E, 0x37264E20, 0x9802688A, 0x2A927E3B, 0x52D748FF, 0x574A74CB,
164  0x65165FDB, 0x8F886DC9, 0x614E97C2, 0x0CE8941A
165 };
166 
167 //Pre-computed value of R^2 mod p (brainpoolP512r1)
168 const uint32_t BRAINPOOLP512R1_PRIME_R2[16] =
169 {
170  0x6158F205, 0x49AD144A, 0x27157905, 0x793FB130, 0x905AFFD3, 0x53B7F9BC, 0x83514A25, 0xE0C19A77,
171  0xD5898057, 0x19486FD8, 0xD42BFF83, 0xA16DAA5F, 0x2056EECC, 0x202E1940, 0xA9FF6450, 0x3C4C9D05
172 };
173 
174 //Pre-computed value of R^2 mod q (brainpoolP512r1)
175 const uint32_t BRAINPOOLP512R1_ORDER_R2[16] =
176 {
177  0xCDA81671, 0xD2A3681E, 0x95283DDD, 0x0886B758, 0x33B7627F, 0x3EC64BD0, 0x2F0207E8, 0xA6F230C7,
178  0x3B790DE3, 0xD7F9CC26, 0x2F16BBDF, 0x723C37A2, 0x194B2E56, 0x95DF1B4C, 0x718407B0, 0xA794586A
179 };
180 
181 //Pre-computed value of R^2 mod p (FRP256v1)
182 const uint32_t FRP256V1_PRIME_R2[8] =
183 {
184  0xC99F1513, 0xB0C24E77, 0x0C960F92, 0x846F8083, 0xCE137EEE, 0x62B7012F, 0x88EB98AC, 0xB02C8F9F
185 };
186 
187 //Pre-computed value of R^2 mod q (FRP256v1)
188 const uint32_t FRP256V1_ORDER_R2[8] =
189 {
190  0xF849D44D, 0x1416B735, 0xBCC2D0E1, 0xB551ADB5, 0xC380D52D, 0xCFB26475, 0x15C243BB, 0x0DF1A20D
191 };
192 
193 //Pre-computed value of R^2 mod p (curveSM2)
194 const uint32_t SM2_PRIME_R2[8] =
195 {
196  0x00000003, 0x00000002, 0xFFFFFFFF, 0x00000002, 0x00000001, 0x00000001, 0x00000002, 0x00000004
197 };
198 
199 //Pre-computed value of R^2 mod q (curveSM2)
200 const uint32_t SM2_ORDER_R2[8] =
201 {
202  0x7C114F20, 0x901192AF, 0xDE6FA2FA, 0x3464504A, 0x3AFFE0D4, 0x620FC84C, 0xA22B3D3B, 0x1EB5E412
203 };
204 
205 
206 /**
207  * @brief RSA module initialization
208  **/
209 
210 void esp32c6RsaInit(void)
211 {
212  //Enable RSA module
213  periph_module_enable(PERIPH_RSA_MODULE);
214 
215  //Clear PCR_RSA_MEM_PD bit
216  REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_PD);
217 
218  //Software should query RSA_CLEAN_REG after being released from reset, and
219  //before writing to any RSA Accelerator memory blocks or registers for the
220  //first time
221  while(REG_READ(RSA_QUERY_CLEAN_REG) == 0)
222  {
223  }
224 }
225 
226 
227 #if (MPI_SUPPORT == ENABLED)
228 
229 /**
230  * @brief Multiple precision multiplication
231  * @param[out] r Resulting integer R = A * B
232  * @param[in] a First operand A
233  * @param[in] b Second operand B
234  * @return Error code
235  **/
236 
237 error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
238 {
239  error_t error;
240  size_t i;
241  size_t n;
242  size_t aLen;
243  size_t bLen;
244 
245  //Get the length of the first operand, in 32-bit words
246  aLen = mpiGetLength(a);
247  //Get the length of the second operand, in 32-bit words
248  bLen = mpiGetLength(b);
249 
250  //The accelerator supports large-number multiplication up to 1536 bits
251  if(aLen <= 48 && bLen <= 48)
252  {
253  //All numbers in calculation must be of the same length
254  n = 1;
255  n = MAX(n, aLen);
256  n = MAX(n, bLen);
257 
258  //Acquire exclusive access to the RSA module
259  esp_crypto_mpi_lock_acquire();
260 
261  //Clear the interrupt flag
262  REG_WRITE(RSA_INT_CLR_REG, 1);
263  //Set mode register
264  REG_WRITE(RSA_MODE_REG, (2 * n) - 1);
265 
266  //Copy the first operand to RSA_X_MEM
267  for(i = 0; i < n; i++)
268  {
269  if(i < a->size)
270  {
271  REG_WRITE(RSA_X_MEM + i * 4, a->data[i]);
272  }
273  else
274  {
275  REG_WRITE(RSA_X_MEM + i * 4, 0);
276  }
277  }
278 
279  //The second operand will not be written to the base address of the
280  //RSA_Z_MEM memory. This area must be filled with zeroes
281  for(i = 0; i < n; i++)
282  {
283  REG_WRITE(RSA_Z_MEM + i * 4, 0);
284  }
285 
286  //The second operand must be written to the base address of the RSA_Z_MEM
287  //memory plus the address offset N
288  for(i = 0; i < n; i++)
289  {
290  if(i < b->size)
291  {
292  REG_WRITE(RSA_Z_MEM + (n + i) * 4, b->data[i]);
293  }
294  else
295  {
296  REG_WRITE(RSA_Z_MEM + (n + i) * 4, 0);
297  }
298  }
299 
300  //Start large-number multiplication
301  REG_WRITE(RSA_SET_START_MULT_REG, 1);
302 
303  //Wait for the operation to complete
304  while(REG_READ(RSA_QUERY_IDLE_REG) == 0)
305  {
306  }
307 
308  //Set the sign of the result
309  r->sign = (a->sign == b->sign) ? 1 : -1;
310 
311  //The length of the result is 2 x N bits
312  error = mpiGrow(r, n * 2);
313 
314  //Check status code
315  if(!error)
316  {
317  //Read the result from RSA_Z_MEM
318  for(i = 0; i < r->size; i++)
319  {
320  if(i < (n * 2))
321  {
322  r->data[i] = REG_READ(RSA_Z_MEM + i * 4);
323  }
324  else
325  {
326  r->data[i] = 0;
327  }
328  }
329  }
330 
331  //Clear the interrupt flag
332  REG_WRITE(RSA_INT_CLR_REG, 1);
333 
334  //Release exclusive access to the RSA module
335  esp_crypto_mpi_lock_release();
336  }
337  else
338  {
339  //Report an error
340  error = ERROR_FAILURE;
341  }
342 
343  //Return status code
344  return error;
345 }
346 
347 
348 /**
349  * @brief Modular exponentiation
350  * @param[out] r Resulting integer R = A ^ E mod P
351  * @param[in] a Pointer to a multiple precision integer
352  * @param[in] e Exponent
353  * @param[in] p Modulus
354  * @return Error code
355  **/
356 
357 error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
358 {
359  error_t error;
360  size_t i;
361  size_t n;
362  size_t modLen;
363  size_t expLen;
364  uint32_t m;
365  Mpi t;
366  Mpi r2;
367 
368  //Initialize multiple precision integers
369  mpiInit(&t);
370  mpiInit(&r2);
371 
372  //Get the length of the modulus, in bits
373  modLen = mpiGetBitLength(p);
374  //Get the length of the exponent, in bits
375  expLen = mpiGetBitLength(e);
376 
377  //The accelerator supports operand lengths up to 3072 bits
378  if(modLen > 0 && modLen <= 3072 && expLen > 0 && expLen <= 3072)
379  {
380  //All numbers in calculation must be of the same length
381  n = MAX(modLen, expLen);
382  n = (n + 31) / 32;
383 
384  //Reduce the operand first
385  error = mpiMod(&t, a, p);
386 
387  //Let R = b^n and pre-compute the quantity R^2 mod M
388  if(!error)
389  {
390  error = mpiSetValue(&r2, 1);
391  }
392 
393  if(!error)
394  {
395  error = mpiShiftLeft(&r2, n * 2 * 32);
396  }
397 
398  if(!error)
399  {
400  error = mpiMod(&r2, &r2, p);
401  }
402 
403  //Check status code
404  if(!error)
405  {
406  //Acquire exclusive access to the RSA module
407  esp_crypto_mpi_lock_acquire();
408 
409  //Clear the interrupt flag
410  REG_WRITE(RSA_INT_CLR_REG, 1);
411  //Set mode register
412  REG_WRITE(RSA_MODE_REG, n - 1);
413 
414  //Copy the operand to RSA_X_MEM
415  for(i = 0; i < n; i++)
416  {
417  if(i < t.size)
418  {
419  REG_WRITE(RSA_X_MEM + i * 4, t.data[i]);
420  }
421  else
422  {
423  REG_WRITE(RSA_X_MEM + i * 4, 0);
424  }
425  }
426 
427  //Copy the exponent to RSA_Y_MEM
428  for(i = 0; i < n; i++)
429  {
430  if(i < e->size)
431  {
432  REG_WRITE(RSA_Y_MEM + i * 4, e->data[i]);
433  }
434  else
435  {
436  REG_WRITE(RSA_Y_MEM + i * 4, 0);
437  }
438  }
439 
440  //Copy the modulus to RSA_M_MEM
441  for(i = 0; i < n; i++)
442  {
443  if(i < p->size)
444  {
445  REG_WRITE(RSA_M_MEM + i * 4, p->data[i]);
446  }
447  else
448  {
449  REG_WRITE(RSA_M_MEM + i * 4, 0);
450  }
451  }
452 
453  //Copy the pre-calculated value of R^2 mod M to RSA_Z_MEM
454  for(i = 0; i < n; i++)
455  {
456  if(i < r2.size)
457  {
458  REG_WRITE(RSA_Z_MEM + i * 4, r2.data[i]);
459  }
460  else
461  {
462  REG_WRITE(RSA_Z_MEM + i * 4, 0);
463  }
464  }
465 
466  //Use Newton's method to compute the inverse of M[0] mod 2^32
467  for(m = p->data[0], i = 0; i < 4; i++)
468  {
469  m = m * (2U - m * p->data[0]);
470  }
471 
472  //Precompute M' = -1/M[0] mod 2^32;
473  m = ~m + 1U;
474 
475  //Write the value of M' to RSA_M_PRIME_REG
476  REG_WRITE(RSA_M_PRIME_REG, m);
477 
478  //Enable search option
479  REG_WRITE(RSA_SEARCH_ENABLE_REG, 1);
480  REG_WRITE(RSA_SEARCH_POS_REG, expLen - 1);
481 
482  //Start modular exponentiation
483  REG_WRITE(RSA_SET_START_MODEXP_REG, 1);
484 
485  //Wait for the operation to complete
486  while(REG_READ(RSA_QUERY_IDLE_REG) == 0)
487  {
488  }
489 
490  //Adjust the size of the result if necessary
491  error = mpiGrow(r, n);
492 
493  //Check status code
494  if(!error)
495  {
496  //Read the result from RSA_Z_MEM
497  for(i = 0; i < r->size; i++)
498  {
499  if(i < n)
500  {
501  r->data[i] = REG_READ(RSA_Z_MEM + i * 4);
502  }
503  else
504  {
505  r->data[i] = 0;
506  }
507  }
508  }
509 
510  //Clear the interrupt flag
511  REG_WRITE(RSA_INT_CLR_REG, 1);
512 
513  //Release exclusive access to the RSA module
514  esp_crypto_mpi_lock_release();
515  }
516  }
517  else
518  {
519  //Report an error
520  error = ERROR_FAILURE;
521  }
522 
523  //Release previously allocated memory
524  mpiFree(&t);
525  mpiFree(&r2);
526 
527  //Return status code
528  return error;
529 }
530 
531 #endif
532 #if (EC_SUPPORT == ENABLED)
533 
534 /**
535  * @brief Multiplication of two integers
536  * @param[out] rl Low part of the result R = (A * B) mod (2^32)^n
537  * @param[out] rh High part of the result R = (A * B) / (2^32)^n
538  * @param[in] a An integer such as 0 <= A < (2^32)^n
539  * @param[in] b An integer such as 0 <= B < (2^32)^n
540  * @param[in] n Size of the operands, in words
541  **/
542 
543 void ecScalarMul(uint32_t *rl, uint32_t *rh, const uint32_t *a,
544  const uint32_t *b, uint_t n)
545 {
546  uint_t i;
547 
548  //Acquire exclusive access to the RSA module
549  esp_crypto_mpi_lock_acquire();
550 
551  //Clear the interrupt flag
552  REG_WRITE(RSA_INT_CLR_REG, 1);
553  //Set mode register
554  REG_WRITE(RSA_MODE_REG, (2 * n) - 1);
555 
556  //Copy the first operand to RSA_X_MEM
557  for(i = 0; i < n; i++)
558  {
559  REG_WRITE(RSA_X_MEM + i * 4, a[i]);
560  }
561 
562  //The second operand will not be written to the base address of the
563  //RSA_Z_MEM memory. This area must be filled with zeroes
564  for(i = 0; i < n; i++)
565  {
566  REG_WRITE(RSA_Z_MEM + i * 4, 0);
567  }
568 
569  //The second operand must be written to the base address of the RSA_Z_MEM
570  //memory plus the address offset N
571  for(i = 0; i < n; i++)
572  {
573  REG_WRITE(RSA_Z_MEM + (n + i) * 4, b[i]);
574  }
575 
576  //Start large-number multiplication
577  REG_WRITE(RSA_SET_START_MULT_REG, 1);
578 
579  //Wait for the operation to complete
580  while(REG_READ(RSA_QUERY_IDLE_REG) == 0)
581  {
582  }
583 
584  //Check whether the low part of the multiplication should be calculated
585  if(rl != NULL)
586  {
587  //Read the result from RSA_Z_MEM
588  for(i = 0; i < n; i++)
589  {
590  rl[i] = REG_READ(RSA_Z_MEM + i * 4);
591  }
592  }
593 
594  //Check whether the high part of the multiplication should be calculated
595  if(rh != NULL)
596  {
597  //Read the result from RSA_Z_MEM
598  for(i = 0; i < n; i++)
599  {
600  rh[i] = REG_READ(RSA_Z_MEM + (n + i) * 4);
601  }
602  }
603 
604  //Clear the interrupt flag
605  REG_WRITE(RSA_INT_CLR_REG, 1);
606 
607  //Release exclusive access to the RSA module
608  esp_crypto_mpi_lock_release();
609 }
610 
611 
612 /**
613  * @brief Squaring operation
614  * @param[out] r Result R = A ^ 2
615  * @param[in] a An integer such as 0 <= A < (2^32)^n
616  * @param[in] n Size of the integer A, in words
617  **/
618 
619 void ecScalarSqr(uint32_t *r, const uint32_t *a, uint_t n)
620 {
621  //Compute R = A ^ 2
622  ecScalarMul(r, r + n, a, a, n);
623 }
624 
625 
626 /**
627  * @brief Modular multiplication
628  * @param[in] curve Elliptic curve parameters
629  * @param[out] r Resulting integer R = (A * B) mod p
630  * @param[in] a An integer such as 0 <= A < p
631  * @param[in] b An integer such as 0 <= B < p
632  **/
633 
634 void ecFieldMulMod(const EcCurve *curve, uint32_t *r, const uint32_t *a,
635  const uint32_t *b)
636 {
637  uint_t i;
638  uint_t n;
639  uint32_t m;
640  const uint32_t *r2;
641 
642  //Get the length of the modulus, in words
643  n = (curve->fieldSize + 31) / 32;
644 
645  //Load modular reduction constants
646  if(osStrcmp(curve->name, "secp224r1") == 0)
647  {
648  r2 = SECP224R1_PRIME_R2;
650  }
651  else if(osStrcmp(curve->name, "secp256k1") == 0)
652  {
653  r2 = SECP256K1_PRIME_R2;
655  }
656  else if(osStrcmp(curve->name, "secp256r1") == 0)
657  {
658  r2 = SECP256R1_PRIME_R2;
660  }
661  else if(osStrcmp(curve->name, "secp384r1") == 0)
662  {
663  r2 = SECP384R1_PRIME_R2;
665  }
666  else if(osStrcmp(curve->name, "secp521r1") == 0)
667  {
668  r2 = SECP521R1_PRIME_R2;
670  }
671  else if(osStrcmp(curve->name, "brainpoolP256r1") == 0)
672  {
675  }
676  else if(osStrcmp(curve->name, "brainpoolP384r1") == 0)
677  {
680  }
681  else if(osStrcmp(curve->name, "brainpoolP512r1") == 0)
682  {
685  }
686  else if(osStrcmp(curve->name, "FRP256v1") == 0)
687  {
688  r2 = FRP256V1_PRIME_R2;
690  }
691  else if(osStrcmp(curve->name, "curveSM2") == 0)
692  {
693  r2 = SM2_PRIME_R2;
694  m = SM2_PRIME_M;
695  }
696  else
697  {
698  r2 = NULL;
699  m = 0;
700  }
701 
702  //Valid parameters?
703  if(r2 != NULL && m != 0)
704  {
705  //Acquire exclusive access to the RSA module
706  esp_crypto_mpi_lock_acquire();
707 
708  //Clear the interrupt flag
709  REG_WRITE(RSA_INT_CLR_REG, 1);
710  //Set mode register
711  REG_WRITE(RSA_MODE_REG, n - 1);
712 
713  //Copy the first operand to RSA_X_MEM
714  for(i = 0; i < n; i++)
715  {
716  REG_WRITE(RSA_X_MEM + i * 4, a[i]);
717  }
718 
719  //Copy the second operand to RSA_Y_MEM
720  for(i = 0; i < n; i++)
721  {
722  REG_WRITE(RSA_Y_MEM + i * 4, b[i]);
723  }
724 
725  //Copy the modulus to RSA_M_MEM
726  for(i = 0; i < n; i++)
727  {
728  REG_WRITE(RSA_M_MEM + i * 4, curve->p[i]);
729  }
730 
731  //Copy the pre-calculated value of R^2 mod M to RSA_Z_MEM
732  for(i = 0; i < n; i++)
733  {
734  REG_WRITE(RSA_Z_MEM + i * 4, r2[i]);
735  }
736 
737  //Write the value of M' to RSA_M_PRIME_REG
738  REG_WRITE(RSA_M_PRIME_REG, m);
739  //Start large-number modular multiplication
740  REG_WRITE(RSA_SET_START_MODMULT_REG, 1);
741 
742  //Wait for the operation to complete
743  while(REG_READ(RSA_QUERY_IDLE_REG) == 0)
744  {
745  }
746 
747  //Read the result from RSA_Z_MEM
748  for(i = 0; i < n; i++)
749  {
750  r[i] = REG_READ(RSA_Z_MEM + i * 4);
751  }
752 
753  //Clear the interrupt flag
754  REG_WRITE(RSA_INT_CLR_REG, 1);
755 
756  //Release exclusive access to the RSA module
757  esp_crypto_mpi_lock_release();
758  }
759  else
760  {
761  uint32_t u[EC_MAX_MODULUS_SIZE * 2];
762 
763  //Compute R = (A * B) mod p
764  ecScalarMul(u, u + n, a, b, n);
765  curve->fieldMod(curve, r, u);
766  }
767 }
768 
769 
770 /**
771  * @brief Modular squaring
772  * @param[in] curve Elliptic curve parameters
773  * @param[out] r Resulting integer R = A^2 mod p
774  * @param[in] a An integer such as 0 <= A < p
775  **/
776 
777 void ecFieldSqrMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
778 {
779  //Compute R = (A ^ 2) mod p
780  ecFieldMulMod(curve, r, a, a);
781 }
782 
783 
784 /**
785  * @brief Modular multiplication
786  * @param[in] curve Elliptic curve parameters
787  * @param[out] r Resulting integer R = (A * B) mod q
788  * @param[in] a An integer such as 0 <= A < q
789  * @param[in] b An integer such as 0 <= B < q
790  **/
791 
792 void ecScalarMulMod(const EcCurve *curve, uint32_t *r, const uint32_t *a,
793  const uint32_t *b)
794 {
795  uint_t i;
796  uint_t n;
797  uint32_t m;
798  const uint32_t *r2;
799 
800  //Get the length of the order, in words
801  n = (curve->orderSize + 31) / 32;
802 
803  //Load modular reduction constants
804  if(osStrcmp(curve->name, "secp224r1") == 0)
805  {
806  r2 = SECP224R1_ORDER_R2;
808  }
809  else if(osStrcmp(curve->name, "secp256k1") == 0)
810  {
811  r2 = SECP256K1_ORDER_R2;
813  }
814  else if(osStrcmp(curve->name, "secp256r1") == 0)
815  {
816  r2 = SECP256R1_ORDER_R2;
818  }
819  else if(osStrcmp(curve->name, "secp384r1") == 0)
820  {
821  r2 = SECP384R1_ORDER_R2;
823  }
824  else if(osStrcmp(curve->name, "secp521r1") == 0)
825  {
826  r2 = SECP521R1_ORDER_R2;
828  }
829  else if(osStrcmp(curve->name, "brainpoolP256r1") == 0)
830  {
833  }
834  else if(osStrcmp(curve->name, "brainpoolP384r1") == 0)
835  {
838  }
839  else if(osStrcmp(curve->name, "brainpoolP512r1") == 0)
840  {
843  }
844  else if(osStrcmp(curve->name, "FRP256v1") == 0)
845  {
846  r2 = FRP256V1_ORDER_R2;
848  }
849  else if(osStrcmp(curve->name, "curveSM2") == 0)
850  {
851  r2 = SM2_ORDER_R2;
852  m = SM2_ORDER_M;
853  }
854  else
855  {
856  r2 = NULL;
857  m = 0;
858  }
859 
860  //Valid parameters?
861  if(r2 != NULL && m != 0)
862  {
863  //Acquire exclusive access to the RSA module
864  esp_crypto_mpi_lock_acquire();
865 
866  //Clear the interrupt flag
867  REG_WRITE(RSA_INT_CLR_REG, 1);
868  //Set mode register
869  REG_WRITE(RSA_MODE_REG, n - 1);
870 
871  //Copy the first operand to RSA_X_MEM
872  for(i = 0; i < n; i++)
873  {
874  REG_WRITE(RSA_X_MEM + i * 4, a[i]);
875  }
876 
877  //Copy the second operand to RSA_Y_MEM
878  for(i = 0; i < n; i++)
879  {
880  REG_WRITE(RSA_Y_MEM + i * 4, b[i]);
881  }
882 
883  //Copy the modulus to RSA_M_MEM
884  for(i = 0; i < n; i++)
885  {
886  REG_WRITE(RSA_M_MEM + i * 4, curve->q[i]);
887  }
888 
889  //Copy the pre-calculated value of R^2 mod M to RSA_Z_MEM
890  for(i = 0; i < n; i++)
891  {
892  REG_WRITE(RSA_Z_MEM + i * 4, r2[i]);
893  }
894 
895  //Write the value of M' to RSA_M_PRIME_REG
896  REG_WRITE(RSA_M_PRIME_REG, m);
897  //Start large-number modular multiplication
898  REG_WRITE(RSA_SET_START_MODMULT_REG, 1);
899 
900  //Wait for the operation to complete
901  while(REG_READ(RSA_QUERY_IDLE_REG) == 0)
902  {
903  }
904 
905  //Read the result from RSA_Z_MEM
906  for(i = 0; i < n; i++)
907  {
908  r[i] = REG_READ(RSA_Z_MEM + i * 4);
909  }
910 
911  //Clear the interrupt flag
912  REG_WRITE(RSA_INT_CLR_REG, 1);
913 
914  //Release exclusive access to the RSA module
915  esp_crypto_mpi_lock_release();
916  }
917  else
918  {
919  uint32_t u[EC_MAX_ORDER_SIZE * 2];
920 
921  //Compute R = (A * B) mod q
922  ecScalarMul(u, u + n, a, b, n);
923  curve->scalarMod(curve, r, u);
924  }
925 }
926 
927 
928 /**
929  * @brief Modular squaring
930  * @param[in] curve Elliptic curve parameters
931  * @param[out] r Resulting integer R = A^2 mod q
932  * @param[in] a An integer such as 0 <= A < q
933  **/
934 
935 void ecScalarSqrMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
936 {
937  //Compute R = (A ^ 2) mod q
938  ecScalarMulMod(curve, r, a, a);
939 }
940 
941 #endif
942 #endif
error_t mpiShiftLeft(Mpi *r, uint_t n)
Left shift operation.
Definition: mpi.c:1243
uint8_t b
Definition: nbns_common.h:104
const uint32_t SECP521R1_PRIME_R2[17]
const uint32_t BRAINPOOLP256R1_ORDER_R2[8]
#define SECP384R1_PRIME_M
uint8_t a
Definition: ndp.h:411
Arbitrary precision integer.
Definition: mpi.h:102
const uint32_t SM2_ORDER_R2[8]
uint8_t p
Definition: ndp.h:300
uint8_t t
Definition: lldp_ext_med.h:212
const uint32_t BRAINPOOLP384R1_ORDER_R2[12]
#define EC_MAX_ORDER_SIZE
Definition: ec.h:315
const uint32_t FRP256V1_PRIME_R2[8]
void ecScalarSqr(uint32_t *r, const uint32_t *a, uint_t n)
Squaring operation.
#define BRAINPOOLP384R1_ORDER_M
#define osStrcmp(s1, s2)
Definition: os_port.h:174
void ecScalarMulMod(const EcCurve *curve, uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular multiplication.
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:48
#define SECP256R1_PRIME_M
void ecScalarMul(uint32_t *rl, uint32_t *rh, const uint32_t *a, const uint32_t *b, uint_t n)
Multiplication of two integers.
ESP32-C6 hardware cryptographic accelerator.
uint8_t r
Definition: ndp.h:346
error_t mpiMod(Mpi *r, const Mpi *a, const Mpi *p)
Modulo operation.
Definition: mpi.c:1587
ESP32-C6 public-key hardware accelerator.
#define SECP256R1_ORDER_M
#define FRP256V1_ORDER_M
#define SM2_PRIME_M
#define SM2_ORDER_M
error_t
Error codes.
Definition: error.h:43
#define SECP224R1_ORDER_M
#define SECP384R1_ORDER_M
error_t mpiSetValue(Mpi *r, mpi_sword_t a)
Set the value of a multiple precision integer.
Definition: mpi.c:562
#define SECP521R1_PRIME_M
#define SECP256K1_PRIME_M
const uint32_t SECP256R1_PRIME_R2[8]
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
Helper routines for ECC.
#define BRAINPOOLP256R1_PRIME_M
const uint32_t BRAINPOOLP512R1_ORDER_R2[16]
#define BRAINPOOLP512R1_PRIME_M
void ecScalarSqrMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Modular squaring.
RSA public-key cryptography standard.
#define SECP224R1_PRIME_M
const uint32_t SM2_PRIME_R2[8]
const uint32_t FRP256V1_ORDER_R2[8]
uint8_t u
Definition: lldp_ext_med.h:213
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:254
const uint32_t BRAINPOOLP256R1_PRIME_R2[8]
#define MAX(a, b)
Definition: os_port.h:67
uint_t mpiGetLength(const Mpi *a)
Get the actual length in words.
Definition: mpi.c:188
const uint32_t SECP256K1_PRIME_R2[8]
void esp32c6RsaInit(void)
RSA module initialization.
uint8_t m
Definition: ndp.h:304
void ecFieldSqrMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Modular squaring.
uint8_t n
#define BRAINPOOLP384R1_PRIME_M
#define SECP256K1_ORDER_M
const uint32_t SECP521R1_ORDER_R2[17]
const uint32_t SECP384R1_ORDER_R2[12]
uint_t size
Definition: mpi.h:104
#define BRAINPOOLP512R1_ORDER_M
const uint32_t SECP256R1_ORDER_R2[8]
#define FRP256V1_PRIME_M
const uint32_t BRAINPOOLP512R1_PRIME_R2[16]
const uint32_t SECP384R1_PRIME_R2[12]
#define EcCurve
Definition: ec.h:346
#define BRAINPOOLP256R1_ORDER_M
const uint32_t SECP256K1_ORDER_R2[8]
unsigned int uint_t
Definition: compiler_port.h:57
void ecFieldMulMod(const EcCurve *curve, uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular multiplication.
const uint32_t SECP224R1_ORDER_R2[7]
#define SECP521R1_ORDER_M
error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision multiplication.
ECC (Elliptic Curve Cryptography)
mpi_word_t * data
Definition: mpi.h:106
error_t mpiGrow(Mpi *r, uint_t size)
Adjust the size of multiple precision integer.
Definition: mpi.c:102
const uint32_t SECP224R1_PRIME_R2[7]
error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation.
#define EC_MAX_MODULUS_SIZE
Definition: ec.h:284
const uint32_t BRAINPOOLP384R1_PRIME_R2[12]
Debugging facilities.
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:64