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.2
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] input 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 *input,
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");
208  TRACE_DEBUG_ARRAY(" ", input, length);
209 
210  //Start of exception handling block
211  do
212  {
213  //Display ASN.1 structure
214  error = asn1DumpObject(input, 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(input, 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  input = tag.value;
235  length = tag.length;
236 
237  //Read the integer R
238  error = asn1ReadTag(input, 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  input += tag.totalLength;
267  length -= tag.totalLength;
268 
269  //Read the integer S
270  error = asn1ReadTag(input, 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] output Pointer to the octet string (optional parameter)
330  * @param[out] written Length of the resulting octet string, in bytes
331  * @return Error code
332  **/
333 
334 error_t dsaExportSignature(const DsaSignature *signature, uint8_t *output,
335  size_t *written)
336 {
337  error_t error;
338  size_t k;
339  size_t n;
340  size_t length;
341  uint8_t *p;
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  //Point to the buffer where to write the ASN.1 structure
354  p = output;
355  //Length of the ASN.1 structure
356  length = 0;
357 
358  //R is always encoded in the smallest possible number of octets
359  k = mpiGetBitLength(&signature->r) / 8 + 1;
360 
361  //R is represented by an integer
362  tag.constructed = FALSE;
365  tag.length = k;
366 
367  //Write the corresponding ASN.1 tag
368  error = asn1WriteHeader(&tag, FALSE, p, &n);
369  //Any error to report?
370  if(error)
371  return error;
372 
373  //Advance data pointer
374  ASN1_INC_POINTER(p, n);
375  length += n;
376 
377  //If the output parameter is NULL, then the function calculates the
378  //length of the ASN.1 structure without copying any data
379  if(p != NULL)
380  {
381  //Convert R to an octet string
382  error = mpiExport(&signature->r, p, k, MPI_FORMAT_BIG_ENDIAN);
383  //Any error to report?
384  if(error)
385  return error;
386  }
387 
388  //Advance data pointer
389  ASN1_INC_POINTER(p, k);
390  length += k;
391 
392  //S is always encoded in the smallest possible number of octets
393  k = mpiGetBitLength(&signature->s) / 8 + 1;
394 
395  //S is represented by an integer
396  tag.constructed = FALSE;
399  tag.length = k;
400 
401  //Write the corresponding ASN.1 tag
402  error = asn1WriteHeader(&tag, FALSE, p, &n);
403  //Any error to report?
404  if(error)
405  return error;
406 
407  //Advance data pointer
408  ASN1_INC_POINTER(p, n);
409  length += n;
410 
411  //If the output parameter is NULL, then the function calculates the
412  //length of the ASN.1 structure without copying any data
413  if(p != NULL)
414  {
415  //Convert S to an octet string
416  error = mpiExport(&signature->s, p, k, MPI_FORMAT_BIG_ENDIAN);
417  //Any error to report?
418  if(error)
419  return error;
420  }
421 
422  //Advance data pointer
423  ASN1_INC_POINTER(p, k);
424  length += k;
425 
426  //The (R, S) integer pair is encapsulated within a sequence
427  tag.constructed = TRUE;
430  tag.length = length;
431 
432  //Write the corresponding ASN.1 tag
433  error = asn1InsertHeader(&tag, output, &n);
434  //Any error to report?
435  if(error)
436  return error;
437 
438  //Total length of the ASN.1 structure
439  *written = length + n;
440 
441  //Successful processing
442  return NO_ERROR;
443 }
444 
445 
446 /**
447  * @brief DSA signature generation
448  * @param[in] prngAlgo PRNG algorithm
449  * @param[in] prngContext Pointer to the PRNG context
450  * @param[in] key Signer's DSA private key
451  * @param[in] digest Digest of the message to be signed
452  * @param[in] digestLen Length in octets of the digest
453  * @param[out] signature (R, S) integer pair
454  * @return Error code
455  **/
456 
457 error_t dsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext,
458  const DsaPrivateKey *key, const uint8_t *digest, size_t digestLen,
459  DsaSignature *signature)
460 {
461  error_t error;
462  uint_t n;
463  Mpi k;
464  Mpi z;
465 
466  //Check parameters
467  if(key == NULL || digest == NULL || signature == NULL)
469 
470  //Debug message
471  TRACE_DEBUG("DSA signature generation...\r\n");
472  TRACE_DEBUG(" p:\r\n");
473  TRACE_DEBUG_MPI(" ", &key->params.p);
474  TRACE_DEBUG(" q:\r\n");
475  TRACE_DEBUG_MPI(" ", &key->params.q);
476  TRACE_DEBUG(" g:\r\n");
477  TRACE_DEBUG_MPI(" ", &key->params.g);
478  TRACE_DEBUG(" x:\r\n");
479  TRACE_DEBUG_MPI(" ", &key->x);
480  TRACE_DEBUG(" digest:\r\n");
481  TRACE_DEBUG_ARRAY(" ", digest, digestLen);
482 
483  //Initialize multiple precision integers
484  mpiInit(&k);
485  mpiInit(&z);
486 
487  //Generate a random number k such as 0 < k < q
488  MPI_CHECK(mpiRandRange(&k, &key->params.q, prngAlgo, prngContext));
489 
490  //Debug message
491  TRACE_DEBUG(" k:\r\n");
492  TRACE_DEBUG_MPI(" ", &k);
493 
494  //Let N be the bit length of q
495  n = mpiGetBitLength(&key->params.q);
496  //Compute N = MIN(N, outlen)
497  n = MIN(n, digestLen * 8);
498 
499  //Convert the digest to a multiple precision integer
500  MPI_CHECK(mpiImport(&z, digest, (n + 7) / 8, MPI_FORMAT_BIG_ENDIAN));
501 
502  //Keep the leftmost N bits of the hash value
503  if((n % 8) != 0)
504  {
505  MPI_CHECK(mpiShiftRight(&z, 8 - (n % 8)));
506  }
507 
508  //Debug message
509  TRACE_DEBUG(" z:\r\n");
510  TRACE_DEBUG_MPI(" ", &z);
511 
512  //Compute r = (g ^ k mod p) mod q
513  MPI_CHECK(mpiExpModRegular(&signature->r, &key->params.g, &k, &key->params.p));
514  MPI_CHECK(mpiMod(&signature->r, &signature->r, &key->params.q));
515 
516  //Compute k ^ -1 mod q
517  MPI_CHECK(mpiInvMod(&k, &k, &key->params.q));
518 
519  //Compute s = k ^ -1 * (z + x * r) mod q
520  MPI_CHECK(mpiMul(&signature->s, &key->x, &signature->r));
521  MPI_CHECK(mpiAdd(&signature->s, &signature->s, &z));
522  MPI_CHECK(mpiMod(&signature->s, &signature->s, &key->params.q));
523  MPI_CHECK(mpiMulMod(&signature->s, &signature->s, &k, &key->params.q));
524 
525  //Dump DSA signature
526  TRACE_DEBUG(" r:\r\n");
527  TRACE_DEBUG_MPI(" ", &signature->r);
528  TRACE_DEBUG(" s:\r\n");
529  TRACE_DEBUG_MPI(" ", &signature->s);
530 
531 end:
532  //Release multiple precision integers
533  mpiFree(&k);
534  mpiFree(&z);
535 
536  //Clean up side effects if necessary
537  if(error)
538  {
539  //Release (R, S) integer pair
540  mpiFree(&signature->r);
541  mpiFree(&signature->r);
542  }
543 
544  //Return status code
545  return error;
546 }
547 
548 
549 /**
550  * @brief DSA signature verification
551  * @param[in] key Signer's DSA public key
552  * @param[in] digest Digest of the message whose signature is to be verified
553  * @param[in] digestLen Length in octets of the digest
554  * @param[in] signature (R, S) integer pair
555  * @return Error code
556  **/
557 
559  const uint8_t *digest, size_t digestLen, const DsaSignature *signature)
560 {
561  error_t error;
562  uint_t n;
563  Mpi w;
564  Mpi z;
565  Mpi u1;
566  Mpi u2;
567  Mpi v;
568 
569  //Check parameters
570  if(key == NULL || digest == NULL || signature == NULL)
572 
573  //Debug message
574  TRACE_DEBUG("DSA signature verification...\r\n");
575  TRACE_DEBUG(" p:\r\n");
576  TRACE_DEBUG_MPI(" ", &key->params.p);
577  TRACE_DEBUG(" q:\r\n");
578  TRACE_DEBUG_MPI(" ", &key->params.q);
579  TRACE_DEBUG(" g:\r\n");
580  TRACE_DEBUG_MPI(" ", &key->params.g);
581  TRACE_DEBUG(" y:\r\n");
582  TRACE_DEBUG_MPI(" ", &key->y);
583  TRACE_DEBUG(" digest:\r\n");
584  TRACE_DEBUG_ARRAY(" ", digest, digestLen);
585  TRACE_DEBUG(" r:\r\n");
586  TRACE_DEBUG_MPI(" ", &signature->r);
587  TRACE_DEBUG(" s:\r\n");
588  TRACE_DEBUG_MPI(" ", &signature->s);
589 
590  //The verifier shall check that 0 < r < q
591  if(mpiCompInt(&signature->r, 0) <= 0 ||
592  mpiComp(&signature->r, &key->params.q) >= 0)
593  {
594  //If the condition is violated, the signature shall be rejected as invalid
596  }
597 
598  //The verifier shall check that 0 < s < q
599  if(mpiCompInt(&signature->s, 0) <= 0 ||
600  mpiComp(&signature->s, &key->params.q) >= 0)
601  {
602  //If the condition is violated, the signature shall be rejected as invalid
604  }
605 
606  //Initialize multiple precision integers
607  mpiInit(&w);
608  mpiInit(&z);
609  mpiInit(&u1);
610  mpiInit(&u2);
611  mpiInit(&v);
612 
613  //Let N be the bit length of q
614  n = mpiGetBitLength(&key->params.q);
615  //Compute N = MIN(N, outlen)
616  n = MIN(n, digestLen * 8);
617 
618  //Convert the digest to a multiple precision integer
619  MPI_CHECK(mpiImport(&z, digest, (n + 7) / 8, MPI_FORMAT_BIG_ENDIAN));
620 
621  //Keep the leftmost N bits of the hash value
622  if((n % 8) != 0)
623  {
624  MPI_CHECK(mpiShiftRight(&z, 8 - (n % 8)));
625  }
626 
627  //Compute w = s ^ -1 mod q
628  MPI_CHECK(mpiInvMod(&w, &signature->s, &key->params.q));
629  //Compute u1 = z * w mod q
630  MPI_CHECK(mpiMulMod(&u1, &z, &w, &key->params.q));
631  //Compute u2 = r * w mod q
632  MPI_CHECK(mpiMulMod(&u2, &signature->r, &w, &key->params.q));
633 
634  //Compute v = ((g ^ u1) * (y ^ u2) mod p) mod q
635  MPI_CHECK(mpiExpModFast(&v, &key->params.g, &u1, &key->params.p));
636  MPI_CHECK(mpiExpModFast(&w, &key->y, &u2, &key->params.p));
637  MPI_CHECK(mpiMulMod(&v, &v, &w, &key->params.p));
638  MPI_CHECK(mpiMod(&v, &v, &key->params.q));
639 
640  //Debug message
641  TRACE_DEBUG(" v:\r\n");
642  TRACE_DEBUG_MPI(" ", &v);
643 
644  //If v = r, then the signature is verified. If v does not equal r, then the
645  //message or the signature may have been modified
646  if(!mpiComp(&v, &signature->r))
647  {
648  error = NO_ERROR;
649  }
650  else
651  {
652  error = ERROR_INVALID_SIGNATURE;
653  }
654 
655 end:
656  //Release multiple precision integers
657  mpiFree(&w);
658  mpiFree(&z);
659  mpiFree(&u1);
660  mpiFree(&u2);
661  mpiFree(&v);
662 
663  //Return status code
664  return error;
665 }
666 
667 #endif
Mpi s
Definition: dsa.h:87
error_t dsaImportSignature(DsaSignature *signature, const uint8_t *input, size_t length)
Import an ASN.1 encoded DSA signature.
Definition: dsa.c:197
const uint8_t DSA_WITH_SHA224_OID[9]
Definition: dsa.c:55
Arbitrary precision integer.
Definition: mpi.h:102
#define PrngAlgo
Definition: crypto.h:980
uint8_t p
Definition: ndp.h:300
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
error_t asn1WriteHeader(Asn1Tag *tag, bool_t reverse, uint8_t *data, size_t *written)
Write an ASN.1 tag header.
Definition: asn1.c:501
error_t asn1InsertHeader(Asn1Tag *tag, uint8_t *data, size_t *written)
Insert an ASN.1 tag header.
Definition: asn1.c:643
error_t asn1DumpObject(const uint8_t *data, size_t length, uint_t level)
Display an ASN.1 data object.
Definition: asn1.c:999
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:111
size_t length
Definition: asn1.h:109
#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:105
#define ASN1_INC_POINTER(p, n)
Definition: asn1.h:58
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:457
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)
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
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:107
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:193
@ ASN1_TYPE_INTEGER
Definition: asn1.h:73
#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:558
const uint8_t DSA_WITH_SHA3_224_OID[9]
Definition: dsa.c:63
error_t dsaExportSignature(const DsaSignature *signature, uint8_t *output, size_t *written)
Export a DSA signature to ASN.1 format.
Definition: dsa.c:334
#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:106
Mpi y
Public key value.
Definition: dsa.h:63
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
@ ASN1_TYPE_SEQUENCE
Definition: asn1.h:83
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.
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:110
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:944
@ 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:108
ASN.1 (Abstract Syntax Notation One)
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:64