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_key.h> 69 70 #include <string.h> 71 72 #include <openssl/ec.h> 73 #include <openssl/ecdsa.h> 74 #include <openssl/engine.h> 75 #include <openssl/err.h> 76 #include <openssl/ex_data.h> 77 #include <openssl/mem.h> 78 #include <openssl/thread.h> 79 80 #include "internal.h" 81 #include "../delocate.h" 82 #include "../../internal.h" 83 84 85 DEFINE_STATIC_EX_DATA_CLASS(g_ec_ex_data_class) 86 87 static EC_WRAPPED_SCALAR *ec_wrapped_scalar_new(const EC_GROUP *group) { 88 EC_WRAPPED_SCALAR *wrapped = OPENSSL_malloc(sizeof(EC_WRAPPED_SCALAR)); 89 if (wrapped == NULL) { 90 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); 91 return NULL; 92 } 93 94 OPENSSL_memset(wrapped, 0, sizeof(EC_WRAPPED_SCALAR)); 95 wrapped->bignum.d = wrapped->scalar.words; 96 wrapped->bignum.width = group->order.width; 97 wrapped->bignum.dmax = group->order.width; 98 wrapped->bignum.flags = BN_FLG_STATIC_DATA; 99 return wrapped; 100 } 101 102 static void ec_wrapped_scalar_free(EC_WRAPPED_SCALAR *scalar) { 103 OPENSSL_free(scalar); 104 } 105 106 EC_KEY *EC_KEY_new(void) { return EC_KEY_new_method(NULL); } 107 108 EC_KEY *EC_KEY_new_method(const ENGINE *engine) { 109 EC_KEY *ret = OPENSSL_malloc(sizeof(EC_KEY)); 110 if (ret == NULL) { 111 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); 112 return NULL; 113 } 114 115 OPENSSL_memset(ret, 0, sizeof(EC_KEY)); 116 117 if (engine) { 118 ret->ecdsa_meth = ENGINE_get_ECDSA_method(engine); 119 } 120 if (ret->ecdsa_meth) { 121 METHOD_ref(ret->ecdsa_meth); 122 } 123 124 ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; 125 ret->references = 1; 126 127 CRYPTO_new_ex_data(&ret->ex_data); 128 129 if (ret->ecdsa_meth && ret->ecdsa_meth->init && !ret->ecdsa_meth->init(ret)) { 130 CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), ret, &ret->ex_data); 131 if (ret->ecdsa_meth) { 132 METHOD_unref(ret->ecdsa_meth); 133 } 134 OPENSSL_free(ret); 135 return NULL; 136 } 137 138 return ret; 139 } 140 141 EC_KEY *EC_KEY_new_by_curve_name(int nid) { 142 EC_KEY *ret = EC_KEY_new(); 143 if (ret == NULL) { 144 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); 145 return NULL; 146 } 147 ret->group = EC_GROUP_new_by_curve_name(nid); 148 if (ret->group == NULL) { 149 EC_KEY_free(ret); 150 return NULL; 151 } 152 return ret; 153 } 154 155 void EC_KEY_free(EC_KEY *r) { 156 if (r == NULL) { 157 return; 158 } 159 160 if (!CRYPTO_refcount_dec_and_test_zero(&r->references)) { 161 return; 162 } 163 164 if (r->ecdsa_meth) { 165 if (r->ecdsa_meth->finish) { 166 r->ecdsa_meth->finish(r); 167 } 168 METHOD_unref(r->ecdsa_meth); 169 } 170 171 EC_GROUP_free(r->group); 172 EC_POINT_free(r->pub_key); 173 ec_wrapped_scalar_free(r->priv_key); 174 BN_free(r->fixed_k); 175 176 CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), r, &r->ex_data); 177 178 OPENSSL_free(r); 179 } 180 181 EC_KEY *EC_KEY_dup(const EC_KEY *src) { 182 if (src == NULL) { 183 OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); 184 return NULL; 185 } 186 187 EC_KEY *ret = EC_KEY_new(); 188 if (ret == NULL) { 189 return NULL; 190 } 191 192 if ((src->group != NULL && 193 !EC_KEY_set_group(ret, src->group)) || 194 (src->pub_key != NULL && 195 !EC_KEY_set_public_key(ret, src->pub_key)) || 196 (src->priv_key != NULL && 197 !EC_KEY_set_private_key(ret, EC_KEY_get0_private_key(src)))) { 198 EC_KEY_free(ret); 199 return NULL; 200 } 201 202 ret->enc_flag = src->enc_flag; 203 ret->conv_form = src->conv_form; 204 return ret; 205 } 206 207 int EC_KEY_up_ref(EC_KEY *r) { 208 CRYPTO_refcount_inc(&r->references); 209 return 1; 210 } 211 212 int EC_KEY_is_opaque(const EC_KEY *key) { 213 return key->ecdsa_meth && (key->ecdsa_meth->flags & ECDSA_FLAG_OPAQUE); 214 } 215 216 const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) { return key->group; } 217 218 int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) { 219 // If |key| already has a group, it is an error to switch to another one. 220 if (key->group != NULL) { 221 if (EC_GROUP_cmp(key->group, group, NULL) != 0) { 222 OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); 223 return 0; 224 } 225 return 1; 226 } 227 228 assert(key->priv_key == NULL); 229 assert(key->pub_key == NULL); 230 231 EC_GROUP_free(key->group); 232 key->group = EC_GROUP_dup(group); 233 return key->group != NULL; 234 } 235 236 const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) { 237 return key->priv_key != NULL ? &key->priv_key->bignum : NULL; 238 } 239 240 int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) { 241 if (key->group == NULL) { 242 OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); 243 return 0; 244 } 245 246 EC_WRAPPED_SCALAR *scalar = ec_wrapped_scalar_new(key->group); 247 if (scalar == NULL) { 248 return 0; 249 } 250 if (!ec_bignum_to_scalar(key->group, &scalar->scalar, priv_key)) { 251 OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER); 252 ec_wrapped_scalar_free(scalar); 253 return 0; 254 } 255 ec_wrapped_scalar_free(key->priv_key); 256 key->priv_key = scalar; 257 return 1; 258 } 259 260 const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key) { 261 return key->pub_key; 262 } 263 264 int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) { 265 if (key->group == NULL) { 266 OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); 267 return 0; 268 } 269 270 if (pub_key != NULL && EC_GROUP_cmp(key->group, pub_key->group, NULL) != 0) { 271 OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); 272 return 0; 273 } 274 275 EC_POINT_free(key->pub_key); 276 key->pub_key = EC_POINT_dup(pub_key, key->group); 277 return (key->pub_key == NULL) ? 0 : 1; 278 } 279 280 unsigned int EC_KEY_get_enc_flags(const EC_KEY *key) { return key->enc_flag; } 281 282 void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) { 283 key->enc_flag = flags; 284 } 285 286 point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) { 287 return key->conv_form; 288 } 289 290 void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) { 291 key->conv_form = cform; 292 } 293 294 int EC_KEY_check_key(const EC_KEY *eckey) { 295 int ok = 0; 296 BN_CTX *ctx = NULL; 297 EC_POINT *point = NULL; 298 299 if (!eckey || !eckey->group || !eckey->pub_key) { 300 OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); 301 return 0; 302 } 303 304 if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) { 305 OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); 306 goto err; 307 } 308 309 ctx = BN_CTX_new(); 310 311 if (ctx == NULL) { 312 goto err; 313 } 314 315 // testing whether the pub_key is on the elliptic curve 316 if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx)) { 317 OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE); 318 goto err; 319 } 320 // in case the priv_key is present : 321 // check if generator * priv_key == pub_key 322 if (eckey->priv_key != NULL) { 323 point = EC_POINT_new(eckey->group); 324 if (point == NULL || 325 !ec_point_mul_scalar(eckey->group, &point->raw, 326 &eckey->priv_key->scalar, NULL, NULL)) { 327 OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); 328 goto err; 329 } 330 if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) { 331 OPENSSL_PUT_ERROR(EC, EC_R_INVALID_PRIVATE_KEY); 332 goto err; 333 } 334 } 335 ok = 1; 336 337 err: 338 BN_CTX_free(ctx); 339 EC_POINT_free(point); 340 return ok; 341 } 342 343 int EC_KEY_check_fips(const EC_KEY *key) { 344 if (EC_KEY_is_opaque(key)) { 345 // Opaque keys can't be checked. 346 OPENSSL_PUT_ERROR(EC, EC_R_PUBLIC_KEY_VALIDATION_FAILED); 347 return 0; 348 } 349 350 if (!EC_KEY_check_key(key)) { 351 return 0; 352 } 353 354 if (key->priv_key) { 355 uint8_t data[16] = {0}; 356 ECDSA_SIG *sig = ECDSA_do_sign(data, sizeof(data), key); 357 #if defined(BORINGSSL_FIPS_BREAK_ECDSA_PWCT) 358 data[0] = ~data[0]; 359 #endif 360 int ok = sig != NULL && 361 ECDSA_do_verify(data, sizeof(data), sig, key); 362 ECDSA_SIG_free(sig); 363 if (!ok) { 364 OPENSSL_PUT_ERROR(EC, EC_R_PUBLIC_KEY_VALIDATION_FAILED); 365 return 0; 366 } 367 } 368 369 return 1; 370 } 371 372 int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, 373 BIGNUM *y) { 374 EC_POINT *point = NULL; 375 int ok = 0; 376 377 if (!key || !key->group || !x || !y) { 378 OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); 379 return 0; 380 } 381 382 point = EC_POINT_new(key->group); 383 if (point == NULL || 384 !EC_POINT_set_affine_coordinates_GFp(key->group, point, x, y, NULL) || 385 !EC_KEY_set_public_key(key, point) || 386 !EC_KEY_check_key(key)) { 387 goto err; 388 } 389 390 ok = 1; 391 392 err: 393 EC_POINT_free(point); 394 return ok; 395 } 396 397 size_t EC_KEY_key2buf(EC_KEY *key, point_conversion_form_t form, 398 unsigned char **out_buf, BN_CTX *ctx) { 399 if (key == NULL || key->pub_key == NULL || key->group == NULL) { 400 return 0; 401 } 402 403 const size_t len = 404 EC_POINT_point2oct(key->group, key->pub_key, form, NULL, 0, ctx); 405 if (len == 0) { 406 return 0; 407 } 408 409 uint8_t *buf = OPENSSL_malloc(len); 410 if (buf == NULL) { 411 return 0; 412 } 413 414 if (EC_POINT_point2oct(key->group, key->pub_key, form, buf, len, ctx) != 415 len) { 416 OPENSSL_free(buf); 417 return 0; 418 } 419 420 *out_buf = buf; 421 return len; 422 } 423 424 int EC_KEY_generate_key(EC_KEY *key) { 425 if (key == NULL || key->group == NULL) { 426 OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); 427 return 0; 428 } 429 430 // Check that the group order is FIPS compliant (FIPS 186-4 B.4.2). 431 if (BN_num_bits(EC_GROUP_get0_order(key->group)) < 160) { 432 OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER); 433 return 0; 434 } 435 436 static const uint8_t kDefaultAdditionalData[32] = {0}; 437 EC_WRAPPED_SCALAR *priv_key = ec_wrapped_scalar_new(key->group); 438 EC_POINT *pub_key = EC_POINT_new(key->group); 439 if (priv_key == NULL || pub_key == NULL || 440 // Generate the private key by testing candidates (FIPS 186-4 B.4.2). 441 !ec_random_nonzero_scalar(key->group, &priv_key->scalar, 442 kDefaultAdditionalData) || 443 !ec_point_mul_scalar(key->group, &pub_key->raw, &priv_key->scalar, NULL, 444 NULL)) { 445 EC_POINT_free(pub_key); 446 ec_wrapped_scalar_free(priv_key); 447 return 0; 448 } 449 450 ec_wrapped_scalar_free(key->priv_key); 451 key->priv_key = priv_key; 452 EC_POINT_free(key->pub_key); 453 key->pub_key = pub_key; 454 return 1; 455 } 456 457 int EC_KEY_generate_key_fips(EC_KEY *eckey) { 458 return EC_KEY_generate_key(eckey) && EC_KEY_check_fips(eckey); 459 } 460 461 int EC_KEY_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, 462 CRYPTO_EX_dup *dup_unused, 463 CRYPTO_EX_free *free_func) { 464 int index; 465 if (!CRYPTO_get_ex_new_index(g_ec_ex_data_class_bss_get(), &index, argl, argp, 466 free_func)) { 467 return -1; 468 } 469 return index; 470 } 471 472 int EC_KEY_set_ex_data(EC_KEY *d, int idx, void *arg) { 473 return CRYPTO_set_ex_data(&d->ex_data, idx, arg); 474 } 475 476 void *EC_KEY_get_ex_data(const EC_KEY *d, int idx) { 477 return CRYPTO_get_ex_data(&d->ex_data, idx); 478 } 479 480 void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) {} 481