Blame SOURCES/ec_curve.c

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