• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.] */
56 
57 #include <openssl/evp.h>
58 
59 #include <string.h>
60 
61 #include <openssl/digest.h>
62 #include <openssl/err.h>
63 #include <openssl/mem.h>
64 
65 #include "../internal.h"
66 #include "internal.h"
67 
68 
69 static const EVP_PKEY_METHOD *const evp_methods[] = {
70     &rsa_pkey_meth,
71     &ec_pkey_meth,
72     &ed25519_pkey_meth,
73     &x25519_pkey_meth,
74     &hkdf_pkey_meth,
75 };
76 
evp_pkey_meth_find(int type)77 static const EVP_PKEY_METHOD *evp_pkey_meth_find(int type) {
78   for (size_t i = 0; i < sizeof(evp_methods)/sizeof(EVP_PKEY_METHOD*); i++) {
79     if (evp_methods[i]->pkey_id == type) {
80       return evp_methods[i];
81     }
82   }
83 
84   return NULL;
85 }
86 
evp_pkey_ctx_new(EVP_PKEY * pkey,ENGINE * e,const EVP_PKEY_METHOD * pmeth)87 static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e,
88                                       const EVP_PKEY_METHOD *pmeth) {
89   EVP_PKEY_CTX *ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
90   if (!ret) {
91     return NULL;
92   }
93   OPENSSL_memset(ret, 0, sizeof(EVP_PKEY_CTX));
94 
95   ret->engine = e;
96   ret->pmeth = pmeth;
97   ret->operation = EVP_PKEY_OP_UNDEFINED;
98 
99   if (pkey) {
100     EVP_PKEY_up_ref(pkey);
101     ret->pkey = pkey;
102   }
103 
104   if (pmeth->init) {
105     if (pmeth->init(ret) <= 0) {
106       EVP_PKEY_free(ret->pkey);
107       OPENSSL_free(ret);
108       return NULL;
109     }
110   }
111 
112   return ret;
113 }
114 
EVP_PKEY_CTX_new(EVP_PKEY * pkey,ENGINE * e)115 EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) {
116   if (pkey == NULL || pkey->ameth == NULL) {
117     OPENSSL_PUT_ERROR(EVP, ERR_R_PASSED_NULL_PARAMETER);
118     return NULL;
119   }
120 
121   const EVP_PKEY_METHOD *pkey_method = pkey->ameth->pkey_method;
122   if (pkey_method == NULL) {
123     OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
124     ERR_add_error_dataf("algorithm %d", pkey->ameth->pkey_id);
125     return NULL;
126   }
127 
128   return evp_pkey_ctx_new(pkey, e, pkey_method);
129 }
130 
EVP_PKEY_CTX_new_id(int id,ENGINE * e)131 EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) {
132   const EVP_PKEY_METHOD *pkey_method = evp_pkey_meth_find(id);
133   if (pkey_method == NULL) {
134     OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
135     ERR_add_error_dataf("algorithm %d", id);
136     return NULL;
137   }
138 
139   return evp_pkey_ctx_new(NULL, e, pkey_method);
140 }
141 
EVP_PKEY_CTX_free(EVP_PKEY_CTX * ctx)142 void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) {
143   if (ctx == NULL) {
144     return;
145   }
146   if (ctx->pmeth && ctx->pmeth->cleanup) {
147     ctx->pmeth->cleanup(ctx);
148   }
149   EVP_PKEY_free(ctx->pkey);
150   EVP_PKEY_free(ctx->peerkey);
151   OPENSSL_free(ctx);
152 }
153 
EVP_PKEY_CTX_dup(EVP_PKEY_CTX * ctx)154 EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx) {
155   if (!ctx->pmeth || !ctx->pmeth->copy) {
156     return NULL;
157   }
158 
159   EVP_PKEY_CTX *ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
160   if (!ret) {
161     return NULL;
162   }
163 
164   OPENSSL_memset(ret, 0, sizeof(EVP_PKEY_CTX));
165 
166   ret->pmeth = ctx->pmeth;
167   ret->engine = ctx->engine;
168   ret->operation = ctx->operation;
169 
170   if (ctx->pkey != NULL) {
171     EVP_PKEY_up_ref(ctx->pkey);
172     ret->pkey = ctx->pkey;
173   }
174 
175   if (ctx->peerkey != NULL) {
176     EVP_PKEY_up_ref(ctx->peerkey);
177     ret->peerkey = ctx->peerkey;
178   }
179 
180   if (ctx->pmeth->copy(ret, ctx) <= 0) {
181     ret->pmeth = NULL;
182     EVP_PKEY_CTX_free(ret);
183     OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP);
184     return NULL;
185   }
186 
187   return ret;
188 }
189 
EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX * ctx)190 EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) { return ctx->pkey; }
191 
EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX * ctx,int keytype,int optype,int cmd,int p1,void * p2)192 int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd,
193                       int p1, void *p2) {
194   if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
195     OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED);
196     return 0;
197   }
198   if (keytype != -1 && ctx->pmeth->pkey_id != keytype) {
199     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
200     return 0;
201   }
202 
203   if (ctx->operation == EVP_PKEY_OP_UNDEFINED) {
204     OPENSSL_PUT_ERROR(EVP, EVP_R_NO_OPERATION_SET);
205     return 0;
206   }
207 
208   if (optype != -1 && !(ctx->operation & optype)) {
209     OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_OPERATION);
210     return 0;
211   }
212 
213   return ctx->pmeth->ctrl(ctx, cmd, p1, p2);
214 }
215 
EVP_PKEY_sign_init(EVP_PKEY_CTX * ctx)216 int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) {
217   if (ctx == NULL || ctx->pmeth == NULL ||
218       (ctx->pmeth->sign == NULL && ctx->pmeth->sign_message == NULL)) {
219     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
220     return 0;
221   }
222 
223   ctx->operation = EVP_PKEY_OP_SIGN;
224   return 1;
225 }
226 
EVP_PKEY_sign(EVP_PKEY_CTX * ctx,uint8_t * sig,size_t * sig_len,const uint8_t * digest,size_t digest_len)227 int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *sig_len,
228                   const uint8_t *digest, size_t digest_len) {
229   if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
230     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
231     return 0;
232   }
233   if (ctx->operation != EVP_PKEY_OP_SIGN) {
234     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
235     return 0;
236   }
237   return ctx->pmeth->sign(ctx, sig, sig_len, digest, digest_len);
238 }
239 
EVP_PKEY_verify_init(EVP_PKEY_CTX * ctx)240 int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) {
241   if (ctx == NULL || ctx->pmeth == NULL ||
242       (ctx->pmeth->verify == NULL && ctx->pmeth->verify_message == NULL)) {
243     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
244     return 0;
245   }
246   ctx->operation = EVP_PKEY_OP_VERIFY;
247   return 1;
248 }
249 
EVP_PKEY_verify(EVP_PKEY_CTX * ctx,const uint8_t * sig,size_t sig_len,const uint8_t * digest,size_t digest_len)250 int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t sig_len,
251                     const uint8_t *digest, size_t digest_len) {
252   if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
253     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
254     return 0;
255   }
256   if (ctx->operation != EVP_PKEY_OP_VERIFY) {
257     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
258     return 0;
259   }
260   return ctx->pmeth->verify(ctx, sig, sig_len, digest, digest_len);
261 }
262 
EVP_PKEY_encrypt_init(EVP_PKEY_CTX * ctx)263 int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) {
264   if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
265     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
266     return 0;
267   }
268   ctx->operation = EVP_PKEY_OP_ENCRYPT;
269   return 1;
270 }
271 
EVP_PKEY_encrypt(EVP_PKEY_CTX * ctx,uint8_t * out,size_t * outlen,const uint8_t * in,size_t inlen)272 int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
273                      const uint8_t *in, size_t inlen) {
274   if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
275     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
276     return 0;
277   }
278   if (ctx->operation != EVP_PKEY_OP_ENCRYPT) {
279     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
280     return 0;
281   }
282   return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
283 }
284 
EVP_PKEY_decrypt_init(EVP_PKEY_CTX * ctx)285 int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) {
286   if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
287     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
288     return 0;
289   }
290   ctx->operation = EVP_PKEY_OP_DECRYPT;
291   return 1;
292 }
293 
EVP_PKEY_decrypt(EVP_PKEY_CTX * ctx,uint8_t * out,size_t * outlen,const uint8_t * in,size_t inlen)294 int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
295                      const uint8_t *in, size_t inlen) {
296   if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
297     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
298     return 0;
299   }
300   if (ctx->operation != EVP_PKEY_OP_DECRYPT) {
301     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
302     return 0;
303   }
304   return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
305 }
306 
EVP_PKEY_verify_recover_init(EVP_PKEY_CTX * ctx)307 int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) {
308   if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
309     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
310     return 0;
311   }
312   ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
313   return 1;
314 }
315 
EVP_PKEY_verify_recover(EVP_PKEY_CTX * ctx,uint8_t * out,size_t * out_len,const uint8_t * sig,size_t sig_len)316 int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len,
317                             const uint8_t *sig, size_t sig_len) {
318   if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
319     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
320     return 0;
321   }
322   if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) {
323     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
324     return 0;
325   }
326   return ctx->pmeth->verify_recover(ctx, out, out_len, sig, sig_len);
327 }
328 
EVP_PKEY_derive_init(EVP_PKEY_CTX * ctx)329 int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) {
330   if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
331     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
332     return 0;
333   }
334   ctx->operation = EVP_PKEY_OP_DERIVE;
335   return 1;
336 }
337 
EVP_PKEY_derive_set_peer(EVP_PKEY_CTX * ctx,EVP_PKEY * peer)338 int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) {
339   int ret;
340   if (!ctx || !ctx->pmeth ||
341       !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt) ||
342       !ctx->pmeth->ctrl) {
343     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
344     return 0;
345   }
346   if (ctx->operation != EVP_PKEY_OP_DERIVE &&
347       ctx->operation != EVP_PKEY_OP_ENCRYPT &&
348       ctx->operation != EVP_PKEY_OP_DECRYPT) {
349     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
350     return 0;
351   }
352 
353   ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
354 
355   if (ret <= 0) {
356     return 0;
357   }
358 
359   if (ret == 2) {
360     return 1;
361   }
362 
363   if (!ctx->pkey) {
364     OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET);
365     return 0;
366   }
367 
368   if (ctx->pkey->type != peer->type) {
369     OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES);
370     return 0;
371   }
372 
373   // ran@cryptocom.ru: For clarity.  The error is if parameters in peer are
374   // present (!missing) but don't match.  EVP_PKEY_cmp_parameters may return
375   // 1 (match), 0 (don't match) and -2 (comparison is not defined).  -1
376   // (different key types) is impossible here because it is checked earlier.
377   // -2 is OK for us here, as well as 1, so we can check for 0 only.
378   if (!EVP_PKEY_missing_parameters(peer) &&
379       !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) {
380     OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_PARAMETERS);
381     return 0;
382   }
383 
384   EVP_PKEY_free(ctx->peerkey);
385   ctx->peerkey = peer;
386 
387   ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
388 
389   if (ret <= 0) {
390     ctx->peerkey = NULL;
391     return 0;
392   }
393 
394   EVP_PKEY_up_ref(peer);
395   return 1;
396 }
397 
EVP_PKEY_derive(EVP_PKEY_CTX * ctx,uint8_t * key,size_t * out_key_len)398 int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *out_key_len) {
399   if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
400     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
401     return 0;
402   }
403   if (ctx->operation != EVP_PKEY_OP_DERIVE) {
404     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
405     return 0;
406   }
407   return ctx->pmeth->derive(ctx, key, out_key_len);
408 }
409 
EVP_PKEY_keygen_init(EVP_PKEY_CTX * ctx)410 int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) {
411   if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
412     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
413     return 0;
414   }
415   ctx->operation = EVP_PKEY_OP_KEYGEN;
416   return 1;
417 }
418 
EVP_PKEY_keygen(EVP_PKEY_CTX * ctx,EVP_PKEY ** out_pkey)419 int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **out_pkey) {
420   if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
421     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
422     return 0;
423   }
424   if (ctx->operation != EVP_PKEY_OP_KEYGEN) {
425     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
426     return 0;
427   }
428 
429   if (!out_pkey) {
430     return 0;
431   }
432 
433   if (!*out_pkey) {
434     *out_pkey = EVP_PKEY_new();
435     if (!*out_pkey) {
436       OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP);
437       return 0;
438     }
439   }
440 
441   if (!ctx->pmeth->keygen(ctx, *out_pkey)) {
442     EVP_PKEY_free(*out_pkey);
443     *out_pkey = NULL;
444     return 0;
445   }
446   return 1;
447 }
448 
EVP_PKEY_paramgen_init(EVP_PKEY_CTX * ctx)449 int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) {
450   if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) {
451     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
452     return 0;
453   }
454   ctx->operation = EVP_PKEY_OP_PARAMGEN;
455   return 1;
456 }
457 
EVP_PKEY_paramgen(EVP_PKEY_CTX * ctx,EVP_PKEY ** out_pkey)458 int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **out_pkey) {
459   if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) {
460     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
461     return 0;
462   }
463   if (ctx->operation != EVP_PKEY_OP_PARAMGEN) {
464     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
465     return 0;
466   }
467 
468   if (!out_pkey) {
469     return 0;
470   }
471 
472   if (!*out_pkey) {
473     *out_pkey = EVP_PKEY_new();
474     if (!*out_pkey) {
475       OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP);
476       return 0;
477     }
478   }
479 
480   if (!ctx->pmeth->paramgen(ctx, *out_pkey)) {
481     EVP_PKEY_free(*out_pkey);
482     *out_pkey = NULL;
483     return 0;
484   }
485   return 1;
486 }
487