]>
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 | ||
10 | #include <openssl/core_numbers.h> | |
11 | #include <openssl/core_names.h> | |
12 | #include <openssl/bn.h> | |
13 | #include <openssl/dh.h> | |
14 | #include <openssl/params.h> | |
1640d48c | 15 | #include "internal/param_build.h" |
af3e7e1b | 16 | #include "prov/implementations.h" |
1640d48c | 17 | #include "prov/providercommon.h" |
8b84b075 | 18 | |
14e3e00f | 19 | static OSSL_OP_keymgmt_importdomparams_fn dh_importdomparams; |
c8f23016 | 20 | static OSSL_OP_keymgmt_exportdomparams_fn dh_exportdomparams; |
8b84b075 | 21 | static OSSL_OP_keymgmt_importkey_fn dh_importkey; |
c8f23016 | 22 | static OSSL_OP_keymgmt_exportkey_fn dh_exportkey; |
8b84b075 | 23 | |
14e3e00f | 24 | static int params_to_domparams(DH *dh, const OSSL_PARAM params[]) |
8b84b075 | 25 | { |
14e3e00f RL |
26 | const OSSL_PARAM *param_p, *param_g; |
27 | BIGNUM *p = NULL, *g = NULL; | |
8b84b075 RL |
28 | |
29 | if (dh == NULL) | |
30 | return 0; | |
31 | ||
4889dadc MC |
32 | param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_P); |
33 | param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_G); | |
14e3e00f RL |
34 | |
35 | if ((param_p != NULL && !OSSL_PARAM_get_BN(param_p, &p)) | |
36 | || (param_g != NULL && !OSSL_PARAM_get_BN(param_g, &g))) | |
37 | goto err; | |
38 | ||
39 | if (!DH_set0_pqg(dh, p, NULL, g)) | |
40 | goto err; | |
41 | ||
42 | return 1; | |
43 | ||
44 | err: | |
45 | BN_free(p); | |
46 | BN_free(g); | |
47 | return 0; | |
48 | } | |
49 | ||
1640d48c | 50 | static int domparams_to_params(DH *dh, OSSL_PARAM_BLD *tmpl) |
c8f23016 | 51 | { |
c8f23016 RL |
52 | const BIGNUM *dh_p = NULL, *dh_g = NULL; |
53 | ||
54 | if (dh == NULL) | |
55 | return 0; | |
56 | ||
57 | DH_get0_pqg(dh, &dh_p, NULL, &dh_g); | |
1640d48c RL |
58 | if (dh_p != NULL |
59 | && !ossl_param_bld_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, dh_p)) | |
c8f23016 | 60 | return 0; |
1640d48c RL |
61 | if (dh_g != NULL |
62 | && !ossl_param_bld_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, dh_g)) | |
c8f23016 RL |
63 | return 0; |
64 | ||
65 | return 1; | |
66 | } | |
67 | ||
14e3e00f RL |
68 | static int params_to_key(DH *dh, const OSSL_PARAM params[]) |
69 | { | |
70 | const OSSL_PARAM *param_priv_key, *param_pub_key; | |
71 | BIGNUM *priv_key = NULL, *pub_key = NULL; | |
72 | ||
73 | if (dh == NULL) | |
74 | return 0; | |
75 | ||
76 | if (!params_to_domparams(dh, params)) | |
77 | return 0; | |
78 | ||
8b84b075 RL |
79 | param_priv_key = |
80 | OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PRIV_KEY); | |
81 | param_pub_key = | |
82 | OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PUB_KEY); | |
83 | ||
84 | /* | |
85 | * DH documentation says that a public key must be present if a | |
86 | * private key is present. | |
87 | * We want to have at least a public key either way, so we end up | |
88 | * requiring it unconditionally. | |
89 | */ | |
90 | if (param_pub_key == NULL) | |
91 | return 0; | |
92 | ||
14e3e00f RL |
93 | if ((param_priv_key != NULL |
94 | && !OSSL_PARAM_get_BN(param_priv_key, &priv_key)) | |
8b84b075 RL |
95 | || !OSSL_PARAM_get_BN(param_pub_key, &pub_key)) |
96 | goto err; | |
97 | ||
8b84b075 RL |
98 | if (!DH_set0_key(dh, pub_key, priv_key)) |
99 | goto err; | |
8b84b075 RL |
100 | |
101 | return 1; | |
102 | ||
103 | err: | |
8b84b075 RL |
104 | BN_free(priv_key); |
105 | BN_free(pub_key); | |
106 | return 0; | |
107 | } | |
108 | ||
1640d48c | 109 | static int key_to_params(DH *dh, OSSL_PARAM_BLD *tmpl) |
c8f23016 | 110 | { |
c8f23016 RL |
111 | const BIGNUM *priv_key = NULL, *pub_key = NULL; |
112 | ||
113 | if (dh == NULL) | |
114 | return 0; | |
1640d48c | 115 | if (!domparams_to_params(dh, tmpl)) |
c8f23016 RL |
116 | return 0; |
117 | ||
118 | DH_get0_key(dh, &pub_key, &priv_key); | |
1640d48c RL |
119 | if (priv_key != NULL |
120 | && !ossl_param_bld_push_BN(tmpl, OSSL_PKEY_PARAM_DH_PRIV_KEY, priv_key)) | |
c8f23016 | 121 | return 0; |
1640d48c RL |
122 | if (pub_key != NULL |
123 | && !ossl_param_bld_push_BN(tmpl, OSSL_PKEY_PARAM_DH_PUB_KEY, pub_key)) | |
c8f23016 RL |
124 | return 0; |
125 | ||
126 | return 1; | |
127 | } | |
128 | ||
14e3e00f RL |
129 | static void *dh_importdomparams(void *provctx, const OSSL_PARAM params[]) |
130 | { | |
131 | DH *dh; | |
132 | ||
133 | if ((dh = DH_new()) == NULL | |
134 | || !params_to_domparams(dh, params)) { | |
135 | DH_free(dh); | |
136 | dh = NULL; | |
137 | } | |
138 | return dh; | |
139 | } | |
140 | ||
1640d48c RL |
141 | static int dh_exportdomparams(void *domparams, OSSL_CALLBACK *param_cb, |
142 | void *cbarg) | |
c8f23016 RL |
143 | { |
144 | DH *dh = domparams; | |
1640d48c RL |
145 | OSSL_PARAM_BLD tmpl; |
146 | OSSL_PARAM *params = NULL; | |
147 | int ret; | |
148 | ||
149 | ossl_param_bld_init(&tmpl); | |
150 | if (dh == NULL | |
151 | || !domparams_to_params(dh, &tmpl) | |
152 | || (params = ossl_param_bld_to_param(&tmpl)) == NULL) | |
153 | return 0; | |
154 | ret = param_cb(params, cbarg); | |
155 | ossl_param_bld_free(params); | |
156 | return ret; | |
c8f23016 RL |
157 | } |
158 | ||
8b84b075 RL |
159 | static void *dh_importkey(void *provctx, const OSSL_PARAM params[]) |
160 | { | |
161 | DH *dh; | |
162 | ||
163 | if ((dh = DH_new()) == NULL | |
164 | || !params_to_key(dh, params)) { | |
165 | DH_free(dh); | |
166 | dh = NULL; | |
167 | } | |
168 | return dh; | |
169 | } | |
170 | ||
1640d48c | 171 | static int dh_exportkey(void *key, OSSL_CALLBACK *param_cb, void *cbarg) |
c8f23016 RL |
172 | { |
173 | DH *dh = key; | |
1640d48c RL |
174 | OSSL_PARAM_BLD tmpl; |
175 | OSSL_PARAM *params = NULL; | |
176 | int ret; | |
177 | ||
178 | ossl_param_bld_init(&tmpl); | |
179 | if (dh == NULL | |
180 | || !key_to_params(dh, &tmpl) | |
181 | || (params = ossl_param_bld_to_param(&tmpl)) == NULL) | |
182 | return 0; | |
183 | ret = param_cb(params, cbarg); | |
184 | ossl_param_bld_free(params); | |
185 | return ret; | |
c8f23016 RL |
186 | } |
187 | ||
8b84b075 RL |
188 | const OSSL_DISPATCH dh_keymgmt_functions[] = { |
189 | /* | |
190 | * TODO(3.0) When implementing OSSL_FUNC_KEYMGMT_GENKEY, remember to also | |
191 | * implement OSSL_FUNC_KEYMGMT_EXPORTKEY. | |
192 | */ | |
14e3e00f | 193 | { OSSL_FUNC_KEYMGMT_IMPORTDOMPARAMS, (void (*)(void))dh_importdomparams }, |
c8f23016 | 194 | { OSSL_FUNC_KEYMGMT_EXPORTDOMPARAMS, (void (*)(void))dh_exportdomparams }, |
14e3e00f | 195 | { OSSL_FUNC_KEYMGMT_FREEDOMPARAMS, (void (*)(void))DH_free }, |
8b84b075 | 196 | { OSSL_FUNC_KEYMGMT_IMPORTKEY, (void (*)(void))dh_importkey }, |
c8f23016 | 197 | { OSSL_FUNC_KEYMGMT_EXPORTKEY, (void (*)(void))dh_exportkey }, |
8b84b075 RL |
198 | { OSSL_FUNC_KEYMGMT_FREEKEY, (void (*)(void))DH_free }, |
199 | { 0, NULL } | |
200 | }; |