1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/ec/ec_key.c */ 2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Written by Nils Larsch for the OpenSSL project. 4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ==================================================================== 6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. 7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without 9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions 10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met: 11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright 13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer. 14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer in 17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the documentation and/or other materials provided with the 18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * distribution. 19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this 21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * software must display the following acknowledgment: 22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software developed by the OpenSSL Project 23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * endorse or promote products derived from this software without 27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * prior written permission. For written permission, please contact 28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * openssl-core@openssl.org. 29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL" 31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * nor may "OpenSSL" appear in their names without prior written 32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * permission of the OpenSSL Project. 33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following 35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * acknowledgment: 36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software developed by the OpenSSL Project 37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE. 51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ==================================================================== 52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young 54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com). This product includes software written by Tim 55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com). 56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ==================================================================== 59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Portions originally developed by SUN MICROSYSTEMS, INC., and 61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * contributed to the OpenSSL project. 62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <string.h> 65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "ec_lcl.h" 66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/err.h> 67392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS 68392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/fips.h> 69392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectEC_KEY *EC_KEY_new(void) 72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_KEY *ret; 74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret=(EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY)); 76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret == NULL) 77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE); 79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(NULL); 80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->version = 1; 83392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ret->flags = 0; 84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->group = NULL; 85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->pub_key = NULL; 86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->priv_key= NULL; 87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->enc_flag= 0; 88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; 89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->references= 1; 90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->method_data = NULL; 91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(ret); 92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectEC_KEY *EC_KEY_new_by_curve_name(int nid) 95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_KEY *ret = EC_KEY_new(); 97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret == NULL) 98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret->group = EC_GROUP_new_by_curve_name(nid); 100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret->group == NULL) 101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_KEY_free(ret); 103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid EC_KEY_free(EC_KEY *r) 109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (r == NULL) return; 113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_EC); 115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef REF_PRINT 116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project REF_PRINT("EC_KEY",r); 117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (i > 0) return; 119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef REF_CHECK 120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (i < 0) 121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project fprintf(stderr,"EC_KEY_free, bad reference count\n"); 123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project abort(); 124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (r->group != NULL) 128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_GROUP_free(r->group); 129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (r->pub_key != NULL) 130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_POINT_free(r->pub_key); 131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (r->priv_key != NULL) 132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(r->priv_key); 133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_EX_DATA_free_all_data(&r->method_data); 135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_cleanse((void *)r, sizeof(EC_KEY)); 137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_free(r); 139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectEC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) 142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_EXTRA_DATA *d; 144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (dest == NULL || src == NULL) 146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER); 148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* copy the parameters */ 151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (src->group) 152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const EC_METHOD *meth = EC_GROUP_method_of(src->group); 154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* clear the old group */ 155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (dest->group) 156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_GROUP_free(dest->group); 157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project dest->group = EC_GROUP_new(meth); 158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (dest->group == NULL) 159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_GROUP_copy(dest->group, src->group)) 161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* copy the public key */ 164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (src->pub_key && src->group) 165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (dest->pub_key) 167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_POINT_free(dest->pub_key); 168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project dest->pub_key = EC_POINT_new(src->group); 169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (dest->pub_key == NULL) 170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_copy(dest->pub_key, src->pub_key)) 172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* copy the private key */ 175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (src->priv_key) 176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (dest->priv_key == NULL) 178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project dest->priv_key = BN_new(); 180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (dest->priv_key == NULL) 181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(dest->priv_key, src->priv_key)) 184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* copy method/extra data */ 187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_EX_DATA_free_all_data(&dest->method_data); 188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (d = src->method_data; d != NULL; d = d->next) 190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project void *t = d->dup_func(d->data); 192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (t == NULL) 194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func, d->free_func, d->clear_free_func)) 196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* copy the rest */ 200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project dest->enc_flag = src->enc_flag; 201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project dest->conv_form = src->conv_form; 202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project dest->version = src->version; 203392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom dest->flags = src->flags; 204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return dest; 206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectEC_KEY *EC_KEY_dup(const EC_KEY *ec_key) 209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_KEY *ret = EC_KEY_new(); 211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ret == NULL) 212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (EC_KEY_copy(ret, ec_key) == NULL) 214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_KEY_free(ret); 216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return NULL; 217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint EC_KEY_up_ref(EC_KEY *r) 222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC); 224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef REF_PRINT 225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project REF_PRINT("EC_KEY",r); 226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef REF_CHECK 228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (i < 2) 229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project fprintf(stderr, "EC_KEY_up, bad reference count\n"); 231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project abort(); 232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif 234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ((i > 1) ? 1 : 0); 235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint EC_KEY_generate_key(EC_KEY *eckey) 238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ok = 0; 240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX *ctx = NULL; 241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *priv_key = NULL, *order = NULL; 242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_POINT *pub_key = NULL; 243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 244392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS 245392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (FIPS_mode()) 246392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return FIPS_ec_key_generate_key(eckey); 247392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 248392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!eckey || !eckey->group) 250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER); 252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((order = BN_new()) == NULL) goto err; 256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((ctx = BN_CTX_new()) == NULL) goto err; 257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (eckey->priv_key == NULL) 259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project priv_key = BN_new(); 261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (priv_key == NULL) 262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project priv_key = eckey->priv_key; 266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_GROUP_get_order(eckey->group, order, ctx)) 268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project do 271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_rand_range(priv_key, order)) 272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project while (BN_is_zero(priv_key)); 274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (eckey->pub_key == NULL) 276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project pub_key = EC_POINT_new(eckey->group); 278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (pub_key == NULL) 279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project pub_key = eckey->pub_key; 283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) 285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project eckey->priv_key = priv_key; 288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project eckey->pub_key = pub_key; 289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ok=1; 291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr: 293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (order) 294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_free(order); 295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (pub_key != NULL && eckey->pub_key == NULL) 296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_POINT_free(pub_key); 297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (priv_key != NULL && eckey->priv_key == NULL) 298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_free(priv_key); 299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx != NULL) 300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_free(ctx); 301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(ok); 302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint EC_KEY_check_key(const EC_KEY *eckey) 305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ok = 0; 307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX *ctx = NULL; 308e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu const BIGNUM *order = NULL; 309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_POINT *point = NULL; 310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!eckey || !eckey->group || !eckey->pub_key) 312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); 314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 31681c4de7869b646592127e952cda763abf8305069Brian Carlstrom 31781c4de7869b646592127e952cda763abf8305069Brian Carlstrom if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) 31881c4de7869b646592127e952cda763abf8305069Brian Carlstrom { 31981c4de7869b646592127e952cda763abf8305069Brian Carlstrom ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY); 32081c4de7869b646592127e952cda763abf8305069Brian Carlstrom goto err; 32181c4de7869b646592127e952cda763abf8305069Brian Carlstrom } 32281c4de7869b646592127e952cda763abf8305069Brian Carlstrom 323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((ctx = BN_CTX_new()) == NULL) 324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((point = EC_POINT_new(eckey->group)) == NULL) 326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* testing whether the pub_key is on the elliptic curve */ 329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx)) 330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE); 332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* testing whether pub_key * order is the point at infinity */ 335e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu order = &eckey->group->order; 336e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu if (BN_is_zero(order)) 337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER); 339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 341e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) 342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); 344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_is_at_infinity(eckey->group, point)) 347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); 349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* in case the priv_key is present : 352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * check if generator * priv_key == pub_key 353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (eckey->priv_key) 355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (BN_cmp(eckey->priv_key, order) >= 0) 357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); 359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, 362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project NULL, NULL, ctx)) 363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); 365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, 368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ctx) != 0) 369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY); 371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ok = 1; 375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr: 376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx != NULL) 377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_free(ctx); 378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (point != NULL) 379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_POINT_free(point); 380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return(ok); 381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 383392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y) 384392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 385392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom BN_CTX *ctx = NULL; 386392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom BIGNUM *tx, *ty; 387392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom EC_POINT *point = NULL; 388392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom int ok = 0, tmp_nid, is_char_two = 0; 389392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 390392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!key || !key->group || !x || !y) 391392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 392392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, 393392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ERR_R_PASSED_NULL_PARAMETER); 394392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 395392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 396392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx = BN_CTX_new(); 397392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!ctx) 398392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom goto err; 399392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 400392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom point = EC_POINT_new(key->group); 401392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 402392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!point) 403392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom goto err; 404392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 405392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group)); 406392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 407392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (tmp_nid == NID_X9_62_characteristic_two_field) 408392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom is_char_two = 1; 409392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 410392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom tx = BN_CTX_get(ctx); 411392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ty = BN_CTX_get(ctx); 412392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_EC2M 413392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (is_char_two) 414392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 415392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point, 416392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom x, y, ctx)) 417392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom goto err; 418392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point, 419392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom tx, ty, ctx)) 420392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom goto err; 421392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 422392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom else 423392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 424392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 425392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!EC_POINT_set_affine_coordinates_GFp(key->group, point, 426392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom x, y, ctx)) 427392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom goto err; 428392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!EC_POINT_get_affine_coordinates_GFp(key->group, point, 429392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom tx, ty, ctx)) 430392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom goto err; 431392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 432392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Check if retrieved coordinates match originals: if not values 433392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * are out of range. 434392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */ 435392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (BN_cmp(x, tx) || BN_cmp(y, ty)) 436392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 437392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, 438392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom EC_R_COORDINATES_OUT_OF_RANGE); 439392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom goto err; 440392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 441392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 442392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!EC_KEY_set_public_key(key, point)) 443392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom goto err; 444392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 445392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (EC_KEY_check_key(key) == 0) 446392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom goto err; 447392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 448392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ok = 1; 449392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 450392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom err: 451392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (ctx) 452392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom BN_CTX_free(ctx); 453392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (point) 454392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom EC_POINT_free(point); 455392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return ok; 456392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 457392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 458392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) 460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return key->group; 462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) 465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (key->group != NULL) 467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_GROUP_free(key->group); 468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project key->group = EC_GROUP_dup(group); 469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return (key->group == NULL) ? 0 : 1; 470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) 473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return key->priv_key; 475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) 478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (key->priv_key) 480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(key->priv_key); 481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project key->priv_key = BN_dup(priv_key); 482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return (key->priv_key == NULL) ? 0 : 1; 483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key) 486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return key->pub_key; 488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) 491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (key->pub_key != NULL) 493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_POINT_free(key->pub_key); 494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project key->pub_key = EC_POINT_dup(pub_key, key->group); 495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return (key->pub_key == NULL) ? 0 : 1; 496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectunsigned int EC_KEY_get_enc_flags(const EC_KEY *key) 499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return key->enc_flag; 501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) 504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project key->enc_flag = flags; 506656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectpoint_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) 509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return key->conv_form; 511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) 514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project key->conv_form = cform; 516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (key->group != NULL) 517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_GROUP_set_point_conversion_form(key->group, cform); 518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 520656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid *EC_KEY_get_key_method_data(EC_KEY *key, 521656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)) 522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 523656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func); 524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid EC_KEY_insert_key_method_data(EC_KEY *key, void *data, 527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)) 528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_EXTRA_DATA *ex_data; 530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project CRYPTO_w_lock(CRYPTO_LOCK_EC); 531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func); 532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ex_data == NULL) 533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func); 534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project CRYPTO_w_unlock(CRYPTO_LOCK_EC); 535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid EC_KEY_set_asn1_flag(EC_KEY *key, int flag) 538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (key->group != NULL) 540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project EC_GROUP_set_asn1_flag(key->group, flag); 541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) 544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (key->group == NULL) 546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return EC_GROUP_precompute_mult(key->group, ctx); 548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 549392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 550392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint EC_KEY_get_flags(const EC_KEY *key) 551392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 552392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return key->flags; 553392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 554392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 555392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid EC_KEY_set_flags(EC_KEY *key, int flags) 556392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 557392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom key->flags |= flags; 558392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 559392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 560392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid EC_KEY_clear_flags(EC_KEY *key, int flags) 561392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom { 562392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom key->flags &= ~flags; 563392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 564