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