1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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 <stdio.h> 60 #include <string.h> 61 62 #include <openssl/err.h> 63 #include <openssl/mem.h> 64 #include <openssl/obj.h> 65 66 #include "internal.h" 67 68 69 static const EVP_PKEY_METHOD *const evp_methods[] = { 70 &rsa_pkey_meth, 71 &ec_pkey_meth, 72 }; 73 74 static const EVP_PKEY_METHOD *evp_pkey_meth_find(int type) { 75 unsigned i; 76 77 for (i = 0; i < sizeof(evp_methods)/sizeof(EVP_PKEY_METHOD*); i++) { 78 if (evp_methods[i]->pkey_id == type) { 79 return evp_methods[i]; 80 } 81 } 82 83 return NULL; 84 } 85 86 static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) { 87 EVP_PKEY_CTX *ret; 88 const EVP_PKEY_METHOD *pmeth; 89 90 if (id == -1) { 91 if (!pkey || !pkey->ameth) { 92 return NULL; 93 } 94 id = pkey->ameth->pkey_id; 95 } 96 97 pmeth = evp_pkey_meth_find(id); 98 99 if (pmeth == NULL) { 100 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); 101 const char *name = OBJ_nid2sn(id); 102 ERR_add_error_dataf("algorithm %d (%s)", id, name); 103 return NULL; 104 } 105 106 ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); 107 if (!ret) { 108 OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); 109 return NULL; 110 } 111 memset(ret, 0, sizeof(EVP_PKEY_CTX)); 112 113 ret->engine = e; 114 ret->pmeth = pmeth; 115 ret->operation = EVP_PKEY_OP_UNDEFINED; 116 117 if (pkey) { 118 ret->pkey = EVP_PKEY_up_ref(pkey); 119 } 120 121 if (pmeth->init) { 122 if (pmeth->init(ret) <= 0) { 123 EVP_PKEY_free(ret->pkey); 124 OPENSSL_free(ret); 125 return NULL; 126 } 127 } 128 129 return ret; 130 } 131 132 EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) { 133 return evp_pkey_ctx_new(pkey, e, -1); 134 } 135 136 EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) { 137 return evp_pkey_ctx_new(NULL, e, id); 138 } 139 140 void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) { 141 if (ctx == NULL) { 142 return; 143 } 144 if (ctx->pmeth && ctx->pmeth->cleanup) { 145 ctx->pmeth->cleanup(ctx); 146 } 147 EVP_PKEY_free(ctx->pkey); 148 EVP_PKEY_free(ctx->peerkey); 149 OPENSSL_free(ctx); 150 } 151 152 EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) { 153 EVP_PKEY_CTX *rctx; 154 155 if (!pctx->pmeth || !pctx->pmeth->copy) { 156 return NULL; 157 } 158 159 rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); 160 if (!rctx) { 161 return NULL; 162 } 163 164 memset(rctx, 0, sizeof(EVP_PKEY_CTX)); 165 166 rctx->pmeth = pctx->pmeth; 167 rctx->engine = pctx->engine; 168 rctx->operation = pctx->operation; 169 170 if (pctx->pkey) { 171 rctx->pkey = EVP_PKEY_up_ref(pctx->pkey); 172 if (rctx->pkey == NULL) { 173 goto err; 174 } 175 } 176 177 if (pctx->peerkey) { 178 rctx->peerkey = EVP_PKEY_up_ref(pctx->peerkey); 179 if (rctx->peerkey == NULL) { 180 goto err; 181 } 182 } 183 184 if (pctx->pmeth->copy(rctx, pctx) > 0) { 185 return rctx; 186 } 187 188 err: 189 EVP_PKEY_CTX_free(rctx); 190 OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); 191 return NULL; 192 } 193 194 EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) { return ctx->pkey; } 195 196 void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data) { 197 ctx->app_data = data; 198 } 199 200 void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx) { return ctx->app_data; } 201 202 int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, 203 int p1, void *p2) { 204 if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { 205 OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); 206 return 0; 207 } 208 if (keytype != -1 && ctx->pmeth->pkey_id != keytype) { 209 return 0; 210 } 211 212 if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { 213 OPENSSL_PUT_ERROR(EVP, EVP_R_NO_OPERATION_SET); 214 return 0; 215 } 216 217 if (optype != -1 && !(ctx->operation & optype)) { 218 OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_OPERATION); 219 return 0; 220 } 221 222 return ctx->pmeth->ctrl(ctx, cmd, p1, p2); 223 } 224 225 int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) { 226 if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { 227 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 228 return 0; 229 } 230 231 ctx->operation = EVP_PKEY_OP_SIGN; 232 if (!ctx->pmeth->sign_init) { 233 return 1; 234 } 235 236 if (!ctx->pmeth->sign_init(ctx)) { 237 ctx->operation = EVP_PKEY_OP_UNDEFINED; 238 return 0; 239 } 240 241 return 1; 242 } 243 244 int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *sig_len, 245 const uint8_t *data, size_t data_len) { 246 if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { 247 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 248 return 0; 249 } 250 if (ctx->operation != EVP_PKEY_OP_SIGN) { 251 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); 252 return 0; 253 } 254 return ctx->pmeth->sign(ctx, sig, sig_len, data, data_len); 255 } 256 257 int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) { 258 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { 259 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 260 return 0; 261 } 262 ctx->operation = EVP_PKEY_OP_VERIFY; 263 if (!ctx->pmeth->verify_init) { 264 return 1; 265 } 266 if (!ctx->pmeth->verify_init(ctx)) { 267 ctx->operation = EVP_PKEY_OP_UNDEFINED; 268 return 0; 269 } 270 271 return 1; 272 } 273 274 int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t sig_len, 275 const uint8_t *data, size_t data_len) { 276 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { 277 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 278 return 0; 279 } 280 if (ctx->operation != EVP_PKEY_OP_VERIFY) { 281 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); 282 return 0; 283 } 284 return ctx->pmeth->verify(ctx, sig, sig_len, data, data_len); 285 } 286 287 int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) { 288 if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { 289 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 290 return 0; 291 } 292 ctx->operation = EVP_PKEY_OP_ENCRYPT; 293 if (!ctx->pmeth->encrypt_init) { 294 return 1; 295 } 296 if (!ctx->pmeth->encrypt_init(ctx)) { 297 ctx->operation = EVP_PKEY_OP_UNDEFINED; 298 return 0; 299 } 300 return 1; 301 } 302 303 int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, 304 const uint8_t *in, size_t inlen) { 305 if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { 306 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 307 return 0; 308 } 309 if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { 310 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); 311 return 0; 312 } 313 return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); 314 } 315 316 int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) { 317 if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { 318 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 319 return 0; 320 } 321 ctx->operation = EVP_PKEY_OP_DECRYPT; 322 if (!ctx->pmeth->decrypt_init) { 323 return 1; 324 } 325 if (!ctx->pmeth->decrypt_init(ctx)) { 326 ctx->operation = EVP_PKEY_OP_UNDEFINED; 327 return 0; 328 } 329 return 1; 330 } 331 332 int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, 333 const uint8_t *in, size_t inlen) { 334 if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { 335 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 336 return 0; 337 } 338 if (ctx->operation != EVP_PKEY_OP_DECRYPT) { 339 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); 340 return 0; 341 } 342 return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); 343 } 344 345 int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) { 346 if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { 347 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 348 return 0; 349 } 350 ctx->operation = EVP_PKEY_OP_DERIVE; 351 if (!ctx->pmeth->derive_init) { 352 return 1; 353 } 354 if (!ctx->pmeth->derive_init(ctx)) { 355 ctx->operation = EVP_PKEY_OP_UNDEFINED; 356 return 0; 357 } 358 return 1; 359 } 360 361 int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) { 362 int ret; 363 if (!ctx || !ctx->pmeth || 364 !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt) || 365 !ctx->pmeth->ctrl) { 366 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 367 return 0; 368 } 369 if (ctx->operation != EVP_PKEY_OP_DERIVE && 370 ctx->operation != EVP_PKEY_OP_ENCRYPT && 371 ctx->operation != EVP_PKEY_OP_DECRYPT) { 372 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); 373 return 0; 374 } 375 376 ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); 377 378 if (ret <= 0) { 379 return 0; 380 } 381 382 if (ret == 2) { 383 return 1; 384 } 385 386 if (!ctx->pkey) { 387 OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); 388 return 0; 389 } 390 391 if (ctx->pkey->type != peer->type) { 392 OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); 393 return 0; 394 } 395 396 /* ran (at) cryptocom.ru: For clarity. The error is if parameters in peer are 397 * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return 398 * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 399 * (different key types) is impossible here because it is checked earlier. 400 * -2 is OK for us here, as well as 1, so we can check for 0 only. */ 401 if (!EVP_PKEY_missing_parameters(peer) && 402 !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) { 403 OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_PARAMETERS); 404 return 0; 405 } 406 407 EVP_PKEY_free(ctx->peerkey); 408 ctx->peerkey = peer; 409 410 ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); 411 412 if (ret <= 0) { 413 ctx->peerkey = NULL; 414 return 0; 415 } 416 417 EVP_PKEY_up_ref(peer); 418 return 1; 419 } 420 421 int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *out_key_len) { 422 if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { 423 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 424 return 0; 425 } 426 if (ctx->operation != EVP_PKEY_OP_DERIVE) { 427 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); 428 return 0; 429 } 430 return ctx->pmeth->derive(ctx, key, out_key_len); 431 } 432 433 int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) { 434 if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { 435 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 436 return 0; 437 } 438 ctx->operation = EVP_PKEY_OP_KEYGEN; 439 if (!ctx->pmeth->keygen_init) { 440 return 1; 441 } 442 if (!ctx->pmeth->keygen_init(ctx)) { 443 ctx->operation = EVP_PKEY_OP_UNDEFINED; 444 return 0; 445 } 446 return 1; 447 } 448 449 int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) { 450 if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { 451 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 452 return 0; 453 } 454 if (ctx->operation != EVP_PKEY_OP_KEYGEN) { 455 OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); 456 return 0; 457 } 458 459 if (!ppkey) { 460 return 0; 461 } 462 463 if (!*ppkey) { 464 *ppkey = EVP_PKEY_new(); 465 if (!*ppkey) { 466 OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); 467 return 0; 468 } 469 } 470 471 if (!ctx->pmeth->keygen(ctx, *ppkey)) { 472 EVP_PKEY_free(*ppkey); 473 *ppkey = NULL; 474 return 0; 475 } 476 return 1; 477 } 478