pmeth_fn.c revision 296341
128328Ssos/* pmeth_fn.c */ 228328Ssos/* 328328Ssos * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 428328Ssos * 2006. 528328Ssos */ 628328Ssos/* ==================================================================== 728328Ssos * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 828328Ssos * 928328Ssos * Redistribution and use in source and binary forms, with or without 1028328Ssos * modification, are permitted provided that the following conditions 1128328Ssos * are met: 1228328Ssos * 1328328Ssos * 1. Redistributions of source code must retain the above copyright 1428328Ssos * notice, this list of conditions and the following disclaimer. 1597748Sschweikh * 1628328Ssos * 2. Redistributions in binary form must reproduce the above copyright 1728328Ssos * notice, this list of conditions and the following disclaimer in 1828328Ssos * the documentation and/or other materials provided with the 1928328Ssos * distribution. 2028328Ssos * 2128328Ssos * 3. All advertising materials mentioning features or use of this 2228328Ssos * software must display the following acknowledgment: 2328328Ssos * "This product includes software developed by the OpenSSL Project 2428328Ssos * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2528328Ssos * 2628328Ssos * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2728328Ssos * endorse or promote products derived from this software without 2828328Ssos * prior written permission. For written permission, please contact 2983551Sdillon * licensing@OpenSSL.org. 3083551Sdillon * 3183551Sdillon * 5. Products derived from this software may not be called "OpenSSL" 3228328Ssos * nor may "OpenSSL" appear in their names without prior written 3366834Sphk * permission of the OpenSSL Project. 3428328Ssos * 3528328Ssos * 6. Redistributions of any form whatsoever must retain the following 3628328Ssos * acknowledgment: 3728328Ssos * "This product includes software developed by the OpenSSL Project 3828328Ssos * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3928328Ssos * 4028328Ssos * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4128328Ssos * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4228328Ssos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4328328Ssos * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4428328Ssos * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4528328Ssos * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4677475Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4728328Ssos * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4828328Ssos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4928328Ssos * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5028328Ssos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5128328Ssos * OF THE POSSIBILITY OF SUCH DAMAGE. 5228328Ssos * ==================================================================== 5328328Ssos * 5428328Ssos * This product includes cryptographic software written by Eric Young 5528328Ssos * (eay@cryptsoft.com). This product includes software written by Tim 5628328Ssos * Hudson (tjh@cryptsoft.com). 5728328Ssos * 5828328Ssos */ 5928328Ssos 6028328Ssos#include <stdio.h> 6128328Ssos#include <stdlib.h> 6228328Ssos#include "cryptlib.h" 6328328Ssos#include <openssl/objects.h> 6428328Ssos#include <openssl/evp.h> 6550141Syokota#include "evp_locl.h" 6628328Ssos 6728328Ssos#define M_check_autoarg(ctx, arg, arglen, err) \ 6828328Ssos if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \ 6928328Ssos { \ 7028328Ssos size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \ 7128328Ssos if (!arg) \ 7228328Ssos { \ 7328328Ssos *arglen = pksize; \ 7428328Ssos return 1; \ 7528328Ssos } \ 7628328Ssos else if (*arglen < pksize) \ 7728328Ssos { \ 7828328Ssos EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\ 7928328Ssos return 0; \ 8028328Ssos } \ 8128328Ssos } 8228328Ssos 8328328Ssosint EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) 8428328Ssos{ 8528328Ssos int ret; 8628328Ssos if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { 8728328Ssos EVPerr(EVP_F_EVP_PKEY_SIGN_INIT, 8828328Ssos EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 8928328Ssos return -2; 9028328Ssos } 9128328Ssos ctx->operation = EVP_PKEY_OP_SIGN; 9228328Ssos if (!ctx->pmeth->sign_init) 9328328Ssos return 1; 9428328Ssos ret = ctx->pmeth->sign_init(ctx); 9528328Ssos if (ret <= 0) 9628328Ssos ctx->operation = EVP_PKEY_OP_UNDEFINED; 9728328Ssos return ret; 9828328Ssos} 9928328Ssos 10028328Ssosint EVP_PKEY_sign(EVP_PKEY_CTX *ctx, 10128328Ssos unsigned char *sig, size_t *siglen, 10228328Ssos const unsigned char *tbs, size_t tbslen) 10328328Ssos{ 10428328Ssos if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { 10528328Ssos EVPerr(EVP_F_EVP_PKEY_SIGN, 10628328Ssos EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 10728328Ssos return -2; 10828328Ssos } 10928328Ssos if (ctx->operation != EVP_PKEY_OP_SIGN) { 11028328Ssos EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED); 11128328Ssos return -1; 11228328Ssos } 11328328Ssos M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN) 11428328Ssos return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen); 11528328Ssos} 11628328Ssos 11728328Ssosint EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) 11828328Ssos{ 11928328Ssos int ret; 12028328Ssos if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { 12128328Ssos EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT, 12228328Ssos EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 12328328Ssos return -2; 12428328Ssos } 12528328Ssos ctx->operation = EVP_PKEY_OP_VERIFY; 12628328Ssos if (!ctx->pmeth->verify_init) 12728328Ssos return 1; 12828328Ssos ret = ctx->pmeth->verify_init(ctx); 12928328Ssos if (ret <= 0) 13028328Ssos ctx->operation = EVP_PKEY_OP_UNDEFINED; 13128328Ssos return ret; 13228328Ssos} 13328328Ssos 13428328Ssosint EVP_PKEY_verify(EVP_PKEY_CTX *ctx, 13528328Ssos const unsigned char *sig, size_t siglen, 13628328Ssos const unsigned char *tbs, size_t tbslen) 13728328Ssos{ 13828328Ssos if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { 13928328Ssos EVPerr(EVP_F_EVP_PKEY_VERIFY, 14028328Ssos EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 14128328Ssos return -2; 14228328Ssos } 14328328Ssos if (ctx->operation != EVP_PKEY_OP_VERIFY) { 14428328Ssos EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED); 14528328Ssos return -1; 14628328Ssos } 14728328Ssos return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen); 14828328Ssos} 14928328Ssos 15028328Ssosint EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) 15128328Ssos{ 15228328Ssos int ret; 15328328Ssos if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { 15428328Ssos EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT, 15528328Ssos EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 15628328Ssos return -2; 15728328Ssos } 15828328Ssos ctx->operation = EVP_PKEY_OP_VERIFYRECOVER; 15928328Ssos if (!ctx->pmeth->verify_recover_init) 16028328Ssos return 1; 16128328Ssos ret = ctx->pmeth->verify_recover_init(ctx); 16228328Ssos if (ret <= 0) 16328328Ssos ctx->operation = EVP_PKEY_OP_UNDEFINED; 16428328Ssos return ret; 16528328Ssos} 16628328Ssos 16728328Ssosint EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, 16828328Ssos unsigned char *rout, size_t *routlen, 16928328Ssos const unsigned char *sig, size_t siglen) 17028328Ssos{ 17128328Ssos if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { 17228328Ssos EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, 17328328Ssos EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 17428328Ssos return -2; 17528328Ssos } 17628328Ssos if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) { 17728328Ssos EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED); 17828328Ssos return -1; 17928328Ssos } 18028328Ssos M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER) 18128328Ssos return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen); 18228328Ssos} 18328328Ssos 18428328Ssosint EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) 18528328Ssos{ 18628328Ssos int ret; 18728328Ssos if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { 18828328Ssos EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT, 18928328Ssos EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 19028328Ssos return -2; 19128328Ssos } 19228328Ssos ctx->operation = EVP_PKEY_OP_ENCRYPT; 19328328Ssos if (!ctx->pmeth->encrypt_init) 19428328Ssos return 1; 19528328Ssos ret = ctx->pmeth->encrypt_init(ctx); 19628328Ssos if (ret <= 0) 19728328Ssos ctx->operation = EVP_PKEY_OP_UNDEFINED; 19828328Ssos return ret; 19928328Ssos} 20028328Ssos 20128328Ssosint EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, 20228328Ssos unsigned char *out, size_t *outlen, 20328328Ssos const unsigned char *in, size_t inlen) 20428328Ssos{ 20528328Ssos if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { 20628328Ssos EVPerr(EVP_F_EVP_PKEY_ENCRYPT, 20728328Ssos EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 20828328Ssos return -2; 20928328Ssos } 21028328Ssos if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { 21128328Ssos EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED); 21228328Ssos return -1; 21328328Ssos } 21428328Ssos M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT) 21528328Ssos return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); 21628328Ssos} 21728328Ssos 21828328Ssosint EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) 21928328Ssos{ 22028328Ssos int ret; 22128328Ssos if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { 22228328Ssos EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT, 22328328Ssos EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 22428328Ssos return -2; 22528328Ssos } 22628328Ssos ctx->operation = EVP_PKEY_OP_DECRYPT; 22728328Ssos if (!ctx->pmeth->decrypt_init) 22828328Ssos return 1; 22928328Ssos ret = ctx->pmeth->decrypt_init(ctx); 23028328Ssos if (ret <= 0) 23128328Ssos ctx->operation = EVP_PKEY_OP_UNDEFINED; 23228328Ssos return ret; 23328328Ssos} 23428328Ssos 23528328Ssosint EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, 23628328Ssos unsigned char *out, size_t *outlen, 23728328Ssos const unsigned char *in, size_t inlen) 23828328Ssos{ 23928328Ssos if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { 24028328Ssos EVPerr(EVP_F_EVP_PKEY_DECRYPT, 24128328Ssos EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 24228328Ssos return -2; 24328328Ssos } 24428328Ssos if (ctx->operation != EVP_PKEY_OP_DECRYPT) { 24528328Ssos EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED); 246 return -1; 247 } 248 M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT) 249 return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); 250} 251 252int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) 253{ 254 int ret; 255 if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { 256 EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT, 257 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 258 return -2; 259 } 260 ctx->operation = EVP_PKEY_OP_DERIVE; 261 if (!ctx->pmeth->derive_init) 262 return 1; 263 ret = ctx->pmeth->derive_init(ctx); 264 if (ret <= 0) 265 ctx->operation = EVP_PKEY_OP_UNDEFINED; 266 return ret; 267} 268 269int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) 270{ 271 int ret; 272 if (!ctx || !ctx->pmeth 273 || !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt) 274 || !ctx->pmeth->ctrl) { 275 EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, 276 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 277 return -2; 278 } 279 if (ctx->operation != EVP_PKEY_OP_DERIVE 280 && ctx->operation != EVP_PKEY_OP_ENCRYPT 281 && ctx->operation != EVP_PKEY_OP_DECRYPT) { 282 EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, 283 EVP_R_OPERATON_NOT_INITIALIZED); 284 return -1; 285 } 286 287 ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); 288 289 if (ret <= 0) 290 return ret; 291 292 if (ret == 2) 293 return 1; 294 295 if (!ctx->pkey) { 296 EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET); 297 return -1; 298 } 299 300 if (ctx->pkey->type != peer->type) { 301 EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_KEY_TYPES); 302 return -1; 303 } 304 305 /* 306 * ran@cryptocom.ru: For clarity. The error is if parameters in peer are 307 * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return 308 * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 309 * (different key types) is impossible here because it is checked earlier. 310 * -2 is OK for us here, as well as 1, so we can check for 0 only. 311 */ 312 if (!EVP_PKEY_missing_parameters(peer) && 313 !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) { 314 EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS); 315 return -1; 316 } 317 318 if (ctx->peerkey) 319 EVP_PKEY_free(ctx->peerkey); 320 ctx->peerkey = peer; 321 322 ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); 323 324 if (ret <= 0) { 325 ctx->peerkey = NULL; 326 return ret; 327 } 328 329 CRYPTO_add(&peer->references, 1, CRYPTO_LOCK_EVP_PKEY); 330 return 1; 331} 332 333int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen) 334{ 335 if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { 336 EVPerr(EVP_F_EVP_PKEY_DERIVE, 337 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 338 return -2; 339 } 340 if (ctx->operation != EVP_PKEY_OP_DERIVE) { 341 EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED); 342 return -1; 343 } 344 M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE) 345 return ctx->pmeth->derive(ctx, key, pkeylen); 346} 347