isaacpittman-hitachi / rpms / openssl

Forked from rpms/openssl 2 years ago
Clone

Blame SOURCES/ec_curve.c

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