1 /* dsa-keygen.c
2 *
3 * Generation of DSA keypairs
4 */
5
6 /* nettle, low-level cryptographics library
7 *
8 * Copyright (C) 2013, 2014 Red Hat
9 *
10 * The nettle library is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or (at your
13 * option) any later version.
14 *
15 * The nettle library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with the nettle library; see the file COPYING.LIB. If not, write to
22 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 * MA 02111-1301, USA.
24 */
25
26 #if HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include <nettle/dsa.h>
34 #include <dsa-fips.h>
35
36 #include <nettle/bignum.h>
37
_dsa_check_qp_sizes(unsigned q_bits,unsigned p_bits,unsigned generate)38 unsigned _dsa_check_qp_sizes(unsigned q_bits, unsigned p_bits, unsigned generate)
39 {
40 switch (q_bits) {
41 case 160:
42 FIPS_RULE(generate != 0, 0, "DSA 160-bit generation\n");
43
44 if (p_bits != 1024)
45 return 0;
46 break;
47 case 224:
48 if (p_bits != 2048)
49 return 0;
50 break;
51 case 256:
52 if (p_bits != 2048 && p_bits != 3072)
53 return 0;
54 break;
55 default:
56 return 0;
57 }
58 return 1;
59 }
60
61 /* This generates p,q params using the A.1.2.1 algorithm in FIPS 186-4.
62 *
63 * The hash function used is SHA384.
64 */
65 int
_dsa_generate_dss_pq(struct dsa_params * params,struct dss_params_validation_seeds * cert,unsigned seed_length,void * seed,void * progress_ctx,nettle_progress_func * progress,unsigned p_bits,unsigned q_bits)66 _dsa_generate_dss_pq(struct dsa_params *params,
67 struct dss_params_validation_seeds *cert,
68 unsigned seed_length, void *seed,
69 void *progress_ctx, nettle_progress_func * progress,
70 unsigned p_bits /* = L */ , unsigned q_bits /* = N */ )
71 {
72 mpz_t r, p0, t, z, s, tmp, dp0;
73 int ret;
74 unsigned iterations, old_counter, i;
75 uint8_t *storage = NULL;
76 unsigned storage_length = 0;
77
78 ret = _dsa_check_qp_sizes(q_bits, p_bits, 1);
79 if (ret == 0) {
80 return 0;
81 }
82
83 if (seed_length < q_bits / 8) {
84 _gnutls_debug_log("Seed length must be larger than %d bytes (it is %d)\n", q_bits/8, seed_length);
85 return 0;
86 }
87
88 mpz_init(p0);
89 mpz_init(dp0);
90 mpz_init(r);
91 mpz_init(t);
92 mpz_init(z);
93 mpz_init(s);
94 mpz_init(tmp);
95
96 /* firstseed < 2^(N-1) */
97 mpz_set_ui(r, 1);
98 mpz_mul_2exp(r, r, q_bits - 1);
99
100 nettle_mpz_set_str_256_u(s, seed_length, seed);
101 if (mpz_cmp(s, r) < 0) {
102 goto fail;
103 }
104
105 cert->qseed_length = sizeof(cert->qseed);
106 cert->pseed_length = sizeof(cert->pseed);
107
108 ret = st_provable_prime(params->q,
109 &cert->qseed_length, cert->qseed,
110 &cert->qgen_counter,
111 q_bits,
112 seed_length, seed, progress_ctx, progress);
113 if (ret == 0) {
114 goto fail;
115 }
116
117 if (progress)
118 progress(progress_ctx, 'q');
119
120 ret = st_provable_prime(p0,
121 &cert->pseed_length, cert->pseed,
122 &cert->pgen_counter,
123 1 + div_ceil(p_bits, 2),
124 cert->qseed_length, cert->qseed,
125 progress_ctx, progress);
126 if (ret == 0) {
127 goto fail;
128 }
129
130 iterations = div_ceil(p_bits, DIGEST_SIZE*8);
131 old_counter = cert->pgen_counter;
132
133 if (iterations > 0) {
134 storage_length = iterations * DIGEST_SIZE;
135 storage = malloc(storage_length);
136 if (storage == NULL) {
137 goto fail;
138 }
139
140 nettle_mpz_set_str_256_u(s, cert->pseed_length, cert->pseed);
141 for (i = 0; i < iterations; i++) {
142 cert->pseed_length = nettle_mpz_sizeinbase_256_u(s);
143 nettle_mpz_get_str_256(cert->pseed_length, cert->pseed, s);
144
145 hash(&storage[(iterations - i - 1) * DIGEST_SIZE],
146 cert->pseed_length, cert->pseed);
147 mpz_add_ui(s, s, 1);
148 }
149
150 /* x = 2^(p_bits-1) + (x mod 2^(p_bits-1)) */
151 nettle_mpz_set_str_256_u(tmp, storage_length, storage);
152 }
153
154 mpz_set_ui(r, 1);
155 mpz_mul_2exp(r, r, p_bits - 1);
156
157 mpz_fdiv_r_2exp(tmp, tmp, p_bits - 1);
158 mpz_add(tmp, tmp, r);
159
160 /* Generate candidate prime p in [2^(bits-1), 2^bits] */
161
162 /* t = u[x/2c0] */
163 mpz_mul_2exp(dp0, p0, 1); /* dp0 = 2*p0 */
164 mpz_mul(dp0, dp0, params->q); /* dp0 = 2*p0*q */
165
166 mpz_cdiv_q(t, tmp, dp0);
167
168 retry:
169 /* c = 2p0*q*t + 1 */
170 mpz_mul(params->p, dp0, t);
171 mpz_add_ui(params->p, params->p, 1);
172
173 if (mpz_sizeinbase(params->p, 2) > p_bits) {
174 /* t = 2^(bits-1)/2qp0 */
175 mpz_set_ui(tmp, 1);
176 mpz_mul_2exp(tmp, tmp, p_bits - 1);
177 mpz_cdiv_q(t, tmp, dp0);
178
179 /* p = t* 2tq p0 + 1 */
180 mpz_mul(params->p, dp0, t);
181 mpz_add_ui(params->p, params->p, 1);
182 }
183
184 cert->pgen_counter++;
185
186 mpz_set_ui(r, 0);
187
188 if (iterations > 0) {
189 for (i = 0; i < iterations; i++) {
190 cert->pseed_length = nettle_mpz_sizeinbase_256_u(s);
191 nettle_mpz_get_str_256(cert->pseed_length, cert->pseed, s);
192
193 hash(&storage[(iterations - i - 1) * DIGEST_SIZE],
194 cert->pseed_length, cert->pseed);
195 mpz_add_ui(s, s, 1);
196 }
197
198 /* r = a */
199 nettle_mpz_set_str_256_u(r, storage_length, storage);
200 }
201
202 cert->pseed_length = nettle_mpz_sizeinbase_256_u(s);
203 nettle_mpz_get_str_256(cert->pseed_length, cert->pseed, s);
204
205 /* a = 2 + (a mod (p-3)) */
206 mpz_sub_ui(tmp, params->p, 3); /* c is too large to worry about negatives */
207 mpz_mod(r, r, tmp);
208 mpz_add_ui(r, r, 2);
209
210 /* z = a^(2tq) mod p */
211 mpz_mul_2exp(tmp, t, 1); /* tmp = 2t */
212 mpz_mul(tmp, tmp, params->q); /* tmp = 2tq */
213 mpz_powm(z, r, tmp, params->p);
214
215 mpz_sub_ui(tmp, z, 1);
216
217 mpz_gcd(tmp, tmp, params->p);
218 if (mpz_cmp_ui(tmp, 1) == 0) {
219 mpz_powm(tmp, z, p0, params->p);
220 if (mpz_cmp_ui(tmp, 1) == 0) {
221 goto success;
222 }
223 }
224
225 if (progress)
226 progress(progress_ctx, 'x');
227
228 if (cert->pgen_counter >= (4 * p_bits + old_counter))
229 return 0;
230
231 mpz_add_ui(t, t, 1);
232 goto retry;
233
234 success:
235 if (progress)
236 progress(progress_ctx, 'p');
237
238 ret = 1;
239 goto finish;
240
241 fail:
242 ret = 0;
243
244 finish:
245 mpz_clear(dp0);
246 mpz_clear(p0);
247 mpz_clear(tmp);
248 mpz_clear(t);
249 mpz_clear(z);
250 mpz_clear(s);
251 mpz_clear(r);
252 free(storage);
253 return ret;
254 }
255
256 int
_dsa_generate_dss_g(struct dsa_params * params,unsigned domain_seed_size,const uint8_t * domain_seed,void * progress_ctx,nettle_progress_func * progress,unsigned index)257 _dsa_generate_dss_g(struct dsa_params *params,
258 unsigned domain_seed_size, const uint8_t* domain_seed,
259 void *progress_ctx, nettle_progress_func * progress,
260 unsigned index)
261 {
262 mpz_t e, w;
263 uint16_t count;
264 uint8_t *dseed = NULL;
265 unsigned dseed_size;
266 unsigned pos;
267 uint8_t digest[DIGEST_SIZE];
268 int ret;
269
270 if (index > 255 || domain_seed_size == 0)
271 return 0;
272
273 dseed_size = domain_seed_size + 4 + 1 + 2;
274 dseed = malloc(dseed_size);
275 if (dseed == NULL)
276 return 0;
277
278 mpz_init(e);
279 mpz_init(w);
280
281 memcpy(dseed, domain_seed, domain_seed_size);
282 pos = domain_seed_size;
283
284 memcpy(dseed + pos, "\x67\x67\x65\x6e", 4);
285 pos += 4;
286
287 *(dseed + pos) = (uint8_t) index;
288 pos += 1;
289
290 mpz_sub_ui(e, params->p, 1);
291 mpz_fdiv_q(e, e, params->q);
292
293 for (count = 1; count < 65535; count++) {
294 *(dseed + pos) = (count >> 8) & 0xff;
295 *(dseed + pos + 1) = count & 0xff;
296
297 hash(digest, dseed_size, dseed);
298
299 nettle_mpz_set_str_256_u(w, DIGEST_SIZE, digest);
300
301 mpz_powm(params->g, w, e, params->p);
302
303 if (mpz_cmp_ui(params->g, 2) >= 0) {
304 /* found */
305 goto success;
306 }
307 if (progress)
308 progress(progress_ctx, 'x');
309 }
310
311 /* if we're here we failed */
312 if (progress)
313 progress(progress_ctx, 'X');
314 ret = 0;
315 goto finish;
316
317 success:
318 if (progress)
319 progress(progress_ctx, 'g');
320
321 ret = 1;
322
323 finish:
324 free(dseed);
325 mpz_clear(e);
326 mpz_clear(w);
327 return ret;
328
329 }
330
331 /* Generates the public and private DSA (or DH) keys
332 */
333 void
_dsa_generate_dss_xy(struct dsa_params * params,mpz_t y,mpz_t x,void * random_ctx,nettle_random_func * random)334 _dsa_generate_dss_xy(struct dsa_params *params,
335 mpz_t y, mpz_t x,
336 void *random_ctx, nettle_random_func * random)
337 {
338 mpz_t r;
339
340 mpz_init(r);
341 mpz_set(r, params->q);
342 mpz_sub_ui(r, r, 2);
343 nettle_mpz_random(x, random_ctx, random, r);
344 mpz_add_ui(x, x, 1);
345
346 mpz_powm(y, params->g, x, params->p);
347
348 mpz_clear(r);
349 }
350
351 /* This generates p, q, g params using the algorithms from FIPS 186-4.
352 * For p, q, the Shawe-Taylor algorithm is used.
353 * For g, the verifiable canonical generation of the generator is used.
354 *
355 * The hash function used is SHA384.
356 *
357 * pub: The output public key
358 * key: The output private key
359 * cert: A certificate that can be used to verify the generated parameters
360 * index: 1 for digital signatures (DSA), 2 for key establishment (DH)
361 * p_bits: The requested size of p
362 * q_bits: The requested size of q
363 *
364 */
365 int
dsa_generate_dss_pqg(struct dsa_params * params,struct dss_params_validation_seeds * cert,unsigned index,void * random_ctx,nettle_random_func * random,void * progress_ctx,nettle_progress_func * progress,unsigned p_bits,unsigned q_bits)366 dsa_generate_dss_pqg(struct dsa_params *params,
367 struct dss_params_validation_seeds *cert,
368 unsigned index,
369 void *random_ctx, nettle_random_func * random,
370 void *progress_ctx, nettle_progress_func * progress,
371 unsigned p_bits /* = L */ , unsigned q_bits /* = N */ )
372 {
373 int ret;
374 uint8_t domain_seed[MAX_PVP_SEED_SIZE*3];
375 unsigned domain_seed_size = 0;
376
377 ret = _dsa_check_qp_sizes(q_bits, p_bits, 1);
378 if (ret == 0)
379 return 0;
380
381 cert->seed_length = 2 * (q_bits / 8) + 1;
382
383 if (cert->seed_length > sizeof(cert->seed))
384 return 0;
385
386 random(random_ctx, cert->seed_length, cert->seed);
387
388 ret = _dsa_generate_dss_pq(params, cert, cert->seed_length, cert->seed,
389 progress_ctx, progress, p_bits, q_bits);
390 if (ret == 0)
391 return 0;
392
393 domain_seed_size = cert->seed_length + cert->qseed_length + cert->pseed_length;
394 memcpy(domain_seed, cert->seed, cert->seed_length);
395 memcpy(&domain_seed[cert->seed_length], cert->pseed, cert->pseed_length);
396 memcpy(&domain_seed[cert->seed_length+cert->pseed_length], cert->qseed, cert->qseed_length);
397 ret = _dsa_generate_dss_g(params, domain_seed_size, domain_seed,
398 progress_ctx, progress, index);
399 if (ret == 0)
400 return 0;
401
402 return 1;
403 }
404
405 int
_dsa_generate_dss_pqg(struct dsa_params * params,struct dss_params_validation_seeds * cert,unsigned index,unsigned seed_size,void * seed,void * progress_ctx,nettle_progress_func * progress,unsigned p_bits,unsigned q_bits)406 _dsa_generate_dss_pqg(struct dsa_params *params,
407 struct dss_params_validation_seeds *cert,
408 unsigned index,
409 unsigned seed_size, void *seed,
410 void *progress_ctx, nettle_progress_func * progress,
411 unsigned p_bits /* = L */ , unsigned q_bits /* = N */ )
412 {
413 int ret;
414 uint8_t domain_seed[MAX_PVP_SEED_SIZE*3];
415 unsigned domain_seed_size = 0;
416
417 ret = _dsa_check_qp_sizes(q_bits, p_bits, 1);
418 if (ret == 0)
419 return 0;
420
421 if (_gnutls_fips_mode_enabled() != 0) {
422 cert->seed_length = 2 * (q_bits / 8) + 1;
423
424 FIPS_RULE(cert->seed_length != seed_size, 0, "unsupported DSA seed length (is %d, should be %d)\n", seed_size, cert->seed_length);
425 } else {
426 cert->seed_length = seed_size;
427 }
428
429 if (cert->seed_length > sizeof(cert->seed))
430 return 0;
431
432
433 memcpy(cert->seed, seed, cert->seed_length);
434
435 ret = _dsa_generate_dss_pq(params, cert, cert->seed_length, cert->seed,
436 progress_ctx, progress, p_bits, q_bits);
437 if (ret == 0)
438 return 0;
439
440 domain_seed_size = cert->seed_length + cert->qseed_length + cert->pseed_length;
441 memcpy(domain_seed, cert->seed, cert->seed_length);
442 memcpy(&domain_seed[cert->seed_length], cert->pseed, cert->pseed_length);
443 memcpy(&domain_seed[cert->seed_length+cert->pseed_length], cert->qseed, cert->qseed_length);
444 ret = _dsa_generate_dss_g(params, domain_seed_size, domain_seed,
445 progress_ctx, progress, index);
446 if (ret == 0)
447 return 0;
448
449 return 1;
450 }
451
452 int
dsa_generate_dss_keypair(struct dsa_params * params,mpz_t y,mpz_t x,void * random_ctx,nettle_random_func * random,void * progress_ctx,nettle_progress_func * progress)453 dsa_generate_dss_keypair(struct dsa_params *params,
454 mpz_t y,
455 mpz_t x,
456 void *random_ctx, nettle_random_func * random,
457 void *progress_ctx, nettle_progress_func * progress)
458 {
459 _dsa_generate_dss_xy(params, y, x, random_ctx, random);
460
461 if (progress)
462 progress(progress_ctx, '\n');
463
464 return 1;
465
466 }
467