1109998Smarkm/* crypto/ec/ec_cvt.c */ 2160814Ssimon/* 3160814Ssimon * Originally written by Bodo Moeller for the OpenSSL project. 4160814Ssimon */ 5109998Smarkm/* ==================================================================== 6160814Ssimon * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. 7109998Smarkm * 8109998Smarkm * Redistribution and use in source and binary forms, with or without 9109998Smarkm * modification, are permitted provided that the following conditions 10109998Smarkm * are met: 11109998Smarkm * 12109998Smarkm * 1. Redistributions of source code must retain the above copyright 13280297Sjkim * notice, this list of conditions and the following disclaimer. 14109998Smarkm * 15109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 16109998Smarkm * notice, this list of conditions and the following disclaimer in 17109998Smarkm * the documentation and/or other materials provided with the 18109998Smarkm * distribution. 19109998Smarkm * 20109998Smarkm * 3. All advertising materials mentioning features or use of this 21109998Smarkm * software must display the following acknowledgment: 22109998Smarkm * "This product includes software developed by the OpenSSL Project 23109998Smarkm * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 24109998Smarkm * 25109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26109998Smarkm * endorse or promote products derived from this software without 27109998Smarkm * prior written permission. For written permission, please contact 28109998Smarkm * openssl-core@openssl.org. 29109998Smarkm * 30109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 31109998Smarkm * nor may "OpenSSL" appear in their names without prior written 32109998Smarkm * permission of the OpenSSL Project. 33109998Smarkm * 34109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 35109998Smarkm * acknowledgment: 36109998Smarkm * "This product includes software developed by the OpenSSL Project 37109998Smarkm * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 38109998Smarkm * 39109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 51109998Smarkm * ==================================================================== 52109998Smarkm * 53109998Smarkm * This product includes cryptographic software written by Eric Young 54109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 55109998Smarkm * Hudson (tjh@cryptsoft.com). 56109998Smarkm * 57109998Smarkm */ 58160814Ssimon/* ==================================================================== 59160814Ssimon * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 60160814Ssimon * 61280297Sjkim * Portions of the attached software ("Contribution") are developed by 62160814Ssimon * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. 63160814Ssimon * 64160814Ssimon * The Contribution is licensed pursuant to the OpenSSL open source 65160814Ssimon * license provided above. 66160814Ssimon * 67160814Ssimon * The elliptic curve binary polynomial software is originally written by 68160814Ssimon * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. 69160814Ssimon * 70160814Ssimon */ 71109998Smarkm 72160814Ssimon#include <openssl/err.h> 73109998Smarkm#include "ec_lcl.h" 74109998Smarkm 75290207Sjkim#ifdef OPENSSL_FIPS 76290207Sjkim# include <openssl/fips.h> 77290207Sjkim#endif 78290207Sjkim 79280297SjkimEC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, 80280297Sjkim const BIGNUM *b, BN_CTX *ctx) 81280297Sjkim{ 82280297Sjkim const EC_METHOD *meth; 83280297Sjkim EC_GROUP *ret; 84109998Smarkm 85290207Sjkim#ifdef OPENSSL_FIPS 86290207Sjkim if (FIPS_mode()) 87290207Sjkim return FIPS_ec_group_new_curve_gfp(p, a, b, ctx); 88290207Sjkim#endif 89238405Sjkim#if defined(OPENSSL_BN_ASM_MONT) 90280297Sjkim /* 91280297Sjkim * This might appear controversial, but the fact is that generic 92280297Sjkim * prime method was observed to deliver better performance even 93280297Sjkim * for NIST primes on a range of platforms, e.g.: 60%-15% 94280297Sjkim * improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25% 95280297Sjkim * in 32-bit build and 35%--12% in 64-bit build on Core2... 96280297Sjkim * Coefficients are relative to optimized bn_nist.c for most 97280297Sjkim * intensive ECDSA verify and ECDH operations for 192- and 521- 98280297Sjkim * bit keys respectively. Choice of these boundary values is 99280297Sjkim * arguable, because the dependency of improvement coefficient 100280297Sjkim * from key length is not a "monotone" curve. For example while 101280297Sjkim * 571-bit result is 23% on ARM, 384-bit one is -1%. But it's 102280297Sjkim * generally faster, sometimes "respectfully" faster, sometimes 103280297Sjkim * "tolerably" slower... What effectively happens is that loop 104280297Sjkim * with bn_mul_add_words is put against bn_mul_mont, and the 105280297Sjkim * latter "wins" on short vectors. Correct solution should be 106280297Sjkim * implementing dedicated NxN multiplication subroutines for 107280297Sjkim * small N. But till it materializes, let's stick to generic 108280297Sjkim * prime method... 109280297Sjkim * <appro> 110280297Sjkim */ 111280297Sjkim meth = EC_GFp_mont_method(); 112238405Sjkim#else 113280297Sjkim meth = EC_GFp_nist_method(); 114238405Sjkim#endif 115109998Smarkm 116280297Sjkim ret = EC_GROUP_new(meth); 117280297Sjkim if (ret == NULL) 118280297Sjkim return NULL; 119160814Ssimon 120280297Sjkim if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) { 121280297Sjkim unsigned long err; 122160814Ssimon 123280297Sjkim err = ERR_peek_last_error(); 124160814Ssimon 125280297Sjkim if (!(ERR_GET_LIB(err) == ERR_LIB_EC && 126280297Sjkim ((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) || 127280297Sjkim (ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME)))) { 128280297Sjkim /* real error */ 129160814Ssimon 130280297Sjkim EC_GROUP_clear_free(ret); 131280297Sjkim return NULL; 132280297Sjkim } 133160814Ssimon 134280297Sjkim /* 135280297Sjkim * not an actual error, we just cannot use EC_GFp_nist_method 136280297Sjkim */ 137160814Ssimon 138280297Sjkim ERR_clear_error(); 139160814Ssimon 140280297Sjkim EC_GROUP_clear_free(ret); 141280297Sjkim meth = EC_GFp_mont_method(); 142280297Sjkim 143280297Sjkim ret = EC_GROUP_new(meth); 144280297Sjkim if (ret == NULL) 145280297Sjkim return NULL; 146280297Sjkim 147280297Sjkim if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) { 148280297Sjkim EC_GROUP_clear_free(ret); 149280297Sjkim return NULL; 150280297Sjkim } 151280297Sjkim } 152280297Sjkim 153280297Sjkim return ret; 154280297Sjkim} 155280297Sjkim 156238405Sjkim#ifndef OPENSSL_NO_EC2M 157280297SjkimEC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, 158280297Sjkim const BIGNUM *b, BN_CTX *ctx) 159280297Sjkim{ 160280297Sjkim const EC_METHOD *meth; 161280297Sjkim EC_GROUP *ret; 162160814Ssimon 163290207Sjkim# ifdef OPENSSL_FIPS 164290207Sjkim if (FIPS_mode()) 165290207Sjkim return FIPS_ec_group_new_curve_gf2m(p, a, b, ctx); 166290207Sjkim# endif 167280297Sjkim meth = EC_GF2m_simple_method(); 168109998Smarkm 169280297Sjkim ret = EC_GROUP_new(meth); 170280297Sjkim if (ret == NULL) 171280297Sjkim return NULL; 172280297Sjkim 173280297Sjkim if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx)) { 174280297Sjkim EC_GROUP_clear_free(ret); 175280297Sjkim return NULL; 176280297Sjkim } 177280297Sjkim 178280297Sjkim return ret; 179280297Sjkim} 180238405Sjkim#endif 181