1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Originally written by Bodo Moeller for the OpenSSL project. 2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ==================================================================== 3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. 4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without 6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions 7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met: 8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the above copyright 10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer. 11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright 13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer in 14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the documentation and/or other materials provided with the 15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * distribution. 16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this 18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * software must display the following acknowledgment: 19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software developed by the OpenSSL Project 20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * endorse or promote products derived from this software without 24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * prior written permission. For written permission, please contact 25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * openssl-core@openssl.org. 26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 5. Products derived from this software may not be called "OpenSSL" 28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * nor may "OpenSSL" appear in their names without prior written 29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * permission of the OpenSSL Project. 30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 6. Redistributions of any form whatsoever must retain the following 32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * acknowledgment: 33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software developed by the OpenSSL Project 34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF THE POSSIBILITY OF SUCH DAMAGE. 48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ==================================================================== 49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This product includes cryptographic software written by Eric Young 51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * (eay@cryptsoft.com). This product includes software written by Tim 52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Hudson (tjh@cryptsoft.com). 53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ==================================================================== 56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Portions of the attached software ("Contribution") are developed by 59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. 60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The Contribution is licensed pursuant to the OpenSSL open source 62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * license provided above. 63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The elliptic curve binary polynomial software is originally written by 65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems 66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Laboratories. */ 67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/ec_key.h> 69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <string.h> 71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/ec.h> 73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/engine.h> 74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/err.h> 75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/ex_data.h> 76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/mem.h> 77e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <openssl/thread.h> 78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "internal.h" 80e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include "../internal.h" 81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 83e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT; 84e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 85d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyEC_KEY *EC_KEY_new(void) { return EC_KEY_new_method(NULL); } 86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 87d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyEC_KEY *EC_KEY_new_method(const ENGINE *engine) { 88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_KEY *ret = (EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY)); 89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ret == NULL) { 90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_KEY_new_method, ERR_R_MALLOC_FAILURE); 91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley memset(ret, 0, sizeof(EC_KEY)); 95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (engine) { 97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ret->ecdsa_meth = ENGINE_get_ECDSA_method(engine); 98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ret->ecdsa_meth) { 100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley METHOD_ref(ret->ecdsa_meth); 101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ret->version = 1; 104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; 105d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ret->references = 1; 106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 107e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (!CRYPTO_new_ex_data(&g_ex_data_class, ret, &ret->ex_data)) { 108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err1; 109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ret->ecdsa_meth && ret->ecdsa_meth->init && !ret->ecdsa_meth->init(ret)) { 112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err2; 113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ret; 116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 117d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyerr2: 118e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CRYPTO_free_ex_data(&g_ex_data_class, ret, &ret->ex_data); 119d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyerr1: 120d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ret->ecdsa_meth) { 121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley METHOD_unref(ret->ecdsa_meth); 122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_free(ret); 124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 127d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyEC_KEY *EC_KEY_new_by_curve_name(int nid) { 128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_KEY *ret = EC_KEY_new(); 129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ret == NULL) { 130e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley OPENSSL_PUT_ERROR(EC, EC_KEY_new_by_curve_name, ERR_R_MALLOC_FAILURE); 131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 132d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ret->group = EC_GROUP_new_by_curve_name(nid); 134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ret->group == NULL) { 135d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_KEY_free(ret); 136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 138d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ret; 139d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 140d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 141d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid EC_KEY_free(EC_KEY *r) { 142d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (r == NULL) { 143d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return; 144d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 145d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 14653b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley if (!CRYPTO_refcount_dec_and_test_zero(&r->references)) { 147d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return; 148d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 149d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 150d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (r->ecdsa_meth) { 151d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (r->ecdsa_meth->finish) { 152d9e397b599b13d642138480a28c14db7a136bf0Adam Langley r->ecdsa_meth->finish(r); 153d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 154d9e397b599b13d642138480a28c14db7a136bf0Adam Langley METHOD_unref(r->ecdsa_meth); 155d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 156d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 157e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley EC_GROUP_free(r->group); 158e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley EC_POINT_free(r->pub_key); 159e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley BN_clear_free(r->priv_key); 160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 161e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CRYPTO_free_ex_data(&g_ex_data_class, r, &r->ex_data); 162d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 163d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_cleanse((void *)r, sizeof(EC_KEY)); 164d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_free(r); 165d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 166d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 167d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyEC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) { 168d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (dest == NULL || src == NULL) { 169d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_KEY_copy, ERR_R_PASSED_NULL_PARAMETER); 170d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 171d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 172e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley /* Copy the parameters. */ 173d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (src->group) { 174d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* TODO(fork): duplicating the group seems wasteful. */ 175e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley EC_GROUP_free(dest->group); 176e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley dest->group = EC_GROUP_dup(src->group); 177d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (dest->group == NULL) { 178d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 179d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 180d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 181d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 182e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley /* Copy the public key. */ 183d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (src->pub_key && src->group) { 184e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley EC_POINT_free(dest->pub_key); 185e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley dest->pub_key = EC_POINT_dup(src->pub_key, src->group); 186d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (dest->pub_key == NULL) { 187d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 188d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 189d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 190d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 191d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* copy the private key */ 192d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (src->priv_key) { 193d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (dest->priv_key == NULL) { 194d9e397b599b13d642138480a28c14db7a136bf0Adam Langley dest->priv_key = BN_new(); 195d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (dest->priv_key == NULL) { 196d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 197d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 198d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 199d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!BN_copy(dest->priv_key, src->priv_key)) { 200d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 201d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 202d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 203d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* copy method/extra data */ 20421c70997ab3c62b97960fd66f02b619850e5d978Adam Langley if (src->ecdsa_meth) { 20521c70997ab3c62b97960fd66f02b619850e5d978Adam Langley METHOD_unref(dest->ecdsa_meth); 20621c70997ab3c62b97960fd66f02b619850e5d978Adam Langley dest->ecdsa_meth = src->ecdsa_meth; 20721c70997ab3c62b97960fd66f02b619850e5d978Adam Langley METHOD_ref(dest->ecdsa_meth); 20821c70997ab3c62b97960fd66f02b619850e5d978Adam Langley } 209e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CRYPTO_free_ex_data(&g_ex_data_class, dest, &dest->ex_data); 210e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (!CRYPTO_dup_ex_data(&g_ex_data_class, &dest->ex_data, 211d9e397b599b13d642138480a28c14db7a136bf0Adam Langley &src->ex_data)) { 212d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 213d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 214d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 215d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* copy the rest */ 216d9e397b599b13d642138480a28c14db7a136bf0Adam Langley dest->enc_flag = src->enc_flag; 217d9e397b599b13d642138480a28c14db7a136bf0Adam Langley dest->conv_form = src->conv_form; 218d9e397b599b13d642138480a28c14db7a136bf0Adam Langley dest->version = src->version; 219d9e397b599b13d642138480a28c14db7a136bf0Adam Langley dest->flags = src->flags; 220d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 221d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return dest; 222d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 223d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 224d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyEC_KEY *EC_KEY_dup(const EC_KEY *ec_key) { 225d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_KEY *ret = EC_KEY_new(); 226d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ret == NULL) { 227d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 228d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 229d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (EC_KEY_copy(ret, ec_key) == NULL) { 230d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_KEY_free(ret); 231d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 232d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 233d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ret; 234d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 235d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 236d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint EC_KEY_up_ref(EC_KEY *r) { 23753b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley CRYPTO_refcount_inc(&r->references); 23853b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley return 1; 239d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 240d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 241d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint EC_KEY_is_opaque(const EC_KEY *key) { 242d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return key->ecdsa_meth && (key->ecdsa_meth->flags & ECDSA_FLAG_OPAQUE); 243d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 244d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 245d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyconst EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) { return key->group; } 246d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 247d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) { 248e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley EC_GROUP_free(key->group); 249d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* TODO(fork): duplicating the group seems wasteful but see 250d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * |EC_KEY_set_conv_form|. */ 251d9e397b599b13d642138480a28c14db7a136bf0Adam Langley key->group = EC_GROUP_dup(group); 252d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return (key->group == NULL) ? 0 : 1; 253d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 254d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 255d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyconst BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) { 256d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return key->priv_key; 257d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 258d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 259d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) { 260e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley BN_clear_free(key->priv_key); 261d9e397b599b13d642138480a28c14db7a136bf0Adam Langley key->priv_key = BN_dup(priv_key); 262d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return (key->priv_key == NULL) ? 0 : 1; 263d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 264d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 265d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyconst EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key) { 266d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return key->pub_key; 267d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 268d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 269d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) { 270e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley EC_POINT_free(key->pub_key); 271d9e397b599b13d642138480a28c14db7a136bf0Adam Langley key->pub_key = EC_POINT_dup(pub_key, key->group); 272d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return (key->pub_key == NULL) ? 0 : 1; 273d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 274d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 275d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyunsigned int EC_KEY_get_enc_flags(const EC_KEY *key) { return key->enc_flag; } 276d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 277d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) { 278d9e397b599b13d642138480a28c14db7a136bf0Adam Langley key->enc_flag = flags; 279d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 280d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 281d9e397b599b13d642138480a28c14db7a136bf0Adam Langleypoint_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) { 282d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return key->conv_form; 283d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 284d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 285d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) { 286d9e397b599b13d642138480a28c14db7a136bf0Adam Langley key->conv_form = cform; 287d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 288d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 289d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) { 290d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (key->group == NULL) { 291d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 292d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 293d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return EC_GROUP_precompute_mult(key->group, ctx); 294d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 295d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 296d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint EC_KEY_check_key(const EC_KEY *eckey) { 297d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int ok = 0; 298d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX *ctx = NULL; 299d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const BIGNUM *order = NULL; 300d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_POINT *point = NULL; 301d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 302d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!eckey || !eckey->group || !eckey->pub_key) { 303d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, ERR_R_PASSED_NULL_PARAMETER); 304d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 305d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 306d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 307d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) { 308d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_POINT_AT_INFINITY); 309d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 310d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 311d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 312d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ctx = BN_CTX_new(); 313d9e397b599b13d642138480a28c14db7a136bf0Adam Langley point = EC_POINT_new(eckey->group); 314d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 315d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ctx == NULL || 316d9e397b599b13d642138480a28c14db7a136bf0Adam Langley point == NULL) { 317d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 318d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 319d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 320d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* testing whether the pub_key is on the elliptic curve */ 321d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx)) { 322d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_POINT_IS_NOT_ON_CURVE); 323d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 324d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 325d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* testing whether pub_key * order is the point at infinity */ 326d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* TODO(fork): can this be skipped if the cofactor is one or if we're about 327d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * to check the private key, below? */ 328d9e397b599b13d642138480a28c14db7a136bf0Adam Langley order = &eckey->group->order; 329d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (BN_is_zero(order)) { 330d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_INVALID_GROUP_ORDER); 331d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 332d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 333d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) { 334d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, ERR_R_EC_LIB); 335d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 336d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 337d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!EC_POINT_is_at_infinity(eckey->group, point)) { 338d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_WRONG_ORDER); 339d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 340d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 341d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* in case the priv_key is present : 342d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * check if generator * priv_key == pub_key 343d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 344d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (eckey->priv_key) { 345d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (BN_cmp(eckey->priv_key, order) >= 0) { 346d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_WRONG_ORDER); 347d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 348d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 349d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) { 350d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, ERR_R_EC_LIB); 351d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 352d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 353d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) { 354d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_INVALID_PRIVATE_KEY); 355d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 356d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 357d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 358d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ok = 1; 359d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 360d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyerr: 361e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley BN_CTX_free(ctx); 362e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley EC_POINT_free(point); 363d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ok; 364d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 365d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 366d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, 367d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIGNUM *y) { 368d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX *ctx = NULL; 369d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIGNUM *tx, *ty; 370d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_POINT *point = NULL; 371d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int ok = 0; 372d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 373d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!key || !key->group || !x || !y) { 374d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_KEY_set_public_key_affine_coordinates, 375d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ERR_R_PASSED_NULL_PARAMETER); 376d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 377d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 378d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ctx = BN_CTX_new(); 379d9e397b599b13d642138480a28c14db7a136bf0Adam Langley point = EC_POINT_new(key->group); 380d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 381d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ctx == NULL || 382d9e397b599b13d642138480a28c14db7a136bf0Adam Langley point == NULL) { 383d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 384d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 385d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 386d9e397b599b13d642138480a28c14db7a136bf0Adam Langley tx = BN_CTX_get(ctx); 387d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ty = BN_CTX_get(ctx); 388d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 389d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!EC_POINT_set_affine_coordinates_GFp(key->group, point, x, y, ctx) || 390d9e397b599b13d642138480a28c14db7a136bf0Adam Langley !EC_POINT_get_affine_coordinates_GFp(key->group, point, tx, ty, ctx)) { 391d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 392d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 393d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 394d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* Check if retrieved coordinates match originals: if not values 395d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are out of range. */ 396d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (BN_cmp(x, tx) || BN_cmp(y, ty)) { 397d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_KEY_set_public_key_affine_coordinates, 398d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_R_COORDINATES_OUT_OF_RANGE); 399d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 400d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 401d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 402d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!EC_KEY_set_public_key(key, point)) { 403d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 404d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 405d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 406d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (EC_KEY_check_key(key) == 0) { 407d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 408d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 409d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 410d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ok = 1; 411d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 412d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyerr: 413e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley BN_CTX_free(ctx); 414e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley EC_POINT_free(point); 415d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ok; 416d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 417d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 418d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint EC_KEY_generate_key(EC_KEY *eckey) { 419d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int ok = 0; 420d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX *ctx = NULL; 421d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIGNUM *priv_key = NULL, *order = NULL; 422d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_POINT *pub_key = NULL; 423d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 424d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!eckey || !eckey->group) { 425d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_KEY_generate_key, ERR_R_PASSED_NULL_PARAMETER); 426d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 427d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 428d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 429d9e397b599b13d642138480a28c14db7a136bf0Adam Langley order = BN_new(); 430d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ctx = BN_CTX_new(); 431d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 432d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (order == NULL || 433d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ctx == NULL) { 434d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 435d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 436d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 437d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (eckey->priv_key == NULL) { 438d9e397b599b13d642138480a28c14db7a136bf0Adam Langley priv_key = BN_new(); 439d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (priv_key == NULL) { 440d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 441d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 442d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 443d9e397b599b13d642138480a28c14db7a136bf0Adam Langley priv_key = eckey->priv_key; 444d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 445d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 446d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!EC_GROUP_get_order(eckey->group, order, ctx)) { 447d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 448d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 449d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 450d9e397b599b13d642138480a28c14db7a136bf0Adam Langley do { 451d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!BN_rand_range(priv_key, order)) { 452d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 453d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 454d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } while (BN_is_zero(priv_key)); 455d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 456d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (eckey->pub_key == NULL) { 457d9e397b599b13d642138480a28c14db7a136bf0Adam Langley pub_key = EC_POINT_new(eckey->group); 458d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (pub_key == NULL) { 459d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 460d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 461d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 462d9e397b599b13d642138480a28c14db7a136bf0Adam Langley pub_key = eckey->pub_key; 463d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 464d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 465d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) { 466d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 467d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 468d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 469d9e397b599b13d642138480a28c14db7a136bf0Adam Langley eckey->priv_key = priv_key; 470d9e397b599b13d642138480a28c14db7a136bf0Adam Langley eckey->pub_key = pub_key; 471d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 472d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ok = 1; 473d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 474d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyerr: 475e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley BN_free(order); 476e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (eckey->pub_key == NULL) { 477d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_POINT_free(pub_key); 478e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 479e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (eckey->priv_key == NULL) { 480d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_free(priv_key); 481e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 482e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley BN_CTX_free(ctx); 483d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ok; 484d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 485d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 486d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint EC_KEY_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, 487d9e397b599b13d642138480a28c14db7a136bf0Adam Langley CRYPTO_EX_dup *dup_func, 488d9e397b599b13d642138480a28c14db7a136bf0Adam Langley CRYPTO_EX_free *free_func) { 489e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley int index; 490e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func, 491e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley dup_func, free_func)) { 492e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley return -1; 493e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 494e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley return index; 495d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 496d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 497d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint EC_KEY_set_ex_data(EC_KEY *d, int idx, void *arg) { 498d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return CRYPTO_set_ex_data(&d->ex_data, idx, arg); 499d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 500d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 501d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid *EC_KEY_get_ex_data(const EC_KEY *d, int idx) { 502d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return CRYPTO_get_ex_data(&d->ex_data, idx); 503d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 504f7e890d94bfb2ecad87621eed301e1897b5a6aefAdam Langley 505f7e890d94bfb2ecad87621eed301e1897b5a6aefAdam Langleyvoid EC_KEY_set_asn1_flag(EC_KEY *key, int flag) {} 506