1 /* 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
62 #include <string.h>
63
64 #include <openssl/asn1.h>
65 #include <openssl/bn.h>
66 #include <openssl/dh.h>
67 #include <openssl/digest.h>
68 #include <openssl/engine.h>
69 #include <openssl/err.h>
70 #include <openssl/ex_data.h>
71 #include <openssl/mem.h>
72 #include <openssl/rand.h>
73 #include <openssl/sha.h>
74 #include <openssl/thread.h>
75
76 #include "internal.h"
77 #include "../internal.h"
78
79
80 #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
85
86 static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
87
DSA_new(void)88 DSA *DSA_new(void) {
89 DSA *dsa = (DSA *)OPENSSL_malloc(sizeof(DSA));
90 if (dsa == NULL) {
91 OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE);
92 return NULL;
93 }
94
95 memset(dsa, 0, sizeof(DSA));
96
97 dsa->write_params = 1;
98 dsa->references = 1;
99
100 CRYPTO_MUTEX_init(&dsa->method_mont_p_lock);
101 CRYPTO_new_ex_data(&dsa->ex_data);
102
103 return dsa;
104 }
105
DSA_free(DSA * dsa)106 void DSA_free(DSA *dsa) {
107 if (dsa == NULL) {
108 return;
109 }
110
111 if (!CRYPTO_refcount_dec_and_test_zero(&dsa->references)) {
112 return;
113 }
114
115 CRYPTO_free_ex_data(&g_ex_data_class, dsa, &dsa->ex_data);
116
117 BN_clear_free(dsa->p);
118 BN_clear_free(dsa->q);
119 BN_clear_free(dsa->g);
120 BN_clear_free(dsa->pub_key);
121 BN_clear_free(dsa->priv_key);
122 BN_clear_free(dsa->kinv);
123 BN_clear_free(dsa->r);
124 BN_MONT_CTX_free(dsa->method_mont_p);
125 CRYPTO_MUTEX_cleanup(&dsa->method_mont_p_lock);
126 OPENSSL_free(dsa);
127 }
128
DSA_up_ref(DSA * dsa)129 int DSA_up_ref(DSA *dsa) {
130 CRYPTO_refcount_inc(&dsa->references);
131 return 1;
132 }
133
DSA_generate_parameters_ex(DSA * dsa,unsigned bits,const uint8_t * seed_in,size_t seed_len,int * out_counter,unsigned long * out_h,BN_GENCB * cb)134 int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
135 size_t seed_len, int *out_counter,
136 unsigned long *out_h, BN_GENCB *cb) {
137 int ok = 0;
138 unsigned char seed[SHA256_DIGEST_LENGTH];
139 unsigned char md[SHA256_DIGEST_LENGTH];
140 unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
141 BIGNUM *r0, *W, *X, *c, *test;
142 BIGNUM *g = NULL, *q = NULL, *p = NULL;
143 BN_MONT_CTX *mont = NULL;
144 int k, n = 0, m = 0;
145 unsigned i;
146 int counter = 0;
147 int r = 0;
148 BN_CTX *ctx = NULL;
149 unsigned int h = 2;
150 unsigned qsize;
151 const EVP_MD *evpmd;
152
153 evpmd = (bits >= 2048) ? EVP_sha256() : EVP_sha1();
154 qsize = EVP_MD_size(evpmd);
155
156 if (bits < 512) {
157 bits = 512;
158 }
159
160 bits = (bits + 63) / 64 * 64;
161
162 if (seed_in != NULL) {
163 if (seed_len < (size_t)qsize) {
164 return 0;
165 }
166 if (seed_len > (size_t)qsize) {
167 /* Only consume as much seed as is expected. */
168 seed_len = qsize;
169 }
170 memcpy(seed, seed_in, seed_len);
171 }
172
173 ctx = BN_CTX_new();
174 if (ctx == NULL) {
175 goto err;
176 }
177 BN_CTX_start(ctx);
178
179 mont = BN_MONT_CTX_new();
180 if (mont == NULL) {
181 goto err;
182 }
183
184 r0 = BN_CTX_get(ctx);
185 g = BN_CTX_get(ctx);
186 W = BN_CTX_get(ctx);
187 q = BN_CTX_get(ctx);
188 X = BN_CTX_get(ctx);
189 c = BN_CTX_get(ctx);
190 p = BN_CTX_get(ctx);
191 test = BN_CTX_get(ctx);
192
193 if (test == NULL || !BN_lshift(test, BN_value_one(), bits - 1)) {
194 goto err;
195 }
196
197 for (;;) {
198 /* Find q. */
199 for (;;) {
200 /* step 1 */
201 if (!BN_GENCB_call(cb, 0, m++)) {
202 goto err;
203 }
204
205 int use_random_seed = (seed_in == NULL);
206 if (use_random_seed) {
207 if (!RAND_bytes(seed, qsize)) {
208 goto err;
209 }
210 } else {
211 /* If we come back through, use random seed next time. */
212 seed_in = NULL;
213 }
214 memcpy(buf, seed, qsize);
215 memcpy(buf2, seed, qsize);
216 /* precompute "SEED + 1" for step 7: */
217 for (i = qsize - 1; i < qsize; i--) {
218 buf[i]++;
219 if (buf[i] != 0) {
220 break;
221 }
222 }
223
224 /* step 2 */
225 if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL) ||
226 !EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) {
227 goto err;
228 }
229 for (i = 0; i < qsize; i++) {
230 md[i] ^= buf2[i];
231 }
232
233 /* step 3 */
234 md[0] |= 0x80;
235 md[qsize - 1] |= 0x01;
236 if (!BN_bin2bn(md, qsize, q)) {
237 goto err;
238 }
239
240 /* step 4 */
241 r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, use_random_seed, cb);
242 if (r > 0) {
243 break;
244 }
245 if (r != 0) {
246 goto err;
247 }
248
249 /* do a callback call */
250 /* step 5 */
251 }
252
253 if (!BN_GENCB_call(cb, 2, 0) || !BN_GENCB_call(cb, 3, 0)) {
254 goto err;
255 }
256
257 /* step 6 */
258 counter = 0;
259 /* "offset = 2" */
260
261 n = (bits - 1) / 160;
262
263 for (;;) {
264 if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) {
265 goto err;
266 }
267
268 /* step 7 */
269 BN_zero(W);
270 /* now 'buf' contains "SEED + offset - 1" */
271 for (k = 0; k <= n; k++) {
272 /* obtain "SEED + offset + k" by incrementing: */
273 for (i = qsize - 1; i < qsize; i--) {
274 buf[i]++;
275 if (buf[i] != 0) {
276 break;
277 }
278 }
279
280 if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL)) {
281 goto err;
282 }
283
284 /* step 8 */
285 if (!BN_bin2bn(md, qsize, r0) ||
286 !BN_lshift(r0, r0, (qsize << 3) * k) ||
287 !BN_add(W, W, r0)) {
288 goto err;
289 }
290 }
291
292 /* more of step 8 */
293 if (!BN_mask_bits(W, bits - 1) ||
294 !BN_copy(X, W) ||
295 !BN_add(X, X, test)) {
296 goto err;
297 }
298
299 /* step 9 */
300 if (!BN_lshift1(r0, q) ||
301 !BN_mod(c, X, r0, ctx) ||
302 !BN_sub(r0, c, BN_value_one()) ||
303 !BN_sub(p, X, r0)) {
304 goto err;
305 }
306
307 /* step 10 */
308 if (BN_cmp(p, test) >= 0) {
309 /* step 11 */
310 r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
311 if (r > 0) {
312 goto end; /* found it */
313 }
314 if (r != 0) {
315 goto err;
316 }
317 }
318
319 /* step 13 */
320 counter++;
321 /* "offset = offset + n + 1" */
322
323 /* step 14 */
324 if (counter >= 4096) {
325 break;
326 }
327 }
328 }
329 end:
330 if (!BN_GENCB_call(cb, 2, 1)) {
331 goto err;
332 }
333
334 /* We now need to generate g */
335 /* Set r0=(p-1)/q */
336 if (!BN_sub(test, p, BN_value_one()) ||
337 !BN_div(r0, NULL, test, q, ctx)) {
338 goto err;
339 }
340
341 if (!BN_set_word(test, h) ||
342 !BN_MONT_CTX_set(mont, p, ctx)) {
343 goto err;
344 }
345
346 for (;;) {
347 /* g=test^r0%p */
348 if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont)) {
349 goto err;
350 }
351 if (!BN_is_one(g)) {
352 break;
353 }
354 if (!BN_add(test, test, BN_value_one())) {
355 goto err;
356 }
357 h++;
358 }
359
360 if (!BN_GENCB_call(cb, 3, 1)) {
361 goto err;
362 }
363
364 ok = 1;
365
366 err:
367 if (ok) {
368 BN_free(dsa->p);
369 BN_free(dsa->q);
370 BN_free(dsa->g);
371 dsa->p = BN_dup(p);
372 dsa->q = BN_dup(q);
373 dsa->g = BN_dup(g);
374 if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
375 ok = 0;
376 goto err;
377 }
378 if (out_counter != NULL) {
379 *out_counter = counter;
380 }
381 if (out_h != NULL) {
382 *out_h = h;
383 }
384 }
385
386 if (ctx) {
387 BN_CTX_end(ctx);
388 BN_CTX_free(ctx);
389 }
390
391 BN_MONT_CTX_free(mont);
392
393 return ok;
394 }
395
DSA_generate_key(DSA * dsa)396 int DSA_generate_key(DSA *dsa) {
397 int ok = 0;
398 BN_CTX *ctx = NULL;
399 BIGNUM *pub_key = NULL, *priv_key = NULL;
400 BIGNUM prk;
401
402 ctx = BN_CTX_new();
403 if (ctx == NULL) {
404 goto err;
405 }
406
407 priv_key = dsa->priv_key;
408 if (priv_key == NULL) {
409 priv_key = BN_new();
410 if (priv_key == NULL) {
411 goto err;
412 }
413 }
414
415 do {
416 if (!BN_rand_range(priv_key, dsa->q)) {
417 goto err;
418 }
419 } while (BN_is_zero(priv_key));
420
421 pub_key = dsa->pub_key;
422 if (pub_key == NULL) {
423 pub_key = BN_new();
424 if (pub_key == NULL) {
425 goto err;
426 }
427 }
428
429 BN_init(&prk);
430 BN_with_flags(&prk, priv_key, BN_FLG_CONSTTIME);
431
432 if (!BN_mod_exp(pub_key, dsa->g, &prk, dsa->p, ctx)) {
433 goto err;
434 }
435
436 dsa->priv_key = priv_key;
437 dsa->pub_key = pub_key;
438 ok = 1;
439
440 err:
441 if (dsa->pub_key == NULL) {
442 BN_free(pub_key);
443 }
444 if (dsa->priv_key == NULL) {
445 BN_free(priv_key);
446 }
447 BN_CTX_free(ctx);
448
449 return ok;
450 }
451
DSA_SIG_new(void)452 DSA_SIG *DSA_SIG_new(void) {
453 DSA_SIG *sig;
454 sig = OPENSSL_malloc(sizeof(DSA_SIG));
455 if (!sig) {
456 return NULL;
457 }
458 sig->r = NULL;
459 sig->s = NULL;
460 return sig;
461 }
462
DSA_SIG_free(DSA_SIG * sig)463 void DSA_SIG_free(DSA_SIG *sig) {
464 if (!sig) {
465 return;
466 }
467
468 BN_free(sig->r);
469 BN_free(sig->s);
470 OPENSSL_free(sig);
471 }
472
DSA_do_sign(const uint8_t * digest,size_t digest_len,DSA * dsa)473 DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, DSA *dsa) {
474 BIGNUM *kinv = NULL, *r = NULL, *s = NULL;
475 BIGNUM m;
476 BIGNUM xr;
477 BN_CTX *ctx = NULL;
478 int reason = ERR_R_BN_LIB;
479 DSA_SIG *ret = NULL;
480 int noredo = 0;
481
482 BN_init(&m);
483 BN_init(&xr);
484
485 if (!dsa->p || !dsa->q || !dsa->g) {
486 reason = DSA_R_MISSING_PARAMETERS;
487 goto err;
488 }
489
490 s = BN_new();
491 if (s == NULL) {
492 goto err;
493 }
494 ctx = BN_CTX_new();
495 if (ctx == NULL) {
496 goto err;
497 }
498
499 redo:
500 if (dsa->kinv == NULL || dsa->r == NULL) {
501 if (!DSA_sign_setup(dsa, ctx, &kinv, &r)) {
502 goto err;
503 }
504 } else {
505 kinv = dsa->kinv;
506 dsa->kinv = NULL;
507 r = dsa->r;
508 dsa->r = NULL;
509 noredo = 1;
510 }
511
512 if (digest_len > BN_num_bytes(dsa->q)) {
513 /* if the digest length is greater than the size of q use the
514 * BN_num_bits(dsa->q) leftmost bits of the digest, see
515 * fips 186-3, 4.2 */
516 digest_len = BN_num_bytes(dsa->q);
517 }
518
519 if (BN_bin2bn(digest, digest_len, &m) == NULL) {
520 goto err;
521 }
522
523 /* Compute s = inv(k) (m + xr) mod q */
524 if (!BN_mod_mul(&xr, dsa->priv_key, r, dsa->q, ctx)) {
525 goto err; /* s = xr */
526 }
527 if (!BN_add(s, &xr, &m)) {
528 goto err; /* s = m + xr */
529 }
530 if (BN_cmp(s, dsa->q) > 0) {
531 if (!BN_sub(s, s, dsa->q)) {
532 goto err;
533 }
534 }
535 if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) {
536 goto err;
537 }
538
539 /* Redo if r or s is zero as required by FIPS 186-3: this is
540 * very unlikely. */
541 if (BN_is_zero(r) || BN_is_zero(s)) {
542 if (noredo) {
543 reason = DSA_R_NEED_NEW_SETUP_VALUES;
544 goto err;
545 }
546 goto redo;
547 }
548 ret = DSA_SIG_new();
549 if (ret == NULL) {
550 goto err;
551 }
552 ret->r = r;
553 ret->s = s;
554
555 err:
556 if (ret == NULL) {
557 OPENSSL_PUT_ERROR(DSA, reason);
558 BN_free(r);
559 BN_free(s);
560 }
561 BN_CTX_free(ctx);
562 BN_clear_free(&m);
563 BN_clear_free(&xr);
564 BN_clear_free(kinv);
565
566 return ret;
567 }
568
DSA_do_verify(const uint8_t * digest,size_t digest_len,DSA_SIG * sig,const DSA * dsa)569 int DSA_do_verify(const uint8_t *digest, size_t digest_len, DSA_SIG *sig,
570 const DSA *dsa) {
571 int valid;
572 if (!DSA_do_check_signature(&valid, digest, digest_len, sig, dsa)) {
573 return -1;
574 }
575 return valid;
576 }
577
DSA_do_check_signature(int * out_valid,const uint8_t * digest,size_t digest_len,DSA_SIG * sig,const DSA * dsa)578 int DSA_do_check_signature(int *out_valid, const uint8_t *digest,
579 size_t digest_len, DSA_SIG *sig, const DSA *dsa) {
580 BN_CTX *ctx;
581 BIGNUM u1, u2, t1;
582 BN_MONT_CTX *mont = NULL;
583 int ret = 0;
584 unsigned i;
585
586 *out_valid = 0;
587
588 if (!dsa->p || !dsa->q || !dsa->g) {
589 OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS);
590 return 0;
591 }
592
593 i = BN_num_bits(dsa->q);
594 /* fips 186-3 allows only different sizes for q */
595 if (i != 160 && i != 224 && i != 256) {
596 OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_Q_VALUE);
597 return 0;
598 }
599
600 if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
601 OPENSSL_PUT_ERROR(DSA, DSA_R_MODULUS_TOO_LARGE);
602 return 0;
603 }
604
605 BN_init(&u1);
606 BN_init(&u2);
607 BN_init(&t1);
608
609 ctx = BN_CTX_new();
610 if (ctx == NULL) {
611 goto err;
612 }
613
614 if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
615 BN_ucmp(sig->r, dsa->q) >= 0) {
616 ret = 1;
617 goto err;
618 }
619 if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
620 BN_ucmp(sig->s, dsa->q) >= 0) {
621 ret = 1;
622 goto err;
623 }
624
625 /* Calculate W = inv(S) mod Q
626 * save W in u2 */
627 if (BN_mod_inverse(&u2, sig->s, dsa->q, ctx) == NULL) {
628 goto err;
629 }
630
631 /* save M in u1 */
632 if (digest_len > (i >> 3)) {
633 /* if the digest length is greater than the size of q use the
634 * BN_num_bits(dsa->q) leftmost bits of the digest, see
635 * fips 186-3, 4.2 */
636 digest_len = (i >> 3);
637 }
638
639 if (BN_bin2bn(digest, digest_len, &u1) == NULL) {
640 goto err;
641 }
642
643 /* u1 = M * w mod q */
644 if (!BN_mod_mul(&u1, &u1, &u2, dsa->q, ctx)) {
645 goto err;
646 }
647
648 /* u2 = r * w mod q */
649 if (!BN_mod_mul(&u2, sig->r, &u2, dsa->q, ctx)) {
650 goto err;
651 }
652
653 mont = BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
654 (CRYPTO_MUTEX *)&dsa->method_mont_p_lock,
655 dsa->p, ctx);
656 if (!mont) {
657 goto err;
658 }
659
660 if (!BN_mod_exp2_mont(&t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx,
661 mont)) {
662 goto err;
663 }
664
665 /* BN_copy(&u1,&t1); */
666 /* let u1 = u1 mod q */
667 if (!BN_mod(&u1, &t1, dsa->q, ctx)) {
668 goto err;
669 }
670
671 /* V is now in u1. If the signature is correct, it will be
672 * equal to R. */
673 *out_valid = BN_ucmp(&u1, sig->r) == 0;
674 ret = 1;
675
676 err:
677 if (ret != 1) {
678 OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB);
679 }
680 BN_CTX_free(ctx);
681 BN_free(&u1);
682 BN_free(&u2);
683 BN_free(&t1);
684
685 return ret;
686 }
687
DSA_sign(int type,const uint8_t * digest,size_t digest_len,uint8_t * out_sig,unsigned int * out_siglen,DSA * dsa)688 int DSA_sign(int type, const uint8_t *digest, size_t digest_len,
689 uint8_t *out_sig, unsigned int *out_siglen, DSA *dsa) {
690 DSA_SIG *s;
691
692 s = DSA_do_sign(digest, digest_len, dsa);
693 if (s == NULL) {
694 *out_siglen = 0;
695 return 0;
696 }
697
698 *out_siglen = i2d_DSA_SIG(s, &out_sig);
699 DSA_SIG_free(s);
700 return 1;
701 }
702
DSA_verify(int type,const uint8_t * digest,size_t digest_len,const uint8_t * sig,size_t sig_len,const DSA * dsa)703 int DSA_verify(int type, const uint8_t *digest, size_t digest_len,
704 const uint8_t *sig, size_t sig_len, const DSA *dsa) {
705 int valid;
706 if (!DSA_check_signature(&valid, digest, digest_len, sig, sig_len, dsa)) {
707 return -1;
708 }
709 return valid;
710 }
711
DSA_check_signature(int * out_valid,const uint8_t * digest,size_t digest_len,const uint8_t * sig,size_t sig_len,const DSA * dsa)712 int DSA_check_signature(int *out_valid, const uint8_t *digest,
713 size_t digest_len, const uint8_t *sig, size_t sig_len,
714 const DSA *dsa) {
715 DSA_SIG *s = NULL;
716 int ret = 0;
717 uint8_t *der = NULL;
718
719 s = DSA_SIG_new();
720 if (s == NULL) {
721 goto err;
722 }
723
724 const uint8_t *sigp = sig;
725 if (d2i_DSA_SIG(&s, &sigp, sig_len) == NULL || sigp != sig + sig_len) {
726 goto err;
727 }
728
729 /* Ensure that the signature uses DER and doesn't have trailing garbage. */
730 int der_len = i2d_DSA_SIG(s, &der);
731 if (der_len < 0 || (size_t)der_len != sig_len || memcmp(sig, der, sig_len)) {
732 goto err;
733 }
734
735 ret = DSA_do_check_signature(out_valid, digest, digest_len, s, dsa);
736
737 err:
738 OPENSSL_free(der);
739 DSA_SIG_free(s);
740 return ret;
741 }
742
DSA_size(const DSA * dsa)743 int DSA_size(const DSA *dsa) {
744 int ret, i;
745 ASN1_INTEGER bs;
746 unsigned char buf[4]; /* 4 bytes looks really small.
747 However, i2d_ASN1_INTEGER() will not look
748 beyond the first byte, as long as the second
749 parameter is NULL. */
750
751 i = BN_num_bits(dsa->q);
752 bs.length = (i + 7) / 8;
753 bs.data = buf;
754 bs.type = V_ASN1_INTEGER;
755 /* If the top bit is set the asn1 encoding is 1 larger. */
756 buf[0] = 0xff;
757
758 i = i2d_ASN1_INTEGER(&bs, NULL);
759 i += i; /* r and s */
760 ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
761 return ret;
762 }
763
DSA_sign_setup(const DSA * dsa,BN_CTX * ctx_in,BIGNUM ** out_kinv,BIGNUM ** out_r)764 int DSA_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv,
765 BIGNUM **out_r) {
766 BN_CTX *ctx;
767 BIGNUM k, kq, *K, *kinv = NULL, *r = NULL;
768 int ret = 0;
769
770 if (!dsa->p || !dsa->q || !dsa->g) {
771 OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS);
772 return 0;
773 }
774
775 BN_init(&k);
776 BN_init(&kq);
777
778 ctx = ctx_in;
779 if (ctx == NULL) {
780 ctx = BN_CTX_new();
781 if (ctx == NULL) {
782 goto err;
783 }
784 }
785
786 r = BN_new();
787 if (r == NULL) {
788 goto err;
789 }
790
791 /* Get random k */
792 do {
793 if (!BN_rand_range(&k, dsa->q)) {
794 goto err;
795 }
796 } while (BN_is_zero(&k));
797
798 BN_set_flags(&k, BN_FLG_CONSTTIME);
799
800 if (BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
801 (CRYPTO_MUTEX *)&dsa->method_mont_p_lock, dsa->p,
802 ctx) == NULL) {
803 goto err;
804 }
805
806 /* Compute r = (g^k mod p) mod q */
807 if (!BN_copy(&kq, &k)) {
808 goto err;
809 }
810
811 /* We do not want timing information to leak the length of k,
812 * so we compute g^k using an equivalent exponent of fixed length.
813 *
814 * (This is a kludge that we need because the BN_mod_exp_mont()
815 * does not let us specify the desired timing behaviour.) */
816
817 if (!BN_add(&kq, &kq, dsa->q)) {
818 goto err;
819 }
820 if (BN_num_bits(&kq) <= BN_num_bits(dsa->q) && !BN_add(&kq, &kq, dsa->q)) {
821 goto err;
822 }
823
824 K = &kq;
825
826 if (!BN_mod_exp_mont(r, dsa->g, K, dsa->p, ctx, dsa->method_mont_p)) {
827 goto err;
828 }
829 if (!BN_mod(r, r, dsa->q, ctx)) {
830 goto err;
831 }
832
833 /* Compute part of 's = inv(k) (m + xr) mod q' */
834 kinv = BN_mod_inverse(NULL, &k, dsa->q, ctx);
835 if (kinv == NULL) {
836 goto err;
837 }
838
839 BN_clear_free(*out_kinv);
840 *out_kinv = kinv;
841 kinv = NULL;
842 BN_clear_free(*out_r);
843 *out_r = r;
844 ret = 1;
845
846 err:
847 if (!ret) {
848 OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB);
849 if (r != NULL) {
850 BN_clear_free(r);
851 }
852 }
853
854 if (ctx_in == NULL) {
855 BN_CTX_free(ctx);
856 }
857 BN_clear_free(&k);
858 BN_clear_free(&kq);
859 return ret;
860 }
861
DSA_get_ex_new_index(long argl,void * argp,CRYPTO_EX_unused * unused,CRYPTO_EX_dup * dup_func,CRYPTO_EX_free * free_func)862 int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
863 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
864 int index;
865 if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
866 free_func)) {
867 return -1;
868 }
869 return index;
870 }
871
DSA_set_ex_data(DSA * d,int idx,void * arg)872 int DSA_set_ex_data(DSA *d, int idx, void *arg) {
873 return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
874 }
875
DSA_get_ex_data(const DSA * d,int idx)876 void *DSA_get_ex_data(const DSA *d, int idx) {
877 return CRYPTO_get_ex_data(&d->ex_data, idx);
878 }
879
DSA_dup_DH(const DSA * r)880 DH *DSA_dup_DH(const DSA *r) {
881 DH *ret = NULL;
882
883 if (r == NULL) {
884 goto err;
885 }
886 ret = DH_new();
887 if (ret == NULL) {
888 goto err;
889 }
890 if (r->q != NULL) {
891 ret->priv_length = BN_num_bits(r->q);
892 if ((ret->q = BN_dup(r->q)) == NULL) {
893 goto err;
894 }
895 }
896 if ((r->p != NULL && (ret->p = BN_dup(r->p)) == NULL) ||
897 (r->g != NULL && (ret->g = BN_dup(r->g)) == NULL) ||
898 (r->pub_key != NULL && (ret->pub_key = BN_dup(r->pub_key)) == NULL) ||
899 (r->priv_key != NULL && (ret->priv_key = BN_dup(r->priv_key)) == NULL)) {
900 goto err;
901 }
902
903 return ret;
904
905 err:
906 DH_free(ret);
907 return NULL;
908 }
909