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