Coverage Report

Created: 2026-03-19 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}