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