/src/boringssl/crypto/evp/evp_ctx.cc
Line | Count | Source |
1 | | // Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #include <openssl/evp.h> |
16 | | |
17 | | #include <string.h> |
18 | | |
19 | | #include <openssl/digest.h> |
20 | | #include <openssl/err.h> |
21 | | #include <openssl/mem.h> |
22 | | |
23 | | #include "../internal.h" |
24 | | #include "../mem_internal.h" |
25 | | #include "internal.h" |
26 | | |
27 | | |
28 | | using namespace bssl; |
29 | | |
30 | | static UniquePtr<EvpPkeyCtx> evp_pkey_ctx_new( |
31 | 56.3k | EvpPkey *pkey, const EVP_PKEY_ALG *alg, const EVP_PKEY_CTX_METHOD *pmeth) { |
32 | 56.3k | assert(pkey != nullptr || alg != nullptr); |
33 | 56.3k | UniquePtr<EvpPkeyCtx> ret = MakeUnique<EvpPkeyCtx>(); |
34 | 56.3k | if (!ret) { |
35 | 0 | return nullptr; |
36 | 0 | } |
37 | | |
38 | 56.3k | ret->pmeth = pmeth; |
39 | 56.3k | ret->operation = EVP_PKEY_OP_UNDEFINED; |
40 | 56.3k | ret->pkey = UpRef(pkey); |
41 | | |
42 | 56.3k | if (pmeth->init && pmeth->init(ret.get(), alg) <= 0) { |
43 | 0 | ret->pmeth = nullptr; // Don't call |pmeth->cleanup|. |
44 | 0 | return nullptr; |
45 | 0 | } |
46 | | |
47 | 56.3k | return ret; |
48 | 56.3k | } |
49 | | |
50 | 56.3k | EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) { |
51 | 56.3k | auto *pkey_impl = FromOpaque(pkey); |
52 | 56.3k | if (pkey_impl == nullptr || pkey_impl->ameth == nullptr) { |
53 | 0 | OPENSSL_PUT_ERROR(EVP, ERR_R_PASSED_NULL_PARAMETER); |
54 | 0 | return nullptr; |
55 | 0 | } |
56 | 56.3k | if (pkey_impl->pkey == nullptr) { |
57 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); |
58 | 0 | return nullptr; |
59 | 0 | } |
60 | | |
61 | 56.3k | const EVP_PKEY_CTX_METHOD *pkey_method = pkey_impl->ameth->pkey_method; |
62 | 56.3k | if (pkey_method == nullptr) { |
63 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); |
64 | 0 | ERR_add_error_dataf("algorithm %d", pkey_impl->ameth->pkey_id); |
65 | 0 | return nullptr; |
66 | 0 | } |
67 | | |
68 | 56.3k | return evp_pkey_ctx_new(pkey_impl, nullptr, pkey_method).release(); |
69 | 56.3k | } |
70 | | |
71 | 0 | EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) { |
72 | | // |EVP_PKEY_RSA_PSS| is intentionally omitted from this list. These are types |
73 | | // that can be created without an |EVP_PKEY|, and we do not support |
74 | | // |EVP_PKEY_RSA_PSS| keygen. |
75 | 0 | const EVP_PKEY_ALG *alg = nullptr; |
76 | 0 | switch (id) { |
77 | 0 | case EVP_PKEY_RSA: |
78 | 0 | alg = EVP_pkey_rsa(); |
79 | 0 | break; |
80 | 0 | case EVP_PKEY_EC: |
81 | 0 | alg = evp_pkey_ec_no_curve(); |
82 | 0 | break; |
83 | 0 | case EVP_PKEY_ED25519: |
84 | 0 | alg = EVP_pkey_ed25519(); |
85 | 0 | break; |
86 | 0 | case EVP_PKEY_X25519: |
87 | 0 | alg = EVP_pkey_x25519(); |
88 | 0 | break; |
89 | 0 | case EVP_PKEY_HKDF: |
90 | 0 | alg = evp_pkey_hkdf(); |
91 | 0 | break; |
92 | 0 | case EVP_PKEY_ML_DSA_44: |
93 | 0 | alg = EVP_pkey_ml_dsa_44(); |
94 | 0 | break; |
95 | 0 | case EVP_PKEY_ML_DSA_65: |
96 | 0 | alg = EVP_pkey_ml_dsa_65(); |
97 | 0 | break; |
98 | 0 | case EVP_PKEY_ML_DSA_87: |
99 | 0 | alg = EVP_pkey_ml_dsa_87(); |
100 | 0 | break; |
101 | 0 | } |
102 | 0 | if (alg == nullptr || alg->pkey_method == nullptr) { |
103 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); |
104 | 0 | ERR_add_error_dataf("algorithm %d", id); |
105 | 0 | return nullptr; |
106 | 0 | } |
107 | 0 | return evp_pkey_ctx_new_alg(alg).release(); |
108 | 0 | } |
109 | | |
110 | 0 | UniquePtr<EvpPkeyCtx> bssl::evp_pkey_ctx_new_alg(const EVP_PKEY_ALG *alg) { |
111 | 0 | return evp_pkey_ctx_new(nullptr, alg, alg->pkey_method); |
112 | 0 | } |
113 | | |
114 | 112k | EvpPkeyCtx::~EvpPkeyCtx() { |
115 | 112k | if (pmeth && pmeth->cleanup) { |
116 | 112k | pmeth->cleanup(this); |
117 | 112k | } |
118 | 112k | } |
119 | | |
120 | 112k | void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) { Delete(FromOpaque(ctx)); } |
121 | | |
122 | 56.3k | EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx) { |
123 | 56.3k | auto *impl = FromOpaque(ctx); |
124 | | |
125 | 56.3k | if (!impl->pmeth || !impl->pmeth->copy) { |
126 | 0 | return nullptr; |
127 | 0 | } |
128 | | |
129 | 56.3k | UniquePtr<EvpPkeyCtx> ret = MakeUnique<EvpPkeyCtx>(); |
130 | 56.3k | if (!ret) { |
131 | 0 | return nullptr; |
132 | 0 | } |
133 | | |
134 | 56.3k | ret->pmeth = impl->pmeth; |
135 | 56.3k | ret->operation = impl->operation; |
136 | 56.3k | ret->pkey = UpRef(impl->pkey); |
137 | 56.3k | ret->peerkey = UpRef(impl->peerkey); |
138 | 56.3k | if (impl->pmeth->copy(ret.get(), impl) <= 0) { |
139 | 0 | ret->pmeth = nullptr; // Don't call |pmeth->cleanup|. |
140 | 0 | OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); |
141 | 0 | return nullptr; |
142 | 0 | } |
143 | | |
144 | 56.3k | return ret.release(); |
145 | 56.3k | } |
146 | | |
147 | 0 | EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) { |
148 | 0 | auto *impl = FromOpaque(ctx); |
149 | 0 | return impl->pkey.get(); |
150 | 0 | } |
151 | | |
152 | | int bssl::EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, |
153 | 90.4k | int p1, void *p2) { |
154 | 90.4k | auto *impl = FromOpaque(ctx); |
155 | 90.4k | if (!impl || !impl->pmeth || !impl->pmeth->ctrl) { |
156 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); |
157 | 0 | return 0; |
158 | 0 | } |
159 | 90.4k | if (keytype != -1 && impl->pmeth->pkey_id != keytype) { |
160 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
161 | 0 | return 0; |
162 | 0 | } |
163 | | |
164 | 90.4k | if (impl->operation == EVP_PKEY_OP_UNDEFINED) { |
165 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_NO_OPERATION_SET); |
166 | 0 | return 0; |
167 | 0 | } |
168 | | |
169 | 90.4k | if (optype != -1 && !(impl->operation & optype)) { |
170 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_OPERATION); |
171 | 0 | return 0; |
172 | 0 | } |
173 | | |
174 | 90.4k | return impl->pmeth->ctrl(impl, cmd, p1, p2); |
175 | 90.4k | } |
176 | | |
177 | 20.1k | int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) { |
178 | 20.1k | auto *impl = FromOpaque(ctx); |
179 | 20.1k | if (!ctx || impl->pmeth == nullptr || |
180 | 20.1k | (impl->pmeth->sign == nullptr && impl->pmeth->sign_message == nullptr)) { |
181 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
182 | 0 | return 0; |
183 | 0 | } |
184 | | |
185 | 20.1k | impl->operation = EVP_PKEY_OP_SIGN; |
186 | 20.1k | return 1; |
187 | 20.1k | } |
188 | | |
189 | | int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *sig_len, |
190 | 20.1k | const uint8_t *digest, size_t digest_len) { |
191 | 20.1k | auto *impl = FromOpaque(ctx); |
192 | 20.1k | if (!impl || !impl->pmeth || !impl->pmeth->sign) { |
193 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
194 | 0 | return 0; |
195 | 0 | } |
196 | 20.1k | if (impl->operation != EVP_PKEY_OP_SIGN) { |
197 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); |
198 | 0 | return 0; |
199 | 0 | } |
200 | 20.1k | return impl->pmeth->sign(impl, sig, sig_len, digest, digest_len); |
201 | 20.1k | } |
202 | | |
203 | 36.2k | int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) { |
204 | 36.2k | auto *impl = FromOpaque(ctx); |
205 | 36.2k | if (!impl || impl->pmeth == nullptr || |
206 | 36.2k | (impl->pmeth->verify == nullptr && |
207 | 0 | impl->pmeth->verify_message == nullptr)) { |
208 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
209 | 0 | return 0; |
210 | 0 | } |
211 | 36.2k | impl->operation = EVP_PKEY_OP_VERIFY; |
212 | 36.2k | return 1; |
213 | 36.2k | } |
214 | | |
215 | | int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t sig_len, |
216 | 36.2k | const uint8_t *digest, size_t digest_len) { |
217 | 36.2k | auto *impl = FromOpaque(ctx); |
218 | 36.2k | if (!impl || !impl->pmeth || !impl->pmeth->verify) { |
219 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
220 | 0 | return 0; |
221 | 0 | } |
222 | 36.2k | if (impl->operation != EVP_PKEY_OP_VERIFY) { |
223 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); |
224 | 0 | return 0; |
225 | 0 | } |
226 | 36.2k | return impl->pmeth->verify(impl, sig, sig_len, digest, digest_len); |
227 | 36.2k | } |
228 | | |
229 | 0 | int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) { |
230 | 0 | auto *impl = FromOpaque(ctx); |
231 | 0 | if (!impl || !impl->pmeth || !impl->pmeth->encrypt) { |
232 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
233 | 0 | return 0; |
234 | 0 | } |
235 | 0 | impl->operation = EVP_PKEY_OP_ENCRYPT; |
236 | 0 | return 1; |
237 | 0 | } |
238 | | |
239 | | int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, |
240 | 0 | const uint8_t *in, size_t inlen) { |
241 | 0 | auto *impl = FromOpaque(ctx); |
242 | 0 | if (!impl || !impl->pmeth || !impl->pmeth->encrypt) { |
243 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
244 | 0 | return 0; |
245 | 0 | } |
246 | 0 | if (impl->operation != EVP_PKEY_OP_ENCRYPT) { |
247 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); |
248 | 0 | return 0; |
249 | 0 | } |
250 | 0 | return impl->pmeth->encrypt(impl, out, outlen, in, inlen); |
251 | 0 | } |
252 | | |
253 | 0 | int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) { |
254 | 0 | auto *impl = FromOpaque(ctx); |
255 | 0 | if (!impl || !impl->pmeth || !impl->pmeth->decrypt) { |
256 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
257 | 0 | return 0; |
258 | 0 | } |
259 | 0 | impl->operation = EVP_PKEY_OP_DECRYPT; |
260 | 0 | return 1; |
261 | 0 | } |
262 | | |
263 | | int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, |
264 | 0 | const uint8_t *in, size_t inlen) { |
265 | 0 | auto *impl = FromOpaque(ctx); |
266 | 0 | if (!impl || !impl->pmeth || !impl->pmeth->decrypt) { |
267 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
268 | 0 | return 0; |
269 | 0 | } |
270 | 0 | if (impl->operation != EVP_PKEY_OP_DECRYPT) { |
271 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); |
272 | 0 | return 0; |
273 | 0 | } |
274 | 0 | return impl->pmeth->decrypt(impl, out, outlen, in, inlen); |
275 | 0 | } |
276 | | |
277 | 0 | int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) { |
278 | 0 | auto *impl = FromOpaque(ctx); |
279 | 0 | if (!impl || !impl->pmeth || !impl->pmeth->verify_recover) { |
280 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
281 | 0 | return 0; |
282 | 0 | } |
283 | 0 | impl->operation = EVP_PKEY_OP_VERIFYRECOVER; |
284 | 0 | return 1; |
285 | 0 | } |
286 | | |
287 | | int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len, |
288 | 0 | const uint8_t *sig, size_t sig_len) { |
289 | 0 | auto *impl = FromOpaque(ctx); |
290 | 0 | if (!impl || !impl->pmeth || !impl->pmeth->verify_recover) { |
291 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
292 | 0 | return 0; |
293 | 0 | } |
294 | 0 | if (impl->operation != EVP_PKEY_OP_VERIFYRECOVER) { |
295 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); |
296 | 0 | return 0; |
297 | 0 | } |
298 | 0 | return impl->pmeth->verify_recover(impl, out, out_len, sig, sig_len); |
299 | 0 | } |
300 | | |
301 | 0 | int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) { |
302 | 0 | auto *impl = FromOpaque(ctx); |
303 | 0 | if (!impl || !impl->pmeth || !impl->pmeth->derive) { |
304 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
305 | 0 | return 0; |
306 | 0 | } |
307 | 0 | impl->operation = EVP_PKEY_OP_DERIVE; |
308 | 0 | return 1; |
309 | 0 | } |
310 | | |
311 | 0 | int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) { |
312 | 0 | auto *impl = FromOpaque(ctx); |
313 | 0 | if (!impl || !impl->pmeth || |
314 | 0 | !(impl->pmeth->derive || impl->pmeth->encrypt || impl->pmeth->decrypt) || |
315 | 0 | !impl->pmeth->ctrl) { |
316 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
317 | 0 | return 0; |
318 | 0 | } |
319 | 0 | if (impl->operation != EVP_PKEY_OP_DERIVE && |
320 | 0 | impl->operation != EVP_PKEY_OP_ENCRYPT && |
321 | 0 | impl->operation != EVP_PKEY_OP_DECRYPT) { |
322 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); |
323 | 0 | return 0; |
324 | 0 | } |
325 | | |
326 | 0 | int ret = impl->pmeth->ctrl(impl, EVP_PKEY_CTRL_PEER_KEY, 0, peer); |
327 | |
|
328 | 0 | if (ret <= 0) { |
329 | 0 | return 0; |
330 | 0 | } |
331 | | |
332 | 0 | if (ret == 2) { |
333 | 0 | return 1; |
334 | 0 | } |
335 | | |
336 | 0 | if (!impl->pkey || !FromOpaque(peer)->pkey) { |
337 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); |
338 | 0 | return 0; |
339 | 0 | } |
340 | | |
341 | 0 | if (EVP_PKEY_id(impl->pkey.get()) != EVP_PKEY_id(peer)) { |
342 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); |
343 | 0 | return 0; |
344 | 0 | } |
345 | | |
346 | | // ran@cryptocom.ru: For clarity. The error is if parameters in peer are |
347 | | // present (!missing) but don't match. EVP_PKEY_cmp_parameters may return |
348 | | // 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 |
349 | | // (different key types) is impossible here because it is checked earlier. |
350 | | // -2 is OK for us here, as well as 1, so we can check for 0 only. |
351 | 0 | if (!EVP_PKEY_missing_parameters(peer) && |
352 | 0 | !EVP_PKEY_cmp_parameters(impl->pkey.get(), peer)) { |
353 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_PARAMETERS); |
354 | 0 | return 0; |
355 | 0 | } |
356 | | |
357 | 0 | impl->peerkey = UpRef(FromOpaque(peer)); |
358 | 0 | ret = impl->pmeth->ctrl(impl, EVP_PKEY_CTRL_PEER_KEY, 1, peer); |
359 | 0 | if (ret <= 0) { |
360 | 0 | impl->peerkey = nullptr; |
361 | 0 | return 0; |
362 | 0 | } |
363 | | |
364 | 0 | return 1; |
365 | 0 | } |
366 | | |
367 | 0 | int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *out_key_len) { |
368 | 0 | auto *impl = FromOpaque(ctx); |
369 | 0 | if (!impl || !impl->pmeth || !impl->pmeth->derive) { |
370 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
371 | 0 | return 0; |
372 | 0 | } |
373 | 0 | if (impl->operation != EVP_PKEY_OP_DERIVE) { |
374 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); |
375 | 0 | return 0; |
376 | 0 | } |
377 | 0 | return impl->pmeth->derive(impl, key, out_key_len); |
378 | 0 | } |
379 | | |
380 | 0 | EVP_PKEY *EVP_PKEY_generate_from_alg(const EVP_PKEY_ALG *alg) { |
381 | 0 | UniquePtr<EvpPkeyCtx> ctx = evp_pkey_ctx_new_alg(alg); |
382 | 0 | EVP_PKEY *pkey = nullptr; |
383 | 0 | if (ctx == nullptr || // |
384 | 0 | !EVP_PKEY_keygen_init(ctx.get()) || // |
385 | 0 | !EVP_PKEY_keygen(ctx.get(), &pkey)) { |
386 | 0 | return nullptr; |
387 | 0 | } |
388 | 0 | return pkey; |
389 | 0 | } |
390 | | |
391 | 0 | int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) { |
392 | 0 | auto *impl = FromOpaque(ctx); |
393 | 0 | if (!impl || !impl->pmeth || !impl->pmeth->keygen) { |
394 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
395 | 0 | return 0; |
396 | 0 | } |
397 | 0 | impl->operation = EVP_PKEY_OP_KEYGEN; |
398 | 0 | return 1; |
399 | 0 | } |
400 | | |
401 | 0 | int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **out_pkey) { |
402 | 0 | auto *impl = FromOpaque(ctx); |
403 | 0 | if (!impl || !impl->pmeth || !impl->pmeth->keygen) { |
404 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
405 | 0 | return 0; |
406 | 0 | } |
407 | 0 | if (impl->operation != EVP_PKEY_OP_KEYGEN) { |
408 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); |
409 | 0 | return 0; |
410 | 0 | } |
411 | | |
412 | 0 | if (!out_pkey) { |
413 | 0 | return 0; |
414 | 0 | } |
415 | | |
416 | 0 | if (!*out_pkey) { |
417 | 0 | *out_pkey = EVP_PKEY_new(); |
418 | 0 | if (!*out_pkey) { |
419 | 0 | OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); |
420 | 0 | return 0; |
421 | 0 | } |
422 | 0 | } |
423 | | |
424 | 0 | if (!impl->pmeth->keygen(impl, FromOpaque(*out_pkey))) { |
425 | 0 | EVP_PKEY_free(*out_pkey); |
426 | 0 | *out_pkey = nullptr; |
427 | 0 | return 0; |
428 | 0 | } |
429 | 0 | return 1; |
430 | 0 | } |
431 | | |
432 | 0 | int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) { |
433 | 0 | auto *impl = FromOpaque(ctx); |
434 | 0 | if (!impl || !impl->pmeth || !impl->pmeth->paramgen) { |
435 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
436 | 0 | return 0; |
437 | 0 | } |
438 | 0 | impl->operation = EVP_PKEY_OP_PARAMGEN; |
439 | 0 | return 1; |
440 | 0 | } |
441 | | |
442 | 0 | int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **out_pkey) { |
443 | 0 | auto *impl = FromOpaque(ctx); |
444 | 0 | if (!impl || !impl->pmeth || !impl->pmeth->paramgen) { |
445 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); |
446 | 0 | return 0; |
447 | 0 | } |
448 | 0 | if (impl->operation != EVP_PKEY_OP_PARAMGEN) { |
449 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); |
450 | 0 | return 0; |
451 | 0 | } |
452 | | |
453 | 0 | if (!out_pkey) { |
454 | 0 | return 0; |
455 | 0 | } |
456 | | |
457 | 0 | if (!*out_pkey) { |
458 | 0 | *out_pkey = EVP_PKEY_new(); |
459 | 0 | if (!*out_pkey) { |
460 | 0 | OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); |
461 | 0 | return 0; |
462 | 0 | } |
463 | 0 | } |
464 | | |
465 | 0 | if (!impl->pmeth->paramgen(impl, FromOpaque(*out_pkey))) { |
466 | 0 | EVP_PKEY_free(*out_pkey); |
467 | 0 | *out_pkey = nullptr; |
468 | 0 | return 0; |
469 | 0 | } |
470 | 0 | return 1; |
471 | 0 | } |