dsa.c
Go to the documentation of this file.
1 /**
2  * @file dsa.c
3  * @brief DSA (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  * @section Description
28  *
29  * The Digital Signature Algorithm (DSA) is a an algorithm developed by the
30  * NSA to generate a digital signature for the authentication of electronic
31  * documents. Refer to FIPS 186-3 for more details
32  *
33  * @author Oryx Embedded SARL (www.oryx-embedded.com)
34  * @version 2.5.0
35  **/
36 
37 //Switch to the appropriate trace level
38 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
39 
40 //Dependencies
41 #include "core/crypto.h"
42 #include "pkc/dsa.h"
43 #include "mpi/mpi.h"
44 #include "encoding/asn1.h"
45 #include "debug.h"
46 
47 //Check crypto library configuration
48 #if (DSA_SUPPORT == ENABLED)
49 
50 //DSA OID (1.2.840.10040.4.1)
51 const uint8_t DSA_OID[7] = {0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x01};
52 //DSA with SHA-1 OID (1.2.840.10040.4.3)
53 const uint8_t DSA_WITH_SHA1_OID[7] = {0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x03};
54 //DSA with SHA-224 OID (2.16.840.1.101.3.4.3.1)
55 const uint8_t DSA_WITH_SHA224_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x01};
56 //DSA with SHA-256 OID (2.16.840.1.101.3.4.3.2)
57 const uint8_t DSA_WITH_SHA256_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x02};
58 //DSA with SHA-384 OID (2.16.840.1.101.3.4.3.3)
59 const uint8_t DSA_WITH_SHA384_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x03};
60 //DSA with SHA-512 OID (2.16.840.1.101.3.4.3.4)
61 const uint8_t DSA_WITH_SHA512_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x04};
62 //DSA with SHA-3-224 OID (2.16.840.1.101.3.4.3.5)
63 const uint8_t DSA_WITH_SHA3_224_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x05};
64 //DSA with SHA-3-256 OID (2.16.840.1.101.3.4.3.6)
65 const uint8_t DSA_WITH_SHA3_256_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x06};
66 //DSA with SHA-3-384 OID (2.16.840.1.101.3.4.3.7)
67 const uint8_t DSA_WITH_SHA3_384_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x07};
68 //DSA with SHA-3-512 OID (2.16.840.1.101.3.4.3.8)
69 const uint8_t DSA_WITH_SHA3_512_OID[9] = {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x08};
70 
71 
72 /**
73  * @brief Initialize DSA domain parameters
74  * @param[in] params Pointer to the DSA domain parameters to initialize
75  **/
76 
78 {
79  //Initialize multiple precision integers
80  mpiInit(&params->p);
81  mpiInit(&params->q);
82  mpiInit(&params->g);
83 }
84 
85 
86 /**
87  * @brief Release DSA domain parameters
88  * @param[in] params Pointer to the DSA domain parameters to free
89  **/
90 
92 {
93  //Free multiple precision integers
94  mpiFree(&params->p);
95  mpiFree(&params->q);
96  mpiFree(&params->g);
97 }
98 
99 
100 /**
101  * @brief Initialize a DSA public key
102  * @param[in] key Pointer to the DSA public key to initialize
103  **/
104 
106 {
107  //Initialize DSA domain parameters
109  //Initialize public key value
110  mpiInit(&key->y);
111 }
112 
113 
114 /**
115  * @brief Release a DSA public key
116  * @param[in] key Pointer to the DSA public key to free
117  **/
118 
120 {
121  //Free DSA domain parameters
123  //Free public key value
124  mpiFree(&key->y);
125 }
126 
127 
128 /**
129  * @brief Initialize a DSA private key
130  * @param[in] key Pointer to the DSA private key to initialize
131  **/
132 
134 {
135  //Initialize DSA domain parameters
137  //Initialize secret exponent
138  mpiInit(&key->x);
139  //Initialize public key value
140  mpiInit(&key->y);
141 
142  //Initialize private key slot
143  key->slot = -1;
144 }
145 
146 
147 /**
148  * @brief Release a DSA private key
149  * @param[in] key Pointer to the DSA public key to free
150  **/
151 
153 {
154  //Free DSA domain parameters
156  //Free secret exponent
157  mpiFree(&key->x);
158  //Free public key value
159  mpiFree(&key->y);
160 }
161 
162 
163 /**
164  * @brief Initialize a DSA signature
165  * @param[in] signature Pointer to the DSA signature to initialize
166  **/
167 
169 {
170  //Initialize multiple precision integers
171  mpiInit(&signature->r);
172  mpiInit(&signature->s);
173 }
174 
175 
176 /**
177  * @brief Release a DSA signature
178  * @param[in] signature Pointer to the DSA signature to free
179  **/
180 
182 {
183  //Release multiple precision integers
184  mpiFree(&signature->r);
185  mpiFree(&signature->s);
186 }
187 
188 
189 /**
190  * @brief Import an ASN.1 encoded DSA signature
191  * @param[out] signature DSA signature
192  * @param[in] data Pointer to the octet string
193  * @param[in] length Length of the octet string, in bytes
194  * @return Error code
195  **/
196 
197 error_t dsaImportSignature(DsaSignature *signature, const uint8_t *data,
198  size_t length)
199 {
200  error_t error;
201  Asn1Tag tag;
202 
203  //Debug message
204  TRACE_DEBUG("Importing DSA signature...\r\n");
205 
206  //Dump DSA signature
207  TRACE_DEBUG(" signature:\r\n");
209 
210  //Start of exception handling block
211  do
212  {
213  //Display ASN.1 structure
214  error = asn1DumpObject(data, length, 0);
215  //Any error to report?
216  if(error)
217  break;
218 
219  //Read the contents of the ASN.1 structure
220  error = asn1ReadSequence(data, length, &tag);
221  //Failed to decode ASN.1 tag?
222  if(error)
223  break;
224 
225  //Malformed DSA signature?
226  if(length != tag.totalLength)
227  {
228  //Report an error
229  error = ERROR_INVALID_SYNTAX;
230  break;
231  }
232 
233  //Point to the first field
234  data = tag.value;
235  length = tag.length;
236 
237  //Read the integer R
238  error = asn1ReadTag(data, length, &tag);
239  //Failed to decode ASN.1 tag?
240  if(error)
241  break;
242 
243  //Enforce encoding, class and type
244  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
246  //Invalid tag?
247  if(error)
248  break;
249 
250  //Make sure R is a positive integer
251  if(tag.length == 0 || (tag.value[0] & 0x80) != 0)
252  {
253  //Report an error
254  error = ERROR_INVALID_SYNTAX;
255  break;
256  }
257 
258  //Convert the octet string to a multiple precision integer
259  error = mpiImport(&signature->r, tag.value, tag.length,
261  //Any error to report?
262  if(error)
263  break;
264 
265  //Point to the next field
266  data += tag.totalLength;
267  length -= tag.totalLength;
268 
269  //Read the integer S
270  error = asn1ReadTag(data, length, &tag);
271  //Failed to decode ASN.1 tag?
272  if(error)
273  break;
274 
275  //Enforce encoding, class and type
276  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
278  //Invalid tag?
279  if(error)
280  break;
281 
282  //Make sure S is a positive integer
283  if(tag.length == 0 || (tag.value[0] & 0x80) != 0)
284  {
285  //Report an error
286  error = ERROR_INVALID_SYNTAX;
287  break;
288  }
289 
290  //Convert the octet string to a multiple precision integer
291  error = mpiImport(&signature->s, tag.value, tag.length,
293  //Any error to report?
294  if(error)
295  break;
296 
297  //Malformed DSA signature?
298  if(length != tag.totalLength)
299  {
300  //Report an error
301  error = ERROR_INVALID_SYNTAX;
302  break;
303  }
304 
305  //Dump (R, S) integer pair
306  TRACE_DEBUG(" r:\r\n");
307  TRACE_DEBUG_MPI(" ", &signature->r);
308  TRACE_DEBUG(" s:\r\n");
309  TRACE_DEBUG_MPI(" ", &signature->s);
310 
311  //End of exception handling block
312  } while(0);
313 
314  //Any error to report?
315  if(error)
316  {
317  //Clean up side effects
318  dsaFreeSignature(signature);
319  }
320 
321  //Return status code
322  return error;
323 }
324 
325 
326 /**
327  * @brief Export a DSA signature to ASN.1 format
328  * @param[in] signature DSA signature
329  * @param[out] data Pointer to the octet string
330  * @param[out] length Length of the octet string, in bytes
331  * @return Error code
332  **/
333 
334 error_t dsaExportSignature(const DsaSignature *signature, uint8_t *data,
335  size_t *length)
336 {
337  error_t error;
338  size_t k;
339  size_t n;
340  size_t rLen;
341  size_t sLen;
342  Asn1Tag tag;
343 
344  //Debug message
345  TRACE_DEBUG("Exporting DSA signature...\r\n");
346 
347  //Dump (R, S) integer pair
348  TRACE_DEBUG(" r:\r\n");
349  TRACE_DEBUG_MPI(" ", &signature->r);
350  TRACE_DEBUG(" s:\r\n");
351  TRACE_DEBUG_MPI(" ", &signature->s);
352 
353  //Calculate the length of R
354  rLen = mpiGetByteLength(&signature->r);
355  //Calculate the length of S
356  sLen = mpiGetByteLength(&signature->s);
357 
358  //Make sure the (R, S) integer pair is valid
359  if(rLen == 0 || sLen == 0)
360  return ERROR_INVALID_LENGTH;
361 
362  //R and S are always encoded in the smallest possible number of octets
363  if(mpiGetBitValue(&signature->r, (rLen * 8) - 1))
364  {
365  rLen++;
366  }
367 
368  if(mpiGetBitValue(&signature->s, (sLen * 8) - 1))
369  {
370  sLen++;
371  }
372 
373  //The first pass computes the length of the ASN.1 sequence
374  n = 0;
375 
376  //The integer R is encapsulated within an ASN.1 structure
377  tag.constructed = FALSE;
380  tag.length = rLen;
381  tag.value = NULL;
382 
383  //Compute the length of the corresponding ASN.1 structure
384  error = asn1WriteTag(&tag, FALSE, NULL, NULL);
385  //Any error to report?
386  if(error)
387  return error;
388 
389  //Update the length of the ASN.1 sequence
390  n += tag.totalLength;
391 
392  //The integer S is encapsulated within an ASN.1 structure
393  tag.constructed = FALSE;
396  tag.length = sLen;
397  tag.value = NULL;
398 
399  //Compute the length of the corresponding ASN.1 structure
400  error = asn1WriteTag(&tag, FALSE, NULL, NULL);
401  //Any error to report?
402  if(error)
403  return error;
404 
405  //Update the length of the ASN.1 sequence
406  n += tag.totalLength;
407 
408  //The second pass encodes the ASN.1 structure
409  k = 0;
410 
411  //The (R, S) integer pair is encapsulated within a sequence
412  tag.constructed = TRUE;
415  tag.length = n;
416  tag.value = NULL;
417 
418  //Write the corresponding ASN.1 tag
419  error = asn1WriteTag(&tag, FALSE, data + k, &n);
420  //Any error to report?
421  if(error)
422  return error;
423 
424  //Advance write pointer
425  k += n;
426 
427  //Encode the integer R using ASN.1
428  tag.constructed = FALSE;
431  tag.length = rLen;
432  tag.value = NULL;
433 
434  //Write the corresponding ASN.1 tag
435  error = asn1WriteTag(&tag, FALSE, data + k, &n);
436  //Any error to report?
437  if(error)
438  return error;
439 
440  //Advance write pointer
441  k += n;
442 
443  //Convert R to an octet string
444  error = mpiExport(&signature->r, data + k, rLen, MPI_FORMAT_BIG_ENDIAN);
445  //Any error to report?
446  if(error)
447  return error;
448 
449  //Advance write pointer
450  k += rLen;
451 
452  //Encode the integer S using ASN.1
453  tag.constructed = FALSE;
456  tag.length = sLen;
457  tag.value = NULL;
458 
459  //Write the corresponding ASN.1 tag
460  error = asn1WriteTag(&tag, FALSE, data + k, &n);
461  //Any error to report?
462  if(error)
463  return error;
464 
465  //Advance write pointer
466  k += n;
467 
468  //Convert S to an octet string
469  error = mpiExport(&signature->s, data + k, sLen, MPI_FORMAT_BIG_ENDIAN);
470  //Any error to report?
471  if(error)
472  return error;
473 
474  //Advance write pointer
475  k += sLen;
476 
477  //Dump DSA signature
478  TRACE_DEBUG(" signature:\r\n");
479  TRACE_DEBUG_ARRAY(" ", data, k);
480 
481  //Total length of the ASN.1 structure
482  *length = k;
483 
484  //Successful processing
485  return NO_ERROR;
486 }
487 
488 
489 /**
490  * @brief DSA signature generation
491  * @param[in] prngAlgo PRNG algorithm
492  * @param[in] prngContext Pointer to the PRNG context
493  * @param[in] key Signer's DSA private key
494  * @param[in] digest Digest of the message to be signed
495  * @param[in] digestLen Length in octets of the digest
496  * @param[out] signature (R, S) integer pair
497  * @return Error code
498  **/
499 
500 error_t dsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext,
501  const DsaPrivateKey *key, const uint8_t *digest, size_t digestLen,
502  DsaSignature *signature)
503 {
504  error_t error;
505  uint_t n;
506  Mpi k;
507  Mpi z;
508 
509  //Check parameters
510  if(key == NULL || digest == NULL || signature == NULL)
512 
513  //Debug message
514  TRACE_DEBUG("DSA signature generation...\r\n");
515  TRACE_DEBUG(" p:\r\n");
516  TRACE_DEBUG_MPI(" ", &key->params.p);
517  TRACE_DEBUG(" q:\r\n");
518  TRACE_DEBUG_MPI(" ", &key->params.q);
519  TRACE_DEBUG(" g:\r\n");
520  TRACE_DEBUG_MPI(" ", &key->params.g);
521  TRACE_DEBUG(" x:\r\n");
522  TRACE_DEBUG_MPI(" ", &key->x);
523  TRACE_DEBUG(" digest:\r\n");
524  TRACE_DEBUG_ARRAY(" ", digest, digestLen);
525 
526  //Initialize multiple precision integers
527  mpiInit(&k);
528  mpiInit(&z);
529 
530  //Generate a random number k such as 0 < k < q
531  MPI_CHECK(mpiRandRange(&k, &key->params.q, prngAlgo, prngContext));
532 
533  //Debug message
534  TRACE_DEBUG(" k:\r\n");
535  TRACE_DEBUG_MPI(" ", &k);
536 
537  //Let N be the bit length of q
538  n = mpiGetBitLength(&key->params.q);
539  //Compute N = MIN(N, outlen)
540  n = MIN(n, digestLen * 8);
541 
542  //Convert the digest to a multiple precision integer
543  MPI_CHECK(mpiImport(&z, digest, (n + 7) / 8, MPI_FORMAT_BIG_ENDIAN));
544 
545  //Keep the leftmost N bits of the hash value
546  if((n % 8) != 0)
547  {
548  MPI_CHECK(mpiShiftRight(&z, 8 - (n % 8)));
549  }
550 
551  //Debug message
552  TRACE_DEBUG(" z:\r\n");
553  TRACE_DEBUG_MPI(" ", &z);
554 
555  //Compute r = (g ^ k mod p) mod q
556  MPI_CHECK(mpiExpModRegular(&signature->r, &key->params.g, &k, &key->params.p));
557  MPI_CHECK(mpiMod(&signature->r, &signature->r, &key->params.q));
558 
559  //Compute k ^ -1 mod q
560  MPI_CHECK(mpiInvMod(&k, &k, &key->params.q));
561 
562  //Compute s = k ^ -1 * (z + x * r) mod q
563  MPI_CHECK(mpiMul(&signature->s, &key->x, &signature->r));
564  MPI_CHECK(mpiAdd(&signature->s, &signature->s, &z));
565  MPI_CHECK(mpiMod(&signature->s, &signature->s, &key->params.q));
566  MPI_CHECK(mpiMulMod(&signature->s, &signature->s, &k, &key->params.q));
567 
568  //Dump DSA signature
569  TRACE_DEBUG(" r:\r\n");
570  TRACE_DEBUG_MPI(" ", &signature->r);
571  TRACE_DEBUG(" s:\r\n");
572  TRACE_DEBUG_MPI(" ", &signature->s);
573 
574 end:
575  //Release multiple precision integers
576  mpiFree(&k);
577  mpiFree(&z);
578 
579  //Clean up side effects if necessary
580  if(error)
581  {
582  //Release (R, S) integer pair
583  mpiFree(&signature->r);
584  mpiFree(&signature->r);
585  }
586 
587  //Return status code
588  return error;
589 }
590 
591 
592 /**
593  * @brief DSA signature verification
594  * @param[in] key Signer's DSA public key
595  * @param[in] digest Digest of the message whose signature is to be verified
596  * @param[in] digestLen Length in octets of the digest
597  * @param[in] signature (R, S) integer pair
598  * @return Error code
599  **/
600 
602  const uint8_t *digest, size_t digestLen, const DsaSignature *signature)
603 {
604  error_t error;
605  uint_t n;
606  Mpi w;
607  Mpi z;
608  Mpi u1;
609  Mpi u2;
610  Mpi v;
611 
612  //Check parameters
613  if(key == NULL || digest == NULL || signature == NULL)
615 
616  //Debug message
617  TRACE_DEBUG("DSA signature verification...\r\n");
618  TRACE_DEBUG(" p:\r\n");
619  TRACE_DEBUG_MPI(" ", &key->params.p);
620  TRACE_DEBUG(" q:\r\n");
621  TRACE_DEBUG_MPI(" ", &key->params.q);
622  TRACE_DEBUG(" g:\r\n");
623  TRACE_DEBUG_MPI(" ", &key->params.g);
624  TRACE_DEBUG(" y:\r\n");
625  TRACE_DEBUG_MPI(" ", &key->y);
626  TRACE_DEBUG(" digest:\r\n");
627  TRACE_DEBUG_ARRAY(" ", digest, digestLen);
628  TRACE_DEBUG(" r:\r\n");
629  TRACE_DEBUG_MPI(" ", &signature->r);
630  TRACE_DEBUG(" s:\r\n");
631  TRACE_DEBUG_MPI(" ", &signature->s);
632 
633  //The verifier shall check that 0 < r < q
634  if(mpiCompInt(&signature->r, 0) <= 0 ||
635  mpiComp(&signature->r, &key->params.q) >= 0)
636  {
637  //If the condition is violated, the signature shall be rejected as invalid
639  }
640 
641  //The verifier shall check that 0 < s < q
642  if(mpiCompInt(&signature->s, 0) <= 0 ||
643  mpiComp(&signature->s, &key->params.q) >= 0)
644  {
645  //If the condition is violated, the signature shall be rejected as invalid
647  }
648 
649  //Initialize multiple precision integers
650  mpiInit(&w);
651  mpiInit(&z);
652  mpiInit(&u1);
653  mpiInit(&u2);
654  mpiInit(&v);
655 
656  //Let N be the bit length of q
657  n = mpiGetBitLength(&key->params.q);
658  //Compute N = MIN(N, outlen)
659  n = MIN(n, digestLen * 8);
660 
661  //Convert the digest to a multiple precision integer
662  MPI_CHECK(mpiImport(&z, digest, (n + 7) / 8, MPI_FORMAT_BIG_ENDIAN));
663 
664  //Keep the leftmost N bits of the hash value
665  if((n % 8) != 0)
666  {
667  MPI_CHECK(mpiShiftRight(&z, 8 - (n % 8)));
668  }
669 
670  //Compute w = s ^ -1 mod q
671  MPI_CHECK(mpiInvMod(&w, &signature->s, &key->params.q));
672  //Compute u1 = z * w mod q
673  MPI_CHECK(mpiMulMod(&u1, &z, &w, &key->params.q));
674  //Compute u2 = r * w mod q
675  MPI_CHECK(mpiMulMod(&u2, &signature->r, &w, &key->params.q));
676 
677  //Compute v = ((g ^ u1) * (y ^ u2) mod p) mod q
678  MPI_CHECK(mpiExpModFast(&v, &key->params.g, &u1, &key->params.p));
679  MPI_CHECK(mpiExpModFast(&w, &key->y, &u2, &key->params.p));
680  MPI_CHECK(mpiMulMod(&v, &v, &w, &key->params.p));
681  MPI_CHECK(mpiMod(&v, &v, &key->params.q));
682 
683  //Debug message
684  TRACE_DEBUG(" v:\r\n");
685  TRACE_DEBUG_MPI(" ", &v);
686 
687  //If v = r, then the signature is verified. If v does not equal r, then the
688  //message or the signature may have been modified
689  if(!mpiComp(&v, &signature->r))
690  {
691  error = NO_ERROR;
692  }
693  else
694  {
695  error = ERROR_INVALID_SIGNATURE;
696  }
697 
698 end:
699  //Release multiple precision integers
700  mpiFree(&w);
701  mpiFree(&z);
702  mpiFree(&u1);
703  mpiFree(&u2);
704  mpiFree(&v);
705 
706  //Return status code
707  return error;
708 }
709 
710 #endif
Mpi s
Definition: dsa.h:87
const uint8_t DSA_WITH_SHA224_OID[9]
Definition: dsa.c:55
Arbitrary precision integer.
Definition: mpi.h:102
#define PrngAlgo
Definition: crypto.h:973
error_t dsaImportSignature(DsaSignature *signature, const uint8_t *data, size_t length)
Import an ASN.1 encoded DSA signature.
Definition: dsa.c:197
Mpi q
Group order.
Definition: dsa.h:51
void dsaFreePrivateKey(DsaPrivateKey *key)
Release a DSA private key.
Definition: dsa.c:152
#define TRUE
Definition: os_port.h:50
uint8_t data[]
Definition: ethernet.h:222
error_t asn1DumpObject(const uint8_t *data, size_t length, uint_t level)
Display an ASN.1 data object.
Definition: asn1.c:856
Mpi r
Definition: dsa.h:86
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:652
error_t mpiShiftRight(Mpi *r, uint_t n)
Right shift operation.
Definition: mpi.c:1310
Mpi p
Prime modulus.
Definition: dsa.h:50
error_t mpiInvMod(Mpi *r, const Mpi *a, const Mpi *p)
Modular inverse.
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
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:48
const uint8_t DSA_WITH_SHA3_512_OID[9]
Definition: dsa.c:69
const uint8_t DSA_OID[7]
Definition: dsa.c:51
error_t mpiMod(Mpi *r, const Mpi *a, const Mpi *p)
Modulo operation.
Definition: mpi.c:1587
size_t totalLength
Definition: asn1.h:108
size_t length
Definition: asn1.h:106
#define FALSE
Definition: os_port.h:46
error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision multiplication.
DSA public key.
Definition: dsa.h:61
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t
Error codes.
Definition: error.h:43
Mpi g
Group generator.
Definition: dsa.h:52
void dsaInitSignature(DsaSignature *signature)
Initialize a DSA signature.
Definition: dsa.c:168
const uint8_t DSA_WITH_SHA3_256_OID[9]
Definition: dsa.c:65
#define MPI_CHECK(f)
Definition: mpi.h:74
error_t mpiAdd(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision addition.
Definition: mpi.c:891
const uint8_t DSA_WITH_SHA384_OID[9]
Definition: dsa.c:59
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:52
ASN.1 tag.
Definition: asn1.h:102
error_t mpiImport(Mpi *r, const uint8_t *input, size_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:712
error_t dsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const DsaPrivateKey *key, const uint8_t *digest, size_t digestLen, DsaSignature *signature)
DSA signature generation.
Definition: dsa.c:500
DSA domain parameters.
Definition: dsa.h:49
void dsaInitPrivateKey(DsaPrivateKey *key)
Initialize a DSA private key.
Definition: dsa.c:133
MPI (Multiple Precision Integer Arithmetic)
@ ERROR_INVALID_LENGTH
Definition: error.h:111
const uint8_t DSA_WITH_SHA512_OID[9]
Definition: dsa.c:61
General definitions for cryptographic algorithms.
Mpi y
Public key value.
Definition: dsa.h:75
error_t asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *data, size_t *written)
Write an ASN.1 tag.
Definition: asn1.c:334
DSA (Digital Signature Algorithm)
DsaDomainParameters params
DSA domain parameters.
Definition: dsa.h:62
DSA private key.
Definition: dsa.h:72
void dsaInitDomainParameters(DsaDomainParameters *params)
Initialize DSA domain parameters.
Definition: dsa.c:77
void dsaFreeDomainParameters(DsaDomainParameters *params)
Release DSA domain parameters.
Definition: dsa.c:91
error_t mpiExport(const Mpi *a, uint8_t *output, size_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:809
uint_t objClass
Definition: asn1.h:104
uint8_t length
Definition: tcp.h:375
#define MIN(a, b)
Definition: os_port.h:63
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:254
const uint8_t DSA_WITH_SHA3_384_OID[9]
Definition: dsa.c:67
uint8_t z
Definition: dns_common.h:191
@ ASN1_TYPE_INTEGER
Definition: asn1.h:70
#define TRACE_DEBUG(...)
Definition: debug.h:119
error_t dsaVerifySignature(const DsaPublicKey *key, const uint8_t *digest, size_t digestLen, const DsaSignature *signature)
DSA signature verification.
Definition: dsa.c:601
const uint8_t DSA_WITH_SHA3_224_OID[9]
Definition: dsa.c:63
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:120
uint8_t n
int_t slot
Private key slot.
Definition: dsa.h:76
void dsaFreeSignature(DsaSignature *signature)
Release a DSA signature.
Definition: dsa.c:181
const uint8_t DSA_WITH_SHA1_OID[7]
Definition: dsa.c:53
const uint8_t DSA_WITH_SHA256_OID[9]
Definition: dsa.c:57
error_t mpiExpModFast(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (fast calculation)
Mpi x
Secret exponent.
Definition: dsa.h:74
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:93
bool_t constructed
Definition: asn1.h:103
Mpi y
Public key value.
Definition: dsa.h:63
error_t dsaExportSignature(const DsaSignature *signature, uint8_t *data, size_t *length)
Export a DSA signature to ASN.1 format.
Definition: dsa.c:334
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
@ ASN1_TYPE_SEQUENCE
Definition: asn1.h:80
DsaDomainParameters params
DSA domain parameters.
Definition: dsa.h:73
DSA signature.
Definition: dsa.h:85
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:358
int_t mpiCompInt(const Mpi *a, mpi_sword_t b)
Compare a multiple precision integer with an integer.
Definition: mpi.c:429
unsigned int uint_t
Definition: compiler_port.h:57
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:122
error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular multiplication.
uint_t mpiGetBitValue(const Mpi *a, uint_t index)
Get the bit value at the specified index.
Definition: mpi.c:333
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:228
void dsaFreePublicKey(DsaPublicKey *key)
Release a DSA public key.
Definition: dsa.c:119
const uint8_t * value
Definition: asn1.h:107
void dsaInitPublicKey(DsaPublicKey *key)
Initialize a DSA public key.
Definition: dsa.c:105
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:803
@ NO_ERROR
Success.
Definition: error.h:44
error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (regular calculation)
Debugging facilities.
uint_t objType
Definition: asn1.h:105
ASN.1 (Abstract Syntax Notation One)
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:215
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:64