Blame SOURCES/ec_curve.c

450916
/* crypto/ec/ec_curve.c */
450916
/*
450916
 * Written by Nils Larsch for the OpenSSL project.
450916
 */
450916
/* ====================================================================
450916
 * Copyright (c) 1998-2010 The OpenSSL Project.  All rights reserved.
450916
 *
450916
 * Redistribution and use in source and binary forms, with or without
450916
 * modification, are permitted provided that the following conditions
450916
 * are met:
450916
 *
450916
 * 1. Redistributions of source code must retain the above copyright
450916
 *    notice, this list of conditions and the following disclaimer.
450916
 *
450916
 * 2. Redistributions in binary form must reproduce the above copyright
450916
 *    notice, this list of conditions and the following disclaimer in
450916
 *    the documentation and/or other materials provided with the
450916
 *    distribution.
450916
 *
450916
 * 3. All advertising materials mentioning features or use of this
450916
 *    software must display the following acknowledgment:
450916
 *    "This product includes software developed by the OpenSSL Project
450916
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
450916
 *
450916
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
450916
 *    endorse or promote products derived from this software without
450916
 *    prior written permission. For written permission, please contact
450916
 *    openssl-core@openssl.org.
450916
 *
450916
 * 5. Products derived from this software may not be called "OpenSSL"
450916
 *    nor may "OpenSSL" appear in their names without prior written
450916
 *    permission of the OpenSSL Project.
450916
 *
450916
 * 6. Redistributions of any form whatsoever must retain the following
450916
 *    acknowledgment:
450916
 *    "This product includes software developed by the OpenSSL Project
450916
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
450916
 *
450916
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
450916
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
450916
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
450916
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
450916
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
450916
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
450916
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
450916
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
450916
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
450916
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
450916
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
450916
 * OF THE POSSIBILITY OF SUCH DAMAGE.
450916
 * ====================================================================
450916
 *
450916
 * This product includes cryptographic software written by Eric Young
450916
 * (eay@cryptsoft.com).  This product includes software written by Tim
450916
 * Hudson (tjh@cryptsoft.com).
450916
 *
450916
 */
450916
/* ====================================================================
450916
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
450916
 *
450916
 * Portions of the attached software ("Contribution") are developed by
450916
 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
450916
 *
450916
 * The Contribution is licensed pursuant to the OpenSSL open source
450916
 * license provided above.
450916
 *
450916
 * The elliptic curve binary polynomial software is originally written by
450916
 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
450916
 *
450916
 */
450916
450916
#include <string.h>
450916
#include "ec_lcl.h"
450916
#include <openssl/err.h>
450916
#include <openssl/obj_mac.h>
450916
#include <openssl/opensslconf.h>
450916
450916
#ifdef OPENSSL_FIPS
450916
# include <openssl/fips.h>
450916
#endif
450916
450916
typedef struct {
450916
    int field_type,             /* either NID_X9_62_prime_field or
450916
                                 * NID_X9_62_characteristic_two_field */
450916
     seed_len, param_len;
450916
    unsigned int cofactor;      /* promoted to BN_ULONG */
450916
} EC_CURVE_DATA;
450916
450916
/* the nist prime curves */
450916
static const struct {
450916
    EC_CURVE_DATA h;
450916
    unsigned char data[20 + 48 * 6];
450916
} _EC_NIST_PRIME_384 = {
450916
    {
450916
        NID_X9_62_prime_field, 20, 48, 1
450916
    },
450916
    {
450916
        /* seed */
450916
        0xA3, 0x35, 0x92, 0x6A, 0xA3, 0x19, 0xA2, 0x7A, 0x1D, 0x00, 0x89, 0x6A,
450916
        0x67, 0x73, 0xA4, 0x82, 0x7A, 0xCD, 0xAC, 0x73,
450916
        /* p */
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        /* a */
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
450916
        /* b */
450916
        0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
450916
        0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
450916
        0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
450916
        0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
450916
        /* x */
450916
        0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
450916
        0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
450916
        0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
450916
        0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
450916
        /* y */
450916
        0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf,
450916
        0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
450916
        0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce,
450916
        0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
450916
        /* order */
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
450916
        0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73
450916
    }
450916
};
450916
450916
static const struct {
450916
    EC_CURVE_DATA h;
450916
    unsigned char data[20 + 66 * 6];
450916
} _EC_NIST_PRIME_521 = {
450916
    {
450916
        NID_X9_62_prime_field, 20, 66, 1
450916
    },
450916
    {
450916
        /* seed */
450916
        0xD0, 0x9E, 0x88, 0x00, 0x29, 0x1C, 0xB8, 0x53, 0x96, 0xCC, 0x67, 0x17,
450916
        0x39, 0x32, 0x84, 0xAA, 0xA0, 0xDA, 0x64, 0xBA,
450916
        /* p */
450916
        0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        /* a */
450916
        0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
450916
        /* b */
450916
        0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
450916
        0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
450916
        0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
450916
        0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
450916
        0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
450916
        0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
450916
        /* x */
450916
        0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
450916
        0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
450916
        0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
450916
        0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
450916
        0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
450916
        0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
450916
        /* y */
450916
        0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
450916
        0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
450916
        0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
450916
        0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
450916
        0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
450916
        0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
450916
        /* order */
450916
        0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
450916
        0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
450916
        0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
450916
        0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09
450916
    }
450916
};
450916
450916
static const struct {
450916
    EC_CURVE_DATA h;
450916
    unsigned char data[20 + 32 * 6];
450916
} _EC_X9_62_PRIME_256V1 = {
450916
    {
450916
        NID_X9_62_prime_field, 20, 32, 1
450916
    },
450916
    {
450916
        /* seed */
450916
        0xC4, 0x9D, 0x36, 0x08, 0x86, 0xE7, 0x04, 0x93, 0x6A, 0x66, 0x78, 0xE1,
450916
        0x13, 0x9D, 0x26, 0xB7, 0x81, 0x9F, 0x7E, 0x90,
450916
        /* p */
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
450916
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        /* a */
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
450916
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
450916
        /* b */
450916
        0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
450916
        0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
450916
        0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B,
450916
        /* x */
450916
        0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
450916
        0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
450916
        0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
450916
        /* y */
450916
        0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
450916
        0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
450916
        0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
450916
        /* order */
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
450916
        0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
450916
        0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
450916
    }
450916
};
450916
450916
typedef struct _ec_list_element_st {
450916
    int nid;
450916
    const EC_CURVE_DATA *data;
450916
    const EC_METHOD *(*meth) (void);
450916
    const char *comment;
450916
} ec_list_element;
450916
450916
static const ec_list_element curve_list[] = {
450916
    /* prime field curves */
450916
    /* secg curves */
450916
    /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
450916
    {NID_secp384r1, &_EC_NIST_PRIME_384.h, 0,
450916
     "NIST/SECG curve over a 384 bit prime field"},
450916
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
450916
    {NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method,
450916
     "NIST/SECG curve over a 521 bit prime field"},
450916
#else
450916
    {NID_secp521r1, &_EC_NIST_PRIME_521.h, 0,
450916
     "NIST/SECG curve over a 521 bit prime field"},
450916
#endif
450916
    /* X9.62 curves */
450916
    {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h,
450916
#if defined(ECP_NISTZ256_ASM)
450916
     EC_GFp_nistz256_method,
450916
#elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
450916
     EC_GFp_nistp256_method,
450916
#else
450916
     0,
450916
#endif
450916
     "X9.62/SECG curve over a 256 bit prime field"},
450916
};
450916
450916
#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element))
450916
450916
static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
450916
{
450916
    EC_GROUP *group = NULL;
450916
    EC_POINT *P = NULL;
450916
    BN_CTX *ctx = NULL;
450916
    BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order =
450916
        NULL;
450916
    int ok = 0;
450916
    int seed_len, param_len;
450916
    const EC_METHOD *meth;
450916
    const EC_CURVE_DATA *data;
450916
    const unsigned char *params;
450916
450916
    if ((ctx = BN_CTX_new()) == NULL) {
450916
        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
450916
        goto err;
450916
    }
450916
450916
    data = curve.data;
450916
    seed_len = data->seed_len;
450916
    param_len = data->param_len;
450916
    params = (const unsigned char *)(data + 1); /* skip header */
450916
    params += seed_len;         /* skip seed */
450916
450916
    if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL))
450916
        || !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL))
450916
        || !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
450916
        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
450916
        goto err;
450916
    }
450916
450916
    if (curve.meth != 0) {
450916
        meth = curve.meth();
450916
        if (((group = EC_GROUP_new(meth)) == NULL) ||
450916
            (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
450916
            ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
450916
            goto err;
450916
        }
450916
    } else if (data->field_type == NID_X9_62_prime_field) {
450916
        if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
450916
            ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
450916
            goto err;
450916
        }
450916
    }
450916
#ifndef OPENSSL_NO_EC2M
450916
    else {                      /* field_type ==
450916
                                 * NID_X9_62_characteristic_two_field */
450916
450916
        if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) {
450916
            ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
450916
            goto err;
450916
        }
450916
    }
450916
#endif
450916
450916
    if ((P = EC_POINT_new(group)) == NULL) {
450916
        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
450916
        goto err;
450916
    }
450916
450916
    if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL))
450916
        || !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
450916
        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
450916
        goto err;
450916
    }
450916
    if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
450916
        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
450916
        goto err;
450916
    }
450916
    if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL))
450916
        || !BN_set_word(x, (BN_ULONG)data->cofactor)) {
450916
        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
450916
        goto err;
450916
    }
450916
    if (!EC_GROUP_set_generator(group, P, order, x)) {
450916
        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
450916
        goto err;
450916
    }
450916
    if (seed_len) {
450916
        if (!EC_GROUP_set_seed(group, params - seed_len, seed_len)) {
450916
            ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
450916
            goto err;
450916
        }
450916
    }
450916
    ok = 1;
450916
 err:
450916
    if (!ok) {
450916
        EC_GROUP_free(group);
450916
        group = NULL;
450916
    }
450916
    if (P)
450916
        EC_POINT_free(P);
450916
    if (ctx)
450916
        BN_CTX_free(ctx);
450916
    if (p)
450916
        BN_free(p);
450916
    if (a)
450916
        BN_free(a);
450916
    if (b)
450916
        BN_free(b);
450916
    if (order)
450916
        BN_free(order);
450916
    if (x)
450916
        BN_free(x);
450916
    if (y)
450916
        BN_free(y);
450916
    return group;
450916
}
450916
450916
EC_GROUP *EC_GROUP_new_by_curve_name(int nid)
450916
{
450916
    size_t i;
450916
    EC_GROUP *ret = NULL;
450916
450916
    if (nid <= 0)
450916
        return NULL;
450916
450916
    for (i = 0; i < curve_list_length; i++)
450916
        if (curve_list[i].nid == nid) {
450916
            ret = ec_group_new_from_data(curve_list[i]);
450916
            break;
450916
        }
450916
450916
    if (ret == NULL) {
450916
        ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP);
450916
        return NULL;
450916
    }
450916
450916
    EC_GROUP_set_curve_name(ret, nid);
450916
450916
    return ret;
450916
}
450916
450916
size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems)
450916
{
450916
    size_t i, min;
450916
450916
    if (r == NULL || nitems == 0)
450916
        return curve_list_length;
450916
450916
    min = nitems < curve_list_length ? nitems : curve_list_length;
450916
450916
    for (i = 0; i < min; i++) {
450916
        r[i].nid = curve_list[i].nid;
450916
        r[i].comment = curve_list[i].comment;
450916
    }
450916
450916
    return curve_list_length;
450916
}
450916
450916
/* Functions to translate between common NIST curve names and NIDs */
450916
450916
typedef struct {
450916
    const char *name;           /* NIST Name of curve */
450916
    int nid;                    /* Curve NID */
450916
} EC_NIST_NAME;
450916
450916
static EC_NIST_NAME nist_curves[] = {
450916
    {"B-163", NID_sect163r2},
450916
    {"B-233", NID_sect233r1},
450916
    {"B-283", NID_sect283r1},
450916
    {"B-409", NID_sect409r1},
450916
    {"B-571", NID_sect571r1},
450916
    {"K-163", NID_sect163k1},
450916
    {"K-233", NID_sect233k1},
450916
    {"K-283", NID_sect283k1},
450916
    {"K-409", NID_sect409k1},
450916
    {"K-571", NID_sect571k1},
450916
    {"P-192", NID_X9_62_prime192v1},
450916
    {"P-224", NID_secp224r1},
450916
    {"P-256", NID_X9_62_prime256v1},
450916
    {"P-384", NID_secp384r1},
450916
    {"P-521", NID_secp521r1}
450916
};
450916
450916
const char *EC_curve_nid2nist(int nid)
450916
{
450916
    size_t i;
450916
    for (i = 0; i < sizeof(nist_curves) / sizeof(EC_NIST_NAME); i++) {
450916
        if (nist_curves[i].nid == nid)
450916
            return nist_curves[i].name;
450916
    }
450916
    return NULL;
450916
}
450916
450916
int EC_curve_nist2nid(const char *name)
450916
{
450916
    size_t i;
450916
    for (i = 0; i < sizeof(nist_curves) / sizeof(EC_NIST_NAME); i++) {
450916
        if (!strcmp(nist_curves[i].name, name))
450916
            return nist_curves[i].nid;
450916
    }
450916
    return NID_undef;
450916
}