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-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCrypto Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @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 1.9.6
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 a DSA public key
74  * @param[in] key Pointer to the DSA public key to initialize
75  **/
76 
78 {
79  //Initialize multiple precision integers
80  mpiInit(&key->p);
81  mpiInit(&key->q);
82  mpiInit(&key->g);
83  mpiInit(&key->y);
84 }
85 
86 
87 /**
88  * @brief Release a DSA public key
89  * @param[in] key Pointer to the DSA public key to free
90  **/
91 
93 {
94  //Free multiple precision integers
95  mpiFree(&key->p);
96  mpiFree(&key->q);
97  mpiFree(&key->g);
98  mpiFree(&key->y);
99 }
100 
101 
102 /**
103  * @brief Initialize a DSA private key
104  * @param[in] key Pointer to the DSA private key to initialize
105  **/
106 
108 {
109  //Initialize multiple precision integers
110  mpiInit(&key->p);
111  mpiInit(&key->q);
112  mpiInit(&key->g);
113  mpiInit(&key->x);
114 }
115 
116 
117 /**
118  * @brief Release a DSA private key
119  * @param[in] key Pointer to the DSA public key to free
120  **/
121 
123 {
124  //Free multiple precision integers
125  mpiFree(&key->p);
126  mpiFree(&key->q);
127  mpiFree(&key->g);
128  mpiFree(&key->x);
129 }
130 
131 
132 /**
133  * @brief Initialize a DSA signature
134  * @param[in] signature Pointer to the DSA signature to initialize
135  **/
136 
138 {
139  //Initialize multiple precision integers
140  mpiInit(&signature->r);
141  mpiInit(&signature->s);
142 }
143 
144 
145 /**
146  * @brief Release a DSA signature
147  * @param[in] signature Pointer to the DSA signature to free
148  **/
149 
151 {
152  //Release multiple precision integers
153  mpiFree(&signature->r);
154  mpiFree(&signature->s);
155 }
156 
157 
158 /**
159  * @brief Encode DSA signature using ASN.1
160  * @param[in] signature (R, S) integer pair
161  * @param[out] data Pointer to the buffer where to store the resulting ASN.1 structure
162  * @param[out] length Length of the ASN.1 structure
163  * @return Error code
164  **/
165 
167 {
168  error_t error;
169  size_t k;
170  size_t n;
171  size_t rLen;
172  size_t sLen;
173  Asn1Tag tag;
174 
175  //Debug message
176  TRACE_DEBUG("Writing DSA signature...\r\n");
177 
178  //Dump (R, S) integer pair
179  TRACE_DEBUG(" r:\r\n");
180  TRACE_DEBUG_MPI(" ", &signature->r);
181  TRACE_DEBUG(" s:\r\n");
182  TRACE_DEBUG_MPI(" ", &signature->s);
183 
184  //Calculate the length of R
185  rLen = mpiGetByteLength(&signature->r);
186  //Calculate the length of S
187  sLen = mpiGetByteLength(&signature->s);
188 
189  //Make sure the (R, S) integer pair is valid
190  if(rLen == 0 || sLen == 0)
191  return ERROR_INVALID_LENGTH;
192 
193  //R and S are always encoded in the smallest possible number of octets
194  if(mpiGetBitValue(&signature->r, (rLen * 8) - 1))
195  rLen++;
196  if(mpiGetBitValue(&signature->s, (sLen * 8) - 1))
197  sLen++;
198 
199  //The first pass computes the length of the ASN.1 sequence
200  n = 0;
201 
202  //The parameter R is encapsulated within an ASN.1 structure
203  tag.constructed = FALSE;
206  tag.length = rLen;
207  tag.value = NULL;
208 
209  //Compute the length of the corresponding ASN.1 structure
210  error = asn1WriteTag(&tag, FALSE, NULL, NULL);
211  //Any error to report?
212  if(error)
213  return error;
214 
215  //Update the length of the ASN.1 sequence
216  n += tag.totalLength;
217 
218  //The parameter S is encapsulated within an ASN.1 structure
219  tag.constructed = FALSE;
222  tag.length = sLen;
223  tag.value = NULL;
224 
225  //Compute the length of the corresponding ASN.1 structure
226  error = asn1WriteTag(&tag, FALSE, NULL, NULL);
227  //Any error to report?
228  if(error)
229  return error;
230 
231  //Update the length of the ASN.1 sequence
232  n += tag.totalLength;
233 
234  //The second pass encodes the ASN.1 structure
235  k = 0;
236 
237  //The (R, S) integer pair is encapsulated within a sequence
238  tag.constructed = TRUE;
241  tag.length = n;
242  tag.value = NULL;
243 
244  //Write the corresponding ASN.1 tag
245  error = asn1WriteTag(&tag, FALSE, data + k, &n);
246  //Any error to report?
247  if(error)
248  return error;
249 
250  //Advance write pointer
251  k += n;
252 
253  //Encode the parameter R using ASN.1
254  tag.constructed = FALSE;
257  tag.length = rLen;
258  tag.value = NULL;
259 
260  //Write the corresponding ASN.1 tag
261  error = asn1WriteTag(&tag, FALSE, data + k, &n);
262  //Any error to report?
263  if(error)
264  return error;
265 
266  //Advance write pointer
267  k += n;
268 
269  //Convert R to an octet string
270  error = mpiWriteRaw(&signature->r, data + k, rLen);
271  //Any error to report?
272  if(error)
273  return error;
274 
275  //Advance write pointer
276  k += rLen;
277 
278  //Encode the parameter S using ASN.1
279  tag.constructed = FALSE;
282  tag.length = sLen;
283  tag.value = NULL;
284 
285  //Write the corresponding ASN.1 tag
286  error = asn1WriteTag(&tag, FALSE, data + k, &n);
287  //Any error to report?
288  if(error)
289  return error;
290 
291  //Advance write pointer
292  k += n;
293 
294  //Convert S to an octet string
295  error = mpiWriteRaw(&signature->s, data + k, sLen);
296  //Any error to report?
297  if(error)
298  return error;
299 
300  //Advance write pointer
301  k += sLen;
302 
303  //Dump DSA signature
304  TRACE_DEBUG(" signature:\r\n");
305  TRACE_DEBUG_ARRAY(" ", data, k);
306 
307  //Total length of the ASN.1 structure
308  *length = k;
309  //Successful processing
310  return NO_ERROR;
311 }
312 
313 
314 /**
315  * @brief Read an ASN.1 encoded DSA signature
316  * @param[in] data Pointer to the ASN.1 structure to decode
317  * @param[in] length Length of the ASN.1 structure
318  * @param[out] signature (R, S) integer pair
319  * @return Error code
320  **/
321 
323 {
324  error_t error;
325  Asn1Tag tag;
326 
327  //Debug message
328  TRACE_DEBUG("Reading DSA signature...\r\n");
329 
330  //Dump DSA signature
331  TRACE_DEBUG(" signature:\r\n");
333 
334  //Start of exception handling block
335  do
336  {
337  //Display ASN.1 structure
338  error = asn1DumpObject(data, length, 0);
339  //Any error to report?
340  if(error)
341  break;
342 
343  //Read the contents of the ASN.1 structure
344  error = asn1ReadSequence(data, length, &tag);
345  //Failed to decode ASN.1 tag?
346  if(error)
347  break;
348 
349  //Malformed DSA signature?
350  if(length != tag.totalLength)
351  {
352  //Report an error
353  error = ERROR_INVALID_SYNTAX;
354  break;
355  }
356 
357  //Point to the first field
358  data = tag.value;
359  length = tag.length;
360 
361  //Read the parameter R
362  error = asn1ReadTag(data, length, &tag);
363  //Failed to decode ASN.1 tag?
364  if(error)
365  break;
366 
367  //Enforce encoding, class and type
369  //Invalid tag?
370  if(error)
371  break;
372 
373  //Make sure R is a positive integer
374  if(tag.length == 0 || (tag.value[0] & 0x80) != 0)
375  {
376  //Report an error
377  error = ERROR_INVALID_SYNTAX;
378  break;
379  }
380 
381  //Convert the octet string to a multiple precision integer
382  error = mpiReadRaw(&signature->r, tag.value, tag.length);
383  //Any error to report?
384  if(error)
385  break;
386 
387  //Point to the next field
388  data += tag.totalLength;
389  length -= tag.totalLength;
390 
391  //Read the parameter S
392  error = asn1ReadTag(data, length, &tag);
393  //Failed to decode ASN.1 tag?
394  if(error)
395  break;
396 
397  //Enforce encoding, class and type
399  //Invalid tag?
400  if(error)
401  break;
402 
403  //Make sure S is a positive integer
404  if(tag.length == 0 || (tag.value[0] & 0x80) != 0)
405  {
406  //Report an error
407  error = ERROR_INVALID_SYNTAX;
408  break;
409  }
410 
411  //Convert the octet string to a multiple precision integer
412  error = mpiReadRaw(&signature->s, tag.value, tag.length);
413  //Any error to report?
414  if(error)
415  break;
416 
417  //Malformed DSA signature?
418  if(length != tag.totalLength)
419  {
420  //Report an error
421  error = ERROR_INVALID_SYNTAX;
422  break;
423  }
424 
425  //Dump (R, S) integer pair
426  TRACE_DEBUG(" r:\r\n");
427  TRACE_DEBUG_MPI(" ", &signature->r);
428  TRACE_DEBUG(" s:\r\n");
429  TRACE_DEBUG_MPI(" ", &signature->s);
430 
431  //End of exception handling block
432  } while(0);
433 
434  //Any error to report?
435  if(error)
436  {
437  //Clean up side effects
439  }
440 
441  //Return status code
442  return 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,
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->p);
474  TRACE_DEBUG(" q:\r\n");
475  TRACE_DEBUG_MPI(" ", &key->q);
476  TRACE_DEBUG(" g:\r\n");
477  TRACE_DEBUG_MPI(" ", &key->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  //Let N be the bit length of q
488  n = mpiGetBitLength(&key->q);
489 
490  //Generated a pseudorandom number
491  MPI_CHECK(mpiRand(&k, n, prngAlgo, prngContext));
492 
493  //Make sure that 0 < k < q
494  if(mpiComp(&k, &key->q) >= 0)
495  mpiShiftRight(&k, 1);
496 
497  //Debug message
498  TRACE_DEBUG(" k:\r\n");
499  TRACE_DEBUG_MPI(" ", &k);
500 
501  //Compute N = MIN(N, outlen)
502  n = MIN(n, digestLen * 8);
503 
504  //Convert the digest to a multiple precision integer
505  MPI_CHECK(mpiReadRaw(&z, digest, (n + 7) / 8));
506 
507  //Keep the leftmost N bits of the hash value
508  if((n % 8) != 0)
509  {
510  MPI_CHECK(mpiShiftRight(&z, 8 - (n % 8)));
511  }
512 
513  //Debug message
514  TRACE_DEBUG(" z:\r\n");
515  TRACE_DEBUG_MPI(" ", &z);
516 
517  //Compute r = (g ^ k mod p) mod q
518  MPI_CHECK(mpiExpMod(&signature->r, &key->g, &k, &key->p));
519  MPI_CHECK(mpiMod(&signature->r, &signature->r, &key->q));
520 
521  //Compute k ^ -1 mod q
522  MPI_CHECK(mpiInvMod(&k, &k, &key->q));
523 
524  //Compute s = k ^ -1 * (z + x * r) mod q
525  MPI_CHECK(mpiMul(&signature->s, &key->x, &signature->r));
526  MPI_CHECK(mpiAdd(&signature->s, &signature->s, &z));
527  MPI_CHECK(mpiMod(&signature->s, &signature->s, &key->q));
528  MPI_CHECK(mpiMulMod(&signature->s, &signature->s, &k, &key->q));
529 
530  //Dump DSA signature
531  TRACE_DEBUG(" r:\r\n");
532  TRACE_DEBUG_MPI(" ", &signature->r);
533  TRACE_DEBUG(" s:\r\n");
534  TRACE_DEBUG_MPI(" ", &signature->s);
535 
536 end:
537  //Release multiple precision integers
538  mpiFree(&k);
539  mpiFree(&z);
540 
541  //Clean up side effects if necessary
542  if(error)
543  {
544  //Release (R, S) integer pair
545  mpiFree(&signature->r);
546  mpiFree(&signature->r);
547  }
548 
549  //Return status code
550  return error;
551 }
552 
553 
554 /**
555  * @brief DSA signature verification
556  * @param[in] key Signer's DSA public key
557  * @param[in] digest Digest of the message whose signature is to be verified
558  * @param[in] digestLen Length in octets of the digest
559  * @param[in] signature (R, S) integer pair
560  * @return Error code
561  **/
562 
564  const uint8_t *digest, size_t digestLen, const DsaSignature *signature)
565 {
566  error_t error;
567  uint_t n;
568  Mpi w;
569  Mpi z;
570  Mpi u1;
571  Mpi u2;
572  Mpi v;
573 
574  //Check parameters
575  if(key == NULL || digest == NULL || signature == NULL)
577 
578  //Debug message
579  TRACE_DEBUG("DSA signature verification...\r\n");
580  TRACE_DEBUG(" p:\r\n");
581  TRACE_DEBUG_MPI(" ", &key->p);
582  TRACE_DEBUG(" q:\r\n");
583  TRACE_DEBUG_MPI(" ", &key->q);
584  TRACE_DEBUG(" g:\r\n");
585  TRACE_DEBUG_MPI(" ", &key->g);
586  TRACE_DEBUG(" y:\r\n");
587  TRACE_DEBUG_MPI(" ", &key->y);
588  TRACE_DEBUG(" digest:\r\n");
589  TRACE_DEBUG_ARRAY(" ", digest, digestLen);
590  TRACE_DEBUG(" r:\r\n");
591  TRACE_DEBUG_MPI(" ", &signature->r);
592  TRACE_DEBUG(" s:\r\n");
593  TRACE_DEBUG_MPI(" ", &signature->s);
594 
595  //The verifier shall check that 0 < r < q
596  if(mpiCompInt(&signature->r, 0) <= 0 || mpiComp(&signature->r, &key->q) >= 0)
597  {
598  //If the condition is violated, the signature shall be rejected as invalid
600  }
601 
602  //The verifier shall check that 0 < s < q
603  if(mpiCompInt(&signature->s, 0) <= 0 || mpiComp(&signature->s, &key->q) >= 0)
604  {
605  //If the condition is violated, the signature shall be rejected as invalid
607  }
608 
609  //Initialize multiple precision integers
610  mpiInit(&w);
611  mpiInit(&z);
612  mpiInit(&u1);
613  mpiInit(&u2);
614  mpiInit(&v);
615 
616  //Let N be the bit length of q
617  n = mpiGetBitLength(&key->q);
618  //Compute N = MIN(N, outlen)
619  n = MIN(n, digestLen * 8);
620 
621  //Convert the digest to a multiple precision integer
622  MPI_CHECK(mpiReadRaw(&z, digest, (n + 7) / 8));
623 
624  //Keep the leftmost N bits of the hash value
625  if((n % 8) != 0)
626  {
627  MPI_CHECK(mpiShiftRight(&z, 8 - (n % 8)));
628  }
629 
630  //Compute w = s ^ -1 mod q
631  MPI_CHECK(mpiInvMod(&w, &signature->s, &key->q));
632  //Compute u1 = z * w mod q
633  MPI_CHECK(mpiMulMod(&u1, &z, &w, &key->q));
634  //Compute u2 = r * w mod q
635  MPI_CHECK(mpiMulMod(&u2, &signature->r, &w, &key->q));
636 
637  //Compute v = ((g ^ u1) * (y ^ u2) mod p) mod q
638  MPI_CHECK(mpiExpMod(&v, &key->g, &u1, &key->p));
639  MPI_CHECK(mpiExpMod(&w, &key->y, &u2, &key->p));
640  MPI_CHECK(mpiMulMod(&v, &v, &w, &key->p));
641  MPI_CHECK(mpiMod(&v, &v, &key->q));
642 
643  //Debug message
644  TRACE_DEBUG(" v:\r\n");
645  TRACE_DEBUG_MPI(" ", &v);
646 
647  //If v = r, then the signature is verified. If v does not equal r,
648  //then the message or the signature may have been modified
649  if(!mpiComp(&v, &signature->r))
650  error = NO_ERROR;
651  else
652  error = ERROR_INVALID_SIGNATURE;
653 
654 end:
655  //Release multiple precision integers
656  mpiFree(&w);
657  mpiFree(&z);
658  mpiFree(&u1);
659  mpiFree(&u2);
660  mpiFree(&v);
661 
662  //Return status code
663  return error;
664 }
665 
666 #endif
uint8_t length
Definition: dtls_misc.h:149
const uint8_t DSA_WITH_SHA224_OID[9]
Definition: dsa.c:55
Arbitrary precision integer.
Definition: mpi.h:69
Common interface for pseudo-random number generators.
Definition: crypto.h:1168
void dsaFreePrivateKey(DsaPrivateKey *key)
Release a DSA private key.
Definition: dsa.c:122
#define TRUE
Definition: os_port.h:50
error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular multiplication.
Definition: mpi.c:1436
uint8_t signature
Definition: tls.h:1370
#define mpiWriteRaw(a, data, length)
Definition: crypto_legacy.h:36
error_t asn1DumpObject(const uint8_t *data, size_t length, uint_t level)
Display an ASN.1 data object.
Definition: asn1.c:690
error_t mpiShiftRight(Mpi *r, uint_t n)
Right shift operation.
Definition: mpi.c:1073
error_t asn1ReadTag(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 tag from the input stream.
Definition: asn1.c:52
error_t mpiRand(Mpi *r, uint_t length, const PrngAlgo *prngAlgo, void *prngContext)
Generate a random value.
Definition: mpi.c:468
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:48
uint16_t w[3]
Definition: ethernet.h:166
#define mpiReadRaw(r, data, length)
Definition: crypto_legacy.h:35
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:1325
size_t totalLength
Definition: asn1.h:104
size_t length
Definition: asn1.h:102
#define FALSE
Definition: os_port.h:46
DSA public key.
Definition: dsa.h:60
Invalid parameter.
Definition: error.h:47
error_t
Error codes.
Definition: error.h:42
void dsaInitSignature(DsaSignature *signature)
Initialize a DSA signature.
Definition: dsa.c:137
const uint8_t DSA_WITH_SHA3_256_OID[9]
Definition: dsa.c:65
#define MPI_CHECK(f)
Definition: mpi.h:42
error_t mpiAdd(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision addition.
Definition: mpi.c:696
const uint8_t DSA_WITH_SHA384_OID[9]
Definition: dsa.c:59
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:48
ASN.1 tag.
Definition: asn1.h:97
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
error_t mpiInvMod(Mpi *r, const Mpi *a, const Mpi *p)
Modular inverse.
void dsaInitPrivateKey(DsaPrivateKey *key)
Initialize a DSA private key.
Definition: dsa.c:107
MPI (Multiple Precision Integer Arithmetic)
const uint8_t DSA_WITH_SHA512_OID[9]
Definition: dsa.c:61
General definitions for cryptographic algorithms.
error_t asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *data, size_t *written)
Write an ASN.1 tag.
Definition: asn1.c:377
DSA (Digital Signature Algorithm)
DSA private key.
Definition: dsa.h:73
uint_t objClass
Definition: asn1.h:100
#define MIN(a, b)
Definition: os_port.h:62
Mpi p
Prime modulus.
Definition: dsa.h:75
Mpi g
Group generator.
Definition: dsa.h:77
error_t dsaWriteSignature(const DsaSignature *signature, uint8_t *data, size_t *length)
Encode DSA signature using ASN.1.
Definition: dsa.c:166
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:195
const uint8_t DSA_WITH_SHA3_384_OID[9]
Definition: dsa.c:67
uint8_t z
Definition: dns_common.h:175
#define TRACE_DEBUG(...)
Definition: debug.h:106
error_t dsaVerifySignature(const DsaPublicKey *key, const uint8_t *digest, size_t digestLen, const DsaSignature *signature)
DSA signature verification.
Definition: dsa.c:563
const uint8_t DSA_WITH_SHA3_224_OID[9]
Definition: dsa.c:63
Mpi q
Group order.
Definition: dsa.h:63
Mpi p
Prime modulus.
Definition: dsa.h:62
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:107
uint8_t n
error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision multiplication.
void dsaFreeSignature(DsaSignature *signature)
Release a DSA signature.
Definition: dsa.c:150
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 dsaReadSignature(const uint8_t *data, size_t length, DsaSignature *signature)
Read an ASN.1 encoded DSA signature.
Definition: dsa.c:322
Mpi x
Secret exponent.
Definition: dsa.h:78
error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation.
bool_t constructed
Definition: asn1.h:99
Mpi y
Public key value.
Definition: dsa.h:65
Mpi q
Group order.
Definition: dsa.h:76
DSA signature.
Definition: dsa.h:86
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:295
unsigned int uint_t
Definition: compiler_port.h:45
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:109
uint8_t data[]
Definition: dtls_misc.h:176
uint_t mpiGetBitValue(const Mpi *a, uint_t index)
Get the bit value at the specified index.
Definition: mpi.c:270
error_t asn1ReadSequence(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 sequence from the input stream.
Definition: asn1.c:163
int_t mpiCompInt(const Mpi *a, int_t b)
Compare a multiple precision integer with an integer.
Definition: mpi.c:339
void dsaFreePublicKey(DsaPublicKey *key)
Release a DSA public key.
Definition: dsa.c:92
Mpi g
Group generator.
Definition: dsa.h:64
const uint8_t * value
Definition: asn1.h:103
void dsaInitPublicKey(DsaPublicKey *key)
Initialize a DSA public key.
Definition: dsa.c:77
error_t asn1CheckTag(const Asn1Tag *tag, bool_t constructed, uint_t objClass, uint_t objType)
Enforce the type of a specified tag.
Definition: asn1.c:637
Success.
Definition: error.h:44
Debugging facilities.
uint_t objType
Definition: asn1.h:101
ASN.1 (Abstract Syntax Notation One)
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:156
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:62