Blame SOURCES/ec_curve.c

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