1904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * project 2006. 3904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom */ 4904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom/* ==================================================================== 5904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 6904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * 7904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * Redistribution and use in source and binary forms, with or without 8904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * modification, are permitted provided that the following conditions 9904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * are met: 10904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * 11904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * 1. Redistributions of source code must retain the above copyright 12904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * notice, this list of conditions and the following disclaimer. 13904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * 14904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * 2. Redistributions in binary form must reproduce the above copyright 15904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * notice, this list of conditions and the following disclaimer in 16904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * the documentation and/or other materials provided with the 17904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * distribution. 18904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * 19904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * 3. All advertising materials mentioning features or use of this 20904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * software must display the following acknowledgment: 21904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * "This product includes software developed by the OpenSSL Project 22904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 23904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * 24904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 25904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * endorse or promote products derived from this software without 26904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * prior written permission. For written permission, please contact 27904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * licensing@OpenSSL.org. 28904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * 29904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * 5. Products derived from this software may not be called "OpenSSL" 30904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * nor may "OpenSSL" appear in their names without prior written 31904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * permission of the OpenSSL Project. 32904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * 33904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * 6. Redistributions of any form whatsoever must retain the following 34904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * acknowledgment: 35904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * "This product includes software developed by the OpenSSL Project 36904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 37904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * 38904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 39904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 41904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 42904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 43904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 44904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 45904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 46904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 47904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 49904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * OF THE POSSIBILITY OF SUCH DAMAGE. 50904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * ==================================================================== 51904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * 52904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * This product includes cryptographic software written by Eric Young 53904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * (eay@cryptsoft.com). This product includes software written by Tim 54904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * Hudson (tjh@cryptsoft.com). 55904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * 56904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom */ 57904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 58904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom#include <stdio.h> 59904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom#include "cryptlib.h" 60904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom#include <openssl/asn1t.h> 61904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom#include <openssl/x509.h> 62904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom#include <openssl/ec.h> 63904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom#include <openssl/ecdsa.h> 64904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom#include <openssl/evp.h> 65904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom#include "evp_locl.h" 66904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 67904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom/* EC pkey context structure */ 68904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 69904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstromtypedef struct 70904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 71904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom /* Key and paramgen group */ 72904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EC_GROUP *gen_group; 73904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom /* message digest */ 74904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom const EVP_MD *md; 75904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } EC_PKEY_CTX; 76904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 77904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstromstatic int pkey_ec_init(EVP_PKEY_CTX *ctx) 78904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 79904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EC_PKEY_CTX *dctx; 80904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX)); 81904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (!dctx) 82904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 0; 83904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom dctx->gen_group = NULL; 84904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom dctx->md = NULL; 85904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 86904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom ctx->data = dctx; 87904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 88904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 1; 89904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 90904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 91904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstromstatic int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) 92904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 93904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EC_PKEY_CTX *dctx, *sctx; 94904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (!pkey_ec_init(dst)) 95904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 0; 96904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom sctx = src->data; 97904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom dctx = dst->data; 98904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (sctx->gen_group) 99904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 100904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom dctx->gen_group = EC_GROUP_dup(sctx->gen_group); 101904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (!dctx->gen_group) 102904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 0; 103904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 104904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom dctx->md = sctx->md; 105904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 1; 106904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 107904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 108904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstromstatic void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) 109904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 110904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EC_PKEY_CTX *dctx = ctx->data; 111904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (dctx) 112904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 113904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (dctx->gen_group) 114904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EC_GROUP_free(dctx->gen_group); 115904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom OPENSSL_free(dctx); 116904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 117904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 118904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 119904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstromstatic int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, 120904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom const unsigned char *tbs, size_t tbslen) 121904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 122904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom int ret, type; 123904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom unsigned int sltmp; 124904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EC_PKEY_CTX *dctx = ctx->data; 125904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EC_KEY *ec = ctx->pkey->pkey.ec; 126904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 127904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (!sig) 128904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 129904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom *siglen = ECDSA_size(ec); 130904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 1; 131904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 132904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom else if(*siglen < (size_t)ECDSA_size(ec)) 133904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 134904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL); 135904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 0; 136904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 137904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 138904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (dctx->md) 139904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom type = EVP_MD_type(dctx->md); 140904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom else 141904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom type = NID_sha1; 142904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 143904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 144904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec); 145904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 146904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (ret <= 0) 147904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return ret; 148904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom *siglen = (size_t)sltmp; 149904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 1; 150904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 151904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 152904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstromstatic int pkey_ec_verify(EVP_PKEY_CTX *ctx, 153904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom const unsigned char *sig, size_t siglen, 154904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom const unsigned char *tbs, size_t tbslen) 155904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 156904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom int ret, type; 157904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EC_PKEY_CTX *dctx = ctx->data; 158904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EC_KEY *ec = ctx->pkey->pkey.ec; 159904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 160904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (dctx->md) 161904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom type = EVP_MD_type(dctx->md); 162904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom else 163904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom type = NID_sha1; 164904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 165904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec); 166904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 167904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return ret; 168904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 169904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 170904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstromstatic int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) 171904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 172904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom int ret; 173904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom size_t outlen; 174904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom const EC_POINT *pubkey = NULL; 175904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (!ctx->pkey || !ctx->peerkey) 176904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 177904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET); 178904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 0; 179904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 180904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 181904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (!key) 182904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 183904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom const EC_GROUP *group; 184904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom group = EC_KEY_get0_group(ctx->pkey->pkey.ec); 185904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom *keylen = (EC_GROUP_get_degree(group) + 7)/8; 186904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 1; 187904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 188904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 189904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec); 190904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 191904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom /* NB: unlike PKS#3 DH, if *outlen is less than maximum size this is 192904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom * not an error, the result is truncated. 193904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom */ 194904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 195904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom outlen = *keylen; 196904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 197904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom ret = ECDH_compute_key(key, outlen, pubkey, ctx->pkey->pkey.ec, 0); 198904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (ret < 0) 199904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return ret; 200904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom *keylen = ret; 201904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 1; 202904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 203904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 204904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstromstatic int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 205904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 206904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EC_PKEY_CTX *dctx = ctx->data; 207904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EC_GROUP *group; 208904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom switch (type) 209904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 210904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: 211904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom group = EC_GROUP_new_by_curve_name(p1); 212904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (group == NULL) 213904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 214904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE); 215904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 0; 216904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 217904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (dctx->gen_group) 218904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EC_GROUP_free(dctx->gen_group); 219904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom dctx->gen_group = group; 220904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 1; 221904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 222904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom case EVP_PKEY_CTRL_MD: 223904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && 224392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 && 225904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && 226904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && 227904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && 228904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EVP_MD_type((const EVP_MD *)p2) != NID_sha512) 229904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 230904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE); 231904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 0; 232904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 233904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom dctx->md = p2; 234904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 1; 235904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 236904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom case EVP_PKEY_CTRL_PEER_KEY: 237904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom /* Default behaviour is OK */ 238904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom case EVP_PKEY_CTRL_DIGESTINIT: 239904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom case EVP_PKEY_CTRL_PKCS7_SIGN: 240904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom case EVP_PKEY_CTRL_CMS_SIGN: 241904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 1; 242904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 243904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom default: 244904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return -2; 245904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 246904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 247904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 248904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 249904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstromstatic int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx, 250904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom const char *type, const char *value) 251904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 252904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (!strcmp(type, "ec_paramgen_curve")) 253904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 254904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom int nid; 255904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom nid = OBJ_sn2nid(value); 256904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (nid == NID_undef) 257904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom nid = OBJ_ln2nid(value); 258904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (nid == NID_undef) 259904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 260904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE); 261904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 0; 262904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 263904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); 264904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 265904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return -2; 266904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 267904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 268904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstromstatic int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 269904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 270904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EC_KEY *ec = NULL; 271904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EC_PKEY_CTX *dctx = ctx->data; 272904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom int ret = 0; 273904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (dctx->gen_group == NULL) 274904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 275904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET); 276904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 0; 277904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 278904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom ec = EC_KEY_new(); 279904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (!ec) 280904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 0; 281904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom ret = EC_KEY_set_group(ec, dctx->gen_group); 282904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (ret) 283904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EVP_PKEY_assign_EC_KEY(pkey, ec); 284904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom else 285904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EC_KEY_free(ec); 286904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return ret; 287904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 288904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 289904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstromstatic int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 290904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 291904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EC_KEY *ec = NULL; 292904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (ctx->pkey == NULL) 293904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 294904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET); 295904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 0; 296904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 297904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom ec = EC_KEY_new(); 298904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (!ec) 299904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 0; 300904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EVP_PKEY_assign_EC_KEY(pkey, ec); 301904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom /* Note: if error return, pkey is freed by parent routine */ 302904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) 303904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return 0; 304904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom return EC_KEY_generate_key(pkey->pkey.ec); 305904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom } 306904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 307904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstromconst EVP_PKEY_METHOD ec_pkey_meth = 308904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom { 309904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom EVP_PKEY_EC, 310904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 0, 311904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom pkey_ec_init, 312904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom pkey_ec_copy, 313904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom pkey_ec_cleanup, 314904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 315904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 0, 316904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom pkey_ec_paramgen, 317904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 318904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 0, 319904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom pkey_ec_keygen, 320904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 321904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 0, 322904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom pkey_ec_sign, 323904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 324904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 0, 325904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom pkey_ec_verify, 326904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 327904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 0,0, 328904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 329904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 0,0,0,0, 330904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 331904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 0,0, 332904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 333904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 0,0, 334904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 335904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 0, 336904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom pkey_ec_derive, 337904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 338904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom pkey_ec_ctrl, 339904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom pkey_ec_ctrl_str 340904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom 341904c5bb06deb8e0b17c3673c0ceb7d80420c16f3Brian Carlstrom }; 342