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