Blame SOURCES/ec_curve.c

acdedc
/*
7d1228
 * Copyright 2002-2019 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>
7d1228
#include "ec_local.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
}
7d1228
7d1228
#define NUM_BN_FIELDS 6
7d1228
/*
7d1228
 * Validates EC domain parameter data for known named curves.
7d1228
 * This can be used when a curve is loaded explicitly (without a curve
7d1228
 * name) or to validate that domain parameters have not been modified.
7d1228
 *
7d1228
 * Returns: The nid associated with the found named curve, or NID_undef
7d1228
 *          if not found. If there was an error it returns -1.
7d1228
 */
7d1228
int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx)
7d1228
{
7d1228
    int ret = -1, nid, len, field_type, param_len;
7d1228
    size_t i, seed_len;
7d1228
    const unsigned char *seed, *params_seed, *params;
7d1228
    unsigned char *param_bytes = NULL;
7d1228
    const EC_CURVE_DATA *data;
7d1228
    const EC_POINT *generator = NULL;
7d1228
    const EC_METHOD *meth;
7d1228
    const BIGNUM *cofactor = NULL;
7d1228
    /* An array of BIGNUMs for (p, a, b, x, y, order) */
7d1228
    BIGNUM *bn[NUM_BN_FIELDS] = {NULL, NULL, NULL, NULL, NULL, NULL};
7d1228
7d1228
    meth = EC_GROUP_method_of(group);
7d1228
    if (meth == NULL)
7d1228
        return -1;
7d1228
    /* Use the optional named curve nid as a search field */
7d1228
    nid = EC_GROUP_get_curve_name(group);
7d1228
    field_type = EC_METHOD_get_field_type(meth);
7d1228
    seed_len = EC_GROUP_get_seed_len(group);
7d1228
    seed = EC_GROUP_get0_seed(group);
7d1228
    cofactor = EC_GROUP_get0_cofactor(group);
7d1228
7d1228
    BN_CTX_start(ctx);
7d1228
7d1228
    /*
7d1228
     * The built-in curves contains data fields (p, a, b, x, y, order) that are
7d1228
     * all zero-padded to be the same size. The size of the padding is
7d1228
     * determined by either the number of bytes in the field modulus (p) or the
7d1228
     * EC group order, whichever is larger.
7d1228
     */
7d1228
    param_len = BN_num_bytes(group->order);
7d1228
    len = BN_num_bytes(group->field);
7d1228
    if (len > param_len)
7d1228
        param_len = len;
7d1228
7d1228
    /* Allocate space to store the padded data for (p, a, b, x, y, order)  */
7d1228
    param_bytes = OPENSSL_malloc(param_len * NUM_BN_FIELDS);
7d1228
    if (param_bytes == NULL)
7d1228
        goto end;
7d1228
7d1228
    /* Create the bignums */
7d1228
    for (i = 0; i < NUM_BN_FIELDS; ++i) {
7d1228
        if ((bn[i] = BN_CTX_get(ctx)) == NULL)
7d1228
            goto end;
7d1228
    }
7d1228
    /*
7d1228
     * Fill in the bn array with the same values as the internal curves
7d1228
     * i.e. the values are p, a, b, x, y, order.
7d1228
     */
7d1228
    /* Get p, a & b */
7d1228
    if (!(EC_GROUP_get_curve(group, bn[0], bn[1], bn[2], ctx)
7d1228
        && ((generator = EC_GROUP_get0_generator(group)) != NULL)
7d1228
        /* Get x & y */
7d1228
        && EC_POINT_get_affine_coordinates(group, generator, bn[3], bn[4], ctx)
7d1228
        /* Get order */
7d1228
        && EC_GROUP_get_order(group, bn[5], ctx)))
7d1228
        goto end;
7d1228
7d1228
   /*
7d1228
     * Convert the bignum array to bytes that are joined together to form
7d1228
     * a single buffer that contains data for all fields.
7d1228
     * (p, a, b, x, y, order) are all zero padded to be the same size.
7d1228
     */
7d1228
    for (i = 0; i < NUM_BN_FIELDS; ++i) {
7d1228
        if (BN_bn2binpad(bn[i], &param_bytes[i*param_len], param_len) <= 0)
7d1228
            goto end;
7d1228
    }
7d1228
7d1228
    for (i = 0; i < curve_list_length; i++) {
7d1228
        const ec_list_element curve = curve_list[i];
7d1228
7d1228
        data = curve.data;
7d1228
        /* Get the raw order byte data */
7d1228
        params_seed = (const unsigned char *)(data + 1); /* skip header */
7d1228
        params = params_seed + data->seed_len;
7d1228
7d1228
        /* Look for unique fields in the fixed curve data */
7d1228
        if (data->field_type == field_type
7d1228
            && param_len == data->param_len
7d1228
            && (nid <= 0 || nid == curve.nid)
7d1228
            /* check the optional cofactor (ignore if its zero) */
7d1228
            && (BN_is_zero(cofactor)
7d1228
                || BN_is_word(cofactor, (const BN_ULONG)curve.data->cofactor))
7d1228
            /* Check the optional seed (ignore if its not set) */
7d1228
            && (data->seed_len == 0 || seed_len == 0
7d1228
                || ((size_t)data->seed_len == seed_len
7d1228
                     && memcmp(params_seed, seed, seed_len) == 0))
7d1228
            /* Check that the groups params match the built-in curve params */
7d1228
            && memcmp(param_bytes, params, param_len * NUM_BN_FIELDS)
7d1228
                             == 0) {
7d1228
            ret = curve.nid;
7d1228
            goto end;
7d1228
        }
7d1228
    }
7d1228
    /* Gets here if the group was not found */
7d1228
    ret = NID_undef;
7d1228
end:
7d1228
    OPENSSL_free(param_bytes);
7d1228
    BN_CTX_end(ctx);
7d1228
    return ret;
7d1228
}