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