evp_ctx.c revision 4969cc9b0ab2905ec478277f50ed3849b37a6c6b
1/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay@cryptsoft.com). 6 * The implementation was written so as to conform with Netscapes SSL. 7 * 8 * This library is free for commercial and non-commercial use as long as 9 * the following conditions are aheared to. The following conditions 10 * apply to all code found in this distribution, be it the RC4, RSA, 11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * included with this distribution is covered by the same copyright terms 13 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 14 * 15 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * the code are not to be removed. 17 * If this package is used in a product, Eric Young should be given attribution 18 * as the author of the parts of the library used. 19 * This can be in the form of a textual message at program startup or 20 * in documentation (online or textual) provided with the package. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 1. Redistributions of source code must retain the copyright 26 * notice, this list of conditions and the following disclaimer. 27 * 2. Redistributions in binary form must reproduce the above copyright 28 * notice, this list of conditions and the following disclaimer in the 29 * documentation and/or other materials provided with the distribution. 30 * 3. All advertising materials mentioning features or use of this software 31 * must display the following acknowledgement: 32 * "This product includes cryptographic software written by 33 * Eric Young (eay@cryptsoft.com)" 34 * The word 'cryptographic' can be left out if the rouines from the library 35 * being used are not cryptographic related :-). 36 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * the apps directory (application code) you must include an acknowledgement: 38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * SUCH DAMAGE. 51 * 52 * The licence and distribution terms for any publically available version or 53 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * copied and put under another distribution licence 55 * [including the GNU Public Licence.] */ 56 57#include <openssl/evp.h> 58 59#include <string.h> 60 61#include <openssl/err.h> 62#include <openssl/mem.h> 63 64#include "internal.h" 65 66 67static const EVP_PKEY_METHOD *const evp_methods[] = { 68 &rsa_pkey_meth, 69 &ec_pkey_meth, 70}; 71 72static const EVP_PKEY_METHOD *evp_pkey_meth_find(int type) { 73 unsigned i; 74 75 for (i = 0; i < sizeof(evp_methods)/sizeof(EVP_PKEY_METHOD*); i++) { 76 if (evp_methods[i]->pkey_id == type) { 77 return evp_methods[i]; 78 } 79 } 80 81 return NULL; 82} 83 84static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) { 85 EVP_PKEY_CTX *ret; 86 const EVP_PKEY_METHOD *pmeth; 87 88 if (id == -1) { 89 if (!pkey || !pkey->ameth) { 90 return NULL; 91 } 92 id = pkey->ameth->pkey_id; 93 } 94 95 pmeth = evp_pkey_meth_find(id); 96 97 if (pmeth == NULL) { 98 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); 99 ERR_add_error_dataf("algorithm %d", id); 100 return NULL; 101 } 102 103 ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); 104 if (!ret) { 105 OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); 106 return NULL; 107 } 108 memset(ret, 0, sizeof(EVP_PKEY_CTX)); 109 110 ret->engine = e; 111 ret->pmeth = pmeth; 112 ret->operation = EVP_PKEY_OP_UNDEFINED; 113 114 if (pkey) { 115 ret->pkey = EVP_PKEY_up_ref(pkey); 116 } 117 118 if (pmeth->init) { 119 if (pmeth->init(ret) <= 0) { 120 EVP_PKEY_free(ret->pkey); 121 OPENSSL_free(ret); 122 return NULL; 123 } 124 } 125 126 return ret; 127} 128 129EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) { 130 return evp_pkey_ctx_new(pkey, e, -1); 131} 132 133EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) { 134 return evp_pkey_ctx_new(NULL, e, id); 135} 136 137void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) { 138 if (ctx == NULL) { 139 return; 140 } 141 if (ctx->pmeth && ctx->pmeth->cleanup) { 142 ctx->pmeth->cleanup(ctx); 143 } 144 EVP_PKEY_free(ctx->pkey); 145 EVP_PKEY_free(ctx->peerkey); 146 OPENSSL_free(ctx); 147} 148 149EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) { 150 EVP_PKEY_CTX *rctx; 151 152 if (!pctx->pmeth || !pctx->pmeth->copy) { 153 return NULL; 154 } 155 156 rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); 157 if (!rctx) { 158 return NULL; 159 } 160 161 memset(rctx, 0, sizeof(EVP_PKEY_CTX)); 162 163 rctx->pmeth = pctx->pmeth; 164 rctx->engine = pctx->engine; 165 rctx->operation = pctx->operation; 166 167 if (pctx->pkey) { 168 rctx->pkey = EVP_PKEY_up_ref(pctx->pkey); 169 if (rctx->pkey == NULL) { 170 goto err; 171 } 172 } 173 174 if (pctx->peerkey) { 175 rctx->peerkey = EVP_PKEY_up_ref(pctx->peerkey); 176 if (rctx->peerkey == NULL) { 177 goto err; 178 } 179 } 180 181 if (pctx->pmeth->copy(rctx, pctx) > 0) { 182 return rctx; 183 } 184 185err: 186 EVP_PKEY_CTX_free(rctx); 187 OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); 188 return NULL; 189} 190 191EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) { return ctx->pkey; } 192 193int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, 194 int p1, void *p2) { 195 if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { 196 OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); 197 return 0; 198 } 199 if (keytype != -1 && ctx->pmeth->pkey_id != keytype) { 200 return 0; 201 } 202 203 if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { 204 OPENSSL_PUT_ERROR(EVP, EVP_R_NO_OPERATION_SET); 205 return 0; 206 } 207 208 if (optype != -1 && !(ctx->operation & optype)) { 209 OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_OPERATION); 210 return 0; 211 } 212 213 return ctx->pmeth->ctrl(ctx, cmd, p1, p2); 214} 215 216int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) { 217 if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { 218 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 219 return 0; 220 } 221 222 ctx->operation = EVP_PKEY_OP_SIGN; 223 return 1; 224} 225 226int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *sig_len, 227 const uint8_t *data, size_t data_len) { 228 if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { 229 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 230 return 0; 231 } 232 if (ctx->operation != EVP_PKEY_OP_SIGN) { 233 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); 234 return 0; 235 } 236 return ctx->pmeth->sign(ctx, sig, sig_len, data, data_len); 237} 238 239int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) { 240 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { 241 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 242 return 0; 243 } 244 ctx->operation = EVP_PKEY_OP_VERIFY; 245 return 1; 246} 247 248int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t sig_len, 249 const uint8_t *data, size_t data_len) { 250 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { 251 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 252 return 0; 253 } 254 if (ctx->operation != EVP_PKEY_OP_VERIFY) { 255 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); 256 return 0; 257 } 258 return ctx->pmeth->verify(ctx, sig, sig_len, data, data_len); 259} 260 261int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) { 262 if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { 263 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 264 return 0; 265 } 266 ctx->operation = EVP_PKEY_OP_ENCRYPT; 267 return 1; 268} 269 270int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, 271 const uint8_t *in, size_t inlen) { 272 if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { 273 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 274 return 0; 275 } 276 if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { 277 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); 278 return 0; 279 } 280 return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); 281} 282 283int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) { 284 if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { 285 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 286 return 0; 287 } 288 ctx->operation = EVP_PKEY_OP_DECRYPT; 289 return 1; 290} 291 292int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, 293 const uint8_t *in, size_t inlen) { 294 if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { 295 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 296 return 0; 297 } 298 if (ctx->operation != EVP_PKEY_OP_DECRYPT) { 299 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); 300 return 0; 301 } 302 return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); 303} 304 305int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) { 306 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { 307 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 308 return 0; 309 } 310 ctx->operation = EVP_PKEY_OP_VERIFYRECOVER; 311 return 1; 312} 313 314int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len, 315 const uint8_t *sig, size_t sig_len) { 316 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { 317 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 318 return 0; 319 } 320 if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) { 321 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); 322 return 0; 323 } 324 return ctx->pmeth->verify_recover(ctx, out, out_len, sig, sig_len); 325} 326 327int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) { 328 if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { 329 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 330 return 0; 331 } 332 ctx->operation = EVP_PKEY_OP_DERIVE; 333 return 1; 334} 335 336int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) { 337 int ret; 338 if (!ctx || !ctx->pmeth || 339 !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt) || 340 !ctx->pmeth->ctrl) { 341 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 342 return 0; 343 } 344 if (ctx->operation != EVP_PKEY_OP_DERIVE && 345 ctx->operation != EVP_PKEY_OP_ENCRYPT && 346 ctx->operation != EVP_PKEY_OP_DECRYPT) { 347 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); 348 return 0; 349 } 350 351 ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); 352 353 if (ret <= 0) { 354 return 0; 355 } 356 357 if (ret == 2) { 358 return 1; 359 } 360 361 if (!ctx->pkey) { 362 OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); 363 return 0; 364 } 365 366 if (ctx->pkey->type != peer->type) { 367 OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); 368 return 0; 369 } 370 371 /* ran@cryptocom.ru: For clarity. The error is if parameters in peer are 372 * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return 373 * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 374 * (different key types) is impossible here because it is checked earlier. 375 * -2 is OK for us here, as well as 1, so we can check for 0 only. */ 376 if (!EVP_PKEY_missing_parameters(peer) && 377 !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) { 378 OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_PARAMETERS); 379 return 0; 380 } 381 382 EVP_PKEY_free(ctx->peerkey); 383 ctx->peerkey = peer; 384 385 ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); 386 387 if (ret <= 0) { 388 ctx->peerkey = NULL; 389 return 0; 390 } 391 392 EVP_PKEY_up_ref(peer); 393 return 1; 394} 395 396int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *out_key_len) { 397 if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { 398 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 399 return 0; 400 } 401 if (ctx->operation != EVP_PKEY_OP_DERIVE) { 402 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); 403 return 0; 404 } 405 return ctx->pmeth->derive(ctx, key, out_key_len); 406} 407 408int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) { 409 if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { 410 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 411 return 0; 412 } 413 ctx->operation = EVP_PKEY_OP_KEYGEN; 414 return 1; 415} 416 417int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) { 418 if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { 419 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 420 return 0; 421 } 422 if (ctx->operation != EVP_PKEY_OP_KEYGEN) { 423 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); 424 return 0; 425 } 426 427 if (!ppkey) { 428 return 0; 429 } 430 431 if (!*ppkey) { 432 *ppkey = EVP_PKEY_new(); 433 if (!*ppkey) { 434 OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); 435 return 0; 436 } 437 } 438 439 if (!ctx->pmeth->keygen(ctx, *ppkey)) { 440 EVP_PKEY_free(*ppkey); 441 *ppkey = NULL; 442 return 0; 443 } 444 return 1; 445} 446