~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to lib/libgcrypt/cipher/dsa.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Evan Broder, Mario Limonciello
  • Date: 2010-11-24 13:59:55 UTC
  • mfrom: (1.17.6 upstream) (17.6.15 experimental)
  • Revision ID: james.westby@ubuntu.com-20101124135955-r6ii5sepayr7jt53
Tags: 1.99~20101124-1ubuntu1
[ Colin Watson ]
* Resynchronise with Debian experimental.  Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed.  If it is, show the
    menu, otherwise boot immediately.  If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt.  Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - Suppress progress messages as the kernel and initrd load for
    non-recovery kernel menu entries.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Don't generate /boot/grub/device.map during grub-install or
    grub-mkconfig by default.
  - Adjust upgrade version checks for Ubuntu.
  - Don't display "GRUB loading" unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
    our backport of the grub-doc split.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack as well, in
    preference.
  - Make sure GRUB_TIMEOUT isn't quoted unnecessarily.
  - Probe all devices in 'grub-probe --target=drive' if
    /boot/grub/device.map is missing.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Use qemu rather than qemu-system-i386.
  - Program vesafb on BIOS systems rather than efifb.
  - Add a grub-rescue-efi-amd64 package containing a rescue CD-ROM image
    for EFI-AMD64.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - When embedding the core image in a post-MBR gap, check for and avoid
    sectors matching any of a list of known signatures.
  - Disable video_bochs and video_cirrus on PC BIOS systems, as probing
    PCI space seems to break on some systems.
* Downgrade "ACPI shutdown failed" error to a debug message, since it can
  cause spurious test failures.

[ Evan Broder ]
* Enable lua from grub-extras.
* Incorporate the bitop library into lua.
* Add enum_pci function to grub module in lua.
* Switch back to gfxpayload=keep by default, unless the video hardware
  is known to not support it.

[ Mario Limonciello ]
* Built part_msdos and vfat into bootx64.efi (LP: #677758)

Show diffs side-by-side

added added

removed removed

Lines of Context:
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, see <http://www.gnu.org/licenses/>.
19
 
 */
20
 
 
21
 
#include <config.h>
22
 
#include <stdio.h>
23
 
#include <stdlib.h>
24
 
#include <string.h>
25
 
 
26
 
#include "g10lib.h"
27
 
#include "mpi.h"
28
 
#include "cipher.h"
29
 
 
30
 
typedef struct
31
 
{
32
 
  gcry_mpi_t p;     /* prime */
33
 
  gcry_mpi_t q;     /* group order */
34
 
  gcry_mpi_t g;     /* group generator */
35
 
  gcry_mpi_t y;     /* g^x mod p */
36
 
} DSA_public_key;
37
 
 
38
 
 
39
 
typedef struct
40
 
{
41
 
  gcry_mpi_t p;     /* prime */
42
 
  gcry_mpi_t q;     /* group order */
43
 
  gcry_mpi_t g;     /* group generator */
44
 
  gcry_mpi_t y;     /* g^x mod p */
45
 
  gcry_mpi_t x;     /* secret exponent */
46
 
} DSA_secret_key;
47
 
 
48
 
 
49
 
/* A structure used to hold domain parameters.  */
50
 
typedef struct
51
 
{
52
 
  gcry_mpi_t p;     /* prime */
53
 
  gcry_mpi_t q;     /* group order */
54
 
  gcry_mpi_t g;     /* group generator */
55
 
} dsa_domain_t;
56
 
 
57
 
 
58
 
/* A sample 1024 bit DSA key used for the selftests.  */
59
 
static const char sample_secret_key[] =
60
 
"(private-key"
61
 
" (dsa"
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[] = 
78
 
"(public-key"
79
 
" (dsa"
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#)))";
93
 
 
94
 
 
95
 
 
96
 
 
97
 
static gcry_mpi_t gen_k (gcry_mpi_t q);
98
 
static int test_keys (DSA_secret_key *sk, unsigned int qbits);
99
 
static int check_secret_key (DSA_secret_key *sk);
100
 
static gpg_err_code_t generate (DSA_secret_key *sk,
101
 
                                unsigned int nbits,
102
 
                                unsigned int qbits,
103
 
                                int transient_key,
104
 
                                dsa_domain_t *domain,
105
 
                                gcry_mpi_t **ret_factors);
106
 
static void sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
107
 
                  DSA_secret_key *skey);
108
 
static int verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
109
 
                   DSA_public_key *pkey);
110
 
 
111
 
static void (*progress_cb) (void *,const char *, int, int, int );
112
 
static void *progress_cb_data;
113
 
 
114
 
 
115
 
void
116
 
_gcry_register_pk_dsa_progress (void (*cb) (void *, const char *,
117
 
                                            int, int, int),
118
 
                                void *cb_data)
119
 
{
120
 
  progress_cb = cb;
121
 
  progress_cb_data = cb_data;
122
 
}
123
 
 
124
 
 
125
 
static void
126
 
progress (int c)
127
 
{
128
 
  if (progress_cb)
129
 
    progress_cb (progress_cb_data, "pk_dsa", c, 0, 0);
130
 
}
131
 
 
132
 
 
133
 
/*
134
 
 * Generate a random secret exponent k less than q.
135
 
 */
136
 
static gcry_mpi_t
137
 
gen_k( gcry_mpi_t q )
138
 
{
139
 
  gcry_mpi_t k = mpi_alloc_secure( mpi_get_nlimbs(q) );
140
 
  unsigned int nbits = mpi_get_nbits(q);
141
 
  unsigned int nbytes = (nbits+7)/8;
142
 
  char *rndbuf = NULL;
143
 
 
144
 
  if ( DBG_CIPHER )
145
 
    log_debug("choosing a random k ");
146
 
  for (;;) 
147
 
    {
148
 
      if( DBG_CIPHER )
149
 
        progress('.');
150
 
 
151
 
      if ( !rndbuf || nbits < 32 ) 
152
 
        {
153
 
          gcry_free(rndbuf);
154
 
          rndbuf = gcry_random_bytes_secure( (nbits+7)/8, GCRY_STRONG_RANDOM );
155
 
        }
156
 
      else
157
 
        { /* Change only some of the higher bits.  We could improve
158
 
             this by directly requesting more memory at the first call
159
 
             to get_random_bytes() and use this the here maybe it is
160
 
             easier to do this directly in random.c. */
161
 
          char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
162
 
          memcpy( rndbuf,pp, 4 );
163
 
          gcry_free(pp);
164
 
        }
165
 
      _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
166
 
      if ( mpi_test_bit( k, nbits-1 ) )
167
 
        mpi_set_highbit( k, nbits-1 );
168
 
      else
169
 
        {
170
 
          mpi_set_highbit( k, nbits-1 );
171
 
          mpi_clear_bit( k, nbits-1 );
172
 
        }
173
 
 
174
 
      if( !(mpi_cmp( k, q ) < 0) ) /* check: k < q */
175
 
        {       
176
 
          if( DBG_CIPHER )
177
 
            progress('+');
178
 
          continue; /* no  */
179
 
        }
180
 
      if( !(mpi_cmp_ui( k, 0 ) > 0) )  /* check: k > 0 */
181
 
        {
182
 
          if( DBG_CIPHER )
183
 
            progress('-');
184
 
          continue; /* no */
185
 
        }
186
 
      break;    /* okay */
187
 
    }
188
 
  gcry_free(rndbuf);
189
 
  if( DBG_CIPHER )
190
 
    progress('\n');
191
 
  
192
 
  return k;
193
 
}
194
 
 
195
 
 
196
 
/* Check that a freshly generated key actually works.  Returns 0 on success. */
197
 
static int
198
 
test_keys (DSA_secret_key *sk, unsigned int qbits)
199
 
{
200
 
  int result = -1;  /* Default to failure.  */
201
 
  DSA_public_key pk;
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);
205
 
 
206
 
  /* Put the relevant parameters into a public key structure.  */
207
 
  pk.p = sk->p;
208
 
  pk.q = sk->q;
209
 
  pk.g = sk->g;
210
 
  pk.y = sk->y;
211
 
 
212
 
  /* Create a random plaintext.  */
213
 
  gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM);
214
 
 
215
 
  /* Sign DATA using the secret key.  */
216
 
  sign (sig_a, sig_b, data, sk);
217
 
 
218
 
  /* Verify the signature using the public key.  */
219
 
  if ( !verify (sig_a, sig_b, data, &pk) )
220
 
    goto leave; /* Signature does not match.  */
221
 
 
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.  */
226
 
 
227
 
  result = 0; /* The test succeeded.  */
228
 
 
229
 
 leave:
230
 
  gcry_mpi_release (sig_b);
231
 
  gcry_mpi_release (sig_a);
232
 
  gcry_mpi_release (data);
233
 
  return result;
234
 
}
235
 
 
236
 
 
237
 
 
238
 
/*
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
241
 
   very secure one.
242
 
 
243
 
   Returns: 2 structures filled with all needed values
244
 
            and an array with the n-1 factors of (p-1)
245
 
 */
246
 
static gpg_err_code_t
247
 
generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
248
 
          int transient_key, dsa_domain_t *domain, gcry_mpi_t **ret_factors )
249
 
{
250
 
  gcry_mpi_t p;    /* the prime */
251
 
  gcry_mpi_t q;    /* the 160 bit prime factor */
252
 
  gcry_mpi_t g;    /* the generator */
253
 
  gcry_mpi_t y;    /* g^x mod p */
254
 
  gcry_mpi_t x;    /* the secret exponent */
255
 
  gcry_mpi_t h, e;  /* helper */
256
 
  unsigned char *rndbuf;
257
 
  gcry_random_level_t random_level;
258
 
 
259
 
  if (qbits)
260
 
    ; /* Caller supplied qbits.  Use this value.  */
261
 
  else if ( nbits >= 512 && nbits <= 1024 )
262
 
    qbits = 160;
263
 
  else if ( nbits == 2048 )
264
 
    qbits = 224;
265
 
  else if ( nbits == 3072 )
266
 
    qbits = 256;
267
 
  else if ( nbits == 7680 )
268
 
    qbits = 384;
269
 
  else if ( nbits == 15360 )
270
 
    qbits = 512;
271
 
  else
272
 
    return GPG_ERR_INV_VALUE;
273
 
 
274
 
  if (qbits < 160 || qbits > 512 || (qbits%8) )
275
 
    return GPG_ERR_INV_VALUE;
276
 
  if (nbits < 2*qbits || nbits > 15360)
277
 
    return GPG_ERR_INV_VALUE;
278
 
 
279
 
  if (fips_mode ())
280
 
    {
281
 
      if (nbits < 1024)
282
 
        return GPG_ERR_INV_VALUE;
283
 
      if (transient_key)
284
 
        return GPG_ERR_INV_VALUE;
285
 
    }
286
 
 
287
 
  if (domain->p && domain->q && domain->g)
288
 
    {
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);
295
 
      h = mpi_alloc (0);
296
 
      e = NULL;
297
 
    }
298
 
  else
299
 
    {
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);
305
 
 
306
 
      /* Find a generator g (h and e are helpers).
307
 
         e = (p-1)/q */
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.) */
313
 
      do
314
 
        {
315
 
          mpi_add_ui (h, h, 1);
316
 
          /* g = h^e mod p */
317
 
          gcry_mpi_powm (g, h, e, p);
318
 
        } 
319
 
      while (!mpi_cmp_ui (g, 1));  /* Continue until g != 1. */
320
 
    }
321
 
 
322
 
  /* Select a random number X with the property:
323
 
   *     0 < x < q-1
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;
327
 
  if (DBG_CIPHER)
328
 
    log_debug("choosing a random x%s", transient_key? " (transient-key)":"");
329
 
  gcry_assert( qbits >= 160 );
330
 
  x = mpi_alloc_secure( mpi_get_nlimbs(q) );
331
 
  mpi_sub_ui( h, q, 1 );  /* put q-1 into h */
332
 
  rndbuf = NULL;
333
 
  do 
334
 
    {
335
 
      if( DBG_CIPHER )
336
 
        progress('.');
337
 
      if( !rndbuf )
338
 
        rndbuf = gcry_random_bytes_secure ((qbits+7)/8, random_level);
339
 
      else 
340
 
        { /* Change only some of the higher bits (= 2 bytes)*/
341
 
          char *r = gcry_random_bytes_secure (2, random_level);
342
 
          memcpy(rndbuf, r, 2 );
343
 
          gcry_free(r);
344
 
        }
345
 
 
346
 
      _gcry_mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
347
 
      mpi_clear_highbit( x, qbits+1 );
348
 
    } 
349
 
  while ( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
350
 
  gcry_free(rndbuf);
351
 
  mpi_free( e );
352
 
  mpi_free( h );
353
 
 
354
 
  /* y = g^x mod p */
355
 
  y = mpi_alloc( mpi_get_nlimbs(p) );
356
 
  gcry_mpi_powm( y, g, x, p );
357
 
 
358
 
  if( DBG_CIPHER ) 
359
 
    {
360
 
      progress('\n');
361
 
      log_mpidump("dsa  p", p );
362
 
      log_mpidump("dsa  q", q );
363
 
      log_mpidump("dsa  g", g );
364
 
      log_mpidump("dsa  y", y );
365
 
      log_mpidump("dsa  x", x );
366
 
    }
367
 
 
368
 
  /* Copy the stuff to the key structures. */
369
 
  sk->p = p;
370
 
  sk->q = q;
371
 
  sk->g = g;
372
 
  sk->y = y;
373
 
  sk->x = x;
374
 
 
375
 
  /* Now we can test our keys (this should never fail!). */
376
 
  if ( test_keys (sk, qbits) )
377
 
    {
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;
385
 
    }
386
 
  return 0;
387
 
}
388
 
 
389
 
 
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,
401
 
                  gcry_mpi_t *r_h)
402
 
{
403
 
  gpg_err_code_t ec;
404
 
  struct {
405
 
    gcry_sexp_t sexp;
406
 
    const void *seed;
407
 
    size_t 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.  */
416
 
 
417
 
  /* Preset return values.  */
418
 
  *r_counter = 0;
419
 
  *r_seed = NULL;
420
 
  *r_seedlen = 0;
421
 
  *r_h = NULL;
422
 
 
423
 
  /* Derive QBITS from NBITS if requested  */
424
 
  if (!qbits)
425
 
    {
426
 
      if (nbits == 1024)
427
 
        qbits = 160;
428
 
      else if (nbits == 2048)
429
 
        qbits = 224;
430
 
      else if (nbits == 3072)
431
 
        qbits = 256;
432
 
    }
433
 
 
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)
437
 
    ;
438
 
  else if (nbits == 2048 && qbits == 224)
439
 
    ;
440
 
  else if (nbits == 2048 && qbits == 256)
441
 
    ;
442
 
  else if (nbits == 3072 && qbits == 256)
443
 
    ;
444
 
  else
445
 
    return GPG_ERR_INV_VALUE;
446
 
 
447
 
  if (domain->p && domain->q && domain->g)
448
 
    {
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);
456
 
      ec = 0;
457
 
    }
458
 
  else
459
 
    {
460
 
      /* Generate new domain parameters.  */
461
 
 
462
 
      /* Get an initial seed value.  */
463
 
      if (deriveparms)
464
 
        {
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);
469
 
        }
470
 
      
471
 
      /* Fixme: Enable 186-3 after it has been approved and after fixing
472
 
         the generation function.  */
473
 
      /*   if (use_fips186_2) */
474
 
      (void)use_fips186_2;
475
 
      ec = _gcry_generate_fips186_2_prime (nbits, qbits, 
476
 
                                           initial_seed.seed, 
477
 
                                           initial_seed.seedlen,
478
 
                                           &prime_q, &prime_p, 
479
 
                                           r_counter,
480
 
                                           r_seed, r_seedlen);
481
 
      /*   else */
482
 
      /*     ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, */
483
 
      /*                                          &prime_q, &prime_p, */
484
 
      /*                                          r_counter, */
485
 
      /*                                          r_seed, r_seedlen, NULL); */
486
 
      gcry_sexp_release (initial_seed.sexp);
487
 
      if (ec)
488
 
        goto leave;
489
 
 
490
 
      /* Find a generator g (h and e are helpers).
491
 
         e = (p-1)/q */
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); 
497
 
      do
498
 
        {
499
 
          mpi_add_ui (value_h, value_h, 1);
500
 
          /* g = h^e mod p */
501
 
          mpi_powm (value_g, value_h, value_e, prime_p);
502
 
        } 
503
 
      while (!mpi_cmp_ui (value_g, 1));  /* Continue until g != 1.  */
504
 
    }
505
 
 
506
 
 
507
 
  /* Select a random number x with:  0 < x < q  */
508
 
  value_x = gcry_mpi_snew (qbits);
509
 
  do 
510
 
    {
511
 
      if( DBG_CIPHER )
512
 
        progress('.');
513
 
      gcry_mpi_randomize (value_x, qbits, GCRY_VERY_STRONG_RANDOM);
514
 
      mpi_clear_highbit (value_x, qbits+1);
515
 
    } 
516
 
  while (!(mpi_cmp_ui (value_x, 0) > 0 && mpi_cmp (value_x, prime_q) < 0));
517
 
 
518
 
  /* y = g^x mod p */
519
 
  value_y = mpi_alloc_like (prime_p);
520
 
  gcry_mpi_powm (value_y, value_g, value_x, prime_p);
521
 
 
522
 
  if (DBG_CIPHER) 
523
 
    {
524
 
      progress('\n');
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 );
531
 
    }
532
 
 
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;
540
 
 
541
 
 leave:
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);
549
 
 
550
 
  /* As a last step test this keys (this should never fail of course). */
551
 
  if (!ec && test_keys (sk, qbits) )
552
 
    {
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;
560
 
    }
561
 
 
562
 
  if (ec)
563
 
    {
564
 
      *r_counter = 0;
565
 
      gcry_free (*r_seed); *r_seed = NULL;
566
 
      *r_seedlen = 0;
567
 
      gcry_mpi_release (*r_h); *r_h = NULL;
568
 
    }
569
 
 
570
 
  return ec;
571
 
}
572
 
 
573
 
 
574
 
 
575
 
/*
576
 
   Test whether the secret key is valid.
577
 
   Returns: if this is a valid key.
578
 
 */
579
 
static int
580
 
check_secret_key( DSA_secret_key *sk )
581
 
{
582
 
  int rc;
583
 
  gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );
584
 
 
585
 
  gcry_mpi_powm( y, sk->g, sk->x, sk->p );
586
 
  rc = !mpi_cmp( y, sk->y );
587
 
  mpi_free( y );
588
 
  return rc;
589
 
}
590
 
 
591
 
 
592
 
 
593
 
/*
594
 
   Make a DSA signature from HASH and put it into r and s.
595
 
 */
596
 
static void
597
 
sign(gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_secret_key *skey )
598
 
{
599
 
  gcry_mpi_t k;
600
 
  gcry_mpi_t kinv;
601
 
  gcry_mpi_t tmp;
602
 
 
603
 
  /* Select a random k with 0 < k < q */
604
 
  k = gen_k( skey->q );
605
 
 
606
 
  /* r = (a^k mod p) mod q */
607
 
  gcry_mpi_powm( r, skey->g, k, skey->p );
608
 
  mpi_fdiv_r( r, r, skey->q );
609
 
 
610
 
  /* kinv = k^(-1) mod q */
611
 
  kinv = mpi_alloc( mpi_get_nlimbs(k) );
612
 
  mpi_invm(kinv, k, skey->q );
613
 
 
614
 
  /* s = (kinv * ( hash + x * r)) mod q */
615
 
  tmp = mpi_alloc( mpi_get_nlimbs(skey->p) );
616
 
  mpi_mul( tmp, skey->x, r );
617
 
  mpi_add( tmp, tmp, hash );
618
 
  mpi_mulm( s , kinv, tmp, skey->q );
619
 
 
620
 
  mpi_free(k);
621
 
  mpi_free(kinv);
622
 
  mpi_free(tmp);
623
 
}
624
 
 
625
 
 
626
 
/*
627
 
   Returns true if the signature composed from R and S is valid.
628
 
 */
629
 
static int
630
 
verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_public_key *pkey )
631
 
{
632
 
  int rc;
633
 
  gcry_mpi_t w, u1, u2, v;
634
 
  gcry_mpi_t base[3];
635
 
  gcry_mpi_t ex[3];
636
 
 
637
 
  if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
638
 
    return 0; /* assertion      0 < r < q  failed */
639
 
  if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
640
 
    return 0; /* assertion      0 < s < q  failed */
641
 
 
642
 
  w  = mpi_alloc( mpi_get_nlimbs(pkey->q) );
643
 
  u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
644
 
  u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
645
 
  v  = mpi_alloc( mpi_get_nlimbs(pkey->p) );
646
 
 
647
 
  /* w = s^(-1) mod q */
648
 
  mpi_invm( w, s, pkey->q );
649
 
 
650
 
  /* u1 = (hash * w) mod q */
651
 
  mpi_mulm( u1, hash, w, pkey->q );
652
 
 
653
 
  /* u2 = r * w mod q  */
654
 
  mpi_mulm( u2, r, w, pkey->q );
655
 
 
656
 
  /* v =  g^u1 * y^u2 mod p mod q */
657
 
  base[0] = pkey->g; ex[0] = u1;
658
 
  base[1] = pkey->y; ex[1] = u2;
659
 
  base[2] = NULL;    ex[2] = NULL;
660
 
  mpi_mulpowm( v, base, ex, pkey->p );
661
 
  mpi_fdiv_r( v, v, pkey->q );
662
 
 
663
 
  rc = !mpi_cmp( v, r );
664
 
 
665
 
  mpi_free(w);
666
 
  mpi_free(u1);
667
 
  mpi_free(u2);
668
 
  mpi_free(v);
669
 
 
670
 
  return rc;
671
 
}
672
 
 
673
 
 
674
 
/*********************************************
675
 
 **************  interface  ******************
676
 
 *********************************************/
677
 
 
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)
683
 
{
684
 
  gpg_err_code_t ec;
685
 
  DSA_secret_key sk;
686
 
  gcry_sexp_t l1;
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;
692
 
  int use_fips186 = 0;
693
 
  dsa_domain_t domain;
694
 
 
695
 
  (void)algo;    /* No need to check it.  */
696
 
  (void)evalue;  /* Not required for DSA. */
697
 
 
698
 
  memset (&domain, 0, sizeof domain);
699
 
 
700
 
  if (genparms)
701
 
    {
702
 
      gcry_sexp_t domainsexp;
703
 
  
704
 
      /* Parse the optional qbits element.  */
705
 
      l1 = gcry_sexp_find_token (genparms, "qbits", 0);
706
 
      if (l1)
707
 
        {
708
 
          char buf[50];
709
 
          const char *s;
710
 
          size_t n;
711
 
          
712
 
          s = gcry_sexp_nth_data (l1, 1, &n);
713
 
          if (!s || n >= DIM (buf) - 1 )
714
 
            {
715
 
              gcry_sexp_release (l1);
716
 
              return GPG_ERR_INV_OBJ; /* No value or value too large.  */
717
 
            }
718
 
          memcpy (buf, s, n);
719
 
          buf[n] = 0;
720
 
          qbits = (unsigned int)strtoul (buf, NULL, 0);
721
 
          gcry_sexp_release (l1);
722
 
        }
723
 
 
724
 
      /* Parse the optional transient-key flag.  */
725
 
      l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
726
 
      if (l1)
727
 
        {
728
 
          transient_key = 1;
729
 
          gcry_sexp_release (l1);
730
 
        }
731
 
 
732
 
      /* Get the optional derive parameters.  */
733
 
      deriveparms = gcry_sexp_find_token (genparms, "derive-parms", 0);
734
 
 
735
 
      /* Parse the optional "use-fips186" flags.  */
736
 
      l1 = gcry_sexp_find_token (genparms, "use-fips186", 0);
737
 
      if (l1)
738
 
        {
739
 
          use_fips186 = 1;
740
 
          gcry_sexp_release (l1);
741
 
        }
742
 
      l1 = gcry_sexp_find_token (genparms, "use-fips186-2", 0);
743
 
      if (l1)
744
 
        {
745
 
          use_fips186_2 = 1;
746
 
          gcry_sexp_release (l1);
747
 
        }
748
 
 
749
 
      /* Check whether domain parameters are given.  */
750
 
      domainsexp = gcry_sexp_find_token (genparms, "domain", 0);
751
 
      if (domainsexp)
752
 
        {
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
756
 
             parameters.  */
757
 
          if (deriveparms || qbits || nbits)
758
 
            {
759
 
              gcry_sexp_release (domainsexp);
760
 
              gcry_sexp_release (deriveparms);
761
 
              return GPG_ERR_INV_VALUE;
762
 
            }
763
 
          
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);
775
 
 
776
 
          /* Check that all domain parameters are available.  */
777
 
          if (!domain.p || !domain.q || !domain.g)
778
 
            {
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;
784
 
            }
785
 
 
786
 
          /* Get NBITS and QBITS from the domain parameters.  */
787
 
          nbits = mpi_get_nbits (domain.p);
788
 
          qbits = mpi_get_nbits (domain.q);
789
 
        }
790
 
    }
791
 
 
792
 
  if (deriveparms || use_fips186 || use_fips186_2 || fips_mode ())
793
 
    {
794
 
      int counter;
795
 
      void *seed;
796
 
      size_t seedlen;
797
 
      gcry_mpi_t h_value;
798
 
 
799
 
      ec = generate_fips186 (&sk, nbits, qbits, deriveparms, use_fips186_2,
800
 
                             &domain,
801
 
                             &counter, &seed, &seedlen, &h_value);
802
 
      gcry_sexp_release (deriveparms);
803
 
      if (!ec && h_value)
804
 
        {
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 
808
 
                             (&seedinfo, NULL,
809
 
                              "(seed-values(counter %d)(seed %b)(h %m))",
810
 
                              counter, (int)seedlen, seed, h_value));
811
 
          if (ec)
812
 
            {
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;
818
 
            }
819
 
          gcry_free (seed);
820
 
          gcry_mpi_release (h_value);
821
 
        }
822
 
    }
823
 
  else
824
 
    {
825
 
      ec = generate (&sk, nbits, qbits, transient_key, &domain, retfactors);
826
 
    }
827
 
 
828
 
  gcry_mpi_release (domain.p);
829
 
  gcry_mpi_release (domain.q);
830
 
  gcry_mpi_release (domain.g);
831
 
 
832
 
  if (!ec)
833
 
    {
834
 
      skey[0] = sk.p;
835
 
      skey[1] = sk.q;
836
 
      skey[2] = sk.g;
837
 
      skey[3] = sk.y;
838
 
      skey[4] = sk.x;
839
 
 
840
 
      if (!r_extrainfo)
841
 
        {
842
 
          /* Old style interface - return the factors - if any - at
843
 
             retfactors.  */
844
 
        }
845
 
      else if (!*retfactors && !seedinfo)
846
 
        {
847
 
          /* No factors and no seedinfo, thus there is nothing to return.  */
848
 
          *r_extrainfo = NULL;
849
 
        }
850
 
      else
851
 
        {
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
855
 
             memory.  */
856
 
          int nfactors, i, j;
857
 
          char *p;
858
 
          char *format = NULL;
859
 
          void **arg_list = NULL;
860
 
 
861
 
          for (nfactors=0; *retfactors && (*retfactors)[nfactors]; nfactors++)
862
 
            ;
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);
867
 
          if (!format)
868
 
            ec = gpg_err_code_from_syserror ();
869
 
          else
870
 
            {
871
 
              p = stpcpy (format, "(misc-key-info");
872
 
              if (seedinfo)
873
 
                p = stpcpy (p, "%S");
874
 
              if (nfactors)
875
 
                {
876
 
                  p = stpcpy (p, "(pm1-factors");
877
 
                  for (i=0; i < nfactors; i++)
878
 
                    p = stpcpy (p, "%m");
879
 
                  p = stpcpy (p, ")");
880
 
                }
881
 
              p = stpcpy (p, ")");
882
 
              
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);
887
 
              if (!arg_list)
888
 
                ec = gpg_err_code_from_syserror ();
889
 
              else
890
 
                {
891
 
                  i = 0;
892
 
                  if (seedinfo)
893
 
                    arg_list[i++] = &seedinfo;
894
 
                  for (j=0; j < nfactors; j++)
895
 
                    arg_list[i++] = (*retfactors) + j;
896
 
                  arg_list[i] = NULL;
897
 
                  
898
 
                  ec = gpg_err_code (gcry_sexp_build_array 
899
 
                                     (r_extrainfo, NULL, format, arg_list));
900
 
                }
901
 
            }
902
 
 
903
 
          gcry_free (arg_list);
904
 
          gcry_free (format);
905
 
          for (i=0; i < nfactors; i++)
906
 
            {
907
 
              gcry_mpi_release ((*retfactors)[i]);
908
 
              (*retfactors)[i] = NULL;
909
 
            }
910
 
          *retfactors = NULL;
911
 
          if (ec)
912
 
            {
913
 
              for (i=0; i < 5; i++)
914
 
                {
915
 
                  gcry_mpi_release (skey[i]);
916
 
                  skey[i] = NULL;
917
 
                }
918
 
            }
919
 
        }
920
 
    }
921
 
 
922
 
  gcry_sexp_release (seedinfo);
923
 
  return ec;
924
 
}
925
 
 
926
 
 
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)
930
 
{
931
 
  (void)evalue;
932
 
  return dsa_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
933
 
}
934
 
 
935
 
 
936
 
 
937
 
static gcry_err_code_t
938
 
dsa_check_secret_key (int algo, gcry_mpi_t *skey)
939
 
{
940
 
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
941
 
  DSA_secret_key sk;
942
 
 
943
 
  (void)algo;
944
 
 
945
 
  if ((! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]) || (! skey[4]))
946
 
    err = GPG_ERR_BAD_MPI;
947
 
  else
948
 
    {
949
 
      sk.p = skey[0];
950
 
      sk.q = skey[1];
951
 
      sk.g = skey[2];
952
 
      sk.y = skey[3];
953
 
      sk.x = skey[4];
954
 
      if (! check_secret_key (&sk))
955
 
        err = GPG_ERR_BAD_SECKEY;
956
 
    }
957
 
 
958
 
  return err;
959
 
}
960
 
 
961
 
 
962
 
static gcry_err_code_t
963
 
dsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
964
 
{
965
 
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
966
 
  DSA_secret_key sk;
967
 
 
968
 
  (void)algo;
969
 
 
970
 
  if ((! data)
971
 
      || (! skey[0]) || (! skey[1]) || (! skey[2])
972
 
      || (! skey[3]) || (! skey[4]))
973
 
    err = GPG_ERR_BAD_MPI;
974
 
  else
975
 
    {
976
 
      sk.p = skey[0];
977
 
      sk.q = skey[1];
978
 
      sk.g = skey[2];
979
 
      sk.y = skey[3];
980
 
      sk.x = skey[4];
981
 
      resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.p));
982
 
      resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p));
983
 
      sign (resarr[0], resarr[1], data, &sk);
984
 
    }
985
 
  return err;
986
 
}
987
 
 
988
 
static gcry_err_code_t
989
 
dsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
990
 
            int (*cmp) (void *, gcry_mpi_t), void *opaquev)
991
 
{
992
 
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
993
 
  DSA_public_key pk;
994
 
 
995
 
  (void)algo;
996
 
  (void)cmp;
997
 
  (void)opaquev;
998
 
 
999
 
  if ((! data[0]) || (! data[1]) || (! hash)
1000
 
      || (! pkey[0]) || (! pkey[1]) || (! pkey[2]) || (! pkey[3]))
1001
 
    err = GPG_ERR_BAD_MPI;
1002
 
  else
1003
 
    {
1004
 
      pk.p = pkey[0];
1005
 
      pk.q = pkey[1];
1006
 
      pk.g = pkey[2];
1007
 
      pk.y = pkey[3];
1008
 
      if (! verify (data[0], data[1], hash, &pk))
1009
 
        err = GPG_ERR_BAD_SIGNATURE;
1010
 
    }
1011
 
  return err;
1012
 
}
1013
 
 
1014
 
 
1015
 
static unsigned int
1016
 
dsa_get_nbits (int algo, gcry_mpi_t *pkey)
1017
 
{
1018
 
  (void)algo;
1019
 
 
1020
 
  return mpi_get_nbits (pkey[0]);
1021
 
}
1022
 
 
1023
 
 
1024
 
 
1025
 
/* 
1026
 
     Self-test section.
1027
 
 */
1028
 
 
1029
 
static const char *
1030
 
selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
1031
 
{
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#))";
1038
 
 
1039
 
  const char *errtxt = NULL;
1040
 
  gcry_error_t err;
1041
 
  gcry_sexp_t data = NULL;
1042
 
  gcry_sexp_t data_bad = NULL;
1043
 
  gcry_sexp_t sig = NULL;
1044
 
 
1045
 
  err = gcry_sexp_sscan (&data, NULL,
1046
 
                         sample_data, strlen (sample_data));
1047
 
  if (!err)
1048
 
    err = gcry_sexp_sscan (&data_bad, NULL, 
1049
 
                           sample_data_bad, strlen (sample_data_bad));
1050
 
  if (err)
1051
 
    {
1052
 
      errtxt = "converting data failed";
1053
 
      goto leave;
1054
 
    }
1055
 
 
1056
 
  err = gcry_pk_sign (&sig, data, skey);
1057
 
  if (err)
1058
 
    {
1059
 
      errtxt = "signing failed";
1060
 
      goto leave;
1061
 
    }
1062
 
  err = gcry_pk_verify (sig, data, pkey);
1063
 
  if (err)
1064
 
    {
1065
 
      errtxt = "verify failed";
1066
 
      goto leave;
1067
 
    }
1068
 
  err = gcry_pk_verify (sig, data_bad, pkey);
1069
 
  if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
1070
 
    {
1071
 
      errtxt = "bad signature not detected";
1072
 
      goto leave;
1073
 
    }
1074
 
 
1075
 
 
1076
 
 leave:
1077
 
  gcry_sexp_release (sig);
1078
 
  gcry_sexp_release (data_bad);
1079
 
  gcry_sexp_release (data);
1080
 
  return errtxt;
1081
 
}
1082
 
 
1083
 
 
1084
 
static gpg_err_code_t
1085
 
selftests_dsa (selftest_report_func_t report)
1086
 
{
1087
 
  const char *what;
1088
 
  const char *errtxt;
1089
 
  gcry_error_t err;
1090
 
  gcry_sexp_t skey = NULL;
1091
 
  gcry_sexp_t pkey = NULL;
1092
 
 
1093
 
  /* Convert the S-expressions into the internal representation.  */
1094
 
  what = "convert";
1095
 
  err = gcry_sexp_sscan (&skey, NULL, 
1096
 
                         sample_secret_key, strlen (sample_secret_key));
1097
 
  if (!err)
1098
 
    err = gcry_sexp_sscan (&pkey, NULL, 
1099
 
                           sample_public_key, strlen (sample_public_key));
1100
 
  if (err)
1101
 
    {
1102
 
      errtxt = gcry_strerror (err);
1103
 
      goto failed;
1104
 
    }
1105
 
 
1106
 
  what = "key consistency";
1107
 
  err = gcry_pk_testkey (skey);
1108
 
  if (err)
1109
 
    {
1110
 
      errtxt = gcry_strerror (err);
1111
 
      goto failed;
1112
 
    }
1113
 
 
1114
 
  what = "sign";
1115
 
  errtxt = selftest_sign_1024 (pkey, skey);
1116
 
  if (errtxt)
1117
 
    goto failed;
1118
 
 
1119
 
  gcry_sexp_release (pkey);
1120
 
  gcry_sexp_release (skey);
1121
 
  return 0; /* Succeeded. */
1122
 
 
1123
 
 failed:
1124
 
  gcry_sexp_release (pkey);
1125
 
  gcry_sexp_release (skey);
1126
 
  if (report)
1127
 
    report ("pubkey", GCRY_PK_DSA, what, errtxt);
1128
 
  return GPG_ERR_SELFTEST_FAILED;
1129
 
}
1130
 
 
1131
 
 
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)
1135
 
{
1136
 
  gpg_err_code_t ec;
1137
 
 
1138
 
  (void)extended;
1139
 
 
1140
 
  switch (algo)
1141
 
    {
1142
 
    case GCRY_PK_DSA:
1143
 
      ec = selftests_dsa (report);
1144
 
      break;
1145
 
    default:
1146
 
      ec = GPG_ERR_PUBKEY_ALGO;
1147
 
      break;
1148
 
        
1149
 
    }
1150
 
  return ec;
1151
 
}
1152
 
 
1153
 
 
1154
 
 
1155
 
 
1156
 
static const char *dsa_names[] =
1157
 
  {
1158
 
    "dsa",
1159
 
    "openpgp-dsa",
1160
 
    NULL,
1161
 
  };
1162
 
 
1163
 
gcry_pk_spec_t _gcry_pubkey_spec_dsa =
1164
 
  {
1165
 
    "DSA", dsa_names, 
1166
 
    "pqgy", "pqgyx", "", "rs", "pqgy",
1167
 
    GCRY_PK_USAGE_SIGN,
1168
 
    dsa_generate,
1169
 
    dsa_check_secret_key,
1170
 
    NULL,
1171
 
    NULL,
1172
 
    dsa_sign,
1173
 
    dsa_verify,
1174
 
    dsa_get_nbits
1175
 
  };
1176
 
pk_extra_spec_t _gcry_pubkey_extraspec_dsa = 
1177
 
  {
1178
 
    run_selftests,
1179
 
    dsa_generate_ext
1180
 
  };
1181