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