Implement deterministic DSA as specified by rfc-6979.
[libgcrypt.git] / tests / dsa-rfc6979.c
1 /* dsa-rfc6979.c - Test for Deterministic DSA
2  * Copyright (C) 2008 Free Software Foundation, Inc.
3  * Copyright (C) 2013 g10 Code GmbH
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdarg.h>
28
29 #ifdef _GCRYPT_IN_LIBGCRYPT
30 # include "../src/gcrypt-int.h"
31 #else
32 # include <gcrypt.h>
33 #endif
34
35
36 #define my_isascii(c) (!((c) & 0x80))
37 #define digitp(p)   (*(p) >= '0' && *(p) <= '9')
38 #define hexdigitp(a) (digitp (a)                     \
39                       || (*(a) >= 'A' && *(a) <= 'F')  \
40                       || (*(a) >= 'a' && *(a) <= 'f'))
41 #define xtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): \
42                      *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
43 #define xtoi_2(p)   ((xtoi_1(p) * 16) + xtoi_1((p)+1))
44 #define DIM(v)               (sizeof(v)/sizeof((v)[0]))
45 #define DIMof(type,member)   DIM(((type *)0)->member)
46
47 static int verbose;
48 static int error_count;
49
50 static void
51 info (const char *format, ...)
52 {
53   va_list arg_ptr;
54
55   va_start (arg_ptr, format);
56   vfprintf (stderr, format, arg_ptr);
57   va_end (arg_ptr);
58 }
59
60 static void
61 fail (const char *format, ...)
62 {
63   va_list arg_ptr;
64
65   va_start (arg_ptr, format);
66   vfprintf (stderr, format, arg_ptr);
67   va_end (arg_ptr);
68   error_count++;
69 }
70
71 static void
72 die (const char *format, ...)
73 {
74   va_list arg_ptr;
75
76   va_start (arg_ptr, format);
77   vfprintf (stderr, format, arg_ptr);
78   va_end (arg_ptr);
79   exit (1);
80 }
81
82 static void
83 show_sexp (const char *prefix, gcry_sexp_t a)
84 {
85   char *buf;
86   size_t size;
87
88   if (prefix)
89     fputs (prefix, stderr);
90   size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
91   buf = gcry_xmalloc (size);
92
93   gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
94   fprintf (stderr, "%.*s", (int)size, buf);
95   gcry_free (buf);
96 }
97
98
99 /* Convert STRING consisting of hex characters into its binary
100    representation and return it as an allocated buffer. The valid
101    length of the buffer is returned at R_LENGTH.  The string is
102    delimited by end of string.  The function returns NULL on
103    error.  */
104 static void *
105 data_from_hex (const char *string, size_t *r_length)
106 {
107   const char *s;
108   unsigned char *buffer;
109   size_t length;
110
111   buffer = gcry_xmalloc (strlen(string)/2+1);
112   length = 0;
113   for (s=string; *s; s +=2 )
114     {
115       if (!hexdigitp (s) || !hexdigitp (s+1))
116         die ("error parsing hex string `%s'\n", string);
117       ((unsigned char*)buffer)[length++] = xtoi_2 (s);
118     }
119   *r_length = length;
120   return buffer;
121 }
122
123
124 static void
125 extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected)
126 {
127   gcry_sexp_t l1;
128   const void *a;
129   size_t alen;
130   void *b;
131   size_t blen;
132
133   l1 = gcry_sexp_find_token (sexp, name, 0);
134   a = gcry_sexp_nth_data (l1, 1, &alen);
135   b = data_from_hex (expected, &blen);
136   if (!a)
137     fail ("parameter \"%s\" missing in key\n", name);
138   else if ( alen != blen || memcmp (a, b, alen) )
139     {
140       fail ("parameter \"%s\" does not match expected value\n", name);
141       if (verbose)
142         {
143           info ("expected: %s\n", expected);
144           show_sexp ("sexp: ", sexp);
145         }
146     }
147   gcry_free (b);
148   gcry_sexp_release (l1);
149 }
150
151
152 /* These test vectors are from RFC 6979.  */
153 static void
154 check_dsa_rfc6979 (void)
155 {
156   static struct {
157     const char *name;
158     const char *key;
159   } keys[] = {
160     {
161       "DSA, 1024 bits",
162       "(private-key"
163       " (DSA"
164       " (p #86F5CA03DCFEB225063FF830A0C769B9DD9D6153AD91D7CE27F787C43278B447"
165       "     E6533B86B18BED6E8A48B784A14C252C5BE0DBF60B86D6385BD2F12FB763ED88"
166       "     73ABFD3F5BA2E0A8C0A59082EAC056935E529DAF7C610467899C77ADEDFC846C"
167       "     881870B7B19B2B58F9BE0521A17002E3BDD6B86685EE90B3D9A1B02B782B1779#)"
168       " (q #996F967F6C8E388D9E28D01E205FBA957A5698B1#)"
169       " (g #07B0F92546150B62514BB771E2A0C0CE387F03BDA6C56B505209FF25FD3C133D"
170       "     89BBCD97E904E09114D9A7DEFDEADFC9078EA544D2E401AEECC40BB9FBBF78FD"
171       "     87995A10A1C27CB7789B594BA7EFB5C4326A9FE59A070E136DB77175464ADCA4"
172       "     17BE5DCE2F40D10A46A3A3943F26AB7FD9C0398FF8C76EE0A56826A8A88F1DBD#)"
173       " (x #411602CB19A6CCC34494D79D98EF1E7ED5AF25F7#)"
174       " (y #5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F653"
175       "     92195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D"
176       "     4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E6"
177       "     82F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B#)"
178       " ))"
179     },
180     {
181       "DSA, 2048 bits",
182       "(private-key"
183       " (DSA"
184       " (p #9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48"
185       "     C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44F"
186       "     FE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5"
187       "     B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE2"
188       "     35567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41"
189       "     F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE"
190       "     92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA15"
191       "     3E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B#)"
192       " (q #F2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F#)"
193       " (g #5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613"
194       "     D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C4"
195       "     6A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472"
196       "     085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5"
197       "     AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA"
198       "     3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71"
199       "     BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0"
200       "     DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7#)"
201       " (x #69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC#)"
202       " (y #667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD94"
203       "     9F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA61"
204       "     1728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADE"
205       "     CB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB"
206       "     5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254"
207       "     687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D1"
208       "     23AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA"
209       "     74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF#)"
210       " ))"
211     },
212     { NULL }
213   };
214
215   static struct {
216     const char *keyname;
217     const char *name;
218     const char *hashname;
219     const char *message;
220     const char *k, *r, *s;
221   } tests[] = {
222     {
223       "DSA, 1024 bits",
224       "With SHA-1, message = \"sample\"",
225       "sha1", "sample",
226       "7BDB6B0FF756E1BB5D53583EF979082F9AD5BD5B",
227       "2E1A0C2562B2912CAAF89186FB0F42001585DA55",
228       "29EFB6B0AFF2D7A68EB70CA313022253B9A88DF5"
229     },
230     {
231       "DSA, 1024 bits",
232       "With SHA-224, message = \"sample\"",
233       "sha224", "sample",
234       "562097C06782D60C3037BA7BE104774344687649",
235       "4BC3B686AEA70145856814A6F1BB53346F02101E",
236       "410697B92295D994D21EDD2F4ADA85566F6F94C1"
237     },
238     {
239       "DSA, 1024 bits",
240       "With SHA-256, message = \"sample\"",
241       "sha256", "sample",
242       "519BA0546D0C39202A7D34D7DFA5E760B318BCFB",
243       "81F2F5850BE5BC123C43F71A3033E9384611C545",
244       "4CDD914B65EB6C66A8AAAD27299BEE6B035F5E89"
245     },
246     {
247       "DSA, 1024 bits",
248       "With SHA-384, message = \"sample\"",
249       "sha384", "sample",
250       "95897CD7BBB944AA932DBC579C1C09EB6FCFC595",
251       "07F2108557EE0E3921BC1774F1CA9B410B4CE65A",
252       "54DF70456C86FAC10FAB47C1949AB83F2C6F7595"
253     },
254     {
255       "DSA, 1024 bits",
256       "With SHA-512, message = \"sample\"",
257       "sha512", "sample",
258       "09ECE7CA27D0F5A4DD4E556C9DF1D21D28104F8B",
259       "16C3491F9B8C3FBBDD5E7A7B667057F0D8EE8E1B",
260       "02C36A127A7B89EDBB72E4FFBC71DABC7D4FC69C"
261     },
262     {
263       "DSA, 1024 bits",
264       "With SHA-1, message = \"test\"",
265       "sha1", "test",
266       "5C842DF4F9E344EE09F056838B42C7A17F4A6433",
267       "42AB2052FD43E123F0607F115052A67DCD9C5C77",
268       "183916B0230D45B9931491D4C6B0BD2FB4AAF088"
269     },
270     {
271       "DSA, 1024 bits",
272       "With SHA-224, message = \"test\"",
273       "sha224", "test",
274       "4598B8EFC1A53BC8AECD58D1ABBB0C0C71E67297",
275       "6868E9964E36C1689F6037F91F28D5F2C30610F2",
276       "49CEC3ACDC83018C5BD2674ECAAD35B8CD22940F"
277     },
278     {
279       "DSA, 1024 bits",
280       "With SHA-256, message = \"test\"",
281       "sha256", "test",
282       "5A67592E8128E03A417B0484410FB72C0B630E1A",
283       "22518C127299B0F6FDC9872B282B9E70D0790812",
284       "6837EC18F150D55DE95B5E29BE7AF5D01E4FE160"
285     },
286     {
287       "DSA, 1024 bits",
288       "With SHA-384, message = \"test\"",
289       "sha384", "test",
290       "220156B761F6CA5E6C9F1B9CF9C24BE25F98CD89",
291       "854CF929B58D73C3CBFDC421E8D5430CD6DB5E66",
292       "91D0E0F53E22F898D158380676A871A157CDA622"
293     },
294     {
295       "DSA, 1024 bits",
296       "With SHA-512, message = \"test\"",
297       "sha512", "test",
298       "65D2C2EEB175E370F28C75BFCDC028D22C7DBE9C",
299       "8EA47E475BA8AC6F2D821DA3BD212D11A3DEB9A0",
300       "7C670C7AD72B6C050C109E1790008097125433E8"
301     },
302     {
303       "DSA, 2048 bits",
304       "With SHA-1, message = \"sample\"",
305       "sha1", "sample",
306       "888FA6F7738A41BDC9846466ABDB8174C0338250AE50CE955CA16230F9CBD53E",
307       "3A1B2DBD7489D6ED7E608FD036C83AF396E290DBD602408E8677DAABD6E7445A",
308       "D26FCBA19FA3E3058FFC02CA1596CDBB6E0D20CB37B06054F7E36DED0CDBBCCF"
309     },
310     {
311       "DSA, 2048 bits",
312       "With SHA-224, message = \"sample\"",
313       "sha224", "sample",
314       "BC372967702082E1AA4FCE892209F71AE4AD25A6DFD869334E6F153BD0C4D806",
315       "DC9F4DEADA8D8FF588E98FED0AB690FFCE858DC8C79376450EB6B76C24537E2C",
316       "A65A9C3BC7BABE286B195D5DA68616DA8D47FA0097F36DD19F517327DC848CEC"
317     },
318     {
319       "DSA, 2048 bits",
320       "With SHA-256, message = \"sample\"",
321       "sha256", "sample",
322       "8926A27C40484216F052F4427CFD5647338B7B3939BC6573AF4333569D597C52",
323       "EACE8BDBBE353C432A795D9EC556C6D021F7A03F42C36E9BC87E4AC7932CC809",
324       "7081E175455F9247B812B74583E9E94F9EA79BD640DC962533B0680793A38D53"
325     },
326     {
327       "DSA, 2048 bits",
328       "With SHA-384, message = \"sample\"",
329       "sha384", "sample",
330       "C345D5AB3DA0A5BCB7EC8F8FB7A7E96069E03B206371EF7D83E39068EC564920",
331       "B2DA945E91858834FD9BF616EBAC151EDBC4B45D27D0DD4A7F6A22739F45C00B",
332       "19048B63D9FD6BCA1D9BAE3664E1BCB97F7276C306130969F63F38FA8319021B"
333     },
334     {
335       "DSA, 2048 bits",
336       "With SHA-512, message = \"sample\"",
337       "sha512", "sample",
338       "5A12994431785485B3F5F067221517791B85A597B7A9436995C89ED0374668FC",
339       "2016ED092DC5FB669B8EFB3D1F31A91EECB199879BE0CF78F02BA062CB4C942E",
340       "D0C76F84B5F091E141572A639A4FB8C230807EEA7D55C8A154A224400AFF2351"
341     },
342     {
343       "DSA, 2048 bits",
344       "With SHA-1, message = \"test\"",
345       "sha1", "test",
346       "6EEA486F9D41A037B2C640BC5645694FF8FF4B98D066A25F76BE641CCB24BA4F",
347       "C18270A93CFC6063F57A4DFA86024F700D980E4CF4E2CB65A504397273D98EA0",
348       "414F22E5F31A8B6D33295C7539C1C1BA3A6160D7D68D50AC0D3A5BEAC2884FAA"
349     },
350     {
351       "DSA, 2048 bits",
352       "With SHA-224, message = \"test\"",
353       "sha224", "test",
354       "06BD4C05ED74719106223BE33F2D95DA6B3B541DAD7BFBD7AC508213B6DA6670",
355       "272ABA31572F6CC55E30BF616B7A265312018DD325BE031BE0CC82AA17870EA3",
356       "E9CC286A52CCE201586722D36D1E917EB96A4EBDB47932F9576AC645B3A60806"
357     },
358     {
359       "DSA, 2048 bits",
360       "With SHA-256, message = \"test\"",
361       "sha256", "test",
362       "1D6CE6DDA1C5D37307839CD03AB0A5CBB18E60D800937D67DFB4479AAC8DEAD7",
363       "8190012A1969F9957D56FCCAAD223186F423398D58EF5B3CEFD5A4146A4476F0",
364       "7452A53F7075D417B4B013B278D1BB8BBD21863F5E7B1CEE679CF2188E1AB19E"
365     },
366     {
367       "DSA, 2048 bits",
368       "With SHA-384, message = \"test\"",
369       "sha384", "test",
370       "206E61F73DBE1B2DC8BE736B22B079E9DACD974DB00EEBBC5B64CAD39CF9F91C",
371       "239E66DDBE8F8C230A3D071D601B6FFBDFB5901F94D444C6AF56F732BEB954BE",
372       "6BD737513D5E72FE85D1C750E0F73921FE299B945AAD1C802F15C26A43D34961"
373     },
374     {
375       "DSA, 2048 bits",
376       "With SHA-512, message = \"test\"",
377       "sha512", "test",
378       "AFF1651E4CD6036D57AA8B2A05CCF1A9D5A40166340ECBBDC55BE10B568AA0AA",
379       "89EC4BB1400ECCFF8E7D9AA515CD1DE7803F2DAFF09693EE7FD1353E90A68307",
380       "C9F0BDABCC0D880BB137A994CC7F3980CE91CC10FAF529FC46565B15CEA854E1"
381     },
382     { NULL }
383   };
384
385   gpg_error_t err;
386   int tno, i, hashalgo;
387   gcry_sexp_t seckey, data, sig;
388   unsigned char digest[64];
389   int digestlen;
390
391   for (tno = 0; tests[tno].keyname; tno++)
392     {
393       if (verbose)
394         info ("Test %d: %s. %s.\n", tno, tests[tno].keyname, tests[tno].name);
395
396       {
397         for (i=0; keys[i].name; i++)
398           if (!strcmp (tests[tno].keyname, keys[i].name))
399             break;
400         if (!keys[i].name)
401           die ("Key '%s' used by test '%s' not found\n",
402                tests[tno].keyname, tests[tno].name);
403
404         err = gcry_sexp_new (&seckey, keys[i].key, 0, 1);
405         if (err)
406           die ("reading key failed: %s\n", gpg_strerror (err));
407       }
408
409       hashalgo = gcry_md_map_name (tests[tno].hashname);
410       if (!hashalgo)
411         die ("hash with name '%s' is not supported\n", tests[tno].hashname);
412
413       digestlen = gcry_md_get_algo_dlen (hashalgo);
414       if (digestlen > sizeof digest)
415         die ("internal error: digest does not fit into our buffer\n");
416
417       gcry_md_hash_buffer (hashalgo, digest,
418                            tests[tno].message, strlen (tests[tno].message));
419
420       err = gcry_sexp_build (&data, NULL,
421                              "(data "
422                              " (flags rfc6979)"
423                              " (hash %s %b))",
424                              tests[tno].hashname, digestlen, digest);
425       if (err)
426         die ("building data sexp failed: %s\n", gpg_strerror (err));
427
428       err = gcry_pk_sign (&sig, data, seckey);
429       if (err)
430         fail ("signing failed: %s\n", gpg_strerror (err));
431
432       extract_cmp_data (sig, "r", tests[tno].r);
433       extract_cmp_data (sig, "s", tests[tno].s);
434
435       err = gcry_pk_verify (sig, data, seckey);
436       if (err)
437         fail ("verification failed: %s\n", gpg_strerror (err));
438
439
440       gcry_sexp_release (sig);
441       gcry_sexp_release (data);
442       gcry_sexp_release (seckey);
443     }
444 }
445
446
447
448 int
449 main (int argc, char **argv)
450 {
451   int debug = 0;
452
453   if (argc > 1 && !strcmp (argv[1], "--verbose"))
454     verbose = 1;
455   else if (argc > 1 && !strcmp (argv[1], "--debug"))
456     {
457       verbose = 2;
458       debug = 1;
459     }
460
461   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
462   /* Check that we test exactly our version - including the patchlevel.  */
463   if (strcmp (GCRYPT_VERSION, gcry_check_version (NULL)))
464     die ("version mismatch; pgm=%s, library=%s\n",
465          GCRYPT_VERSION,gcry_check_version (NULL));
466   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
467   if (debug)
468     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
469   /* No valuable keys are create, so we can speed up our RNG. */
470   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
471
472   check_dsa_rfc6979 ();
473
474   return error_count ? 1 : 0;
475 }