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-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.4
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[in] digestLen Length in octets of the digest
663  * @param[out] signature (R, S) integer pair
664  * @return Error code
665  **/
666 
668  const HashAlgo *hashAlgo, const uint8_t *digest, EcdsaSignature *signature)
669 {
670  error_t error;
671  uint_t n;
672  uint_t pLen;
673  uint_t qLen;
674 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
676 #else
678 #endif
679 
680  //Check parameters
681  if(hashAlgo == NULL || privateKey == NULL || digest == NULL ||
682  signature == NULL)
683  {
685  }
686 
687  //Invalid elliptic curve?
688  if(privateKey->curve == NULL)
690 
691  //Get the length of the modulus, in words
692  pLen = (privateKey->curve->fieldSize + 31) / 32;
693  //Get the length of the order, in words
694  qLen = (privateKey->curve->orderSize + 31) / 32;
695 
696  //Debug message
697  TRACE_DEBUG("ECDSA signature generation...\r\n");
698  TRACE_DEBUG(" curve: %s\r\n", privateKey->curve->name);
699  TRACE_DEBUG(" private key:\r\n");
700  TRACE_DEBUG_EC_SCALAR(" ", privateKey->d, qLen);
701  TRACE_DEBUG(" digest:\r\n");
702  TRACE_DEBUG_ARRAY(" ", digest, hashAlgo->digestSize);
703 
704 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
705  //Allocate working state
707  //Failed to allocate memory?
708  if(state == NULL)
709  return ERROR_OUT_OF_MEMORY;
710 #endif
711 
712  //Initialize working state
713  osMemset(state, 0, sizeof(EcdsaGenerateSignatureState));
714 
715  //Initialize (R, S) integer pair
716  ecScalarSetInt(signature->r, 0, EC_MAX_ORDER_SIZE);
717  ecScalarSetInt(signature->s, 0, EC_MAX_ORDER_SIZE);
718 
719  //Let N be the bit length of q
720  n = privateKey->curve->orderSize;
721  //Compute N = MIN(N, outlen)
722  n = MIN(n, hashAlgo->digestSize * 8);
723 
724  //Convert the digest to an integer
725  error = ecScalarImport(state->z, qLen, digest, (n + 7) / 8,
727 
728  //Check status code
729  if(!error)
730  {
731  uint32_t c;
732  uint32_t z2[EC_MAX_ORDER_SIZE];
733 
734  //Keep the leftmost N bits of the hash value
735  if((n % 8) != 0)
736  {
737  ecScalarShiftRight(state->z, state->z, 8 - (n % 8), qLen);
738  }
739 
740  //Debug message
741  TRACE_DEBUG(" z:\r\n");
742  TRACE_DEBUG_EC_SCALAR(" ", state->z, qLen);
743 
744  //z is reduced modulo q. The modular reduction can be implemented with a
745  //simple conditional subtraction
746  c = ecScalarSub(z2, state->z, privateKey->curve->q, qLen);
747  ecScalarSelect(state->z, z2, state->z, c, qLen);
748 
749  //Compute the pseudorandom k for signature generation
750  error = ecdsaGenerateK(privateKey->curve, hashAlgo, privateKey->d,
751  state->z, state->k);
752  }
753 
754  //Check status code
755  if(!error)
756  {
757  //Debug message
758  TRACE_DEBUG(" k:\r\n");
759  TRACE_DEBUG_EC_SCALAR(" ", state->k, qLen);
760 
761  //Compute R1 = (x1, y1) = k.G
762  error = ecMulRegular(privateKey->curve, &state->r1, state->k,
763  &privateKey->curve->g);
764  }
765 
766  //Check status code
767  if(!error)
768  {
769  //Convert R1 to affine representation
770  error = ecAffinify(privateKey->curve, &state->r1, &state->r1);
771  }
772 
773  //Check status code
774  if(!error)
775  {
776  //Debug message
777  TRACE_DEBUG(" x1:\r\n");
778  TRACE_DEBUG_EC_SCALAR(" ", state->r1.x, pLen);
779  TRACE_DEBUG(" y1:\r\n");
780  TRACE_DEBUG_EC_SCALAR(" ", state->r1.y, pLen);
781 
782  //Compute r = x1 mod q
783  ecScalarMod(signature->r, state->r1.x, pLen, privateKey->curve->q, qLen);
784  //Compute k ^ -1 mod q
785  ecScalarInvMod(privateKey->curve, state->k, state->k);
786 
787  //Compute s = k ^ -1 * (z + x * r) mod q
788  ecScalarMulMod(privateKey->curve, signature->s, privateKey->d, signature->r);
789  ecScalarAddMod(privateKey->curve, signature->s, signature->s, state->z);
790  ecScalarMulMod(privateKey->curve, signature->s, signature->s, state->k);
791 
792  //Save elliptic curve parameters
793  signature->curve = privateKey->curve;
794 
795  //Debug message
796  TRACE_DEBUG(" r:\r\n");
797  TRACE_DEBUG_EC_SCALAR(" ", signature->r, qLen);
798  TRACE_DEBUG(" s:\r\n");
799  TRACE_DEBUG_EC_SCALAR(" ", signature->s, qLen);
800 
801  //If r = 0 or if s = 0, and k was generated deterministically, then
802  //output failure (refer to FIPS 186-5, section 6.4.1)
803  if(ecScalarCompInt(signature->r, 0, qLen) == 0 ||
804  ecScalarCompInt(signature->s, 0, qLen) == 0)
805  {
806  error = ERROR_FAILURE;
807  }
808  }
809 
810  //Erase working state
811  osMemset(state, 0, sizeof(EcdsaGenerateSignatureState));
812 
813 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
814  //Release working state
815  cryptoFreeMem(state);
816 #endif
817 
818  //Return status code
819  return error;
820 }
821 
822 
823 /**
824  * @brief Generation of pseudorandom k
825  * @param[in] curve Elliptic curve parameters
826  * @param[in] hashAlgo Underlying hash function
827  * @param[in] x ECDSA private key
828  * @param[in] h Digest of the message to be signed
829  * @param[in] k Pseudorandom value k
830  * @return Error code
831  **/
832 
833 error_t ecdsaGenerateK(const EcCurve *curve, const HashAlgo *hashAlgo,
834  const uint32_t *x, const uint32_t *h, uint32_t *k)
835 {
836 #if (HMAC_DRBG_SUPPORT == ENABLED)
837  error_t error;
838  size_t n;
839  uint8_t seed[EC_MAX_ORDER_SIZE * 8];
840  uint8_t t[EC_MAX_ORDER_SIZE * 4];
841  uint32_t q[EC_MAX_ORDER_SIZE];
842 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
843  HmacDrbgContext *hmacDrbgContext;
844 #else
845  HmacDrbgContext hmacDrbgContext[1];
846 #endif
847 
848 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
849  //Allocate HMAC_DRBG context
850  hmacDrbgContext = cryptoAllocMem(sizeof(HmacDrbgContext));
851  //Failed to allocate memory?
852  if(hmacDrbgContext == NULL)
853  return ERROR_OUT_OF_MEMORY;
854 #endif
855 
856  //Get the length of the order, in bytes
857  n = (curve->orderSize + 7) / 8;
858 
859  //Instantiate HMAC_DRBG using HMAC parameterized with the same hash function
860  //H as the one used for processing the message that is to be signed (refer
861  //to RFC 6979, section 3.3)
862  error = hmacDrbgInit(hmacDrbgContext, hashAlgo);
863 
864  //Check status code
865  if(!error)
866  {
867  //The private key is used as entropy string
868  error = ecScalarExport(x, (n + 3) / 4, seed, n,
870  }
871 
872  //Check status code
873  if(!error)
874  {
875  //The hashed message (truncated and expanded by bits2octets) is used as
876  //nonce. The entropy string and nonce are simply concatenated into the
877  //initial seed
878  error = ecScalarExport(h, (n + 3) / 4, seed + n, n,
880  }
881 
882  //Check status code
883  if(!error)
884  {
885  //For deterministic ECDSA, we want HMAC_DRBG to run with the entropy
886  //string and nonce that we specify, without accessing an actual entropy
887  //source
888  error = hmacDrbgSeed(hmacDrbgContext, seed, n * 2);
889  }
890 
891  //Repeat this step until an acceptable value is obtained
892  while(!error)
893  {
894  //Generate a candidate value for k by requesting qlen bits from HMAC_DRBG
895  error = hmacDrbgGenerate(hmacDrbgContext, t, n);
896 
897  //Check status code
898  if(!error)
899  {
900  //The resulting value is then converted to an integer value using the
901  //big-endian convention
902  error = ecScalarImport(k, (n + 3) / 4, t, n,
904  }
905 
906  //Check status code
907  if(!error)
908  {
909  //The qlen leftmost bits are kept, and subsequent bits are discarded
910  if(curve->orderSize < (n * 8))
911  {
912  ecScalarShiftRight(k, k, (n * 8) - curve->orderSize, (n + 3) / 4);
913  }
914 
915  //Precompte q-1
916  ecScalarSubInt(q, curve->q, 1, (n + 3) / 4);
917 
918  //If that value of k is within the [1,q-1] range, and is suitable for
919  //ECDSA, then the generation of k is finished
920  if(ecScalarCompInt(k, 0, (n + 3) / 4) > 0 &&
921  ecScalarComp(k, q, (n + 3) / 4) < 0)
922  {
923  //The obtained value of k can be used in ECDSA
924  break;
925  }
926  }
927  }
928 
929 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
930  //Release working state
931  cryptoFreeMem(hmacDrbgContext);
932 #endif
933 
934  //Return status code
935  return error;
936 #else
937  //HMAC_DRBG is not implemented
938  return ERROR_NOT_IMPLEMENTED;
939 #endif
940 }
941 
942 
943 /**
944  * @brief ECDSA signature verification
945  * @param[in] publicKey Signer's EC public key
946  * @param[in] digest Digest of the message whose signature is to be verified
947  * @param[in] digestLen Length in octets of the digest
948  * @param[in] signature (R, S) integer pair
949  * @return Error code
950  **/
951 
952 __weak_func error_t ecdsaVerifySignature(const EcPublicKey *publicKey,
953  const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
954 {
955  error_t error;
956  uint_t n;
957  uint_t pLen;
958  uint_t qLen;
959 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
961 #else
962  EcdsaVerifySignatureState state[1];
963 #endif
964 
965  //Check parameters
966  if(publicKey == NULL || digest == NULL || signature == NULL)
968 
969  //Invalid elliptic curve?
970  if(publicKey->curve == NULL)
972 
973  //Get the length of the modulus, in words
974  pLen = (publicKey->curve->fieldSize + 31) / 32;
975  //Get the length of the order, in words
976  qLen = (publicKey->curve->orderSize + 31) / 32;
977 
978  //Debug message
979  TRACE_DEBUG("ECDSA signature verification...\r\n");
980  TRACE_DEBUG(" curve: %s\r\n", publicKey->curve->name);
981  TRACE_DEBUG(" public key X:\r\n");
982  TRACE_DEBUG_EC_SCALAR(" ", publicKey->q.x, pLen);
983  TRACE_DEBUG(" public key Y:\r\n");
984  TRACE_DEBUG_EC_SCALAR(" ", publicKey->q.y, pLen);
985  TRACE_DEBUG(" digest:\r\n");
986  TRACE_DEBUG_ARRAY(" ", digest, digestLen);
987  TRACE_DEBUG(" r:\r\n");
988  TRACE_DEBUG_EC_SCALAR(" ", signature->r, qLen);
989  TRACE_DEBUG(" s:\r\n");
990  TRACE_DEBUG_EC_SCALAR(" ", signature->s, qLen);
991 
992  //Verify that the public key is on the curve
993  if(!ecIsPointAffine(publicKey->curve, &publicKey->q))
994  {
996  }
997 
998  //The verifier shall check that 0 < r < q
999  if(ecScalarCompInt(signature->r, 0, EC_MAX_ORDER_SIZE) <= 0 ||
1000  ecScalarComp(signature->r, publicKey->curve->q, EC_MAX_ORDER_SIZE) >= 0)
1001  {
1002  //If the condition is violated, the signature shall be rejected as invalid
1003  return ERROR_INVALID_SIGNATURE;
1004  }
1005 
1006  //The verifier shall check that 0 < s < q
1007  if(ecScalarCompInt(signature->s, 0, EC_MAX_ORDER_SIZE) <= 0 ||
1008  ecScalarComp(signature->s, publicKey->curve->q, EC_MAX_ORDER_SIZE) >= 0)
1009  {
1010  //If the condition is violated, the signature shall be rejected as invalid
1011  return ERROR_INVALID_SIGNATURE;
1012  }
1013 
1014 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1015  //Allocate working state
1016  state = cryptoAllocMem(sizeof(EcdsaVerifySignatureState));
1017  //Failed to allocate memory?
1018  if(state == NULL)
1019  return ERROR_OUT_OF_MEMORY;
1020 #endif
1021 
1022  //Initialize working state
1023  osMemset(state, 0, sizeof(EcdsaVerifySignatureState));
1024 
1025  //Let N be the bit length of q
1026  n = publicKey->curve->orderSize;
1027  //Compute N = MIN(N, outlen)
1028  n = MIN(n, digestLen * 8);
1029 
1030  //Convert the digest to an integer
1031  error = ecScalarImport(state->z, qLen, digest, (n + 7) / 8,
1033 
1034  //Check status code
1035  if(!error)
1036  {
1037  //Keep the leftmost N bits of the hash value
1038  if((n % 8) != 0)
1039  {
1040  ecScalarShiftRight(state->z, state->z, 8 - (n % 8), qLen);
1041  }
1042 
1043  //Compute w = s ^ -1 mod q
1044  ecScalarInvMod(publicKey->curve, state->w, signature->s);
1045 
1046  //Compute u1 = z * w mod q
1047  ecScalarMulMod(publicKey->curve, state->u1, state->z, state->w);
1048  //Compute u2 = r * w mod q
1049  ecScalarMulMod(publicKey->curve, state->u2, signature->r, state->w);
1050 
1051  //Convert the public key to projective representation
1052  ecProjectify(publicKey->curve, &state->v1, &publicKey->q);
1053 
1054  //Compute V0 = (x0, y0) = u1.G + u2.Q
1055  error = ecTwinMul(publicKey->curve, &state->v0, state->u1,
1056  &publicKey->curve->g, state->u2, &state->v1);
1057  }
1058 
1059  //Check status code
1060  if(!error)
1061  {
1062  //Convert V0 to affine representation
1063  error = ecAffinify(publicKey->curve, &state->v0, &state->v0);
1064  }
1065 
1066  //Check status code
1067  if(!error)
1068  {
1069  //Debug message
1070  TRACE_DEBUG(" x0:\r\n");
1071  TRACE_DEBUG_EC_SCALAR(" ", state->v0.x, pLen);
1072  TRACE_DEBUG(" y0:\r\n");
1073  TRACE_DEBUG_EC_SCALAR(" ", state->v0.y, pLen);
1074 
1075  //Compute v = x0 mod q
1076  ecScalarMod(state->v, state->v0.x, pLen, publicKey->curve->q, qLen);
1077 
1078  //Debug message
1079  TRACE_DEBUG(" v:\r\n");
1080  TRACE_DEBUG_EC_SCALAR(" ", state->v, qLen);
1081 
1082  //If v = r, then the signature is verified. If v does not equal r, then the
1083  //message or the signature may have been modified
1084  if(ecScalarComp(state->v, signature->r, qLen) == 0)
1085  {
1086  error = NO_ERROR;
1087  }
1088  else
1089  {
1090  error = ERROR_INVALID_SIGNATURE;
1091  }
1092  }
1093 
1094  //Erase working state
1095  osMemset(state, 0, sizeof(EcdsaVerifySignatureState));
1096 
1097 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1098  //Release working state
1099  cryptoFreeMem(state);
1100 #endif
1101 
1102  //Return status code
1103  return error;
1104 }
1105 
1106 #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:1008
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:1130
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:667
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:952
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:833
@ 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:1124
#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