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 
     81 
     82 static const struct curve_data P224 = {
     83     "NIST P-224",
     84     28,
     85     {/* p */
     86      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     87      0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     88      0x00, 0x00, 0x00, 0x01,
     89      /* a */
     90      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     91      0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     92      0xFF, 0xFF, 0xFF, 0xFE,
     93      /* b */
     94      0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
     95      0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
     96      0x23, 0x55, 0xFF, 0xB4,
     97      /* x */
     98      0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
     99      0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
    100      0x11, 0x5C, 0x1D, 0x21,
    101      /* y */
    102      0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
    103      0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
    104      0x85, 0x00, 0x7e, 0x34,
    105      /* order */
    106      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    107      0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
    108      0x5C, 0x5C, 0x2A, 0x3D,
    109     }};
    110 
    111 static const struct curve_data P256 = {
    112     "NIST P-256",
    113     32,
    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     {/* p */
    143      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    144      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    145      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
    146      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    147      /* a */
    148      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    149      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    150      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
    151      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
    152      /* b */
    153      0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
    154      0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
    155      0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
    156      0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
    157      /* x */
    158      0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
    159      0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
    160      0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
    161      0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
    162      /* y */
    163      0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf,
    164      0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
    165      0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce,
    166      0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
    167      /* order */
    168      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    169      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    170      0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
    171      0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73}};
    172 
    173 static const struct curve_data P521 = {
    174     "NIST P-521",
    175     66,
    176     {/* p */
    177      0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    178      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    179      0xFF, 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,
    183      /* a */
    184      0x01, 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, 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, 0xFC,
    190      /* b */
    191      0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
    192      0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
    193      0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
    194      0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
    195      0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
    196      0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
    197      /* x */
    198      0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
    199      0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
    200      0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
    201      0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
    202      0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
    203      0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
    204      /* y */
    205      0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
    206      0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
    207      0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
    208      0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
    209      0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
    210      0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
    211      /* order */
    212      0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    213      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    214      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
    215      0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
    216      0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
    217      0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09}};
    218 
    219 /* MSan appears to have a bug that causes code to be miscompiled in opt mode.
    220  * While that is being looked at, don't run the uint128_t code under MSan. */
    221 #if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \
    222     !defined(MEMORY_SANITIZER)
    223 #define BORINGSSL_USE_INT128_CODE
    224 #endif
    225 
    226 const struct built_in_curve OPENSSL_built_in_curves[] = {
    227     {
    228         NID_secp521r1,
    229         /* 1.3.132.0.35 */
    230         {0x2b, 0x81, 0x04, 0x00, 0x23}, 5,
    231         &P521,
    232         &EC_GFp_mont_method,
    233       },
    234     {
    235         NID_secp384r1,
    236         /* 1.3.132.0.34 */
    237         {0x2b, 0x81, 0x04, 0x00, 0x22}, 5,
    238         &P384,
    239         &EC_GFp_mont_method,
    240     },
    241     {
    242         NID_X9_62_prime256v1,
    243         /* 1.2.840.10045.3.1.7 */
    244         {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}, 8,
    245         &P256,
    246 #if defined(BORINGSSL_USE_INT128_CODE)
    247 #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
    248     !defined(OPENSSL_SMALL)
    249         &EC_GFp_nistz256_method,
    250 #else
    251         &EC_GFp_nistp256_method,
    252 #endif
    253 #else
    254         &EC_GFp_mont_method,
    255 #endif
    256     },
    257     {
    258         NID_secp224r1,
    259         /* 1.3.132.0.33 */
    260         {0x2b, 0x81, 0x04, 0x00, 0x21}, 5,
    261         &P224,
    262 #if defined(BORINGSSL_USE_INT128_CODE) && !defined(OPENSSL_SMALL)
    263         &EC_GFp_nistp224_method,
    264 #else
    265         &EC_GFp_mont_method,
    266 #endif
    267     },
    268     {NID_undef, {0}, 0, NULL, NULL},
    269 };
    270 
    271 /* built_in_curve_scalar_field_monts contains Montgomery contexts for
    272  * performing inversions in the scalar fields of each of the built-in
    273  * curves. It's protected by |built_in_curve_scalar_field_monts_once|. */
    274 static const BN_MONT_CTX **built_in_curve_scalar_field_monts;
    275 
    276 static CRYPTO_once_t built_in_curve_scalar_field_monts_once;
    277 
    278 static void built_in_curve_scalar_field_monts_init(void) {
    279   unsigned num_built_in_curves;
    280   for (num_built_in_curves = 0;; num_built_in_curves++) {
    281     if (OPENSSL_built_in_curves[num_built_in_curves].nid == NID_undef) {
    282       break;
    283     }
    284   }
    285 
    286   assert(0 < num_built_in_curves);
    287 
    288   built_in_curve_scalar_field_monts =
    289       OPENSSL_malloc(sizeof(BN_MONT_CTX *) * num_built_in_curves);
    290   if (built_in_curve_scalar_field_monts == NULL) {
    291     return;
    292   }
    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   unsigned i;
    304   for (i = 0; i < num_built_in_curves; i++) {
    305     const struct curve_data *curve = OPENSSL_built_in_curves[i].data;
    306     const unsigned param_len = curve->param_len;
    307     const uint8_t *params = curve->data;
    308 
    309     mont_ctx = BN_MONT_CTX_new();
    310     if (mont_ctx == NULL) {
    311       goto err;
    312     }
    313 
    314     if (!BN_bin2bn(params + 5 * param_len, param_len, order) ||
    315         !BN_MONT_CTX_set(mont_ctx, order, bn_ctx)) {
    316       goto err;
    317     }
    318 
    319     built_in_curve_scalar_field_monts[i] = mont_ctx;
    320     mont_ctx = NULL;
    321   }
    322 
    323   goto out;
    324 
    325 err:
    326   BN_MONT_CTX_free(mont_ctx);
    327   OPENSSL_free((BN_MONT_CTX**) built_in_curve_scalar_field_monts);
    328   built_in_curve_scalar_field_monts = NULL;
    329 
    330 out:
    331   BN_free(order);
    332   BN_CTX_free(bn_ctx);
    333 }
    334 
    335 EC_GROUP *ec_group_new(const EC_METHOD *meth) {
    336   EC_GROUP *ret;
    337 
    338   if (meth == NULL) {
    339     OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL);
    340     return NULL;
    341   }
    342 
    343   if (meth->group_init == 0) {
    344     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    345     return NULL;
    346   }
    347 
    348   ret = OPENSSL_malloc(sizeof(EC_GROUP));
    349   if (ret == NULL) {
    350     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    351     return NULL;
    352   }
    353   OPENSSL_memset(ret, 0, sizeof(EC_GROUP));
    354 
    355   ret->meth = meth;
    356   BN_init(&ret->order);
    357 
    358   if (!meth->group_init(ret)) {
    359     OPENSSL_free(ret);
    360     return NULL;
    361   }
    362 
    363   return ret;
    364 }
    365 
    366 EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
    367                                  const BIGNUM *b, BN_CTX *ctx) {
    368   EC_GROUP *ret = ec_group_new(&EC_GFp_mont_method);
    369   if (ret == NULL) {
    370     return NULL;
    371   }
    372 
    373   if (ret->meth->group_set_curve == 0) {
    374     OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    375     return 0;
    376   }
    377   if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) {
    378     EC_GROUP_free(ret);
    379     return NULL;
    380   }
    381   return ret;
    382 }
    383 
    384 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
    385                            const BIGNUM *order, const BIGNUM *cofactor) {
    386   if (group->curve_name != NID_undef || group->generator != NULL) {
    387     /* |EC_GROUP_set_generator| may only be used with |EC_GROUP|s returned by
    388      * |EC_GROUP_new_curve_GFp| and may only used once on each group. */
    389     return 0;
    390   }
    391 
    392   /* Require a cofactor of one for custom curves, which implies prime order. */
    393   if (!BN_is_one(cofactor)) {
    394     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COFACTOR);
    395     return 0;
    396   }
    397 
    398   group->generator = EC_POINT_new(group);
    399   return group->generator != NULL &&
    400          EC_POINT_copy(group->generator, generator) &&
    401          BN_copy(&group->order, order);
    402 }
    403 
    404 static EC_GROUP *ec_group_new_from_data(unsigned built_in_index) {
    405   const struct built_in_curve *curve = &OPENSSL_built_in_curves[built_in_index];
    406   EC_GROUP *group = NULL;
    407   EC_POINT *P = NULL;
    408   BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
    409   int ok = 0;
    410 
    411   BN_CTX *ctx = BN_CTX_new();
    412   if (ctx == NULL) {
    413     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    414     goto err;
    415   }
    416 
    417   const struct curve_data *data = curve->data;
    418   const unsigned param_len = data->param_len;
    419   const uint8_t *params = data->data;
    420 
    421   if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
    422       !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
    423       !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
    424     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    425     goto err;
    426   }
    427 
    428   group = ec_group_new(curve->method);
    429   if (group == NULL ||
    430       !group->meth->group_set_curve(group, p, a, b, ctx)) {
    431     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    432     goto err;
    433   }
    434 
    435   if ((P = EC_POINT_new(group)) == NULL) {
    436     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    437     goto err;
    438   }
    439 
    440   if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
    441       !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
    442     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    443     goto err;
    444   }
    445 
    446   if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
    447     OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
    448     goto err;
    449   }
    450   if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order)) {
    451     OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    452     goto err;
    453   }
    454 
    455   CRYPTO_once(&built_in_curve_scalar_field_monts_once,
    456               built_in_curve_scalar_field_monts_init);
    457   if (built_in_curve_scalar_field_monts != NULL) {
    458     group->mont_data = built_in_curve_scalar_field_monts[built_in_index];
    459   }
    460 
    461   group->generator = P;
    462   P = NULL;
    463   ok = 1;
    464 
    465 err:
    466   if (!ok) {
    467     EC_GROUP_free(group);
    468     group = NULL;
    469   }
    470   EC_POINT_free(P);
    471   BN_CTX_free(ctx);
    472   BN_free(p);
    473   BN_free(a);
    474   BN_free(b);
    475   BN_free(x);
    476   BN_free(y);
    477   return group;
    478 }
    479 
    480 EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
    481   unsigned i;
    482   const struct built_in_curve *curve;
    483   EC_GROUP *ret = NULL;
    484 
    485   for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
    486     curve = &OPENSSL_built_in_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, EC_POINT *point,
    804                                              const BIGNUM *x, const BIGNUM *y,
    805                                              const BIGNUM *z, BN_CTX *ctx) {
    806   if (group->meth != point->meth) {
    807     OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
    808     return 0;
    809   }
    810   return ec_GFp_simple_set_Jprojective_coordinates_GFp(group, point, x, y, z,
    811                                                        ctx);
    812 }
    813 
    814 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
    815 
    816 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) {
    817   return NULL;
    818 }
    819 
    820 int EC_METHOD_get_field_type(const EC_METHOD *meth) {
    821   return NID_X9_62_prime_field;
    822 }
    823 
    824 void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
    825                                         point_conversion_form_t form) {
    826   if (form != POINT_CONVERSION_UNCOMPRESSED) {
    827     abort();
    828   }
    829 }
    830 
    831 size_t EC_get_builtin_curves(EC_builtin_curve *out_curves,
    832                              size_t max_num_curves) {
    833   unsigned num_built_in_curves;
    834   for (num_built_in_curves = 0;; num_built_in_curves++) {
    835     if (OPENSSL_built_in_curves[num_built_in_curves].nid == NID_undef) {
    836       break;
    837     }
    838   }
    839 
    840   unsigned i;
    841   for (i = 0; i < max_num_curves && i < num_built_in_curves; i++) {
    842     out_curves[i].comment = OPENSSL_built_in_curves[i].data->comment;
    843     out_curves[i].nid = OPENSSL_built_in_curves[i].nid;
    844   }
    845 
    846   return num_built_in_curves;
    847 }
    848