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