blob: 2a9524a332f945329c2bbb9e5625a28a420d1856 [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
395int DSA_generate_key(DSA *dsa) {
David Benjamine8f783a2015-10-30 16:53:00 -0400396 int ok = 0;
397 BN_CTX *ctx = NULL;
398 BIGNUM *pub_key = NULL, *priv_key = NULL;
399 BIGNUM prk;
400
401 ctx = BN_CTX_new();
402 if (ctx == NULL) {
403 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -0700404 }
David Benjamine8f783a2015-10-30 16:53:00 -0400405
406 priv_key = dsa->priv_key;
407 if (priv_key == NULL) {
408 priv_key = BN_new();
409 if (priv_key == NULL) {
410 goto err;
411 }
412 }
413
414 do {
415 if (!BN_rand_range(priv_key, dsa->q)) {
416 goto err;
417 }
418 } while (BN_is_zero(priv_key));
419
420 pub_key = dsa->pub_key;
421 if (pub_key == NULL) {
422 pub_key = BN_new();
423 if (pub_key == NULL) {
424 goto err;
425 }
426 }
427
428 BN_init(&prk);
429 BN_with_flags(&prk, priv_key, BN_FLG_CONSTTIME);
430
431 if (!BN_mod_exp(pub_key, dsa->g, &prk, dsa->p, ctx)) {
432 goto err;
433 }
434
435 dsa->priv_key = priv_key;
436 dsa->pub_key = pub_key;
437 ok = 1;
438
439err:
440 if (dsa->pub_key == NULL) {
441 BN_free(pub_key);
442 }
443 if (dsa->priv_key == NULL) {
444 BN_free(priv_key);
445 }
446 BN_CTX_free(ctx);
447
448 return ok;
Adam Langley95c29f32014-06-20 12:00:00 -0700449}
450
451DSA_SIG *DSA_SIG_new(void) {
452 DSA_SIG *sig;
453 sig = OPENSSL_malloc(sizeof(DSA_SIG));
454 if (!sig) {
455 return NULL;
456 }
457 sig->r = NULL;
458 sig->s = NULL;
459 return sig;
460}
461
462void DSA_SIG_free(DSA_SIG *sig) {
463 if (!sig) {
464 return;
465 }
466
David Benjamin22ccc2d2015-04-22 13:50:28 -0400467 BN_free(sig->r);
468 BN_free(sig->s);
Adam Langley95c29f32014-06-20 12:00:00 -0700469 OPENSSL_free(sig);
470}
471
472DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, DSA *dsa) {
David Benjamine8f783a2015-10-30 16:53:00 -0400473 BIGNUM *kinv = NULL, *r = NULL, *s = NULL;
474 BIGNUM m;
475 BIGNUM xr;
476 BN_CTX *ctx = NULL;
477 int reason = ERR_R_BN_LIB;
478 DSA_SIG *ret = NULL;
479 int noredo = 0;
480
481 BN_init(&m);
482 BN_init(&xr);
483
484 if (!dsa->p || !dsa->q || !dsa->g) {
485 reason = DSA_R_MISSING_PARAMETERS;
486 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -0700487 }
David Benjamine8f783a2015-10-30 16:53:00 -0400488
489 s = BN_new();
490 if (s == NULL) {
491 goto err;
492 }
493 ctx = BN_CTX_new();
494 if (ctx == NULL) {
495 goto err;
496 }
497
498redo:
499 if (dsa->kinv == NULL || dsa->r == NULL) {
500 if (!DSA_sign_setup(dsa, ctx, &kinv, &r)) {
501 goto err;
502 }
503 } else {
504 kinv = dsa->kinv;
505 dsa->kinv = NULL;
506 r = dsa->r;
507 dsa->r = NULL;
508 noredo = 1;
509 }
510
511 if (digest_len > BN_num_bytes(dsa->q)) {
512 /* if the digest length is greater than the size of q use the
513 * BN_num_bits(dsa->q) leftmost bits of the digest, see
514 * fips 186-3, 4.2 */
515 digest_len = BN_num_bytes(dsa->q);
516 }
517
518 if (BN_bin2bn(digest, digest_len, &m) == NULL) {
519 goto err;
520 }
521
522 /* Compute s = inv(k) (m + xr) mod q */
523 if (!BN_mod_mul(&xr, dsa->priv_key, r, dsa->q, ctx)) {
524 goto err; /* s = xr */
525 }
526 if (!BN_add(s, &xr, &m)) {
527 goto err; /* s = m + xr */
528 }
529 if (BN_cmp(s, dsa->q) > 0) {
530 if (!BN_sub(s, s, dsa->q)) {
531 goto err;
532 }
533 }
534 if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) {
535 goto err;
536 }
537
David Benjamine8f783a2015-10-30 16:53:00 -0400538 /* Redo if r or s is zero as required by FIPS 186-3: this is
539 * very unlikely. */
540 if (BN_is_zero(r) || BN_is_zero(s)) {
541 if (noredo) {
542 reason = DSA_R_NEED_NEW_SETUP_VALUES;
543 goto err;
544 }
545 goto redo;
546 }
David Benjamin29361702015-12-11 15:29:17 -0500547 ret = DSA_SIG_new();
548 if (ret == NULL) {
549 goto err;
550 }
David Benjamine8f783a2015-10-30 16:53:00 -0400551 ret->r = r;
552 ret->s = s;
553
554err:
David Benjamin29361702015-12-11 15:29:17 -0500555 if (ret == NULL) {
David Benjamine8f783a2015-10-30 16:53:00 -0400556 OPENSSL_PUT_ERROR(DSA, reason);
557 BN_free(r);
558 BN_free(s);
559 }
560 BN_CTX_free(ctx);
561 BN_clear_free(&m);
562 BN_clear_free(&xr);
563 BN_clear_free(kinv);
564
565 return ret;
Adam Langley95c29f32014-06-20 12:00:00 -0700566}
567
568int DSA_do_verify(const uint8_t *digest, size_t digest_len, DSA_SIG *sig,
569 const DSA *dsa) {
David Benjamin95e18c52015-01-10 23:37:17 -0500570 int valid;
571 if (!DSA_do_check_signature(&valid, digest, digest_len, sig, dsa)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700572 return -1;
Adam Langley95c29f32014-06-20 12:00:00 -0700573 }
David Benjamin95e18c52015-01-10 23:37:17 -0500574 return valid;
Adam Langley95c29f32014-06-20 12:00:00 -0700575}
576
577int DSA_do_check_signature(int *out_valid, const uint8_t *digest,
578 size_t digest_len, DSA_SIG *sig, const DSA *dsa) {
David Benjamine8f783a2015-10-30 16:53:00 -0400579 BN_CTX *ctx;
580 BIGNUM u1, u2, t1;
581 BN_MONT_CTX *mont = NULL;
582 int ret = 0;
583 unsigned i;
584
585 *out_valid = 0;
586
587 if (!dsa->p || !dsa->q || !dsa->g) {
588 OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS);
589 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700590 }
591
David Benjamine8f783a2015-10-30 16:53:00 -0400592 i = BN_num_bits(dsa->q);
593 /* fips 186-3 allows only different sizes for q */
594 if (i != 160 && i != 224 && i != 256) {
595 OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_Q_VALUE);
596 return 0;
597 }
598
599 if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
600 OPENSSL_PUT_ERROR(DSA, DSA_R_MODULUS_TOO_LARGE);
601 return 0;
602 }
603
604 BN_init(&u1);
605 BN_init(&u2);
606 BN_init(&t1);
607
608 ctx = BN_CTX_new();
609 if (ctx == NULL) {
610 goto err;
611 }
612
613 if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
614 BN_ucmp(sig->r, dsa->q) >= 0) {
615 ret = 1;
616 goto err;
617 }
618 if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
619 BN_ucmp(sig->s, dsa->q) >= 0) {
620 ret = 1;
621 goto err;
622 }
623
624 /* Calculate W = inv(S) mod Q
625 * save W in u2 */
626 if (BN_mod_inverse(&u2, sig->s, dsa->q, ctx) == NULL) {
627 goto err;
628 }
629
630 /* save M in u1 */
631 if (digest_len > (i >> 3)) {
632 /* if the digest length is greater than the size of q use the
633 * BN_num_bits(dsa->q) leftmost bits of the digest, see
634 * fips 186-3, 4.2 */
635 digest_len = (i >> 3);
636 }
637
638 if (BN_bin2bn(digest, digest_len, &u1) == NULL) {
639 goto err;
640 }
641
642 /* u1 = M * w mod q */
643 if (!BN_mod_mul(&u1, &u1, &u2, dsa->q, ctx)) {
644 goto err;
645 }
646
647 /* u2 = r * w mod q */
648 if (!BN_mod_mul(&u2, sig->r, &u2, dsa->q, ctx)) {
649 goto err;
650 }
651
652 mont = BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
653 (CRYPTO_MUTEX *)&dsa->method_mont_p_lock,
654 dsa->p, ctx);
655 if (!mont) {
656 goto err;
657 }
658
659 if (!BN_mod_exp2_mont(&t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx,
660 mont)) {
661 goto err;
662 }
663
664 /* BN_copy(&u1,&t1); */
665 /* let u1 = u1 mod q */
666 if (!BN_mod(&u1, &t1, dsa->q, ctx)) {
667 goto err;
668 }
669
670 /* V is now in u1. If the signature is correct, it will be
671 * equal to R. */
672 *out_valid = BN_ucmp(&u1, sig->r) == 0;
673 ret = 1;
674
675err:
676 if (ret != 1) {
677 OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB);
678 }
679 BN_CTX_free(ctx);
680 BN_free(&u1);
681 BN_free(&u2);
682 BN_free(&t1);
683
684 return ret;
Adam Langley95c29f32014-06-20 12:00:00 -0700685}
686
687int DSA_sign(int type, const uint8_t *digest, size_t digest_len,
688 uint8_t *out_sig, unsigned int *out_siglen, DSA *dsa) {
689 DSA_SIG *s;
690
691 s = DSA_do_sign(digest, digest_len, dsa);
692 if (s == NULL) {
693 *out_siglen = 0;
694 return 0;
695 }
696
697 *out_siglen = i2d_DSA_SIG(s, &out_sig);
698 DSA_SIG_free(s);
699 return 1;
700}
701
702int DSA_verify(int type, const uint8_t *digest, size_t digest_len,
703 const uint8_t *sig, size_t sig_len, const DSA *dsa) {
David Benjamin95e18c52015-01-10 23:37:17 -0500704 int valid;
705 if (!DSA_check_signature(&valid, digest, digest_len, sig, sig_len, dsa)) {
706 return -1;
707 }
708 return valid;
709}
710
711int DSA_check_signature(int *out_valid, const uint8_t *digest,
712 size_t digest_len, const uint8_t *sig, size_t sig_len,
713 const DSA *dsa) {
Adam Langley95c29f32014-06-20 12:00:00 -0700714 DSA_SIG *s = NULL;
David Benjamin95e18c52015-01-10 23:37:17 -0500715 int ret = 0;
Adam Langleyca9a5382015-01-08 12:26:55 -0800716 uint8_t *der = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700717
718 s = DSA_SIG_new();
719 if (s == NULL) {
720 goto err;
721 }
722
Adam Langleyca9a5382015-01-08 12:26:55 -0800723 const uint8_t *sigp = sig;
724 if (d2i_DSA_SIG(&s, &sigp, sig_len) == NULL || sigp != sig + sig_len) {
725 goto err;
726 }
727
728 /* Ensure that the signature uses DER and doesn't have trailing garbage. */
729 int der_len = i2d_DSA_SIG(s, &der);
730 if (der_len < 0 || (size_t)der_len != sig_len || memcmp(sig, der, sig_len)) {
Adam Langley95c29f32014-06-20 12:00:00 -0700731 goto err;
732 }
733
David Benjamin95e18c52015-01-10 23:37:17 -0500734 ret = DSA_do_check_signature(out_valid, digest, digest_len, s, dsa);
Adam Langley95c29f32014-06-20 12:00:00 -0700735
736err:
David Benjamin22ccc2d2015-04-22 13:50:28 -0400737 OPENSSL_free(der);
738 DSA_SIG_free(s);
Adam Langley95c29f32014-06-20 12:00:00 -0700739 return ret;
740}
741
Adam Langley95c29f32014-06-20 12:00:00 -0700742int DSA_size(const DSA *dsa) {
743 int ret, i;
744 ASN1_INTEGER bs;
745 unsigned char buf[4]; /* 4 bytes looks really small.
746 However, i2d_ASN1_INTEGER() will not look
747 beyond the first byte, as long as the second
748 parameter is NULL. */
749
750 i = BN_num_bits(dsa->q);
751 bs.length = (i + 7) / 8;
752 bs.data = buf;
753 bs.type = V_ASN1_INTEGER;
754 /* If the top bit is set the asn1 encoding is 1 larger. */
755 buf[0] = 0xff;
756
757 i = i2d_ASN1_INTEGER(&bs, NULL);
758 i += i; /* r and s */
759 ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
760 return ret;
761}
762
David Benjamine8f783a2015-10-30 16:53:00 -0400763int DSA_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv,
Adam Langley95c29f32014-06-20 12:00:00 -0700764 BIGNUM **out_r) {
David Benjamine8f783a2015-10-30 16:53:00 -0400765 BN_CTX *ctx;
766 BIGNUM k, kq, *K, *kinv = NULL, *r = NULL;
767 int ret = 0;
768
769 if (!dsa->p || !dsa->q || !dsa->g) {
770 OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS);
771 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700772 }
773
David Benjamine8f783a2015-10-30 16:53:00 -0400774 BN_init(&k);
775 BN_init(&kq);
776
777 ctx = ctx_in;
778 if (ctx == NULL) {
779 ctx = BN_CTX_new();
780 if (ctx == NULL) {
781 goto err;
782 }
783 }
784
785 r = BN_new();
786 if (r == NULL) {
787 goto err;
788 }
789
790 /* Get random k */
791 do {
792 if (!BN_rand_range(&k, dsa->q)) {
793 goto err;
794 }
795 } while (BN_is_zero(&k));
796
797 BN_set_flags(&k, BN_FLG_CONSTTIME);
798
799 if (BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
800 (CRYPTO_MUTEX *)&dsa->method_mont_p_lock, dsa->p,
801 ctx) == NULL) {
802 goto err;
803 }
804
805 /* Compute r = (g^k mod p) mod q */
806 if (!BN_copy(&kq, &k)) {
807 goto err;
808 }
809
810 /* We do not want timing information to leak the length of k,
811 * so we compute g^k using an equivalent exponent of fixed length.
812 *
813 * (This is a kludge that we need because the BN_mod_exp_mont()
814 * does not let us specify the desired timing behaviour.) */
815
816 if (!BN_add(&kq, &kq, dsa->q)) {
817 goto err;
818 }
819 if (BN_num_bits(&kq) <= BN_num_bits(dsa->q) && !BN_add(&kq, &kq, dsa->q)) {
820 goto err;
821 }
822
823 K = &kq;
824
825 if (!BN_mod_exp_mont(r, dsa->g, K, dsa->p, ctx, dsa->method_mont_p)) {
826 goto err;
827 }
828 if (!BN_mod(r, r, dsa->q, ctx)) {
829 goto err;
830 }
831
832 /* Compute part of 's = inv(k) (m + xr) mod q' */
833 kinv = BN_mod_inverse(NULL, &k, dsa->q, ctx);
834 if (kinv == NULL) {
835 goto err;
836 }
837
838 BN_clear_free(*out_kinv);
839 *out_kinv = kinv;
840 kinv = NULL;
841 BN_clear_free(*out_r);
842 *out_r = r;
843 ret = 1;
844
845err:
846 if (!ret) {
847 OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB);
848 if (r != NULL) {
849 BN_clear_free(r);
850 }
851 }
852
853 if (ctx_in == NULL) {
854 BN_CTX_free(ctx);
855 }
856 BN_clear_free(&k);
857 BN_clear_free(&kq);
858 return ret;
Adam Langley95c29f32014-06-20 12:00:00 -0700859}
860
David Benjamin8a589332015-12-04 23:14:35 -0500861int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
Adam Langley95c29f32014-06-20 12:00:00 -0700862 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
David Benjamin9f33fc62015-04-15 17:29:53 -0400863 int index;
David Benjamin8a589332015-12-04 23:14:35 -0500864 if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
865 free_func)) {
David Benjamin9f33fc62015-04-15 17:29:53 -0400866 return -1;
867 }
868 return index;
Adam Langley95c29f32014-06-20 12:00:00 -0700869}
870
871int DSA_set_ex_data(DSA *d, int idx, void *arg) {
872 return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
873}
874
875void *DSA_get_ex_data(const DSA *d, int idx) {
876 return CRYPTO_get_ex_data(&d->ex_data, idx);
877}
Adam Langleybed8ce72014-09-05 17:04:51 -0700878
879DH *DSA_dup_DH(const DSA *r) {
880 DH *ret = NULL;
881
882 if (r == NULL) {
883 goto err;
884 }
885 ret = DH_new();
886 if (ret == NULL) {
887 goto err;
888 }
889 if (r->q != NULL) {
890 ret->priv_length = BN_num_bits(r->q);
891 if ((ret->q = BN_dup(r->q)) == NULL) {
892 goto err;
893 }
894 }
895 if ((r->p != NULL && (ret->p = BN_dup(r->p)) == NULL) ||
896 (r->g != NULL && (ret->g = BN_dup(r->g)) == NULL) ||
897 (r->pub_key != NULL && (ret->pub_key = BN_dup(r->pub_key)) == NULL) ||
898 (r->priv_key != NULL && (ret->priv_key = BN_dup(r->priv_key)) == NULL)) {
899 goto err;
900 }
901
902 return ret;
903
904err:
David Benjamin22ccc2d2015-04-22 13:50:28 -0400905 DH_free(ret);
Adam Langleybed8ce72014-09-05 17:04:51 -0700906 return NULL;
907}