Line data Source code
1 : /* dsa.c - DSA signature algorithm
2 : * Copyright (C) 1998, 2000, 2001, 2002, 2003,
3 : * 2006, 2008 Free Software Foundation, Inc.
4 : * Copyright (C) 2013 g10 Code GmbH.
5 : *
6 : * This file is part of Libgcrypt.
7 : *
8 : * Libgcrypt is free software; you can redistribute it and/or modify
9 : * it under the terms of the GNU Lesser General Public License as
10 : * published by the Free Software Foundation; either version 2.1 of
11 : * the License, or (at your option) any later version.
12 : *
13 : * Libgcrypt is distributed in the hope that it will be useful,
14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : * GNU Lesser General Public License for more details.
17 : *
18 : * You should have received a copy of the GNU Lesser General Public
19 : * License along with this program; if not, see <http://www.gnu.org/licenses/>.
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 : #include "pubkey-internal.h"
31 :
32 :
33 : typedef struct
34 : {
35 : gcry_mpi_t p; /* prime */
36 : gcry_mpi_t q; /* group order */
37 : gcry_mpi_t g; /* group generator */
38 : gcry_mpi_t y; /* g^x mod p */
39 : } DSA_public_key;
40 :
41 :
42 : typedef struct
43 : {
44 : gcry_mpi_t p; /* prime */
45 : gcry_mpi_t q; /* group order */
46 : gcry_mpi_t g; /* group generator */
47 : gcry_mpi_t y; /* g^x mod p */
48 : gcry_mpi_t x; /* secret exponent */
49 : } DSA_secret_key;
50 :
51 :
52 : /* A structure used to hold domain parameters. */
53 : typedef struct
54 : {
55 : gcry_mpi_t p; /* prime */
56 : gcry_mpi_t q; /* group order */
57 : gcry_mpi_t g; /* group generator */
58 : } dsa_domain_t;
59 :
60 :
61 : static const char *dsa_names[] =
62 : {
63 : "dsa",
64 : "openpgp-dsa",
65 : NULL,
66 : };
67 :
68 :
69 : /* A sample 1024 bit DSA key used for the selftests. Not anymore
70 : * used, kept only for reference. */
71 : #if 0
72 : static const char sample_secret_key_1024[] =
73 : "(private-key"
74 : " (dsa"
75 : " (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
76 : " 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
77 : " CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
78 : " 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)"
79 : " (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)"
80 : " (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
81 : " AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
82 : " B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
83 : " 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)"
84 : " (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
85 : " A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
86 : " 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
87 : " 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)"
88 : " (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))";
89 : /* A sample 1024 bit DSA key used for the selftests (public only). */
90 : static const char sample_public_key_1024[] =
91 : "(public-key"
92 : " (dsa"
93 : " (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
94 : " 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
95 : " CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
96 : " 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)"
97 : " (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)"
98 : " (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
99 : " AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
100 : " B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
101 : " 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)"
102 : " (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
103 : " A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
104 : " 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
105 : " 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))";
106 : #endif /*0*/
107 :
108 : /* 2048 DSA key from RFC 6979 A.2.2 */
109 : static const char sample_public_key_2048[] =
110 : "(public-key"
111 : " (dsa"
112 : " (p #9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44FFE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE235567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA153E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B#)"
113 : " (q #F2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F#)"
114 : " (g #5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C46A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7#)"
115 : " (y #667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF#)))";
116 :
117 : static const char sample_secret_key_2048[] =
118 : "(private-key"
119 : " (dsa"
120 : " (p #9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44FFE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE235567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA153E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B#)"
121 : " (q #F2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F#)"
122 : " (g #5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C46A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7#)"
123 : " (y #667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF#)"
124 : " (x #69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC#)))";
125 :
126 :
127 :
128 : static int test_keys (DSA_secret_key *sk, unsigned int qbits);
129 : static int check_secret_key (DSA_secret_key *sk);
130 : static gpg_err_code_t generate (DSA_secret_key *sk,
131 : unsigned int nbits,
132 : unsigned int qbits,
133 : int transient_key,
134 : dsa_domain_t *domain,
135 : gcry_mpi_t **ret_factors);
136 : static gpg_err_code_t sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
137 : DSA_secret_key *skey, int flags, int hashalgo);
138 : static gpg_err_code_t verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
139 : DSA_public_key *pkey);
140 : static unsigned int dsa_get_nbits (gcry_sexp_t parms);
141 :
142 :
143 : static void (*progress_cb) (void *,const char *, int, int, int );
144 : static void *progress_cb_data;
145 :
146 :
147 : void
148 1 : _gcry_register_pk_dsa_progress (void (*cb) (void *, const char *,
149 : int, int, int),
150 : void *cb_data)
151 : {
152 1 : progress_cb = cb;
153 1 : progress_cb_data = cb_data;
154 1 : }
155 :
156 :
157 : static void
158 0 : progress (int c)
159 : {
160 0 : if (progress_cb)
161 0 : progress_cb (progress_cb_data, "pk_dsa", c, 0, 0);
162 0 : }
163 :
164 :
165 : /* Check that a freshly generated key actually works. Returns 0 on success. */
166 : static int
167 29 : test_keys (DSA_secret_key *sk, unsigned int qbits)
168 : {
169 29 : int result = -1; /* Default to failure. */
170 : DSA_public_key pk;
171 29 : gcry_mpi_t data = mpi_new (qbits);
172 29 : gcry_mpi_t sig_a = mpi_new (qbits);
173 29 : gcry_mpi_t sig_b = mpi_new (qbits);
174 :
175 : /* Put the relevant parameters into a public key structure. */
176 29 : pk.p = sk->p;
177 29 : pk.q = sk->q;
178 29 : pk.g = sk->g;
179 29 : pk.y = sk->y;
180 :
181 : /* Create a random plaintext. */
182 29 : _gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM);
183 :
184 : /* Sign DATA using the secret key. */
185 29 : sign (sig_a, sig_b, data, sk, 0, 0);
186 :
187 : /* Verify the signature using the public key. */
188 29 : if ( verify (sig_a, sig_b, data, &pk) )
189 0 : goto leave; /* Signature does not match. */
190 :
191 : /* Modify the data and check that the signing fails. */
192 29 : mpi_add_ui (data, data, 1);
193 29 : if ( !verify (sig_a, sig_b, data, &pk) )
194 0 : goto leave; /* Signature matches but should not. */
195 :
196 29 : result = 0; /* The test succeeded. */
197 :
198 : leave:
199 29 : _gcry_mpi_release (sig_b);
200 29 : _gcry_mpi_release (sig_a);
201 29 : _gcry_mpi_release (data);
202 29 : return result;
203 : }
204 :
205 :
206 :
207 : /*
208 : Generate a DSA key pair with a key of size NBITS. If transient_key
209 : is true the key is generated using the standard RNG and not the
210 : very secure one.
211 :
212 : Returns: 2 structures filled with all needed values
213 : and an array with the n-1 factors of (p-1)
214 : */
215 : static gpg_err_code_t
216 15 : generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
217 : int transient_key, dsa_domain_t *domain, gcry_mpi_t **ret_factors )
218 : {
219 : gpg_err_code_t rc;
220 : gcry_mpi_t p; /* the prime */
221 : gcry_mpi_t q; /* the 160 bit prime factor */
222 : gcry_mpi_t g; /* the generator */
223 : gcry_mpi_t y; /* g^x mod p */
224 : gcry_mpi_t x; /* the secret exponent */
225 : gcry_mpi_t h, e; /* helper */
226 : unsigned char *rndbuf;
227 : gcry_random_level_t random_level;
228 :
229 15 : if (qbits)
230 : ; /* Caller supplied qbits. Use this value. */
231 9 : else if ( nbits >= 512 && nbits <= 1024 )
232 5 : qbits = 160;
233 4 : else if ( nbits == 2048 )
234 4 : qbits = 224;
235 0 : else if ( nbits == 3072 )
236 0 : qbits = 256;
237 0 : else if ( nbits == 7680 )
238 0 : qbits = 384;
239 0 : else if ( nbits == 15360 )
240 0 : qbits = 512;
241 : else
242 0 : return GPG_ERR_INV_VALUE;
243 :
244 15 : if (qbits < 160 || qbits > 512 || (qbits%8) )
245 0 : return GPG_ERR_INV_VALUE;
246 15 : if (nbits < 2*qbits || nbits > 15360)
247 0 : return GPG_ERR_INV_VALUE;
248 :
249 15 : if (fips_mode ())
250 : {
251 0 : if (nbits < 1024)
252 0 : return GPG_ERR_INV_VALUE;
253 0 : if (transient_key)
254 0 : return GPG_ERR_INV_VALUE;
255 : }
256 :
257 15 : if (domain->p && domain->q && domain->g)
258 : {
259 : /* Domain parameters are given; use them. */
260 2 : p = mpi_copy (domain->p);
261 2 : q = mpi_copy (domain->q);
262 2 : g = mpi_copy (domain->g);
263 2 : gcry_assert (mpi_get_nbits (p) == nbits);
264 2 : gcry_assert (mpi_get_nbits (q) == qbits);
265 2 : h = mpi_alloc (0);
266 2 : e = NULL;
267 : }
268 : else
269 : {
270 : /* Generate new domain parameters. */
271 13 : rc = _gcry_generate_elg_prime (1, nbits, qbits, NULL, &p, ret_factors);
272 13 : if (rc)
273 0 : return rc;
274 :
275 : /* Get q out of factors. */
276 13 : q = mpi_copy ((*ret_factors)[0]);
277 13 : gcry_assert (mpi_get_nbits (q) == qbits);
278 :
279 : /* Find a generator g (h and e are helpers).
280 : e = (p-1)/q */
281 13 : e = mpi_alloc (mpi_get_nlimbs (p));
282 13 : mpi_sub_ui (e, p, 1);
283 13 : mpi_fdiv_q (e, e, q);
284 13 : g = mpi_alloc (mpi_get_nlimbs (p));
285 13 : h = mpi_alloc_set_ui (1); /* (We start with 2.) */
286 : do
287 : {
288 13 : mpi_add_ui (h, h, 1);
289 : /* g = h^e mod p */
290 13 : mpi_powm (g, h, e, p);
291 : }
292 13 : while (!mpi_cmp_ui (g, 1)); /* Continue until g != 1. */
293 : }
294 :
295 : /* Select a random number X with the property:
296 : * 0 < x < q-1
297 : *
298 : * FIXME: Why do we use the requirement x < q-1 ? It should be
299 : * sufficient to test for x < q. FIPS-186-3 check x < q-1 but it
300 : * does not check for 0 < x because it makes sure that Q is unsigned
301 : * and finally adds one to the result so that 0 will never be
302 : * returned. We should replace the code below with _gcry_dsa_gen_k.
303 : *
304 : * This must be a very good random number because this is the secret
305 : * part. The random quality depends on the transient_key flag. */
306 15 : random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
307 15 : if (DBG_CIPHER)
308 0 : log_debug("choosing a random x%s\n", transient_key? " (transient-key)":"");
309 15 : gcry_assert( qbits >= 160 );
310 15 : x = mpi_alloc_secure( mpi_get_nlimbs(q) );
311 15 : mpi_sub_ui( h, q, 1 ); /* put q-1 into h */
312 15 : rndbuf = NULL;
313 : do
314 : {
315 20 : if( DBG_CIPHER )
316 0 : progress('.');
317 20 : if( !rndbuf )
318 15 : rndbuf = _gcry_random_bytes_secure ((qbits+7)/8, random_level);
319 : else
320 : { /* Change only some of the higher bits (= 2 bytes)*/
321 5 : char *r = _gcry_random_bytes_secure (2, random_level);
322 5 : memcpy(rndbuf, r, 2 );
323 5 : xfree(r);
324 : }
325 :
326 20 : _gcry_mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
327 20 : mpi_clear_highbit( x, qbits+1 );
328 : }
329 20 : while ( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
330 15 : xfree(rndbuf);
331 15 : mpi_free( e );
332 15 : mpi_free( h );
333 :
334 : /* y = g^x mod p */
335 15 : y = mpi_alloc( mpi_get_nlimbs(p) );
336 15 : mpi_powm (y, g, x, p);
337 :
338 15 : if( DBG_CIPHER )
339 : {
340 0 : progress('\n');
341 0 : log_mpidump("dsa p", p );
342 0 : log_mpidump("dsa q", q );
343 0 : log_mpidump("dsa g", g );
344 0 : log_mpidump("dsa y", y );
345 0 : log_mpidump("dsa x", x );
346 : }
347 :
348 : /* Copy the stuff to the key structures. */
349 15 : sk->p = p;
350 15 : sk->q = q;
351 15 : sk->g = g;
352 15 : sk->y = y;
353 15 : sk->x = x;
354 :
355 : /* Now we can test our keys (this should never fail!). */
356 15 : if ( test_keys (sk, qbits) )
357 : {
358 0 : _gcry_mpi_release (sk->p); sk->p = NULL;
359 0 : _gcry_mpi_release (sk->q); sk->q = NULL;
360 0 : _gcry_mpi_release (sk->g); sk->g = NULL;
361 0 : _gcry_mpi_release (sk->y); sk->y = NULL;
362 0 : _gcry_mpi_release (sk->x); sk->x = NULL;
363 0 : fips_signal_error ("self-test after key generation failed");
364 0 : return GPG_ERR_SELFTEST_FAILED;
365 : }
366 15 : return 0;
367 : }
368 :
369 :
370 : /* Generate a DSA key pair with a key of size NBITS using the
371 : algorithm given in FIPS-186-3. If USE_FIPS186_2 is true,
372 : FIPS-186-2 is used and thus the length is restricted to 1024/160.
373 : If DERIVEPARMS is not NULL it may contain a seed value. If domain
374 : parameters are specified in DOMAIN, DERIVEPARMS may not be given
375 : and NBITS and QBITS must match the specified domain parameters. */
376 : static gpg_err_code_t
377 14 : generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
378 : gcry_sexp_t deriveparms, int use_fips186_2,
379 : dsa_domain_t *domain,
380 : int *r_counter, void **r_seed, size_t *r_seedlen,
381 : gcry_mpi_t *r_h)
382 : {
383 : gpg_err_code_t ec;
384 : struct {
385 : gcry_sexp_t sexp;
386 : const void *seed;
387 : size_t seedlen;
388 14 : } initial_seed = { NULL, NULL, 0 };
389 14 : gcry_mpi_t prime_q = NULL;
390 14 : gcry_mpi_t prime_p = NULL;
391 14 : gcry_mpi_t value_g = NULL; /* The generator. */
392 14 : gcry_mpi_t value_y = NULL; /* g^x mod p */
393 14 : gcry_mpi_t value_x = NULL; /* The secret exponent. */
394 14 : gcry_mpi_t value_h = NULL; /* Helper. */
395 14 : gcry_mpi_t value_e = NULL; /* Helper. */
396 14 : gcry_mpi_t value_c = NULL; /* helper for x */
397 14 : gcry_mpi_t value_qm2 = NULL; /* q - 2 */
398 :
399 : /* Preset return values. */
400 14 : *r_counter = 0;
401 14 : *r_seed = NULL;
402 14 : *r_seedlen = 0;
403 14 : *r_h = NULL;
404 :
405 : /* Derive QBITS from NBITS if requested */
406 14 : if (!qbits)
407 : {
408 14 : if (nbits == 1024)
409 10 : qbits = 160;
410 4 : else if (nbits == 2048)
411 4 : qbits = 224;
412 0 : else if (nbits == 3072)
413 0 : qbits = 256;
414 : }
415 :
416 : /* Check that QBITS and NBITS match the standard. Note that FIPS
417 : 186-3 uses N for QBITS and L for NBITS. */
418 14 : if (nbits == 1024 && qbits == 160 && use_fips186_2)
419 : ; /* Allowed in FIPS 186-2 mode. */
420 4 : else if (nbits == 2048 && qbits == 224)
421 : ;
422 0 : else if (nbits == 2048 && qbits == 256)
423 : ;
424 0 : else if (nbits == 3072 && qbits == 256)
425 : ;
426 : else
427 0 : return GPG_ERR_INV_VALUE;
428 :
429 14 : if (domain->p && domain->q && domain->g)
430 : {
431 : /* Domain parameters are given; use them. */
432 0 : prime_p = mpi_copy (domain->p);
433 0 : prime_q = mpi_copy (domain->q);
434 0 : value_g = mpi_copy (domain->g);
435 0 : gcry_assert (mpi_get_nbits (prime_p) == nbits);
436 0 : gcry_assert (mpi_get_nbits (prime_q) == qbits);
437 0 : gcry_assert (!deriveparms);
438 0 : ec = 0;
439 : }
440 : else
441 : {
442 : /* Generate new domain parameters. */
443 :
444 : /* Get an initial seed value. */
445 14 : if (deriveparms)
446 : {
447 12 : initial_seed.sexp = sexp_find_token (deriveparms, "seed", 0);
448 12 : if (initial_seed.sexp)
449 12 : initial_seed.seed = sexp_nth_data (initial_seed.sexp, 1,
450 : &initial_seed.seedlen);
451 : }
452 :
453 14 : if (use_fips186_2)
454 10 : ec = _gcry_generate_fips186_2_prime (nbits, qbits,
455 : initial_seed.seed,
456 : initial_seed.seedlen,
457 : &prime_q, &prime_p,
458 : r_counter,
459 : r_seed, r_seedlen);
460 : else
461 4 : ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0,
462 : &prime_q, &prime_p,
463 : r_counter,
464 : r_seed, r_seedlen, NULL);
465 14 : sexp_release (initial_seed.sexp);
466 14 : if (ec)
467 0 : goto leave;
468 :
469 : /* Find a generator g (h and e are helpers).
470 : * e = (p-1)/q
471 : */
472 14 : value_e = mpi_alloc_like (prime_p);
473 14 : mpi_sub_ui (value_e, prime_p, 1);
474 14 : mpi_fdiv_q (value_e, value_e, prime_q );
475 14 : value_g = mpi_alloc_like (prime_p);
476 14 : value_h = mpi_alloc_set_ui (1);
477 : do
478 : {
479 14 : mpi_add_ui (value_h, value_h, 1);
480 : /* g = h^e mod p */
481 14 : mpi_powm (value_g, value_h, value_e, prime_p);
482 : }
483 14 : while (!mpi_cmp_ui (value_g, 1)); /* Continue until g != 1. */
484 : }
485 :
486 14 : value_c = mpi_snew (qbits);
487 14 : value_x = mpi_snew (qbits);
488 14 : value_qm2 = mpi_snew (qbits);
489 14 : mpi_sub_ui (value_qm2, prime_q, 2);
490 :
491 : /* FIPS 186-4 B.1.2 steps 4-6 */
492 : do
493 : {
494 16 : if( DBG_CIPHER )
495 0 : progress('.');
496 16 : _gcry_mpi_randomize (value_c, qbits, GCRY_VERY_STRONG_RANDOM);
497 16 : mpi_clear_highbit (value_c, qbits+1);
498 : }
499 16 : while (!(mpi_cmp_ui (value_c, 0) > 0 && mpi_cmp (value_c, value_qm2) < 0));
500 : /* while (mpi_cmp (value_c, value_qm2) > 0); */
501 :
502 : /* x = c + 1 */
503 14 : mpi_add_ui(value_x, value_c, 1);
504 :
505 : /* y = g^x mod p */
506 14 : value_y = mpi_alloc_like (prime_p);
507 14 : mpi_powm (value_y, value_g, value_x, prime_p);
508 :
509 14 : if (DBG_CIPHER)
510 : {
511 0 : progress('\n');
512 0 : log_mpidump("dsa p", prime_p );
513 0 : log_mpidump("dsa q", prime_q );
514 0 : log_mpidump("dsa g", value_g );
515 0 : log_mpidump("dsa y", value_y );
516 0 : log_mpidump("dsa x", value_x );
517 0 : log_mpidump("dsa h", value_h );
518 : }
519 :
520 : /* Copy the stuff to the key structures. */
521 14 : sk->p = prime_p; prime_p = NULL;
522 14 : sk->q = prime_q; prime_q = NULL;
523 14 : sk->g = value_g; value_g = NULL;
524 14 : sk->y = value_y; value_y = NULL;
525 14 : sk->x = value_x; value_x = NULL;
526 14 : *r_h = value_h; value_h = NULL;
527 :
528 : leave:
529 14 : _gcry_mpi_release (prime_p);
530 14 : _gcry_mpi_release (prime_q);
531 14 : _gcry_mpi_release (value_g);
532 14 : _gcry_mpi_release (value_y);
533 14 : _gcry_mpi_release (value_x);
534 14 : _gcry_mpi_release (value_h);
535 14 : _gcry_mpi_release (value_e);
536 14 : _gcry_mpi_release (value_c);
537 14 : _gcry_mpi_release (value_qm2);
538 :
539 : /* As a last step test this keys (this should never fail of course). */
540 14 : if (!ec && test_keys (sk, qbits) )
541 : {
542 0 : _gcry_mpi_release (sk->p); sk->p = NULL;
543 0 : _gcry_mpi_release (sk->q); sk->q = NULL;
544 0 : _gcry_mpi_release (sk->g); sk->g = NULL;
545 0 : _gcry_mpi_release (sk->y); sk->y = NULL;
546 0 : _gcry_mpi_release (sk->x); sk->x = NULL;
547 0 : fips_signal_error ("self-test after key generation failed");
548 0 : ec = GPG_ERR_SELFTEST_FAILED;
549 : }
550 :
551 14 : if (ec)
552 : {
553 0 : *r_counter = 0;
554 0 : xfree (*r_seed); *r_seed = NULL;
555 0 : *r_seedlen = 0;
556 0 : _gcry_mpi_release (*r_h); *r_h = NULL;
557 : }
558 :
559 14 : return ec;
560 : }
561 :
562 :
563 :
564 : /*
565 : Test whether the secret key is valid.
566 : Returns: if this is a valid key.
567 : */
568 : static int
569 2 : check_secret_key( DSA_secret_key *sk )
570 : {
571 : int rc;
572 2 : gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );
573 :
574 2 : mpi_powm( y, sk->g, sk->x, sk->p );
575 2 : rc = !mpi_cmp( y, sk->y );
576 2 : mpi_free( y );
577 2 : return rc;
578 : }
579 :
580 :
581 :
582 : /*
583 : Make a DSA signature from INPUT and put it into r and s.
584 :
585 : INPUT may either be a plain MPI or an opaque MPI which is then
586 : internally converted to a plain MPI. FLAGS and HASHALGO may both
587 : be 0 for standard operation mode.
588 :
589 : The return value is 0 on success or an error code. Note that for
590 : backward compatibility the function will not return any error if
591 : FLAGS and HASHALGO are both 0 and INPUT is a plain MPI.
592 : */
593 : static gpg_err_code_t
594 87 : sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, DSA_secret_key *skey,
595 : int flags, int hashalgo)
596 : {
597 : gpg_err_code_t rc;
598 : gcry_mpi_t hash;
599 : gcry_mpi_t k;
600 : gcry_mpi_t kinv;
601 : gcry_mpi_t tmp;
602 : const void *abuf;
603 : unsigned int abits, qbits;
604 87 : int extraloops = 0;
605 :
606 87 : qbits = mpi_get_nbits (skey->q);
607 :
608 : /* Convert the INPUT into an MPI. */
609 87 : rc = _gcry_dsa_normalize_hash (input, &hash, qbits);
610 87 : if (rc)
611 0 : return rc;
612 :
613 : again:
614 : /* Create the K value. */
615 87 : if ((flags & PUBKEY_FLAG_RFC6979) && hashalgo)
616 : {
617 : /* Use Pornin's method for deterministic DSA. If this flag is
618 : set, it is expected that HASH is an opaque MPI with the to be
619 : signed hash. That hash is also used as h1 from 3.2.a. */
620 22 : if (!mpi_is_opaque (input))
621 : {
622 0 : rc = GPG_ERR_CONFLICT;
623 0 : goto leave;
624 : }
625 :
626 22 : abuf = mpi_get_opaque (input, &abits);
627 44 : rc = _gcry_dsa_gen_rfc6979_k (&k, skey->q, skey->x,
628 22 : abuf, (abits+7)/8, hashalgo, extraloops);
629 44 : if (rc)
630 0 : goto leave;
631 : }
632 : else
633 : {
634 : /* Select a random k with 0 < k < q */
635 65 : k = _gcry_dsa_gen_k (skey->q, GCRY_STRONG_RANDOM);
636 : }
637 :
638 : /* r = (a^k mod p) mod q */
639 87 : mpi_powm( r, skey->g, k, skey->p );
640 87 : mpi_fdiv_r( r, r, skey->q );
641 :
642 : /* kinv = k^(-1) mod q */
643 87 : kinv = mpi_alloc( mpi_get_nlimbs(k) );
644 87 : mpi_invm(kinv, k, skey->q );
645 :
646 : /* s = (kinv * ( hash + x * r)) mod q */
647 87 : tmp = mpi_alloc( mpi_get_nlimbs(skey->p) );
648 87 : mpi_mul( tmp, skey->x, r );
649 87 : mpi_add( tmp, tmp, hash );
650 87 : mpi_mulm( s , kinv, tmp, skey->q );
651 :
652 87 : mpi_free(k);
653 87 : mpi_free(kinv);
654 87 : mpi_free(tmp);
655 :
656 87 : if (!mpi_cmp_ui (r, 0))
657 : {
658 : /* This is a highly unlikely code path. */
659 0 : extraloops++;
660 0 : goto again;
661 : }
662 :
663 87 : rc = 0;
664 :
665 : leave:
666 87 : if (hash != input)
667 22 : mpi_free (hash);
668 :
669 87 : return rc;
670 : }
671 :
672 :
673 : /*
674 : Returns true if the signature composed from R and S is valid.
675 : */
676 : static gpg_err_code_t
677 124 : verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, DSA_public_key *pkey )
678 : {
679 124 : gpg_err_code_t rc = 0;
680 : gcry_mpi_t w, u1, u2, v;
681 : gcry_mpi_t base[3];
682 : gcry_mpi_t ex[3];
683 : gcry_mpi_t hash;
684 : unsigned int nbits;
685 :
686 124 : if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
687 0 : return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < r < n failed. */
688 124 : if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
689 0 : return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n failed. */
690 :
691 124 : nbits = mpi_get_nbits (pkey->q);
692 124 : rc = _gcry_dsa_normalize_hash (input, &hash, nbits);
693 124 : if (rc)
694 0 : return rc;
695 :
696 124 : w = mpi_alloc( mpi_get_nlimbs(pkey->q) );
697 124 : u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
698 124 : u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
699 124 : v = mpi_alloc( mpi_get_nlimbs(pkey->p) );
700 :
701 : /* w = s^(-1) mod q */
702 124 : mpi_invm( w, s, pkey->q );
703 :
704 : /* u1 = (hash * w) mod q */
705 124 : mpi_mulm( u1, hash, w, pkey->q );
706 :
707 : /* u2 = r * w mod q */
708 124 : mpi_mulm( u2, r, w, pkey->q );
709 :
710 : /* v = g^u1 * y^u2 mod p mod q */
711 124 : base[0] = pkey->g; ex[0] = u1;
712 124 : base[1] = pkey->y; ex[1] = u2;
713 124 : base[2] = NULL; ex[2] = NULL;
714 124 : mpi_mulpowm( v, base, ex, pkey->p );
715 124 : mpi_fdiv_r( v, v, pkey->q );
716 :
717 124 : if (mpi_cmp( v, r ))
718 : {
719 37 : if (DBG_CIPHER)
720 : {
721 0 : log_mpidump (" i", input);
722 0 : log_mpidump (" h", hash);
723 0 : log_mpidump (" v", v);
724 0 : log_mpidump (" r", r);
725 0 : log_mpidump (" s", s);
726 : }
727 37 : rc = GPG_ERR_BAD_SIGNATURE;
728 : }
729 :
730 124 : mpi_free(w);
731 124 : mpi_free(u1);
732 124 : mpi_free(u2);
733 124 : mpi_free(v);
734 124 : if (hash != input)
735 24 : mpi_free (hash);
736 :
737 124 : return rc;
738 : }
739 :
740 :
741 : /*********************************************
742 : ************** interface ******************
743 : *********************************************/
744 :
745 : static gcry_err_code_t
746 29 : dsa_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
747 : {
748 : gpg_err_code_t rc;
749 : unsigned int nbits;
750 : gcry_sexp_t domainsexp;
751 : DSA_secret_key sk;
752 : gcry_sexp_t l1;
753 29 : unsigned int qbits = 0;
754 29 : gcry_sexp_t deriveparms = NULL;
755 29 : gcry_sexp_t seedinfo = NULL;
756 29 : gcry_sexp_t misc_info = NULL;
757 29 : int flags = 0;
758 : dsa_domain_t domain;
759 29 : gcry_mpi_t *factors = NULL;
760 :
761 29 : memset (&sk, 0, sizeof sk);
762 29 : memset (&domain, 0, sizeof domain);
763 :
764 29 : rc = _gcry_pk_util_get_nbits (genparms, &nbits);
765 29 : if (rc)
766 0 : return rc;
767 :
768 : /* Parse the optional flags list. */
769 29 : l1 = sexp_find_token (genparms, "flags", 0);
770 29 : if (l1)
771 : {
772 0 : rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
773 0 : sexp_release (l1);
774 0 : if (rc)
775 0 : return rc;\
776 : }
777 :
778 : /* Parse the optional qbits element. */
779 29 : l1 = sexp_find_token (genparms, "qbits", 0);
780 29 : if (l1)
781 : {
782 : char buf[50];
783 : const char *s;
784 : size_t n;
785 :
786 4 : s = sexp_nth_data (l1, 1, &n);
787 4 : if (!s || n >= DIM (buf) - 1 )
788 : {
789 0 : sexp_release (l1);
790 0 : return GPG_ERR_INV_OBJ; /* No value or value too large. */
791 : }
792 4 : memcpy (buf, s, n);
793 4 : buf[n] = 0;
794 4 : qbits = (unsigned int)strtoul (buf, NULL, 0);
795 4 : sexp_release (l1);
796 : }
797 :
798 : /* Parse the optional transient-key flag. */
799 29 : if (!(flags & PUBKEY_FLAG_TRANSIENT_KEY))
800 : {
801 29 : l1 = sexp_find_token (genparms, "transient-key", 0);
802 29 : if (l1)
803 : {
804 6 : flags |= PUBKEY_FLAG_TRANSIENT_KEY;
805 6 : sexp_release (l1);
806 : }
807 : }
808 :
809 : /* Get the optional derive parameters. */
810 29 : deriveparms = sexp_find_token (genparms, "derive-parms", 0);
811 :
812 : /* Parse the optional "use-fips186" flags. */
813 29 : if (!(flags & PUBKEY_FLAG_USE_FIPS186))
814 : {
815 29 : l1 = sexp_find_token (genparms, "use-fips186", 0);
816 29 : if (l1)
817 : {
818 4 : flags |= PUBKEY_FLAG_USE_FIPS186;
819 4 : sexp_release (l1);
820 : }
821 : }
822 29 : if (!(flags & PUBKEY_FLAG_USE_FIPS186_2))
823 : {
824 29 : l1 = sexp_find_token (genparms, "use-fips186-2", 0);
825 29 : if (l1)
826 : {
827 10 : flags |= PUBKEY_FLAG_USE_FIPS186_2;
828 10 : sexp_release (l1);
829 : }
830 : }
831 :
832 : /* Check whether domain parameters are given. */
833 29 : domainsexp = sexp_find_token (genparms, "domain", 0);
834 29 : if (domainsexp)
835 : {
836 : /* DERIVEPARMS can't be used together with domain parameters.
837 : NBITS abnd QBITS may not be specified because there values
838 : are derived from the domain parameters. */
839 2 : if (deriveparms || qbits || nbits)
840 : {
841 0 : sexp_release (domainsexp);
842 0 : sexp_release (deriveparms);
843 0 : return GPG_ERR_INV_VALUE;
844 : }
845 :
846 : /* Put all domain parameters into the domain object. */
847 2 : l1 = sexp_find_token (domainsexp, "p", 0);
848 2 : domain.p = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
849 2 : sexp_release (l1);
850 2 : l1 = sexp_find_token (domainsexp, "q", 0);
851 2 : domain.q = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
852 2 : sexp_release (l1);
853 2 : l1 = sexp_find_token (domainsexp, "g", 0);
854 2 : domain.g = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
855 2 : sexp_release (l1);
856 2 : sexp_release (domainsexp);
857 :
858 : /* Check that all domain parameters are available. */
859 2 : if (!domain.p || !domain.q || !domain.g)
860 : {
861 0 : _gcry_mpi_release (domain.p);
862 0 : _gcry_mpi_release (domain.q);
863 0 : _gcry_mpi_release (domain.g);
864 0 : sexp_release (deriveparms);
865 0 : return GPG_ERR_MISSING_VALUE;
866 : }
867 :
868 : /* Get NBITS and QBITS from the domain parameters. */
869 2 : nbits = mpi_get_nbits (domain.p);
870 2 : qbits = mpi_get_nbits (domain.q);
871 : }
872 :
873 29 : if (deriveparms
874 17 : || (flags & PUBKEY_FLAG_USE_FIPS186)
875 15 : || (flags & PUBKEY_FLAG_USE_FIPS186_2)
876 15 : || fips_mode ())
877 14 : {
878 : int counter;
879 : void *seed;
880 : size_t seedlen;
881 : gcry_mpi_t h_value;
882 :
883 14 : rc = generate_fips186 (&sk, nbits, qbits, deriveparms,
884 14 : !!(flags & PUBKEY_FLAG_USE_FIPS186_2),
885 : &domain,
886 : &counter, &seed, &seedlen, &h_value);
887 14 : if (!rc && h_value)
888 : {
889 : /* Format the seed-values unless domain parameters are used
890 : for which a H_VALUE of NULL is an indication. */
891 14 : rc = sexp_build (&seedinfo, NULL,
892 : "(seed-values(counter %d)(seed %b)(h %m))",
893 : counter, (int)seedlen, seed, h_value);
894 14 : xfree (seed);
895 14 : _gcry_mpi_release (h_value);
896 : }
897 : }
898 : else
899 : {
900 15 : rc = generate (&sk, nbits, qbits,
901 15 : !!(flags & PUBKEY_FLAG_TRANSIENT_KEY),
902 : &domain, &factors);
903 : }
904 :
905 29 : if (!rc)
906 : {
907 : /* Put the factors into MISC_INFO. Note that the factors are
908 : not confidential thus we can store them in standard memory. */
909 : int nfactors, i, j;
910 : char *p;
911 29 : char *format = NULL;
912 29 : void **arg_list = NULL;
913 :
914 29 : for (nfactors=0; factors && factors[nfactors]; nfactors++)
915 : ;
916 : /* Allocate space for the format string:
917 : "(misc-key-info%S(pm1-factors%m))"
918 : with one "%m" for each factor and construct it. */
919 29 : format = xtrymalloc (50 + 2*nfactors);
920 29 : if (!format)
921 0 : rc = gpg_err_code_from_syserror ();
922 : else
923 : {
924 29 : p = stpcpy (format, "(misc-key-info");
925 29 : if (seedinfo)
926 14 : p = stpcpy (p, "%S");
927 29 : if (nfactors)
928 : {
929 13 : p = stpcpy (p, "(pm1-factors");
930 86 : for (i=0; i < nfactors; i++)
931 73 : p = stpcpy (p, "%m");
932 13 : p = stpcpy (p, ")");
933 : }
934 29 : p = stpcpy (p, ")");
935 :
936 : /* Allocate space for the list of factors plus one for the
937 : seedinfo s-exp plus an extra NULL entry for safety and
938 : fill it with the factors. */
939 29 : arg_list = xtrycalloc (nfactors+1+1, sizeof *arg_list);
940 29 : if (!arg_list)
941 0 : rc = gpg_err_code_from_syserror ();
942 : else
943 : {
944 29 : i = 0;
945 29 : if (seedinfo)
946 14 : arg_list[i++] = &seedinfo;
947 102 : for (j=0; j < nfactors; j++)
948 73 : arg_list[i++] = factors + j;
949 29 : arg_list[i] = NULL;
950 :
951 29 : rc = sexp_build_array (&misc_info, NULL, format, arg_list);
952 : }
953 : }
954 :
955 29 : xfree (arg_list);
956 29 : xfree (format);
957 : }
958 :
959 29 : if (!rc)
960 29 : rc = sexp_build (r_skey, NULL,
961 : "(key-data"
962 : " (public-key"
963 : " (dsa(p%m)(q%m)(g%m)(y%m)))"
964 : " (private-key"
965 : " (dsa(p%m)(q%m)(g%m)(y%m)(x%m)))"
966 : " %S)",
967 : sk.p, sk.q, sk.g, sk.y,
968 : sk.p, sk.q, sk.g, sk.y, sk.x,
969 : misc_info);
970 :
971 :
972 29 : _gcry_mpi_release (sk.p);
973 29 : _gcry_mpi_release (sk.q);
974 29 : _gcry_mpi_release (sk.g);
975 29 : _gcry_mpi_release (sk.y);
976 29 : _gcry_mpi_release (sk.x);
977 :
978 29 : _gcry_mpi_release (domain.p);
979 29 : _gcry_mpi_release (domain.q);
980 29 : _gcry_mpi_release (domain.g);
981 :
982 29 : sexp_release (seedinfo);
983 29 : sexp_release (misc_info);
984 29 : sexp_release (deriveparms);
985 29 : if (factors)
986 : {
987 : gcry_mpi_t *mp;
988 86 : for (mp = factors; *mp; mp++)
989 73 : mpi_free (*mp);
990 13 : xfree (factors);
991 : }
992 29 : return rc;
993 : }
994 :
995 :
996 :
997 : static gcry_err_code_t
998 2 : dsa_check_secret_key (gcry_sexp_t keyparms)
999 : {
1000 : gcry_err_code_t rc;
1001 2 : DSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL};
1002 :
1003 2 : rc = _gcry_sexp_extract_param (keyparms, NULL, "pqgyx",
1004 : &sk.p, &sk.q, &sk.g, &sk.y, &sk.x,
1005 : NULL);
1006 2 : if (rc)
1007 0 : goto leave;
1008 :
1009 2 : if (!check_secret_key (&sk))
1010 0 : rc = GPG_ERR_BAD_SECKEY;
1011 :
1012 : leave:
1013 2 : _gcry_mpi_release (sk.p);
1014 2 : _gcry_mpi_release (sk.q);
1015 2 : _gcry_mpi_release (sk.g);
1016 2 : _gcry_mpi_release (sk.y);
1017 2 : _gcry_mpi_release (sk.x);
1018 2 : if (DBG_CIPHER)
1019 0 : log_debug ("dsa_testkey => %s\n", gpg_strerror (rc));
1020 2 : return rc;
1021 : }
1022 :
1023 :
1024 : static gcry_err_code_t
1025 64 : dsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
1026 : {
1027 : gcry_err_code_t rc;
1028 : struct pk_encoding_ctx ctx;
1029 64 : gcry_mpi_t data = NULL;
1030 64 : DSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL};
1031 64 : gcry_mpi_t sig_r = NULL;
1032 64 : gcry_mpi_t sig_s = NULL;
1033 :
1034 64 : _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN,
1035 : dsa_get_nbits (keyparms));
1036 :
1037 : /* Extract the data. */
1038 64 : rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
1039 64 : if (rc)
1040 6 : goto leave;
1041 58 : if (DBG_CIPHER)
1042 0 : log_mpidump ("dsa_sign data", data);
1043 :
1044 : /* Extract the key. */
1045 58 : rc = _gcry_sexp_extract_param (keyparms, NULL, "pqgyx",
1046 : &sk.p, &sk.q, &sk.g, &sk.y, &sk.x, NULL);
1047 58 : if (rc)
1048 0 : goto leave;
1049 58 : if (DBG_CIPHER)
1050 : {
1051 0 : log_mpidump ("dsa_sign p", sk.p);
1052 0 : log_mpidump ("dsa_sign q", sk.q);
1053 0 : log_mpidump ("dsa_sign g", sk.g);
1054 0 : log_mpidump ("dsa_sign y", sk.y);
1055 0 : if (!fips_mode ())
1056 0 : log_mpidump ("dsa_sign x", sk.x);
1057 : }
1058 :
1059 58 : sig_r = mpi_new (0);
1060 58 : sig_s = mpi_new (0);
1061 58 : rc = sign (sig_r, sig_s, data, &sk, ctx.flags, ctx.hash_algo);
1062 58 : if (rc)
1063 0 : goto leave;
1064 58 : if (DBG_CIPHER)
1065 : {
1066 0 : log_mpidump ("dsa_sign sig_r", sig_r);
1067 0 : log_mpidump ("dsa_sign sig_s", sig_s);
1068 : }
1069 58 : rc = sexp_build (r_sig, NULL, "(sig-val(dsa(r%M)(s%M)))", sig_r, sig_s);
1070 :
1071 : leave:
1072 64 : _gcry_mpi_release (sig_r);
1073 64 : _gcry_mpi_release (sig_s);
1074 64 : _gcry_mpi_release (sk.p);
1075 64 : _gcry_mpi_release (sk.q);
1076 64 : _gcry_mpi_release (sk.g);
1077 64 : _gcry_mpi_release (sk.y);
1078 64 : _gcry_mpi_release (sk.x);
1079 64 : _gcry_mpi_release (data);
1080 64 : _gcry_pk_util_free_encoding_ctx (&ctx);
1081 64 : if (DBG_CIPHER)
1082 0 : log_debug ("dsa_sign => %s\n", gpg_strerror (rc));
1083 64 : return rc;
1084 : }
1085 :
1086 :
1087 : static gcry_err_code_t
1088 66 : dsa_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
1089 : {
1090 : gcry_err_code_t rc;
1091 : struct pk_encoding_ctx ctx;
1092 66 : gcry_sexp_t l1 = NULL;
1093 66 : gcry_mpi_t sig_r = NULL;
1094 66 : gcry_mpi_t sig_s = NULL;
1095 66 : gcry_mpi_t data = NULL;
1096 66 : DSA_public_key pk = { NULL, NULL, NULL, NULL };
1097 :
1098 66 : _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY,
1099 : dsa_get_nbits (s_keyparms));
1100 :
1101 : /* Extract the data. */
1102 66 : rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
1103 66 : if (rc)
1104 0 : goto leave;
1105 66 : if (DBG_CIPHER)
1106 0 : log_mpidump ("dsa_verify data", data);
1107 :
1108 : /* Extract the signature value. */
1109 66 : rc = _gcry_pk_util_preparse_sigval (s_sig, dsa_names, &l1, NULL);
1110 66 : if (rc)
1111 0 : goto leave;
1112 66 : rc = _gcry_sexp_extract_param (l1, NULL, "rs", &sig_r, &sig_s, NULL);
1113 66 : if (rc)
1114 0 : goto leave;
1115 66 : if (DBG_CIPHER)
1116 : {
1117 0 : log_mpidump ("dsa_verify s_r", sig_r);
1118 0 : log_mpidump ("dsa_verify s_s", sig_s);
1119 : }
1120 :
1121 : /* Extract the key. */
1122 66 : rc = _gcry_sexp_extract_param (s_keyparms, NULL, "pqgy",
1123 : &pk.p, &pk.q, &pk.g, &pk.y, NULL);
1124 66 : if (rc)
1125 0 : goto leave;
1126 66 : if (DBG_CIPHER)
1127 : {
1128 0 : log_mpidump ("dsa_verify p", pk.p);
1129 0 : log_mpidump ("dsa_verify q", pk.q);
1130 0 : log_mpidump ("dsa_verify g", pk.g);
1131 0 : log_mpidump ("dsa_verify y", pk.y);
1132 : }
1133 :
1134 : /* Verify the signature. */
1135 66 : rc = verify (sig_r, sig_s, data, &pk);
1136 :
1137 : leave:
1138 66 : _gcry_mpi_release (pk.p);
1139 66 : _gcry_mpi_release (pk.q);
1140 66 : _gcry_mpi_release (pk.g);
1141 66 : _gcry_mpi_release (pk.y);
1142 66 : _gcry_mpi_release (data);
1143 66 : _gcry_mpi_release (sig_r);
1144 66 : _gcry_mpi_release (sig_s);
1145 66 : sexp_release (l1);
1146 66 : _gcry_pk_util_free_encoding_ctx (&ctx);
1147 66 : if (DBG_CIPHER)
1148 0 : log_debug ("dsa_verify => %s\n", rc?gpg_strerror (rc):"Good");
1149 66 : return rc;
1150 : }
1151 :
1152 :
1153 : /* Return the number of bits for the key described by PARMS. On error
1154 : * 0 is returned. The format of PARMS starts with the algorithm name;
1155 : * for example:
1156 : *
1157 : * (dsa
1158 : * (p <mpi>)
1159 : * (q <mpi>)
1160 : * (g <mpi>)
1161 : * (y <mpi>))
1162 : *
1163 : * More parameters may be given but we only need P here.
1164 : */
1165 : static unsigned int
1166 130 : dsa_get_nbits (gcry_sexp_t parms)
1167 : {
1168 : gcry_sexp_t l1;
1169 : gcry_mpi_t p;
1170 : unsigned int nbits;
1171 :
1172 130 : l1 = sexp_find_token (parms, "p", 1);
1173 130 : if (!l1)
1174 0 : return 0; /* Parameter P not found. */
1175 :
1176 130 : p = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1177 130 : sexp_release (l1);
1178 130 : nbits = p? mpi_get_nbits (p) : 0;
1179 130 : _gcry_mpi_release (p);
1180 130 : return nbits;
1181 : }
1182 :
1183 :
1184 :
1185 : /*
1186 : Self-test section.
1187 : */
1188 :
1189 : static const char *
1190 2 : selftest_sign (gcry_sexp_t pkey, gcry_sexp_t skey)
1191 : {
1192 : /* Sample data from RFC 6979 section A.2.2, hash is of message "sample" */
1193 : static const char sample_data[] =
1194 : "(data (flags rfc6979)"
1195 : " (hash sha256 #af2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e9891562113d8a62add1bf#))";
1196 : static const char sample_data_bad[] =
1197 : "(data (flags rfc6979)"
1198 : " (hash sha256 #bf2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e9891562113d8a62add1bf#))";
1199 : static const char signature_r[] =
1200 : "eace8bdbbe353c432a795d9ec556c6d021f7a03f42c36e9bc87e4ac7932cc809";
1201 : static const char signature_s[] =
1202 : "7081e175455f9247b812b74583e9e94f9ea79bd640dc962533b0680793a38d53";
1203 :
1204 2 : const char *errtxt = NULL;
1205 : gcry_error_t err;
1206 2 : gcry_sexp_t data = NULL;
1207 2 : gcry_sexp_t data_bad = NULL;
1208 2 : gcry_sexp_t sig = NULL;
1209 2 : gcry_sexp_t l1 = NULL;
1210 2 : gcry_sexp_t l2 = NULL;
1211 2 : gcry_mpi_t r = NULL;
1212 2 : gcry_mpi_t s = NULL;
1213 2 : gcry_mpi_t calculated_r = NULL;
1214 2 : gcry_mpi_t calculated_s = NULL;
1215 : int cmp;
1216 :
1217 2 : err = sexp_sscan (&data, NULL, sample_data, strlen (sample_data));
1218 2 : if (!err)
1219 2 : err = sexp_sscan (&data_bad, NULL,
1220 : sample_data_bad, strlen (sample_data_bad));
1221 2 : if (!err)
1222 2 : err = _gcry_mpi_scan (&r, GCRYMPI_FMT_HEX, signature_r, 0, NULL);
1223 2 : if (!err)
1224 2 : err = _gcry_mpi_scan (&s, GCRYMPI_FMT_HEX, signature_s, 0, NULL);
1225 :
1226 2 : if (err)
1227 : {
1228 0 : errtxt = "converting data failed";
1229 0 : goto leave;
1230 : }
1231 :
1232 2 : err = _gcry_pk_sign (&sig, data, skey);
1233 2 : if (err)
1234 : {
1235 0 : errtxt = "signing failed";
1236 0 : goto leave;
1237 : }
1238 :
1239 : /* check against known signature */
1240 2 : errtxt = "signature validity failed";
1241 2 : l1 = _gcry_sexp_find_token (sig, "sig-val", 0);
1242 2 : if (!l1)
1243 0 : goto leave;
1244 2 : l2 = _gcry_sexp_find_token (l1, "dsa", 0);
1245 2 : if (!l2)
1246 0 : goto leave;
1247 :
1248 2 : sexp_release (l1);
1249 2 : l1 = l2;
1250 :
1251 2 : l2 = _gcry_sexp_find_token (l1, "r", 0);
1252 2 : if (!l2)
1253 0 : goto leave;
1254 2 : calculated_r = _gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
1255 2 : if (!calculated_r)
1256 0 : goto leave;
1257 :
1258 2 : sexp_release (l2);
1259 2 : l2 = _gcry_sexp_find_token (l1, "s", 0);
1260 2 : if (!l2)
1261 0 : goto leave;
1262 2 : calculated_s = _gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
1263 2 : if (!calculated_s)
1264 0 : goto leave;
1265 :
1266 2 : errtxt = "known sig check failed";
1267 :
1268 2 : cmp = _gcry_mpi_cmp (r, calculated_r);
1269 2 : if (cmp)
1270 0 : goto leave;
1271 2 : cmp = _gcry_mpi_cmp (s, calculated_s);
1272 2 : if (cmp)
1273 0 : goto leave;
1274 :
1275 2 : errtxt = NULL;
1276 :
1277 :
1278 2 : err = _gcry_pk_verify (sig, data, pkey);
1279 2 : if (err)
1280 : {
1281 0 : errtxt = "verify failed";
1282 0 : goto leave;
1283 : }
1284 2 : err = _gcry_pk_verify (sig, data_bad, pkey);
1285 2 : if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
1286 : {
1287 0 : errtxt = "bad signature not detected";
1288 0 : goto leave;
1289 : }
1290 :
1291 :
1292 : leave:
1293 2 : _gcry_mpi_release (calculated_s);
1294 2 : _gcry_mpi_release (calculated_r);
1295 2 : _gcry_mpi_release (s);
1296 2 : _gcry_mpi_release (r);
1297 2 : sexp_release (l2);
1298 2 : sexp_release (l1);
1299 2 : sexp_release (sig);
1300 2 : sexp_release (data_bad);
1301 2 : sexp_release (data);
1302 2 : return errtxt;
1303 : }
1304 :
1305 :
1306 : static gpg_err_code_t
1307 2 : selftests_dsa_2048 (selftest_report_func_t report)
1308 : {
1309 : const char *what;
1310 : const char *errtxt;
1311 : gcry_error_t err;
1312 2 : gcry_sexp_t skey = NULL;
1313 2 : gcry_sexp_t pkey = NULL;
1314 :
1315 : /* Convert the S-expressions into the internal representation. */
1316 2 : what = "convert";
1317 2 : err = sexp_sscan (&skey, NULL, sample_secret_key_2048, strlen (sample_secret_key_2048));
1318 2 : if (!err)
1319 2 : err = sexp_sscan (&pkey, NULL,
1320 : sample_public_key_2048, strlen (sample_public_key_2048));
1321 2 : if (err)
1322 : {
1323 0 : errtxt = _gcry_strerror (err);
1324 0 : goto failed;
1325 : }
1326 :
1327 2 : what = "key consistency";
1328 2 : err = _gcry_pk_testkey (skey);
1329 2 : if (err)
1330 : {
1331 0 : errtxt = _gcry_strerror (err);
1332 0 : goto failed;
1333 : }
1334 :
1335 2 : what = "sign";
1336 2 : errtxt = selftest_sign (pkey, skey);
1337 2 : if (errtxt)
1338 0 : goto failed;
1339 :
1340 2 : sexp_release (pkey);
1341 2 : sexp_release (skey);
1342 2 : return 0; /* Succeeded. */
1343 :
1344 : failed:
1345 0 : sexp_release (pkey);
1346 0 : sexp_release (skey);
1347 0 : if (report)
1348 0 : report ("pubkey", GCRY_PK_DSA, what, errtxt);
1349 0 : return GPG_ERR_SELFTEST_FAILED;
1350 : }
1351 :
1352 :
1353 : /* Run a full self-test for ALGO and return 0 on success. */
1354 : static gpg_err_code_t
1355 2 : run_selftests (int algo, int extended, selftest_report_func_t report)
1356 : {
1357 : gpg_err_code_t ec;
1358 :
1359 : (void)extended;
1360 :
1361 2 : switch (algo)
1362 : {
1363 : case GCRY_PK_DSA:
1364 2 : ec = selftests_dsa_2048 (report);
1365 2 : break;
1366 : default:
1367 0 : ec = GPG_ERR_PUBKEY_ALGO;
1368 0 : break;
1369 :
1370 : }
1371 2 : return ec;
1372 : }
1373 :
1374 :
1375 :
1376 : gcry_pk_spec_t _gcry_pubkey_spec_dsa =
1377 : {
1378 : GCRY_PK_DSA, { 0, 1 },
1379 : GCRY_PK_USAGE_SIGN,
1380 : "DSA", dsa_names,
1381 : "pqgy", "pqgyx", "", "rs", "pqgy",
1382 : dsa_generate,
1383 : dsa_check_secret_key,
1384 : NULL,
1385 : NULL,
1386 : dsa_sign,
1387 : dsa_verify,
1388 : dsa_get_nbits,
1389 : run_selftests
1390 : };
|