ecdsa.c
Go to the documentation of this file.
1 /**
2  * @file ecdsa.c
3  * @brief ECDSA (Elliptic Curve Digital Signature Algorithm)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2026 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.6.2
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/crypto.h"
36 #include "ecc/ecdsa.h"
37 #include "ecc/ec_misc.h"
38 #include "encoding/asn1.h"
39 #include "rng/hmac_drbg.h"
40 #include "debug.h"
41 
42 //Check crypto library configuration
43 #if (ECDSA_SUPPORT == ENABLED)
44 
45 //ECDSA with SHA-1 OID (1.2.840.10045.4.1)
46 const uint8_t ECDSA_WITH_SHA1_OID[7] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x01};
47 //ECDSA with SHA-224 OID (1.2.840.10045.4.3.1)
48 const uint8_t ECDSA_WITH_SHA224_OID[8] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01};
49 //ECDSA with SHA-256 OID (1.2.840.10045.4.3.2)
50 const uint8_t ECDSA_WITH_SHA256_OID[8] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02};
51 //ECDSA with SHA-384 OID (1.2.840.10045.4.3.3)
52 const uint8_t ECDSA_WITH_SHA384_OID[8] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03};
53 //ECDSA with SHA-512 OID (1.2.840.10045.4.3.4)
54 const uint8_t ECDSA_WITH_SHA512_OID[8] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x04};
55 //ECDSA with SHA-3-224 OID (2.16.840.1.101.3.4.3.9)
56 const uint8_t ECDSA_WITH_SHA3_224_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x09};
57 //ECDSA with SHA-3-256 OID (2.16.840.1.101.3.4.3.10)
58 const uint8_t ECDSA_WITH_SHA3_256_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0A};
59 //ECDSA with SHA-3-384 OID (2.16.840.1.101.3.4.3.11)
60 const uint8_t ECDSA_WITH_SHA3_384_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0B};
61 //ECDSA with SHA-3-512 OID (2.16.840.1.101.3.4.3.12)
62 const uint8_t ECDSA_WITH_SHA3_512_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0C};
63 //ECDSA with SHAKE128 OID (1.3.6.1.5.5.7.6.32)
64 const uint8_t ECDSA_WITH_SHAKE128_OID[8] = {0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x06, 0x20};
65 //ECDSA with SHAKE256 OID (1.3.6.1.5.5.7.6.33)
66 const uint8_t ECDSA_WITH_SHAKE256_OID[8] = {0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x06, 0x21};
67 
68 
69 /**
70  * @brief Initialize an ECDSA signature
71  * @param[in] signature Pointer to the ECDSA signature to initialize
72  **/
73 
75 {
76  //Initialize elliptic curve parameters
77  signature->curve = NULL;
78 
79  //Initialize (R, S) integer pair
80  ecScalarSetInt(signature->r, 0, EC_MAX_ORDER_SIZE);
81  ecScalarSetInt(signature->s, 0, EC_MAX_ORDER_SIZE);
82 }
83 
84 
85 /**
86  * @brief Release an ECDSA signature
87  * @param[in] signature Pointer to the ECDSA signature to free
88  **/
89 
91 {
92  //Clear ECDSA signature
93  osMemset(signature, 0, sizeof(EcdsaSignature));
94 }
95 
96 
97 /**
98  * @brief Import an ECDSA signature
99  * @param[out] signature ECDSA signature
100  * @param[in] curve Elliptic curve parameters
101  * @param[in] input Pointer to the octet string
102  * @param[in] length Length of the octet string, in bytes
103  * @param[in] format ECDSA signature format (ASN.1 or raw format)
104  * @return Error code
105  **/
106 
108  const uint8_t *input, size_t length, EcdsaSignatureFormat format)
109 {
110  error_t error;
111  size_t n;
112 
113  //Check parameters
114  if(signature == NULL || curve == NULL || input == NULL)
116 
117  //Get the length of the order, in bytes
118  n = (curve->orderSize + 7) / 8;
119 
120  //Debug message
121  TRACE_DEBUG("Importing ECDSA signature...\r\n");
122 
123  //Dump ECDSA signature
124  TRACE_DEBUG(" signature:\r\n");
125  TRACE_DEBUG_ARRAY(" ", input, length);
126 
127  //Check the format of the ECDSA signature
128  if(format == ECDSA_SIGNATURE_FORMAT_ASN1)
129  {
130  Asn1Tag tag;
131 
132  //Display ASN.1 structure
133  error = asn1DumpObject(input, length, 0);
134  //Any error to report?
135  if(error)
136  return error;
137 
138  //Read the contents of the ASN.1 structure
139  error = asn1ReadSequence(input, length, &tag);
140  //Failed to decode ASN.1 tag?
141  if(error)
142  return error;
143 
144  //Malformed ECDSA signature?
145  if(length != tag.totalLength)
146  return ERROR_INVALID_SYNTAX;
147 
148  //Point to the first field
149  input = tag.value;
150  length = tag.length;
151 
152  //Read the integer R
153  error = asn1ReadTag(input, length, &tag);
154  //Failed to decode ASN.1 tag?
155  if(error)
156  return error;
157 
158  //Enforce encoding, class and type
159  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
161  //Invalid tag?
162  if(error)
163  return error;
164 
165  //Make sure R is a positive integer
166  if(tag.length == 0 || (tag.value[0] & 0x80) != 0)
167  return ERROR_INVALID_SYNTAX;
168 
169  //Convert the octet string to an integer
170  error = ecScalarImport(signature->r, EC_MAX_ORDER_SIZE, tag.value,
172  //Any error to report?
173  if(error)
174  return error;
175 
176  //Point to the next field
177  input += tag.totalLength;
178  length -= tag.totalLength;
179 
180  //Read the integer S
181  error = asn1ReadTag(input, length, &tag);
182  //Failed to decode ASN.1 tag?
183  if(error)
184  return error;
185 
186  //Enforce encoding, class and type
187  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
189  //Invalid tag?
190  if(error)
191  return error;
192 
193  //Make sure S is a positive integer
194  if(tag.length == 0 || (tag.value[0] & 0x80) != 0)
195  return ERROR_INVALID_SYNTAX;
196 
197  //Convert the octet string to an integer
198  error = ecScalarImport(signature->s, EC_MAX_ORDER_SIZE, tag.value,
200  //Any error to report?
201  if(error)
202  return error;
203 
204  //Malformed ECDSA signature?
205  if(length != tag.totalLength)
206  return ERROR_INVALID_SYNTAX;
207 
208  //Dump (R, S) integer pair
209  TRACE_DEBUG(" r:\r\n");
210  TRACE_DEBUG_EC_SCALAR(" ", signature->r, EC_MAX_ORDER_SIZE);
211  TRACE_DEBUG(" s:\r\n");
212  TRACE_DEBUG_EC_SCALAR(" ", signature->s, EC_MAX_ORDER_SIZE);
213  }
214  else if(format == ECDSA_SIGNATURE_FORMAT_RAW)
215  {
216  //Check the length of the octet string
217  if(length != (n * 2))
218  return ERROR_INVALID_LENGTH;
219 
220  //Convert R to an integer
221  error = ecScalarImport(signature->r, EC_MAX_ORDER_SIZE, input, n,
223  //Any error to report?
224  if(error)
225  return error;
226 
227  //Convert S to an integer
228  error = ecScalarImport(signature->s, EC_MAX_ORDER_SIZE,
229  input + n, n, EC_SCALAR_FORMAT_BIG_ENDIAN);
230  //Any error to report?
231  if(error)
232  return error;
233  }
234  else if(format == ECDSA_SIGNATURE_FORMAT_RAW_R)
235  {
236  //Convert R to an integer
237  error = ecScalarImport(signature->r, EC_MAX_ORDER_SIZE, input, length,
239  //Any error to report?
240  if(error)
241  return error;
242  }
243  else if(format == ECDSA_SIGNATURE_FORMAT_RAW_S)
244  {
245  //Convert S to an integer
246  error = ecScalarImport(signature->s, EC_MAX_ORDER_SIZE, input, length,
248  //Any error to report?
249  if(error)
250  return error;
251  }
252  else
253  {
254  //Invalid format
256  }
257 
258  //Save elliptic curve parameters
259  signature->curve = curve;
260 
261  //Successful processing
262  return NO_ERROR;
263 }
264 
265 
266 /**
267  * @brief Export an ECDSA signature
268  * @param[in] signature ECDSA signature
269  * @param[out] output Pointer to the octet string (optional parameter)
270  * @param[out] written Length of the resulting octet string, in bytes
271  * @param[in] format ECDSA signature format (ASN.1 or raw format)
272  * @return Error code
273  **/
274 
275 error_t ecdsaExportSignature(const EcdsaSignature *signature, uint8_t *output,
276  size_t *written, EcdsaSignatureFormat format)
277 {
278  error_t error;
279  size_t k;
280  size_t n;
281  size_t length;
282  size_t orderLen;
283  uint8_t *p;
284  Asn1Tag tag;
285 
286  //Check parameters
287  if(signature == NULL || written == NULL)
289 
290  //Invalid elliptic curve?
291  if(signature->curve == NULL)
293 
294  //Get the length of the order, in words
295  orderLen = (signature->curve->orderSize + 31) / 32;
296 
297  //Debug message
298  TRACE_DEBUG("Exporting ECDSA signature...\r\n");
299 
300  //Dump (R, S) integer pair
301  TRACE_DEBUG(" r:\r\n");
302  TRACE_DEBUG_EC_SCALAR(" ", signature->r, orderLen);
303  TRACE_DEBUG(" s:\r\n");
304  TRACE_DEBUG_EC_SCALAR(" ", signature->s, orderLen);
305 
306  //Check the format of the ECDSA signature
307  if(format == ECDSA_SIGNATURE_FORMAT_ASN1)
308  {
309  //Point to the buffer where to write the ASN.1 structure
310  p = output;
311  //Length of the ASN.1 structure
312  length = 0;
313 
314  //R is always encoded in the smallest possible number of octets
315  k = ecScalarGetBitLength(signature->r, orderLen) / 8 + 1;
316 
317  //R is represented by an integer
318  tag.constructed = FALSE;
321  tag.length = k;
322 
323  //Write the corresponding ASN.1 tag
324  error = asn1WriteHeader(&tag, FALSE, p, &n);
325  //Any error to report?
326  if(error)
327  return error;
328 
329  //Advance data pointer
330  ASN1_INC_POINTER(p, n);
331  length += n;
332 
333  //If the output parameter is NULL, then the function calculates the
334  //length of the ASN.1 structure without copying any data
335  if(p != NULL)
336  {
337  //Convert R to an octet string
338  error = ecScalarExport(signature->r, EC_MAX_ORDER_SIZE, p, k,
340  //Any error to report?
341  if(error)
342  return error;
343  }
344 
345  //Advance data pointer
346  ASN1_INC_POINTER(p, k);
347  length += k;
348 
349  //S is always encoded in the smallest possible number of octets
350  k = ecScalarGetBitLength(signature->s, orderLen) / 8 + 1;
351 
352  //S is represented by an integer
353  tag.constructed = FALSE;
356  tag.length = k;
357 
358  //Write the corresponding ASN.1 tag
359  error = asn1WriteHeader(&tag, FALSE, p, &n);
360  //Any error to report?
361  if(error)
362  return error;
363 
364  //Advance data pointer
365  ASN1_INC_POINTER(p, n);
366  length += n;
367 
368  //If the output parameter is NULL, then the function calculates the
369  //length of the ASN.1 structure without copying any data
370  if(p != NULL)
371  {
372  //Convert S to an octet string
373  error = ecScalarExport(signature->s, EC_MAX_ORDER_SIZE, p, k,
375  //Any error to report?
376  if(error)
377  return error;
378  }
379 
380  //Advance data pointer
381  ASN1_INC_POINTER(p, k);
382  length += k;
383 
384  //The (R, S) integer pair is encapsulated within a sequence
385  tag.constructed = TRUE;
388  tag.length = length;
389 
390  //Write the corresponding ASN.1 tag
391  error = asn1InsertHeader(&tag, output, &n);
392  //Any error to report?
393  if(error)
394  return error;
395 
396  //Total length of the ASN.1 structure
397  *written = length + n;
398  }
399  else if(format == ECDSA_SIGNATURE_FORMAT_RAW)
400  {
401  //Get the length of the order, in bytes
402  n = (signature->curve->orderSize + 7) / 8;
403 
404  //If the output parameter is NULL, then the function calculates the
405  //length of the octet string without copying any data
406  if(output != NULL)
407  {
408  //Convert R to an octet string
409  error = ecScalarExport(signature->r, (n + 3) / 4, output, n,
411  //Any error to report?
412  if(error)
413  return error;
414 
415  //Convert S to an octet string
416  error = ecScalarExport(signature->s, (n + 3) / 4, output + n, n,
418  //Any error to report?
419  if(error)
420  return error;
421  }
422 
423  //Length of the resulting octet string
424  *written = 2 * n;
425  }
426  else if(format == ECDSA_SIGNATURE_FORMAT_RAW_R)
427  {
428  //Get the length of the order, in bytes
429  n = (signature->curve->orderSize + 7) / 8;
430 
431  //If the output parameter is NULL, then the function calculates the
432  //length of the octet string without copying any data
433  if(output != NULL)
434  {
435  //Convert R to an octet string
436  error = ecScalarExport(signature->r, (n + 3) / 4, output, n,
438  //Any error to report?
439  if(error)
440  return error;
441  }
442 
443  //Length of the resulting octet string
444  *written = n;
445  }
446  else if(format == ECDSA_SIGNATURE_FORMAT_RAW_S)
447  {
448  //Get the length of the order, in bytes
449  n = (signature->curve->orderSize + 7) / 8;
450 
451  //If the output parameter is NULL, then the function calculates the
452  //length of the octet string without copying any data
453  if(output != NULL)
454  {
455  //Convert S to an octet string
456  error = ecScalarExport(signature->s, (n + 3) / 4, output, n,
458  //Any error to report?
459  if(error)
460  return error;
461  }
462 
463  //Length of the resulting octet string
464  *written = n;
465  }
466  else
467  {
468  //Invalid format
470  }
471 
472  //Dump ECDSA signature
473  if(output != NULL)
474  {
475  TRACE_DEBUG(" signature:\r\n");
476  TRACE_DEBUG_ARRAY(" ", output, *written);
477  }
478 
479  //Successful processing
480  return NO_ERROR;
481 }
482 
483 
484 /**
485  * @brief ECDSA signature generation
486  * @param[in] prngAlgo PRNG algorithm
487  * @param[in] prngContext Pointer to the PRNG context
488  * @param[in] privateKey Signer's EC private key
489  * @param[in] digest Digest of the message to be signed
490  * @param[in] digestLen Length in octets of the digest
491  * @param[out] signature (R, S) integer pair
492  * @return Error code
493  **/
494 
495 __weak_func error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo,
496  void *prngContext, const EcPrivateKey *privateKey, const uint8_t *digest,
497  size_t digestLen, EcdsaSignature *signature)
498 {
499  error_t error;
500  uint_t n;
501  uint_t pLen;
502  uint_t qLen;
503 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
505 #else
507 #endif
508 
509  //Check parameters
510  if(privateKey == NULL || digest == NULL || signature == NULL)
512 
513  //Invalid elliptic curve?
514  if(privateKey->curve == NULL)
516 
517  //Get the length of the modulus, in words
518  pLen = (privateKey->curve->fieldSize + 31) / 32;
519  //Get the length of the order, in words
520  qLen = (privateKey->curve->orderSize + 31) / 32;
521 
522  //Debug message
523  TRACE_DEBUG("ECDSA signature generation...\r\n");
524  TRACE_DEBUG(" curve: %s\r\n", privateKey->curve->name);
525  TRACE_DEBUG(" private key:\r\n");
526  TRACE_DEBUG_EC_SCALAR(" ", privateKey->d, qLen);
527  TRACE_DEBUG(" digest:\r\n");
528  TRACE_DEBUG_ARRAY(" ", digest, digestLen);
529 
530 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
531  //Allocate working state
533  //Failed to allocate memory?
534  if(state == NULL)
535  return ERROR_OUT_OF_MEMORY;
536 #endif
537 
538  //Initialize working state
539  osMemset(state, 0, sizeof(EcdsaGenerateSignatureState));
540 
541  //Initialize (R, S) integer pair
542  ecScalarSetInt(signature->r, 0, EC_MAX_ORDER_SIZE);
543  ecScalarSetInt(signature->s, 0, EC_MAX_ORDER_SIZE);
544 
545  //Let N be the bit length of q
546  n = privateKey->curve->orderSize;
547  //Compute N = MIN(N, outlen)
548  n = MIN(n, digestLen * 8);
549 
550  //Convert the digest to an integer
551  error = ecScalarImport(state->z, qLen, digest, (n + 7) / 8,
553 
554  //Check status code
555  if(!error)
556  {
557  uint32_t c;
558  uint32_t z2[EC_MAX_ORDER_SIZE];
559 
560  //Keep the leftmost N bits of the hash value
561  if((n % 8) != 0)
562  {
563  ecScalarShiftRight(state->z, state->z, 8 - (n % 8), qLen);
564  }
565 
566  //Debug message
567  TRACE_DEBUG(" z:\r\n");
568  TRACE_DEBUG_EC_SCALAR(" ", state->z, qLen);
569 
570  //z is reduced modulo q. The modular reduction can be implemented with a
571  //simple conditional subtraction
572  c = ecScalarSub(z2, state->z, privateKey->curve->q, qLen);
573  ecScalarSelect(state->z, z2, state->z, c, qLen);
574  }
575 
576  //ECDSA signature generation process
577  while(!error)
578  {
579  //Generate a random number k such as 0 < k < q - 1
580  error = ecScalarRand(privateKey->curve, state->k, prngAlgo, prngContext);
581 
582  //Check status code
583  if(!error)
584  {
585  //Debug message
586  TRACE_DEBUG(" k:\r\n");
587  TRACE_DEBUG_EC_SCALAR(" ", state->k, qLen);
588 
589  //Compute R1 = (x1, y1) = k.G
590  error = ecMulRegular(privateKey->curve, &state->r1, state->k,
591  &privateKey->curve->g);
592  }
593 
594  //Check status code
595  if(!error)
596  {
597  //Convert R1 to affine representation
598  error = ecAffinify(privateKey->curve, &state->r1, &state->r1);
599  }
600 
601  //Check status code
602  if(!error)
603  {
604  //Debug message
605  TRACE_DEBUG(" x1:\r\n");
606  TRACE_DEBUG_EC_SCALAR(" ", state->r1.x, pLen);
607  TRACE_DEBUG(" y1:\r\n");
608  TRACE_DEBUG_EC_SCALAR(" ", state->r1.y, pLen);
609 
610  //Compute r = x1 mod q
611  ecScalarMod(signature->r, state->r1.x, pLen, privateKey->curve->q, qLen);
612  //Compute k ^ -1 mod q
613  ecScalarInvMod(privateKey->curve, state->k, state->k);
614 
615  //Compute s = k ^ -1 * (z + x * r) mod q
616  ecScalarMulMod(privateKey->curve, signature->s, privateKey->d, signature->r);
617  ecScalarAddMod(privateKey->curve, signature->s, signature->s, state->z);
618  ecScalarMulMod(privateKey->curve, signature->s, signature->s, state->k);
619 
620  //The values of r and s shall be checked to determine if r = 0 or s = 0.
621  //If either r = 0 or s = 0, a new value of k shall be generated, and the
622  //signature shall be recalculated (refer to FIPS 186-5, section 6.4.1)
623  if(ecScalarCompInt(signature->r, 0, qLen) != 0 &&
624  ecScalarCompInt(signature->s, 0, qLen) != 0)
625  {
626  break;
627  }
628  }
629  }
630 
631  //Check status code
632  if(!error)
633  {
634  //Save elliptic curve parameters
635  signature->curve = privateKey->curve;
636 
637  //Debug message
638  TRACE_DEBUG(" r:\r\n");
639  TRACE_DEBUG_EC_SCALAR(" ", signature->r, qLen);
640  TRACE_DEBUG(" s:\r\n");
641  TRACE_DEBUG_EC_SCALAR(" ", signature->s, qLen);
642  }
643 
644  //Erase working state
645  osMemset(state, 0, sizeof(EcdsaGenerateSignatureState));
646 
647 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
648  //Release working state
649  cryptoFreeMem(state);
650 #endif
651 
652  //Return status code
653  return error;
654 }
655 
656 
657 /**
658  * @brief Deterministic ECDSA signature generation
659  * @param[in] privateKey Signer's EC private key
660  * @param[in] hashAlgo Underlying hash function
661  * @param[in] digest Digest of the message to be signed
662  * @param[out] signature (R, S) integer pair
663  * @return Error code
664  **/
665 
667  const HashAlgo *hashAlgo, const uint8_t *digest, EcdsaSignature *signature)
668 {
669  error_t error;
670  uint_t n;
671  uint_t pLen;
672  uint_t qLen;
673 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
675 #else
677 #endif
678 
679  //Check parameters
680  if(hashAlgo == NULL || privateKey == NULL || digest == NULL ||
681  signature == NULL)
682  {
684  }
685 
686  //Invalid elliptic curve?
687  if(privateKey->curve == NULL)
689 
690  //Get the length of the modulus, in words
691  pLen = (privateKey->curve->fieldSize + 31) / 32;
692  //Get the length of the order, in words
693  qLen = (privateKey->curve->orderSize + 31) / 32;
694 
695  //Debug message
696  TRACE_DEBUG("ECDSA signature generation...\r\n");
697  TRACE_DEBUG(" curve: %s\r\n", privateKey->curve->name);
698  TRACE_DEBUG(" private key:\r\n");
699  TRACE_DEBUG_EC_SCALAR(" ", privateKey->d, qLen);
700  TRACE_DEBUG(" digest:\r\n");
701  TRACE_DEBUG_ARRAY(" ", digest, hashAlgo->digestSize);
702 
703 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
704  //Allocate working state
706  //Failed to allocate memory?
707  if(state == NULL)
708  return ERROR_OUT_OF_MEMORY;
709 #endif
710 
711  //Initialize working state
712  osMemset(state, 0, sizeof(EcdsaGenerateSignatureState));
713 
714  //Initialize (R, S) integer pair
715  ecScalarSetInt(signature->r, 0, EC_MAX_ORDER_SIZE);
716  ecScalarSetInt(signature->s, 0, EC_MAX_ORDER_SIZE);
717 
718  //Let N be the bit length of q
719  n = privateKey->curve->orderSize;
720  //Compute N = MIN(N, outlen)
721  n = MIN(n, hashAlgo->digestSize * 8);
722 
723  //Convert the digest to an integer
724  error = ecScalarImport(state->z, qLen, digest, (n + 7) / 8,
726 
727  //Check status code
728  if(!error)
729  {
730  uint32_t c;
731  uint32_t z2[EC_MAX_ORDER_SIZE];
732 
733  //Keep the leftmost N bits of the hash value
734  if((n % 8) != 0)
735  {
736  ecScalarShiftRight(state->z, state->z, 8 - (n % 8), qLen);
737  }
738 
739  //Debug message
740  TRACE_DEBUG(" z:\r\n");
741  TRACE_DEBUG_EC_SCALAR(" ", state->z, qLen);
742 
743  //z is reduced modulo q. The modular reduction can be implemented with a
744  //simple conditional subtraction
745  c = ecScalarSub(z2, state->z, privateKey->curve->q, qLen);
746  ecScalarSelect(state->z, z2, state->z, c, qLen);
747 
748  //Compute the pseudorandom k for signature generation
749  error = ecdsaGenerateK(privateKey->curve, hashAlgo, privateKey->d,
750  state->z, state->k);
751  }
752 
753  //Check status code
754  if(!error)
755  {
756  //Debug message
757  TRACE_DEBUG(" k:\r\n");
758  TRACE_DEBUG_EC_SCALAR(" ", state->k, qLen);
759 
760  //Compute R1 = (x1, y1) = k.G
761  error = ecMulRegular(privateKey->curve, &state->r1, state->k,
762  &privateKey->curve->g);
763  }
764 
765  //Check status code
766  if(!error)
767  {
768  //Convert R1 to affine representation
769  error = ecAffinify(privateKey->curve, &state->r1, &state->r1);
770  }
771 
772  //Check status code
773  if(!error)
774  {
775  //Debug message
776  TRACE_DEBUG(" x1:\r\n");
777  TRACE_DEBUG_EC_SCALAR(" ", state->r1.x, pLen);
778  TRACE_DEBUG(" y1:\r\n");
779  TRACE_DEBUG_EC_SCALAR(" ", state->r1.y, pLen);
780 
781  //Compute r = x1 mod q
782  ecScalarMod(signature->r, state->r1.x, pLen, privateKey->curve->q, qLen);
783  //Compute k ^ -1 mod q
784  ecScalarInvMod(privateKey->curve, state->k, state->k);
785 
786  //Compute s = k ^ -1 * (z + x * r) mod q
787  ecScalarMulMod(privateKey->curve, signature->s, privateKey->d, signature->r);
788  ecScalarAddMod(privateKey->curve, signature->s, signature->s, state->z);
789  ecScalarMulMod(privateKey->curve, signature->s, signature->s, state->k);
790 
791  //Save elliptic curve parameters
792  signature->curve = privateKey->curve;
793 
794  //Debug message
795  TRACE_DEBUG(" r:\r\n");
796  TRACE_DEBUG_EC_SCALAR(" ", signature->r, qLen);
797  TRACE_DEBUG(" s:\r\n");
798  TRACE_DEBUG_EC_SCALAR(" ", signature->s, qLen);
799 
800  //If r = 0 or if s = 0, and k was generated deterministically, then
801  //output failure (refer to FIPS 186-5, section 6.4.1)
802  if(ecScalarCompInt(signature->r, 0, qLen) == 0 ||
803  ecScalarCompInt(signature->s, 0, qLen) == 0)
804  {
805  error = ERROR_FAILURE;
806  }
807  }
808 
809  //Erase working state
810  osMemset(state, 0, sizeof(EcdsaGenerateSignatureState));
811 
812 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
813  //Release working state
814  cryptoFreeMem(state);
815 #endif
816 
817  //Return status code
818  return error;
819 }
820 
821 
822 /**
823  * @brief Generation of pseudorandom k
824  * @param[in] curve Elliptic curve parameters
825  * @param[in] hashAlgo Underlying hash function
826  * @param[in] x ECDSA private key
827  * @param[in] h Digest of the message to be signed
828  * @param[in] k Pseudorandom value k
829  * @return Error code
830  **/
831 
832 error_t ecdsaGenerateK(const EcCurve *curve, const HashAlgo *hashAlgo,
833  const uint32_t *x, const uint32_t *h, uint32_t *k)
834 {
835 #if (HMAC_DRBG_SUPPORT == ENABLED)
836  error_t error;
837  size_t n;
838  uint8_t seed[EC_MAX_ORDER_SIZE * 8];
839  uint8_t t[EC_MAX_ORDER_SIZE * 4];
840  uint32_t q[EC_MAX_ORDER_SIZE];
841 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
842  HmacDrbgContext *hmacDrbgContext;
843 #else
844  HmacDrbgContext hmacDrbgContext[1];
845 #endif
846 
847 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
848  //Allocate HMAC_DRBG context
849  hmacDrbgContext = cryptoAllocMem(sizeof(HmacDrbgContext));
850  //Failed to allocate memory?
851  if(hmacDrbgContext == NULL)
852  return ERROR_OUT_OF_MEMORY;
853 #endif
854 
855  //Get the length of the order, in bytes
856  n = (curve->orderSize + 7) / 8;
857 
858  //Instantiate HMAC_DRBG using HMAC parameterized with the same hash function
859  //H as the one used for processing the message that is to be signed (refer
860  //to RFC 6979, section 3.3)
861  error = hmacDrbgInit(hmacDrbgContext, hashAlgo);
862 
863  //Check status code
864  if(!error)
865  {
866  //The private key is used as entropy string
867  error = ecScalarExport(x, (n + 3) / 4, seed, n,
869  }
870 
871  //Check status code
872  if(!error)
873  {
874  //The hashed message (truncated and expanded by bits2octets) is used as
875  //nonce. The entropy string and nonce are simply concatenated into the
876  //initial seed
877  error = ecScalarExport(h, (n + 3) / 4, seed + n, n,
879  }
880 
881  //Check status code
882  if(!error)
883  {
884  //For deterministic ECDSA, we want HMAC_DRBG to run with the entropy
885  //string and nonce that we specify, without accessing an actual entropy
886  //source
887  error = hmacDrbgSeed(hmacDrbgContext, seed, n * 2);
888  }
889 
890  //Repeat this step until an acceptable value is obtained
891  while(!error)
892  {
893  //Generate a candidate value for k by requesting qlen bits from HMAC_DRBG
894  error = hmacDrbgGenerate(hmacDrbgContext, t, n);
895 
896  //Check status code
897  if(!error)
898  {
899  //The resulting value is then converted to an integer value using the
900  //big-endian convention
901  error = ecScalarImport(k, (n + 3) / 4, t, n,
903  }
904 
905  //Check status code
906  if(!error)
907  {
908  //The qlen leftmost bits are kept, and subsequent bits are discarded
909  if(curve->orderSize < (n * 8))
910  {
911  ecScalarShiftRight(k, k, (n * 8) - curve->orderSize, (n + 3) / 4);
912  }
913 
914  //Precompte q-1
915  ecScalarSubInt(q, curve->q, 1, (n + 3) / 4);
916 
917  //If that value of k is within the [1,q-1] range, and is suitable for
918  //ECDSA, then the generation of k is finished
919  if(ecScalarCompInt(k, 0, (n + 3) / 4) > 0 &&
920  ecScalarComp(k, q, (n + 3) / 4) < 0)
921  {
922  //The obtained value of k can be used in ECDSA
923  break;
924  }
925  }
926  }
927 
928 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
929  //Release working state
930  cryptoFreeMem(hmacDrbgContext);
931 #endif
932 
933  //Return status code
934  return error;
935 #else
936  //HMAC_DRBG is not implemented
937  return ERROR_NOT_IMPLEMENTED;
938 #endif
939 }
940 
941 
942 /**
943  * @brief ECDSA signature verification
944  * @param[in] publicKey Signer's EC public key
945  * @param[in] digest Digest of the message whose signature is to be verified
946  * @param[in] digestLen Length in octets of the digest
947  * @param[in] signature (R, S) integer pair
948  * @return Error code
949  **/
950 
951 __weak_func error_t ecdsaVerifySignature(const EcPublicKey *publicKey,
952  const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
953 {
954  error_t error;
955  uint_t n;
956  uint_t pLen;
957  uint_t qLen;
958 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
960 #else
961  EcdsaVerifySignatureState state[1];
962 #endif
963 
964  //Check parameters
965  if(publicKey == NULL || digest == NULL || signature == NULL)
967 
968  //Invalid elliptic curve?
969  if(publicKey->curve == NULL)
971 
972  //Get the length of the modulus, in words
973  pLen = (publicKey->curve->fieldSize + 31) / 32;
974  //Get the length of the order, in words
975  qLen = (publicKey->curve->orderSize + 31) / 32;
976 
977  //Debug message
978  TRACE_DEBUG("ECDSA signature verification...\r\n");
979  TRACE_DEBUG(" curve: %s\r\n", publicKey->curve->name);
980  TRACE_DEBUG(" public key X:\r\n");
981  TRACE_DEBUG_EC_SCALAR(" ", publicKey->q.x, pLen);
982  TRACE_DEBUG(" public key Y:\r\n");
983  TRACE_DEBUG_EC_SCALAR(" ", publicKey->q.y, pLen);
984  TRACE_DEBUG(" digest:\r\n");
985  TRACE_DEBUG_ARRAY(" ", digest, digestLen);
986  TRACE_DEBUG(" r:\r\n");
987  TRACE_DEBUG_EC_SCALAR(" ", signature->r, qLen);
988  TRACE_DEBUG(" s:\r\n");
989  TRACE_DEBUG_EC_SCALAR(" ", signature->s, qLen);
990 
991  //Verify that the public key is on the curve
992  if(!ecIsPointAffine(publicKey->curve, &publicKey->q))
993  {
995  }
996 
997  //The verifier shall check that 0 < r < q
998  if(ecScalarCompInt(signature->r, 0, EC_MAX_ORDER_SIZE) <= 0 ||
999  ecScalarComp(signature->r, publicKey->curve->q, EC_MAX_ORDER_SIZE) >= 0)
1000  {
1001  //If the condition is violated, the signature shall be rejected as invalid
1002  return ERROR_INVALID_SIGNATURE;
1003  }
1004 
1005  //The verifier shall check that 0 < s < q
1006  if(ecScalarCompInt(signature->s, 0, EC_MAX_ORDER_SIZE) <= 0 ||
1007  ecScalarComp(signature->s, publicKey->curve->q, EC_MAX_ORDER_SIZE) >= 0)
1008  {
1009  //If the condition is violated, the signature shall be rejected as invalid
1010  return ERROR_INVALID_SIGNATURE;
1011  }
1012 
1013 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1014  //Allocate working state
1015  state = cryptoAllocMem(sizeof(EcdsaVerifySignatureState));
1016  //Failed to allocate memory?
1017  if(state == NULL)
1018  return ERROR_OUT_OF_MEMORY;
1019 #endif
1020 
1021  //Initialize working state
1022  osMemset(state, 0, sizeof(EcdsaVerifySignatureState));
1023 
1024  //Let N be the bit length of q
1025  n = publicKey->curve->orderSize;
1026  //Compute N = MIN(N, outlen)
1027  n = MIN(n, digestLen * 8);
1028 
1029  //Convert the digest to an integer
1030  error = ecScalarImport(state->z, qLen, digest, (n + 7) / 8,
1032 
1033  //Check status code
1034  if(!error)
1035  {
1036  //Keep the leftmost N bits of the hash value
1037  if((n % 8) != 0)
1038  {
1039  ecScalarShiftRight(state->z, state->z, 8 - (n % 8), qLen);
1040  }
1041 
1042  //Compute w = s ^ -1 mod q
1043  ecScalarInvMod(publicKey->curve, state->w, signature->s);
1044 
1045  //Compute u1 = z * w mod q
1046  ecScalarMulMod(publicKey->curve, state->u1, state->z, state->w);
1047  //Compute u2 = r * w mod q
1048  ecScalarMulMod(publicKey->curve, state->u2, signature->r, state->w);
1049 
1050  //Convert the public key to projective representation
1051  ecProjectify(publicKey->curve, &state->v1, &publicKey->q);
1052 
1053  //Compute V0 = (x0, y0) = u1.G + u2.Q
1054  error = ecTwinMul(publicKey->curve, &state->v0, state->u1,
1055  &publicKey->curve->g, state->u2, &state->v1);
1056  }
1057 
1058  //Check status code
1059  if(!error)
1060  {
1061  //Convert V0 to affine representation
1062  error = ecAffinify(publicKey->curve, &state->v0, &state->v0);
1063  }
1064 
1065  //Check status code
1066  if(!error)
1067  {
1068  //Debug message
1069  TRACE_DEBUG(" x0:\r\n");
1070  TRACE_DEBUG_EC_SCALAR(" ", state->v0.x, pLen);
1071  TRACE_DEBUG(" y0:\r\n");
1072  TRACE_DEBUG_EC_SCALAR(" ", state->v0.y, pLen);
1073 
1074  //Compute v = x0 mod q
1075  ecScalarMod(state->v, state->v0.x, pLen, publicKey->curve->q, qLen);
1076 
1077  //Debug message
1078  TRACE_DEBUG(" v:\r\n");
1079  TRACE_DEBUG_EC_SCALAR(" ", state->v, qLen);
1080 
1081  //If v = r, then the signature is verified. If v does not equal r, then the
1082  //message or the signature may have been modified
1083  if(ecScalarComp(state->v, signature->r, qLen) == 0)
1084  {
1085  error = NO_ERROR;
1086  }
1087  else
1088  {
1089  error = ERROR_INVALID_SIGNATURE;
1090  }
1091  }
1092 
1093  //Erase working state
1094  osMemset(state, 0, sizeof(EcdsaVerifySignatureState));
1095 
1096 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1097  //Release working state
1098  cryptoFreeMem(state);
1099 #endif
1100 
1101  //Return status code
1102  return error;
1103 }
1104 
1105 #endif
error_t ecdsaImportSignature(EcdsaSignature *signature, const EcCurve *curve, const uint8_t *input, size_t length, EcdsaSignatureFormat format)
Import an ECDSA signature.
Definition: ecdsa.c:107
error_t ecScalarImport(uint32_t *r, uint_t n, const uint8_t *input, size_t length, EcScalarFormat format)
Octet string to integer conversion.
Definition: ec_misc.c:54
uint32_t u1[EC_MAX_ORDER_SIZE]
Definition: ecdsa.h:90
__weak_func error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const EcPrivateKey *privateKey, const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
ECDSA signature generation.
Definition: ecdsa.c:495
ECDSA signature.
Definition: ecdsa.h:63
__weak_func error_t ecAffinify(const EcCurve *curve, EcPoint3 *r, const EcPoint3 *s)
Recover affine representation.
Definition: ec.c:791
error_t ecScalarExport(const uint32_t *a, uint_t n, uint8_t *output, size_t length, EcScalarFormat format)
Integer to octet string conversion.
Definition: ec_misc.c:150
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
#define PrngAlgo
Definition: crypto.h:1035
ECDSA (Elliptic Curve Digital Signature Algorithm)
uint8_t p
Definition: ndp.h:300
uint8_t x
Definition: lldp_ext_med.h:211
const EcCurve * curve
Elliptic curve parameters.
Definition: ecdsa.h:64
const EcCurve * curve
Elliptic curve parameters.
Definition: ec.h:433
uint8_t t
Definition: lldp_ext_med.h:212
#define TRUE
Definition: os_port.h:50
error_t asn1WriteHeader(Asn1Tag *tag, bool_t reverse, uint8_t *data, size_t *written)
Write an ASN.1 tag header.
Definition: asn1.c:501
error_t asn1InsertHeader(Asn1Tag *tag, uint8_t *data, size_t *written)
Insert an ASN.1 tag header.
Definition: asn1.c:643
size_t digestSize
Definition: crypto.h:1157
const uint8_t ECDSA_WITH_SHA3_512_OID[9]
Definition: ecdsa.c:62
#define EC_MAX_ORDER_SIZE
Definition: ec.h:315
uint_t ecScalarGetBitLength(const uint32_t *a, uint_t n)
Get the actual length in bits.
Definition: ec_misc.c:273
const uint8_t ECDSA_WITH_SHA3_256_OID[9]
Definition: ecdsa.c:58
error_t asn1DumpObject(const uint8_t *data, size_t length, uint_t level)
Display an ASN.1 data object.
Definition: asn1.c:999
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
#define TRACE_DEBUG_EC_SCALAR(p, a, n)
Definition: debug.h:123
error_t asn1ReadTag(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 tag from the input stream.
Definition: asn1.c:52
uint32_t y[EC_MAX_MODULUS_SIZE]
y-coordinate
Definition: ec.h:400
const uint8_t ECDSA_WITH_SHA256_OID[8]
Definition: ecdsa.c:50
HMAC_DRBG PRNG context.
Definition: hmac_drbg.h:55
__weak_func error_t ecTwinMul(const EcCurve *curve, EcPoint3 *r, const uint32_t *d0, const EcPoint3 *s, const uint32_t *d1, const EcPoint3 *t)
Twin multiplication.
Definition: ec.c:1460
error_t ecdsaExportSignature(const EcdsaSignature *signature, uint8_t *output, size_t *written, EcdsaSignatureFormat format)
Export an ECDSA signature.
Definition: ecdsa.c:275
const uint8_t ECDSA_WITH_SHAKE256_OID[8]
Definition: ecdsa.c:66
size_t totalLength
Definition: asn1.h:111
@ ERROR_INVALID_ELLIPTIC_CURVE
Definition: error.h:134
void ecdsaFreeSignature(EcdsaSignature *signature)
Release an ECDSA signature.
Definition: ecdsa.c:90
size_t length
Definition: asn1.h:109
#define FALSE
Definition: os_port.h:46
uint8_t h
Definition: ndp.h:302
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t
Error codes.
Definition: error.h:43
uint32_t ecScalarSub(uint32_t *r, const uint32_t *a, const uint32_t *b, uint_t n)
Subtraction of two integers.
Definition: ec_misc.c:707
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:52
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
void ecScalarSetInt(uint32_t *a, uint32_t b, uint_t n)
Set integer value.
Definition: ec_misc.c:505
ASN.1 tag.
Definition: asn1.h:105
HMAC_DRBG pseudorandom number generator.
#define ASN1_INC_POINTER(p, n)
Definition: asn1.h:58
Helper routines for ECC.
void ecdsaInitSignature(EcdsaSignature *signature)
Initialize an ECDSA signature.
Definition: ecdsa.c:74
const uint8_t ECDSA_WITH_SHAKE128_OID[8]
Definition: ecdsa.c:64
uint32_t ecScalarSubInt(uint32_t *r, const uint32_t *a, uint32_t b, uint_t n)
Subtraction of two integers.
Definition: ec_misc.c:736
EcdsaSignatureFormat
ECDSA signature format.
Definition: ecdsa.h:50
uint32_t r[EC_MAX_ORDER_SIZE]
Integer R.
Definition: ecdsa.h:65
@ ECDSA_SIGNATURE_FORMAT_RAW
Definition: ecdsa.h:52
Working state (ECDSA signature generation)
Definition: ecdsa.h:75
const uint8_t ECDSA_WITH_SHA384_OID[8]
Definition: ecdsa.c:52
@ ERROR_INVALID_LENGTH
Definition: error.h:111
uint32_t z[EC_MAX_ORDER_SIZE]
Definition: ecdsa.h:89
General definitions for cryptographic algorithms.
void ecScalarInvMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Modular inversion.
Definition: ec_misc.c:1181
error_t hmacDrbgInit(HmacDrbgContext *context, const HashAlgo *hashAlgo)
Initialize PRNG context.
Definition: hmac_drbg.c:62
EC private key.
Definition: ec.h:432
uint_t objClass
Definition: asn1.h:107
uint8_t length
Definition: tcp.h:375
const uint8_t ECDSA_WITH_SHA3_224_OID[9]
Definition: ecdsa.c:56
#define MIN(a, b)
Definition: os_port.h:63
void ecScalarSelect(uint32_t *r, const uint32_t *a, const uint32_t *b, uint32_t c, uint_t n)
Select an integer.
Definition: ec_misc.c:576
const uint8_t ECDSA_WITH_SHA1_OID[7]
Definition: ecdsa.c:46
const uint8_t ECDSA_WITH_SHA224_OID[8]
Definition: ecdsa.c:48
const uint8_t ECDSA_WITH_SHA512_OID[8]
Definition: ecdsa.c:54
uint32_t w[EC_MAX_ORDER_SIZE]
Definition: ecdsa.h:88
error_t ecdsaGenerateDeterministicSignature(const EcPrivateKey *privateKey, const HashAlgo *hashAlgo, const uint8_t *digest, EcdsaSignature *signature)
Deterministic ECDSA signature generation.
Definition: ecdsa.c:666
EC public key.
Definition: ec.h:421
@ ASN1_TYPE_INTEGER
Definition: asn1.h:73
#define TRACE_DEBUG(...)
Definition: debug.h:119
__weak_func bool_t ecIsPointAffine(const EcCurve *curve, const EcPoint *s)
Check whether the affine point S is on the curve.
Definition: ec.c:840
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:120
uint32_t z[EC_MAX_ORDER_SIZE]
Definition: ecdsa.h:77
@ ECDSA_SIGNATURE_FORMAT_ASN1
Definition: ecdsa.h:51
uint32_t d[EC_MAX_ORDER_SIZE]
Private key.
Definition: ec.h:434
void ecScalarAddMod(const EcCurve *curve, uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular addition.
Definition: ec_misc.c:1062
uint32_t k[EC_MAX_ORDER_SIZE]
Definition: ecdsa.h:76
int_t ecScalarCompInt(const uint32_t *a, uint32_t b, uint_t n)
Compare integers.
Definition: ec_misc.c:374
const uint8_t ECDSA_WITH_SHA3_384_OID[9]
Definition: ecdsa.c:60
uint8_t n
@ EC_SCALAR_FORMAT_BIG_ENDIAN
Definition: ec_misc.h:51
@ ECDSA_SIGNATURE_FORMAT_RAW_R
Definition: ecdsa.h:53
#define cryptoFreeMem(p)
Definition: crypto.h:861
error_t hmacDrbgGenerate(HmacDrbgContext *context, uint8_t *output, size_t length)
Generate pseudorandom data.
Definition: hmac_drbg.c:287
__weak_func error_t ecdsaVerifySignature(const EcPublicKey *publicKey, const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
ECDSA signature verification.
Definition: ecdsa.c:951
void ecProjectify(const EcCurve *curve, EcPoint3 *r, const EcPoint *s)
Compute projective representation.
Definition: ec.c:762
__weak_func error_t ecMulRegular(const EcCurve *curve, EcPoint3 *r, const uint32_t *d, const EcPoint3 *s)
Scalar multiplication (regular calculation)
Definition: ec.c:1354
EcPoint q
Public key.
Definition: ec.h:423
uint32_t s[EC_MAX_ORDER_SIZE]
Integer S.
Definition: ecdsa.h:66
bool_t constructed
Definition: asn1.h:106
void ecScalarShiftRight(uint32_t *r, const uint32_t *a, uint_t k, uint_t n)
Right shift operation.
Definition: ec_misc.c:940
error_t ecScalarRand(const EcCurve *curve, uint32_t *r, const PrngAlgo *prngAlgo, void *prngContext)
Generate a random value.
Definition: ec_misc.c:603
#define cryptoAllocMem(size)
Definition: crypto.h:856
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
error_t ecdsaGenerateK(const EcCurve *curve, const HashAlgo *hashAlgo, const uint32_t *x, const uint32_t *h, uint32_t *k)
Generation of pseudorandom k.
Definition: ecdsa.c:832
@ ASN1_TYPE_SEQUENCE
Definition: asn1.h:83
uint32_t u2[EC_MAX_ORDER_SIZE]
Definition: ecdsa.h:91
Common interface for hash algorithms.
Definition: crypto.h:1151
#define EcCurve
Definition: ec.h:346
void ecScalarMod(uint32_t *r, const uint32_t *a, uint_t m, const uint32_t *p, uint_t n)
Modulo operation.
Definition: ec_misc.c:1009
int_t ecScalarComp(const uint32_t *a, const uint32_t *b, uint_t n)
Compare integers.
Definition: ec_misc.c:337
unsigned int uint_t
Definition: compiler_port.h:57
uint32_t x[EC_MAX_MODULUS_SIZE]
x-coordinate
Definition: ec.h:399
@ ECDSA_SIGNATURE_FORMAT_RAW_S
Definition: ecdsa.h:54
#define osMemset(p, value, length)
Definition: os_port.h:138
error_t asn1ReadSequence(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 sequence from the input stream.
Definition: asn1.c:163
Working state (ECDSA signature verification)
Definition: ecdsa.h:87
uint32_t v[EC_MAX_ORDER_SIZE]
Definition: ecdsa.h:92
@ ERROR_INVALID_SIGNATURE
Definition: error.h:228
const EcCurve * curve
Elliptic curve parameters.
Definition: ec.h:422
__weak_func void ecScalarMulMod(const EcCurve *curve, uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular multiplication.
Definition: ec_misc.c:1113
uint32_t x[EC_MAX_MODULUS_SIZE]
x-coordinate
Definition: ec.h:410
const uint8_t * value
Definition: asn1.h:110
error_t hmacDrbgSeed(HmacDrbgContext *context, const uint8_t *seed, size_t length)
Seed the PRNG state.
Definition: hmac_drbg.c:109
error_t asn1CheckTag(const Asn1Tag *tag, bool_t constructed, uint_t objClass, uint_t objType)
Enforce the type of a specified tag.
Definition: asn1.c:944
@ NO_ERROR
Success.
Definition: error.h:44
uint8_t c
Definition: ndp.h:514
Debugging facilities.
uint_t objType
Definition: asn1.h:108
ASN.1 (Abstract Syntax Notation One)
uint32_t y[EC_MAX_MODULUS_SIZE]
y-coordinate
Definition: ec.h:411