Home | History | Annotate | Download | only in ec
      1 /* Originally written by Bodo Moeller for the OpenSSL project.
      2  * ====================================================================
      3  * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  *
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in
     14  *    the documentation and/or other materials provided with the
     15  *    distribution.
     16  *
     17  * 3. All advertising materials mentioning features or use of this
     18  *    software must display the following acknowledgment:
     19  *    "This product includes software developed by the OpenSSL Project
     20  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
     21  *
     22  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     23  *    endorse or promote products derived from this software without
     24  *    prior written permission. For written permission, please contact
     25  *    openssl-core (at) openssl.org.
     26  *
     27  * 5. Products derived from this software may not be called "OpenSSL"
     28  *    nor may "OpenSSL" appear in their names without prior written
     29  *    permission of the OpenSSL Project.
     30  *
     31  * 6. Redistributions of any form whatsoever must retain the following
     32  *    acknowledgment:
     33  *    "This product includes software developed by the OpenSSL Project
     34  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
     35  *
     36  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     37  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     38  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     39  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     42  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     43  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     44  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     45  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     47  * OF THE POSSIBILITY OF SUCH DAMAGE.
     48  * ====================================================================
     49  *
     50  * This product includes cryptographic software written by Eric Young
     51  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     52  * Hudson (tjh (at) cryptsoft.com).
     53  *
     54  */
     55 /* ====================================================================
     56  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
     57  *
     58  * Portions of the attached software ("Contribution") are developed by
     59  * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
     60  *
     61  * The Contribution is licensed pursuant to the OpenSSL open source
     62  * license provided above.
     63  *
     64  * The elliptic curve binary polynomial software is originally written by
     65  * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
     66  * Laboratories. */
     67 
     68 #include <openssl/ec.h>
     69 
     70 #include <string.h>
     71 
     72 #include <openssl/bn.h>
     73 #include <openssl/err.h>
     74 #include <openssl/mem.h>
     75 #include <openssl/obj.h>
     76 
     77 #include "internal.h"
     78 
     79 
     80 static const struct curve_data P224 = {
     81     "NIST P-224",
     82     28,
     83     1,
     84     {/* p */
     85      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     86      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     87      0x00, 0x00, 0x00, 0x01,
     88      /* a */
     89      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     90      0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     91      0xFF, 0xFF, 0xFF, 0xFE,
     92      /* b */
     93      0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
     94      0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
     95      0x23, 0x55, 0xFF, 0xB4,
     96      /* x */
     97      0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
     98      0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
     99      0x11, 0x5C, 0x1D, 0x21,
    100      /* y */
    101      0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
    102      0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
    103      0x85, 0x00, 0x7e, 0x34,
    104      /* order */
    105      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    106      0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
    107      0x5C, 0x5C, 0x2A, 0x3D,
    108     }};
    109 
    110 static const struct curve_data P256 = {
    111     "NIST P-256",
    112     32,
    113     1,
    114     {/* p */
    115      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
    116      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    117      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    118      /* a */
    119      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
    120      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    121      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
    122      /* b */
    123      0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
    124      0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
    125      0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B,
    126      /* x */
    127      0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
    128      0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
    129      0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
    130      /* y */
    131      0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
    132      0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
    133      0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
    134      /* order */
    135      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    136      0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
    137      0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51}};
    138 
    139 static const struct curve_data P384 = {
    140     "NIST P-384",
    141     48,
    142     1,
    143     {/* p */
    144      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    145      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    146      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
    147      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    148      /* a */
    149      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    150      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    151      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
    152      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
    153      /* b */
    154      0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
    155      0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
    156      0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
    157      0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
    158      /* x */
    159      0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
    160      0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
    161      0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
    162      0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
    163      /* y */
    164      0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf,
    165      0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
    166      0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce,
    167      0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
    168      /* order */
    169      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    170      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    171      0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
    172      0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73}};
    173 
    174 static const struct curve_data P521 = {
    175     "NIST P-521",
    176     66,
    177     1,
    178     {/* p */
    179      0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    180      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    181      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    182      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    183      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    184      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    185      /* a */
    186      0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    187      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    188      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    189      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    190      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    191      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
    192      /* b */
    193      0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
    194      0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
    195      0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
    196      0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
    197      0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
    198      0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
    199      /* x */
    200      0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
    201      0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
    202      0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
    203      0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
    204      0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
    205      0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
    206      /* y */
    207      0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
    208      0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
    209      0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
    210      0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
    211      0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
    212      0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
    213      /* order */
    214      0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    215      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    216      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
    217      0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
    218      0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
    219      0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09}};
    220 
    221 const struct built_in_curve OPENSSL_built_in_curves[] = {
    222     {NID_secp224r1, &P224, 0},
    223     {
    224         NID_X9_62_prime256v1, &P256,
    225 #if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS)
    226         EC_GFp_nistp256_method,
    227 #else
    228         0,
    229 #endif
    230     },
    231     {NID_secp384r1, &P384, 0},
    232     {NID_secp521r1, &P521, 0},
    233     {NID_undef, 0, 0},
    234 };
    235 
    236 EC_GROUP *ec_group_new(const EC_METHOD *meth) {
    237   EC_GROUP *ret;
    238 
    239   if (meth == NULL) {
    240     OPENSSL_PUT_ERROR(EC, ec_group_new, EC_R_SLOT_FULL);
    241     return NULL;
    242   }
    243 
    244   if (meth->group_init == 0) {
    245     OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    246     return NULL;
    247   }
    248 
    249   ret = OPENSSL_malloc(sizeof(EC_GROUP));
    250   if (ret == NULL) {
    251     OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_MALLOC_FAILURE);
    252     return NULL;
    253   }
    254   memset(ret, 0, sizeof(EC_GROUP));
    255 
    256   ret->meth = meth;
    257   BN_init(&ret->order);
    258   BN_init(&ret->cofactor);
    259 
    260   if (!meth->group_init(ret)) {
    261     OPENSSL_free(ret);
    262     return NULL;
    263   }
    264 
    265   return ret;
    266 }
    267 
    268 EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
    269                                  const BIGNUM *b, BN_CTX *ctx) {
    270   const EC_METHOD *meth = EC_GFp_mont_method();
    271   EC_GROUP *ret;
    272 
    273   ret = ec_group_new(meth);
    274   if (ret == NULL) {
    275     return NULL;
    276   }
    277 
    278   if (ret->meth->group_set_curve == 0) {
    279     OPENSSL_PUT_ERROR(EC, EC_GROUP_new_curve_GFp,
    280                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    281     return 0;
    282   }
    283   if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) {
    284     EC_GROUP_free(ret);
    285     return NULL;
    286   }
    287   return ret;
    288 }
    289 
    290 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
    291                            const BIGNUM *order, const BIGNUM *cofactor) {
    292   if (group->curve_name != NID_undef) {
    293     /* |EC_GROUP_set_generator| should only be used with |EC_GROUP|s returned
    294      * by |EC_GROUP_new_curve_GFp|. */
    295     return 0;
    296   }
    297 
    298   if (group->generator == NULL) {
    299     group->generator = EC_POINT_new(group);
    300     if (group->generator == NULL) {
    301       return 0;
    302     }
    303   }
    304 
    305   if (!EC_POINT_copy(group->generator, generator)) {
    306     return 0;
    307   }
    308 
    309   if (order != NULL) {
    310     if (!BN_copy(&group->order, order)) {
    311       return 0;
    312     }
    313   } else {
    314     BN_zero(&group->order);
    315   }
    316 
    317   if (cofactor != NULL) {
    318     if (!BN_copy(&group->cofactor, cofactor)) {
    319       return 0;
    320     }
    321   } else {
    322     BN_zero(&group->cofactor);
    323   }
    324 
    325   return 1;
    326 }
    327 
    328 static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
    329   EC_GROUP *group = NULL;
    330   EC_POINT *P = NULL;
    331   BN_CTX *ctx = NULL;
    332   BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = NULL;
    333   int ok = 0;
    334   unsigned param_len;
    335   const EC_METHOD *meth;
    336   const struct curve_data *data;
    337   const uint8_t *params;
    338 
    339   if ((ctx = BN_CTX_new()) == NULL) {
    340     OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_MALLOC_FAILURE);
    341     goto err;
    342   }
    343 
    344   data = curve->data;
    345   param_len = data->param_len;
    346   params = data->data;
    347 
    348   if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
    349       !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
    350       !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
    351     OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
    352     goto err;
    353   }
    354 
    355   if (curve->method != 0) {
    356     meth = curve->method();
    357     if (((group = ec_group_new(meth)) == NULL) ||
    358         (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
    359       OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
    360       goto err;
    361     }
    362   } else {
    363     if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
    364       OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
    365       goto err;
    366     }
    367   }
    368 
    369   if ((P = EC_POINT_new(group)) == NULL) {
    370     OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
    371     goto err;
    372   }
    373 
    374   if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
    375       !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
    376     OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
    377     goto err;
    378   }
    379 
    380   if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
    381     OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
    382     goto err;
    383   }
    384   if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) ||
    385       !BN_set_word(x, (BN_ULONG)data->cofactor)) {
    386     OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
    387     goto err;
    388   }
    389 
    390   group->generator = P;
    391   P = NULL;
    392   if (!BN_copy(&group->order, order) ||
    393       !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) {
    394     OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
    395     goto err;
    396   }
    397 
    398   ok = 1;
    399 
    400 err:
    401   if (!ok) {
    402     EC_GROUP_free(group);
    403     group = NULL;
    404   }
    405   EC_POINT_free(P);
    406   BN_CTX_free(ctx);
    407   BN_free(p);
    408   BN_free(a);
    409   BN_free(b);
    410   BN_free(order);
    411   BN_free(x);
    412   BN_free(y);
    413   return group;
    414 }
    415 
    416 EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
    417   unsigned i;
    418   const struct built_in_curve *curve;
    419   EC_GROUP *ret = NULL;
    420 
    421   for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
    422     curve = &OPENSSL_built_in_curves[i];
    423     if (curve->nid == nid) {
    424       ret = ec_group_new_from_data(curve);
    425       break;
    426     }
    427   }
    428 
    429   if (ret == NULL) {
    430     OPENSSL_PUT_ERROR(EC, EC_GROUP_new_by_curve_name, EC_R_UNKNOWN_GROUP);
    431     return NULL;
    432   }
    433 
    434   ret->curve_name = nid;
    435   return ret;
    436 }
    437 
    438 void EC_GROUP_free(EC_GROUP *group) {
    439   if (!group) {
    440     return;
    441   }
    442 
    443   if (group->meth->group_finish != 0) {
    444     group->meth->group_finish(group);
    445   }
    446 
    447   ec_pre_comp_free(group->pre_comp);
    448 
    449   EC_POINT_free(group->generator);
    450   BN_free(&group->order);
    451   BN_free(&group->cofactor);
    452 
    453   OPENSSL_free(group);
    454 }
    455 
    456 int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
    457   if (dest->meth->group_copy == 0) {
    458     OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    459     return 0;
    460   }
    461   if (dest->meth != src->meth) {
    462     OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, EC_R_INCOMPATIBLE_OBJECTS);
    463     return 0;
    464   }
    465   if (dest == src) {
    466     return 1;
    467   }
    468 
    469   ec_pre_comp_free(dest->pre_comp);
    470   dest->pre_comp = ec_pre_comp_dup(src->pre_comp);
    471 
    472   if (src->generator != NULL) {
    473     if (dest->generator == NULL) {
    474       dest->generator = EC_POINT_new(dest);
    475       if (dest->generator == NULL) {
    476         return 0;
    477       }
    478     }
    479     if (!EC_POINT_copy(dest->generator, src->generator)) {
    480       return 0;
    481     }
    482   } else {
    483     /* src->generator == NULL */
    484     if (dest->generator != NULL) {
    485       EC_POINT_clear_free(dest->generator);
    486       dest->generator = NULL;
    487     }
    488   }
    489 
    490   if (!BN_copy(&dest->order, &src->order) ||
    491       !BN_copy(&dest->cofactor, &src->cofactor)) {
    492     return 0;
    493   }
    494 
    495   dest->curve_name = src->curve_name;
    496 
    497   return dest->meth->group_copy(dest, src);
    498 }
    499 
    500 EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
    501   EC_GROUP *t = NULL;
    502   int ok = 0;
    503 
    504   if (a == NULL) {
    505     return NULL;
    506   }
    507 
    508   t = ec_group_new(a->meth);
    509   if (t == NULL) {
    510     return NULL;
    511   }
    512   if (!ec_group_copy(t, a)) {
    513     goto err;
    514   }
    515 
    516   ok = 1;
    517 
    518 err:
    519   if (!ok) {
    520     EC_GROUP_free(t);
    521     return NULL;
    522   } else {
    523     return t;
    524   }
    525 }
    526 
    527 int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
    528   return a->curve_name == NID_undef ||
    529          b->curve_name == NID_undef ||
    530          a->curve_name != b->curve_name;
    531 }
    532 
    533 const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
    534   return group->generator;
    535 }
    536 
    537 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
    538   if (!BN_copy(order, &group->order)) {
    539     return 0;
    540   }
    541 
    542   return !BN_is_zero(order);
    543 }
    544 
    545 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
    546                           BN_CTX *ctx) {
    547   if (!BN_copy(cofactor, &group->cofactor)) {
    548     return 0;
    549   }
    550 
    551   return !BN_is_zero(&group->cofactor);
    552 }
    553 
    554 int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
    555                            BIGNUM *out_b, BN_CTX *ctx) {
    556   if (group->meth->group_get_curve == 0) {
    557     OPENSSL_PUT_ERROR(EC, EC_GROUP_get_curve_GFp,
    558                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    559     return 0;
    560   }
    561   return group->meth->group_get_curve(group, out_p, out_a, out_b, ctx);
    562 }
    563 
    564 int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
    565 
    566 int EC_GROUP_get_degree(const EC_GROUP *group) {
    567   if (group->meth->group_get_degree == 0) {
    568     OPENSSL_PUT_ERROR(EC, EC_GROUP_get_degree,
    569                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    570     return 0;
    571   }
    572   return group->meth->group_get_degree(group);
    573 }
    574 
    575 int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
    576   if (group->meth->mul == 0) {
    577     /* use default */
    578     return ec_wNAF_precompute_mult(group, ctx);
    579   }
    580 
    581   if (group->meth->precompute_mult != 0) {
    582     return group->meth->precompute_mult(group, ctx);
    583   }
    584 
    585   return 1; /* nothing to do, so report success */
    586 }
    587 
    588 int EC_GROUP_have_precompute_mult(const EC_GROUP *group) {
    589   if (group->meth->mul == 0) {
    590     /* use default */
    591     return ec_wNAF_have_precompute_mult(group);
    592   }
    593 
    594   if (group->meth->have_precompute_mult != 0) {
    595     return group->meth->have_precompute_mult(group);
    596   }
    597 
    598   return 0; /* cannot tell whether precomputation has been performed */
    599 }
    600 
    601 EC_POINT *EC_POINT_new(const EC_GROUP *group) {
    602   EC_POINT *ret;
    603 
    604   if (group == NULL) {
    605     OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_PASSED_NULL_PARAMETER);
    606     return NULL;
    607   }
    608   if (group->meth->point_init == 0) {
    609     OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    610     return NULL;
    611   }
    612 
    613   ret = OPENSSL_malloc(sizeof *ret);
    614   if (ret == NULL) {
    615     OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_MALLOC_FAILURE);
    616     return NULL;
    617   }
    618 
    619   ret->meth = group->meth;
    620 
    621   if (!ret->meth->point_init(ret)) {
    622     OPENSSL_free(ret);
    623     return NULL;
    624   }
    625 
    626   return ret;
    627 }
    628 
    629 void EC_POINT_free(EC_POINT *point) {
    630   if (!point) {
    631     return;
    632   }
    633 
    634   if (point->meth->point_finish != 0) {
    635     point->meth->point_finish(point);
    636   }
    637   OPENSSL_free(point);
    638 }
    639 
    640 void EC_POINT_clear_free(EC_POINT *point) {
    641   if (!point) {
    642     return;
    643   }
    644 
    645   if (point->meth->point_clear_finish != 0) {
    646     point->meth->point_clear_finish(point);
    647   } else if (point->meth->point_finish != 0) {
    648     point->meth->point_finish(point);
    649   }
    650   OPENSSL_cleanse(point, sizeof *point);
    651   OPENSSL_free(point);
    652 }
    653 
    654 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
    655   if (dest->meth->point_copy == 0) {
    656     OPENSSL_PUT_ERROR(EC, EC_POINT_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    657     return 0;
    658   }
    659   if (dest->meth != src->meth) {
    660     OPENSSL_PUT_ERROR(EC, EC_POINT_copy, EC_R_INCOMPATIBLE_OBJECTS);
    661     return 0;
    662   }
    663   if (dest == src) {
    664     return 1;
    665   }
    666   return dest->meth->point_copy(dest, src);
    667 }
    668 
    669 EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
    670   EC_POINT *t;
    671   int r;
    672 
    673   if (a == NULL) {
    674     return NULL;
    675   }
    676 
    677   t = EC_POINT_new(group);
    678   if (t == NULL) {
    679     OPENSSL_PUT_ERROR(EC, EC_POINT_dup, ERR_R_MALLOC_FAILURE);
    680     return NULL;
    681   }
    682   r = EC_POINT_copy(t, a);
    683   if (!r) {
    684     EC_POINT_free(t);
    685     return NULL;
    686   } else {
    687     return t;
    688   }
    689 }
    690 
    691 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
    692   if (group->meth->point_set_to_infinity == 0) {
    693     OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity,
    694                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    695     return 0;
    696   }
    697   if (group->meth != point->meth) {
    698     OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity, EC_R_INCOMPATIBLE_OBJECTS);
    699     return 0;
    700   }
    701   return group->meth->point_set_to_infinity(group, point);
    702 }
    703 
    704 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
    705   if (group->meth->is_at_infinity == 0) {
    706     OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity,
    707                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    708     return 0;
    709   }
    710   if (group->meth != point->meth) {
    711     OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity, EC_R_INCOMPATIBLE_OBJECTS);
    712     return 0;
    713   }
    714   return group->meth->is_at_infinity(group, point);
    715 }
    716 
    717 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
    718                          BN_CTX *ctx) {
    719   if (group->meth->is_on_curve == 0) {
    720     OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve,
    721                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    722     return 0;
    723   }
    724   if (group->meth != point->meth) {
    725     OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve, EC_R_INCOMPATIBLE_OBJECTS);
    726     return 0;
    727   }
    728   return group->meth->is_on_curve(group, point, ctx);
    729 }
    730 
    731 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
    732                  BN_CTX *ctx) {
    733   if (group->meth->point_cmp == 0) {
    734     OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    735     return -1;
    736   }
    737   if ((group->meth != a->meth) || (a->meth != b->meth)) {
    738     OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, EC_R_INCOMPATIBLE_OBJECTS);
    739     return -1;
    740   }
    741   return group->meth->point_cmp(group, a, b, ctx);
    742 }
    743 
    744 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
    745   if (group->meth->make_affine == 0) {
    746     OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine,
    747                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    748     return 0;
    749   }
    750   if (group->meth != point->meth) {
    751     OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine, EC_R_INCOMPATIBLE_OBJECTS);
    752     return 0;
    753   }
    754   return group->meth->make_affine(group, point, ctx);
    755 }
    756 
    757 int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
    758                           BN_CTX *ctx) {
    759   size_t i;
    760 
    761   if (group->meth->points_make_affine == 0) {
    762     OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine,
    763                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    764     return 0;
    765   }
    766   for (i = 0; i < num; i++) {
    767     if (group->meth != points[i]->meth) {
    768       OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine, EC_R_INCOMPATIBLE_OBJECTS);
    769       return 0;
    770     }
    771   }
    772   return group->meth->points_make_affine(group, num, points, ctx);
    773 }
    774 
    775 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
    776                                         const EC_POINT *point, BIGNUM *x,
    777                                         BIGNUM *y, BN_CTX *ctx) {
    778   if (group->meth->point_get_affine_coordinates == 0) {
    779     OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp,
    780                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    781     return 0;
    782   }
    783   if (group->meth != point->meth) {
    784     OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp,
    785                       EC_R_INCOMPATIBLE_OBJECTS);
    786     return 0;
    787   }
    788   return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
    789 }
    790 
    791 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
    792                                         const BIGNUM *x, const BIGNUM *y,
    793                                         BN_CTX *ctx) {
    794   if (group->meth->point_set_affine_coordinates == 0) {
    795     OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp,
    796                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    797     return 0;
    798   }
    799   if (group->meth != point->meth) {
    800     OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp,
    801                       EC_R_INCOMPATIBLE_OBJECTS);
    802     return 0;
    803   }
    804   return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
    805 }
    806 
    807 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
    808                  const EC_POINT *b, BN_CTX *ctx) {
    809   if (group->meth->add == 0) {
    810     OPENSSL_PUT_ERROR(EC, EC_POINT_add, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    811     return 0;
    812   }
    813   if ((group->meth != r->meth) || (r->meth != a->meth) ||
    814       (a->meth != b->meth)) {
    815     OPENSSL_PUT_ERROR(EC, EC_POINT_add, EC_R_INCOMPATIBLE_OBJECTS);
    816     return 0;
    817   }
    818   return group->meth->add(group, r, a, b, ctx);
    819 }
    820 
    821 
    822 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
    823                  BN_CTX *ctx) {
    824   if (group->meth->dbl == 0) {
    825     OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    826     return 0;
    827   }
    828   if ((group->meth != r->meth) || (r->meth != a->meth)) {
    829     OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, EC_R_INCOMPATIBLE_OBJECTS);
    830     return 0;
    831   }
    832   return group->meth->dbl(group, r, a, ctx);
    833 }
    834 
    835 
    836 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
    837   if (group->meth->invert == 0) {
    838     OPENSSL_PUT_ERROR(EC, EC_POINT_invert, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    839     return 0;
    840   }
    841   if (group->meth != a->meth) {
    842     OPENSSL_PUT_ERROR(EC, EC_POINT_invert, EC_R_INCOMPATIBLE_OBJECTS);
    843     return 0;
    844   }
    845   return group->meth->invert(group, a, ctx);
    846 }
    847 
    848 int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
    849                  const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) {
    850   /* just a convenient interface to EC_POINTs_mul() */
    851 
    852   const EC_POINT *points[1];
    853   const BIGNUM *scalars[1];
    854 
    855   points[0] = point;
    856   scalars[0] = p_scalar;
    857 
    858   return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL),
    859                        points, scalars, ctx);
    860 }
    861 
    862 int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
    863                   size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
    864                   BN_CTX *ctx) {
    865   if (group->meth->mul == 0) {
    866     /* use default. Warning, not constant-time. */
    867     return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
    868   }
    869 
    870   return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
    871 }
    872 
    873 int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
    874                                              const BIGNUM *x, const BIGNUM *y,
    875                                              const BIGNUM *z, BN_CTX *ctx) {
    876   if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
    877     OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp,
    878                       ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    879     return 0;
    880   }
    881   if (group->meth != point->meth) {
    882     OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp,
    883                       EC_R_INCOMPATIBLE_OBJECTS);
    884     return 0;
    885   }
    886   return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y,
    887                                                             z, ctx);
    888 }
    889 
    890 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
    891 
    892 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) {
    893   return NULL;
    894 }
    895 
    896 int EC_METHOD_get_field_type(const EC_METHOD *meth) {
    897   return NID_X9_62_prime_field;
    898 }
    899 
    900 void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
    901                                         point_conversion_form_t form) {
    902   if (form != POINT_CONVERSION_UNCOMPRESSED) {
    903     abort();
    904   }
    905 }
    906