/src/openssl/crypto/dsa/dsa_key.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. |
3 | | * |
4 | | * Licensed under the Apache License 2.0 (the "License"). You may not use |
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 |
8 | | */ |
9 | | |
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 | | |
16 | | #include <stdio.h> |
17 | | #include <time.h> |
18 | | #include "internal/cryptlib.h" |
19 | | #include <openssl/bn.h> |
20 | | #include <openssl/self_test.h> |
21 | | #include "prov/providercommon.h" |
22 | | #include "crypto/dsa.h" |
23 | | #include "dsa_local.h" |
24 | | |
25 | | #ifdef FIPS_MODULE |
26 | | # define MIN_STRENGTH 112 |
27 | | #else |
28 | 9 | # define MIN_STRENGTH 80 |
29 | | #endif |
30 | | |
31 | | static int dsa_keygen(DSA *dsa); |
32 | | |
33 | | int DSA_generate_key(DSA *dsa) |
34 | 53 | { |
35 | 53 | #ifndef FIPS_MODULE |
36 | 53 | if (dsa->meth->dsa_keygen != NULL) |
37 | 0 | return dsa->meth->dsa_keygen(dsa); |
38 | 53 | #endif |
39 | 53 | return dsa_keygen(dsa); |
40 | 53 | } |
41 | | |
42 | | int ossl_dsa_generate_public_key(BN_CTX *ctx, const DSA *dsa, |
43 | | const BIGNUM *priv_key, BIGNUM *pub_key) |
44 | 8 | { |
45 | 8 | int ret = 0; |
46 | 8 | BIGNUM *prk = BN_new(); |
47 | | |
48 | 8 | if (prk == NULL) |
49 | 0 | return 0; |
50 | 8 | BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); |
51 | | |
52 | | /* pub_key = g ^ priv_key mod p */ |
53 | 8 | if (!BN_mod_exp(pub_key, dsa->params.g, prk, dsa->params.p, ctx)) |
54 | 0 | goto err; |
55 | 8 | ret = 1; |
56 | 8 | err: |
57 | 8 | BN_clear_free(prk); |
58 | 8 | return ret; |
59 | 8 | } |
60 | | |
61 | | #ifdef FIPS_MODULE |
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 | | |
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) |
148 | 53 | { |
149 | 53 | int ok = 0; |
150 | 53 | BN_CTX *ctx = NULL; |
151 | 53 | BIGNUM *pub_key = NULL, *priv_key = NULL; |
152 | | |
153 | 53 | if ((ctx = BN_CTX_new_ex(dsa->libctx)) == NULL) |
154 | 0 | goto err; |
155 | | |
156 | 53 | if (dsa->priv_key == NULL) { |
157 | 0 | if ((priv_key = BN_secure_new()) == NULL) |
158 | 0 | goto err; |
159 | 53 | } else { |
160 | 53 | priv_key = dsa->priv_key; |
161 | 53 | } |
162 | | |
163 | | /* Do a partial check for invalid p, q, g */ |
164 | 53 | if (!ossl_ffc_params_simple_validate(dsa->libctx, &dsa->params, |
165 | 53 | FFC_PARAM_TYPE_DSA, NULL)) |
166 | 44 | goto err; |
167 | | |
168 | | /* |
169 | | * For FFC FIPS 186-4 keygen |
170 | | * security strength s = 112, |
171 | | * Max Private key size N = len(q) |
172 | | */ |
173 | 9 | if (!ossl_ffc_generate_private_key(ctx, &dsa->params, |
174 | 9 | BN_num_bits(dsa->params.q), |
175 | 9 | MIN_STRENGTH, priv_key)) |
176 | 1 | goto err; |
177 | | |
178 | 8 | if (dsa->pub_key == NULL) { |
179 | 0 | if ((pub_key = BN_new()) == NULL) |
180 | 0 | goto err; |
181 | 8 | } else { |
182 | 8 | pub_key = dsa->pub_key; |
183 | 8 | } |
184 | | |
185 | 8 | if (!ossl_dsa_generate_public_key(ctx, dsa, priv_key, pub_key)) |
186 | 0 | goto err; |
187 | | |
188 | 8 | dsa->priv_key = priv_key; |
189 | 8 | dsa->pub_key = pub_key; |
190 | | |
191 | 8 | ok = 1; |
192 | | #ifdef FIPS_MODULE |
193 | | { |
194 | | OSSL_CALLBACK *cb = NULL; |
195 | | void *cbarg = NULL; |
196 | | |
197 | | OSSL_SELF_TEST_get_callback(dsa->libctx, &cb, &cbarg); |
198 | | ok = dsa_keygen_pairwise_test(dsa, cb, cbarg) |
199 | | && dsa_keygen_knownanswer_test(dsa, ctx, cb, cbarg); |
200 | | if (!ok) { |
201 | | ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT); |
202 | | BN_free(dsa->pub_key); |
203 | | BN_clear_free(dsa->priv_key); |
204 | | dsa->pub_key = NULL; |
205 | | dsa->priv_key = NULL; |
206 | | BN_CTX_free(ctx); |
207 | | return ok; |
208 | | } |
209 | | } |
210 | | #endif |
211 | 8 | dsa->dirty_cnt++; |
212 | | |
213 | 53 | err: |
214 | 53 | if (pub_key != dsa->pub_key) |
215 | 44 | BN_free(pub_key); |
216 | 53 | if (priv_key != dsa->priv_key) |
217 | 0 | BN_free(priv_key); |
218 | 53 | BN_CTX_free(ctx); |
219 | | |
220 | 53 | return ok; |
221 | 8 | } |