Blame SOURCES/ec_curve.c

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