]>
Commit | Line | Data |
---|---|---|
d2e9e320 | 1 | /* |
da1c088f | 2 | * Copyright 1995-2023 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> |
35e6ea3b | 21 | #include "prov/providercommon.h" |
f11f86f6 | 22 | #include "crypto/dsa.h" |
706457b7 | 23 | #include "dsa_local.h" |
d02b48c6 | 24 | |
f844f9eb | 25 | #ifdef FIPS_MODULE |
b03ec3b5 SL |
26 | # define MIN_STRENGTH 112 |
27 | #else | |
28 | # define MIN_STRENGTH 80 | |
29 | #endif | |
30 | ||
a76ccb9d | 31 | static int dsa_keygen(DSA *dsa); |
0e4aa0d2 | 32 | |
6b691a5c | 33 | int DSA_generate_key(DSA *dsa) |
0f113f3e | 34 | { |
f844f9eb | 35 | #ifndef FIPS_MODULE |
f11f86f6 | 36 | if (dsa->meth->dsa_keygen != NULL) |
0f113f3e | 37 | return dsa->meth->dsa_keygen(dsa); |
8083fd3a | 38 | #endif |
a76ccb9d | 39 | return dsa_keygen(dsa); |
0f113f3e | 40 | } |
0e4aa0d2 | 41 | |
5af02212 SL |
42 | int ossl_dsa_generate_public_key(BN_CTX *ctx, const DSA *dsa, |
43 | const BIGNUM *priv_key, 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 | ||
a76ccb9d | 61 | #ifdef FIPS_MODULE |
5b234be4 P |
62 | /* |
63 | * Refer: FIPS 140-3 IG 10.3.A Additional Comment 1 | |
64 | * Perform a KAT by duplicating the public key generation. | |
65 | * | |
66 | * NOTE: This issue requires a background understanding, provided in a separate | |
67 | * document; the current IG 10.3.A AC1 is insufficient regarding the PCT for | |
68 | * the key agreement scenario. | |
69 | * | |
70 | * Currently IG 10.3.A requires PCT in the mode of use prior to use of the | |
71 | * key pair, citing the PCT defined in the associated standard. For key | |
72 | * agreement, the only PCT defined in SP 800-56A is that of Section 5.6.2.4: | |
73 | * the comparison of the original public key to a newly calculated public key. | |
74 | */ | |
75 | static int dsa_keygen_knownanswer_test(DSA *dsa, BN_CTX *ctx, | |
76 | OSSL_CALLBACK *cb, void *cbarg) | |
77 | { | |
78 | int len, ret = 0; | |
79 | OSSL_SELF_TEST *st = NULL; | |
80 | unsigned char bytes[512] = {0}; | |
81 | BIGNUM *pub_key2 = BN_new(); | |
82 | ||
83 | if (pub_key2 == NULL) | |
84 | return 0; | |
85 | ||
86 | st = OSSL_SELF_TEST_new(cb, cbarg); | |
87 | if (st == NULL) | |
88 | goto err; | |
89 | ||
90 | OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT_KAT, | |
91 | OSSL_SELF_TEST_DESC_PCT_DSA); | |
92 | ||
93 | if (!ossl_dsa_generate_public_key(ctx, dsa, dsa->priv_key, pub_key2)) | |
94 | goto err; | |
95 | ||
96 | if (BN_num_bytes(pub_key2) > (int)sizeof(bytes)) | |
97 | goto err; | |
98 | len = BN_bn2bin(pub_key2, bytes); | |
99 | OSSL_SELF_TEST_oncorrupt_byte(st, bytes); | |
100 | if (BN_bin2bn(bytes, len, pub_key2) != NULL) | |
101 | ret = !BN_cmp(dsa->pub_key, pub_key2); | |
102 | ||
103 | err: | |
104 | OSSL_SELF_TEST_onend(st, ret); | |
105 | OSSL_SELF_TEST_free(st); | |
106 | BN_free(pub_key2); | |
107 | return ret; | |
108 | } | |
109 | ||
a76ccb9d | 110 | /* |
111 | * FIPS 140-2 IG 9.9 AS09.33 | |
112 | * Perform a sign/verify operation. | |
113 | */ | |
114 | static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg) | |
115 | { | |
116 | int ret = 0; | |
117 | unsigned char dgst[16] = {0}; | |
118 | unsigned int dgst_len = (unsigned int)sizeof(dgst); | |
119 | DSA_SIG *sig = NULL; | |
120 | OSSL_SELF_TEST *st = NULL; | |
121 | ||
122 | st = OSSL_SELF_TEST_new(cb, cbarg); | |
123 | if (st == NULL) | |
124 | goto err; | |
125 | ||
126 | OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT, | |
127 | OSSL_SELF_TEST_DESC_PCT_DSA); | |
128 | ||
129 | sig = DSA_do_sign(dgst, (int)dgst_len, dsa); | |
130 | if (sig == NULL) | |
131 | goto err; | |
132 | ||
133 | OSSL_SELF_TEST_oncorrupt_byte(st, dgst); | |
134 | ||
135 | if (DSA_do_verify(dgst, dgst_len, sig, dsa) != 1) | |
136 | goto err; | |
137 | ||
138 | ret = 1; | |
139 | err: | |
140 | OSSL_SELF_TEST_onend(st, ret); | |
141 | OSSL_SELF_TEST_free(st); | |
142 | DSA_SIG_free(sig); | |
143 | return ret; | |
144 | } | |
145 | #endif /* FIPS_MODULE */ | |
146 | ||
147 | static int dsa_keygen(DSA *dsa) | |
0f113f3e MC |
148 | { |
149 | int ok = 0; | |
150 | BN_CTX *ctx = NULL; | |
151 | BIGNUM *pub_key = NULL, *priv_key = NULL; | |
152 | ||
8083fd3a | 153 | if ((ctx = BN_CTX_new_ex(dsa->libctx)) == NULL) |
0f113f3e | 154 | goto err; |
d02b48c6 | 155 | |
0f113f3e | 156 | if (dsa->priv_key == NULL) { |
74924dcb | 157 | if ((priv_key = BN_secure_new()) == NULL) |
0f113f3e | 158 | goto err; |
f11f86f6 | 159 | } else { |
0f113f3e | 160 | priv_key = dsa->priv_key; |
f11f86f6 | 161 | } |
d02b48c6 | 162 | |
63794b04 | 163 | /* Do a partial check for invalid p, q, g */ |
5357c106 | 164 | if (!ossl_ffc_params_simple_validate(dsa->libctx, &dsa->params, |
ba37b820 | 165 | FFC_PARAM_TYPE_DSA, NULL)) |
63794b04 SL |
166 | goto err; |
167 | ||
738ee181 SL |
168 | /* |
169 | * For FFC FIPS 186-4 keygen | |
170 | * security strength s = 112, | |
171 | * Max Private key size N = len(q) | |
172 | */ | |
5357c106 P |
173 | if (!ossl_ffc_generate_private_key(ctx, &dsa->params, |
174 | BN_num_bits(dsa->params.q), | |
175 | MIN_STRENGTH, priv_key)) | |
f11f86f6 | 176 | goto err; |
d02b48c6 | 177 | |
0f113f3e MC |
178 | if (dsa->pub_key == NULL) { |
179 | if ((pub_key = BN_new()) == NULL) | |
180 | goto err; | |
f11f86f6 | 181 | } else { |
0f113f3e | 182 | pub_key = dsa->pub_key; |
f11f86f6 | 183 | } |
d02b48c6 | 184 | |
5af02212 | 185 | if (!ossl_dsa_generate_public_key(ctx, dsa, priv_key, pub_key)) |
8083fd3a | 186 | goto err; |
d02b48c6 | 187 | |
0f113f3e MC |
188 | dsa->priv_key = priv_key; |
189 | dsa->pub_key = pub_key; | |
47c239c6 | 190 | |
0f113f3e | 191 | ok = 1; |
a76ccb9d | 192 | #ifdef FIPS_MODULE |
193 | { | |
47c239c6 SL |
194 | OSSL_CALLBACK *cb = NULL; |
195 | void *cbarg = NULL; | |
196 | ||
197 | OSSL_SELF_TEST_get_callback(dsa->libctx, &cb, &cbarg); | |
5b234be4 P |
198 | ok = dsa_keygen_pairwise_test(dsa, cb, cbarg) |
199 | && dsa_keygen_knownanswer_test(dsa, ctx, cb, cbarg); | |
47c239c6 | 200 | if (!ok) { |
35e6ea3b | 201 | ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT); |
47c239c6 SL |
202 | BN_free(dsa->pub_key); |
203 | BN_clear_free(dsa->priv_key); | |
63794b04 SL |
204 | dsa->pub_key = NULL; |
205 | dsa->priv_key = NULL; | |
47c239c6 SL |
206 | BN_CTX_free(ctx); |
207 | return ok; | |
208 | } | |
209 | } | |
a76ccb9d | 210 | #endif |
47c239c6 | 211 | dsa->dirty_cnt++; |
d02b48c6 | 212 | |
0f113f3e | 213 | err: |
23a1d5e9 | 214 | if (pub_key != dsa->pub_key) |
0f113f3e | 215 | BN_free(pub_key); |
23a1d5e9 | 216 | if (priv_key != dsa->priv_key) |
0f113f3e | 217 | BN_free(priv_key); |
23a1d5e9 | 218 | BN_CTX_free(ctx); |
47c239c6 | 219 | |
26a7d938 | 220 | return ok; |
0f113f3e | 221 | } |