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