1 /* Written by Dr Stephen N Henson (steve (at) openssl.org) for the OpenSSL 2 * project 2006. 3 */ 4 /* ==================================================================== 5 * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 19 * 3. All advertising materials mentioning features or use of this 20 * software must display the following acknowledgment: 21 * "This product includes software developed by the OpenSSL Project 22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 23 * 24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 25 * endorse or promote products derived from this software without 26 * prior written permission. For written permission, please contact 27 * licensing (at) OpenSSL.org. 28 * 29 * 5. Products derived from this software may not be called "OpenSSL" 30 * nor may "OpenSSL" appear in their names without prior written 31 * permission of the OpenSSL Project. 32 * 33 * 6. Redistributions of any form whatsoever must retain the following 34 * acknowledgment: 35 * "This product includes software developed by the OpenSSL Project 36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 37 * 38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 49 * OF THE POSSIBILITY OF SUCH DAMAGE. 50 * ==================================================================== 51 * 52 * This product includes cryptographic software written by Eric Young 53 * (eay (at) cryptsoft.com). This product includes software written by Tim 54 * Hudson (tjh (at) cryptsoft.com). */ 55 56 #include <openssl/evp.h> 57 58 #include <openssl/asn1t.h> 59 #include <openssl/bn.h> 60 #include <openssl/ec.h> 61 #include <openssl/err.h> 62 #include <openssl/mem.h> 63 #include <openssl/obj.h> 64 #include <openssl/x509.h> 65 66 #include "internal.h" 67 68 69 static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) { 70 const EC_GROUP *group; 71 int nid; 72 73 if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) { 74 OPENSSL_PUT_ERROR(EVP, eckey_param2type, EVP_R_MISSING_PARAMETERS); 75 return 0; 76 } 77 78 nid = EC_GROUP_get_curve_name(group); 79 if (nid == NID_undef) { 80 OPENSSL_PUT_ERROR(EVP, eckey_param2type, EVP_R_NO_NID_FOR_CURVE); 81 return 0; 82 } 83 84 *ppval = (void*) OBJ_nid2obj(nid); 85 *pptype = V_ASN1_OBJECT; 86 return 1; 87 } 88 89 static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { 90 EC_KEY *ec_key = pkey->pkey.ec; 91 void *pval = NULL; 92 int ptype; 93 uint8_t *penc = NULL, *p; 94 int penclen; 95 96 if (!eckey_param2type(&ptype, &pval, ec_key)) { 97 OPENSSL_PUT_ERROR(EVP, eckey_pub_encode, ERR_R_EC_LIB); 98 return 0; 99 } 100 penclen = i2o_ECPublicKey(ec_key, NULL); 101 if (penclen <= 0) { 102 goto err; 103 } 104 penc = OPENSSL_malloc(penclen); 105 if (!penc) { 106 goto err; 107 } 108 p = penc; 109 penclen = i2o_ECPublicKey(ec_key, &p); 110 if (penclen <= 0) { 111 goto err; 112 } 113 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), ptype, pval, penc, 114 penclen)) { 115 return 1; 116 } 117 118 err: 119 if (ptype == V_ASN1_OBJECT) { 120 ASN1_OBJECT_free(pval); 121 } else { 122 ASN1_STRING_free(pval); 123 } 124 if (penc) { 125 OPENSSL_free(penc); 126 } 127 return 0; 128 } 129 130 static EC_KEY *eckey_type2param(int ptype, void *pval) { 131 EC_KEY *eckey = NULL; 132 133 if (ptype == V_ASN1_SEQUENCE) { 134 ASN1_STRING *pstr = pval; 135 const uint8_t *pm = pstr->data; 136 int pmlen = pstr->length; 137 138 eckey = d2i_ECParameters(NULL, &pm, pmlen); 139 if (eckey == NULL) { 140 OPENSSL_PUT_ERROR(EVP, eckey_type2param, EVP_R_DECODE_ERROR); 141 goto err; 142 } 143 } else if (ptype == V_ASN1_OBJECT) { 144 ASN1_OBJECT *poid = pval; 145 EC_GROUP *group; 146 147 /* type == V_ASN1_OBJECT => the parameters are given 148 * by an asn1 OID */ 149 eckey = EC_KEY_new(); 150 if (eckey == NULL) { 151 OPENSSL_PUT_ERROR(EVP, eckey_type2param, ERR_R_MALLOC_FAILURE); 152 goto err; 153 } 154 group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)); 155 if (group == NULL) { 156 goto err; 157 } 158 if (EC_KEY_set_group(eckey, group) == 0) { 159 goto err; 160 } 161 EC_GROUP_free(group); 162 } else { 163 OPENSSL_PUT_ERROR(EVP, eckey_type2param, EVP_R_DECODE_ERROR); 164 goto err; 165 } 166 167 return eckey; 168 169 err: 170 if (eckey) { 171 EC_KEY_free(eckey); 172 } 173 return NULL; 174 } 175 176 static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { 177 const uint8_t *p = NULL; 178 void *pval; 179 int ptype, pklen; 180 EC_KEY *eckey = NULL; 181 X509_ALGOR *palg; 182 183 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) { 184 return 0; 185 } 186 X509_ALGOR_get0(NULL, &ptype, &pval, palg); 187 188 eckey = eckey_type2param(ptype, pval); 189 if (!eckey) { 190 OPENSSL_PUT_ERROR(EVP, eckey_pub_decode, ERR_R_EC_LIB); 191 return 0; 192 } 193 194 /* We have parameters now set public key */ 195 if (!o2i_ECPublicKey(&eckey, &p, pklen)) { 196 OPENSSL_PUT_ERROR(EVP, eckey_pub_decode, EVP_R_DECODE_ERROR); 197 goto err; 198 } 199 200 EVP_PKEY_assign_EC_KEY(pkey, eckey); 201 return 1; 202 203 err: 204 if (eckey) 205 EC_KEY_free(eckey); 206 return 0; 207 } 208 209 static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { 210 int r; 211 const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); 212 const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), 213 *pb = EC_KEY_get0_public_key(b->pkey.ec); 214 r = EC_POINT_cmp(group, pa, pb, NULL); 215 if (r == 0) { 216 return 1; 217 } else if (r == 1) { 218 return 0; 219 } else { 220 return -2; 221 } 222 } 223 224 static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { 225 const uint8_t *p = NULL; 226 void *pval; 227 int ptype, pklen; 228 EC_KEY *eckey = NULL; 229 X509_ALGOR *palg; 230 231 if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) { 232 return 0; 233 } 234 X509_ALGOR_get0(NULL, &ptype, &pval, palg); 235 236 eckey = eckey_type2param(ptype, pval); 237 238 if (!eckey) 239 goto ecliberr; 240 241 /* We have parameters now set private key */ 242 if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { 243 OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, EVP_R_DECODE_ERROR); 244 goto ecerr; 245 } 246 247 /* calculate public key (if necessary) */ 248 if (EC_KEY_get0_public_key(eckey) == NULL) { 249 const BIGNUM *priv_key; 250 const EC_GROUP *group; 251 EC_POINT *pub_key; 252 /* the public key was not included in the SEC1 private 253 * key => calculate the public key */ 254 group = EC_KEY_get0_group(eckey); 255 pub_key = EC_POINT_new(group); 256 if (pub_key == NULL) { 257 OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB); 258 goto ecliberr; 259 } 260 if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { 261 EC_POINT_free(pub_key); 262 OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB); 263 goto ecliberr; 264 } 265 priv_key = EC_KEY_get0_private_key(eckey); 266 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) { 267 EC_POINT_free(pub_key); 268 OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB); 269 goto ecliberr; 270 } 271 if (EC_KEY_set_public_key(eckey, pub_key) == 0) { 272 EC_POINT_free(pub_key); 273 OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB); 274 goto ecliberr; 275 } 276 EC_POINT_free(pub_key); 277 } 278 279 EVP_PKEY_assign_EC_KEY(pkey, eckey); 280 return 1; 281 282 ecliberr: 283 OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB); 284 ecerr: 285 if (eckey) 286 EC_KEY_free(eckey); 287 return 0; 288 } 289 290 static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { 291 EC_KEY *ec_key; 292 uint8_t *ep, *p; 293 int eplen, ptype; 294 void *pval; 295 unsigned int tmp_flags, old_flags; 296 297 ec_key = pkey->pkey.ec; 298 299 if (!eckey_param2type(&ptype, &pval, ec_key)) { 300 OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, EVP_R_DECODE_ERROR); 301 return 0; 302 } 303 304 /* set the private key */ 305 306 /* do not include the parameters in the SEC1 private key 307 * see PKCS#11 12.11 */ 308 old_flags = EC_KEY_get_enc_flags(ec_key); 309 tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS; 310 EC_KEY_set_enc_flags(ec_key, tmp_flags); 311 eplen = i2d_ECPrivateKey(ec_key, NULL); 312 if (!eplen) { 313 EC_KEY_set_enc_flags(ec_key, old_flags); 314 OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, ERR_R_EC_LIB); 315 return 0; 316 } 317 ep = (uint8_t *)OPENSSL_malloc(eplen); 318 if (!ep) { 319 EC_KEY_set_enc_flags(ec_key, old_flags); 320 OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, ERR_R_MALLOC_FAILURE); 321 return 0; 322 } 323 p = ep; 324 if (!i2d_ECPrivateKey(ec_key, &p)) { 325 EC_KEY_set_enc_flags(ec_key, old_flags); 326 OPENSSL_free(ep); 327 OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, ERR_R_EC_LIB); 328 return 0; 329 } 330 /* restore old encoding flags */ 331 EC_KEY_set_enc_flags(ec_key, old_flags); 332 333 if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 334 0, ptype, pval, ep, eplen)) { 335 return 0; 336 } 337 338 return 1; 339 } 340 341 static int int_ec_size(const EVP_PKEY *pkey) { 342 return ECDSA_size(pkey->pkey.ec); 343 } 344 345 static int ec_bits(const EVP_PKEY *pkey) { 346 BIGNUM *order = BN_new(); 347 const EC_GROUP *group; 348 int ret; 349 350 if (!order) { 351 ERR_clear_error(); 352 return 0; 353 } 354 group = EC_KEY_get0_group(pkey->pkey.ec); 355 if (!EC_GROUP_get_order(group, order, NULL)) { 356 ERR_clear_error(); 357 return 0; 358 } 359 360 ret = BN_num_bits(order); 361 BN_free(order); 362 return ret; 363 } 364 365 static int ec_missing_parameters(const EVP_PKEY *pkey) { 366 return EC_KEY_get0_group(pkey->pkey.ec) == NULL; 367 } 368 369 static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { 370 EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec)); 371 if (group == NULL || 372 EC_KEY_set_group(to->pkey.ec, group) == 0) { 373 return 0; 374 } 375 EC_GROUP_free(group); 376 return 1; 377 } 378 379 static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { 380 const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), 381 *group_b = EC_KEY_get0_group(b->pkey.ec); 382 return EC_GROUP_cmp(group_a, group_b); 383 } 384 385 static void int_ec_free(EVP_PKEY *pkey) { EC_KEY_free(pkey->pkey.ec); } 386 387 static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { 388 uint8_t *buffer = NULL; 389 const char *ecstr; 390 size_t buf_len = 0, i; 391 int ret = 0, reason = ERR_R_BIO_LIB; 392 BIGNUM *order = NULL; 393 BN_CTX *ctx = NULL; 394 const EC_GROUP *group; 395 const EC_POINT *public_key; 396 const BIGNUM *priv_key; 397 uint8_t *pub_key_bytes = NULL; 398 size_t pub_key_bytes_len = 0; 399 400 if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { 401 reason = ERR_R_PASSED_NULL_PARAMETER; 402 goto err; 403 } 404 405 ctx = BN_CTX_new(); 406 if (ctx == NULL) { 407 reason = ERR_R_MALLOC_FAILURE; 408 goto err; 409 } 410 411 if (ktype > 0) { 412 public_key = EC_KEY_get0_public_key(x); 413 if (public_key != NULL) { 414 pub_key_bytes_len = EC_POINT_point2oct( 415 group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx); 416 if (pub_key_bytes_len == 0) { 417 reason = ERR_R_MALLOC_FAILURE; 418 goto err; 419 } 420 pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len); 421 if (pub_key_bytes == NULL) { 422 reason = ERR_R_MALLOC_FAILURE; 423 goto err; 424 } 425 pub_key_bytes_len = 426 EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x), 427 pub_key_bytes, pub_key_bytes_len, ctx); 428 if (pub_key_bytes_len == 0) { 429 reason = ERR_R_MALLOC_FAILURE; 430 goto err; 431 } 432 buf_len = pub_key_bytes_len; 433 } 434 } 435 436 if (ktype == 2) { 437 priv_key = EC_KEY_get0_private_key(x); 438 if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) 439 buf_len = i; 440 } else 441 priv_key = NULL; 442 443 if (ktype > 0) { 444 buf_len += 10; 445 if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { 446 reason = ERR_R_MALLOC_FAILURE; 447 goto err; 448 } 449 } 450 if (ktype == 2) 451 ecstr = "Private-Key"; 452 else if (ktype == 1) 453 ecstr = "Public-Key"; 454 else 455 ecstr = "ECDSA-Parameters"; 456 457 if (!BIO_indent(bp, off, 128)) 458 goto err; 459 if ((order = BN_new()) == NULL) 460 goto err; 461 if (!EC_GROUP_get_order(group, order, NULL)) 462 goto err; 463 if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) 464 goto err; 465 466 if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, buffer, off)) 467 goto err; 468 if (pub_key_bytes != NULL) { 469 BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off); 470 } 471 /* TODO(fork): implement */ 472 /* 473 if (!ECPKParameters_print(bp, group, off)) 474 goto err; */ 475 ret = 1; 476 477 err: 478 if (!ret) 479 OPENSSL_PUT_ERROR(EVP, do_EC_KEY_print, reason); 480 if (pub_key_bytes) 481 OPENSSL_free(pub_key_bytes); 482 if (order) 483 BN_free(order); 484 if (ctx) 485 BN_CTX_free(ctx); 486 if (buffer != NULL) 487 OPENSSL_free(buffer); 488 return ret; 489 } 490 491 static int eckey_param_decode(EVP_PKEY *pkey, const uint8_t **pder, 492 int derlen) { 493 EC_KEY *eckey; 494 if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) { 495 OPENSSL_PUT_ERROR(EVP, eckey_param_decode, ERR_R_EC_LIB); 496 return 0; 497 } 498 EVP_PKEY_assign_EC_KEY(pkey, eckey); 499 return 1; 500 } 501 502 static int eckey_param_encode(const EVP_PKEY *pkey, uint8_t **pder) { 503 return i2d_ECParameters(pkey->pkey.ec, pder); 504 } 505 506 static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, 507 ASN1_PCTX *ctx) { 508 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); 509 } 510 511 static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, 512 ASN1_PCTX *ctx) { 513 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); 514 } 515 516 517 static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, 518 ASN1_PCTX *ctx) { 519 return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); 520 } 521 522 static int eckey_opaque(const EVP_PKEY *pkey) { 523 return EC_KEY_is_opaque(pkey->pkey.ec); 524 } 525 526 static int old_ec_priv_decode(EVP_PKEY *pkey, const uint8_t **pder, 527 int derlen) { 528 EC_KEY *ec; 529 if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) { 530 OPENSSL_PUT_ERROR(EVP, old_ec_priv_decode, EVP_R_DECODE_ERROR); 531 return 0; 532 } 533 EVP_PKEY_assign_EC_KEY(pkey, ec); 534 return 1; 535 } 536 537 static int old_ec_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) { 538 return i2d_ECPrivateKey(pkey->pkey.ec, pder); 539 } 540 541 static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { 542 switch (op) { 543 case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 544 *(int *)arg2 = NID_sha1; 545 return 2; 546 547 default: 548 return -2; 549 } 550 } 551 552 const EVP_PKEY_ASN1_METHOD ec_asn1_meth = { 553 EVP_PKEY_EC, 554 EVP_PKEY_EC, 555 0, 556 "EC", 557 "OpenSSL EC algorithm", 558 559 eckey_pub_decode, 560 eckey_pub_encode, 561 eckey_pub_cmp, 562 eckey_pub_print, 563 564 eckey_priv_decode, 565 eckey_priv_encode, 566 eckey_priv_print, 567 568 eckey_opaque, 569 570 int_ec_size, 571 ec_bits, 572 573 eckey_param_decode, 574 eckey_param_encode, 575 ec_missing_parameters, 576 ec_copy_parameters, 577 ec_cmp_parameters, 578 eckey_param_print, 579 0, 580 581 int_ec_free, 582 ec_pkey_ctrl, 583 old_ec_priv_decode, 584 old_ec_priv_encode 585 }; 586