xref: /openbsd-src/lib/libcrypto/evp/pmeth_lib.c (revision 20c8931adecc22652cd956637c221c603d96b10b)
1 /* $OpenBSD: pmeth_lib.c,v 1.36 2024/01/04 20:15:01 tb Exp $ */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project 2006.
4  */
5 /* ====================================================================
6  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58 
59 #include <limits.h>
60 #include <stdio.h>
61 #include <stdlib.h>
62 #include <string.h>
63 
64 #include <openssl/opensslconf.h>
65 
66 #include <openssl/err.h>
67 #include <openssl/evp.h>
68 #include <openssl/objects.h>
69 #include <openssl/x509v3.h>
70 
71 #include "asn1_local.h"
72 #include "evp_local.h"
73 
74 extern const EVP_PKEY_METHOD cmac_pkey_meth;
75 extern const EVP_PKEY_METHOD dh_pkey_meth;
76 extern const EVP_PKEY_METHOD dsa_pkey_meth;
77 extern const EVP_PKEY_METHOD ec_pkey_meth;
78 extern const EVP_PKEY_METHOD ed25519_pkey_meth;
79 extern const EVP_PKEY_METHOD gostimit_pkey_meth;
80 extern const EVP_PKEY_METHOD gostr01_pkey_meth;
81 extern const EVP_PKEY_METHOD hkdf_pkey_meth;
82 extern const EVP_PKEY_METHOD hmac_pkey_meth;
83 extern const EVP_PKEY_METHOD rsa_pkey_meth;
84 extern const EVP_PKEY_METHOD rsa_pss_pkey_meth;
85 extern const EVP_PKEY_METHOD x25519_pkey_meth;
86 
87 static const EVP_PKEY_METHOD *pkey_methods[] = {
88 	&cmac_pkey_meth,
89 	&dh_pkey_meth,
90 	&dsa_pkey_meth,
91 	&ec_pkey_meth,
92 	&ed25519_pkey_meth,
93 	&gostimit_pkey_meth,
94 	&gostr01_pkey_meth,
95 	&hkdf_pkey_meth,
96 	&hmac_pkey_meth,
97 	&rsa_pkey_meth,
98 	&rsa_pss_pkey_meth,
99 	&x25519_pkey_meth,
100 };
101 
102 #define N_PKEY_METHODS (sizeof(pkey_methods) / sizeof(pkey_methods[0]))
103 
104 const EVP_PKEY_METHOD *
105 EVP_PKEY_meth_find(int type)
106 {
107 	size_t i;
108 
109 	for (i = 0; i < N_PKEY_METHODS; i++) {
110 		const EVP_PKEY_METHOD *pmeth = pkey_methods[i];
111 		if (pmeth->pkey_id == type)
112 			return pmeth;
113 	}
114 
115 	return NULL;
116 }
117 
118 static EVP_PKEY_CTX *
119 evp_pkey_ctx_new(EVP_PKEY *pkey, int id)
120 {
121 	EVP_PKEY_CTX *pkey_ctx = NULL;
122 	const EVP_PKEY_METHOD *pmeth;
123 
124 	if (id == -1) {
125 		if (pkey == NULL || pkey->ameth == NULL)
126 			return NULL;
127 		id = pkey->ameth->pkey_id;
128 	}
129 
130 	if ((pmeth = EVP_PKEY_meth_find(id)) == NULL) {
131 		EVPerror(EVP_R_UNSUPPORTED_ALGORITHM);
132 		goto err;
133 	}
134 
135 	if ((pkey_ctx = calloc(1, sizeof(*pkey_ctx))) == NULL) {
136 		EVPerror(ERR_R_MALLOC_FAILURE);
137 		goto err;
138 	}
139 	pkey_ctx->pmeth = pmeth;
140 	pkey_ctx->operation = EVP_PKEY_OP_UNDEFINED;
141 	if ((pkey_ctx->pkey = pkey) != NULL)
142 		EVP_PKEY_up_ref(pkey_ctx->pkey);
143 
144 	if (pmeth->init != NULL) {
145 		if (pmeth->init(pkey_ctx) <= 0)
146 			goto err;
147 	}
148 
149 	return pkey_ctx;
150 
151  err:
152 	EVP_PKEY_CTX_free(pkey_ctx);
153 
154 	return NULL;
155 }
156 
157 EVP_PKEY_METHOD*
158 EVP_PKEY_meth_new(int id, int flags)
159 {
160 	EVP_PKEY_METHOD *pmeth;
161 
162 	if ((pmeth = calloc(1, sizeof(EVP_PKEY_METHOD))) == NULL)
163 		return NULL;
164 
165 	pmeth->pkey_id = id;
166 	pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
167 
168 	return pmeth;
169 }
170 
171 void
172 EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, const EVP_PKEY_METHOD *meth)
173 {
174 	if (ppkey_id)
175 		*ppkey_id = meth->pkey_id;
176 	if (pflags)
177 		*pflags = meth->flags;
178 }
179 
180 void
181 EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
182 {
183 	EVP_PKEY_METHOD preserve;
184 
185 	preserve.pkey_id = dst->pkey_id;
186 	preserve.flags = dst->flags;
187 
188 	*dst = *src;
189 
190 	dst->pkey_id = preserve.pkey_id;
191 	dst->flags = preserve.flags;
192 }
193 
194 void
195 EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
196 {
197 	if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
198 		free(pmeth);
199 }
200 
201 EVP_PKEY_CTX *
202 EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *engine)
203 {
204 	return evp_pkey_ctx_new(pkey, -1);
205 }
206 
207 EVP_PKEY_CTX *
208 EVP_PKEY_CTX_new_id(int id, ENGINE *engine)
209 {
210 	return evp_pkey_ctx_new(NULL, id);
211 }
212 
213 EVP_PKEY_CTX *
214 EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
215 {
216 	EVP_PKEY_CTX *rctx = NULL;
217 
218 	if (pctx->pmeth == NULL || pctx->pmeth->copy == NULL)
219 		goto err;
220 	if ((rctx = calloc(1, sizeof(*rctx))) == NULL) {
221 		EVPerror(ERR_R_MALLOC_FAILURE);
222 		goto err;
223 	}
224 
225 	rctx->pmeth = pctx->pmeth;
226 
227 	if ((rctx->pkey = pctx->pkey) != NULL)
228 		EVP_PKEY_up_ref(rctx->pkey);
229 	if ((rctx->peerkey = pctx->peerkey) != NULL)
230 		EVP_PKEY_up_ref(rctx->peerkey);
231 
232 	rctx->operation = pctx->operation;
233 
234 	if (pctx->pmeth->copy(rctx, pctx) <= 0)
235 		goto err;
236 
237 	return rctx;
238 
239  err:
240 	EVP_PKEY_CTX_free(rctx);
241 	return NULL;
242 }
243 
244 int
245 EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
246 {
247 	EVPerror(ERR_R_DISABLED);
248 	return 0;
249 }
250 
251 void
252 EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
253 {
254 	if (ctx == NULL)
255 		return;
256 	if (ctx->pmeth && ctx->pmeth->cleanup)
257 		ctx->pmeth->cleanup(ctx);
258 	EVP_PKEY_free(ctx->pkey);
259 	EVP_PKEY_free(ctx->peerkey);
260 	free(ctx);
261 }
262 
263 int
264 EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd,
265     int p1, void *p2)
266 {
267 	int ret;
268 
269 	if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
270 		EVPerror(EVP_R_COMMAND_NOT_SUPPORTED);
271 		return -2;
272 	}
273 	if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
274 		return -1;
275 
276 	if (ctx->operation == EVP_PKEY_OP_UNDEFINED) {
277 		EVPerror(EVP_R_NO_OPERATION_SET);
278 		return -1;
279 	}
280 
281 	if ((optype != -1) && !(ctx->operation & optype)) {
282 		EVPerror(EVP_R_INVALID_OPERATION);
283 		return -1;
284 	}
285 
286 	ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
287 
288 	if (ret == -2)
289 		EVPerror(EVP_R_COMMAND_NOT_SUPPORTED);
290 
291 	return ret;
292 
293 }
294 
295 int
296 EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *name, const char *value)
297 {
298 	if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) {
299 		EVPerror(EVP_R_COMMAND_NOT_SUPPORTED);
300 		return -2;
301 	}
302 	if (!strcmp(name, "digest")) {
303 		return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_SIG,
304 		    EVP_PKEY_CTRL_MD, value);
305 	}
306 	return ctx->pmeth->ctrl_str(ctx, name, value);
307 }
308 
309 int
310 EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str)
311 {
312 	size_t len;
313 
314 	if ((len = strlen(str)) > INT_MAX)
315 		return -1;
316 
317 	return ctx->pmeth->ctrl(ctx, cmd, len, (void *)str);
318 }
319 
320 int
321 EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hexstr)
322 {
323 	unsigned char *hex = NULL;
324 	long length;
325 	int ret = 0;
326 
327 	if ((hex = string_to_hex(hexstr, &length)) == NULL)
328 		goto err;
329 	if (length < 0 || length > INT_MAX) {
330 		ret = -1;
331 		goto err;
332 	}
333 
334 	ret = ctx->pmeth->ctrl(ctx, cmd, length, hex);
335 
336  err:
337 	free(hex);
338 	return ret;
339 }
340 
341 int
342 EVP_PKEY_CTX_md(EVP_PKEY_CTX *ctx, int optype, int cmd, const char *md_name)
343 {
344 	const EVP_MD *md;
345 
346 	if ((md = EVP_get_digestbyname(md_name)) == NULL) {
347 		EVPerror(EVP_R_INVALID_DIGEST);
348 		return 0;
349 	}
350 	return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, 0, (void *)md);
351 }
352 
353 int
354 EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
355 {
356 	return ctx->operation;
357 }
358 
359 void
360 EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
361 {
362 	ctx->keygen_info = dat;
363 	ctx->keygen_info_count = datlen;
364 }
365 
366 void
367 EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
368 {
369 	ctx->data = data;
370 }
371 
372 void *
373 EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
374 {
375 	return ctx->data;
376 }
377 
378 EVP_PKEY *
379 EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
380 {
381 	return ctx->pkey;
382 }
383 
384 EVP_PKEY *
385 EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
386 {
387 	return ctx->peerkey;
388 }
389 
390 void
391 EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
392 {
393 	ctx->app_data = data;
394 }
395 
396 void *
397 EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
398 {
399 	return ctx->app_data;
400 }
401 
402 void
403 EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
404     int (*init)(EVP_PKEY_CTX *ctx))
405 {
406 	pmeth->init = init;
407 }
408 
409 void
410 EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
411     int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src))
412 {
413 	pmeth->copy = copy;
414 }
415 
416 void
417 EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
418     void (*cleanup)(EVP_PKEY_CTX *ctx))
419 {
420 	pmeth->cleanup = cleanup;
421 }
422 
423 void
424 EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
425     int (*paramgen_init)(EVP_PKEY_CTX *ctx),
426     int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey))
427 {
428 	pmeth->paramgen_init = paramgen_init;
429 	pmeth->paramgen = paramgen;
430 }
431 
432 void
433 EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
434     int (*keygen_init)(EVP_PKEY_CTX *ctx),
435     int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey))
436 {
437 	pmeth->keygen_init = keygen_init;
438 	pmeth->keygen = keygen;
439 }
440 
441 void
442 EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
443     int (*sign_init)(EVP_PKEY_CTX *ctx),
444     int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
445     const unsigned char *tbs, size_t tbslen))
446 {
447 	pmeth->sign_init = sign_init;
448 	pmeth->sign = sign;
449 }
450 
451 void
452 EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
453     int (*verify_init)(EVP_PKEY_CTX *ctx),
454     int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
455     const unsigned char *tbs, size_t tbslen))
456 {
457 	pmeth->verify_init = verify_init;
458 	pmeth->verify = verify;
459 }
460 
461 void
462 EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
463     int (*verify_recover_init)(EVP_PKEY_CTX *ctx),
464     int (*verify_recover)(EVP_PKEY_CTX *ctx,
465     unsigned char *sig, size_t *siglen,
466     const unsigned char *tbs, size_t tbslen))
467 {
468 	pmeth->verify_recover_init = verify_recover_init;
469 	pmeth->verify_recover = verify_recover;
470 }
471 
472 void
473 EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
474     int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
475     int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
476     EVP_MD_CTX *mctx))
477 {
478 	pmeth->signctx_init = signctx_init;
479 	pmeth->signctx = signctx;
480 }
481 
482 void
483 EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
484     int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
485     int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen,
486     EVP_MD_CTX *mctx))
487 {
488 	pmeth->verifyctx_init = verifyctx_init;
489 	pmeth->verifyctx = verifyctx;
490 }
491 
492 void
493 EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
494     int (*encrypt_init)(EVP_PKEY_CTX *ctx),
495     int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
496     const unsigned char *in, size_t inlen))
497 {
498 	pmeth->encrypt_init = encrypt_init;
499 	pmeth->encrypt = encryptfn;
500 }
501 
502 void
503 EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
504     int (*decrypt_init)(EVP_PKEY_CTX *ctx),
505     int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
506     const unsigned char *in, size_t inlen))
507 {
508 	pmeth->decrypt_init = decrypt_init;
509 	pmeth->decrypt = decrypt;
510 }
511 
512 void
513 EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
514     int (*derive_init)(EVP_PKEY_CTX *ctx),
515     int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen))
516 {
517 	pmeth->derive_init = derive_init;
518 	pmeth->derive = derive;
519 }
520 
521 void
522 EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
523     int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2),
524     int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value))
525 {
526 	pmeth->ctrl = ctrl;
527 	pmeth->ctrl_str = ctrl_str;
528 }
529 
530 void
531 EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth, int (*check)(EVP_PKEY *pkey))
532 {
533 	pmeth->check = check;
534 }
535 
536 void
537 EVP_PKEY_meth_set_public_check(EVP_PKEY_METHOD *pmeth,
538     int (*public_check)(EVP_PKEY *pkey))
539 {
540 	pmeth->public_check = public_check;
541 }
542 
543 void
544 EVP_PKEY_meth_set_param_check(EVP_PKEY_METHOD *pmeth,
545     int (*param_check)(EVP_PKEY *pkey))
546 {
547 	pmeth->param_check = param_check;
548 }
549