]>
Commit | Line | Data |
---|---|---|
d2e9e320 | 1 | /* |
47c239c6 | 2 | * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. |
d02b48c6 | 3 | * |
3cdbea65 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
d2e9e320 RS |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
d02b48c6 RE |
8 | */ |
9 | ||
f41ac0ee P |
10 | /* |
11 | * DSA low level APIs are deprecated for public use, but still ok for | |
12 | * internal use. | |
13 | */ | |
14 | #include "internal/deprecated.h" | |
15 | ||
d02b48c6 RE |
16 | #include <stdio.h> |
17 | #include <time.h> | |
b39fc560 | 18 | #include "internal/cryptlib.h" |
474e469b | 19 | #include <openssl/bn.h> |
47c239c6 | 20 | #include <openssl/self_test.h> |
f11f86f6 | 21 | #include "crypto/dsa.h" |
706457b7 | 22 | #include "dsa_local.h" |
d02b48c6 | 23 | |
b03ec3b5 SL |
24 | #ifdef FIPS_MODE |
25 | # define MIN_STRENGTH 112 | |
26 | #else | |
27 | # define MIN_STRENGTH 80 | |
28 | #endif | |
29 | ||
47c239c6 SL |
30 | static int dsa_keygen(DSA *dsa, int pairwise_test); |
31 | static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg); | |
0e4aa0d2 | 32 | |
6b691a5c | 33 | int DSA_generate_key(DSA *dsa) |
0f113f3e | 34 | { |
8083fd3a | 35 | #ifndef FIPS_MODE |
f11f86f6 | 36 | if (dsa->meth->dsa_keygen != NULL) |
0f113f3e | 37 | return dsa->meth->dsa_keygen(dsa); |
8083fd3a | 38 | #endif |
47c239c6 | 39 | return dsa_keygen(dsa, 0); |
0f113f3e | 40 | } |
0e4aa0d2 | 41 | |
8083fd3a SL |
42 | int dsa_generate_public_key(BN_CTX *ctx, const DSA *dsa, const BIGNUM *priv_key, |
43 | BIGNUM *pub_key) | |
f11f86f6 | 44 | { |
8083fd3a SL |
45 | int ret = 0; |
46 | BIGNUM *prk = BN_new(); | |
47 | ||
48 | if (prk == NULL) | |
49 | return 0; | |
50 | BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); | |
51 | ||
52 | /* pub_key = g ^ priv_key mod p */ | |
53 | if (!BN_mod_exp(pub_key, dsa->params.g, prk, dsa->params.p, ctx)) | |
54 | goto err; | |
55 | ret = 1; | |
56 | err: | |
57 | BN_clear_free(prk); | |
58 | return ret; | |
f11f86f6 SL |
59 | } |
60 | ||
47c239c6 | 61 | static int dsa_keygen(DSA *dsa, int pairwise_test) |
0f113f3e MC |
62 | { |
63 | int ok = 0; | |
64 | BN_CTX *ctx = NULL; | |
65 | BIGNUM *pub_key = NULL, *priv_key = NULL; | |
66 | ||
8083fd3a | 67 | if ((ctx = BN_CTX_new_ex(dsa->libctx)) == NULL) |
0f113f3e | 68 | goto err; |
d02b48c6 | 69 | |
0f113f3e | 70 | if (dsa->priv_key == NULL) { |
74924dcb | 71 | if ((priv_key = BN_secure_new()) == NULL) |
0f113f3e | 72 | goto err; |
f11f86f6 | 73 | } else { |
0f113f3e | 74 | priv_key = dsa->priv_key; |
f11f86f6 | 75 | } |
d02b48c6 | 76 | |
f11f86f6 | 77 | if (!ffc_generate_private_key(ctx, &dsa->params, BN_num_bits(dsa->params.q), |
b03ec3b5 | 78 | MIN_STRENGTH, priv_key)) |
f11f86f6 | 79 | goto err; |
d02b48c6 | 80 | |
0f113f3e MC |
81 | if (dsa->pub_key == NULL) { |
82 | if ((pub_key = BN_new()) == NULL) | |
83 | goto err; | |
f11f86f6 | 84 | } else { |
0f113f3e | 85 | pub_key = dsa->pub_key; |
f11f86f6 | 86 | } |
d02b48c6 | 87 | |
8083fd3a SL |
88 | if (!dsa_generate_public_key(ctx, dsa, priv_key, pub_key)) |
89 | goto err; | |
d02b48c6 | 90 | |
0f113f3e MC |
91 | dsa->priv_key = priv_key; |
92 | dsa->pub_key = pub_key; | |
47c239c6 SL |
93 | |
94 | #ifdef FIPS_MODE | |
95 | pairwise_test = 1; | |
96 | #endif /* FIPS_MODE */ | |
97 | ||
0f113f3e | 98 | ok = 1; |
47c239c6 SL |
99 | if (pairwise_test) { |
100 | OSSL_CALLBACK *cb = NULL; | |
101 | void *cbarg = NULL; | |
102 | ||
103 | OSSL_SELF_TEST_get_callback(dsa->libctx, &cb, &cbarg); | |
104 | ok = dsa_keygen_pairwise_test(dsa, cb, cbarg); | |
105 | if (!ok) { | |
106 | BN_free(dsa->pub_key); | |
107 | BN_clear_free(dsa->priv_key); | |
108 | BN_CTX_free(ctx); | |
109 | return ok; | |
110 | } | |
111 | } | |
112 | dsa->dirty_cnt++; | |
d02b48c6 | 113 | |
0f113f3e | 114 | err: |
23a1d5e9 | 115 | if (pub_key != dsa->pub_key) |
0f113f3e | 116 | BN_free(pub_key); |
23a1d5e9 | 117 | if (priv_key != dsa->priv_key) |
0f113f3e | 118 | BN_free(priv_key); |
23a1d5e9 | 119 | BN_CTX_free(ctx); |
47c239c6 | 120 | |
26a7d938 | 121 | return ok; |
0f113f3e | 122 | } |
47c239c6 SL |
123 | |
124 | /* | |
125 | * FIPS 140-2 IG 9.9 AS09.33 | |
126 | * Perform a sign/verify operation. | |
127 | */ | |
128 | static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg) | |
129 | { | |
130 | int ret = 0; | |
131 | unsigned char dgst[16] = {0}; | |
132 | unsigned int dgst_len = (unsigned int)sizeof(dgst); | |
133 | DSA_SIG *sig = NULL; | |
134 | OSSL_SELF_TEST *st = NULL; | |
135 | ||
136 | st = OSSL_SELF_TEST_new(cb, cbarg); | |
137 | if (st == NULL) | |
138 | goto err; | |
139 | ||
140 | OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT, | |
141 | OSSL_SELF_TEST_DESC_PCT_DSA); | |
142 | ||
143 | sig = DSA_do_sign(dgst, (int)dgst_len, dsa); | |
144 | if (sig == NULL) | |
145 | goto err; | |
146 | ||
147 | OSSL_SELF_TEST_oncorrupt_byte(st, dgst); | |
148 | ||
149 | if (DSA_do_verify(dgst, dgst_len, sig, dsa) != 1) | |
150 | goto err; | |
151 | ||
152 | ret = 1; | |
153 | err: | |
154 | OSSL_SELF_TEST_onend(st, ret); | |
155 | OSSL_SELF_TEST_free(st); | |
156 | DSA_SIG_free(sig); | |
157 | return ret; | |
158 | } |