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