Finished RSA X9.31 key generation.
[libgcrypt.git] / cipher / dsa.c
1 /* dsa.c - DSA signature algorithm
2  * Copyright (C) 1998, 2000, 2001, 2002, 2003,
3  *               2006, 2008  Free Software Foundation, Inc.
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, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "g10lib.h"
28 #include "mpi.h"
29 #include "cipher.h"
30
31 typedef struct
32 {
33   gcry_mpi_t p;     /* prime */
34   gcry_mpi_t q;     /* group order */
35   gcry_mpi_t g;     /* group generator */
36   gcry_mpi_t y;     /* g^x mod p */
37 } DSA_public_key;
38
39
40 typedef struct
41 {
42   gcry_mpi_t p;     /* prime */
43   gcry_mpi_t q;     /* group order */
44   gcry_mpi_t g;     /* group generator */
45   gcry_mpi_t y;     /* g^x mod p */
46   gcry_mpi_t x;     /* secret exponent */
47 } DSA_secret_key;
48
49
50 /* A sample 1024 bit DSA key used for the selftests.  */
51 static const char sample_secret_key[] =
52 "(private-key"
53 " (dsa"
54 "  (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
55 "      96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
56 "      CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
57 "      44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)"
58 "  (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)"
59 "  (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
60 "      AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
61 "      B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
62 "      3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)"
63 "  (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
64 "      A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
65 "      6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
66 "      42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)"
67 "  (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))";
68 /* A sample 1024 bit DSA key used for the selftests (public only).  */
69 static const char sample_public_key[] = 
70 "(public-key"
71 " (dsa"
72 "  (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
73 "      96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
74 "      CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
75 "      44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)"
76 "  (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)"
77 "  (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
78 "      AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
79 "      B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
80 "      3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)"
81 "  (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
82 "      A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
83 "      6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
84 "      42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))";
85
86
87
88 \f
89 static gcry_mpi_t gen_k (gcry_mpi_t q);
90 static int test_keys (DSA_secret_key *sk, unsigned int qbits);
91 static int check_secret_key (DSA_secret_key *sk);
92 static gpg_err_code_t generate (DSA_secret_key *sk,
93                                 unsigned int nbits,
94                                 unsigned int qbits,
95                                 gcry_mpi_t **ret_factors);
96 static void sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
97                   DSA_secret_key *skey);
98 static int verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
99                    DSA_public_key *pkey);
100
101 static void (*progress_cb) (void *,const char *, int, int, int );
102 static void *progress_cb_data;
103
104
105 void
106 _gcry_register_pk_dsa_progress (void (*cb) (void *, const char *,
107                                             int, int, int),
108                                 void *cb_data)
109 {
110   progress_cb = cb;
111   progress_cb_data = cb_data;
112 }
113
114
115 static void
116 progress (int c)
117 {
118   if (progress_cb)
119     progress_cb (progress_cb_data, "pk_dsa", c, 0, 0);
120 }
121
122
123 /*
124  * Generate a random secret exponent k less than q.
125  */
126 static gcry_mpi_t
127 gen_k( gcry_mpi_t q )
128 {
129   gcry_mpi_t k = mpi_alloc_secure( mpi_get_nlimbs(q) );
130   unsigned int nbits = mpi_get_nbits(q);
131   unsigned int nbytes = (nbits+7)/8;
132   char *rndbuf = NULL;
133
134   if ( DBG_CIPHER )
135     log_debug("choosing a random k ");
136   for (;;) 
137     {
138       if( DBG_CIPHER )
139         progress('.');
140
141       if ( !rndbuf || nbits < 32 ) 
142         {
143           gcry_free(rndbuf);
144           rndbuf = gcry_random_bytes_secure( (nbits+7)/8, GCRY_STRONG_RANDOM );
145         }
146       else
147         { /* Change only some of the higher bits.  We could improve
148              this by directly requesting more memory at the first call
149              to get_random_bytes() and use this the here maybe it is
150              easier to do this directly in random.c. */
151           char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
152           memcpy( rndbuf,pp, 4 );
153           gcry_free(pp);
154         }
155       _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
156       if ( mpi_test_bit( k, nbits-1 ) )
157         mpi_set_highbit( k, nbits-1 );
158       else
159         {
160           mpi_set_highbit( k, nbits-1 );
161           mpi_clear_bit( k, nbits-1 );
162         }
163
164       if( !(mpi_cmp( k, q ) < 0) ) /* check: k < q */
165         {       
166           if( DBG_CIPHER )
167             progress('+');
168           continue; /* no  */
169         }
170       if( !(mpi_cmp_ui( k, 0 ) > 0) )  /* check: k > 0 */
171         {
172           if( DBG_CIPHER )
173             progress('-');
174           continue; /* no */
175         }
176       break;    /* okay */
177     }
178   gcry_free(rndbuf);
179   if( DBG_CIPHER )
180     progress('\n');
181   
182   return k;
183 }
184
185
186 /* Check that a freshly generated key actually works.  Returns 0 on success. */
187 static int
188 test_keys (DSA_secret_key *sk, unsigned int qbits)
189 {
190   int result = -1;  /* Default to failure.  */
191   DSA_public_key pk;
192   gcry_mpi_t data  = gcry_mpi_new (qbits);
193   gcry_mpi_t sig_a = gcry_mpi_new (qbits);
194   gcry_mpi_t sig_b = gcry_mpi_new (qbits);
195
196   /* Put the relevant parameters into a public key structure.  */
197   pk.p = sk->p;
198   pk.q = sk->q;
199   pk.g = sk->g;
200   pk.y = sk->y;
201
202   /* Create a random plaintext.  */
203   gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM);
204
205   /* Sign DATA using the secret key.  */
206   sign (sig_a, sig_b, data, sk);
207
208   /* Verify the signature using the public key.  */
209   if ( !verify (sig_a, sig_b, data, &pk) )
210     goto leave; /* Signature does not match.  */
211
212   /* Modify the data and check that the signing fails.  */
213   gcry_mpi_add_ui (data, data, 1);
214   if ( verify (sig_a, sig_b, data, &pk) )
215     goto leave; /* Signature matches but should not.  */
216
217   result = 0; /* The test succeeded.  */
218
219  leave:
220   gcry_mpi_release (sig_b);
221   gcry_mpi_release (sig_a);
222   gcry_mpi_release (data);
223   return result;
224 }
225
226
227
228 /*
229    Generate a DSA key pair with a key of size NBITS.
230    Returns: 2 structures filled with all needed values
231             and an array with the n-1 factors of (p-1)
232  */
233 static gpg_err_code_t
234 generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
235           gcry_mpi_t **ret_factors )
236 {
237   gcry_mpi_t p;    /* the prime */
238   gcry_mpi_t q;    /* the 160 bit prime factor */
239   gcry_mpi_t g;    /* the generator */
240   gcry_mpi_t y;    /* g^x mod p */
241   gcry_mpi_t x;    /* the secret exponent */
242   gcry_mpi_t h, e;  /* helper */
243   unsigned char *rndbuf;
244
245   if (qbits)
246     ; /* Caller supplied qbits.  Use this value.  */
247   else if ( nbits >= 512 && nbits <= 1024 )
248     qbits = 160;
249   else if ( nbits == 2048 )
250     qbits = 224;
251   else if ( nbits == 3072 )
252     qbits = 256;
253   else if ( nbits == 7680 )
254     qbits = 384;
255   else if ( nbits == 15360 )
256     qbits = 512;
257   else
258     return GPG_ERR_INV_VALUE;
259
260   if (qbits < 160 || qbits > 512 || (qbits%8) )
261     return GPG_ERR_INV_VALUE;
262   if (nbits < 2*qbits || nbits > 15360)
263     return GPG_ERR_INV_VALUE;
264
265   if (nbits < 1024 && fips_mode ())
266     return GPG_ERR_INV_VALUE;
267
268   p = _gcry_generate_elg_prime( 1, nbits, qbits, NULL, ret_factors );
269   /* get q out of factors */
270   q = mpi_copy((*ret_factors)[0]);
271   if( mpi_get_nbits(q) != qbits )
272     BUG();
273
274   /* Find a generator g (h and e are helpers).
275      e = (p-1)/q */
276   e = mpi_alloc( mpi_get_nlimbs(p) );
277   mpi_sub_ui( e, p, 1 );
278   mpi_fdiv_q( e, e, q );
279   g = mpi_alloc( mpi_get_nlimbs(p) );
280   h = mpi_alloc_set_ui( 1 ); /* we start with 2 */
281   do
282     {
283       mpi_add_ui( h, h, 1 );
284       /* g = h^e mod p */
285       gcry_mpi_powm( g, h, e, p );
286     } 
287   while( !mpi_cmp_ui( g, 1 ) );  /* continue until g != 1 */
288
289   /* Select a random number which has these properties:
290    *     0 < x < q-1
291    * This must be a very good random number because this
292    * is the secret part. */
293   if( DBG_CIPHER )
294     log_debug("choosing a random x ");
295   gcry_assert( qbits >= 160 );
296   x = mpi_alloc_secure( mpi_get_nlimbs(q) );
297   mpi_sub_ui( h, q, 1 );  /* put q-1 into h */
298   rndbuf = NULL;
299   do 
300     {
301       if( DBG_CIPHER )
302         progress('.');
303       if( !rndbuf )
304         rndbuf = gcry_random_bytes_secure( (qbits+7)/8,
305                                            GCRY_VERY_STRONG_RANDOM );
306       else 
307         { /* Change only some of the higher bits (= 2 bytes)*/
308           char *r = gcry_random_bytes_secure (2, GCRY_VERY_STRONG_RANDOM);
309           memcpy(rndbuf, r, 2 );
310           gcry_free(r);
311         }
312
313       _gcry_mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
314       mpi_clear_highbit( x, qbits+1 );
315     } 
316   while ( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
317   gcry_free(rndbuf);
318   mpi_free( e );
319   mpi_free( h );
320
321   /* y = g^x mod p */
322   y = mpi_alloc( mpi_get_nlimbs(p) );
323   gcry_mpi_powm( y, g, x, p );
324
325   if( DBG_CIPHER ) 
326     {
327       progress('\n');
328       log_mpidump("dsa  p= ", p );
329       log_mpidump("dsa  q= ", q );
330       log_mpidump("dsa  g= ", g );
331       log_mpidump("dsa  y= ", y );
332       log_mpidump("dsa  x= ", x );
333     }
334
335   /* Copy the stuff to the key structures. */
336   sk->p = p;
337   sk->q = q;
338   sk->g = g;
339   sk->y = y;
340   sk->x = x;
341
342   /* Now we can test our keys (this should never fail!). */
343   if ( test_keys (sk, qbits) )
344     {
345       gcry_mpi_release (sk->p); sk->p = NULL;
346       gcry_mpi_release (sk->q); sk->q = NULL;
347       gcry_mpi_release (sk->g); sk->g = NULL;
348       gcry_mpi_release (sk->y); sk->y = NULL;
349       gcry_mpi_release (sk->x); sk->x = NULL;
350       fips_signal_error ("self-test after key generation failed");
351       return GPG_ERR_SELFTEST_FAILED;
352     }
353   return 0;
354 }
355
356
357
358 /*
359    Test whether the secret key is valid.
360    Returns: if this is a valid key.
361  */
362 static int
363 check_secret_key( DSA_secret_key *sk )
364 {
365   int rc;
366   gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );
367
368   gcry_mpi_powm( y, sk->g, sk->x, sk->p );
369   rc = !mpi_cmp( y, sk->y );
370   mpi_free( y );
371   return rc;
372 }
373
374
375
376 /*
377    Make a DSA signature from HASH and put it into r and s.
378  */
379 static void
380 sign(gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_secret_key *skey )
381 {
382   gcry_mpi_t k;
383   gcry_mpi_t kinv;
384   gcry_mpi_t tmp;
385
386   /* Select a random k with 0 < k < q */
387   k = gen_k( skey->q );
388
389   /* r = (a^k mod p) mod q */
390   gcry_mpi_powm( r, skey->g, k, skey->p );
391   mpi_fdiv_r( r, r, skey->q );
392
393   /* kinv = k^(-1) mod q */
394   kinv = mpi_alloc( mpi_get_nlimbs(k) );
395   mpi_invm(kinv, k, skey->q );
396
397   /* s = (kinv * ( hash + x * r)) mod q */
398   tmp = mpi_alloc( mpi_get_nlimbs(skey->p) );
399   mpi_mul( tmp, skey->x, r );
400   mpi_add( tmp, tmp, hash );
401   mpi_mulm( s , kinv, tmp, skey->q );
402
403   mpi_free(k);
404   mpi_free(kinv);
405   mpi_free(tmp);
406 }
407
408
409 /*
410    Returns true if the signature composed from R and S is valid.
411  */
412 static int
413 verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_public_key *pkey )
414 {
415   int rc;
416   gcry_mpi_t w, u1, u2, v;
417   gcry_mpi_t base[3];
418   gcry_mpi_t ex[3];
419
420   if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
421     return 0; /* assertion      0 < r < q  failed */
422   if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
423     return 0; /* assertion      0 < s < q  failed */
424
425   w  = mpi_alloc( mpi_get_nlimbs(pkey->q) );
426   u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
427   u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
428   v  = mpi_alloc( mpi_get_nlimbs(pkey->p) );
429
430   /* w = s^(-1) mod q */
431   mpi_invm( w, s, pkey->q );
432
433   /* u1 = (hash * w) mod q */
434   mpi_mulm( u1, hash, w, pkey->q );
435
436   /* u2 = r * w mod q  */
437   mpi_mulm( u2, r, w, pkey->q );
438
439   /* v =  g^u1 * y^u2 mod p mod q */
440   base[0] = pkey->g; ex[0] = u1;
441   base[1] = pkey->y; ex[1] = u2;
442   base[2] = NULL;    ex[2] = NULL;
443   mpi_mulpowm( v, base, ex, pkey->p );
444   mpi_fdiv_r( v, v, pkey->q );
445
446   rc = !mpi_cmp( v, r );
447
448   mpi_free(w);
449   mpi_free(u1);
450   mpi_free(u2);
451   mpi_free(v);
452
453   return rc;
454 }
455
456
457 /*********************************************
458  **************  interface  ******************
459  *********************************************/
460
461 static gcry_err_code_t
462 dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
463                   const gcry_sexp_t genparms,
464                   gcry_mpi_t *skey, gcry_mpi_t **retfactors,
465                   gcry_sexp_t *r_extrainfo)
466 {
467   gpg_err_code_t ec;
468   DSA_secret_key sk;
469   gcry_sexp_t l1;
470   unsigned int qbits = 0;
471
472   (void)algo;    /* No need to check it.  */
473   (void)evalue;  /* Not required for DSA. */
474
475   /* Parse the optional qbits element. */
476   if (genparms)
477     {
478       l1 = gcry_sexp_find_token (genparms, "qbits", 0);
479       if (l1)
480         {
481           char buf[50];
482           const char *s;
483           size_t n;
484           
485           s = gcry_sexp_nth_data (l1, 1, &n);
486           if (!s || n >= DIM (buf) - 1 )
487             {
488               gcry_sexp_release (l1);
489               return GPG_ERR_INV_OBJ; /* No value or value too large.  */
490             }
491           memcpy (buf, s, n);
492           buf[n] = 0;
493           qbits = (unsigned int)strtoul (buf, NULL, 0);
494           gcry_sexp_release (l1);
495         }
496     }
497
498   ec = generate (&sk, nbits, qbits, retfactors);
499   if (!ec)
500     {
501       skey[0] = sk.p;
502       skey[1] = sk.q;
503       skey[2] = sk.g;
504       skey[3] = sk.y;
505       skey[4] = sk.x;
506
507       if (!r_extrainfo)
508         {
509           /* Old style interface - return the factors - if any - at
510              retfactors.  */
511         }
512       else if (r_extrainfo && !*retfactors)
513         {
514           /* No factors, thus there is nothing to return.  */
515           *r_extrainfo = NULL;
516         }
517       else
518         {
519           /* Put the factors into extrainfo and set retfactors to NULL
520              to make use of the new interface.  Note that the factors
521              are not confidential thus we can store them in standard
522              memory.  */
523           int nfactors, i;
524           char *p;
525           char *format = NULL;
526           void **arg_list = NULL;
527
528           for (nfactors=0; (*retfactors)[nfactors]; nfactors++)
529             ;
530           /* Allocate space for the format string:
531                "(misc-key-info(pm1-factors%m))"
532              with one "%m" for each factor and build the string  */
533           format = gcry_malloc (40 + 2*nfactors);
534           if (!format)
535             ec = gpg_err_code_from_syserror ();
536           else
537             {
538               p = stpcpy (format, "(misc-key-info(pm1-factors");
539               for (i=0; i < nfactors; i++)
540                 p = stpcpy (p, "%m");
541               p = stpcpy (p, "))");
542               
543               /* Allocate space for the argument list plus an extra
544                  NULL entry for safety and fill it with the
545                  factors.  */
546               arg_list = gcry_calloc (nfactors+1, sizeof *arg_list);
547               if (!arg_list)
548                 ec = gpg_err_code_from_syserror ();
549               else
550                 {
551                   for (i=0; i < nfactors; i++)
552                     arg_list[i] = (*retfactors) + i;
553                   arg_list[i] = NULL;
554                   
555                   ec = gpg_err_code (gcry_sexp_build_array 
556                                      (r_extrainfo, NULL, format, arg_list));
557                 }
558             }
559
560           gcry_free (arg_list);
561           gcry_free (format);
562           for (i=0; i < nfactors; i++)
563             {
564               gcry_mpi_release ((*retfactors)[i]);
565               (*retfactors)[i] = NULL;
566             }
567           *retfactors = NULL;
568           if (ec)
569             {
570               for (i=0; i < 5; i++)
571                 {
572                   gcry_mpi_release (skey[i]);
573                   skey[i] = NULL;
574                 }
575             }
576         }
577     }
578
579   return ec;
580 }
581
582
583 static gcry_err_code_t
584 dsa_generate (int algo, unsigned int nbits, unsigned long evalue,
585               gcry_mpi_t *skey, gcry_mpi_t **retfactors)
586 {
587   (void)evalue;
588   return dsa_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
589 }
590
591
592
593 static gcry_err_code_t
594 dsa_check_secret_key (int algo, gcry_mpi_t *skey)
595 {
596   gcry_err_code_t err = GPG_ERR_NO_ERROR;
597   DSA_secret_key sk;
598
599   (void)algo;
600
601   if ((! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]) || (! skey[4]))
602     err = GPG_ERR_BAD_MPI;
603   else
604     {
605       sk.p = skey[0];
606       sk.q = skey[1];
607       sk.g = skey[2];
608       sk.y = skey[3];
609       sk.x = skey[4];
610       if (! check_secret_key (&sk))
611         err = GPG_ERR_BAD_SECKEY;
612     }
613
614   return err;
615 }
616
617
618 static gcry_err_code_t
619 dsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
620 {
621   gcry_err_code_t err = GPG_ERR_NO_ERROR;
622   DSA_secret_key sk;
623
624   (void)algo;
625
626   if ((! data)
627       || (! skey[0]) || (! skey[1]) || (! skey[2])
628       || (! skey[3]) || (! skey[4]))
629     err = GPG_ERR_BAD_MPI;
630   else
631     {
632       sk.p = skey[0];
633       sk.q = skey[1];
634       sk.g = skey[2];
635       sk.y = skey[3];
636       sk.x = skey[4];
637       resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.p));
638       resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p));
639       sign (resarr[0], resarr[1], data, &sk);
640     }
641   return err;
642 }
643
644 static gcry_err_code_t
645 dsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
646             int (*cmp) (void *, gcry_mpi_t), void *opaquev)
647 {
648   gcry_err_code_t err = GPG_ERR_NO_ERROR;
649   DSA_public_key pk;
650
651   (void)algo;
652   (void)cmp;
653   (void)opaquev;
654
655   if ((! data[0]) || (! data[1]) || (! hash)
656       || (! pkey[0]) || (! pkey[1]) || (! pkey[2]) || (! pkey[3]))
657     err = GPG_ERR_BAD_MPI;
658   else
659     {
660       pk.p = pkey[0];
661       pk.q = pkey[1];
662       pk.g = pkey[2];
663       pk.y = pkey[3];
664       if (! verify (data[0], data[1], hash, &pk))
665         err = GPG_ERR_BAD_SIGNATURE;
666     }
667   return err;
668 }
669
670
671 static unsigned int
672 dsa_get_nbits (int algo, gcry_mpi_t *pkey)
673 {
674   (void)algo;
675
676   return mpi_get_nbits (pkey[0]);
677 }
678
679
680 \f
681 /* 
682      Self-test section.
683  */
684
685 static const char *
686 selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
687 {
688   static const char sample_data[] = 
689     "(data (flags pkcs1)"
690     " (hash sha1 #a0b1c2d3e4f500102030405060708090a1b2c3d4#))";
691   static const char sample_data_bad[] = 
692     "(data (flags pkcs1)"
693     " (hash sha1 #a0b1c2d3e4f510102030405060708090a1b2c3d4#))";
694
695   const char *errtxt = NULL;
696   gcry_error_t err;
697   gcry_sexp_t data = NULL;
698   gcry_sexp_t data_bad = NULL;
699   gcry_sexp_t sig = NULL;
700
701   err = gcry_sexp_sscan (&data, NULL,
702                          sample_data, strlen (sample_data));
703   if (!err)
704     err = gcry_sexp_sscan (&data_bad, NULL, 
705                            sample_data_bad, strlen (sample_data_bad));
706   if (err)
707     {
708       errtxt = "converting data failed";
709       goto leave;
710     }
711
712   err = gcry_pk_sign (&sig, data, skey);
713   if (err)
714     {
715       errtxt = "signing failed";
716       goto leave;
717     }
718   err = gcry_pk_verify (sig, data, pkey);
719   if (err)
720     {
721       errtxt = "verify failed";
722       goto leave;
723     }
724   err = gcry_pk_verify (sig, data_bad, pkey);
725   if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
726     {
727       errtxt = "bad signature not detected";
728       goto leave;
729     }
730
731
732  leave:
733   gcry_sexp_release (sig);
734   gcry_sexp_release (data_bad);
735   gcry_sexp_release (data);
736   return errtxt;
737 }
738
739
740 static gpg_err_code_t
741 selftests_dsa (selftest_report_func_t report)
742 {
743   const char *what;
744   const char *errtxt;
745   gcry_error_t err;
746   gcry_sexp_t skey = NULL;
747   gcry_sexp_t pkey = NULL;
748
749   /* Convert the S-expressions into the internal representation.  */
750   what = "convert";
751   err = gcry_sexp_sscan (&skey, NULL, 
752                          sample_secret_key, strlen (sample_secret_key));
753   if (!err)
754     err = gcry_sexp_sscan (&pkey, NULL, 
755                            sample_public_key, strlen (sample_public_key));
756   if (err)
757     {
758       errtxt = gcry_strerror (err);
759       goto failed;
760     }
761
762   what = "key consistency";
763   err = gcry_pk_testkey (skey);
764   if (err)
765     {
766       errtxt = gcry_strerror (err);
767       goto failed;
768     }
769
770   what = "sign";
771   errtxt = selftest_sign_1024 (pkey, skey);
772   if (errtxt)
773     goto failed;
774
775   gcry_sexp_release (pkey);
776   gcry_sexp_release (skey);
777   return 0; /* Succeeded. */
778
779  failed:
780   gcry_sexp_release (pkey);
781   gcry_sexp_release (skey);
782   if (report)
783     report ("pubkey", GCRY_PK_DSA, what, errtxt);
784   return GPG_ERR_SELFTEST_FAILED;
785 }
786
787
788 /* Run a full self-test for ALGO and return 0 on success.  */
789 static gpg_err_code_t
790 run_selftests (int algo, int extended, selftest_report_func_t report)
791 {
792   gpg_err_code_t ec;
793
794   (void)extended;
795
796   switch (algo)
797     {
798     case GCRY_PK_DSA:
799       ec = selftests_dsa (report);
800       break;
801     default:
802       ec = GPG_ERR_PUBKEY_ALGO;
803       break;
804         
805     }
806   return ec;
807 }
808
809
810
811 \f
812 static const char *dsa_names[] =
813   {
814     "dsa",
815     "openpgp-dsa",
816     NULL,
817   };
818
819 gcry_pk_spec_t _gcry_pubkey_spec_dsa =
820   {
821     "DSA", dsa_names, 
822     "pqgy", "pqgyx", "", "rs", "pqgy",
823     GCRY_PK_USAGE_SIGN,
824     dsa_generate,
825     dsa_check_secret_key,
826     NULL,
827     NULL,
828     dsa_sign,
829     dsa_verify,
830     dsa_get_nbits
831   };
832 pk_extra_spec_t _gcry_pubkey_extraspec_dsa = 
833   {
834     run_selftests,
835     dsa_generate_ext
836   };
837