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 <assert.h>
     71 #include <string.h>
     72 
     73 #include <openssl/bn.h>
     74 #include <openssl/err.h>
     75 #include <openssl/mem.h>
     76 #include <openssl/obj.h>
     77 
     78 #include "internal.h"
     79 #include "../internal.h"
     80 
     81 
     82 static const struct curve_data P224 = {
     83     "NIST P-224",
     84     28,
     85     1,
     86     {/* p */
     87      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     88      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     89      0x00, 0x00, 0x00, 0x01,
     90      /* a */
     91      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     92      0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     93      0xFF, 0xFF, 0xFF, 0xFE,
     94      /* b */
     95      0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
     96      0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
     97      0x23, 0x55, 0xFF, 0xB4,
     98      /* x */
     99      0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
    100      0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
    101      0x11, 0x5C, 0x1D, 0x21,
    102      /* y */
    103      0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
    104      0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
    105      0x85, 0x00, 0x7e, 0x34,
    106      /* order */
    107      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    108      0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
    109      0x5C, 0x5C, 0x2A, 0x3D,
    110     }};
    111 
    112 static const struct curve_data P256 = {
    113     "NIST P-256",
    114     32,
    115     1,
    116     {/* p */
    117      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
    118      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    119      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    120      /* a */
    121      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
    122      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    123      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
    124      /* b */
    125      0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
    126      0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
    127      0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B,
    128      /* x */
    129      0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
    130      0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
    131      0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
    132      /* y */
    133      0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
    134      0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
    135      0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
    136      /* order */
    137      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    138      0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
    139      0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51}};
    140 
    141 static const struct curve_data P384 = {
    142     "NIST P-384",
    143     48,
    144     1,
    145     {/* p */
    146      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    147      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    148      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
    149      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    150      /* a */
    151      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    152      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    153      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
    154      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
    155      /* b */
    156      0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
    157      0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
    158      0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
    159      0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
    160      /* x */
    161      0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
    162      0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
    163      0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
    164      0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
    165      /* y */
    166      0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf,
    167      0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
    168      0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce,
    169      0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
    170      /* order */
    171      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    172      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    173      0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
    174      0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73}};
    175 
    176 static const struct curve_data P521 = {
    177     "NIST P-521",
    178     66,
    179     1,
    180     {/* p */
    181      0x01, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    185      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    186      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    187      /* a */
    188      0x01, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    192      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    193      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
    194      /* b */
    195      0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
    196      0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
    197      0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
    198      0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
    199      0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
    200      0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
    201      /* x */
    202      0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
    203      0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
    204      0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
    205      0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
    206      0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
    207      0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
    208      /* y */
    209      0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
    210      0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
    211      0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
    212      0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
    213      0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
    214      0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
    215      /* order */
    216      0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    217      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    218      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
    219      0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
    220      0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
    221      0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09}};
    222 
    223 /* MSan appears to have a bug that causes code to be miscompiled in opt mode.
    224  * While that is being looked at, don't run the uint128_t code under MSan. */
    225 #if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \
    226     !defined(MEMORY_SANITIZER)
    227 #define BORINGSSL_USE_INT128_CODE
    228 #endif
    229 
    230 const struct built_in_curve OPENSSL_built_in_curves[] = {
    231     {NID_secp521r1, &P521, 0},
    232     {NID_secp384r1, &P384, 0},
    233     {
    234         NID_X9_62_prime256v1, &P256,
    235 #if defined(BORINGSSL_USE_INT128_CODE)
    236 #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
    237     !defined(OPENSSL_SMALL)
    238         EC_GFp_nistz256_method,
    239 #else
    240         EC_GFp_nistp256_method,
    241 #endif
    242 #else
    243         0,
    244 #endif
    245     },
    246     {
    247         NID_secp224r1, &P224,
    248 #if defined(BORINGSSL_USE_INT128_CODE) && !defined(OPENSSL_SMALL)
    249         EC_GFp_nistp224_method,
    250 #else
    251         0,
    252 #endif
    253     },
    254     {NID_undef, 0, 0},
    255 };
    256 
    257 /* built_in_curve_scalar_field_monts contains Montgomery contexts for
    258  * performing inversions in the scalar fields of each of the built-in
    259  * curves. It's protected by |built_in_curve_scalar_field_monts_once|. */
    260 static const BN_MONT_CTX **built_in_curve_scalar_field_monts;
    261 
    262 static CRYPTO_once_t built_in_curve_scalar_field_monts_once;
    263 
    264 static void built_in_curve_scalar_field_monts_init(void) {
    265   unsigned num_built_in_curves;
    266   for (num_built_in_curves = 0;; num_built_in_curves++) {
    267     if (OPENSSL_built_in_curves[num_built_in_curves].nid == NID_undef) {
    268       break;
    269     }
    270   }
    271 
    272   assert(0 < num_built_in_curves);
    273 
    274   built_in_curve_scalar_field_monts =
    275       OPENSSL_malloc(sizeof(BN_MONT_CTX *) * num_built_in_curves);
    276   if (built_in_curve_scalar_field_monts == NULL) {
    277     return;
    278   }
    279 
    280   BIGNUM *order = BN_new();
    281   BN_CTX *bn_ctx = BN_CTX_new();
    282   BN_MONT_CTX *mont_ctx = NULL;
    283 
    284   if (bn_ctx == NULL ||
    285       order == NULL) {
    286     goto err;
    287   }
    288 
    289   unsigned i;
    290   for (i = 0; i < num_built_in_curves; i++) {
    291     const struct curve_data *curve = OPENSSL_built_in_curves[i].data;
    292     const unsigned param_len = curve->param_len;
    293     const uint8_t *params = curve->data;
    294 
    295     mont_ctx = BN_MONT_CTX_new();
    296     if (mont_ctx == NULL) {
    297       goto err;
    298     }
    299 
    300     if (!BN_bin2bn(params + 5 * param_len, param_len, order) ||
    301         !BN_MONT_CTX_set(mont_ctx, order, bn_ctx)) {
    302       goto err;
    303     }
    304 
    305     built_in_curve_scalar_field_monts[i] = mont_ctx;
    306     mont_ctx = NULL;
    307   }
    308 
    309   goto out;
    310 
    311 err:
    312   BN_MONT_CTX_free(mont_ctx);
    313   OPENSSL_free((BN_MONT_CTX**) built_in_curve_scalar_field_monts);
    314   built_in_curve_scalar_field_monts = NULL;
    315 
    316 out:
    317   BN_free(order);
    318   BN_CTX_free(bn_ctx);
    319 }
    320 
    321 EC_GROUP *ec_group_new(const EC_METHOD *meth) {
    322   EC_GROUP *ret;
    323 
    324   if (meth == NULL) {
    325     OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL);
    326     return NULL;
    327   }
    328 
    329   if (meth->group_init == 0) {
    330     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    331     return NULL;
    332   }
    333 
    334   ret = OPENSSL_malloc(sizeof(EC_GROUP));
    335   if (ret == NULL) {
    336     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    337     return NULL;
    338   }
    339   memset(ret, 0, sizeof(EC_GROUP));
    340 
    341   ret->meth = meth;
    342   BN_init(&ret->order);
    343   BN_init(&ret->cofactor);
    344 
    345   if (!meth->group_init(ret)) {
    346     OPENSSL_free(ret);
    347     return NULL;
    348   }
    349 
    350   return ret;
    351 }
    352 
    353 EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
    354                                  const BIGNUM *b, BN_CTX *ctx) {
    355   const EC_METHOD *meth = EC_GFp_mont_method();
    356   EC_GROUP *ret;
    357 
    358   ret = ec_group_new(meth);
    359   if (ret == NULL) {
    360     return NULL;
    361   }
    362 
    363   if (ret->meth->group_set_curve == 0) {
    364     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    365     return 0;
    366   }
    367   if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) {
    368     EC_GROUP_free(ret);
    369     return NULL;
    370   }
    371   return ret;
    372 }
    373 
    374 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
    375                            const BIGNUM *order, const BIGNUM *cofactor) {
    376   if (group->curve_name != NID_undef) {
    377     /* |EC_GROUP_set_generator| should only be used with |EC_GROUP|s returned
    378      * by |EC_GROUP_new_curve_GFp|. */
    379     return 0;
    380   }
    381 
    382   if (group->generator == NULL) {
    383     group->generator = EC_POINT_new(group);
    384     if (group->generator == NULL) {
    385       return 0;
    386     }
    387   }
    388 
    389   if (!EC_POINT_copy(group->generator, generator)) {
    390     return 0;
    391   }
    392 
    393   if (order != NULL) {
    394     if (!BN_copy(&group->order, order)) {
    395       return 0;
    396     }
    397   } else {
    398     BN_zero(&group->order);
    399   }
    400 
    401   if (cofactor != NULL) {
    402     if (!BN_copy(&group->cofactor, cofactor)) {
    403       return 0;
    404     }
    405   } else {
    406     BN_zero(&group->cofactor);
    407   }
    408 
    409   return 1;
    410 }
    411 
    412 static EC_GROUP *ec_group_new_from_data(unsigned built_in_index) {
    413   const struct built_in_curve *curve = &OPENSSL_built_in_curves[built_in_index];
    414   EC_GROUP *group = NULL;
    415   EC_POINT *P = NULL;
    416   BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
    417   const EC_METHOD *meth;
    418   int ok = 0;
    419 
    420   BN_CTX *ctx = BN_CTX_new();
    421   if (ctx == NULL) {
    422     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    423     goto err;
    424   }
    425 
    426   const struct curve_data *data = curve->data;
    427   const unsigned param_len = data->param_len;
    428   const uint8_t *params = data->data;
    429 
    430   if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
    431       !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
    432       !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
    433     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    434     goto err;
    435   }
    436 
    437   if (curve->method != 0) {
    438     meth = curve->method();
    439     if (((group = ec_group_new(meth)) == NULL) ||
    440         (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
    441       OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    442       goto err;
    443     }
    444   } else {
    445     if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
    446       OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    447       goto err;
    448     }
    449   }
    450 
    451   if ((P = EC_POINT_new(group)) == NULL) {
    452     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    453     goto err;
    454   }
    455 
    456   if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
    457       !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
    458     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    459     goto err;
    460   }
    461 
    462   if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
    463     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    464     goto err;
    465   }
    466   if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order) ||
    467       !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) {
    468     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    469     goto err;
    470   }
    471 
    472   CRYPTO_once(&built_in_curve_scalar_field_monts_once,
    473               built_in_curve_scalar_field_monts_init);
    474   if (built_in_curve_scalar_field_monts != NULL) {
    475     group->mont_data = built_in_curve_scalar_field_monts[built_in_index];
    476   }
    477 
    478   group->generator = P;
    479   P = NULL;
    480   ok = 1;
    481 
    482 err:
    483   if (!ok) {
    484     EC_GROUP_free(group);
    485     group = NULL;
    486   }
    487   EC_POINT_free(P);
    488   BN_CTX_free(ctx);
    489   BN_free(p);
    490   BN_free(a);
    491   BN_free(b);
    492   BN_free(x);
    493   BN_free(y);
    494   return group;
    495 }
    496 
    497 EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
    498   unsigned i;
    499   const struct built_in_curve *curve;
    500   EC_GROUP *ret = NULL;
    501 
    502   for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
    503     curve = &OPENSSL_built_in_curves[i];
    504     if (curve->nid == nid) {
    505       ret = ec_group_new_from_data(i);
    506       break;
    507     }
    508   }
    509 
    510   if (ret == NULL) {
    511     OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
    512     return NULL;
    513   }
    514 
    515   ret->curve_name = nid;
    516   return ret;
    517 }
    518 
    519 void EC_GROUP_free(EC_GROUP *group) {
    520   if (!group) {
    521     return;
    522   }
    523 
    524   if (group->meth->group_finish != 0) {
    525     group->meth->group_finish(group);
    526   }
    527 
    528   EC_POINT_free(group->generator);
    529   BN_free(&group->order);
    530   BN_free(&group->cofactor);
    531 
    532   OPENSSL_free(group);
    533 }
    534 
    535 int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
    536   if (dest->meth->group_copy == 0) {
    537     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    538     return 0;
    539   }
    540   if (dest->meth != src->meth) {
    541     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    542     return 0;
    543   }
    544   if (dest == src) {
    545     return 1;
    546   }
    547 
    548   dest->mont_data = src->mont_data;
    549 
    550   if (src->generator != NULL) {
    551     if (dest->generator == NULL) {
    552       dest->generator = EC_POINT_new(dest);
    553       if (dest->generator == NULL) {
    554         return 0;
    555       }
    556     }
    557     if (!EC_POINT_copy(dest->generator, src->generator)) {
    558       return 0;
    559     }
    560   } else {
    561     EC_POINT_clear_free(dest->generator);
    562     dest->generator = NULL;
    563   }
    564 
    565   if (!BN_copy(&dest->order, &src->order) ||
    566       !BN_copy(&dest->cofactor, &src->cofactor)) {
    567     return 0;
    568   }
    569 
    570   dest->curve_name = src->curve_name;
    571 
    572   return dest->meth->group_copy(dest, src);
    573 }
    574 
    575 const BN_MONT_CTX *ec_group_get_mont_data(const EC_GROUP *group) {
    576   return group->mont_data;
    577 }
    578 
    579 EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
    580   EC_GROUP *t = NULL;
    581   int ok = 0;
    582 
    583   if (a == NULL) {
    584     return NULL;
    585   }
    586 
    587   t = ec_group_new(a->meth);
    588   if (t == NULL) {
    589     return NULL;
    590   }
    591   if (!ec_group_copy(t, a)) {
    592     goto err;
    593   }
    594 
    595   ok = 1;
    596 
    597 err:
    598   if (!ok) {
    599     EC_GROUP_free(t);
    600     return NULL;
    601   } else {
    602     return t;
    603   }
    604 }
    605 
    606 int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
    607   return a->curve_name == NID_undef ||
    608          b->curve_name == NID_undef ||
    609          a->curve_name != b->curve_name;
    610 }
    611 
    612 const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
    613   return group->generator;
    614 }
    615 
    616 const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) {
    617   assert(!BN_is_zero(&group->order));
    618   return &group->order;
    619 }
    620 
    621 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
    622   if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) {
    623     return 0;
    624   }
    625   return 1;
    626 }
    627 
    628 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
    629                           BN_CTX *ctx) {
    630   if (!BN_copy(cofactor, &group->cofactor)) {
    631     return 0;
    632   }
    633 
    634   return !BN_is_zero(&group->cofactor);
    635 }
    636 
    637 int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
    638                            BIGNUM *out_b, BN_CTX *ctx) {
    639   return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b, ctx);
    640 }
    641 
    642 int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
    643 
    644 unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
    645   return ec_GFp_simple_group_get_degree(group);
    646 }
    647 
    648 EC_POINT *EC_POINT_new(const EC_GROUP *group) {
    649   EC_POINT *ret;
    650 
    651   if (group == NULL) {
    652     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
    653     return NULL;
    654   }
    655 
    656   ret = OPENSSL_malloc(sizeof *ret);
    657   if (ret == NULL) {
    658     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    659     return NULL;
    660   }
    661 
    662   ret->meth = group->meth;
    663 
    664   if (!ec_GFp_simple_point_init(ret)) {
    665     OPENSSL_free(ret);
    666     return NULL;
    667   }
    668 
    669   return ret;
    670 }
    671 
    672 void EC_POINT_free(EC_POINT *point) {
    673   if (!point) {
    674     return;
    675   }
    676 
    677   ec_GFp_simple_point_finish(point);
    678 
    679   OPENSSL_free(point);
    680 }
    681 
    682 void EC_POINT_clear_free(EC_POINT *point) {
    683   if (!point) {
    684     return;
    685   }
    686 
    687   ec_GFp_simple_point_clear_finish(point);
    688 
    689   OPENSSL_cleanse(point, sizeof *point);
    690   OPENSSL_free(point);
    691 }
    692 
    693 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
    694   if (dest->meth != src->meth) {
    695     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    696     return 0;
    697   }
    698   if (dest == src) {
    699     return 1;
    700   }
    701   return ec_GFp_simple_point_copy(dest, src);
    702 }
    703 
    704 EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
    705   EC_POINT *t;
    706   int r;
    707 
    708   if (a == NULL) {
    709     return NULL;
    710   }
    711 
    712   t = EC_POINT_new(group);
    713   if (t == NULL) {
    714     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    715     return NULL;
    716   }
    717   r = EC_POINT_copy(t, a);
    718   if (!r) {
    719     EC_POINT_free(t);
    720     return NULL;
    721   } else {
    722     return t;
    723   }
    724 }
    725 
    726 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
    727   if (group->meth != point->meth) {
    728     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    729     return 0;
    730   }
    731   return ec_GFp_simple_point_set_to_infinity(group, point);
    732 }
    733 
    734 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
    735   if (group->meth != point->meth) {
    736     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    737     return 0;
    738   }
    739   return ec_GFp_simple_is_at_infinity(group, point);
    740 }
    741 
    742 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
    743                          BN_CTX *ctx) {
    744   if (group->meth != point->meth) {
    745     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    746     return 0;
    747   }
    748   return ec_GFp_simple_is_on_curve(group, point, ctx);
    749 }
    750 
    751 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
    752                  BN_CTX *ctx) {
    753   if ((group->meth != a->meth) || (a->meth != b->meth)) {
    754     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    755     return -1;
    756   }
    757   return ec_GFp_simple_cmp(group, a, b, ctx);
    758 }
    759 
    760 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
    761   if (group->meth != point->meth) {
    762     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    763     return 0;
    764   }
    765   return ec_GFp_simple_make_affine(group, point, ctx);
    766 }
    767 
    768 int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
    769                           BN_CTX *ctx) {
    770   size_t i;
    771 
    772   for (i = 0; i < num; i++) {
    773     if (group->meth != points[i]->meth) {
    774       OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    775       return 0;
    776     }
    777   }
    778   return ec_GFp_simple_points_make_affine(group, num, points, ctx);
    779 }
    780 
    781 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
    782                                         const EC_POINT *point, BIGNUM *x,
    783                                         BIGNUM *y, BN_CTX *ctx) {
    784   if (group->meth->point_get_affine_coordinates == 0) {
    785     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    786     return 0;
    787   }
    788   if (group->meth != point->meth) {
    789     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    790     return 0;
    791   }
    792   return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
    793 }
    794 
    795 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
    796                                         const BIGNUM *x, const BIGNUM *y,
    797                                         BN_CTX *ctx) {
    798   if (group->meth != point->meth) {
    799     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    800     return 0;
    801   }
    802   if (!ec_GFp_simple_point_set_affine_coordinates(group, point, x, y, ctx)) {
    803     return 0;
    804   }
    805 
    806   if (!EC_POINT_is_on_curve(group, point, ctx)) {
    807     OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
    808     return 0;
    809   }
    810 
    811   return 1;
    812 }
    813 
    814 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
    815                  const EC_POINT *b, BN_CTX *ctx) {
    816   if ((group->meth != r->meth) || (r->meth != a->meth) ||
    817       (a->meth != b->meth)) {
    818     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    819     return 0;
    820   }
    821   return ec_GFp_simple_add(group, r, a, b, ctx);
    822 }
    823 
    824 
    825 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
    826                  BN_CTX *ctx) {
    827   if ((group->meth != r->meth) || (r->meth != a->meth)) {
    828     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    829     return 0;
    830   }
    831   return ec_GFp_simple_dbl(group, r, a, ctx);
    832 }
    833 
    834 
    835 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
    836   if (group->meth != a->meth) {
    837     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    838     return 0;
    839   }
    840   return ec_GFp_simple_invert(group, a, ctx);
    841 }
    842 
    843 int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
    844                  const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) {
    845   /* Previously, this function set |r| to the point at infinity if there was
    846    * nothing to multiply. But, nobody should be calling this function with
    847    * nothing to multiply in the first place. */
    848   if ((g_scalar == NULL && p_scalar == NULL) ||
    849       ((p == NULL) != (p_scalar == NULL)))  {
    850     OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
    851     return 0;
    852   }
    853 
    854   if (group->meth != r->meth ||
    855       (p != NULL && group->meth != p->meth)) {
    856     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    857     return 0;
    858   }
    859 
    860   return group->meth->mul(group, r, g_scalar, p, p_scalar, ctx);
    861 }
    862 
    863 int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
    864                                              const BIGNUM *x, const BIGNUM *y,
    865                                              const BIGNUM *z, BN_CTX *ctx) {
    866   if (group->meth != point->meth) {
    867     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    868     return 0;
    869   }
    870   return ec_GFp_simple_set_Jprojective_coordinates_GFp(group, point, x, y, z,
    871                                                        ctx);
    872 }
    873 
    874 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
    875 
    876 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) {
    877   return NULL;
    878 }
    879 
    880 int EC_METHOD_get_field_type(const EC_METHOD *meth) {
    881   return NID_X9_62_prime_field;
    882 }
    883 
    884 void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
    885                                         point_conversion_form_t form) {
    886   if (form != POINT_CONVERSION_UNCOMPRESSED) {
    887     abort();
    888   }
    889 }
    890