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-2019 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 1.9.6
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 "mpi/mpi.h"
38 #include "encoding/asn1.h"
39 #include "debug.h"
40 
41 //Check crypto library configuration
42 #if (ECDSA_SUPPORT == ENABLED)
43 
44 //ECDSA with SHA-1 OID (1.2.840.10045.4.1)
45 const uint8_t ECDSA_WITH_SHA1_OID[7] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x01};
46 //ECDSA with SHA-224 OID (1.2.840.10045.4.3.1)
47 const uint8_t ECDSA_WITH_SHA224_OID[8] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01};
48 //ECDSA with SHA-256 OID (1.2.840.10045.4.3.2)
49 const uint8_t ECDSA_WITH_SHA256_OID[8] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02};
50 //ECDSA with SHA-384 OID (1.2.840.10045.4.3.3)
51 const uint8_t ECDSA_WITH_SHA384_OID[8] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03};
52 //ECDSA with SHA-512 OID (1.2.840.10045.4.3.4)
53 const uint8_t ECDSA_WITH_SHA512_OID[8] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x04};
54 //ECDSA with SHA-3-224 OID (2.16.840.1.101.3.4.3.9)
55 const uint8_t ECDSA_WITH_SHA3_224_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x09};
56 //ECDSA with SHA-3-256 OID (2.16.840.1.101.3.4.3.10)
57 const uint8_t ECDSA_WITH_SHA3_256_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0A};
58 //ECDSA with SHA-3-384 OID (2.16.840.1.101.3.4.3.11)
59 const uint8_t ECDSA_WITH_SHA3_384_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0B};
60 //ECDSA with SHA-3-512 OID (2.16.840.1.101.3.4.3.12)
61 const uint8_t ECDSA_WITH_SHA3_512_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0C};
62 
63 
64 /**
65  * @brief Initialize an ECDSA signature
66  * @param[in] signature Pointer to the ECDSA signature to initialize
67  **/
68 
70 {
71  //Initialize multiple precision integers
72  mpiInit(&signature->r);
73  mpiInit(&signature->s);
74 }
75 
76 
77 /**
78  * @brief Release an ECDSA signature
79  * @param[in] signature Pointer to the ECDSA signature to free
80  **/
81 
83 {
84  //Release multiple precision integers
85  mpiFree(&signature->r);
86  mpiFree(&signature->s);
87 }
88 
89 
90 /**
91  * @brief Encode ECDSA signature using ASN.1
92  * @param[in] signature (R, S) integer pair
93  * @param[out] data Pointer to the buffer where to store the resulting ASN.1 structure
94  * @param[out] length Length of the ASN.1 structure
95  * @return Error code
96  **/
97 
99  size_t *length)
100 {
101  error_t error;
102  size_t k;
103  size_t n;
104  size_t rLen;
105  size_t sLen;
106  Asn1Tag tag;
107 
108  //Debug message
109  TRACE_DEBUG("Writing ECDSA signature...\r\n");
110 
111  //Dump (R, S) integer pair
112  TRACE_DEBUG(" r:\r\n");
113  TRACE_DEBUG_MPI(" ", &signature->r);
114  TRACE_DEBUG(" s:\r\n");
115  TRACE_DEBUG_MPI(" ", &signature->s);
116 
117  //Calculate the length of R
118  rLen = mpiGetByteLength(&signature->r);
119  //Calculate the length of S
120  sLen = mpiGetByteLength(&signature->s);
121 
122  //Make sure the (R, S) integer pair is valid
123  if(rLen == 0 || sLen == 0)
124  return ERROR_INVALID_LENGTH;
125 
126  //R and S are always encoded in the smallest possible number of octets
127  if(mpiGetBitValue(&signature->r, (rLen * 8) - 1))
128  rLen++;
129  if(mpiGetBitValue(&signature->s, (sLen * 8) - 1))
130  sLen++;
131 
132  //The first pass computes the length of the ASN.1 sequence
133  n = 0;
134 
135  //The parameter R is encapsulated within an ASN.1 structure
136  tag.constructed = FALSE;
139  tag.length = rLen;
140  tag.value = NULL;
141 
142  //Compute the length of the corresponding ASN.1 structure
143  error = asn1WriteTag(&tag, FALSE, NULL, NULL);
144  //Any error to report?
145  if(error)
146  return error;
147 
148  //Update the length of the ASN.1 sequence
149  n += tag.totalLength;
150 
151  //The parameter S is encapsulated within an ASN.1 structure
152  tag.constructed = FALSE;
155  tag.length = sLen;
156  tag.value = NULL;
157 
158  //Compute the length of the corresponding ASN.1 structure
159  error = asn1WriteTag(&tag, FALSE, NULL, NULL);
160  //Any error to report?
161  if(error)
162  return error;
163 
164  //Update the length of the ASN.1 sequence
165  n += tag.totalLength;
166 
167  //The second pass encodes the ASN.1 structure
168  k = 0;
169 
170  //The (R, S) integer pair is encapsulated within a sequence
171  tag.constructed = TRUE;
174  tag.length = n;
175  tag.value = NULL;
176 
177  //Write the corresponding ASN.1 tag
178  error = asn1WriteTag(&tag, FALSE, data + k, &n);
179  //Any error to report?
180  if(error)
181  return error;
182 
183  //Advance write pointer
184  k += n;
185 
186  //Encode the parameter R using ASN.1
187  tag.constructed = FALSE;
190  tag.length = rLen;
191  tag.value = NULL;
192 
193  //Write the corresponding ASN.1 tag
194  error = asn1WriteTag(&tag, FALSE, data + k, &n);
195  //Any error to report?
196  if(error)
197  return error;
198 
199  //Advance write pointer
200  k += n;
201 
202  //Convert R to an octet string
203  error = mpiWriteRaw(&signature->r, data + k, rLen);
204  //Any error to report?
205  if(error)
206  return error;
207 
208  //Advance write pointer
209  k += rLen;
210 
211  //Encode the parameter S using ASN.1
212  tag.constructed = FALSE;
215  tag.length = sLen;
216  tag.value = NULL;
217 
218  //Write the corresponding ASN.1 tag
219  error = asn1WriteTag(&tag, FALSE, data + k, &n);
220  //Any error to report?
221  if(error)
222  return error;
223 
224  //Advance write pointer
225  k += n;
226 
227  //Convert S to an octet string
228  error = mpiWriteRaw(&signature->s, data + k, sLen);
229  //Any error to report?
230  if(error)
231  return error;
232 
233  //Advance write pointer
234  k += sLen;
235 
236  //Dump ECDSA signature
237  TRACE_DEBUG(" signature:\r\n");
238  TRACE_DEBUG_ARRAY(" ", data, k);
239 
240  //Total length of the ASN.1 structure
241  *length = k;
242  //Successful processing
243  return NO_ERROR;
244 }
245 
246 
247 /**
248  * @brief Read an ASN.1 encoded ECDSA signature
249  * @param[in] data Pointer to the ASN.1 structure to decode
250  * @param[in] length Length of the ASN.1 structure
251  * @param[out] signature (R, S) integer pair
252  * @return Error code
253  **/
254 
255 error_t ecdsaReadSignature(const uint8_t *data, size_t length,
257 {
258  error_t error;
259  Asn1Tag tag;
260 
261  //Debug message
262  TRACE_DEBUG("Reading ECDSA signature...\r\n");
263 
264  //Dump ECDSA signature
265  TRACE_DEBUG(" signature:\r\n");
267 
268  //Start of exception handling block
269  do
270  {
271  //Display ASN.1 structure
272  error = asn1DumpObject(data, length, 0);
273  //Any error to report?
274  if(error)
275  break;
276 
277  //Read the contents of the ASN.1 structure
278  error = asn1ReadSequence(data, length, &tag);
279  //Failed to decode ASN.1 tag?
280  if(error)
281  break;
282 
283  //Malformed ECDSA signature?
284  if(length != tag.totalLength)
285  {
286  //Report an error
287  error = ERROR_INVALID_SYNTAX;
288  break;
289  }
290 
291  //Point to the first field
292  data = tag.value;
293  length = tag.length;
294 
295  //Read the parameter R
296  error = asn1ReadTag(data, length, &tag);
297  //Failed to decode ASN.1 tag?
298  if(error)
299  break;
300 
301  //Enforce encoding, class and type
303  //Invalid tag?
304  if(error)
305  break;
306 
307  //Make sure R is a positive integer
308  if(tag.length == 0 || (tag.value[0] & 0x80) != 0)
309  {
310  //Report an error
311  error = ERROR_INVALID_SYNTAX;
312  break;
313  }
314 
315  //Convert the octet string to a multiple precision integer
316  error = mpiReadRaw(&signature->r, tag.value, tag.length);
317  //Any error to report?
318  if(error)
319  break;
320 
321  //Point to the next field
322  data += tag.totalLength;
323  length -= tag.totalLength;
324 
325  //Read the parameter S
326  error = asn1ReadTag(data, length, &tag);
327  //Failed to decode ASN.1 tag?
328  if(error)
329  break;
330 
331  //Enforce encoding, class and type
333  //Invalid tag?
334  if(error)
335  break;
336 
337  //Make sure S is a positive integer
338  if(tag.length == 0 || (tag.value[0] & 0x80) != 0)
339  {
340  //Report an error
341  error = ERROR_INVALID_SYNTAX;
342  break;
343  }
344 
345  //Convert the octet string to a multiple precision integer
346  error = mpiReadRaw(&signature->s, tag.value, tag.length);
347  //Any error to report?
348  if(error)
349  break;
350 
351  //Malformed ECDSA signature?
352  if(length != tag.totalLength)
353  {
354  //Report an error
355  error = ERROR_INVALID_SYNTAX;
356  break;
357  }
358 
359  //Dump (R, S) integer pair
360  TRACE_DEBUG(" r:\r\n");
361  TRACE_DEBUG_MPI(" ", &signature->r);
362  TRACE_DEBUG(" s:\r\n");
363  TRACE_DEBUG_MPI(" ", &signature->s);
364 
365  //End of exception handling block
366  } while(0);
367 
368  //Any error to report?
369  if(error)
370  {
371  //Clean up side effects
373  }
374 
375  //Return status code
376  return error;
377 }
378 
379 
380 /**
381  * @brief ECDSA key pair generation
382  * @param[in] prngAlgo PRNG algorithm
383  * @param[in] prngContext Pointer to the PRNG context
384  * @param[in] params EC domain parameters
385  * @param[out] privateKey EC private key
386  * @param[out] publicKey EC public key
387  * @return Error code
388  **/
389 
390 error_t ecdsaGenerateKeyPair(const PrngAlgo *prngAlgo, void *prngContext,
391  const EcDomainParameters *params, Mpi *privateKey, EcPoint *publicKey)
392 {
393  error_t error;
394  uint_t n;
395 
396  //Check parameters
397  if(params == NULL || privateKey == NULL || publicKey == NULL)
399 
400  //Debug message
401  TRACE_DEBUG("Generating ECDSA key pair...\r\n");
402 
403  //Let N be the bit length of q
404  n = mpiGetBitLength(&params->q);
405 
406  //Generated a pseudorandom number
407  MPI_CHECK(mpiRand(privateKey, n, prngAlgo, prngContext));
408 
409  //Make sure that 0 < d < q
410  if(mpiComp(privateKey, &params->q) >= 0)
411  {
412  EC_CHECK(mpiShiftRight(privateKey, 1));
413  }
414 
415  //Debug message
416  TRACE_DEBUG(" Private key:\r\n");
417  TRACE_DEBUG_MPI(" ", privateKey);
418 
419  //Compute Q = d.G
420  EC_CHECK(ecMult(params, publicKey, privateKey, &params->g));
421  EC_CHECK(ecAffinify(params, publicKey, publicKey));
422 
423  //Debug message
424  TRACE_DEBUG(" Public key X:\r\n");
425  TRACE_DEBUG_MPI(" ", &publicKey->x);
426  TRACE_DEBUG(" Public key Y:\r\n");
427  TRACE_DEBUG_MPI(" ", &publicKey->y);
428 
429 end:
430  //Return status code
431  return error;
432 }
433 
434 
435 /**
436  * @brief ECDSA signature generation
437  * @param[in] prngAlgo PRNG algorithm
438  * @param[in] prngContext Pointer to the PRNG context
439  * @param[in] params EC domain parameters
440  * @param[in] privateKey Signer's EC private key
441  * @param[in] digest Digest of the message to be signed
442  * @param[in] digestLen Length in octets of the digest
443  * @param[out] signature (R, S) integer pair
444  * @return Error code
445  **/
446 
447 __weak error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo,
448  void *prngContext, const EcDomainParameters *params, const Mpi *privateKey,
449  const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
450 {
451  error_t error;
452  uint_t n;
453  Mpi k;
454  Mpi z;
455  EcPoint r1;
456 
457  //Check parameters
458  if(params == NULL || privateKey == NULL || digest == NULL || signature == NULL)
460 
461  //Debug message
462  TRACE_DEBUG("ECDSA signature generation...\r\n");
463  TRACE_DEBUG(" private key:\r\n");
464  TRACE_DEBUG_MPI(" ", privateKey);
465  TRACE_DEBUG(" digest:\r\n");
466  TRACE_DEBUG_ARRAY(" ", digest, digestLen);
467 
468  //Initialize multiple precision integers
469  mpiInit(&k);
470  mpiInit(&z);
471  //Initialize EC point
472  ecInit(&r1);
473 
474  //Let N be the bit length of q
475  n = mpiGetBitLength(&params->q);
476 
477  //Generated a pseudorandom number
478  MPI_CHECK(mpiRand(&k, n, prngAlgo, prngContext));
479 
480  //Make sure that 0 < k < q
481  if(mpiComp(&k, &params->q) >= 0)
482  mpiShiftRight(&k, 1);
483 
484  //Debug message
485  TRACE_DEBUG(" k:\r\n");
486  TRACE_DEBUG_MPI(" ", &k);
487 
488  //Compute N = MIN(N, outlen)
489  n = MIN(n, digestLen * 8);
490 
491  //Convert the digest to a multiple precision integer
492  MPI_CHECK(mpiReadRaw(&z, digest, (n + 7) / 8));
493 
494  //Keep the leftmost N bits of the hash value
495  if((n % 8) != 0)
496  {
497  MPI_CHECK(mpiShiftRight(&z, 8 - (n % 8)));
498  }
499 
500  //Debug message
501  TRACE_DEBUG(" z:\r\n");
502  TRACE_DEBUG_MPI(" ", &z);
503 
504  //Compute R1 = (x1, y1) = k.G
505  EC_CHECK(ecMult(params, &r1, &k, &params->g));
506  EC_CHECK(ecAffinify(params, &r1, &r1));
507 
508  //Debug message
509  TRACE_DEBUG(" x1:\r\n");
510  TRACE_DEBUG_MPI(" ", &r1.x);
511  TRACE_DEBUG(" y1:\r\n");
512  TRACE_DEBUG_MPI(" ", &r1.y);
513 
514  //Compute r = x1 mod q
515  MPI_CHECK(mpiMod(&signature->r, &r1.x, &params->q));
516 
517  //Compute k ^ -1 mod q
518  MPI_CHECK(mpiInvMod(&k, &k, &params->q));
519 
520  //Compute s = k ^ -1 * (z + x * r) mod q
521  MPI_CHECK(mpiMul(&signature->s, privateKey, &signature->r));
522  MPI_CHECK(mpiAdd(&signature->s, &signature->s, &z));
523  MPI_CHECK(mpiMod(&signature->s, &signature->s, &params->q));
524  MPI_CHECK(mpiMulMod(&signature->s, &signature->s, &k, &params->q));
525 
526  //Dump ECDSA signature
527  TRACE_DEBUG(" r:\r\n");
528  TRACE_DEBUG_MPI(" ", &signature->r);
529  TRACE_DEBUG(" s:\r\n");
530  TRACE_DEBUG_MPI(" ", &signature->s);
531 
532 end:
533  //Release multiple precision integers
534  mpiFree(&k);
535  mpiFree(&z);
536  //Release EC point
537  ecFree(&r1);
538 
539  //Clean up side effects if necessary
540  if(error)
541  {
542  //Release (R, S) integer pair
543  mpiFree(&signature->r);
544  mpiFree(&signature->s);
545  }
546 
547  //Return status code
548  return error;
549 }
550 
551 
552 /**
553  * @brief ECDSA signature verification
554  * @param[in] params EC domain parameters
555  * @param[in] publicKey Signer's EC public key
556  * @param[in] digest Digest of the message whose signature is to be verified
557  * @param[in] digestLen Length in octets of the digest
558  * @param[in] signature (R, S) integer pair
559  * @return Error code
560  **/
561 
563  const EcPoint *publicKey, const uint8_t *digest, size_t digestLen,
564  const EcdsaSignature *signature)
565 {
566  error_t error;
567  uint_t n;
568  Mpi w;
569  Mpi z;
570  Mpi u1;
571  Mpi u2;
572  Mpi v;
573  EcPoint v0;
574  EcPoint v1;
575 
576  //Check parameters
577  if(params == NULL || publicKey == NULL || digest == NULL || signature == NULL)
579 
580  //Debug message
581  TRACE_DEBUG("ECDSA signature verification...\r\n");
582  TRACE_DEBUG(" public key X:\r\n");
583  TRACE_DEBUG_MPI(" ", &publicKey->x);
584  TRACE_DEBUG(" public key Y:\r\n");
585  TRACE_DEBUG_MPI(" ", &publicKey->y);
586  TRACE_DEBUG(" digest:\r\n");
587  TRACE_DEBUG_ARRAY(" ", digest, digestLen);
588  TRACE_DEBUG(" r:\r\n");
589  TRACE_DEBUG_MPI(" ", &signature->r);
590  TRACE_DEBUG(" s:\r\n");
591  TRACE_DEBUG_MPI(" ", &signature->s);
592 
593  //The verifier shall check that 0 < r < q
594  if(mpiCompInt(&signature->r, 0) <= 0 || mpiComp(&signature->r, &params->q) >= 0)
595  {
596  //If the condition is violated, the signature shall be rejected as invalid
598  }
599 
600  //The verifier shall check that 0 < s < q
601  if(mpiCompInt(&signature->s, 0) <= 0 || mpiComp(&signature->s, &params->q) >= 0)
602  {
603  //If the condition is violated, the signature shall be rejected as invalid
605  }
606 
607  //Initialize multiple precision integers
608  mpiInit(&w);
609  mpiInit(&z);
610  mpiInit(&u1);
611  mpiInit(&u2);
612  mpiInit(&v);
613  //Initialize EC points
614  ecInit(&v0);
615  ecInit(&v1);
616 
617  //Let N be the bit length of q
618  n = mpiGetBitLength(&params->q);
619  //Compute N = MIN(N, outlen)
620  n = MIN(n, digestLen * 8);
621 
622  //Convert the digest to a multiple precision integer
623  MPI_CHECK(mpiReadRaw(&z, digest, (n + 7) / 8));
624 
625  //Keep the leftmost N bits of the hash value
626  if((n % 8) != 0)
627  {
628  MPI_CHECK(mpiShiftRight(&z, 8 - (n % 8)));
629  }
630 
631  //Compute w = s ^ -1 mod q
632  MPI_CHECK(mpiInvMod(&w, &signature->s, &params->q));
633  //Compute u1 = z * w mod q
634  MPI_CHECK(mpiMulMod(&u1, &z, &w, &params->q));
635  //Compute u2 = r * w mod q
636  MPI_CHECK(mpiMulMod(&u2, &signature->r, &w, &params->q));
637 
638  //Compute V0 = (x0, y0) = u1.G + u2.Q
639  EC_CHECK(ecProjectify(params, &v1, publicKey));
640  EC_CHECK(ecTwinMult(params, &v0, &u1, &params->g, &u2, &v1));
641  EC_CHECK(ecAffinify(params, &v0, &v0));
642 
643  //Debug message
644  TRACE_DEBUG(" x0:\r\n");
645  TRACE_DEBUG_MPI(" ", &v0.x);
646  TRACE_DEBUG(" y0:\r\n");
647  TRACE_DEBUG_MPI(" ", &v0.y);
648 
649  //Compute v = x0 mod q
650  MPI_CHECK(mpiMod(&v, &v0.x, &params->q));
651 
652  //Debug message
653  TRACE_DEBUG(" v:\r\n");
654  TRACE_DEBUG_MPI(" ", &v);
655 
656  //If v = r, then the signature is verified. If v does not equal r,
657  //then the message or the signature may have been modified
658  if(!mpiComp(&v, &signature->r))
659  error = NO_ERROR;
660  else
661  error = ERROR_INVALID_SIGNATURE;
662 
663 end:
664  //Release multiple precision integers
665  mpiFree(&w);
666  mpiFree(&z);
667  mpiFree(&u1);
668  mpiFree(&u2);
669  mpiFree(&v);
670  //Release EC points
671  ecFree(&v0);
672  ecFree(&v1);
673 
674  //Return status code
675  return error;
676 }
677 
678 #endif
ECDSA signature.
Definition: ecdsa.h:48
error_t ecdsaGenerateKeyPair(const PrngAlgo *prngAlgo, void *prngContext, const EcDomainParameters *params, Mpi *privateKey, EcPoint *publicKey)
ECDSA key pair generation.
Definition: ecdsa.c:390
uint8_t length
Definition: dtls_misc.h:149
Arbitrary precision integer.
Definition: mpi.h:69
Common interface for pseudo-random number generators.
Definition: crypto.h:1168
ECDSA (Elliptic Curve Digital Signature Algorithm)
#define TRUE
Definition: os_port.h:50
const uint8_t ECDSA_WITH_SHA3_512_OID[9]
Definition: ecdsa.c:61
error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular multiplication.
Definition: mpi.c:1436
uint8_t signature
Definition: tls.h:1370
#define mpiWriteRaw(a, data, length)
Definition: crypto_legacy.h:36
EcPoint g
Base point G.
Definition: ec.h:70
const uint8_t ECDSA_WITH_SHA3_256_OID[9]
Definition: ecdsa.c:57
error_t asn1DumpObject(const uint8_t *data, size_t length, uint_t level)
Display an ASN.1 data object.
Definition: asn1.c:690
error_t mpiShiftRight(Mpi *r, uint_t n)
Right shift operation.
Definition: mpi.c:1073
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
error_t mpiRand(Mpi *r, uint_t length, const PrngAlgo *prngAlgo, void *prngContext)
Generate a random value.
Definition: mpi.c:468
Mpi y
y-coordinate
Definition: ec.h:54
const uint8_t ECDSA_WITH_SHA256_OID[8]
Definition: ecdsa.c:49
__weak error_t ecMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d, const EcPoint *s)
Scalar multiplication.
Definition: ec.c:835
EC domain parameters.
Definition: ec.h:63
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:48
uint16_t w[3]
Definition: ethernet.h:166
#define mpiReadRaw(r, data, length)
Definition: crypto_legacy.h:35
__weak error_t ecdsaVerifySignature(const EcDomainParameters *params, const EcPoint *publicKey, const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
ECDSA signature verification.
Definition: ecdsa.c:562
error_t mpiMod(Mpi *r, const Mpi *a, const Mpi *p)
Modulo operation.
Definition: mpi.c:1325
size_t totalLength
Definition: asn1.h:104
void ecdsaFreeSignature(EcdsaSignature *signature)
Release an ECDSA signature.
Definition: ecdsa.c:82
size_t length
Definition: asn1.h:102
#define FALSE
Definition: os_port.h:46
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t
Error codes.
Definition: error.h:42
#define MPI_CHECK(f)
Definition: mpi.h:42
error_t mpiAdd(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision addition.
Definition: mpi.c:696
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:48
#define EC_CHECK(f)
Definition: ec.h:39
ASN.1 tag.
Definition: asn1.h:97
void ecInit(EcPoint *r)
Initialize elliptic curve point.
Definition: ec.c:156
void ecdsaInitSignature(EcdsaSignature *signature)
Initialize an ECDSA signature.
Definition: ecdsa.c:69
error_t mpiInvMod(Mpi *r, const Mpi *a, const Mpi *p)
Modular inverse.
MPI (Multiple Precision Integer Arithmetic)
const uint8_t ECDSA_WITH_SHA384_OID[8]
Definition: ecdsa.c:51
@ ERROR_INVALID_LENGTH
Definition: error.h:109
General definitions for cryptographic algorithms.
Mpi x
x-coordinate
Definition: ec.h:53
error_t asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *data, size_t *written)
Write an ASN.1 tag.
Definition: asn1.c:377
uint_t objClass
Definition: asn1.h:100
Elliptic curve point.
Definition: ec.h:51
error_t ecProjectify(const EcDomainParameters *params, EcPoint *r, const EcPoint *s)
Compute projective representation.
Definition: ec.c:344
const uint8_t ECDSA_WITH_SHA3_224_OID[9]
Definition: ecdsa.c:55
#define MIN(a, b)
Definition: os_port.h:62
const uint8_t ECDSA_WITH_SHA1_OID[7]
Definition: ecdsa.c:45
const uint8_t ECDSA_WITH_SHA224_OID[8]
Definition: ecdsa.c:47
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:195
__weak error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const EcDomainParameters *params, const Mpi *privateKey, const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
ECDSA signature generation.
Definition: ecdsa.c:447
const uint8_t ECDSA_WITH_SHA512_OID[8]
Definition: ecdsa.c:53
uint8_t z
Definition: dns_common.h:175
@ ASN1_TYPE_INTEGER
Definition: asn1.h:66
error_t ecdsaWriteSignature(const EcdsaSignature *signature, uint8_t *data, size_t *length)
Encode ECDSA signature using ASN.1.
Definition: ecdsa.c:98
#define TRACE_DEBUG(...)
Definition: debug.h:106
__weak error_t ecAffinify(const EcDomainParameters *params, EcPoint *r, const EcPoint *s)
Recover affine representation.
Definition: ec.c:368
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:107
const uint8_t ECDSA_WITH_SHA3_384_OID[9]
Definition: ecdsa.c:59
uint8_t n
error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision multiplication.
bool_t constructed
Definition: asn1.h:99
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
@ ASN1_TYPE_SEQUENCE
Definition: asn1.h:76
error_t ecdsaReadSignature(const uint8_t *data, size_t length, EcdsaSignature *signature)
Read an ASN.1 encoded ECDSA signature.
Definition: ecdsa.c:255
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:295
unsigned int uint_t
Definition: compiler_port.h:45
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:109
uint8_t data[]
Definition: dtls_misc.h:176
void ecFree(EcPoint *r)
Release an elliptic curve point.
Definition: ec.c:170
error_t ecTwinMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d0, const EcPoint *s, const Mpi *d1, const EcPoint *t)
Twin multiplication.
Definition: ec.c:984
uint_t mpiGetBitValue(const Mpi *a, uint_t index)
Get the bit value at the specified index.
Definition: mpi.c:270
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
@ ERROR_INVALID_SIGNATURE
Definition: error.h:223
int_t mpiCompInt(const Mpi *a, int_t b)
Compare a multiple precision integer with an integer.
Definition: mpi.c:339
Mpi q
Order of the point G.
Definition: ec.h:71
const uint8_t * value
Definition: asn1.h:103
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:637
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
uint_t objType
Definition: asn1.h:101
ASN.1 (Abstract Syntax Notation One)
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:156
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:62