fb5654e81e8d9fe90c191da80a387596908a2ab2
[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 {
466   gpg_err_code_t ec;
467   DSA_secret_key sk;
468   gcry_sexp_t l1;
469   unsigned int qbits = 0;
470
471   (void)algo;    /* No need to check it.  */
472   (void)evalue;  /* Not required for DSA. */
473
474   /* Parse the optional qbits element. */
475   if (genparms)
476     {
477       l1 = gcry_sexp_find_token (genparms, "qbits", 0);
478       if (l1)
479         {
480           char buf[50];
481           const char *s;
482           size_t n;
483           
484           s = gcry_sexp_nth_data (l1, 1, &n);
485           if (!s || n >= DIM (buf) - 1 )
486             {
487               gcry_sexp_release (l1);
488               return GPG_ERR_INV_OBJ; /* No value or value too large.  */
489             }
490           memcpy (buf, s, n);
491           buf[n] = 0;
492           qbits = (unsigned int)strtoul (buf, NULL, 0);
493           gcry_sexp_release (l1);
494         }
495     }
496
497   ec = generate (&sk, nbits, qbits, retfactors);
498   if (!ec)
499     {
500       skey[0] = sk.p;
501       skey[1] = sk.q;
502       skey[2] = sk.g;
503       skey[3] = sk.y;
504       skey[4] = sk.x;
505     }
506
507   return ec;
508 }
509
510
511 static gcry_err_code_t
512 dsa_generate (int algo, unsigned int nbits, unsigned long evalue,
513               gcry_mpi_t *skey, gcry_mpi_t **retfactors)
514 {
515   (void)evalue;
516   return dsa_generate_ext (algo, nbits, 0, NULL, skey, retfactors);
517 }
518
519
520
521 static gcry_err_code_t
522 dsa_check_secret_key (int algo, gcry_mpi_t *skey)
523 {
524   gcry_err_code_t err = GPG_ERR_NO_ERROR;
525   DSA_secret_key sk;
526
527   (void)algo;
528
529   if ((! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]) || (! skey[4]))
530     err = GPG_ERR_BAD_MPI;
531   else
532     {
533       sk.p = skey[0];
534       sk.q = skey[1];
535       sk.g = skey[2];
536       sk.y = skey[3];
537       sk.x = skey[4];
538       if (! check_secret_key (&sk))
539         err = GPG_ERR_BAD_SECKEY;
540     }
541
542   return err;
543 }
544
545
546 static gcry_err_code_t
547 dsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
548 {
549   gcry_err_code_t err = GPG_ERR_NO_ERROR;
550   DSA_secret_key sk;
551
552   (void)algo;
553
554   if ((! data)
555       || (! skey[0]) || (! skey[1]) || (! skey[2])
556       || (! skey[3]) || (! skey[4]))
557     err = GPG_ERR_BAD_MPI;
558   else
559     {
560       sk.p = skey[0];
561       sk.q = skey[1];
562       sk.g = skey[2];
563       sk.y = skey[3];
564       sk.x = skey[4];
565       resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.p));
566       resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p));
567       sign (resarr[0], resarr[1], data, &sk);
568     }
569   return err;
570 }
571
572 static gcry_err_code_t
573 dsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
574             int (*cmp) (void *, gcry_mpi_t), void *opaquev)
575 {
576   gcry_err_code_t err = GPG_ERR_NO_ERROR;
577   DSA_public_key pk;
578
579   (void)algo;
580   (void)cmp;
581   (void)opaquev;
582
583   if ((! data[0]) || (! data[1]) || (! hash)
584       || (! pkey[0]) || (! pkey[1]) || (! pkey[2]) || (! pkey[3]))
585     err = GPG_ERR_BAD_MPI;
586   else
587     {
588       pk.p = pkey[0];
589       pk.q = pkey[1];
590       pk.g = pkey[2];
591       pk.y = pkey[3];
592       if (! verify (data[0], data[1], hash, &pk))
593         err = GPG_ERR_BAD_SIGNATURE;
594     }
595   return err;
596 }
597
598
599 static unsigned int
600 dsa_get_nbits (int algo, gcry_mpi_t *pkey)
601 {
602   (void)algo;
603
604   return mpi_get_nbits (pkey[0]);
605 }
606
607
608 \f
609 /* 
610      Self-test section.
611  */
612
613 static const char *
614 selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
615 {
616   static const char sample_data[] = 
617     "(data (flags pkcs1)"
618     " (hash sha1 #a0b1c2d3e4f500102030405060708090a1b2c3d4#))";
619   static const char sample_data_bad[] = 
620     "(data (flags pkcs1)"
621     " (hash sha1 #a0b1c2d3e4f510102030405060708090a1b2c3d4#))";
622
623   const char *errtxt = NULL;
624   gcry_error_t err;
625   gcry_sexp_t data = NULL;
626   gcry_sexp_t data_bad = NULL;
627   gcry_sexp_t sig = NULL;
628
629   err = gcry_sexp_sscan (&data, NULL,
630                          sample_data, strlen (sample_data));
631   if (!err)
632     err = gcry_sexp_sscan (&data_bad, NULL, 
633                            sample_data_bad, strlen (sample_data_bad));
634   if (err)
635     {
636       errtxt = "converting data failed";
637       goto leave;
638     }
639
640   err = gcry_pk_sign (&sig, data, skey);
641   if (err)
642     {
643       errtxt = "signing failed";
644       goto leave;
645     }
646   err = gcry_pk_verify (sig, data, pkey);
647   if (err)
648     {
649       errtxt = "verify failed";
650       goto leave;
651     }
652   err = gcry_pk_verify (sig, data_bad, pkey);
653   if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
654     {
655       errtxt = "bad signature not detected";
656       goto leave;
657     }
658
659
660  leave:
661   gcry_sexp_release (sig);
662   gcry_sexp_release (data_bad);
663   gcry_sexp_release (data);
664   return errtxt;
665 }
666
667
668 static gpg_err_code_t
669 selftests_dsa (selftest_report_func_t report)
670 {
671   const char *what;
672   const char *errtxt;
673   gcry_error_t err;
674   gcry_sexp_t skey = NULL;
675   gcry_sexp_t pkey = NULL;
676
677   /* Convert the S-expressions into the internal representation.  */
678   what = "convert";
679   err = gcry_sexp_sscan (&skey, NULL, 
680                          sample_secret_key, strlen (sample_secret_key));
681   if (!err)
682     err = gcry_sexp_sscan (&pkey, NULL, 
683                            sample_public_key, strlen (sample_public_key));
684   if (err)
685     {
686       errtxt = gcry_strerror (err);
687       goto failed;
688     }
689
690   what = "key consistency";
691   err = gcry_pk_testkey (skey);
692   if (err)
693     {
694       errtxt = gcry_strerror (err);
695       goto failed;
696     }
697
698   what = "sign";
699   errtxt = selftest_sign_1024 (pkey, skey);
700   if (errtxt)
701     goto failed;
702
703   gcry_sexp_release (pkey);
704   gcry_sexp_release (skey);
705   return 0; /* Succeeded. */
706
707  failed:
708   gcry_sexp_release (pkey);
709   gcry_sexp_release (skey);
710   if (report)
711     report ("pubkey", GCRY_PK_DSA, what, errtxt);
712   return GPG_ERR_SELFTEST_FAILED;
713 }
714
715
716 /* Run a full self-test for ALGO and return 0 on success.  */
717 static gpg_err_code_t
718 run_selftests (int algo, int extended, selftest_report_func_t report)
719 {
720   gpg_err_code_t ec;
721
722   (void)extended;
723
724   switch (algo)
725     {
726     case GCRY_PK_DSA:
727       ec = selftests_dsa (report);
728       break;
729     default:
730       ec = GPG_ERR_PUBKEY_ALGO;
731       break;
732         
733     }
734   return ec;
735 }
736
737
738
739 \f
740 static const char *dsa_names[] =
741   {
742     "dsa",
743     "openpgp-dsa",
744     NULL,
745   };
746
747 gcry_pk_spec_t _gcry_pubkey_spec_dsa =
748   {
749     "DSA", dsa_names, 
750     "pqgy", "pqgyx", "", "rs", "pqgy",
751     GCRY_PK_USAGE_SIGN,
752     dsa_generate,
753     dsa_check_secret_key,
754     NULL,
755     NULL,
756     dsa_sign,
757     dsa_verify,
758     dsa_get_nbits
759   };
760 pk_extra_spec_t _gcry_pubkey_extraspec_dsa = 
761   {
762     run_selftests,
763     dsa_generate_ext
764   };
765