blob: 3b269d4f821f64c89fdfed42768ec47eb236e5ba [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 *
57 * The DSS routines are based on patches supplied by
58 * Steven Schoch <schoch@sheba.arc.nasa.gov>. */
59
60#include <openssl/dsa.h>
61
Adam Langley2b2d66d2015-01-30 17:08:37 -080062#include <string.h>
63
Adam Langley95c29f32014-06-20 12:00:00 -070064#include <openssl/asn1.h>
David Benjamine8f783a2015-10-30 16:53:00 -040065#include <openssl/bn.h>
Adam Langleybed8ce72014-09-05 17:04:51 -070066#include <openssl/dh.h>
David Benjamine8f783a2015-10-30 16:53:00 -040067#include <openssl/digest.h>
Adam Langley95c29f32014-06-20 12:00:00 -070068#include <openssl/engine.h>
69#include <openssl/err.h>
70#include <openssl/ex_data.h>
71#include <openssl/mem.h>
David Benjamine8f783a2015-10-30 16:53:00 -040072#include <openssl/rand.h>
73#include <openssl/sha.h>
Brian Smith054e6822015-03-27 21:12:01 -100074#include <openssl/thread.h>
Adam Langley95c29f32014-06-20 12:00:00 -070075
76#include "internal.h"
Adam Langley683d7bd2015-04-13 11:04:14 -070077#include "../internal.h"
Adam Langley95c29f32014-06-20 12:00:00 -070078
Adam Langley2b2d66d2015-01-30 17:08:37 -080079
David Benjamine8f783a2015-10-30 16:53:00 -040080#define OPENSSL_DSA_MAX_MODULUS_BITS 10000
81
82/* Primality test according to FIPS PUB 186[-1], Appendix 2.1: 50 rounds of
83 * Rabin-Miller */
84#define DSS_prime_checks 50
Adam Langley95c29f32014-06-20 12:00:00 -070085
David Benjamin9f33fc62015-04-15 17:29:53 -040086static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
87
David Benjamine8f783a2015-10-30 16:53:00 -040088DSA *DSA_new(void) {
Brian Smith5ba06892016-02-07 09:36:04 -100089 DSA *dsa = OPENSSL_malloc(sizeof(DSA));
Adam Langley95c29f32014-06-20 12:00:00 -070090 if (dsa == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -040091 OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -070092 return NULL;
93 }
94
95 memset(dsa, 0, sizeof(DSA));
96
Adam Langley95c29f32014-06-20 12:00:00 -070097 dsa->references = 1;
98
Adam Langley683d7bd2015-04-13 11:04:14 -070099 CRYPTO_MUTEX_init(&dsa->method_mont_p_lock);
David Benjamin8a589332015-12-04 23:14:35 -0500100 CRYPTO_new_ex_data(&dsa->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -0700101
102 return dsa;
103}
104
105void DSA_free(DSA *dsa) {
106 if (dsa == NULL) {
107 return;
108 }
109
Adam Langley0da323a2015-05-15 12:49:30 -0700110 if (!CRYPTO_refcount_dec_and_test_zero(&dsa->references)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700111 return;
112 }
113
David Benjamin9f33fc62015-04-15 17:29:53 -0400114 CRYPTO_free_ex_data(&g_ex_data_class, dsa, &dsa->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -0700115
David Benjamin22ccc2d2015-04-22 13:50:28 -0400116 BN_clear_free(dsa->p);
117 BN_clear_free(dsa->q);
118 BN_clear_free(dsa->g);
119 BN_clear_free(dsa->pub_key);
120 BN_clear_free(dsa->priv_key);
121 BN_clear_free(dsa->kinv);
122 BN_clear_free(dsa->r);
David Benjamine8f783a2015-10-30 16:53:00 -0400123 BN_MONT_CTX_free(dsa->method_mont_p);
Adam Langley683d7bd2015-04-13 11:04:14 -0700124 CRYPTO_MUTEX_cleanup(&dsa->method_mont_p_lock);
Adam Langley95c29f32014-06-20 12:00:00 -0700125 OPENSSL_free(dsa);
126}
127
128int DSA_up_ref(DSA *dsa) {
Adam Langley0da323a2015-05-15 12:49:30 -0700129 CRYPTO_refcount_inc(&dsa->references);
Adam Langley95c29f32014-06-20 12:00:00 -0700130 return 1;
131}
132
133int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
134 size_t seed_len, int *out_counter,
135 unsigned long *out_h, BN_GENCB *cb) {
David Benjamine8f783a2015-10-30 16:53:00 -0400136 int ok = 0;
137 unsigned char seed[SHA256_DIGEST_LENGTH];
138 unsigned char md[SHA256_DIGEST_LENGTH];
139 unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
140 BIGNUM *r0, *W, *X, *c, *test;
141 BIGNUM *g = NULL, *q = NULL, *p = NULL;
142 BN_MONT_CTX *mont = NULL;
143 int k, n = 0, m = 0;
144 unsigned i;
145 int counter = 0;
146 int r = 0;
147 BN_CTX *ctx = NULL;
148 unsigned int h = 2;
149 unsigned qsize;
150 const EVP_MD *evpmd;
151
152 evpmd = (bits >= 2048) ? EVP_sha256() : EVP_sha1();
153 qsize = EVP_MD_size(evpmd);
154
155 if (bits < 512) {
156 bits = 512;
Adam Langley95c29f32014-06-20 12:00:00 -0700157 }
David Benjamine8f783a2015-10-30 16:53:00 -0400158
159 bits = (bits + 63) / 64 * 64;
160
161 if (seed_in != NULL) {
162 if (seed_len < (size_t)qsize) {
163 return 0;
164 }
165 if (seed_len > (size_t)qsize) {
166 /* Only consume as much seed as is expected. */
167 seed_len = qsize;
168 }
169 memcpy(seed, seed_in, seed_len);
170 }
171
172 ctx = BN_CTX_new();
173 if (ctx == NULL) {
174 goto err;
175 }
176 BN_CTX_start(ctx);
177
178 mont = BN_MONT_CTX_new();
179 if (mont == NULL) {
180 goto err;
181 }
182
183 r0 = BN_CTX_get(ctx);
184 g = BN_CTX_get(ctx);
185 W = BN_CTX_get(ctx);
186 q = BN_CTX_get(ctx);
187 X = BN_CTX_get(ctx);
188 c = BN_CTX_get(ctx);
189 p = BN_CTX_get(ctx);
190 test = BN_CTX_get(ctx);
191
192 if (test == NULL || !BN_lshift(test, BN_value_one(), bits - 1)) {
193 goto err;
194 }
195
196 for (;;) {
197 /* Find q. */
198 for (;;) {
199 /* step 1 */
200 if (!BN_GENCB_call(cb, 0, m++)) {
201 goto err;
202 }
203
204 int use_random_seed = (seed_in == NULL);
205 if (use_random_seed) {
206 if (!RAND_bytes(seed, qsize)) {
207 goto err;
208 }
209 } else {
210 /* If we come back through, use random seed next time. */
211 seed_in = NULL;
212 }
213 memcpy(buf, seed, qsize);
214 memcpy(buf2, seed, qsize);
215 /* precompute "SEED + 1" for step 7: */
216 for (i = qsize - 1; i < qsize; i--) {
217 buf[i]++;
218 if (buf[i] != 0) {
219 break;
220 }
221 }
222
223 /* step 2 */
224 if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL) ||
225 !EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) {
226 goto err;
227 }
228 for (i = 0; i < qsize; i++) {
229 md[i] ^= buf2[i];
230 }
231
232 /* step 3 */
233 md[0] |= 0x80;
234 md[qsize - 1] |= 0x01;
235 if (!BN_bin2bn(md, qsize, q)) {
236 goto err;
237 }
238
239 /* step 4 */
240 r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, use_random_seed, cb);
241 if (r > 0) {
242 break;
243 }
244 if (r != 0) {
245 goto err;
246 }
247
248 /* do a callback call */
249 /* step 5 */
250 }
251
252 if (!BN_GENCB_call(cb, 2, 0) || !BN_GENCB_call(cb, 3, 0)) {
253 goto err;
254 }
255
256 /* step 6 */
257 counter = 0;
258 /* "offset = 2" */
259
260 n = (bits - 1) / 160;
261
262 for (;;) {
263 if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) {
264 goto err;
265 }
266
267 /* step 7 */
268 BN_zero(W);
269 /* now 'buf' contains "SEED + offset - 1" */
270 for (k = 0; k <= n; k++) {
271 /* obtain "SEED + offset + k" by incrementing: */
272 for (i = qsize - 1; i < qsize; i--) {
273 buf[i]++;
274 if (buf[i] != 0) {
275 break;
276 }
277 }
278
279 if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL)) {
280 goto err;
281 }
282
283 /* step 8 */
284 if (!BN_bin2bn(md, qsize, r0) ||
285 !BN_lshift(r0, r0, (qsize << 3) * k) ||
286 !BN_add(W, W, r0)) {
287 goto err;
288 }
289 }
290
291 /* more of step 8 */
292 if (!BN_mask_bits(W, bits - 1) ||
293 !BN_copy(X, W) ||
294 !BN_add(X, X, test)) {
295 goto err;
296 }
297
298 /* step 9 */
299 if (!BN_lshift1(r0, q) ||
300 !BN_mod(c, X, r0, ctx) ||
301 !BN_sub(r0, c, BN_value_one()) ||
302 !BN_sub(p, X, r0)) {
303 goto err;
304 }
305
306 /* step 10 */
307 if (BN_cmp(p, test) >= 0) {
308 /* step 11 */
309 r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
310 if (r > 0) {
311 goto end; /* found it */
312 }
313 if (r != 0) {
314 goto err;
315 }
316 }
317
318 /* step 13 */
319 counter++;
320 /* "offset = offset + n + 1" */
321
322 /* step 14 */
323 if (counter >= 4096) {
324 break;
325 }
326 }
327 }
328end:
329 if (!BN_GENCB_call(cb, 2, 1)) {
330 goto err;
331 }
332
333 /* We now need to generate g */
334 /* Set r0=(p-1)/q */
335 if (!BN_sub(test, p, BN_value_one()) ||
336 !BN_div(r0, NULL, test, q, ctx)) {
337 goto err;
338 }
339
340 if (!BN_set_word(test, h) ||
341 !BN_MONT_CTX_set(mont, p, ctx)) {
342 goto err;
343 }
344
345 for (;;) {
346 /* g=test^r0%p */
347 if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont)) {
348 goto err;
349 }
350 if (!BN_is_one(g)) {
351 break;
352 }
353 if (!BN_add(test, test, BN_value_one())) {
354 goto err;
355 }
356 h++;
357 }
358
359 if (!BN_GENCB_call(cb, 3, 1)) {
360 goto err;
361 }
362
363 ok = 1;
364
365err:
366 if (ok) {
367 BN_free(dsa->p);
368 BN_free(dsa->q);
369 BN_free(dsa->g);
370 dsa->p = BN_dup(p);
371 dsa->q = BN_dup(q);
372 dsa->g = BN_dup(g);
373 if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
374 ok = 0;
375 goto err;
376 }
377 if (out_counter != NULL) {
378 *out_counter = counter;
379 }
380 if (out_h != NULL) {
381 *out_h = h;
382 }
383 }
384
385 if (ctx) {
386 BN_CTX_end(ctx);
387 BN_CTX_free(ctx);
388 }
389
390 BN_MONT_CTX_free(mont);
391
392 return ok;
Adam Langley95c29f32014-06-20 12:00:00 -0700393}
394
David Benjaminfda22a72016-01-30 01:51:01 -0500395DSA *DSAparams_dup(const DSA *dsa) {
396 DSA *ret = DSA_new();
397 if (ret == NULL) {
398 return NULL;
399 }
400 ret->p = BN_dup(dsa->p);
401 ret->q = BN_dup(dsa->q);
402 ret->g = BN_dup(dsa->g);
403 if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
404 DSA_free(ret);
405 return NULL;
406 }
407 return ret;
408}
409
Adam Langley95c29f32014-06-20 12:00:00 -0700410int DSA_generate_key(DSA *dsa) {
David Benjamine8f783a2015-10-30 16:53:00 -0400411 int ok = 0;
412 BN_CTX *ctx = NULL;
413 BIGNUM *pub_key = NULL, *priv_key = NULL;
414 BIGNUM prk;
415
416 ctx = BN_CTX_new();
417 if (ctx == NULL) {
418 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -0700419 }
David Benjamine8f783a2015-10-30 16:53:00 -0400420
421 priv_key = dsa->priv_key;
422 if (priv_key == NULL) {
423 priv_key = BN_new();
424 if (priv_key == NULL) {
425 goto err;
426 }
427 }
428
429 do {
430 if (!BN_rand_range(priv_key, dsa->q)) {
431 goto err;
432 }
433 } while (BN_is_zero(priv_key));
434
435 pub_key = dsa->pub_key;
436 if (pub_key == NULL) {
437 pub_key = BN_new();
438 if (pub_key == NULL) {
439 goto err;
440 }
441 }
442
443 BN_init(&prk);
444 BN_with_flags(&prk, priv_key, BN_FLG_CONSTTIME);
445
446 if (!BN_mod_exp(pub_key, dsa->g, &prk, dsa->p, ctx)) {
447 goto err;
448 }
449
450 dsa->priv_key = priv_key;
451 dsa->pub_key = pub_key;
452 ok = 1;
453
454err:
455 if (dsa->pub_key == NULL) {
456 BN_free(pub_key);
457 }
458 if (dsa->priv_key == NULL) {
459 BN_free(priv_key);
460 }
461 BN_CTX_free(ctx);
462
463 return ok;
Adam Langley95c29f32014-06-20 12:00:00 -0700464}
465
466DSA_SIG *DSA_SIG_new(void) {
467 DSA_SIG *sig;
468 sig = OPENSSL_malloc(sizeof(DSA_SIG));
469 if (!sig) {
470 return NULL;
471 }
472 sig->r = NULL;
473 sig->s = NULL;
474 return sig;
475}
476
477void DSA_SIG_free(DSA_SIG *sig) {
478 if (!sig) {
479 return;
480 }
481
David Benjamin22ccc2d2015-04-22 13:50:28 -0400482 BN_free(sig->r);
483 BN_free(sig->s);
Adam Langley95c29f32014-06-20 12:00:00 -0700484 OPENSSL_free(sig);
485}
486
487DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, DSA *dsa) {
David Benjamine8f783a2015-10-30 16:53:00 -0400488 BIGNUM *kinv = NULL, *r = NULL, *s = NULL;
489 BIGNUM m;
490 BIGNUM xr;
491 BN_CTX *ctx = NULL;
492 int reason = ERR_R_BN_LIB;
493 DSA_SIG *ret = NULL;
494 int noredo = 0;
495
496 BN_init(&m);
497 BN_init(&xr);
498
499 if (!dsa->p || !dsa->q || !dsa->g) {
500 reason = DSA_R_MISSING_PARAMETERS;
501 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -0700502 }
David Benjamine8f783a2015-10-30 16:53:00 -0400503
504 s = BN_new();
505 if (s == NULL) {
506 goto err;
507 }
508 ctx = BN_CTX_new();
509 if (ctx == NULL) {
510 goto err;
511 }
512
513redo:
514 if (dsa->kinv == NULL || dsa->r == NULL) {
515 if (!DSA_sign_setup(dsa, ctx, &kinv, &r)) {
516 goto err;
517 }
518 } else {
519 kinv = dsa->kinv;
520 dsa->kinv = NULL;
521 r = dsa->r;
522 dsa->r = NULL;
523 noredo = 1;
524 }
525
526 if (digest_len > BN_num_bytes(dsa->q)) {
527 /* if the digest length is greater than the size of q use the
528 * BN_num_bits(dsa->q) leftmost bits of the digest, see
529 * fips 186-3, 4.2 */
530 digest_len = BN_num_bytes(dsa->q);
531 }
532
533 if (BN_bin2bn(digest, digest_len, &m) == NULL) {
534 goto err;
535 }
536
537 /* Compute s = inv(k) (m + xr) mod q */
538 if (!BN_mod_mul(&xr, dsa->priv_key, r, dsa->q, ctx)) {
539 goto err; /* s = xr */
540 }
541 if (!BN_add(s, &xr, &m)) {
542 goto err; /* s = m + xr */
543 }
544 if (BN_cmp(s, dsa->q) > 0) {
545 if (!BN_sub(s, s, dsa->q)) {
546 goto err;
547 }
548 }
549 if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) {
550 goto err;
551 }
552
David Benjamine8f783a2015-10-30 16:53:00 -0400553 /* Redo if r or s is zero as required by FIPS 186-3: this is
554 * very unlikely. */
555 if (BN_is_zero(r) || BN_is_zero(s)) {
556 if (noredo) {
557 reason = DSA_R_NEED_NEW_SETUP_VALUES;
558 goto err;
559 }
560 goto redo;
561 }
David Benjamin29361702015-12-11 15:29:17 -0500562 ret = DSA_SIG_new();
563 if (ret == NULL) {
564 goto err;
565 }
David Benjamine8f783a2015-10-30 16:53:00 -0400566 ret->r = r;
567 ret->s = s;
568
569err:
David Benjamin29361702015-12-11 15:29:17 -0500570 if (ret == NULL) {
David Benjamine8f783a2015-10-30 16:53:00 -0400571 OPENSSL_PUT_ERROR(DSA, reason);
572 BN_free(r);
573 BN_free(s);
574 }
575 BN_CTX_free(ctx);
576 BN_clear_free(&m);
577 BN_clear_free(&xr);
578 BN_clear_free(kinv);
579
580 return ret;
Adam Langley95c29f32014-06-20 12:00:00 -0700581}
582
583int DSA_do_verify(const uint8_t *digest, size_t digest_len, DSA_SIG *sig,
584 const DSA *dsa) {
David Benjamin95e18c52015-01-10 23:37:17 -0500585 int valid;
586 if (!DSA_do_check_signature(&valid, digest, digest_len, sig, dsa)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700587 return -1;
Adam Langley95c29f32014-06-20 12:00:00 -0700588 }
David Benjamin95e18c52015-01-10 23:37:17 -0500589 return valid;
Adam Langley95c29f32014-06-20 12:00:00 -0700590}
591
592int DSA_do_check_signature(int *out_valid, const uint8_t *digest,
593 size_t digest_len, DSA_SIG *sig, const DSA *dsa) {
David Benjamine8f783a2015-10-30 16:53:00 -0400594 BN_CTX *ctx;
595 BIGNUM u1, u2, t1;
596 BN_MONT_CTX *mont = NULL;
597 int ret = 0;
598 unsigned i;
599
600 *out_valid = 0;
601
602 if (!dsa->p || !dsa->q || !dsa->g) {
603 OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS);
604 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700605 }
606
David Benjamine8f783a2015-10-30 16:53:00 -0400607 i = BN_num_bits(dsa->q);
608 /* fips 186-3 allows only different sizes for q */
609 if (i != 160 && i != 224 && i != 256) {
610 OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_Q_VALUE);
611 return 0;
612 }
613
614 if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
615 OPENSSL_PUT_ERROR(DSA, DSA_R_MODULUS_TOO_LARGE);
616 return 0;
617 }
618
619 BN_init(&u1);
620 BN_init(&u2);
621 BN_init(&t1);
622
623 ctx = BN_CTX_new();
624 if (ctx == NULL) {
625 goto err;
626 }
627
628 if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
629 BN_ucmp(sig->r, dsa->q) >= 0) {
630 ret = 1;
631 goto err;
632 }
633 if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
634 BN_ucmp(sig->s, dsa->q) >= 0) {
635 ret = 1;
636 goto err;
637 }
638
639 /* Calculate W = inv(S) mod Q
640 * save W in u2 */
641 if (BN_mod_inverse(&u2, sig->s, dsa->q, ctx) == NULL) {
642 goto err;
643 }
644
645 /* save M in u1 */
646 if (digest_len > (i >> 3)) {
647 /* if the digest length is greater than the size of q use the
648 * BN_num_bits(dsa->q) leftmost bits of the digest, see
649 * fips 186-3, 4.2 */
650 digest_len = (i >> 3);
651 }
652
653 if (BN_bin2bn(digest, digest_len, &u1) == NULL) {
654 goto err;
655 }
656
657 /* u1 = M * w mod q */
658 if (!BN_mod_mul(&u1, &u1, &u2, dsa->q, ctx)) {
659 goto err;
660 }
661
662 /* u2 = r * w mod q */
663 if (!BN_mod_mul(&u2, sig->r, &u2, dsa->q, ctx)) {
664 goto err;
665 }
666
667 mont = BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
668 (CRYPTO_MUTEX *)&dsa->method_mont_p_lock,
669 dsa->p, ctx);
670 if (!mont) {
671 goto err;
672 }
673
674 if (!BN_mod_exp2_mont(&t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx,
675 mont)) {
676 goto err;
677 }
678
679 /* BN_copy(&u1,&t1); */
680 /* let u1 = u1 mod q */
681 if (!BN_mod(&u1, &t1, dsa->q, ctx)) {
682 goto err;
683 }
684
685 /* V is now in u1. If the signature is correct, it will be
686 * equal to R. */
687 *out_valid = BN_ucmp(&u1, sig->r) == 0;
688 ret = 1;
689
690err:
691 if (ret != 1) {
692 OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB);
693 }
694 BN_CTX_free(ctx);
695 BN_free(&u1);
696 BN_free(&u2);
697 BN_free(&t1);
698
699 return ret;
Adam Langley95c29f32014-06-20 12:00:00 -0700700}
701
702int DSA_sign(int type, const uint8_t *digest, size_t digest_len,
703 uint8_t *out_sig, unsigned int *out_siglen, DSA *dsa) {
704 DSA_SIG *s;
705
706 s = DSA_do_sign(digest, digest_len, dsa);
707 if (s == NULL) {
708 *out_siglen = 0;
709 return 0;
710 }
711
712 *out_siglen = i2d_DSA_SIG(s, &out_sig);
713 DSA_SIG_free(s);
714 return 1;
715}
716
717int DSA_verify(int type, const uint8_t *digest, size_t digest_len,
718 const uint8_t *sig, size_t sig_len, const DSA *dsa) {
David Benjamin95e18c52015-01-10 23:37:17 -0500719 int valid;
720 if (!DSA_check_signature(&valid, digest, digest_len, sig, sig_len, dsa)) {
721 return -1;
722 }
723 return valid;
724}
725
726int DSA_check_signature(int *out_valid, const uint8_t *digest,
727 size_t digest_len, const uint8_t *sig, size_t sig_len,
728 const DSA *dsa) {
Adam Langley95c29f32014-06-20 12:00:00 -0700729 DSA_SIG *s = NULL;
David Benjamin95e18c52015-01-10 23:37:17 -0500730 int ret = 0;
Adam Langleyca9a5382015-01-08 12:26:55 -0800731 uint8_t *der = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700732
733 s = DSA_SIG_new();
734 if (s == NULL) {
735 goto err;
736 }
737
Adam Langleyca9a5382015-01-08 12:26:55 -0800738 const uint8_t *sigp = sig;
739 if (d2i_DSA_SIG(&s, &sigp, sig_len) == NULL || sigp != sig + sig_len) {
740 goto err;
741 }
742
743 /* Ensure that the signature uses DER and doesn't have trailing garbage. */
744 int der_len = i2d_DSA_SIG(s, &der);
745 if (der_len < 0 || (size_t)der_len != sig_len || memcmp(sig, der, sig_len)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700746 goto err;
747 }
748
David Benjamin95e18c52015-01-10 23:37:17 -0500749 ret = DSA_do_check_signature(out_valid, digest, digest_len, s, dsa);
Adam Langley95c29f32014-06-20 12:00:00 -0700750
751err:
David Benjamin22ccc2d2015-04-22 13:50:28 -0400752 OPENSSL_free(der);
753 DSA_SIG_free(s);
Adam Langley95c29f32014-06-20 12:00:00 -0700754 return ret;
755}
756
Adam Langley95c29f32014-06-20 12:00:00 -0700757int DSA_size(const DSA *dsa) {
758 int ret, i;
759 ASN1_INTEGER bs;
760 unsigned char buf[4]; /* 4 bytes looks really small.
761 However, i2d_ASN1_INTEGER() will not look
762 beyond the first byte, as long as the second
763 parameter is NULL. */
764
765 i = BN_num_bits(dsa->q);
766 bs.length = (i + 7) / 8;
767 bs.data = buf;
768 bs.type = V_ASN1_INTEGER;
769 /* If the top bit is set the asn1 encoding is 1 larger. */
770 buf[0] = 0xff;
771
772 i = i2d_ASN1_INTEGER(&bs, NULL);
773 i += i; /* r and s */
774 ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
775 return ret;
776}
777
David Benjamine8f783a2015-10-30 16:53:00 -0400778int DSA_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv,
Adam Langley95c29f32014-06-20 12:00:00 -0700779 BIGNUM **out_r) {
David Benjamine8f783a2015-10-30 16:53:00 -0400780 BN_CTX *ctx;
781 BIGNUM k, kq, *K, *kinv = NULL, *r = NULL;
782 int ret = 0;
783
784 if (!dsa->p || !dsa->q || !dsa->g) {
785 OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS);
786 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700787 }
788
David Benjamine8f783a2015-10-30 16:53:00 -0400789 BN_init(&k);
790 BN_init(&kq);
791
792 ctx = ctx_in;
793 if (ctx == NULL) {
794 ctx = BN_CTX_new();
795 if (ctx == NULL) {
796 goto err;
797 }
798 }
799
800 r = BN_new();
801 if (r == NULL) {
802 goto err;
803 }
804
805 /* Get random k */
806 do {
807 if (!BN_rand_range(&k, dsa->q)) {
808 goto err;
809 }
810 } while (BN_is_zero(&k));
811
812 BN_set_flags(&k, BN_FLG_CONSTTIME);
813
814 if (BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
815 (CRYPTO_MUTEX *)&dsa->method_mont_p_lock, dsa->p,
816 ctx) == NULL) {
817 goto err;
818 }
819
820 /* Compute r = (g^k mod p) mod q */
821 if (!BN_copy(&kq, &k)) {
822 goto err;
823 }
824
825 /* We do not want timing information to leak the length of k,
826 * so we compute g^k using an equivalent exponent of fixed length.
827 *
828 * (This is a kludge that we need because the BN_mod_exp_mont()
829 * does not let us specify the desired timing behaviour.) */
830
831 if (!BN_add(&kq, &kq, dsa->q)) {
832 goto err;
833 }
834 if (BN_num_bits(&kq) <= BN_num_bits(dsa->q) && !BN_add(&kq, &kq, dsa->q)) {
835 goto err;
836 }
837
838 K = &kq;
839
840 if (!BN_mod_exp_mont(r, dsa->g, K, dsa->p, ctx, dsa->method_mont_p)) {
841 goto err;
842 }
843 if (!BN_mod(r, r, dsa->q, ctx)) {
844 goto err;
845 }
846
847 /* Compute part of 's = inv(k) (m + xr) mod q' */
848 kinv = BN_mod_inverse(NULL, &k, dsa->q, ctx);
849 if (kinv == NULL) {
850 goto err;
851 }
852
853 BN_clear_free(*out_kinv);
854 *out_kinv = kinv;
855 kinv = NULL;
856 BN_clear_free(*out_r);
857 *out_r = r;
858 ret = 1;
859
860err:
861 if (!ret) {
862 OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB);
863 if (r != NULL) {
864 BN_clear_free(r);
865 }
866 }
867
868 if (ctx_in == NULL) {
869 BN_CTX_free(ctx);
870 }
871 BN_clear_free(&k);
872 BN_clear_free(&kq);
873 return ret;
Adam Langley95c29f32014-06-20 12:00:00 -0700874}
875
David Benjamin8a589332015-12-04 23:14:35 -0500876int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
Adam Langley95c29f32014-06-20 12:00:00 -0700877 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
David Benjamin9f33fc62015-04-15 17:29:53 -0400878 int index;
David Benjamin8a589332015-12-04 23:14:35 -0500879 if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
880 free_func)) {
David Benjamin9f33fc62015-04-15 17:29:53 -0400881 return -1;
882 }
883 return index;
Adam Langley95c29f32014-06-20 12:00:00 -0700884}
885
886int DSA_set_ex_data(DSA *d, int idx, void *arg) {
887 return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
888}
889
890void *DSA_get_ex_data(const DSA *d, int idx) {
891 return CRYPTO_get_ex_data(&d->ex_data, idx);
892}
Adam Langleybed8ce72014-09-05 17:04:51 -0700893
894DH *DSA_dup_DH(const DSA *r) {
895 DH *ret = NULL;
896
897 if (r == NULL) {
898 goto err;
899 }
900 ret = DH_new();
901 if (ret == NULL) {
902 goto err;
903 }
904 if (r->q != NULL) {
905 ret->priv_length = BN_num_bits(r->q);
906 if ((ret->q = BN_dup(r->q)) == NULL) {
907 goto err;
908 }
909 }
910 if ((r->p != NULL && (ret->p = BN_dup(r->p)) == NULL) ||
911 (r->g != NULL && (ret->g = BN_dup(r->g)) == NULL) ||
912 (r->pub_key != NULL && (ret->pub_key = BN_dup(r->pub_key)) == NULL) ||
913 (r->priv_key != NULL && (ret->priv_key = BN_dup(r->priv_key)) == NULL)) {
914 goto err;
915 }
916
917 return ret;
918
919err:
David Benjamin22ccc2d2015-04-22 13:50:28 -0400920 DH_free(ret);
Adam Langleybed8ce72014-09-05 17:04:51 -0700921 return NULL;
922}