Blame SOURCES/ec_curve.c

acdedc
/*
acdedc
 * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
acdedc
 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
acdedc
 *
acdedc
 * Licensed under the OpenSSL license (the "License").  You may not use
acdedc
 * this file except in compliance with the License.  You can obtain a copy
acdedc
 * in the file LICENSE in the source distribution or at
acdedc
 * https://www.openssl.org/source/license.html
acdedc
 */
acdedc
acdedc
#include <string.h>
acdedc
#include "ec_lcl.h"
acdedc
#include <openssl/err.h>
acdedc
#include <openssl/obj_mac.h>
acdedc
#include <openssl/opensslconf.h>
acdedc
#include "internal/nelem.h"
acdedc
acdedc
typedef struct {
acdedc
    int field_type,             /* either NID_X9_62_prime_field or
acdedc
                                 * NID_X9_62_characteristic_two_field */
acdedc
     seed_len, param_len;
acdedc
    unsigned int cofactor;      /* promoted to BN_ULONG */
acdedc
} EC_CURVE_DATA;
acdedc
acdedc
/* the nist prime curves */
acdedc
static const struct {
acdedc
    EC_CURVE_DATA h;
acdedc
    unsigned char data[20 + 28 * 6];
acdedc
} _EC_NIST_PRIME_224 = {
acdedc
    {
acdedc
        NID_X9_62_prime_field, 20, 28, 1
acdedc
    },
acdedc
    {
acdedc
        /* seed */
acdedc
        0xBD, 0x71, 0x34, 0x47, 0x99, 0xD5, 0xC7, 0xFC, 0xDC, 0x45, 0xB5, 0x9F,
acdedc
        0xA3, 0xB9, 0xAB, 0x8F, 0x6A, 0x94, 0x8B, 0xC5,
acdedc
        /* p */
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
acdedc
        0x00, 0x00, 0x00, 0x01,
acdedc
        /* a */
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFE,
acdedc
        /* b */
acdedc
        0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
acdedc
        0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
acdedc
        0x23, 0x55, 0xFF, 0xB4,
acdedc
        /* x */
acdedc
        0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
acdedc
        0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
acdedc
        0x11, 0x5C, 0x1D, 0x21,
acdedc
        /* y */
acdedc
        0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
acdedc
        0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
acdedc
        0x85, 0x00, 0x7e, 0x34,
acdedc
        /* order */
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
acdedc
        0x5C, 0x5C, 0x2A, 0x3D
acdedc
    }
acdedc
};
acdedc
acdedc
static const struct {
acdedc
    EC_CURVE_DATA h;
acdedc
    unsigned char data[20 + 48 * 6];
acdedc
} _EC_NIST_PRIME_384 = {
acdedc
    {
acdedc
        NID_X9_62_prime_field, 20, 48, 1
acdedc
    },
acdedc
    {
acdedc
        /* seed */
acdedc
        0xA3, 0x35, 0x92, 0x6A, 0xA3, 0x19, 0xA2, 0x7A, 0x1D, 0x00, 0x89, 0x6A,
acdedc
        0x67, 0x73, 0xA4, 0x82, 0x7A, 0xCD, 0xAC, 0x73,
acdedc
        /* p */
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        /* a */
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
acdedc
        /* b */
acdedc
        0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
acdedc
        0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
acdedc
        0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
acdedc
        0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
acdedc
        /* x */
acdedc
        0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
acdedc
        0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
acdedc
        0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
acdedc
        0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
acdedc
        /* y */
acdedc
        0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf,
acdedc
        0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
acdedc
        0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce,
acdedc
        0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
acdedc
        /* order */
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
acdedc
        0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73
acdedc
    }
acdedc
};
acdedc
acdedc
static const struct {
acdedc
    EC_CURVE_DATA h;
acdedc
    unsigned char data[20 + 66 * 6];
acdedc
} _EC_NIST_PRIME_521 = {
acdedc
    {
acdedc
        NID_X9_62_prime_field, 20, 66, 1
acdedc
    },
acdedc
    {
acdedc
        /* seed */
acdedc
        0xD0, 0x9E, 0x88, 0x00, 0x29, 0x1C, 0xB8, 0x53, 0x96, 0xCC, 0x67, 0x17,
acdedc
        0x39, 0x32, 0x84, 0xAA, 0xA0, 0xDA, 0x64, 0xBA,
acdedc
        /* p */
acdedc
        0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        /* a */
acdedc
        0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
acdedc
        /* b */
acdedc
        0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
acdedc
        0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
acdedc
        0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
acdedc
        0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
acdedc
        0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
acdedc
        0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
acdedc
        /* x */
acdedc
        0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
acdedc
        0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
acdedc
        0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
acdedc
        0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
acdedc
        0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
acdedc
        0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
acdedc
        /* y */
acdedc
        0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
acdedc
        0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
acdedc
        0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
acdedc
        0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
acdedc
        0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
acdedc
        0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
acdedc
        /* order */
acdedc
        0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
acdedc
        0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
acdedc
        0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
acdedc
        0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09
acdedc
    }
acdedc
};
acdedc
acdedc
static const struct {
acdedc
    EC_CURVE_DATA h;
acdedc
    unsigned char data[20 + 32 * 6];
acdedc
} _EC_X9_62_PRIME_256V1 = {
acdedc
    {
acdedc
        NID_X9_62_prime_field, 20, 32, 1
acdedc
    },
acdedc
    {
acdedc
        /* seed */
acdedc
        0xC4, 0x9D, 0x36, 0x08, 0x86, 0xE7, 0x04, 0x93, 0x6A, 0x66, 0x78, 0xE1,
acdedc
        0x13, 0x9D, 0x26, 0xB7, 0x81, 0x9F, 0x7E, 0x90,
acdedc
        /* p */
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
acdedc
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        /* a */
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
acdedc
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
acdedc
        /* b */
acdedc
        0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
acdedc
        0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
acdedc
        0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B,
acdedc
        /* x */
acdedc
        0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
acdedc
        0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
acdedc
        0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
acdedc
        /* y */
acdedc
        0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
acdedc
        0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
acdedc
        0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
acdedc
        /* order */
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
acdedc
        0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
acdedc
    }
acdedc
};
acdedc
acdedc
static const struct {
acdedc
    EC_CURVE_DATA h;
acdedc
    unsigned char data[0 + 32 * 6];
acdedc
} _EC_SECG_PRIME_256K1 = {
acdedc
    {
acdedc
        NID_X9_62_prime_field, 0, 32, 1
acdedc
    },
acdedc
    {
acdedc
        /* no seed */
acdedc
        /* p */
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F,
acdedc
        /* a */
acdedc
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
acdedc
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
acdedc
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
acdedc
        /* b */
acdedc
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
acdedc
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
acdedc
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
acdedc
        /* x */
acdedc
        0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95,
acdedc
        0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9,
acdedc
        0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98,
acdedc
        /* y */
acdedc
        0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb, 0xfc,
acdedc
        0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19,
acdedc
        0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10, 0xd4, 0xb8,
acdedc
        /* order */
acdedc
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
acdedc
        0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
acdedc
        0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41
acdedc
    }
acdedc
};
acdedc
acdedc
typedef struct _ec_list_element_st {
acdedc
    int nid;
acdedc
    const EC_CURVE_DATA *data;
acdedc
    const EC_METHOD *(*meth) (void);
acdedc
    const char *comment;
acdedc
} ec_list_element;
acdedc
acdedc
static const ec_list_element curve_list[] = {
acdedc
    /* prime field curves */
acdedc
    /* secg curves */
acdedc
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
acdedc
    {NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method,
acdedc
     "NIST/SECG curve over a 224 bit prime field"},
acdedc
#else
acdedc
    {NID_secp224r1, &_EC_NIST_PRIME_224.h, 0,
acdedc
     "NIST/SECG curve over a 224 bit prime field"},
acdedc
#endif
acdedc
    {NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0,
acdedc
     "SECG curve over a 256 bit prime field"},
acdedc
    /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
acdedc
    {NID_secp384r1, &_EC_NIST_PRIME_384.h, 0,
acdedc
     "NIST/SECG curve over a 384 bit prime field"},
acdedc
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
acdedc
    {NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method,
acdedc
     "NIST/SECG curve over a 521 bit prime field"},
acdedc
#else
acdedc
    {NID_secp521r1, &_EC_NIST_PRIME_521.h, 0,
acdedc
     "NIST/SECG curve over a 521 bit prime field"},
acdedc
#endif
acdedc
    /* X9.62 curves */
acdedc
    {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h,
acdedc
#if defined(ECP_NISTZ256_ASM)
acdedc
     EC_GFp_nistz256_method,
acdedc
#elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
acdedc
     EC_GFp_nistp256_method,
acdedc
#else
acdedc
     0,
acdedc
#endif
acdedc
     "X9.62/SECG curve over a 256 bit prime field"},
acdedc
};
acdedc
acdedc
#define curve_list_length OSSL_NELEM(curve_list)
acdedc
acdedc
static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
acdedc
{
acdedc
    EC_GROUP *group = NULL;
acdedc
    EC_POINT *P = NULL;
acdedc
    BN_CTX *ctx = NULL;
acdedc
    BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order =
acdedc
        NULL;
acdedc
    int ok = 0;
acdedc
    int seed_len, param_len;
acdedc
    const EC_METHOD *meth;
acdedc
    const EC_CURVE_DATA *data;
acdedc
    const unsigned char *params;
acdedc
acdedc
    /* If no curve data curve method must handle everything */
acdedc
    if (curve.data == NULL)
acdedc
        return EC_GROUP_new(curve.meth != NULL ? curve.meth() : NULL);
acdedc
acdedc
    if ((ctx = BN_CTX_new()) == NULL) {
acdedc
        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
acdedc
        goto err;
acdedc
    }
acdedc
acdedc
    data = curve.data;
acdedc
    seed_len = data->seed_len;
acdedc
    param_len = data->param_len;
acdedc
    params = (const unsigned char *)(data + 1); /* skip header */
acdedc
    params += seed_len;         /* skip seed */
acdedc
acdedc
    if ((p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) == NULL
acdedc
        || (a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) == NULL
acdedc
        || (b = BN_bin2bn(params + 2 * param_len, param_len, NULL)) == NULL) {
acdedc
        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
acdedc
        goto err;
acdedc
    }
acdedc
acdedc
    if (curve.meth != 0) {
acdedc
        meth = curve.meth();
acdedc
        if (((group = EC_GROUP_new(meth)) == NULL) ||
acdedc
            (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
acdedc
            ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
acdedc
            goto err;
acdedc
        }
acdedc
    } else if (data->field_type == NID_X9_62_prime_field) {
acdedc
        if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
acdedc
            ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
acdedc
            goto err;
acdedc
        }
acdedc
    }
acdedc
#ifndef OPENSSL_NO_EC2M
acdedc
    else {                      /* field_type ==
acdedc
                                 * NID_X9_62_characteristic_two_field */
acdedc
acdedc
        if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) {
acdedc
            ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
acdedc
            goto err;
acdedc
        }
acdedc
    }
acdedc
#endif
acdedc
acdedc
    EC_GROUP_set_curve_name(group, curve.nid);
acdedc
acdedc
    if ((P = EC_POINT_new(group)) == NULL) {
acdedc
        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
acdedc
        goto err;
acdedc
    }
acdedc
acdedc
    if ((x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) == NULL
acdedc
        || (y = BN_bin2bn(params + 4 * param_len, param_len, NULL)) == NULL) {
acdedc
        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
acdedc
        goto err;
acdedc
    }
acdedc
    if (!EC_POINT_set_affine_coordinates(group, P, x, y, ctx)) {
acdedc
        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
acdedc
        goto err;
acdedc
    }
acdedc
    if ((order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) == NULL
acdedc
        || !BN_set_word(x, (BN_ULONG)data->cofactor)) {
acdedc
        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
acdedc
        goto err;
acdedc
    }
acdedc
    if (!EC_GROUP_set_generator(group, P, order, x)) {
acdedc
        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
acdedc
        goto err;
acdedc
    }
acdedc
    if (seed_len) {
acdedc
        if (!EC_GROUP_set_seed(group, params - seed_len, seed_len)) {
acdedc
            ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
acdedc
            goto err;
acdedc
        }
acdedc
    }
acdedc
    ok = 1;
acdedc
 err:
acdedc
    if (!ok) {
acdedc
        EC_GROUP_free(group);
acdedc
        group = NULL;
acdedc
    }
acdedc
    EC_POINT_free(P);
acdedc
    BN_CTX_free(ctx);
acdedc
    BN_free(p);
acdedc
    BN_free(a);
acdedc
    BN_free(b);
acdedc
    BN_free(order);
acdedc
    BN_free(x);
acdedc
    BN_free(y);
acdedc
    return group;
acdedc
}
acdedc
acdedc
EC_GROUP *EC_GROUP_new_by_curve_name(int nid)
acdedc
{
acdedc
    size_t i;
acdedc
    EC_GROUP *ret = NULL;
acdedc
acdedc
    if (nid <= 0)
acdedc
        return NULL;
acdedc
acdedc
    for (i = 0; i < curve_list_length; i++)
acdedc
        if (curve_list[i].nid == nid) {
acdedc
            ret = ec_group_new_from_data(curve_list[i]);
acdedc
            break;
acdedc
        }
acdedc
acdedc
    if (ret == NULL) {
acdedc
        ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP);
acdedc
        return NULL;
acdedc
    }
acdedc
acdedc
    return ret;
acdedc
}
acdedc
acdedc
size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems)
acdedc
{
acdedc
    size_t i, min;
acdedc
acdedc
    if (r == NULL || nitems == 0)
acdedc
        return curve_list_length;
acdedc
acdedc
    min = nitems < curve_list_length ? nitems : curve_list_length;
acdedc
acdedc
    for (i = 0; i < min; i++) {
acdedc
        r[i].nid = curve_list[i].nid;
acdedc
        r[i].comment = curve_list[i].comment;
acdedc
    }
acdedc
acdedc
    return curve_list_length;
acdedc
}
acdedc
acdedc
/* Functions to translate between common NIST curve names and NIDs */
acdedc
acdedc
typedef struct {
acdedc
    const char *name;           /* NIST Name of curve */
acdedc
    int nid;                    /* Curve NID */
acdedc
} EC_NIST_NAME;
acdedc
acdedc
static EC_NIST_NAME nist_curves[] = {
acdedc
    {"B-163", NID_sect163r2},
acdedc
    {"B-233", NID_sect233r1},
acdedc
    {"B-283", NID_sect283r1},
acdedc
    {"B-409", NID_sect409r1},
acdedc
    {"B-571", NID_sect571r1},
acdedc
    {"K-163", NID_sect163k1},
acdedc
    {"K-233", NID_sect233k1},
acdedc
    {"K-283", NID_sect283k1},
acdedc
    {"K-409", NID_sect409k1},
acdedc
    {"K-571", NID_sect571k1},
acdedc
    {"P-192", NID_X9_62_prime192v1},
acdedc
    {"P-224", NID_secp224r1},
acdedc
    {"P-256", NID_X9_62_prime256v1},
acdedc
    {"P-384", NID_secp384r1},
acdedc
    {"P-521", NID_secp521r1}
acdedc
};
acdedc
acdedc
const char *EC_curve_nid2nist(int nid)
acdedc
{
acdedc
    size_t i;
acdedc
    for (i = 0; i < OSSL_NELEM(nist_curves); i++) {
acdedc
        if (nist_curves[i].nid == nid)
acdedc
            return nist_curves[i].name;
acdedc
    }
acdedc
    return NULL;
acdedc
}
acdedc
acdedc
int EC_curve_nist2nid(const char *name)
acdedc
{
acdedc
    size_t i;
acdedc
    for (i = 0; i < OSSL_NELEM(nist_curves); i++) {
acdedc
        if (strcmp(nist_curves[i].name, name) == 0)
acdedc
            return nist_curves[i].nid;
acdedc
    }
acdedc
    return NID_undef;
acdedc
}