0db5eba50523929831b23dcce62f1f3d65f88bfe
[openssl.git] / crypto / dh / dh_ctrl.c
1 /*
2  * Copyright 1995-2020 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 /*
11  * DH low level APIs are deprecated for public use, but still ok for
12  * internal use.
13  */
14 #include "internal/deprecated.h"
15
16 #include <stdio.h>
17 #include "crypto/evp.h"
18 #include <openssl/bn.h>
19 #include <openssl/engine.h>
20 #include <openssl/obj_mac.h>
21 #include <openssl/core_names.h>
22 #include "internal/cryptlib.h"
23 #include "internal/refcount.h"
24 #include "crypto/dh.h"
25 #include "dh_local.h"
26
27 static int dh_paramgen_check(EVP_PKEY_CTX *ctx)
28 {
29     if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
30         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
31         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
32         return -2;
33     }
34     /* If key type not DH return error */
35     if (ctx->pmeth != NULL
36         && ctx->pmeth->pkey_id != EVP_PKEY_DH
37         && ctx->pmeth->pkey_id != EVP_PKEY_DHX)
38         return -1;
39     return 1;
40 }
41
42 static int dh_param_derive_check(EVP_PKEY_CTX *ctx)
43 {
44     if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
45         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
46         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
47         return -2;
48     }
49     /* If key type not DH return error */
50     if (ctx->pmeth != NULL
51         && ctx->pmeth->pkey_id != EVP_PKEY_DH
52         && ctx->pmeth->pkey_id != EVP_PKEY_DHX)
53         return -1;
54     return 1;
55 }
56
57 int EVP_PKEY_CTX_set_dh_paramgen_gindex(EVP_PKEY_CTX *ctx, int gindex)
58 {
59     int ret;
60     OSSL_PARAM params[2], *p = params;
61
62     if ((ret = dh_paramgen_check(ctx)) <= 0)
63         return ret;
64
65     *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_FFC_GINDEX, &gindex);
66     *p = OSSL_PARAM_construct_end();
67
68     return EVP_PKEY_CTX_set_params(ctx, params);
69 }
70
71 int EVP_PKEY_CTX_set_dh_paramgen_seed(EVP_PKEY_CTX *ctx,
72                                       const unsigned char *seed,
73                                       size_t seedlen)
74 {
75     int ret;
76     OSSL_PARAM params[2], *p = params;
77
78     if ((ret = dh_paramgen_check(ctx)) <= 0)
79         return ret;
80
81     *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_FFC_SEED,
82                                              (void *)seed, seedlen);
83     *p = OSSL_PARAM_construct_end();
84
85     return EVP_PKEY_CTX_set_params(ctx, params);
86 }
87
88 int EVP_PKEY_CTX_set_dh_paramgen_type(EVP_PKEY_CTX *ctx, int typ)
89 {
90     int ret;
91     OSSL_PARAM params[2], *p = params;
92     const char *name;
93
94     if ((ret = dh_paramgen_check(ctx)) <= 0)
95         return ret;
96
97     /* TODO(3.0): Remove this eventually when no more legacy */
98     if (ctx->op.keymgmt.genctx == NULL)
99         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN,
100                                  EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL);
101
102     name = dh_gen_type_id2name(typ);
103     if (name == NULL)
104         return 0;
105     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE,
106                                             (char *) name, 0);
107     *p = OSSL_PARAM_construct_end();
108
109     return EVP_PKEY_CTX_set_params(ctx, params);
110 }
111
112 int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits)
113 {
114     int ret;
115     OSSL_PARAM params[2], *p = params;
116     size_t bits = pbits;
117
118     if ((ret = dh_paramgen_check(ctx)) <= 0)
119         return ret;
120
121     /* TODO(3.0): Remove this eventually when no more legacy */
122     if (ctx->op.keymgmt.genctx == NULL)
123         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN,
124                                  EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, pbits,
125                                  NULL);
126     *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_PBITS, &bits);
127     *p = OSSL_PARAM_construct_end();
128     return EVP_PKEY_CTX_set_params(ctx, params);
129 }
130
131 int EVP_PKEY_CTX_set_dh_paramgen_subprime_len(EVP_PKEY_CTX *ctx, int qbits)
132 {
133     int ret;
134     OSSL_PARAM params[2], *p = params;
135     size_t bits2 = qbits;
136
137     if ((ret = dh_paramgen_check(ctx)) <= 0)
138         return ret;
139
140     /* TODO(3.0): Remove this eventually when no more legacy */
141     if (ctx->op.keymgmt.genctx == NULL)
142         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN,
143                                  EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, qbits,
144                                  NULL);
145     *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_QBITS, &bits2);
146     *p = OSSL_PARAM_construct_end();
147
148     return EVP_PKEY_CTX_set_params(ctx, params);
149 }
150
151 int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen)
152 {
153     int ret;
154     OSSL_PARAM params[2], *p = params;
155
156     if ((ret = dh_paramgen_check(ctx)) <= 0)
157         return ret;
158
159     /* TODO(3.0): Remove this eventually when no more legacy */
160     if (ctx->op.keymgmt.genctx == NULL)
161         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN,
162                                  EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL);
163     *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_DH_GENERATOR, &gen);
164     *p = OSSL_PARAM_construct_end();
165
166     return EVP_PKEY_CTX_set_params(ctx, params);
167 }
168
169 int EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX *ctx, int gen)
170 {
171     int ret;
172     OSSL_PARAM params[2], *p = params;
173     const char *name;
174
175     if ((ret = dh_paramgen_check(ctx)) <= 0)
176         return ret;
177
178     /* TODO(3.0): Remove this eventually when no more legacy */
179     if (ctx->op.keymgmt.genctx == NULL)
180         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN,
181                                  EVP_PKEY_CTRL_DH_RFC5114, gen, NULL);
182     name = ffc_named_group_from_uid(gen);
183     if (name == NULL)
184         return 0;
185
186     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
187                                             (void *)name, 0);
188     *p = OSSL_PARAM_construct_end();
189     return EVP_PKEY_CTX_set_params(ctx, params);
190 }
191
192 int EVP_PKEY_CTX_set_dhx_rfc5114(EVP_PKEY_CTX *ctx, int gen)
193 {
194     return EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen);
195 }
196
197 int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid)
198 {
199     int ret;
200     OSSL_PARAM params[2], *p = params;
201     const char *name;
202
203     if ((ret = dh_paramgen_check(ctx)) <= 0)
204         return ret;
205
206     /* TODO(3.0): Remove this eventually when no more legacy */
207     if (ctx->op.keymgmt.genctx == NULL)
208         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH,
209                                  EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN,
210                                  EVP_PKEY_CTRL_DH_NID, nid, NULL);
211     name = ffc_named_group_from_uid(nid);
212     if (name == NULL)
213         return 0;
214
215     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
216                                             (void *)name, 0);
217     *p = OSSL_PARAM_construct_end();
218     return EVP_PKEY_CTX_set_params(ctx, params);
219 }
220
221 int EVP_PKEY_CTX_set_dh_kdf_type(EVP_PKEY_CTX *ctx, int kdf)
222 {
223     int ret;
224     const char *kdf_type;
225     OSSL_PARAM params[2], *p = params;
226
227     ret = dh_param_derive_check(ctx);
228     if (ret != 1)
229         return ret;
230
231     /* TODO(3.0): Remove this eventually when no more legacy */
232     if (ctx->op.kex.exchprovctx == NULL)
233         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
234                                  EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL);
235     switch (kdf) {
236         case EVP_PKEY_DH_KDF_NONE:
237             kdf_type = "";
238             break;
239         case EVP_PKEY_DH_KDF_X9_42:
240             kdf_type = OSSL_KDF_NAME_X942KDF;
241             break;
242         default:
243             return -2;
244     }
245     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE,
246                                             /*
247                                              * Cast away the const. This is read
248                                              * only so should be safe
249                                              */
250                                             (char *)kdf_type, 0);
251     *p = OSSL_PARAM_construct_end();
252
253     ret = evp_pkey_ctx_set_params_strict(ctx, params);
254     if (ret == -2) {
255         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
256         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
257         return -2;
258     }
259
260     return ret;
261 }
262
263 int EVP_PKEY_CTX_get_dh_kdf_type(EVP_PKEY_CTX *ctx)
264 {
265     int ret;
266     char kdf_type[80]; /* 80 should be big enough */
267     OSSL_PARAM params[2], *p = params;
268
269     ret = dh_param_derive_check(ctx);
270     if (ret != 1)
271         return ret;
272
273     /* TODO(3.0): Remove this eventually when no more legacy */
274     if (ctx->op.kex.exchprovctx == NULL)
275         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
276                                  EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL);
277     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE,
278                                             kdf_type, sizeof(kdf_type));
279     *p = OSSL_PARAM_construct_end();
280
281     ret = evp_pkey_ctx_get_params_strict(ctx, params);
282     if (ret == -2) {
283         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
284         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
285         return -2;
286     } else if (ret != 1) {
287         return -1;
288     }
289
290     if (kdf_type[0] == '\0')
291         return EVP_PKEY_DH_KDF_NONE;
292     else if (strcmp(kdf_type, OSSL_KDF_NAME_X942KDF) == 0)
293         return EVP_PKEY_DH_KDF_X9_42;
294
295     return -1;
296 }
297
298 int EVP_PKEY_CTX_set0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT *oid)
299 {
300     int ret;
301     OSSL_PARAM params[2], *p = params;
302     const char *oid_name;
303
304     ret = dh_param_derive_check(ctx);
305     if (ret != 1)
306         return ret;
307
308     /* TODO(3.0): Remove this eventually when no more legacy */
309     if (ctx->op.kex.exchprovctx == NULL)
310         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
311                                  EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)(oid));
312     oid_name = OBJ_nid2sn(OBJ_obj2nid(oid));
313
314     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG,
315                                             (char *)oid_name, 0);
316     *p = OSSL_PARAM_construct_end();
317     ret = evp_pkey_ctx_set_params_strict(ctx, params);
318     if (ret == -2) {
319         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
320         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
321         return -2;
322     }
323
324     return ret;
325 }
326
327 int EVP_PKEY_CTX_get0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT **oid)
328 {
329     int ret, nid;
330     OSSL_PARAM params[2], *p = params;
331     char oid_name[80]; /* 80 should be big enough */
332
333     ret = dh_param_derive_check(ctx);
334     if (ret != 1)
335         return ret;
336
337     /* TODO(3.0): Remove this eventually when no more legacy */
338     if (ctx->op.kex.exchprovctx == NULL)
339         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
340                                  EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)(oid));
341     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG,
342                                             oid_name, sizeof(oid_name));
343     *p = OSSL_PARAM_construct_end();
344
345     ret = evp_pkey_ctx_get_params_strict(ctx, params);
346     if (ret == -2) {
347         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
348         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
349         return -2;
350     } else if (ret != 1) {
351         return -1;
352     }
353     nid = OBJ_sn2nid(oid_name);
354     if (nid == NID_undef)
355         nid = OBJ_ln2nid(oid_name);
356     *oid = (nid == NID_undef ? NULL : OBJ_nid2obj(nid));
357     return *oid != NULL;
358 }
359
360 int EVP_PKEY_CTX_set_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
361 {
362     int ret;
363     OSSL_PARAM params[2], *p = params;
364     const char *md_name = NULL;
365
366     ret = dh_param_derive_check(ctx);
367     if (ret != 1)
368         return ret;
369
370     /* TODO(3.0): Remove this eventually when no more legacy */
371     if (ctx->op.kex.exchprovctx == NULL)
372         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
373                                  EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)(md));
374     md_name = (md == NULL) ? "" : EVP_MD_name(md);
375
376     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST,
377                                             /*
378                                              * Cast away the const. This is read
379                                              * only so should be safe
380                                              */
381                                             (char *)md_name, 0);
382     *p = OSSL_PARAM_construct_end();
383
384     ret = evp_pkey_ctx_set_params_strict(ctx, params);
385     if (ret == -2) {
386         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
387         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
388         return -2;
389     }
390     return ret;
391 }
392
393 int EVP_PKEY_CTX_get_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd)
394 {
395     int ret;
396     char name[80] = "";  /* 80 should be big enough */
397     OSSL_PARAM params[2], *p = params;
398
399     ret = dh_param_derive_check(ctx);
400     if (ret != 1)
401         return ret;
402
403     /* TODO(3.0): Remove this eventually when no more legacy */
404     if (ctx->op.kex.exchprovctx == NULL)
405         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
406                                  EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)(pmd));
407     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST,
408                                             name, sizeof(name));
409     *p = OSSL_PARAM_construct_end();
410
411     ret = evp_pkey_ctx_get_params_strict(ctx, params);
412     if (ret == -2) {
413         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
414         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
415         return -2;
416     } else if (ret != 1) {
417         return -1;
418     }
419
420     /* May be NULL meaning "unknown" */
421     *pmd = EVP_get_digestbyname(name);
422
423     return 1;
424 }
425
426 int EVP_PKEY_CTX_set_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int inlen)
427 {
428     int ret;
429     size_t len = inlen;
430     OSSL_PARAM params[2], *p = params;
431
432     ret = dh_param_derive_check(ctx);
433     if (ret != 1)
434         return ret;
435
436     /* TODO(3.0): Remove this eventually when no more legacy */
437     if (ctx->op.kex.exchprovctx == NULL)
438         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
439                                  EVP_PKEY_CTRL_DH_KDF_OUTLEN, inlen, NULL);
440     if (inlen <= 0) {
441         /*
442          * This would ideally be -1 or 0, but we have to retain compatibility
443          * with legacy behaviour of EVP_PKEY_CTX_ctrl() which returned -2 if
444          * in <= 0
445          */
446         return -2;
447     }
448
449     *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
450                                        &len);
451     *p = OSSL_PARAM_construct_end();
452
453     ret = evp_pkey_ctx_set_params_strict(ctx, params);
454     if (ret == -2) {
455         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
456         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
457         return -2;
458     }
459     return ret;
460 }
461
462 int EVP_PKEY_CTX_get_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int *plen)
463 {
464     int ret;
465     size_t len = UINT_MAX;
466     OSSL_PARAM params[2], *p = params;
467
468     ret = dh_param_derive_check(ctx);
469     if (ret != 1)
470         return ret;
471
472     /* TODO(3.0): Remove this eventually when no more legacy */
473     if (ctx->op.kex.exchprovctx == NULL)
474         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
475                                  EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0,
476                                  (void *)(plen));
477     *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
478                                        &len);
479     *p = OSSL_PARAM_construct_end();
480
481     ret = evp_pkey_ctx_get_params_strict(ctx, params);
482     if (ret == -2) {
483         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
484         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
485         return -2;
486     } else if (ret != 1) {
487         return -1;
488     }
489
490     if (len > INT_MAX)
491         return -1;
492
493     *plen = (int)len;
494
495     return 1;
496 }
497
498 int EVP_PKEY_CTX_set0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len)
499 {
500     int ret;
501     OSSL_PARAM params[2], *p = params;
502
503     if (len <= 0)
504         return -1;
505
506     ret = dh_param_derive_check(ctx);
507     if (ret != 1)
508         return ret;
509
510     /* TODO(3.0): Remove this eventually when no more legacy */
511     if (ctx->op.kex.exchprovctx == NULL)
512         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
513                                  EVP_PKEY_CTRL_DH_KDF_UKM, len, (void *)(ukm));
514
515     *p++ = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM,
516                                             /*
517                                              * Cast away the const. This is read
518                                              * only so should be safe
519                                              */
520                                             (void *)ukm,
521                                             (size_t)len);
522     *p = OSSL_PARAM_construct_end();
523
524     ret = evp_pkey_ctx_set_params_strict(ctx, params);
525     if (ret == -2) {
526         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
527         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
528         return -2;
529     }
530     if (ret == 1)
531         OPENSSL_free(ukm);
532     return ret;
533 }
534
535 int EVP_PKEY_CTX_get0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm)
536 {
537     int ret;
538     size_t ukmlen;
539     OSSL_PARAM params[3], *p = params;
540
541     ret = dh_param_derive_check(ctx);
542     if (ret != 1)
543         return ret;
544
545     /* TODO(3.0): Remove this eventually when no more legacy */
546     if (ctx->op.kex.exchprovctx == NULL)
547         return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE,
548                                  EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)(pukm));
549
550     *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM,
551                                           (void **)pukm, 0);
552     *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_UKM_LEN,
553                                        &ukmlen);
554     *p = OSSL_PARAM_construct_end();
555
556     ret = evp_pkey_ctx_get_params_strict(ctx, params);
557     if (ret == -2) {
558         ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
559         /* Uses the same return values as EVP_PKEY_CTX_ctrl */
560         return -2;
561     } else if (ret != 1) {
562         return -1;
563     }
564
565     if (ukmlen > INT_MAX)
566         return -1;
567
568     return (int)ukmlen;
569 }