xref: /openbsd-src/lib/libcrypto/evp/pmeth_gn.c (revision df8006feef6efde7ed88951227ec9a2f73ab0bb3)
1*df8006feStb /* $OpenBSD: pmeth_gn.c,v 1.21 2024/08/31 09:14:21 tb Exp $ */
2f1535dc8Sdjm /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3f1535dc8Sdjm  * project 2006.
4f1535dc8Sdjm  */
5f1535dc8Sdjm /* ====================================================================
6f1535dc8Sdjm  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
7f1535dc8Sdjm  *
8f1535dc8Sdjm  * Redistribution and use in source and binary forms, with or without
9f1535dc8Sdjm  * modification, are permitted provided that the following conditions
10f1535dc8Sdjm  * are met:
11f1535dc8Sdjm  *
12f1535dc8Sdjm  * 1. Redistributions of source code must retain the above copyright
13f1535dc8Sdjm  *    notice, this list of conditions and the following disclaimer.
14f1535dc8Sdjm  *
15f1535dc8Sdjm  * 2. Redistributions in binary form must reproduce the above copyright
16f1535dc8Sdjm  *    notice, this list of conditions and the following disclaimer in
17f1535dc8Sdjm  *    the documentation and/or other materials provided with the
18f1535dc8Sdjm  *    distribution.
19f1535dc8Sdjm  *
20f1535dc8Sdjm  * 3. All advertising materials mentioning features or use of this
21f1535dc8Sdjm  *    software must display the following acknowledgment:
22f1535dc8Sdjm  *    "This product includes software developed by the OpenSSL Project
23f1535dc8Sdjm  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24f1535dc8Sdjm  *
25f1535dc8Sdjm  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26f1535dc8Sdjm  *    endorse or promote products derived from this software without
27f1535dc8Sdjm  *    prior written permission. For written permission, please contact
28f1535dc8Sdjm  *    licensing@OpenSSL.org.
29f1535dc8Sdjm  *
30f1535dc8Sdjm  * 5. Products derived from this software may not be called "OpenSSL"
31f1535dc8Sdjm  *    nor may "OpenSSL" appear in their names without prior written
32f1535dc8Sdjm  *    permission of the OpenSSL Project.
33f1535dc8Sdjm  *
34f1535dc8Sdjm  * 6. Redistributions of any form whatsoever must retain the following
35f1535dc8Sdjm  *    acknowledgment:
36f1535dc8Sdjm  *    "This product includes software developed by the OpenSSL Project
37f1535dc8Sdjm  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38f1535dc8Sdjm  *
39f1535dc8Sdjm  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40f1535dc8Sdjm  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41f1535dc8Sdjm  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42f1535dc8Sdjm  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43f1535dc8Sdjm  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44f1535dc8Sdjm  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45f1535dc8Sdjm  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46f1535dc8Sdjm  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47f1535dc8Sdjm  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48f1535dc8Sdjm  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49f1535dc8Sdjm  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50f1535dc8Sdjm  * OF THE POSSIBILITY OF SUCH DAMAGE.
51f1535dc8Sdjm  * ====================================================================
52f1535dc8Sdjm  *
53f1535dc8Sdjm  * This product includes cryptographic software written by Eric Young
54f1535dc8Sdjm  * (eay@cryptsoft.com).  This product includes software written by Tim
55f1535dc8Sdjm  * Hudson (tjh@cryptsoft.com).
56f1535dc8Sdjm  *
57f1535dc8Sdjm  */
58f1535dc8Sdjm 
59f1535dc8Sdjm #include <stdio.h>
60f1535dc8Sdjm #include <stdlib.h>
61b6ab114eSjsing 
62f1535dc8Sdjm #include <openssl/bn.h>
63b6ab114eSjsing #include <openssl/err.h>
64b6ab114eSjsing #include <openssl/evp.h>
65b6ab114eSjsing #include <openssl/objects.h>
66b6ab114eSjsing 
67c9675a23Stb #include "asn1_local.h"
68c9675a23Stb #include "bn_local.h"
69c9675a23Stb #include "evp_local.h"
70f1535dc8Sdjm 
71f7631d64Sjsing int
72f7631d64Sjsing EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
73f1535dc8Sdjm {
74474ea8baStb 	if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->paramgen == NULL) {
755067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
76f1535dc8Sdjm 		return -2;
77f1535dc8Sdjm 	}
78474ea8baStb 
79f1535dc8Sdjm 	ctx->operation = EVP_PKEY_OP_PARAMGEN;
80474ea8baStb 
81f1535dc8Sdjm 	return 1;
82f1535dc8Sdjm }
839bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_paramgen_init);
84f1535dc8Sdjm 
85f7631d64Sjsing int
86f7631d64Sjsing EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
87f1535dc8Sdjm {
88f1535dc8Sdjm 	int ret;
89f7631d64Sjsing 
90dc7bfa45Stb 	if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->paramgen == NULL) {
915067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
92f1535dc8Sdjm 		return -2;
93f1535dc8Sdjm 	}
94f1535dc8Sdjm 
95f7631d64Sjsing 	if (ctx->operation != EVP_PKEY_OP_PARAMGEN) {
965067ae9fSbeck 		EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
97f1535dc8Sdjm 		return -1;
98f1535dc8Sdjm 	}
99f1535dc8Sdjm 
100dc7bfa45Stb 	if (ppkey == NULL)
101f1535dc8Sdjm 		return -1;
102f1535dc8Sdjm 
103dc7bfa45Stb 	if (*ppkey == NULL)
104f1535dc8Sdjm 		*ppkey = EVP_PKEY_new();
105dc7bfa45Stb 	if (*ppkey == NULL)
106dc7bfa45Stb 		return -1;
107f1535dc8Sdjm 
108dc7bfa45Stb 	if ((ret = ctx->pmeth->paramgen(ctx, *ppkey)) <= 0) {
109f1535dc8Sdjm 		EVP_PKEY_free(*ppkey);
110f1535dc8Sdjm 		*ppkey = NULL;
111f1535dc8Sdjm 	}
112dc7bfa45Stb 
113f1535dc8Sdjm 	return ret;
114f1535dc8Sdjm }
1159bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_paramgen);
116f1535dc8Sdjm 
117f7631d64Sjsing int
118f7631d64Sjsing EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx)
119f1535dc8Sdjm {
120474ea8baStb 	if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->keygen == NULL)  {
1215067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
122f1535dc8Sdjm 		return -2;
123f1535dc8Sdjm 	}
124474ea8baStb 
125f1535dc8Sdjm 	ctx->operation = EVP_PKEY_OP_KEYGEN;
126474ea8baStb 
127f1535dc8Sdjm 	return 1;
128f1535dc8Sdjm }
1299bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_keygen_init);
130f1535dc8Sdjm 
131f7631d64Sjsing int
132f7631d64Sjsing EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
133f1535dc8Sdjm {
134f1535dc8Sdjm 	int ret;
135f1535dc8Sdjm 
136db6d3e6bStb 	if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->keygen == NULL) {
1375067ae9fSbeck 		EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
138f1535dc8Sdjm 		return -2;
139f1535dc8Sdjm 	}
140f7631d64Sjsing 	if (ctx->operation != EVP_PKEY_OP_KEYGEN) {
1415067ae9fSbeck 		EVPerror(EVP_R_OPERATON_NOT_INITIALIZED);
142f1535dc8Sdjm 		return -1;
143f1535dc8Sdjm 	}
144f1535dc8Sdjm 
145db6d3e6bStb 	if (ppkey == NULL)
146f1535dc8Sdjm 		return -1;
147f1535dc8Sdjm 
148db6d3e6bStb 	if (*ppkey == NULL)
149f1535dc8Sdjm 		*ppkey = EVP_PKEY_new();
150db6d3e6bStb 	if (*ppkey == NULL)
151db6d3e6bStb 		return -1;
152f1535dc8Sdjm 
153db6d3e6bStb 	if ((ret = ctx->pmeth->keygen(ctx, *ppkey)) <= 0) {
154f1535dc8Sdjm 		EVP_PKEY_free(*ppkey);
155f1535dc8Sdjm 		*ppkey = NULL;
156f1535dc8Sdjm 	}
157db6d3e6bStb 
158f1535dc8Sdjm 	return ret;
159f1535dc8Sdjm }
1609bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_keygen);
161f1535dc8Sdjm 
162f7631d64Sjsing void
163f7631d64Sjsing EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb)
164f1535dc8Sdjm {
165f1535dc8Sdjm 	ctx->pkey_gencb = cb;
166f1535dc8Sdjm }
1679bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_CTX_set_cb);
168f1535dc8Sdjm 
169f7631d64Sjsing EVP_PKEY_gen_cb *
170f7631d64Sjsing EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx)
171f1535dc8Sdjm {
172f1535dc8Sdjm 	return ctx->pkey_gencb;
173f1535dc8Sdjm }
1749bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_CTX_get_cb);
175f1535dc8Sdjm 
176f1535dc8Sdjm /* "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB
177f1535dc8Sdjm  * style callbacks.
178f1535dc8Sdjm  */
179f1535dc8Sdjm 
180f7631d64Sjsing static int
181f7631d64Sjsing trans_cb(int a, int b, BN_GENCB *gcb)
182f1535dc8Sdjm {
183f1535dc8Sdjm 	EVP_PKEY_CTX *ctx = gcb->arg;
184f1535dc8Sdjm 	ctx->keygen_info[0] = a;
185f1535dc8Sdjm 	ctx->keygen_info[1] = b;
186f1535dc8Sdjm 	return ctx->pkey_gencb(ctx);
187f1535dc8Sdjm }
188f1535dc8Sdjm 
189f7631d64Sjsing void
190f7631d64Sjsing evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx)
191f1535dc8Sdjm {
19232863f3eStb 	BN_GENCB_set(cb, trans_cb, ctx);
193f1535dc8Sdjm }
194f1535dc8Sdjm 
195f7631d64Sjsing int
196f7631d64Sjsing EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
197f1535dc8Sdjm {
198f1535dc8Sdjm 	if (idx == -1)
199f1535dc8Sdjm 		return ctx->keygen_info_count;
2007054f42fStb 	if (idx < 0 || idx >= ctx->keygen_info_count)
201f1535dc8Sdjm 		return 0;
202f1535dc8Sdjm 	return ctx->keygen_info[idx];
203f1535dc8Sdjm }
2049bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_CTX_get_keygen_info);
205f1535dc8Sdjm 
206f7631d64Sjsing EVP_PKEY *
207f7631d64Sjsing EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key, int keylen)
208f1535dc8Sdjm {
209f1535dc8Sdjm 	EVP_PKEY_CTX *mac_ctx = NULL;
210f1535dc8Sdjm 	EVP_PKEY *mac_key = NULL;
211f7631d64Sjsing 
212592331b2Stb 	mac_ctx = EVP_PKEY_CTX_new_id(type, NULL);
213f1535dc8Sdjm 	if (!mac_ctx)
214f1535dc8Sdjm 		return NULL;
215f1535dc8Sdjm 	if (EVP_PKEY_keygen_init(mac_ctx) <= 0)
216f1535dc8Sdjm 		goto merr;
217f1535dc8Sdjm 	if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
218f7631d64Sjsing 	    EVP_PKEY_CTRL_SET_MAC_KEY, keylen, (void *)key) <= 0)
219f1535dc8Sdjm 		goto merr;
220f1535dc8Sdjm 	if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
221f1535dc8Sdjm 		goto merr;
222f7631d64Sjsing 
223f1535dc8Sdjm merr:
224f1535dc8Sdjm 	EVP_PKEY_CTX_free(mac_ctx);
225f1535dc8Sdjm 	return mac_key;
226f1535dc8Sdjm }
2279bac3682Sbeck LCRYPTO_ALIAS(EVP_PKEY_new_mac_key);
228