1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * project 2006. 3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ==================================================================== 5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without 8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions 9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met: 10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the above copyright 12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer. 13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright 15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer in 16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the documentation and/or other materials provided with the 17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * distribution. 18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this 20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * software must display the following acknowledgment: 21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software developed by the OpenSSL Project 22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * endorse or promote products derived from this software without 26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * prior written permission. For written permission, please contact 27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * licensing@OpenSSL.org. 28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 5. Products derived from this software may not be called "OpenSSL" 30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * nor may "OpenSSL" appear in their names without prior written 31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * permission of the OpenSSL Project. 32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 6. Redistributions of any form whatsoever must retain the following 34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * acknowledgment: 35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software developed by the OpenSSL Project 36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF THE POSSIBILITY OF SUCH DAMAGE. 50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ==================================================================== 51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This product includes cryptographic software written by Eric Young 53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * (eay@cryptsoft.com). This product includes software written by Tim 54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Hudson (tjh@cryptsoft.com). */ 55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/evp.h> 57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <string.h> 59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/bn.h> 61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/buf.h> 62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/digest.h> 63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/ec.h> 64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/ec_key.h> 65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/ecdh.h> 66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/ecdsa.h> 67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/err.h> 68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/mem.h> 694969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#include <openssl/nid.h> 70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "internal.h" 728ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan#include "../fipsmodule/ec/internal.h" 7369939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan#include "../internal.h" 74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 76d9e397b599b13d642138480a28c14db7a136bf0Adam Langleytypedef struct { 77d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* message digest */ 78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const EVP_MD *md; 79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} EC_PKEY_CTX; 80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 82d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int pkey_ec_init(EVP_PKEY_CTX *ctx) { 83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_PKEY_CTX *dctx; 84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX)); 85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!dctx) { 86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 8869939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan OPENSSL_memset(dctx, 0, sizeof(EC_PKEY_CTX)); 89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ctx->data = dctx; 91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 95d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { 96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_PKEY_CTX *dctx, *sctx; 97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!pkey_ec_init(dst)) { 98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley sctx = src->data; 101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley dctx = dst->data; 102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley dctx->md = sctx->md; 104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 105d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 108d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) { 109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_PKEY_CTX *dctx = ctx->data; 110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!dctx) { 111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return; 112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_free(dctx); 115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 117d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, 118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const uint8_t *tbs, size_t tbslen) { 119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley unsigned int sltmp; 120d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_KEY *ec = ctx->pkey->pkey.ec; 121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!sig) { 123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *siglen = ECDSA_size(ec); 124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else if (*siglen < (size_t)ECDSA_size(ec)) { 126b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); 127d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 130b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root if (!ECDSA_sign(0, tbs, tbslen, sig, &sltmp, ec)) { 131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 132d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *siglen = (size_t)sltmp; 134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 135d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 137d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int pkey_ec_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, 138d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const uint8_t *tbs, size_t tbslen) { 139b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root return ECDSA_verify(0, tbs, tbslen, sig, siglen, ctx->pkey->pkey.ec); 140d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 141d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 142d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int pkey_ec_derive(EVP_PKEY_CTX *ctx, uint8_t *key, 143d9e397b599b13d642138480a28c14db7a136bf0Adam Langley size_t *keylen) { 144d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int ret; 145d9e397b599b13d642138480a28c14db7a136bf0Adam Langley size_t outlen; 146d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const EC_POINT *pubkey = NULL; 147d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_KEY *eckey; 148d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 149d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!ctx->pkey || !ctx->peerkey) { 150b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET); 151d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 152d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 153d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 154d9e397b599b13d642138480a28c14db7a136bf0Adam Langley eckey = ctx->pkey->pkey.ec; 155d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 156d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!key) { 157d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const EC_GROUP *group; 158d9e397b599b13d642138480a28c14db7a136bf0Adam Langley group = EC_KEY_get0_group(eckey); 159d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *keylen = (EC_GROUP_get_degree(group) + 7) / 8; 160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 161d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 162d9e397b599b13d642138480a28c14db7a136bf0Adam Langley pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec); 163d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 164d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is 165d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * not an error, the result is truncated. */ 166d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 167d9e397b599b13d642138480a28c14db7a136bf0Adam Langley outlen = *keylen; 168d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 169d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0); 170d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ret < 0) { 171d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 172d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 173d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *keylen = ret; 174d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 175d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 176d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 177d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { 178d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_PKEY_CTX *dctx = ctx->data; 179d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 180d9e397b599b13d642138480a28c14db7a136bf0Adam Langley switch (type) { 181d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case EVP_PKEY_CTRL_MD: 182d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && 183d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 && 184d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && 185d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && 186d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && 187d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EVP_MD_type((const EVP_MD *)p2) != NID_sha512) { 188b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_DIGEST_TYPE); 189d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 190d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 191d9e397b599b13d642138480a28c14db7a136bf0Adam Langley dctx->md = p2; 192d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 193d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 194d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case EVP_PKEY_CTRL_GET_MD: 195d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *(const EVP_MD **)p2 = dctx->md; 196d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 197d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 198d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case EVP_PKEY_CTRL_PEER_KEY: 199b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root /* Default behaviour is OK */ 200d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 201d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 202d9e397b599b13d642138480a28c14db7a136bf0Adam Langley default: 203b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); 204e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley return 0; 205d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 206d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 207d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 208d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { 2094969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (ctx->pkey == NULL) { 210b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET); 211d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 212d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 2134969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin EC_KEY *ec = EC_KEY_new(); 2144969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (ec == NULL || 2154969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !EC_KEY_set_group(ec, EC_KEY_get0_group(ctx->pkey->pkey.ec)) || 2164969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin !EC_KEY_generate_key(ec)) { 2174969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin EC_KEY_free(ec); 218d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 219d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 220d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EVP_PKEY_assign_EC_KEY(pkey, ec); 2214969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 1; 222d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 223d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 224d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyconst EVP_PKEY_METHOD ec_pkey_meth = { 2254969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin EVP_PKEY_EC, 2264969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin pkey_ec_init, 2274969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin pkey_ec_copy, 2284969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin pkey_ec_cleanup, 2294969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin pkey_ec_keygen, 2304969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin pkey_ec_sign, 231572a4e2e687520da9e518528d7371b794b1decc0Robert Sloan NULL /* sign_message */, 2324969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin pkey_ec_verify, 233572a4e2e687520da9e518528d7371b794b1decc0Robert Sloan NULL /* verify_message */, 234572a4e2e687520da9e518528d7371b794b1decc0Robert Sloan NULL /* verify_recover */, 235572a4e2e687520da9e518528d7371b794b1decc0Robert Sloan NULL /* encrypt */, 236572a4e2e687520da9e518528d7371b794b1decc0Robert Sloan NULL /* decrypt */, 2374969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin pkey_ec_derive, 2384969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin pkey_ec_ctrl, 239d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}; 240