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