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