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-2024 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.4.0
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 
98 error_t ecdsaWriteSignature(const EcdsaSignature *signature, uint8_t *data,
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  {
129  rLen++;
130  }
131 
132  if(mpiGetBitValue(&signature->s, (sLen * 8) - 1))
133  {
134  sLen++;
135  }
136 
137  //The first pass computes the length of the ASN.1 sequence
138  n = 0;
139 
140  //The parameter R is encapsulated within an ASN.1 structure
141  tag.constructed = FALSE;
144  tag.length = rLen;
145  tag.value = NULL;
146 
147  //Compute the length of the corresponding ASN.1 structure
148  error = asn1WriteTag(&tag, FALSE, NULL, NULL);
149  //Any error to report?
150  if(error)
151  return error;
152 
153  //Update the length of the ASN.1 sequence
154  n += tag.totalLength;
155 
156  //The parameter S is encapsulated within an ASN.1 structure
157  tag.constructed = FALSE;
160  tag.length = sLen;
161  tag.value = NULL;
162 
163  //Compute the length of the corresponding ASN.1 structure
164  error = asn1WriteTag(&tag, FALSE, NULL, NULL);
165  //Any error to report?
166  if(error)
167  return error;
168 
169  //Update the length of the ASN.1 sequence
170  n += tag.totalLength;
171 
172  //The second pass encodes the ASN.1 structure
173  k = 0;
174 
175  //The (R, S) integer pair is encapsulated within a sequence
176  tag.constructed = TRUE;
179  tag.length = n;
180  tag.value = NULL;
181 
182  //Write the corresponding ASN.1 tag
183  error = asn1WriteTag(&tag, FALSE, data + k, &n);
184  //Any error to report?
185  if(error)
186  return error;
187 
188  //Advance write pointer
189  k += n;
190 
191  //Encode the parameter R using ASN.1
192  tag.constructed = FALSE;
195  tag.length = rLen;
196  tag.value = NULL;
197 
198  //Write the corresponding ASN.1 tag
199  error = asn1WriteTag(&tag, FALSE, data + k, &n);
200  //Any error to report?
201  if(error)
202  return error;
203 
204  //Advance write pointer
205  k += n;
206 
207  //Convert R to an octet string
208  error = mpiWriteRaw(&signature->r, data + k, rLen);
209  //Any error to report?
210  if(error)
211  return error;
212 
213  //Advance write pointer
214  k += rLen;
215 
216  //Encode the parameter S using ASN.1
217  tag.constructed = FALSE;
220  tag.length = sLen;
221  tag.value = NULL;
222 
223  //Write the corresponding ASN.1 tag
224  error = asn1WriteTag(&tag, FALSE, data + k, &n);
225  //Any error to report?
226  if(error)
227  return error;
228 
229  //Advance write pointer
230  k += n;
231 
232  //Convert S to an octet string
233  error = mpiWriteRaw(&signature->s, data + k, sLen);
234  //Any error to report?
235  if(error)
236  return error;
237 
238  //Advance write pointer
239  k += sLen;
240 
241  //Dump ECDSA signature
242  TRACE_DEBUG(" signature:\r\n");
243  TRACE_DEBUG_ARRAY(" ", data, k);
244 
245  //Total length of the ASN.1 structure
246  *length = k;
247  //Successful processing
248  return NO_ERROR;
249 }
250 
251 
252 /**
253  * @brief Read an ASN.1 encoded ECDSA signature
254  * @param[in] data Pointer to the ASN.1 structure to decode
255  * @param[in] length Length of the ASN.1 structure
256  * @param[out] signature (R, S) integer pair
257  * @return Error code
258  **/
259 
260 error_t ecdsaReadSignature(const uint8_t *data, size_t length,
261  EcdsaSignature *signature)
262 {
263  error_t error;
264  Asn1Tag tag;
265 
266  //Debug message
267  TRACE_DEBUG("Reading ECDSA signature...\r\n");
268 
269  //Dump ECDSA signature
270  TRACE_DEBUG(" signature:\r\n");
272 
273  //Start of exception handling block
274  do
275  {
276  //Display ASN.1 structure
277  error = asn1DumpObject(data, length, 0);
278  //Any error to report?
279  if(error)
280  break;
281 
282  //Read the contents of the ASN.1 structure
283  error = asn1ReadSequence(data, length, &tag);
284  //Failed to decode ASN.1 tag?
285  if(error)
286  break;
287 
288  //Malformed ECDSA signature?
289  if(length != tag.totalLength)
290  {
291  //Report an error
292  error = ERROR_INVALID_SYNTAX;
293  break;
294  }
295 
296  //Point to the first field
297  data = tag.value;
298  length = tag.length;
299 
300  //Read the parameter R
301  error = asn1ReadTag(data, length, &tag);
302  //Failed to decode ASN.1 tag?
303  if(error)
304  break;
305 
306  //Enforce encoding, class and type
308  //Invalid tag?
309  if(error)
310  break;
311 
312  //Make sure R is a positive integer
313  if(tag.length == 0 || (tag.value[0] & 0x80) != 0)
314  {
315  //Report an error
316  error = ERROR_INVALID_SYNTAX;
317  break;
318  }
319 
320  //Convert the octet string to a multiple precision integer
321  error = mpiReadRaw(&signature->r, tag.value, tag.length);
322  //Any error to report?
323  if(error)
324  break;
325 
326  //Point to the next field
327  data += tag.totalLength;
328  length -= tag.totalLength;
329 
330  //Read the parameter S
331  error = asn1ReadTag(data, length, &tag);
332  //Failed to decode ASN.1 tag?
333  if(error)
334  break;
335 
336  //Enforce encoding, class and type
338  //Invalid tag?
339  if(error)
340  break;
341 
342  //Make sure S is a positive integer
343  if(tag.length == 0 || (tag.value[0] & 0x80) != 0)
344  {
345  //Report an error
346  error = ERROR_INVALID_SYNTAX;
347  break;
348  }
349 
350  //Convert the octet string to a multiple precision integer
351  error = mpiReadRaw(&signature->s, tag.value, tag.length);
352  //Any error to report?
353  if(error)
354  break;
355 
356  //Malformed ECDSA signature?
357  if(length != tag.totalLength)
358  {
359  //Report an error
360  error = ERROR_INVALID_SYNTAX;
361  break;
362  }
363 
364  //Dump (R, S) integer pair
365  TRACE_DEBUG(" r:\r\n");
366  TRACE_DEBUG_MPI(" ", &signature->r);
367  TRACE_DEBUG(" s:\r\n");
368  TRACE_DEBUG_MPI(" ", &signature->s);
369 
370  //End of exception handling block
371  } while(0);
372 
373  //Any error to report?
374  if(error)
375  {
376  //Clean up side effects
377  ecdsaFreeSignature(signature);
378  }
379 
380  //Return status code
381  return error;
382 }
383 
384 
385 /**
386  * @brief ECDSA signature generation
387  * @param[in] prngAlgo PRNG algorithm
388  * @param[in] prngContext Pointer to the PRNG context
389  * @param[in] params EC domain parameters
390  * @param[in] privateKey Signer's EC private key
391  * @param[in] digest Digest of the message to be signed
392  * @param[in] digestLen Length in octets of the digest
393  * @param[out] signature (R, S) integer pair
394  * @return Error code
395  **/
396 
397 __weak_func error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext,
398  const EcDomainParameters *params, const EcPrivateKey *privateKey,
399  const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
400 {
401  error_t error;
402  uint_t n;
403  Mpi k;
404  Mpi z;
405  EcPoint r1;
406 
407  //Check parameters
408  if(params == NULL || privateKey == NULL || digest == NULL || signature == NULL)
410 
411  //Debug message
412  TRACE_DEBUG("ECDSA signature generation...\r\n");
413  TRACE_DEBUG(" private key:\r\n");
414  TRACE_DEBUG_MPI(" ", &privateKey->d);
415  TRACE_DEBUG(" digest:\r\n");
416  TRACE_DEBUG_ARRAY(" ", digest, digestLen);
417 
418  //Initialize multiple precision integers
419  mpiInit(&k);
420  mpiInit(&z);
421  //Initialize EC point
422  ecInit(&r1);
423 
424  //Generate a random number k such as 0 < k < q
425  MPI_CHECK(mpiRandRange(&k, &params->q, prngAlgo, prngContext));
426 
427  //Debug message
428  TRACE_DEBUG(" k:\r\n");
429  TRACE_DEBUG_MPI(" ", &k);
430 
431  //Let N be the bit length of q
432  n = mpiGetBitLength(&params->q);
433  //Compute N = MIN(N, outlen)
434  n = MIN(n, digestLen * 8);
435 
436  //Convert the digest to a multiple precision integer
437  MPI_CHECK(mpiReadRaw(&z, digest, (n + 7) / 8));
438 
439  //Keep the leftmost N bits of the hash value
440  if((n % 8) != 0)
441  {
442  MPI_CHECK(mpiShiftRight(&z, 8 - (n % 8)));
443  }
444 
445  //Debug message
446  TRACE_DEBUG(" z:\r\n");
447  TRACE_DEBUG_MPI(" ", &z);
448 
449  //Compute R1 = (x1, y1) = k.G
450  EC_CHECK(ecMult(params, &r1, &k, &params->g));
451  EC_CHECK(ecAffinify(params, &r1, &r1));
452 
453  //Debug message
454  TRACE_DEBUG(" x1:\r\n");
455  TRACE_DEBUG_MPI(" ", &r1.x);
456  TRACE_DEBUG(" y1:\r\n");
457  TRACE_DEBUG_MPI(" ", &r1.y);
458 
459  //Compute r = x1 mod q
460  MPI_CHECK(mpiMod(&signature->r, &r1.x, &params->q));
461 
462  //Compute k ^ -1 mod q
463  MPI_CHECK(mpiInvMod(&k, &k, &params->q));
464 
465  //Compute s = k ^ -1 * (z + x * r) mod q
466  MPI_CHECK(mpiMul(&signature->s, &privateKey->d, &signature->r));
467  MPI_CHECK(mpiAdd(&signature->s, &signature->s, &z));
468  MPI_CHECK(mpiMod(&signature->s, &signature->s, &params->q));
469  MPI_CHECK(mpiMulMod(&signature->s, &signature->s, &k, &params->q));
470 
471  //Dump ECDSA signature
472  TRACE_DEBUG(" r:\r\n");
473  TRACE_DEBUG_MPI(" ", &signature->r);
474  TRACE_DEBUG(" s:\r\n");
475  TRACE_DEBUG_MPI(" ", &signature->s);
476 
477 end:
478  //Release multiple precision integers
479  mpiFree(&k);
480  mpiFree(&z);
481  //Release EC point
482  ecFree(&r1);
483 
484  //Clean up side effects if necessary
485  if(error)
486  {
487  //Release (R, S) integer pair
488  mpiFree(&signature->r);
489  mpiFree(&signature->s);
490  }
491 
492  //Return status code
493  return error;
494 }
495 
496 
497 /**
498  * @brief ECDSA signature verification
499  * @param[in] params EC domain parameters
500  * @param[in] publicKey Signer's EC public key
501  * @param[in] digest Digest of the message whose signature is to be verified
502  * @param[in] digestLen Length in octets of the digest
503  * @param[in] signature (R, S) integer pair
504  * @return Error code
505  **/
506 
508  const EcPublicKey *publicKey, const uint8_t *digest, size_t digestLen,
509  const EcdsaSignature *signature)
510 {
511  error_t error;
512  uint_t n;
513  Mpi w;
514  Mpi z;
515  Mpi u1;
516  Mpi u2;
517  Mpi v;
518  EcPoint v0;
519  EcPoint v1;
520 
521  //Check parameters
522  if(params == NULL || publicKey == NULL || digest == NULL || signature == NULL)
524 
525  //Debug message
526  TRACE_DEBUG("ECDSA signature verification...\r\n");
527  TRACE_DEBUG(" public key X:\r\n");
528  TRACE_DEBUG_MPI(" ", &publicKey->q.x);
529  TRACE_DEBUG(" public key Y:\r\n");
530  TRACE_DEBUG_MPI(" ", &publicKey->q.y);
531  TRACE_DEBUG(" digest:\r\n");
532  TRACE_DEBUG_ARRAY(" ", digest, digestLen);
533  TRACE_DEBUG(" r:\r\n");
534  TRACE_DEBUG_MPI(" ", &signature->r);
535  TRACE_DEBUG(" s:\r\n");
536  TRACE_DEBUG_MPI(" ", &signature->s);
537 
538  //The verifier shall check that 0 < r < q
539  if(mpiCompInt(&signature->r, 0) <= 0 ||
540  mpiComp(&signature->r, &params->q) >= 0)
541  {
542  //If the condition is violated, the signature shall be rejected as invalid
544  }
545 
546  //The verifier shall check that 0 < s < q
547  if(mpiCompInt(&signature->s, 0) <= 0 ||
548  mpiComp(&signature->s, &params->q) >= 0)
549  {
550  //If the condition is violated, the signature shall be rejected as invalid
552  }
553 
554  //Initialize multiple precision integers
555  mpiInit(&w);
556  mpiInit(&z);
557  mpiInit(&u1);
558  mpiInit(&u2);
559  mpiInit(&v);
560  //Initialize EC points
561  ecInit(&v0);
562  ecInit(&v1);
563 
564  //Let N be the bit length of q
565  n = mpiGetBitLength(&params->q);
566  //Compute N = MIN(N, outlen)
567  n = MIN(n, digestLen * 8);
568 
569  //Convert the digest to a multiple precision integer
570  MPI_CHECK(mpiReadRaw(&z, digest, (n + 7) / 8));
571 
572  //Keep the leftmost N bits of the hash value
573  if((n % 8) != 0)
574  {
575  MPI_CHECK(mpiShiftRight(&z, 8 - (n % 8)));
576  }
577 
578  //Compute w = s ^ -1 mod q
579  MPI_CHECK(mpiInvMod(&w, &signature->s, &params->q));
580  //Compute u1 = z * w mod q
581  MPI_CHECK(mpiMulMod(&u1, &z, &w, &params->q));
582  //Compute u2 = r * w mod q
583  MPI_CHECK(mpiMulMod(&u2, &signature->r, &w, &params->q));
584 
585  //Compute V0 = (x0, y0) = u1.G + u2.Q
586  EC_CHECK(ecProjectify(params, &v1, &publicKey->q));
587  EC_CHECK(ecTwinMult(params, &v0, &u1, &params->g, &u2, &v1));
588  EC_CHECK(ecAffinify(params, &v0, &v0));
589 
590  //Debug message
591  TRACE_DEBUG(" x0:\r\n");
592  TRACE_DEBUG_MPI(" ", &v0.x);
593  TRACE_DEBUG(" y0:\r\n");
594  TRACE_DEBUG_MPI(" ", &v0.y);
595 
596  //Compute v = x0 mod q
597  MPI_CHECK(mpiMod(&v, &v0.x, &params->q));
598 
599  //Debug message
600  TRACE_DEBUG(" v:\r\n");
601  TRACE_DEBUG_MPI(" ", &v);
602 
603  //If v = r, then the signature is verified. If v does not equal r,
604  //then the message or the signature may have been modified
605  if(!mpiComp(&v, &signature->r))
606  {
607  error = NO_ERROR;
608  }
609  else
610  {
611  error = ERROR_INVALID_SIGNATURE;
612  }
613 
614 end:
615  //Release multiple precision integers
616  mpiFree(&w);
617  mpiFree(&z);
618  mpiFree(&u1);
619  mpiFree(&u2);
620  mpiFree(&v);
621  //Release EC points
622  ecFree(&v0);
623  ecFree(&v1);
624 
625  //Return status code
626  return error;
627 }
628 
629 #endif
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 asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *data, size_t *written)
Write an ASN.1 tag.
Definition: asn1.c:334
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_t asn1CheckTag(const Asn1Tag *tag, bool_t constructed, uint_t objClass, uint_t objType)
Enforce the type of a specified tag.
Definition: asn1.c:653
error_t asn1DumpObject(const uint8_t *data, size_t length, uint_t level)
Display an ASN.1 data object.
Definition: asn1.c:706
ASN.1 (Abstract Syntax Notation One)
@ ASN1_TYPE_INTEGER
Definition: asn1.h:70
@ ASN1_TYPE_SEQUENCE
Definition: asn1.h:80
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:52
unsigned int uint_t
Definition: compiler_port.h:50
General definitions for cryptographic algorithms.
#define PrngAlgo
Definition: crypto.h:917
#define mpiReadRaw(r, data, length)
Definition: crypto_legacy.h:35
#define mpiWriteRaw(a, data, length)
Definition: crypto_legacy.h:36
Debugging facilities.
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:108
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:110
uint8_t n
uint8_t z
Definition: dns_common.h:191
error_t ecProjectify(const EcDomainParameters *params, EcPoint *r, const EcPoint *s)
Compute projective representation.
Definition: ec.c:495
__weak_func error_t ecAffinify(const EcDomainParameters *params, EcPoint *r, const EcPoint *s)
Recover affine representation.
Definition: ec.c:519
__weak_func error_t ecMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d, const EcPoint *s)
Scalar multiplication.
Definition: ec.c:986
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:1135
void ecInit(EcPoint *r)
Initialize elliptic curve point.
Definition: ec.c:307
void ecFree(EcPoint *r)
Release an elliptic curve point.
Definition: ec.c:321
#define EC_CHECK(f)
Definition: ec.h:39
const uint8_t ECDSA_WITH_SHA224_OID[8]
Definition: ecdsa.c:47
const uint8_t ECDSA_WITH_SHA3_224_OID[9]
Definition: ecdsa.c:55
const uint8_t ECDSA_WITH_SHA3_512_OID[9]
Definition: ecdsa.c:61
error_t ecdsaWriteSignature(const EcdsaSignature *signature, uint8_t *data, size_t *length)
Encode ECDSA signature using ASN.1.
Definition: ecdsa.c:98
error_t ecdsaReadSignature(const uint8_t *data, size_t length, EcdsaSignature *signature)
Read an ASN.1 encoded ECDSA signature.
Definition: ecdsa.c:260
const uint8_t ECDSA_WITH_SHA256_OID[8]
Definition: ecdsa.c:49
const uint8_t ECDSA_WITH_SHA3_256_OID[9]
Definition: ecdsa.c:57
__weak_func error_t ecdsaVerifySignature(const EcDomainParameters *params, const EcPublicKey *publicKey, const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
ECDSA signature verification.
Definition: ecdsa.c:507
void ecdsaFreeSignature(EcdsaSignature *signature)
Release an ECDSA signature.
Definition: ecdsa.c:82
const uint8_t ECDSA_WITH_SHA384_OID[8]
Definition: ecdsa.c:51
__weak_func error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const EcDomainParameters *params, const EcPrivateKey *privateKey, const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
ECDSA signature generation.
Definition: ecdsa.c:397
const uint8_t ECDSA_WITH_SHA512_OID[8]
Definition: ecdsa.c:53
void ecdsaInitSignature(EcdsaSignature *signature)
Initialize an ECDSA signature.
Definition: ecdsa.c:69
const uint8_t ECDSA_WITH_SHA1_OID[7]
Definition: ecdsa.c:45
const uint8_t ECDSA_WITH_SHA3_384_OID[9]
Definition: ecdsa.c:59
ECDSA (Elliptic Curve Digital Signature Algorithm)
error_t
Error codes.
Definition: error.h:43
@ ERROR_INVALID_SIGNATURE
Definition: error.h:226
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision multiplication.
uint8_t data[]
Definition: ethernet.h:222
error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular multiplication.
error_t mpiRandRange(Mpi *r, const Mpi *p, const PrngAlgo *prngAlgo, void *prngContext)
Generate a random value in the range 1 to p-1.
Definition: mpi.c:564
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:234
int_t mpiCompInt(const Mpi *a, int_t b)
Compare a multiple precision integer with an integer.
Definition: mpi.c:382
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:338
error_t mpiShiftRight(Mpi *r, uint_t n)
Right shift operation.
Definition: mpi.c:1178
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:48
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:195
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:64
error_t mpiAdd(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision addition.
Definition: mpi.c:787
error_t mpiMod(Mpi *r, const Mpi *a, const Mpi *p)
Modulo operation.
Definition: mpi.c:1444
uint_t mpiGetBitValue(const Mpi *a, uint_t index)
Get the bit value at the specified index.
Definition: mpi.c:313
MPI (Multiple Precision Integer Arithmetic)
#define MPI_CHECK(f)
Definition: mpi.h:52
#define MIN(a, b)
Definition: os_port.h:63
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
error_t mpiInvMod(Mpi *r, const Mpi *a, const Mpi *p)
Modular inverse.
ASN.1 tag.
Definition: asn1.h:102
size_t totalLength
Definition: asn1.h:108
const uint8_t * value
Definition: asn1.h:107
uint_t objClass
Definition: asn1.h:104
uint_t objType
Definition: asn1.h:105
bool_t constructed
Definition: asn1.h:103
size_t length
Definition: asn1.h:106
EC domain parameters.
Definition: ec.h:76
EcPoint g
Base point G.
Definition: ec.h:82
Mpi q
Order of the point G.
Definition: ec.h:83
EC point.
Definition: ec.h:64
Mpi y
y-coordinate
Definition: ec.h:66
Mpi x
x-coordinate
Definition: ec.h:65
EC private key.
Definition: ec.h:104
Mpi d
Private key.
Definition: ec.h:105
EC public key.
Definition: ec.h:94
EcPoint q
Public key.
Definition: ec.h:95
ECDSA signature.
Definition: ecdsa.h:49
Arbitrary precision integer.
Definition: mpi.h:80
uint8_t length
Definition: tcp.h:368