ec.c revision 03bcf618b7ed811b305845461fbb5497dfe55ac3
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@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@cryptsoft.com). This product includes software written by Tim 52 * Hudson (tjh@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 80static 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 110static 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 139static 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 174static 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 221const struct built_in_curve OPENSSL_built_in_curves[] = { 222 {NID_secp224r1, &P224, 0}, 223 { 224 NID_X9_62_prime256v1, &P256, 225 /* MSAN appears to have a bug that causes this P-256 code to be miscompiled 226 * in opt mode. While that is being looked at, don't run the uint128_t 227 * P-256 code under MSAN for now. */ 228#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \ 229 !defined(MEMORY_SANITIZER) 230 EC_GFp_nistp256_method, 231#else 232 0, 233#endif 234 }, 235 {NID_secp384r1, &P384, 0}, 236 {NID_secp521r1, &P521, 0}, 237 {NID_undef, 0, 0}, 238}; 239 240EC_GROUP *ec_group_new(const EC_METHOD *meth) { 241 EC_GROUP *ret; 242 243 if (meth == NULL) { 244 OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL); 245 return NULL; 246 } 247 248 if (meth->group_init == 0) { 249 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 250 return NULL; 251 } 252 253 ret = OPENSSL_malloc(sizeof(EC_GROUP)); 254 if (ret == NULL) { 255 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); 256 return NULL; 257 } 258 memset(ret, 0, sizeof(EC_GROUP)); 259 260 ret->meth = meth; 261 BN_init(&ret->order); 262 BN_init(&ret->cofactor); 263 264 if (!meth->group_init(ret)) { 265 OPENSSL_free(ret); 266 return NULL; 267 } 268 269 return ret; 270} 271 272EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, 273 const BIGNUM *b, BN_CTX *ctx) { 274 const EC_METHOD *meth = EC_GFp_mont_method(); 275 EC_GROUP *ret; 276 277 ret = ec_group_new(meth); 278 if (ret == NULL) { 279 return NULL; 280 } 281 282 if (ret->meth->group_set_curve == 0) { 283 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 284 return 0; 285 } 286 if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) { 287 EC_GROUP_free(ret); 288 return NULL; 289 } 290 return ret; 291} 292 293int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, 294 const BIGNUM *order, const BIGNUM *cofactor) { 295 if (group->curve_name != NID_undef) { 296 /* |EC_GROUP_set_generator| should only be used with |EC_GROUP|s returned 297 * by |EC_GROUP_new_curve_GFp|. */ 298 return 0; 299 } 300 301 if (group->generator == NULL) { 302 group->generator = EC_POINT_new(group); 303 if (group->generator == NULL) { 304 return 0; 305 } 306 } 307 308 if (!EC_POINT_copy(group->generator, generator)) { 309 return 0; 310 } 311 312 if (order != NULL) { 313 if (!BN_copy(&group->order, order)) { 314 return 0; 315 } 316 } else { 317 BN_zero(&group->order); 318 } 319 320 if (cofactor != NULL) { 321 if (!BN_copy(&group->cofactor, cofactor)) { 322 return 0; 323 } 324 } else { 325 BN_zero(&group->cofactor); 326 } 327 328 return 1; 329} 330 331static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) { 332 EC_GROUP *group = NULL; 333 EC_POINT *P = NULL; 334 BN_CTX *ctx = NULL; 335 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL; 336 int ok = 0; 337 unsigned param_len; 338 const EC_METHOD *meth; 339 const struct curve_data *data; 340 const uint8_t *params; 341 342 if ((ctx = BN_CTX_new()) == NULL) { 343 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); 344 goto err; 345 } 346 347 data = curve->data; 348 param_len = data->param_len; 349 params = data->data; 350 351 if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) || 352 !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) || 353 !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) { 354 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); 355 goto err; 356 } 357 358 if (curve->method != 0) { 359 meth = curve->method(); 360 if (((group = ec_group_new(meth)) == NULL) || 361 (!(group->meth->group_set_curve(group, p, a, b, ctx)))) { 362 OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); 363 goto err; 364 } 365 } else { 366 if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { 367 OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); 368 goto err; 369 } 370 } 371 372 if ((P = EC_POINT_new(group)) == NULL) { 373 OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); 374 goto err; 375 } 376 377 if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) || 378 !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) { 379 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); 380 goto err; 381 } 382 383 if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) { 384 OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); 385 goto err; 386 } 387 if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order) || 388 !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) { 389 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); 390 goto err; 391 } 392 393 group->generator = P; 394 P = NULL; 395 ok = 1; 396 397err: 398 if (!ok) { 399 EC_GROUP_free(group); 400 group = NULL; 401 } 402 EC_POINT_free(P); 403 BN_CTX_free(ctx); 404 BN_free(p); 405 BN_free(a); 406 BN_free(b); 407 BN_free(x); 408 BN_free(y); 409 return group; 410} 411 412EC_GROUP *EC_GROUP_new_by_curve_name(int nid) { 413 unsigned i; 414 const struct built_in_curve *curve; 415 EC_GROUP *ret = NULL; 416 417 for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) { 418 curve = &OPENSSL_built_in_curves[i]; 419 if (curve->nid == nid) { 420 ret = ec_group_new_from_data(curve); 421 break; 422 } 423 } 424 425 if (ret == NULL) { 426 OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); 427 return NULL; 428 } 429 430 ret->curve_name = nid; 431 return ret; 432} 433 434void EC_GROUP_free(EC_GROUP *group) { 435 if (!group) { 436 return; 437 } 438 439 if (group->meth->group_finish != 0) { 440 group->meth->group_finish(group); 441 } 442 443 ec_pre_comp_free(group->pre_comp); 444 445 EC_POINT_free(group->generator); 446 BN_free(&group->order); 447 BN_free(&group->cofactor); 448 449 OPENSSL_free(group); 450} 451 452int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) { 453 if (dest->meth->group_copy == 0) { 454 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 455 return 0; 456 } 457 if (dest->meth != src->meth) { 458 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 459 return 0; 460 } 461 if (dest == src) { 462 return 1; 463 } 464 465 ec_pre_comp_free(dest->pre_comp); 466 dest->pre_comp = ec_pre_comp_dup(src->pre_comp); 467 468 if (src->generator != NULL) { 469 if (dest->generator == NULL) { 470 dest->generator = EC_POINT_new(dest); 471 if (dest->generator == NULL) { 472 return 0; 473 } 474 } 475 if (!EC_POINT_copy(dest->generator, src->generator)) { 476 return 0; 477 } 478 } else { 479 /* src->generator == NULL */ 480 if (dest->generator != NULL) { 481 EC_POINT_clear_free(dest->generator); 482 dest->generator = NULL; 483 } 484 } 485 486 if (!BN_copy(&dest->order, &src->order) || 487 !BN_copy(&dest->cofactor, &src->cofactor)) { 488 return 0; 489 } 490 491 dest->curve_name = src->curve_name; 492 493 return dest->meth->group_copy(dest, src); 494} 495 496EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) { 497 EC_GROUP *t = NULL; 498 int ok = 0; 499 500 if (a == NULL) { 501 return NULL; 502 } 503 504 t = ec_group_new(a->meth); 505 if (t == NULL) { 506 return NULL; 507 } 508 if (!ec_group_copy(t, a)) { 509 goto err; 510 } 511 512 ok = 1; 513 514err: 515 if (!ok) { 516 EC_GROUP_free(t); 517 return NULL; 518 } else { 519 return t; 520 } 521} 522 523int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) { 524 return a->curve_name == NID_undef || 525 b->curve_name == NID_undef || 526 a->curve_name != b->curve_name; 527} 528 529const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) { 530 return group->generator; 531} 532 533int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) { 534 if (!BN_copy(order, &group->order)) { 535 return 0; 536 } 537 538 return !BN_is_zero(order); 539} 540 541int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, 542 BN_CTX *ctx) { 543 if (!BN_copy(cofactor, &group->cofactor)) { 544 return 0; 545 } 546 547 return !BN_is_zero(&group->cofactor); 548} 549 550int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a, 551 BIGNUM *out_b, BN_CTX *ctx) { 552 if (group->meth->group_get_curve == 0) { 553 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 554 return 0; 555 } 556 return group->meth->group_get_curve(group, out_p, out_a, out_b, ctx); 557} 558 559int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; } 560 561int EC_GROUP_get_degree(const EC_GROUP *group) { 562 if (group->meth->group_get_degree == 0) { 563 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 564 return 0; 565 } 566 return group->meth->group_get_degree(group); 567} 568 569int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) { 570 if (group->meth->mul == 0) { 571 /* use default */ 572 return ec_wNAF_precompute_mult(group, ctx); 573 } 574 575 if (group->meth->precompute_mult != 0) { 576 return group->meth->precompute_mult(group, ctx); 577 } 578 579 return 1; /* nothing to do, so report success */ 580} 581 582int EC_GROUP_have_precompute_mult(const EC_GROUP *group) { 583 if (group->meth->mul == 0) { 584 /* use default */ 585 return ec_wNAF_have_precompute_mult(group); 586 } 587 588 if (group->meth->have_precompute_mult != 0) { 589 return group->meth->have_precompute_mult(group); 590 } 591 592 return 0; /* cannot tell whether precomputation has been performed */ 593} 594 595EC_POINT *EC_POINT_new(const EC_GROUP *group) { 596 EC_POINT *ret; 597 598 if (group == NULL) { 599 OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); 600 return NULL; 601 } 602 if (group->meth->point_init == 0) { 603 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 604 return NULL; 605 } 606 607 ret = OPENSSL_malloc(sizeof *ret); 608 if (ret == NULL) { 609 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); 610 return NULL; 611 } 612 613 ret->meth = group->meth; 614 615 if (!ret->meth->point_init(ret)) { 616 OPENSSL_free(ret); 617 return NULL; 618 } 619 620 return ret; 621} 622 623void EC_POINT_free(EC_POINT *point) { 624 if (!point) { 625 return; 626 } 627 628 if (point->meth->point_finish != 0) { 629 point->meth->point_finish(point); 630 } 631 OPENSSL_free(point); 632} 633 634void EC_POINT_clear_free(EC_POINT *point) { 635 if (!point) { 636 return; 637 } 638 639 if (point->meth->point_clear_finish != 0) { 640 point->meth->point_clear_finish(point); 641 } else if (point->meth->point_finish != 0) { 642 point->meth->point_finish(point); 643 } 644 OPENSSL_cleanse(point, sizeof *point); 645 OPENSSL_free(point); 646} 647 648int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) { 649 if (dest->meth->point_copy == 0) { 650 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 651 return 0; 652 } 653 if (dest->meth != src->meth) { 654 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 655 return 0; 656 } 657 if (dest == src) { 658 return 1; 659 } 660 return dest->meth->point_copy(dest, src); 661} 662 663EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) { 664 EC_POINT *t; 665 int r; 666 667 if (a == NULL) { 668 return NULL; 669 } 670 671 t = EC_POINT_new(group); 672 if (t == NULL) { 673 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); 674 return NULL; 675 } 676 r = EC_POINT_copy(t, a); 677 if (!r) { 678 EC_POINT_free(t); 679 return NULL; 680 } else { 681 return t; 682 } 683} 684 685int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) { 686 if (group->meth->point_set_to_infinity == 0) { 687 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 688 return 0; 689 } 690 if (group->meth != point->meth) { 691 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 692 return 0; 693 } 694 return group->meth->point_set_to_infinity(group, point); 695} 696 697int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) { 698 if (group->meth->is_at_infinity == 0) { 699 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 700 return 0; 701 } 702 if (group->meth != point->meth) { 703 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 704 return 0; 705 } 706 return group->meth->is_at_infinity(group, point); 707} 708 709int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, 710 BN_CTX *ctx) { 711 if (group->meth->is_on_curve == 0) { 712 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 713 return 0; 714 } 715 if (group->meth != point->meth) { 716 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 717 return 0; 718 } 719 return group->meth->is_on_curve(group, point, ctx); 720} 721 722int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, 723 BN_CTX *ctx) { 724 if (group->meth->point_cmp == 0) { 725 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 726 return -1; 727 } 728 if ((group->meth != a->meth) || (a->meth != b->meth)) { 729 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 730 return -1; 731 } 732 return group->meth->point_cmp(group, a, b, ctx); 733} 734 735int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) { 736 if (group->meth->make_affine == 0) { 737 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 738 return 0; 739 } 740 if (group->meth != point->meth) { 741 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 742 return 0; 743 } 744 return group->meth->make_affine(group, point, ctx); 745} 746 747int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], 748 BN_CTX *ctx) { 749 size_t i; 750 751 if (group->meth->points_make_affine == 0) { 752 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 753 return 0; 754 } 755 for (i = 0; i < num; i++) { 756 if (group->meth != points[i]->meth) { 757 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 758 return 0; 759 } 760 } 761 return group->meth->points_make_affine(group, num, points, ctx); 762} 763 764int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, 765 const EC_POINT *point, BIGNUM *x, 766 BIGNUM *y, BN_CTX *ctx) { 767 if (group->meth->point_get_affine_coordinates == 0) { 768 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 769 return 0; 770 } 771 if (group->meth != point->meth) { 772 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 773 return 0; 774 } 775 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); 776} 777 778int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, 779 const BIGNUM *x, const BIGNUM *y, 780 BN_CTX *ctx) { 781 if (group->meth->point_set_affine_coordinates == 0) { 782 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 783 return 0; 784 } 785 if (group->meth != point->meth) { 786 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 787 return 0; 788 } 789 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); 790} 791 792int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 793 const EC_POINT *b, BN_CTX *ctx) { 794 if (group->meth->add == 0) { 795 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 796 return 0; 797 } 798 if ((group->meth != r->meth) || (r->meth != a->meth) || 799 (a->meth != b->meth)) { 800 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 801 return 0; 802 } 803 return group->meth->add(group, r, a, b, ctx); 804} 805 806 807int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 808 BN_CTX *ctx) { 809 if (group->meth->dbl == 0) { 810 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 811 return 0; 812 } 813 if ((group->meth != r->meth) || (r->meth != a->meth)) { 814 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 815 return 0; 816 } 817 return group->meth->dbl(group, r, a, ctx); 818} 819 820 821int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) { 822 if (group->meth->invert == 0) { 823 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 824 return 0; 825 } 826 if (group->meth != a->meth) { 827 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 828 return 0; 829 } 830 return group->meth->invert(group, a, ctx); 831} 832 833int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, 834 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) { 835 /* just a convenient interface to EC_POINTs_mul() */ 836 837 const EC_POINT *points[1]; 838 const BIGNUM *scalars[1]; 839 840 points[0] = point; 841 scalars[0] = p_scalar; 842 843 return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL), 844 points, scalars, ctx); 845} 846 847int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 848 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], 849 BN_CTX *ctx) { 850 if (group->meth->mul == 0) { 851 /* use default. Warning, not constant-time. */ 852 return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); 853 } 854 855 return group->meth->mul(group, r, scalar, num, points, scalars, ctx); 856} 857 858int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, 859 const BIGNUM *x, const BIGNUM *y, 860 const BIGNUM *z, BN_CTX *ctx) { 861 if (group->meth->point_set_Jprojective_coordinates_GFp == 0) { 862 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 863 return 0; 864 } 865 if (group->meth != point->meth) { 866 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 867 return 0; 868 } 869 return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, 870 z, ctx); 871} 872 873void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {} 874 875const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) { 876 return NULL; 877} 878 879int EC_METHOD_get_field_type(const EC_METHOD *meth) { 880 return NID_X9_62_prime_field; 881} 882 883void EC_GROUP_set_point_conversion_form(EC_GROUP *group, 884 point_conversion_form_t form) { 885 if (form != POINT_CONVERSION_UNCOMPRESSED) { 886 abort(); 887 } 888} 889