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