1c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* crypto/ec/ec_key.c */ 2c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* 3c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Written by Nils Larsch for the OpenSSL project. 4c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 5c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* ==================================================================== 6c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. 7c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 8c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Redistribution and use in source and binary forms, with or without 9c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * modification, are permitted provided that the following conditions 10c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * are met: 11c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 12c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1. Redistributions of source code must retain the above copyright 13c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * notice, this list of conditions and the following disclaimer. 14c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 15c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 2. Redistributions in binary form must reproduce the above copyright 16c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * notice, this list of conditions and the following disclaimer in 17c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the documentation and/or other materials provided with the 18c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * distribution. 19c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 20c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 3. All advertising materials mentioning features or use of this 21c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * software must display the following acknowledgment: 22c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * "This product includes software developed by the OpenSSL Project 23c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 24c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 25c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * endorse or promote products derived from this software without 27c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * prior written permission. For written permission, please contact 28c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * openssl-core@openssl.org. 29c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 30c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 5. Products derived from this software may not be called "OpenSSL" 31c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * nor may "OpenSSL" appear in their names without prior written 32c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * permission of the OpenSSL Project. 33c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 34c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 6. Redistributions of any form whatsoever must retain the following 35c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * acknowledgment: 36c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * "This product includes software developed by the OpenSSL Project 37c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 38c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 39c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OF THE POSSIBILITY OF SUCH DAMAGE. 51c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ==================================================================== 52c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 53c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This product includes cryptographic software written by Eric Young 54c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * (eay@cryptsoft.com). This product includes software written by Tim 55c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Hudson (tjh@cryptsoft.com). 56c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 57c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 58c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* ==================================================================== 59c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 60c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Portions originally developed by SUN MICROSYSTEMS, INC., and 61c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * contributed to the OpenSSL project. 62c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 63c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 64c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <string.h> 65c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include "ec_lcl.h" 66c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/err.h> 672c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef OPENSSL_FIPS 682c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#include <openssl/fips.h> 692c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 70c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 71c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgEC_KEY *EC_KEY_new(void) 72c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 73c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_KEY *ret; 74c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 75c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret=(EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY)); 76c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret == NULL) 77c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 78c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE); 79c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(NULL); 80c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 81c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 82c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->version = 1; 832c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ret->flags = 0; 84c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->group = NULL; 85c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->pub_key = NULL; 86c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->priv_key= NULL; 87c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->enc_flag= 0; 88c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; 89c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->references= 1; 90c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->method_data = NULL; 91c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ret); 92c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 93c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 94c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgEC_KEY *EC_KEY_new_by_curve_name(int nid) 95c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 96c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_KEY *ret = EC_KEY_new(); 97c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret == NULL) 98c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 99c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ret->group = EC_GROUP_new_by_curve_name(nid); 100c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret->group == NULL) 101c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 102c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_KEY_free(ret); 103c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 104c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 105c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return ret; 106c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 107c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 108c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid EC_KEY_free(EC_KEY *r) 109c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 110c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i; 111c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 112c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (r == NULL) return; 113c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 114c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_EC); 115c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef REF_PRINT 116c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org REF_PRINT("EC_KEY",r); 117c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 118c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (i > 0) return; 119c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef REF_CHECK 120c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (i < 0) 121c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 122c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org fprintf(stderr,"EC_KEY_free, bad reference count\n"); 123c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org abort(); 124c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 125c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 126c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 127c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (r->group != NULL) 128c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_GROUP_free(r->group); 129c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (r->pub_key != NULL) 130c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_POINT_free(r->pub_key); 131c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (r->priv_key != NULL) 132c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BN_clear_free(r->priv_key); 133c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 134c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_EX_DATA_free_all_data(&r->method_data); 135c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 136c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_cleanse((void *)r, sizeof(EC_KEY)); 137c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 138c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(r); 139c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 140c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 141c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgEC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) 142c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 143c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_EXTRA_DATA *d; 144c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 145c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (dest == NULL || src == NULL) 146c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 147c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER); 148c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 149c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 150c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* copy the parameters */ 151c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (src->group) 152c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 153c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org const EC_METHOD *meth = EC_GROUP_method_of(src->group); 154c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* clear the old group */ 155c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (dest->group) 156c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_GROUP_free(dest->group); 157c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org dest->group = EC_GROUP_new(meth); 158c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (dest->group == NULL) 159c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 160c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!EC_GROUP_copy(dest->group, src->group)) 161c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 162c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 163c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* copy the public key */ 164c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (src->pub_key && src->group) 165c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 166c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (dest->pub_key) 167c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_POINT_free(dest->pub_key); 168c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org dest->pub_key = EC_POINT_new(src->group); 169c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (dest->pub_key == NULL) 170c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 171c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!EC_POINT_copy(dest->pub_key, src->pub_key)) 172c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 173c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 174c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* copy the private key */ 175c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (src->priv_key) 176c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 177c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (dest->priv_key == NULL) 178c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 179c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org dest->priv_key = BN_new(); 180c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (dest->priv_key == NULL) 181c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 182c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 183c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_copy(dest->priv_key, src->priv_key)) 184c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 185c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 186c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* copy method/extra data */ 187c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_EX_DATA_free_all_data(&dest->method_data); 188c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 189c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (d = src->method_data; d != NULL; d = d->next) 190c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 191c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org void *t = d->dup_func(d->data); 192c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 193c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (t == NULL) 194c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 195c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func, d->free_func, d->clear_free_func)) 196c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 197c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 198c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 199c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* copy the rest */ 200c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org dest->enc_flag = src->enc_flag; 201c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org dest->conv_form = src->conv_form; 202c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org dest->version = src->version; 2032c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org dest->flags = src->flags; 204c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 205c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return dest; 206c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 207c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 208c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgEC_KEY *EC_KEY_dup(const EC_KEY *ec_key) 209c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 210c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_KEY *ret = EC_KEY_new(); 211c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ret == NULL) 212c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 213c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (EC_KEY_copy(ret, ec_key) == NULL) 214c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 215c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_KEY_free(ret); 216c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return NULL; 217c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 218c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return ret; 219c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 220c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 221c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint EC_KEY_up_ref(EC_KEY *r) 222c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 223c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC); 224c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef REF_PRINT 225c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org REF_PRINT("EC_KEY",r); 226c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 227c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef REF_CHECK 228c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (i < 2) 229c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 230c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org fprintf(stderr, "EC_KEY_up, bad reference count\n"); 231c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org abort(); 232c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 233c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif 234c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return ((i > 1) ? 1 : 0); 235c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 236c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 237c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint EC_KEY_generate_key(EC_KEY *eckey) 238c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 239c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int ok = 0; 240c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BN_CTX *ctx = NULL; 241c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BIGNUM *priv_key = NULL, *order = NULL; 242c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_POINT *pub_key = NULL; 243c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 2442c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef OPENSSL_FIPS 2452c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (FIPS_mode()) 2462c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return FIPS_ec_key_generate_key(eckey); 2472c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 2482c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 249c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!eckey || !eckey->group) 250c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 251c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER); 252c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 253c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 254c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 255c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((order = BN_new()) == NULL) goto err; 256c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((ctx = BN_CTX_new()) == NULL) goto err; 257c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 258c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (eckey->priv_key == NULL) 259c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 260c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org priv_key = BN_new(); 261c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (priv_key == NULL) 262c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 263c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 264c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 265c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org priv_key = eckey->priv_key; 266c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 267c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!EC_GROUP_get_order(eckey->group, order, ctx)) 268c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 269c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 270c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org do 271c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!BN_rand_range(priv_key, order)) 272c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 273c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org while (BN_is_zero(priv_key)); 274c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 275c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (eckey->pub_key == NULL) 276c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 277c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org pub_key = EC_POINT_new(eckey->group); 278c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (pub_key == NULL) 279c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 280c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 281c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else 282c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org pub_key = eckey->pub_key; 283c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 284c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) 285c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 286c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 287c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org eckey->priv_key = priv_key; 288c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org eckey->pub_key = pub_key; 289c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 290c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ok=1; 291c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 292c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgerr: 293c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (order) 294c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BN_free(order); 295c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (pub_key != NULL && eckey->pub_key == NULL) 296c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_POINT_free(pub_key); 297c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (priv_key != NULL && eckey->priv_key == NULL) 298c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BN_free(priv_key); 299c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ctx != NULL) 300c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BN_CTX_free(ctx); 301c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ok); 302c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 303c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 304c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint EC_KEY_check_key(const EC_KEY *eckey) 305c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 306c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int ok = 0; 307c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BN_CTX *ctx = NULL; 308c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org const BIGNUM *order = NULL; 309c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_POINT *point = NULL; 310c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 311c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!eckey || !eckey->group || !eckey->pub_key) 312c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 313c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); 314c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 315c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 316480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 317480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) 318480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 319480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY); 320480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 321480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 322480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 323c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((ctx = BN_CTX_new()) == NULL) 324c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 325c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((point = EC_POINT_new(eckey->group)) == NULL) 326c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 327c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 328c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* testing whether the pub_key is on the elliptic curve */ 329c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx)) 330c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 331c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE); 332c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 333c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 334c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* testing whether pub_key * order is the point at infinity */ 335c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org order = &eckey->group->order; 336c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (BN_is_zero(order)) 337c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 338c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER); 339c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 340c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 341c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) 342c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 343c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); 344c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 345c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 346c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!EC_POINT_is_at_infinity(eckey->group, point)) 347c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 348c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); 349c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 350c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 351c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* in case the priv_key is present : 352c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * check if generator * priv_key == pub_key 353c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 354c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (eckey->priv_key) 355c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 356c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (BN_cmp(eckey->priv_key, order) >= 0) 357c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 358c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); 359c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 360c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 361c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, 362c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org NULL, NULL, ctx)) 363c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 364c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); 365c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 366c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 367c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, 368c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ctx) != 0) 369c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 370c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY); 371c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 372c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 373c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 374c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ok = 1; 375c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgerr: 376c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ctx != NULL) 377c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BN_CTX_free(ctx); 378c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (point != NULL) 379c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_POINT_free(point); 380c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return(ok); 381c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 382c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 3832c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgint EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y) 3842c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 3852c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org BN_CTX *ctx = NULL; 3862c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org BIGNUM *tx, *ty; 3872c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org EC_POINT *point = NULL; 3882c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org int ok = 0, tmp_nid, is_char_two = 0; 3892c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 3902c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!key || !key->group || !x || !y) 3912c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 3922c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, 3932c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ERR_R_PASSED_NULL_PARAMETER); 3942c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return 0; 3952c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 3962c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ctx = BN_CTX_new(); 3972c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!ctx) 3982c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 3992c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 4002c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org point = EC_POINT_new(key->group); 4012c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 4022c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!point) 4032c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 4042c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 4052c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group)); 4062c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 4072c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (tmp_nid == NID_X9_62_characteristic_two_field) 4082c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org is_char_two = 1; 4092c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 4102c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org tx = BN_CTX_get(ctx); 4112c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ty = BN_CTX_get(ctx); 4122c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifndef OPENSSL_NO_EC2M 4132c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (is_char_two) 4142c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 4152c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point, 4162c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org x, y, ctx)) 4172c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 4182c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point, 4192c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org tx, ty, ctx)) 4202c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 4212c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 4222c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org else 4232c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif 4242c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 4252c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!EC_POINT_set_affine_coordinates_GFp(key->group, point, 4262c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org x, y, ctx)) 4272c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 4282c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!EC_POINT_get_affine_coordinates_GFp(key->group, point, 4292c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org tx, ty, ctx)) 4302c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 4312c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 4322c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org /* Check if retrieved coordinates match originals: if not values 4332c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org * are out of range. 4342c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org */ 4352c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (BN_cmp(x, tx) || BN_cmp(y, ty)) 4362c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 4372c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, 4382c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org EC_R_COORDINATES_OUT_OF_RANGE); 4392c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 4402c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 4412c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 4422c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (!EC_KEY_set_public_key(key, point)) 4432c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 4442c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 4452c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (EC_KEY_check_key(key) == 0) 4462c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org goto err; 4472c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 4482c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org ok = 1; 4492c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 4502c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org err: 4512c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (ctx) 4522c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org BN_CTX_free(ctx); 4532c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org if (point) 4542c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org EC_POINT_free(point); 4552c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return ok; 4562c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 4572c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 4582c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 459c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgconst EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) 460c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 461c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return key->group; 462c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 463c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 464c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) 465c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 466c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (key->group != NULL) 467c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_GROUP_free(key->group); 468c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org key->group = EC_GROUP_dup(group); 469c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return (key->group == NULL) ? 0 : 1; 470c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 471c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 472c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgconst BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) 473c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 474c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return key->priv_key; 475c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 476c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 477c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) 478c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 479c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (key->priv_key) 480c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org BN_clear_free(key->priv_key); 481c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org key->priv_key = BN_dup(priv_key); 482c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return (key->priv_key == NULL) ? 0 : 1; 483c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 484c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 485c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgconst EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key) 486c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 487c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return key->pub_key; 488c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 489c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 490c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) 491c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 492c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (key->pub_key != NULL) 493c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_POINT_free(key->pub_key); 494c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org key->pub_key = EC_POINT_dup(pub_key, key->group); 495c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return (key->pub_key == NULL) ? 0 : 1; 496c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 497c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 498c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgunsigned int EC_KEY_get_enc_flags(const EC_KEY *key) 499c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 500c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return key->enc_flag; 501c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 502c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 503c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) 504c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 505c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org key->enc_flag = flags; 506c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 507c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 508c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgpoint_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) 509c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 510c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return key->conv_form; 511c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 512c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 513c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) 514c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 515c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org key->conv_form = cform; 516c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (key->group != NULL) 517c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_GROUP_set_point_conversion_form(key->group, cform); 518c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 519c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 520c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid *EC_KEY_get_key_method_data(EC_KEY *key, 521c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)) 522c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 5237453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org void *ret; 5247453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org 5257453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org CRYPTO_r_lock(CRYPTO_LOCK_EC); 5267453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org ret = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func); 5277453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org CRYPTO_r_unlock(CRYPTO_LOCK_EC); 5287453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org 5297453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org return ret; 530c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 531c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 5327453c6c0666947e06d87565404f4397a4b387f91digit@chromium.orgvoid *EC_KEY_insert_key_method_data(EC_KEY *key, void *data, 533c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)) 534c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 535c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_EXTRA_DATA *ex_data; 5367453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org 537c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org CRYPTO_w_lock(CRYPTO_LOCK_EC); 538c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func); 539c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (ex_data == NULL) 540c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func); 541c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org CRYPTO_w_unlock(CRYPTO_LOCK_EC); 5427453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org 5437453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org return ex_data; 544c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 545c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 546c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid EC_KEY_set_asn1_flag(EC_KEY *key, int flag) 547c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 548c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (key->group != NULL) 549c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org EC_GROUP_set_asn1_flag(key->group, flag); 550c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 551c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 552c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) 553c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 554c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (key->group == NULL) 555c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 556c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return EC_GROUP_precompute_mult(key->group, ctx); 557c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 5582c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 5592c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgint EC_KEY_get_flags(const EC_KEY *key) 5602c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 5612c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org return key->flags; 5622c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 5632c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 5642c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgvoid EC_KEY_set_flags(EC_KEY *key, int flags) 5652c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 5662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org key->flags |= flags; 5672c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 5682c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org 5692c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.orgvoid EC_KEY_clear_flags(EC_KEY *key, int flags) 5702c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org { 5712c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org key->flags &= ~flags; 5722c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org } 573