49
/* A structure used to hold domain parameters. */
52
gcry_mpi_t p; /* prime */
53
gcry_mpi_t q; /* group order */
54
gcry_mpi_t g; /* group generator */
58
/* A sample 1024 bit DSA key used for the selftests. */
59
static const char sample_secret_key[] =
62
" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
63
" 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
64
" CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
65
" 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)"
66
" (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)"
67
" (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
68
" AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
69
" B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
70
" 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)"
71
" (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
72
" A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
73
" 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
74
" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)"
75
" (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))";
76
/* A sample 1024 bit DSA key used for the selftests (public only). */
77
static const char sample_public_key[] =
80
" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
81
" 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
82
" CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
83
" 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)"
84
" (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)"
85
" (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
86
" AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
87
" B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
88
" 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)"
89
" (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
90
" A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
91
" 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
92
" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))";
51
97
static gcry_mpi_t gen_k (gcry_mpi_t q);
52
static void test_keys (DSA_secret_key *sk, unsigned qbits);
98
static int test_keys (DSA_secret_key *sk, unsigned int qbits);
53
99
static int check_secret_key (DSA_secret_key *sk);
54
100
static gpg_err_code_t generate (DSA_secret_key *sk,
55
101
unsigned int nbits,
56
102
unsigned int qbits,
104
dsa_domain_t *domain,
57
105
gcry_mpi_t **ret_factors);
58
106
static void sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
59
107
DSA_secret_key *skey);
149
test_keys( DSA_secret_key *sk, unsigned qbits )
196
/* Check that a freshly generated key actually works. Returns 0 on success. */
198
test_keys (DSA_secret_key *sk, unsigned int qbits)
200
int result = -1; /* Default to failure. */
151
201
DSA_public_key pk;
152
gcry_mpi_t test = gcry_mpi_new ( qbits );
153
gcry_mpi_t out1_a = gcry_mpi_new ( qbits );
154
gcry_mpi_t out1_b = gcry_mpi_new ( qbits );
202
gcry_mpi_t data = gcry_mpi_new (qbits);
203
gcry_mpi_t sig_a = gcry_mpi_new (qbits);
204
gcry_mpi_t sig_b = gcry_mpi_new (qbits);
206
/* Put the relevant parameters into a public key structure. */
160
gcry_mpi_randomize( test, qbits, GCRY_WEAK_RANDOM );
162
sign( out1_a, out1_b, test, sk );
163
if( !verify( out1_a, out1_b, test, &pk ) )
164
log_fatal("DSA:: sign, verify failed\n");
166
gcry_mpi_release ( test );
167
gcry_mpi_release ( out1_a );
168
gcry_mpi_release ( out1_b );
212
/* Create a random plaintext. */
213
gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM);
215
/* Sign DATA using the secret key. */
216
sign (sig_a, sig_b, data, sk);
218
/* Verify the signature using the public key. */
219
if ( !verify (sig_a, sig_b, data, &pk) )
220
goto leave; /* Signature does not match. */
222
/* Modify the data and check that the signing fails. */
223
gcry_mpi_add_ui (data, data, 1);
224
if ( verify (sig_a, sig_b, data, &pk) )
225
goto leave; /* Signature matches but should not. */
227
result = 0; /* The test succeeded. */
230
gcry_mpi_release (sig_b);
231
gcry_mpi_release (sig_a);
232
gcry_mpi_release (data);
174
Generate a DSA key pair with a key of size NBITS.
239
Generate a DSA key pair with a key of size NBITS. If transient_key
240
is true the key is generated using the standard RNG and not the
175
243
Returns: 2 structures filled with all needed values
176
244
and an array with the n-1 factors of (p-1)
178
246
static gpg_err_code_t
179
247
generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
180
gcry_mpi_t **ret_factors )
248
int transient_key, dsa_domain_t *domain, gcry_mpi_t **ret_factors )
182
250
gcry_mpi_t p; /* the prime */
183
251
gcry_mpi_t q; /* the 160 bit prime factor */
207
276
if (nbits < 2*qbits || nbits > 15360)
208
277
return GPG_ERR_INV_VALUE;
210
p = _gcry_generate_elg_prime( 1, nbits, qbits, NULL, ret_factors );
211
/* get q out of factors */
212
q = mpi_copy((*ret_factors)[0]);
213
if( mpi_get_nbits(q) != qbits )
216
/* Find a generator g (h and e are helpers).
218
e = mpi_alloc( mpi_get_nlimbs(p) );
219
mpi_sub_ui( e, p, 1 );
220
mpi_fdiv_q( e, e, q );
221
g = mpi_alloc( mpi_get_nlimbs(p) );
222
h = mpi_alloc_set_ui( 1 ); /* we start with 2 */
225
mpi_add_ui( h, h, 1 );
227
gcry_mpi_powm( g, h, e, p );
229
while( !mpi_cmp_ui( g, 1 ) ); /* continue until g != 1 */
231
/* Select a random number which has these properties:
282
return GPG_ERR_INV_VALUE;
284
return GPG_ERR_INV_VALUE;
287
if (domain->p && domain->q && domain->g)
289
/* Domain parameters are given; use them. */
290
p = mpi_copy (domain->p);
291
q = mpi_copy (domain->q);
292
g = mpi_copy (domain->g);
293
gcry_assert (mpi_get_nbits (p) == nbits);
294
gcry_assert (mpi_get_nbits (q) == qbits);
300
/* Generate new domain parameters. */
301
p = _gcry_generate_elg_prime (1, nbits, qbits, NULL, ret_factors);
302
/* Get q out of factors. */
303
q = mpi_copy ((*ret_factors)[0]);
304
gcry_assert (mpi_get_nbits (q) == qbits);
306
/* Find a generator g (h and e are helpers).
308
e = mpi_alloc (mpi_get_nlimbs (p));
309
mpi_sub_ui (e, p, 1);
310
mpi_fdiv_q (e, e, q);
311
g = mpi_alloc (mpi_get_nlimbs (p));
312
h = mpi_alloc_set_ui (1); /* (We start with 2.) */
315
mpi_add_ui (h, h, 1);
317
gcry_mpi_powm (g, h, e, p);
319
while (!mpi_cmp_ui (g, 1)); /* Continue until g != 1. */
322
/* Select a random number X with the property:
233
* This must be a very good random number because this
234
* is the secret part. */
236
log_debug("choosing a random x ");
237
assert( qbits >= 160 );
324
* This must be a very good random number because this is the secret
325
* part. The random quality depends on the transient_key flag. */
326
random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
328
log_debug("choosing a random x%s", transient_key? " (transient-key)":"");
329
gcry_assert( qbits >= 160 );
238
330
x = mpi_alloc_secure( mpi_get_nlimbs(q) );
239
331
mpi_sub_ui( h, q, 1 ); /* put q-1 into h */
284
375
/* Now we can test our keys (this should never fail!). */
285
test_keys( sk, qbits );
376
if ( test_keys (sk, qbits) )
378
gcry_mpi_release (sk->p); sk->p = NULL;
379
gcry_mpi_release (sk->q); sk->q = NULL;
380
gcry_mpi_release (sk->g); sk->g = NULL;
381
gcry_mpi_release (sk->y); sk->y = NULL;
382
gcry_mpi_release (sk->x); sk->x = NULL;
383
fips_signal_error ("self-test after key generation failed");
384
return GPG_ERR_SELFTEST_FAILED;
390
/* Generate a DSA key pair with a key of size NBITS using the
391
algorithm given in FIPS-186-3. If USE_FIPS186_2 is true,
392
FIPS-186-2 is used and thus the length is restricted to 1024/160.
393
If DERIVEPARMS is not NULL it may contain a seed value. If domain
394
parameters are specified in DOMAIN, DERIVEPARMS may not be given
395
and NBITS and QBITS must match the specified domain parameters. */
396
static gpg_err_code_t
397
generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
398
gcry_sexp_t deriveparms, int use_fips186_2,
399
dsa_domain_t *domain,
400
int *r_counter, void **r_seed, size_t *r_seedlen,
408
} initial_seed = { NULL, NULL, 0 };
409
gcry_mpi_t prime_q = NULL;
410
gcry_mpi_t prime_p = NULL;
411
gcry_mpi_t value_g = NULL; /* The generator. */
412
gcry_mpi_t value_y = NULL; /* g^x mod p */
413
gcry_mpi_t value_x = NULL; /* The secret exponent. */
414
gcry_mpi_t value_h = NULL; /* Helper. */
415
gcry_mpi_t value_e = NULL; /* Helper. */
417
/* Preset return values. */
423
/* Derive QBITS from NBITS if requested */
428
else if (nbits == 2048)
430
else if (nbits == 3072)
434
/* Check that QBITS and NBITS match the standard. Note that FIPS
435
186-3 uses N for QBITS and L for NBITS. */
436
if (nbits == 1024 && qbits == 160)
438
else if (nbits == 2048 && qbits == 224)
440
else if (nbits == 2048 && qbits == 256)
442
else if (nbits == 3072 && qbits == 256)
445
return GPG_ERR_INV_VALUE;
447
if (domain->p && domain->q && domain->g)
449
/* Domain parameters are given; use them. */
450
prime_p = mpi_copy (domain->p);
451
prime_q = mpi_copy (domain->q);
452
value_g = mpi_copy (domain->g);
453
gcry_assert (mpi_get_nbits (prime_p) == nbits);
454
gcry_assert (mpi_get_nbits (prime_q) == qbits);
455
gcry_assert (!deriveparms);
460
/* Generate new domain parameters. */
462
/* Get an initial seed value. */
465
initial_seed.sexp = gcry_sexp_find_token (deriveparms, "seed", 0);
466
if (initial_seed.sexp)
467
initial_seed.seed = gcry_sexp_nth_data (initial_seed.sexp, 1,
468
&initial_seed.seedlen);
471
/* Fixme: Enable 186-3 after it has been approved and after fixing
472
the generation function. */
473
/* if (use_fips186_2) */
475
ec = _gcry_generate_fips186_2_prime (nbits, qbits,
477
initial_seed.seedlen,
482
/* ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, */
483
/* &prime_q, &prime_p, */
485
/* r_seed, r_seedlen, NULL); */
486
gcry_sexp_release (initial_seed.sexp);
490
/* Find a generator g (h and e are helpers).
492
value_e = mpi_alloc_like (prime_p);
493
mpi_sub_ui (value_e, prime_p, 1);
494
mpi_fdiv_q (value_e, value_e, prime_q );
495
value_g = mpi_alloc_like (prime_p);
496
value_h = mpi_alloc_set_ui (1);
499
mpi_add_ui (value_h, value_h, 1);
501
mpi_powm (value_g, value_h, value_e, prime_p);
503
while (!mpi_cmp_ui (value_g, 1)); /* Continue until g != 1. */
507
/* Select a random number x with: 0 < x < q */
508
value_x = gcry_mpi_snew (qbits);
513
gcry_mpi_randomize (value_x, qbits, GCRY_VERY_STRONG_RANDOM);
514
mpi_clear_highbit (value_x, qbits+1);
516
while (!(mpi_cmp_ui (value_x, 0) > 0 && mpi_cmp (value_x, prime_q) < 0));
519
value_y = mpi_alloc_like (prime_p);
520
gcry_mpi_powm (value_y, value_g, value_x, prime_p);
525
log_mpidump("dsa p", prime_p );
526
log_mpidump("dsa q", prime_q );
527
log_mpidump("dsa g", value_g );
528
log_mpidump("dsa y", value_y );
529
log_mpidump("dsa x", value_x );
530
log_mpidump("dsa h", value_h );
533
/* Copy the stuff to the key structures. */
534
sk->p = prime_p; prime_p = NULL;
535
sk->q = prime_q; prime_q = NULL;
536
sk->g = value_g; value_g = NULL;
537
sk->y = value_y; value_y = NULL;
538
sk->x = value_x; value_x = NULL;
539
*r_h = value_h; value_h = NULL;
542
gcry_mpi_release (prime_p);
543
gcry_mpi_release (prime_q);
544
gcry_mpi_release (value_g);
545
gcry_mpi_release (value_y);
546
gcry_mpi_release (value_x);
547
gcry_mpi_release (value_h);
548
gcry_mpi_release (value_e);
550
/* As a last step test this keys (this should never fail of course). */
551
if (!ec && test_keys (sk, qbits) )
553
gcry_mpi_release (sk->p); sk->p = NULL;
554
gcry_mpi_release (sk->q); sk->q = NULL;
555
gcry_mpi_release (sk->g); sk->g = NULL;
556
gcry_mpi_release (sk->y); sk->y = NULL;
557
gcry_mpi_release (sk->x); sk->x = NULL;
558
fips_signal_error ("self-test after key generation failed");
559
ec = GPG_ERR_SELFTEST_FAILED;
565
gcry_free (*r_seed); *r_seed = NULL;
567
gcry_mpi_release (*r_h); *r_h = NULL;
292
576
Test whether the secret key is valid.
391
675
************** interface ******************
392
676
*********************************************/
395
_gcry_dsa_generate (int algo, unsigned int nbits, unsigned long dummy,
396
gcry_mpi_t *skey, gcry_mpi_t **retfactors)
404
err = generate (&sk, nbits, 0, retfactors);
418
/* We don't want to break our API. Thus we use a hack in pubkey.c to
419
link directly to this function. Note that we can't reuse the dummy
420
parameter because we can't be sure that applicaions accidently pass
421
a USE_E (that is for what dummy is used with RSA) to a DSA
424
_gcry_dsa_generate2 (int algo, unsigned int nbits, unsigned int qbits,
426
gcry_mpi_t *skey, gcry_mpi_t **retfactors)
434
err = generate (&sk, nbits, qbits, retfactors);
449
_gcry_dsa_check_secret_key (int algo, gcry_mpi_t *skey)
678
static gcry_err_code_t
679
dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
680
const gcry_sexp_t genparms,
681
gcry_mpi_t *skey, gcry_mpi_t **retfactors,
682
gcry_sexp_t *r_extrainfo)
687
unsigned int qbits = 0;
688
gcry_sexp_t deriveparms = NULL;
689
gcry_sexp_t seedinfo = NULL;
690
int transient_key = 0;
691
int use_fips186_2 = 0;
695
(void)algo; /* No need to check it. */
696
(void)evalue; /* Not required for DSA. */
698
memset (&domain, 0, sizeof domain);
702
gcry_sexp_t domainsexp;
704
/* Parse the optional qbits element. */
705
l1 = gcry_sexp_find_token (genparms, "qbits", 0);
712
s = gcry_sexp_nth_data (l1, 1, &n);
713
if (!s || n >= DIM (buf) - 1 )
715
gcry_sexp_release (l1);
716
return GPG_ERR_INV_OBJ; /* No value or value too large. */
720
qbits = (unsigned int)strtoul (buf, NULL, 0);
721
gcry_sexp_release (l1);
724
/* Parse the optional transient-key flag. */
725
l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
729
gcry_sexp_release (l1);
732
/* Get the optional derive parameters. */
733
deriveparms = gcry_sexp_find_token (genparms, "derive-parms", 0);
735
/* Parse the optional "use-fips186" flags. */
736
l1 = gcry_sexp_find_token (genparms, "use-fips186", 0);
740
gcry_sexp_release (l1);
742
l1 = gcry_sexp_find_token (genparms, "use-fips186-2", 0);
746
gcry_sexp_release (l1);
749
/* Check whether domain parameters are given. */
750
domainsexp = gcry_sexp_find_token (genparms, "domain", 0);
753
/* DERIVEPARMS can't be used together with domain
754
parameters. NBITS abnd QBITS may not be specified
755
because there values are derived from the domain
757
if (deriveparms || qbits || nbits)
759
gcry_sexp_release (domainsexp);
760
gcry_sexp_release (deriveparms);
761
return GPG_ERR_INV_VALUE;
764
/* Put all domain parameters into the domain object. */
765
l1 = gcry_sexp_find_token (domainsexp, "p", 0);
766
domain.p = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
767
gcry_sexp_release (l1);
768
l1 = gcry_sexp_find_token (domainsexp, "q", 0);
769
domain.q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
770
gcry_sexp_release (l1);
771
l1 = gcry_sexp_find_token (domainsexp, "g", 0);
772
domain.g = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
773
gcry_sexp_release (l1);
774
gcry_sexp_release (domainsexp);
776
/* Check that all domain parameters are available. */
777
if (!domain.p || !domain.q || !domain.g)
779
gcry_mpi_release (domain.p);
780
gcry_mpi_release (domain.q);
781
gcry_mpi_release (domain.g);
782
gcry_sexp_release (deriveparms);
783
return GPG_ERR_MISSING_VALUE;
786
/* Get NBITS and QBITS from the domain parameters. */
787
nbits = mpi_get_nbits (domain.p);
788
qbits = mpi_get_nbits (domain.q);
792
if (deriveparms || use_fips186 || use_fips186_2 || fips_mode ())
799
ec = generate_fips186 (&sk, nbits, qbits, deriveparms, use_fips186_2,
801
&counter, &seed, &seedlen, &h_value);
802
gcry_sexp_release (deriveparms);
805
/* Format the seed-values unless domain parameters are used
806
for which a H_VALUE of NULL is an indication. */
807
ec = gpg_err_code (gcry_sexp_build
809
"(seed-values(counter %d)(seed %b)(h %m))",
810
counter, (int)seedlen, seed, h_value));
813
gcry_mpi_release (sk.p); sk.p = NULL;
814
gcry_mpi_release (sk.q); sk.q = NULL;
815
gcry_mpi_release (sk.g); sk.g = NULL;
816
gcry_mpi_release (sk.y); sk.y = NULL;
817
gcry_mpi_release (sk.x); sk.x = NULL;
820
gcry_mpi_release (h_value);
825
ec = generate (&sk, nbits, qbits, transient_key, &domain, retfactors);
828
gcry_mpi_release (domain.p);
829
gcry_mpi_release (domain.q);
830
gcry_mpi_release (domain.g);
842
/* Old style interface - return the factors - if any - at
845
else if (!*retfactors && !seedinfo)
847
/* No factors and no seedinfo, thus there is nothing to return. */
852
/* Put the factors into extrainfo and set retfactors to NULL
853
to make use of the new interface. Note that the factors
854
are not confidential thus we can store them in standard
859
void **arg_list = NULL;
861
for (nfactors=0; *retfactors && (*retfactors)[nfactors]; nfactors++)
863
/* Allocate space for the format string:
864
"(misc-key-info%S(pm1-factors%m))"
865
with one "%m" for each factor and construct it. */
866
format = gcry_malloc (50 + 2*nfactors);
868
ec = gpg_err_code_from_syserror ();
871
p = stpcpy (format, "(misc-key-info");
873
p = stpcpy (p, "%S");
876
p = stpcpy (p, "(pm1-factors");
877
for (i=0; i < nfactors; i++)
878
p = stpcpy (p, "%m");
883
/* Allocate space for the list of factors plus one for
884
an S-expression plus an extra NULL entry for safety
885
and fill it with the factors. */
886
arg_list = gcry_calloc (nfactors+1+1, sizeof *arg_list);
888
ec = gpg_err_code_from_syserror ();
893
arg_list[i++] = &seedinfo;
894
for (j=0; j < nfactors; j++)
895
arg_list[i++] = (*retfactors) + j;
898
ec = gpg_err_code (gcry_sexp_build_array
899
(r_extrainfo, NULL, format, arg_list));
903
gcry_free (arg_list);
905
for (i=0; i < nfactors; i++)
907
gcry_mpi_release ((*retfactors)[i]);
908
(*retfactors)[i] = NULL;
913
for (i=0; i < 5; i++)
915
gcry_mpi_release (skey[i]);
922
gcry_sexp_release (seedinfo);
927
static gcry_err_code_t
928
dsa_generate (int algo, unsigned int nbits, unsigned long evalue,
929
gcry_mpi_t *skey, gcry_mpi_t **retfactors)
932
return dsa_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
937
static gcry_err_code_t
938
dsa_check_secret_key (int algo, gcry_mpi_t *skey)
451
940
gcry_err_code_t err = GPG_ERR_NO_ERROR;
452
941
DSA_secret_key sk;
527
_gcry_dsa_get_nbits (int algo, gcry_mpi_t *pkey)
1016
dsa_get_nbits (int algo, gcry_mpi_t *pkey)
531
1020
return mpi_get_nbits (pkey[0]);
1030
selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
1032
static const char sample_data[] =
1033
"(data (flags pkcs1)"
1034
" (hash sha1 #a0b1c2d3e4f500102030405060708090a1b2c3d4#))";
1035
static const char sample_data_bad[] =
1036
"(data (flags pkcs1)"
1037
" (hash sha1 #a0b1c2d3e4f510102030405060708090a1b2c3d4#))";
1039
const char *errtxt = NULL;
1041
gcry_sexp_t data = NULL;
1042
gcry_sexp_t data_bad = NULL;
1043
gcry_sexp_t sig = NULL;
1045
err = gcry_sexp_sscan (&data, NULL,
1046
sample_data, strlen (sample_data));
1048
err = gcry_sexp_sscan (&data_bad, NULL,
1049
sample_data_bad, strlen (sample_data_bad));
1052
errtxt = "converting data failed";
1056
err = gcry_pk_sign (&sig, data, skey);
1059
errtxt = "signing failed";
1062
err = gcry_pk_verify (sig, data, pkey);
1065
errtxt = "verify failed";
1068
err = gcry_pk_verify (sig, data_bad, pkey);
1069
if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
1071
errtxt = "bad signature not detected";
1077
gcry_sexp_release (sig);
1078
gcry_sexp_release (data_bad);
1079
gcry_sexp_release (data);
1084
static gpg_err_code_t
1085
selftests_dsa (selftest_report_func_t report)
1090
gcry_sexp_t skey = NULL;
1091
gcry_sexp_t pkey = NULL;
1093
/* Convert the S-expressions into the internal representation. */
1095
err = gcry_sexp_sscan (&skey, NULL,
1096
sample_secret_key, strlen (sample_secret_key));
1098
err = gcry_sexp_sscan (&pkey, NULL,
1099
sample_public_key, strlen (sample_public_key));
1102
errtxt = gcry_strerror (err);
1106
what = "key consistency";
1107
err = gcry_pk_testkey (skey);
1110
errtxt = gcry_strerror (err);
1115
errtxt = selftest_sign_1024 (pkey, skey);
1119
gcry_sexp_release (pkey);
1120
gcry_sexp_release (skey);
1121
return 0; /* Succeeded. */
1124
gcry_sexp_release (pkey);
1125
gcry_sexp_release (skey);
1127
report ("pubkey", GCRY_PK_DSA, what, errtxt);
1128
return GPG_ERR_SELFTEST_FAILED;
1132
/* Run a full self-test for ALGO and return 0 on success. */
1133
static gpg_err_code_t
1134
run_selftests (int algo, int extended, selftest_report_func_t report)
1143
ec = selftests_dsa (report);
1146
ec = GPG_ERR_PUBKEY_ALGO;
534
1156
static const char *dsa_names[] =