1221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* pmeth_fn.c */
2221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * project 2006.
4221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */
5221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* ====================================================================
6221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
7221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
8221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Redistribution and use in source and binary forms, with or without
9221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * modification, are permitted provided that the following conditions
10221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * are met:
11221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
12221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 1. Redistributions of source code must retain the above copyright
13221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    notice, this list of conditions and the following disclaimer.
14221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
15221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 2. Redistributions in binary form must reproduce the above copyright
16221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    notice, this list of conditions and the following disclaimer in
17221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    the documentation and/or other materials provided with the
18221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    distribution.
19221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
20221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 3. All advertising materials mentioning features or use of this
21221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    software must display the following acknowledgment:
22221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    "This product includes software developed by the OpenSSL Project
23221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
25221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    endorse or promote products derived from this software without
27221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    prior written permission. For written permission, please contact
28221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    licensing@OpenSSL.org.
29221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
30221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 5. Products derived from this software may not be called "OpenSSL"
31221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    nor may "OpenSSL" appear in their names without prior written
32221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    permission of the OpenSSL Project.
33221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
34221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 6. Redistributions of any form whatsoever must retain the following
35221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    acknowledgment:
36221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    "This product includes software developed by the OpenSSL Project
37221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
39221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * OF THE POSSIBILITY OF SUCH DAMAGE.
51221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * ====================================================================
52221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
53221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * This product includes cryptographic software written by Eric Young
54221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * (eay@cryptsoft.com).  This product includes software written by Tim
55221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Hudson (tjh@cryptsoft.com).
56221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
57221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */
58221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
59221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <stdio.h>
60221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <stdlib.h>
61221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include "cryptlib.h"
62221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <openssl/objects.h>
63221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <openssl/evp.h>
64221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include "evp_locl.h"
65221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
66221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define M_check_autoarg(ctx, arg, arglen, err) \
67221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \
68221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{ \
69221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
70221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!arg) \
71221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{ \
72221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			*arglen = pksize; \
73221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 1; \
74221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			} \
75221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else if (*arglen < pksize) \
76221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{ \
77221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\
78221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 0; \
79221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			} \
80221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
81221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
82221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
83221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
84221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret;
85221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
86221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
87221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_SIGN_INIT,
88221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
89221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -2;
90221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
91221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ctx->operation = EVP_PKEY_OP_SIGN;
92221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx->pmeth->sign_init)
93221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
94221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ret = ctx->pmeth->sign_init(ctx);
95221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret <= 0)
96221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ctx->operation = EVP_PKEY_OP_UNDEFINED;
97221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ret;
98221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
99221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
100221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
101221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			unsigned char *sig, size_t *siglen,
102221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const unsigned char *tbs, size_t tbslen)
103221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
104221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
105221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
106221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_SIGN,
107221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
108221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -2;
109221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
110221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ctx->operation != EVP_PKEY_OP_SIGN)
111221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
112221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED);
113221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -1;
114221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
115221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
116221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
117221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
118221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
119221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
120221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
121221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret;
122221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
123221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
124221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT,
125221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
126221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -2;
127221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
128221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ctx->operation = EVP_PKEY_OP_VERIFY;
129221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx->pmeth->verify_init)
130221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
131221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ret = ctx->pmeth->verify_init(ctx);
132221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret <= 0)
133221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ctx->operation = EVP_PKEY_OP_UNDEFINED;
134221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ret;
135221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
136221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
137221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
138221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const unsigned char *sig, size_t siglen,
139221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const unsigned char *tbs, size_t tbslen)
140221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
141221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
142221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
143221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_VERIFY,
144221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
145221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -2;
146221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
147221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ctx->operation != EVP_PKEY_OP_VERIFY)
148221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
149221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED);
150221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -1;
151221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
152221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
153221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
154221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
155221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
156221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
157221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret;
158221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
159221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
160221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT,
161221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
162221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -2;
163221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
164221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
165221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx->pmeth->verify_recover_init)
166221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
167221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ret = ctx->pmeth->verify_recover_init(ctx);
168221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret <= 0)
169221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ctx->operation = EVP_PKEY_OP_UNDEFINED;
170221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ret;
171221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
172221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
173221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
174221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			unsigned char *rout, size_t *routlen,
175221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const unsigned char *sig, size_t siglen)
176221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
177221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
178221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
179221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
180221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
181221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -2;
182221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
183221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER)
184221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
185221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED);
186221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -1;
187221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
188221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
189221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
190221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
191221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
192221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
193221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
194221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret;
195221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
196221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
197221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT,
198221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
199221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -2;
200221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
201221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ctx->operation = EVP_PKEY_OP_ENCRYPT;
202221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx->pmeth->encrypt_init)
203221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
204221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ret = ctx->pmeth->encrypt_init(ctx);
205221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret <= 0)
206221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ctx->operation = EVP_PKEY_OP_UNDEFINED;
207221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ret;
208221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
209221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
210221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
211221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			unsigned char *out, size_t *outlen,
212221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const unsigned char *in, size_t inlen)
213221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
214221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
215221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
216221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_ENCRYPT,
217221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
218221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -2;
219221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
220221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ctx->operation != EVP_PKEY_OP_ENCRYPT)
221221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
222221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
223221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -1;
224221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
225221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
226221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
227221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
228221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
229221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
230221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
231221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret;
232221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
233221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
234221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT,
235221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
236221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -2;
237221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
238221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ctx->operation = EVP_PKEY_OP_DECRYPT;
239221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx->pmeth->decrypt_init)
240221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
241221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ret = ctx->pmeth->decrypt_init(ctx);
242221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret <= 0)
243221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ctx->operation = EVP_PKEY_OP_UNDEFINED;
244221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ret;
245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
246221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
247221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
248221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			unsigned char *out, size_t *outlen,
249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const unsigned char *in, size_t inlen)
250221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
251221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
252221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
253221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_DECRYPT,
254221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
255221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -2;
256221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
257221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ctx->operation != EVP_PKEY_OP_DECRYPT)
258221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
259221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
260221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -1;
261221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
262221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
263221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
264221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
265221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
266221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
267221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
268221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
269221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret;
270221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
271221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
272221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
273221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
274221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -2;
275221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
276221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ctx->operation = EVP_PKEY_OP_DERIVE;
277221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx->pmeth->derive_init)
278221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
279221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ret = ctx->pmeth->derive_init(ctx);
280221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret <= 0)
281221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ctx->operation = EVP_PKEY_OP_UNDEFINED;
282221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ret;
283221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
284221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
285221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
286221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
287221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret;
288221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive||ctx->pmeth->encrypt||ctx->pmeth->decrypt) || !ctx->pmeth->ctrl)
289221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
290221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
291221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
292221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -2;
293221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
294221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ctx->operation != EVP_PKEY_OP_DERIVE && ctx->operation != EVP_PKEY_OP_ENCRYPT && ctx->operation != EVP_PKEY_OP_DECRYPT)
295221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
296221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
297221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					EVP_R_OPERATON_NOT_INITIALIZED);
298221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -1;
299221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
300221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
301221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
302221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
303221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret <= 0)
304221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return ret;
305221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
306221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret == 2)
307221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
308221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
309221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx->pkey)
310221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
311221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
312221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -1;
313221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
314221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
315221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ctx->pkey->type != peer->type)
316221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
317221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
318221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom						EVP_R_DIFFERENT_KEY_TYPES);
319221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -1;
320221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
321221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
322221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* ran@cryptocom.ru: For clarity.  The error is if parameters in peer are
323221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	 * present (!missing) but don't match.  EVP_PKEY_cmp_parameters may return
324221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	 * 1 (match), 0 (don't match) and -2 (comparison is not defined).  -1
325221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	 * (different key types) is impossible here because it is checked earlier.
326221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	 * -2 is OK for us here, as well as 1, so we can check for 0 only. */
327221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!EVP_PKEY_missing_parameters(peer) &&
328221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		!EVP_PKEY_cmp_parameters(ctx->pkey, peer))
329221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
330221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
331221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom						EVP_R_DIFFERENT_PARAMETERS);
332221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -1;
333221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
334221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
335221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ctx->peerkey)
336221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVP_PKEY_free(ctx->peerkey);
337221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ctx->peerkey = peer;
338221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
339221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
340221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
341221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ret <= 0)
342221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
343221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ctx->peerkey = NULL;
344221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return ret;
345221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
346221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
347221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	CRYPTO_add(&peer->references,1,CRYPTO_LOCK_EVP_PKEY);
348221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
349221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
350221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
351221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
352221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
353221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
354221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
355221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
356221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_DERIVE,
357221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
358221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -2;
359221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
360221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ctx->operation != EVP_PKEY_OP_DERIVE)
361221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
362221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
363221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return -1;
364221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
365221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
366221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ctx->pmeth->derive(ctx, key, pkeylen);
367221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
368221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
369