Home | History | Annotate | Download | only in evp
      1 /* pmeth_fn.c */
      2 /* Written by Dr Stephen N Henson (steve (at) 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 (at) 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 (at) cryptsoft.com).  This product includes software written by Tim
     55  * Hudson (tjh (at) cryptsoft.com).
     56  *
     57  */
     58 
     59 #include <stdio.h>
     60 #include <stdlib.h>
     61 #include "cryptlib.h"
     62 #include <openssl/objects.h>
     63 #include <openssl/evp.h>
     64 #include "evp_locl.h"
     65 
     66 #define M_check_autoarg(ctx, arg, arglen, err) \
     67 	if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \
     68 		{ \
     69 		size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
     70 		if (!arg) \
     71 			{ \
     72 			*arglen = pksize; \
     73 			return 1; \
     74 			} \
     75 		else if (*arglen < pksize) \
     76 			{ \
     77 			EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\
     78 			return 0; \
     79 			} \
     80 		}
     81 
     82 int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
     83 	{
     84 	int ret;
     85 	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
     86 		{
     87 		EVPerr(EVP_F_EVP_PKEY_SIGN_INIT,
     88 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
     89 		return -2;
     90 		}
     91 	ctx->operation = EVP_PKEY_OP_SIGN;
     92 	if (!ctx->pmeth->sign_init)
     93 		return 1;
     94 	ret = ctx->pmeth->sign_init(ctx);
     95 	if (ret <= 0)
     96 		ctx->operation = EVP_PKEY_OP_UNDEFINED;
     97 	return ret;
     98 	}
     99 
    100 int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
    101 			unsigned char *sig, size_t *siglen,
    102 			const unsigned char *tbs, size_t tbslen)
    103 	{
    104 	if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
    105 		{
    106 		EVPerr(EVP_F_EVP_PKEY_SIGN,
    107 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    108 		return -2;
    109 		}
    110 	if (ctx->operation != EVP_PKEY_OP_SIGN)
    111 		{
    112 		EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED);
    113 		return -1;
    114 		}
    115 	M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
    116 	return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
    117 	}
    118 
    119 int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
    120 	{
    121 	int ret;
    122 	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
    123 		{
    124 		EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT,
    125 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    126 		return -2;
    127 		}
    128 	ctx->operation = EVP_PKEY_OP_VERIFY;
    129 	if (!ctx->pmeth->verify_init)
    130 		return 1;
    131 	ret = ctx->pmeth->verify_init(ctx);
    132 	if (ret <= 0)
    133 		ctx->operation = EVP_PKEY_OP_UNDEFINED;
    134 	return ret;
    135 	}
    136 
    137 int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
    138 			const unsigned char *sig, size_t siglen,
    139 			const unsigned char *tbs, size_t tbslen)
    140 	{
    141 	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
    142 		{
    143 		EVPerr(EVP_F_EVP_PKEY_VERIFY,
    144 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    145 		return -2;
    146 		}
    147 	if (ctx->operation != EVP_PKEY_OP_VERIFY)
    148 		{
    149 		EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED);
    150 		return -1;
    151 		}
    152 	return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
    153 	}
    154 
    155 int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
    156 	{
    157 	int ret;
    158 	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
    159 		{
    160 		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT,
    161 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    162 		return -2;
    163 		}
    164 	ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
    165 	if (!ctx->pmeth->verify_recover_init)
    166 		return 1;
    167 	ret = ctx->pmeth->verify_recover_init(ctx);
    168 	if (ret <= 0)
    169 		ctx->operation = EVP_PKEY_OP_UNDEFINED;
    170 	return ret;
    171 	}
    172 
    173 int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
    174 			unsigned char *rout, size_t *routlen,
    175 			const unsigned char *sig, size_t siglen)
    176 	{
    177 	if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
    178 		{
    179 		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
    180 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    181 		return -2;
    182 		}
    183 	if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER)
    184 		{
    185 		EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED);
    186 		return -1;
    187 		}
    188 	M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
    189 	return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
    190 	}
    191 
    192 int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
    193 	{
    194 	int ret;
    195 	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
    196 		{
    197 		EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT,
    198 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    199 		return -2;
    200 		}
    201 	ctx->operation = EVP_PKEY_OP_ENCRYPT;
    202 	if (!ctx->pmeth->encrypt_init)
    203 		return 1;
    204 	ret = ctx->pmeth->encrypt_init(ctx);
    205 	if (ret <= 0)
    206 		ctx->operation = EVP_PKEY_OP_UNDEFINED;
    207 	return ret;
    208 	}
    209 
    210 int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
    211 			unsigned char *out, size_t *outlen,
    212 			const unsigned char *in, size_t inlen)
    213 	{
    214 	if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
    215 		{
    216 		EVPerr(EVP_F_EVP_PKEY_ENCRYPT,
    217 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    218 		return -2;
    219 		}
    220 	if (ctx->operation != EVP_PKEY_OP_ENCRYPT)
    221 		{
    222 		EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
    223 		return -1;
    224 		}
    225 	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
    226 	return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
    227 	}
    228 
    229 int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
    230 	{
    231 	int ret;
    232 	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
    233 		{
    234 		EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT,
    235 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    236 		return -2;
    237 		}
    238 	ctx->operation = EVP_PKEY_OP_DECRYPT;
    239 	if (!ctx->pmeth->decrypt_init)
    240 		return 1;
    241 	ret = ctx->pmeth->decrypt_init(ctx);
    242 	if (ret <= 0)
    243 		ctx->operation = EVP_PKEY_OP_UNDEFINED;
    244 	return ret;
    245 	}
    246 
    247 int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
    248 			unsigned char *out, size_t *outlen,
    249 			const unsigned char *in, size_t inlen)
    250 	{
    251 	if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
    252 		{
    253 		EVPerr(EVP_F_EVP_PKEY_DECRYPT,
    254 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    255 		return -2;
    256 		}
    257 	if (ctx->operation != EVP_PKEY_OP_DECRYPT)
    258 		{
    259 		EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
    260 		return -1;
    261 		}
    262 	M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
    263 	return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
    264 	}
    265 
    266 
    267 int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
    268 	{
    269 	int ret;
    270 	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
    271 		{
    272 		EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
    273 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    274 		return -2;
    275 		}
    276 	ctx->operation = EVP_PKEY_OP_DERIVE;
    277 	if (!ctx->pmeth->derive_init)
    278 		return 1;
    279 	ret = ctx->pmeth->derive_init(ctx);
    280 	if (ret <= 0)
    281 		ctx->operation = EVP_PKEY_OP_UNDEFINED;
    282 	return ret;
    283 	}
    284 
    285 int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
    286 	{
    287 	int ret;
    288 	if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive||ctx->pmeth->encrypt||ctx->pmeth->decrypt) || !ctx->pmeth->ctrl)
    289 		{
    290 		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
    291 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    292 		return -2;
    293 		}
    294 	if (ctx->operation != EVP_PKEY_OP_DERIVE && ctx->operation != EVP_PKEY_OP_ENCRYPT && ctx->operation != EVP_PKEY_OP_DECRYPT)
    295 		{
    296 		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
    297 					EVP_R_OPERATON_NOT_INITIALIZED);
    298 		return -1;
    299 		}
    300 
    301 	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
    302 
    303 	if (ret <= 0)
    304 		return ret;
    305 
    306 	if (ret == 2)
    307 		return 1;
    308 
    309 	if (!ctx->pkey)
    310 		{
    311 		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
    312 		return -1;
    313 		}
    314 
    315 	if (ctx->pkey->type != peer->type)
    316 		{
    317 		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
    318 						EVP_R_DIFFERENT_KEY_TYPES);
    319 		return -1;
    320 		}
    321 
    322 	/* ran (at) cryptocom.ru: For clarity.  The error is if parameters in peer are
    323 	 * present (!missing) but don't match.  EVP_PKEY_cmp_parameters may return
    324 	 * 1 (match), 0 (don't match) and -2 (comparison is not defined).  -1
    325 	 * (different key types) is impossible here because it is checked earlier.
    326 	 * -2 is OK for us here, as well as 1, so we can check for 0 only. */
    327 	if (!EVP_PKEY_missing_parameters(peer) &&
    328 		!EVP_PKEY_cmp_parameters(ctx->pkey, peer))
    329 		{
    330 		EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
    331 						EVP_R_DIFFERENT_PARAMETERS);
    332 		return -1;
    333 		}
    334 
    335 	if (ctx->peerkey)
    336 		EVP_PKEY_free(ctx->peerkey);
    337 	ctx->peerkey = peer;
    338 
    339 	ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
    340 
    341 	if (ret <= 0)
    342 		{
    343 		ctx->peerkey = NULL;
    344 		return ret;
    345 		}
    346 
    347 	CRYPTO_add(&peer->references,1,CRYPTO_LOCK_EVP_PKEY);
    348 	return 1;
    349 	}
    350 
    351 
    352 int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
    353 	{
    354 	if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
    355 		{
    356 		EVPerr(EVP_F_EVP_PKEY_DERIVE,
    357 			EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    358 		return -2;
    359 		}
    360 	if (ctx->operation != EVP_PKEY_OP_DERIVE)
    361 		{
    362 		EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
    363 		return -1;
    364 		}
    365 	M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
    366 	return ctx->pmeth->derive(ctx, key, pkeylen);
    367 	}
    368 
    369