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