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 <string.h> 71 72 #include <openssl/bn.h> 73 #include <openssl/err.h> 74 #include <openssl/mem.h> 75 #include <openssl/obj.h> 76 77 #include "internal.h" 78 79 80 static const struct curve_data P224 = { 81 "NIST P-224", 82 28, 83 1, 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 struct curve_data P256 = { 111 "NIST P-256", 112 32, 113 1, 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 1, 143 {/* p */ 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, 0xFF, 148 /* a */ 149 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 150 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 151 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 153 /* b */ 154 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, 155 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, 156 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D, 157 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF, 158 /* x */ 159 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, 160 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, 161 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, 162 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7, 163 /* y */ 164 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf, 165 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, 166 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce, 167 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f, 168 /* order */ 169 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 170 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 171 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2, 172 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73}}; 173 174 static const struct curve_data P521 = { 175 "NIST P-521", 176 66, 177 1, 178 {/* p */ 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, 0xFF, 185 /* a */ 186 0x01, 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, 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, 0xFC, 192 /* b */ 193 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A, 194 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, 195 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19, 196 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, 197 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45, 198 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00, 199 /* x */ 200 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, 201 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, 202 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, 203 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, 204 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, 205 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66, 206 /* y */ 207 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 208 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 209 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 210 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 211 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 212 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50, 213 /* order */ 214 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 215 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 216 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86, 217 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, 218 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F, 219 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09}}; 220 221 const struct built_in_curve OPENSSL_built_in_curves[] = { 222 {NID_secp224r1, &P224, 0}, 223 { 224 NID_X9_62_prime256v1, &P256, 225 #if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) 226 EC_GFp_nistp256_method, 227 #else 228 0, 229 #endif 230 }, 231 {NID_secp384r1, &P384, 0}, 232 {NID_secp521r1, &P521, 0}, 233 {NID_undef, 0, 0}, 234 }; 235 236 EC_GROUP *ec_group_new(const EC_METHOD *meth) { 237 EC_GROUP *ret; 238 239 if (meth == NULL) { 240 OPENSSL_PUT_ERROR(EC, ec_group_new, EC_R_SLOT_FULL); 241 return NULL; 242 } 243 244 if (meth->group_init == 0) { 245 OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 246 return NULL; 247 } 248 249 ret = OPENSSL_malloc(sizeof(EC_GROUP)); 250 if (ret == NULL) { 251 OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_MALLOC_FAILURE); 252 return NULL; 253 } 254 memset(ret, 0, sizeof(EC_GROUP)); 255 256 ret->meth = meth; 257 BN_init(&ret->order); 258 BN_init(&ret->cofactor); 259 260 if (!meth->group_init(ret)) { 261 OPENSSL_free(ret); 262 return NULL; 263 } 264 265 return ret; 266 } 267 268 EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, 269 const BIGNUM *b, BN_CTX *ctx) { 270 const EC_METHOD *meth = EC_GFp_mont_method(); 271 EC_GROUP *ret; 272 273 ret = ec_group_new(meth); 274 if (ret == NULL) { 275 return NULL; 276 } 277 278 if (ret->meth->group_set_curve == 0) { 279 OPENSSL_PUT_ERROR(EC, EC_GROUP_new_curve_GFp, 280 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 281 return 0; 282 } 283 if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) { 284 EC_GROUP_free(ret); 285 return NULL; 286 } 287 return ret; 288 } 289 290 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, 291 const BIGNUM *order, const BIGNUM *cofactor) { 292 if (group->curve_name != NID_undef) { 293 /* |EC_GROUP_set_generator| should only be used with |EC_GROUP|s returned 294 * by |EC_GROUP_new_curve_GFp|. */ 295 return 0; 296 } 297 298 if (group->generator == NULL) { 299 group->generator = EC_POINT_new(group); 300 if (group->generator == NULL) { 301 return 0; 302 } 303 } 304 305 if (!EC_POINT_copy(group->generator, generator)) { 306 return 0; 307 } 308 309 if (order != NULL) { 310 if (!BN_copy(&group->order, order)) { 311 return 0; 312 } 313 } else { 314 BN_zero(&group->order); 315 } 316 317 if (cofactor != NULL) { 318 if (!BN_copy(&group->cofactor, cofactor)) { 319 return 0; 320 } 321 } else { 322 BN_zero(&group->cofactor); 323 } 324 325 return 1; 326 } 327 328 static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) { 329 EC_GROUP *group = NULL; 330 EC_POINT *P = NULL; 331 BN_CTX *ctx = NULL; 332 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = NULL; 333 int ok = 0; 334 unsigned param_len; 335 const EC_METHOD *meth; 336 const struct curve_data *data; 337 const uint8_t *params; 338 339 if ((ctx = BN_CTX_new()) == NULL) { 340 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_MALLOC_FAILURE); 341 goto err; 342 } 343 344 data = curve->data; 345 param_len = data->param_len; 346 params = data->data; 347 348 if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) || 349 !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) || 350 !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) { 351 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB); 352 goto err; 353 } 354 355 if (curve->method != 0) { 356 meth = curve->method(); 357 if (((group = ec_group_new(meth)) == NULL) || 358 (!(group->meth->group_set_curve(group, p, a, b, ctx)))) { 359 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB); 360 goto err; 361 } 362 } else { 363 if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { 364 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB); 365 goto err; 366 } 367 } 368 369 if ((P = EC_POINT_new(group)) == NULL) { 370 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB); 371 goto err; 372 } 373 374 if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) || 375 !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) { 376 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB); 377 goto err; 378 } 379 380 if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) { 381 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB); 382 goto err; 383 } 384 if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) || 385 !BN_set_word(x, (BN_ULONG)data->cofactor)) { 386 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB); 387 goto err; 388 } 389 390 group->generator = P; 391 P = NULL; 392 if (!BN_copy(&group->order, order) || 393 !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) { 394 OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB); 395 goto err; 396 } 397 398 ok = 1; 399 400 err: 401 if (!ok) { 402 EC_GROUP_free(group); 403 group = NULL; 404 } 405 EC_POINT_free(P); 406 BN_CTX_free(ctx); 407 BN_free(p); 408 BN_free(a); 409 BN_free(b); 410 BN_free(order); 411 BN_free(x); 412 BN_free(y); 413 return group; 414 } 415 416 EC_GROUP *EC_GROUP_new_by_curve_name(int nid) { 417 unsigned i; 418 const struct built_in_curve *curve; 419 EC_GROUP *ret = NULL; 420 421 for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) { 422 curve = &OPENSSL_built_in_curves[i]; 423 if (curve->nid == nid) { 424 ret = ec_group_new_from_data(curve); 425 break; 426 } 427 } 428 429 if (ret == NULL) { 430 OPENSSL_PUT_ERROR(EC, EC_GROUP_new_by_curve_name, EC_R_UNKNOWN_GROUP); 431 return NULL; 432 } 433 434 ret->curve_name = nid; 435 return ret; 436 } 437 438 void EC_GROUP_free(EC_GROUP *group) { 439 if (!group) { 440 return; 441 } 442 443 if (group->meth->group_finish != 0) { 444 group->meth->group_finish(group); 445 } 446 447 ec_pre_comp_free(group->pre_comp); 448 449 EC_POINT_free(group->generator); 450 BN_free(&group->order); 451 BN_free(&group->cofactor); 452 453 OPENSSL_free(group); 454 } 455 456 int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) { 457 if (dest->meth->group_copy == 0) { 458 OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 459 return 0; 460 } 461 if (dest->meth != src->meth) { 462 OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, EC_R_INCOMPATIBLE_OBJECTS); 463 return 0; 464 } 465 if (dest == src) { 466 return 1; 467 } 468 469 ec_pre_comp_free(dest->pre_comp); 470 dest->pre_comp = ec_pre_comp_dup(src->pre_comp); 471 472 if (src->generator != NULL) { 473 if (dest->generator == NULL) { 474 dest->generator = EC_POINT_new(dest); 475 if (dest->generator == NULL) { 476 return 0; 477 } 478 } 479 if (!EC_POINT_copy(dest->generator, src->generator)) { 480 return 0; 481 } 482 } else { 483 /* src->generator == NULL */ 484 if (dest->generator != NULL) { 485 EC_POINT_clear_free(dest->generator); 486 dest->generator = NULL; 487 } 488 } 489 490 if (!BN_copy(&dest->order, &src->order) || 491 !BN_copy(&dest->cofactor, &src->cofactor)) { 492 return 0; 493 } 494 495 dest->curve_name = src->curve_name; 496 497 return dest->meth->group_copy(dest, src); 498 } 499 500 EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) { 501 EC_GROUP *t = NULL; 502 int ok = 0; 503 504 if (a == NULL) { 505 return NULL; 506 } 507 508 t = ec_group_new(a->meth); 509 if (t == NULL) { 510 return NULL; 511 } 512 if (!ec_group_copy(t, a)) { 513 goto err; 514 } 515 516 ok = 1; 517 518 err: 519 if (!ok) { 520 EC_GROUP_free(t); 521 return NULL; 522 } else { 523 return t; 524 } 525 } 526 527 int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) { 528 return a->curve_name == NID_undef || 529 b->curve_name == NID_undef || 530 a->curve_name != b->curve_name; 531 } 532 533 const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) { 534 return group->generator; 535 } 536 537 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) { 538 if (!BN_copy(order, &group->order)) { 539 return 0; 540 } 541 542 return !BN_is_zero(order); 543 } 544 545 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, 546 BN_CTX *ctx) { 547 if (!BN_copy(cofactor, &group->cofactor)) { 548 return 0; 549 } 550 551 return !BN_is_zero(&group->cofactor); 552 } 553 554 int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a, 555 BIGNUM *out_b, BN_CTX *ctx) { 556 if (group->meth->group_get_curve == 0) { 557 OPENSSL_PUT_ERROR(EC, EC_GROUP_get_curve_GFp, 558 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 559 return 0; 560 } 561 return group->meth->group_get_curve(group, out_p, out_a, out_b, ctx); 562 } 563 564 int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; } 565 566 int EC_GROUP_get_degree(const EC_GROUP *group) { 567 if (group->meth->group_get_degree == 0) { 568 OPENSSL_PUT_ERROR(EC, EC_GROUP_get_degree, 569 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 570 return 0; 571 } 572 return group->meth->group_get_degree(group); 573 } 574 575 int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) { 576 if (group->meth->mul == 0) { 577 /* use default */ 578 return ec_wNAF_precompute_mult(group, ctx); 579 } 580 581 if (group->meth->precompute_mult != 0) { 582 return group->meth->precompute_mult(group, ctx); 583 } 584 585 return 1; /* nothing to do, so report success */ 586 } 587 588 int EC_GROUP_have_precompute_mult(const EC_GROUP *group) { 589 if (group->meth->mul == 0) { 590 /* use default */ 591 return ec_wNAF_have_precompute_mult(group); 592 } 593 594 if (group->meth->have_precompute_mult != 0) { 595 return group->meth->have_precompute_mult(group); 596 } 597 598 return 0; /* cannot tell whether precomputation has been performed */ 599 } 600 601 EC_POINT *EC_POINT_new(const EC_GROUP *group) { 602 EC_POINT *ret; 603 604 if (group == NULL) { 605 OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_PASSED_NULL_PARAMETER); 606 return NULL; 607 } 608 if (group->meth->point_init == 0) { 609 OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 610 return NULL; 611 } 612 613 ret = OPENSSL_malloc(sizeof *ret); 614 if (ret == NULL) { 615 OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_MALLOC_FAILURE); 616 return NULL; 617 } 618 619 ret->meth = group->meth; 620 621 if (!ret->meth->point_init(ret)) { 622 OPENSSL_free(ret); 623 return NULL; 624 } 625 626 return ret; 627 } 628 629 void EC_POINT_free(EC_POINT *point) { 630 if (!point) { 631 return; 632 } 633 634 if (point->meth->point_finish != 0) { 635 point->meth->point_finish(point); 636 } 637 OPENSSL_free(point); 638 } 639 640 void EC_POINT_clear_free(EC_POINT *point) { 641 if (!point) { 642 return; 643 } 644 645 if (point->meth->point_clear_finish != 0) { 646 point->meth->point_clear_finish(point); 647 } else if (point->meth->point_finish != 0) { 648 point->meth->point_finish(point); 649 } 650 OPENSSL_cleanse(point, sizeof *point); 651 OPENSSL_free(point); 652 } 653 654 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) { 655 if (dest->meth->point_copy == 0) { 656 OPENSSL_PUT_ERROR(EC, EC_POINT_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 657 return 0; 658 } 659 if (dest->meth != src->meth) { 660 OPENSSL_PUT_ERROR(EC, EC_POINT_copy, EC_R_INCOMPATIBLE_OBJECTS); 661 return 0; 662 } 663 if (dest == src) { 664 return 1; 665 } 666 return dest->meth->point_copy(dest, src); 667 } 668 669 EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) { 670 EC_POINT *t; 671 int r; 672 673 if (a == NULL) { 674 return NULL; 675 } 676 677 t = EC_POINT_new(group); 678 if (t == NULL) { 679 OPENSSL_PUT_ERROR(EC, EC_POINT_dup, ERR_R_MALLOC_FAILURE); 680 return NULL; 681 } 682 r = EC_POINT_copy(t, a); 683 if (!r) { 684 EC_POINT_free(t); 685 return NULL; 686 } else { 687 return t; 688 } 689 } 690 691 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) { 692 if (group->meth->point_set_to_infinity == 0) { 693 OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity, 694 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 695 return 0; 696 } 697 if (group->meth != point->meth) { 698 OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity, EC_R_INCOMPATIBLE_OBJECTS); 699 return 0; 700 } 701 return group->meth->point_set_to_infinity(group, point); 702 } 703 704 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) { 705 if (group->meth->is_at_infinity == 0) { 706 OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity, 707 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 708 return 0; 709 } 710 if (group->meth != point->meth) { 711 OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity, EC_R_INCOMPATIBLE_OBJECTS); 712 return 0; 713 } 714 return group->meth->is_at_infinity(group, point); 715 } 716 717 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, 718 BN_CTX *ctx) { 719 if (group->meth->is_on_curve == 0) { 720 OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve, 721 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 722 return 0; 723 } 724 if (group->meth != point->meth) { 725 OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve, EC_R_INCOMPATIBLE_OBJECTS); 726 return 0; 727 } 728 return group->meth->is_on_curve(group, point, ctx); 729 } 730 731 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, 732 BN_CTX *ctx) { 733 if (group->meth->point_cmp == 0) { 734 OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 735 return -1; 736 } 737 if ((group->meth != a->meth) || (a->meth != b->meth)) { 738 OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, EC_R_INCOMPATIBLE_OBJECTS); 739 return -1; 740 } 741 return group->meth->point_cmp(group, a, b, ctx); 742 } 743 744 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) { 745 if (group->meth->make_affine == 0) { 746 OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine, 747 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 748 return 0; 749 } 750 if (group->meth != point->meth) { 751 OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine, EC_R_INCOMPATIBLE_OBJECTS); 752 return 0; 753 } 754 return group->meth->make_affine(group, point, ctx); 755 } 756 757 int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], 758 BN_CTX *ctx) { 759 size_t i; 760 761 if (group->meth->points_make_affine == 0) { 762 OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine, 763 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 764 return 0; 765 } 766 for (i = 0; i < num; i++) { 767 if (group->meth != points[i]->meth) { 768 OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine, EC_R_INCOMPATIBLE_OBJECTS); 769 return 0; 770 } 771 } 772 return group->meth->points_make_affine(group, num, points, ctx); 773 } 774 775 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, 776 const EC_POINT *point, BIGNUM *x, 777 BIGNUM *y, BN_CTX *ctx) { 778 if (group->meth->point_get_affine_coordinates == 0) { 779 OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp, 780 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 781 return 0; 782 } 783 if (group->meth != point->meth) { 784 OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp, 785 EC_R_INCOMPATIBLE_OBJECTS); 786 return 0; 787 } 788 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); 789 } 790 791 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, 792 const BIGNUM *x, const BIGNUM *y, 793 BN_CTX *ctx) { 794 if (group->meth->point_set_affine_coordinates == 0) { 795 OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp, 796 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 797 return 0; 798 } 799 if (group->meth != point->meth) { 800 OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp, 801 EC_R_INCOMPATIBLE_OBJECTS); 802 return 0; 803 } 804 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); 805 } 806 807 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 808 const EC_POINT *b, BN_CTX *ctx) { 809 if (group->meth->add == 0) { 810 OPENSSL_PUT_ERROR(EC, EC_POINT_add, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 811 return 0; 812 } 813 if ((group->meth != r->meth) || (r->meth != a->meth) || 814 (a->meth != b->meth)) { 815 OPENSSL_PUT_ERROR(EC, EC_POINT_add, EC_R_INCOMPATIBLE_OBJECTS); 816 return 0; 817 } 818 return group->meth->add(group, r, a, b, ctx); 819 } 820 821 822 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 823 BN_CTX *ctx) { 824 if (group->meth->dbl == 0) { 825 OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 826 return 0; 827 } 828 if ((group->meth != r->meth) || (r->meth != a->meth)) { 829 OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, EC_R_INCOMPATIBLE_OBJECTS); 830 return 0; 831 } 832 return group->meth->dbl(group, r, a, ctx); 833 } 834 835 836 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) { 837 if (group->meth->invert == 0) { 838 OPENSSL_PUT_ERROR(EC, EC_POINT_invert, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 839 return 0; 840 } 841 if (group->meth != a->meth) { 842 OPENSSL_PUT_ERROR(EC, EC_POINT_invert, EC_R_INCOMPATIBLE_OBJECTS); 843 return 0; 844 } 845 return group->meth->invert(group, a, ctx); 846 } 847 848 int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, 849 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) { 850 /* just a convenient interface to EC_POINTs_mul() */ 851 852 const EC_POINT *points[1]; 853 const BIGNUM *scalars[1]; 854 855 points[0] = point; 856 scalars[0] = p_scalar; 857 858 return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL), 859 points, scalars, ctx); 860 } 861 862 int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 863 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], 864 BN_CTX *ctx) { 865 if (group->meth->mul == 0) { 866 /* use default. Warning, not constant-time. */ 867 return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); 868 } 869 870 return group->meth->mul(group, r, scalar, num, points, scalars, ctx); 871 } 872 873 int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, 874 const BIGNUM *x, const BIGNUM *y, 875 const BIGNUM *z, BN_CTX *ctx) { 876 if (group->meth->point_set_Jprojective_coordinates_GFp == 0) { 877 OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp, 878 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 879 return 0; 880 } 881 if (group->meth != point->meth) { 882 OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp, 883 EC_R_INCOMPATIBLE_OBJECTS); 884 return 0; 885 } 886 return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, 887 z, ctx); 888 } 889 890 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {} 891 892 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) { 893 return NULL; 894 } 895 896 int EC_METHOD_get_field_type(const EC_METHOD *meth) { 897 return NID_X9_62_prime_field; 898 } 899 900 void EC_GROUP_set_point_conversion_form(EC_GROUP *group, 901 point_conversion_form_t form) { 902 if (form != POINT_CONVERSION_UNCOMPRESSED) { 903 abort(); 904 } 905 } 906