]>
Commit | Line | Data |
---|---|---|
8b84b075 RL |
1 | /* |
2 | * Copyright 2019 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 | ||
ada66e78 P |
10 | /* |
11 | * DH low level APIs are deprecated for public use, but still ok for | |
12 | * internal use. | |
13 | */ | |
14 | #include "internal/deprecated.h" | |
15 | ||
8b84b075 RL |
16 | #include <openssl/core_numbers.h> |
17 | #include <openssl/core_names.h> | |
18 | #include <openssl/bn.h> | |
a54ff473 | 19 | #include <openssl/dh.h> |
8b84b075 | 20 | #include <openssl/params.h> |
af3e7e1b | 21 | #include "prov/implementations.h" |
1640d48c | 22 | #include "prov/providercommon.h" |
8083fd3a SL |
23 | #include "prov/provider_ctx.h" |
24 | #include "crypto/dh.h" | |
a54ff473 | 25 | #include "internal/param_build.h" |
8b84b075 | 26 | |
8dd5c603 RL |
27 | static OSSL_OP_keymgmt_new_fn dh_newdata; |
28 | static OSSL_OP_keymgmt_free_fn dh_freedata; | |
273a67e3 RL |
29 | static OSSL_OP_keymgmt_get_params_fn dh_get_params; |
30 | static OSSL_OP_keymgmt_gettable_params_fn dh_gettable_params; | |
8dd5c603 | 31 | static OSSL_OP_keymgmt_has_fn dh_has; |
2888fc15 | 32 | static OSSL_OP_keymgmt_match_fn dh_match; |
a54ff473 | 33 | static OSSL_OP_keymgmt_validate_fn dh_validate; |
8dd5c603 | 34 | static OSSL_OP_keymgmt_import_fn dh_import; |
273a67e3 | 35 | static OSSL_OP_keymgmt_import_types_fn dh_import_types; |
8dd5c603 | 36 | static OSSL_OP_keymgmt_export_fn dh_export; |
273a67e3 | 37 | static OSSL_OP_keymgmt_export_types_fn dh_export_types; |
8dd5c603 RL |
38 | |
39 | #define DH_POSSIBLE_SELECTIONS \ | |
273a67e3 | 40 | (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) |
8b84b075 | 41 | |
1640d48c | 42 | static int domparams_to_params(DH *dh, OSSL_PARAM_BLD *tmpl) |
c8f23016 | 43 | { |
c8f23016 RL |
44 | const BIGNUM *dh_p = NULL, *dh_g = NULL; |
45 | ||
46 | if (dh == NULL) | |
47 | return 0; | |
48 | ||
49 | DH_get0_pqg(dh, &dh_p, NULL, &dh_g); | |
1640d48c RL |
50 | if (dh_p != NULL |
51 | && !ossl_param_bld_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, dh_p)) | |
c8f23016 | 52 | return 0; |
1640d48c RL |
53 | if (dh_g != NULL |
54 | && !ossl_param_bld_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, dh_g)) | |
c8f23016 RL |
55 | return 0; |
56 | ||
57 | return 1; | |
58 | } | |
59 | ||
1640d48c | 60 | static int key_to_params(DH *dh, OSSL_PARAM_BLD *tmpl) |
c8f23016 | 61 | { |
c8f23016 RL |
62 | const BIGNUM *priv_key = NULL, *pub_key = NULL; |
63 | ||
64 | if (dh == NULL) | |
65 | return 0; | |
1640d48c | 66 | if (!domparams_to_params(dh, tmpl)) |
c8f23016 RL |
67 | return 0; |
68 | ||
69 | DH_get0_key(dh, &pub_key, &priv_key); | |
1640d48c | 70 | if (priv_key != NULL |
90d3cb57 | 71 | && !ossl_param_bld_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY, priv_key)) |
c8f23016 | 72 | return 0; |
1640d48c | 73 | if (pub_key != NULL |
90d3cb57 | 74 | && !ossl_param_bld_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY, pub_key)) |
c8f23016 RL |
75 | return 0; |
76 | ||
77 | return 1; | |
78 | } | |
79 | ||
8dd5c603 | 80 | static void *dh_newdata(void *provctx) |
14e3e00f | 81 | { |
8083fd3a | 82 | return dh_new_with_ctx(PROV_LIBRARY_CONTEXT_OF(provctx)); |
14e3e00f RL |
83 | } |
84 | ||
8dd5c603 | 85 | static void dh_freedata(void *keydata) |
c8f23016 | 86 | { |
8dd5c603 RL |
87 | DH_free(keydata); |
88 | } | |
1640d48c | 89 | |
8dd5c603 RL |
90 | static int dh_has(void *keydata, int selection) |
91 | { | |
92 | DH *dh = keydata; | |
93 | int ok = 0; | |
94 | ||
adc9f731 RL |
95 | if (dh != NULL) { |
96 | if ((selection & DH_POSSIBLE_SELECTIONS) != 0) | |
97 | ok = 1; | |
98 | ||
99 | if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) | |
100 | ok = ok && (DH_get0_pub_key(dh) != NULL); | |
101 | if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) | |
102 | ok = ok && (DH_get0_priv_key(dh) != NULL); | |
103 | if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) | |
104 | ok = ok && (DH_get0_p(dh) != NULL && DH_get0_g(dh) != NULL); | |
105 | } | |
8dd5c603 | 106 | return ok; |
c8f23016 RL |
107 | } |
108 | ||
2888fc15 RL |
109 | static int dh_match(const void *keydata1, const void *keydata2, int selection) |
110 | { | |
111 | const DH *dh1 = keydata1; | |
112 | const DH *dh2 = keydata2; | |
113 | int ok = 1; | |
114 | ||
115 | if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) | |
116 | ok = ok && BN_cmp(DH_get0_pub_key(dh1), DH_get0_pub_key(dh2)) == 0; | |
117 | if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) | |
118 | ok = ok && BN_cmp(DH_get0_priv_key(dh1), DH_get0_priv_key(dh2)) == 0; | |
119 | if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { | |
120 | FFC_PARAMS *dhparams1 = dh_get0_params((DH *)dh1); | |
121 | FFC_PARAMS *dhparams2 = dh_get0_params((DH *)dh2); | |
122 | ||
123 | ok = ok && ffc_params_cmp(dhparams1, dhparams2, 1); | |
124 | } | |
125 | return ok; | |
126 | } | |
127 | ||
8dd5c603 | 128 | static int dh_import(void *keydata, int selection, const OSSL_PARAM params[]) |
8b84b075 | 129 | { |
8dd5c603 RL |
130 | DH *dh = keydata; |
131 | int ok = 0; | |
132 | ||
133 | if (dh == NULL) | |
134 | return 0; | |
135 | ||
136 | if ((selection & DH_POSSIBLE_SELECTIONS) != 0) | |
137 | ok = 1; | |
138 | ||
139 | if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) | |
0abae163 | 140 | ok = ok && ffc_fromdata(dh_get0_params(dh), params); |
8dd5c603 | 141 | if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) |
0abae163 | 142 | ok = ok && dh_key_fromdata(dh, params); |
8dd5c603 RL |
143 | |
144 | return ok; | |
8b84b075 RL |
145 | } |
146 | ||
8dd5c603 RL |
147 | static int dh_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, |
148 | void *cbarg) | |
c8f23016 | 149 | { |
8dd5c603 | 150 | DH *dh = keydata; |
1640d48c RL |
151 | OSSL_PARAM_BLD tmpl; |
152 | OSSL_PARAM *params = NULL; | |
8dd5c603 RL |
153 | int ok = 1; |
154 | ||
155 | if (dh == NULL) | |
156 | return 0; | |
1640d48c RL |
157 | |
158 | ossl_param_bld_init(&tmpl); | |
8dd5c603 RL |
159 | |
160 | if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) | |
161 | ok = ok && domparams_to_params(dh, &tmpl); | |
162 | if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) | |
163 | ok = ok && key_to_params(dh, &tmpl); | |
164 | ||
165 | if (!ok | |
1640d48c RL |
166 | || (params = ossl_param_bld_to_param(&tmpl)) == NULL) |
167 | return 0; | |
8dd5c603 RL |
168 | |
169 | ok = param_cb(params, cbarg); | |
1640d48c | 170 | ossl_param_bld_free(params); |
8dd5c603 | 171 | return ok; |
c8f23016 RL |
172 | } |
173 | ||
273a67e3 RL |
174 | /* IMEXPORT = IMPORT + EXPORT */ |
175 | ||
176 | # define DH_IMEXPORTABLE_PARAMETERS \ | |
177 | OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_P, NULL, 0), \ | |
178 | OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_G, NULL, 0) | |
179 | # define DH_IMEXPORTABLE_PUBLIC_KEY \ | |
90d3cb57 | 180 | OSSL_PARAM_BN(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0) |
273a67e3 | 181 | # define DH_IMEXPORTABLE_PRIVATE_KEY \ |
90d3cb57 | 182 | OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0) |
273a67e3 RL |
183 | static const OSSL_PARAM dh_all_types[] = { |
184 | DH_IMEXPORTABLE_PARAMETERS, | |
185 | DH_IMEXPORTABLE_PUBLIC_KEY, | |
186 | DH_IMEXPORTABLE_PRIVATE_KEY, | |
187 | OSSL_PARAM_END | |
188 | }; | |
189 | static const OSSL_PARAM dh_parameter_types[] = { | |
190 | DH_IMEXPORTABLE_PARAMETERS, | |
191 | OSSL_PARAM_END | |
192 | }; | |
193 | static const OSSL_PARAM dh_key_types[] = { | |
194 | DH_IMEXPORTABLE_PUBLIC_KEY, | |
195 | DH_IMEXPORTABLE_PRIVATE_KEY, | |
196 | OSSL_PARAM_END | |
197 | }; | |
198 | static const OSSL_PARAM *dh_types[] = { | |
199 | NULL, /* Index 0 = none of them */ | |
200 | dh_parameter_types, /* Index 1 = parameter types */ | |
201 | dh_key_types, /* Index 2 = key types */ | |
202 | dh_all_types /* Index 3 = 1 + 2 */ | |
203 | }; | |
204 | ||
205 | static const OSSL_PARAM *dh_imexport_types(int selection) | |
206 | { | |
207 | int type_select = 0; | |
208 | ||
209 | if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) | |
210 | type_select += 1; | |
211 | if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) | |
212 | type_select += 2; | |
213 | return dh_types[type_select]; | |
214 | } | |
215 | ||
216 | static const OSSL_PARAM *dh_import_types(int selection) | |
217 | { | |
218 | return dh_imexport_types(selection); | |
219 | } | |
220 | ||
221 | static const OSSL_PARAM *dh_export_types(int selection) | |
222 | { | |
223 | return dh_imexport_types(selection); | |
224 | } | |
225 | ||
8dd5c603 | 226 | static ossl_inline int dh_get_params(void *key, OSSL_PARAM params[]) |
9e5aaf78 RL |
227 | { |
228 | DH *dh = key; | |
229 | OSSL_PARAM *p; | |
230 | ||
231 | if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL | |
232 | && !OSSL_PARAM_set_int(p, DH_bits(dh))) | |
233 | return 0; | |
234 | if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL | |
235 | && !OSSL_PARAM_set_int(p, DH_security_bits(dh))) | |
236 | return 0; | |
237 | if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL | |
238 | && !OSSL_PARAM_set_int(p, DH_size(dh))) | |
239 | return 0; | |
240 | return 1; | |
241 | } | |
242 | ||
273a67e3 RL |
243 | static const OSSL_PARAM dh_params[] = { |
244 | OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), | |
245 | OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), | |
246 | OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), | |
247 | OSSL_PARAM_END | |
248 | }; | |
249 | ||
250 | static const OSSL_PARAM *dh_gettable_params(void) | |
251 | { | |
252 | return dh_params; | |
253 | } | |
254 | ||
a54ff473 SL |
255 | static int dh_validate_public(DH *dh) |
256 | { | |
257 | const BIGNUM *pub_key = NULL; | |
258 | ||
259 | DH_get0_key(dh, &pub_key, NULL); | |
260 | return DH_check_pub_key_ex(dh, pub_key); | |
261 | } | |
262 | ||
263 | static int dh_validate_private(DH *dh) | |
264 | { | |
265 | int status = 0; | |
266 | const BIGNUM *priv_key = NULL; | |
267 | ||
268 | DH_get0_key(dh, NULL, &priv_key); | |
269 | return dh_check_priv_key(dh, priv_key, &status);; | |
270 | } | |
271 | ||
272 | static int dh_validate(void *keydata, int selection) | |
273 | { | |
274 | DH *dh = keydata; | |
275 | int ok = 0; | |
276 | ||
277 | if ((selection & DH_POSSIBLE_SELECTIONS) != 0) | |
278 | ok = 1; | |
279 | ||
280 | if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) | |
281 | ok = ok && DH_check_params_ex(dh); | |
282 | ||
283 | if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) | |
284 | ok = ok && dh_validate_public(dh); | |
285 | ||
286 | if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) | |
287 | ok = ok && dh_validate_private(dh); | |
288 | ||
289 | if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) | |
290 | == OSSL_KEYMGMT_SELECT_KEYPAIR) | |
291 | ok = ok && dh_check_pairwise(dh); | |
292 | return ok; | |
293 | } | |
294 | ||
8b84b075 | 295 | const OSSL_DISPATCH dh_keymgmt_functions[] = { |
8dd5c603 RL |
296 | { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dh_newdata }, |
297 | { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))dh_freedata }, | |
273a67e3 RL |
298 | { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))dh_get_params }, |
299 | { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))dh_gettable_params }, | |
8dd5c603 | 300 | { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))dh_has }, |
2888fc15 | 301 | { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))dh_match }, |
a54ff473 | 302 | { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))dh_validate }, |
8dd5c603 | 303 | { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))dh_import }, |
273a67e3 | 304 | { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))dh_import_types }, |
8dd5c603 | 305 | { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))dh_export }, |
273a67e3 | 306 | { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dh_export_types }, |
8b84b075 RL |
307 | { 0, NULL } |
308 | }; |