/src/openssl31/crypto/dsa/dsa_key.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 1995-2022 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 | 0 | # define MIN_STRENGTH 80 |
29 | | #endif |
30 | | |
31 | | static int dsa_keygen(DSA *dsa, int pairwise_test); |
32 | | static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg); |
33 | | |
34 | | int DSA_generate_key(DSA *dsa) |
35 | 0 | { |
36 | 0 | #ifndef FIPS_MODULE |
37 | 0 | if (dsa->meth->dsa_keygen != NULL) |
38 | 0 | return dsa->meth->dsa_keygen(dsa); |
39 | 0 | #endif |
40 | 0 | return dsa_keygen(dsa, 0); |
41 | 0 | } |
42 | | |
43 | | int ossl_dsa_generate_public_key(BN_CTX *ctx, const DSA *dsa, |
44 | | const BIGNUM *priv_key, BIGNUM *pub_key) |
45 | 23 | { |
46 | 23 | int ret = 0; |
47 | 23 | BIGNUM *prk = BN_new(); |
48 | | |
49 | 23 | if (prk == NULL) |
50 | 0 | return 0; |
51 | 23 | BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); |
52 | | |
53 | | /* pub_key = g ^ priv_key mod p */ |
54 | 23 | if (!BN_mod_exp(pub_key, dsa->params.g, prk, dsa->params.p, ctx)) |
55 | 2 | goto err; |
56 | 21 | ret = 1; |
57 | 23 | err: |
58 | 23 | BN_clear_free(prk); |
59 | 23 | return ret; |
60 | 21 | } |
61 | | |
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 | 0 | { |
78 | 0 | int len, ret = 0; |
79 | 0 | OSSL_SELF_TEST *st = NULL; |
80 | 0 | unsigned char bytes[512] = {0}; |
81 | 0 | BIGNUM *pub_key2 = BN_new(); |
82 | |
|
83 | 0 | if (pub_key2 == NULL) |
84 | 0 | return 0; |
85 | | |
86 | 0 | st = OSSL_SELF_TEST_new(cb, cbarg); |
87 | 0 | if (st == NULL) |
88 | 0 | goto err; |
89 | | |
90 | 0 | OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT_KAT, |
91 | 0 | OSSL_SELF_TEST_DESC_PCT_DSA); |
92 | |
|
93 | 0 | if (!ossl_dsa_generate_public_key(ctx, dsa, dsa->priv_key, pub_key2)) |
94 | 0 | goto err; |
95 | | |
96 | 0 | if (BN_num_bytes(pub_key2) > (int)sizeof(bytes)) |
97 | 0 | goto err; |
98 | 0 | len = BN_bn2bin(pub_key2, bytes); |
99 | 0 | OSSL_SELF_TEST_oncorrupt_byte(st, bytes); |
100 | 0 | if (BN_bin2bn(bytes, len, pub_key2) != NULL) |
101 | 0 | ret = !BN_cmp(dsa->pub_key, pub_key2); |
102 | |
|
103 | 0 | err: |
104 | 0 | OSSL_SELF_TEST_onend(st, ret); |
105 | 0 | OSSL_SELF_TEST_free(st); |
106 | 0 | BN_free(pub_key2); |
107 | 0 | return ret; |
108 | 0 | } |
109 | | |
110 | | static int dsa_keygen(DSA *dsa, int pairwise_test) |
111 | 0 | { |
112 | 0 | int ok = 0; |
113 | 0 | BN_CTX *ctx = NULL; |
114 | 0 | BIGNUM *pub_key = NULL, *priv_key = NULL; |
115 | |
|
116 | 0 | if ((ctx = BN_CTX_new_ex(dsa->libctx)) == NULL) |
117 | 0 | goto err; |
118 | | |
119 | 0 | if (dsa->priv_key == NULL) { |
120 | 0 | if ((priv_key = BN_secure_new()) == NULL) |
121 | 0 | goto err; |
122 | 0 | } else { |
123 | 0 | priv_key = dsa->priv_key; |
124 | 0 | } |
125 | | |
126 | | /* Do a partial check for invalid p, q, g */ |
127 | 0 | if (!ossl_ffc_params_simple_validate(dsa->libctx, &dsa->params, |
128 | 0 | FFC_PARAM_TYPE_DSA, NULL)) |
129 | 0 | goto err; |
130 | | |
131 | | /* |
132 | | * For FFC FIPS 186-4 keygen |
133 | | * security strength s = 112, |
134 | | * Max Private key size N = len(q) |
135 | | */ |
136 | 0 | if (!ossl_ffc_generate_private_key(ctx, &dsa->params, |
137 | 0 | BN_num_bits(dsa->params.q), |
138 | 0 | MIN_STRENGTH, priv_key)) |
139 | 0 | goto err; |
140 | | |
141 | 0 | if (dsa->pub_key == NULL) { |
142 | 0 | if ((pub_key = BN_new()) == NULL) |
143 | 0 | goto err; |
144 | 0 | } else { |
145 | 0 | pub_key = dsa->pub_key; |
146 | 0 | } |
147 | | |
148 | 0 | if (!ossl_dsa_generate_public_key(ctx, dsa, priv_key, pub_key)) |
149 | 0 | goto err; |
150 | | |
151 | 0 | dsa->priv_key = priv_key; |
152 | 0 | dsa->pub_key = pub_key; |
153 | |
|
154 | | #ifdef FIPS_MODULE |
155 | | pairwise_test = 1; |
156 | | #endif /* FIPS_MODULE */ |
157 | |
|
158 | 0 | ok = 1; |
159 | 0 | if (pairwise_test) { |
160 | 0 | OSSL_CALLBACK *cb = NULL; |
161 | 0 | void *cbarg = NULL; |
162 | |
|
163 | 0 | OSSL_SELF_TEST_get_callback(dsa->libctx, &cb, &cbarg); |
164 | 0 | ok = dsa_keygen_pairwise_test(dsa, cb, cbarg) |
165 | 0 | && dsa_keygen_knownanswer_test(dsa, ctx, cb, cbarg); |
166 | 0 | if (!ok) { |
167 | 0 | ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT); |
168 | 0 | BN_free(dsa->pub_key); |
169 | 0 | BN_clear_free(dsa->priv_key); |
170 | 0 | dsa->pub_key = NULL; |
171 | 0 | dsa->priv_key = NULL; |
172 | 0 | BN_CTX_free(ctx); |
173 | 0 | return ok; |
174 | 0 | } |
175 | 0 | } |
176 | 0 | dsa->dirty_cnt++; |
177 | |
|
178 | 0 | err: |
179 | 0 | if (pub_key != dsa->pub_key) |
180 | 0 | BN_free(pub_key); |
181 | 0 | if (priv_key != dsa->priv_key) |
182 | 0 | BN_free(priv_key); |
183 | 0 | BN_CTX_free(ctx); |
184 | |
|
185 | 0 | return ok; |
186 | 0 | } |
187 | | |
188 | | /* |
189 | | * FIPS 140-2 IG 9.9 AS09.33 |
190 | | * Perform a sign/verify operation. |
191 | | */ |
192 | | static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg) |
193 | 0 | { |
194 | 0 | int ret = 0; |
195 | 0 | unsigned char dgst[16] = {0}; |
196 | 0 | unsigned int dgst_len = (unsigned int)sizeof(dgst); |
197 | 0 | DSA_SIG *sig = NULL; |
198 | 0 | OSSL_SELF_TEST *st = NULL; |
199 | |
|
200 | 0 | st = OSSL_SELF_TEST_new(cb, cbarg); |
201 | 0 | if (st == NULL) |
202 | 0 | goto err; |
203 | | |
204 | 0 | OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT, |
205 | 0 | OSSL_SELF_TEST_DESC_PCT_DSA); |
206 | |
|
207 | 0 | sig = DSA_do_sign(dgst, (int)dgst_len, dsa); |
208 | 0 | if (sig == NULL) |
209 | 0 | goto err; |
210 | | |
211 | 0 | OSSL_SELF_TEST_oncorrupt_byte(st, dgst); |
212 | |
|
213 | 0 | if (DSA_do_verify(dgst, dgst_len, sig, dsa) != 1) |
214 | 0 | goto err; |
215 | | |
216 | 0 | ret = 1; |
217 | 0 | err: |
218 | 0 | OSSL_SELF_TEST_onend(st, ret); |
219 | 0 | OSSL_SELF_TEST_free(st); |
220 | 0 | DSA_SIG_free(sig); |
221 | 0 | return ret; |
222 | 0 | } |