1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* 26 * Copyright 2010 Nexenta Systems, Inc. All rights reserved. 27 */ 28 29 #include <sys/types.h> 30 #include <sys/systm.h> 31 #include <sys/param.h> 32 #include <sys/modctl.h> 33 #include <sys/ddi.h> 34 #include <sys/crypto/spi.h> 35 #include <sys/crypto/impl.h> 36 #include <sys/crypto/ioctladmin.h> 37 #include <sys/sysmacros.h> 38 #include <sys/strsun.h> 39 #include <sys/sha1.h> 40 #include <sys/random.h> 41 #include <sys/conf.h> 42 #include <sys/devops.h> 43 #include <sys/sunddi.h> 44 #include <sys/varargs.h> 45 #include <sys/kmem.h> 46 #include <sys/kstat.h> 47 48 #include <des/des_impl.h> 49 #include <ecc/ecc_impl.h> 50 51 #define CKD_NULL 0x00000001 52 53 extern struct mod_ops mod_cryptoops; 54 55 /* 56 * Module linkage information for the kernel. 57 */ 58 static struct modlcrypto modlcrypto = { 59 &mod_cryptoops, 60 "EC Kernel SW Provider" 61 }; 62 63 static struct modlinkage modlinkage = { 64 MODREV_1, 65 (void *)&modlcrypto, 66 NULL 67 }; 68 69 /* 70 * CSPI information (entry points, provider info, etc.) 71 */ 72 typedef enum ecc_mech_type { 73 EC_KEY_PAIR_GEN_MECH_INFO_TYPE, /* SUN_CKM_EC_KEY_PAIR_GEN */ 74 ECDSA_MECH_INFO_TYPE, /* SUN_CKM_ECDSA */ 75 ECDSA_SHA1_MECH_INFO_TYPE, /* SUN_CKM_ECDSA_SHA1 */ 76 ECDH1_DERIVE_MECH_INFO_TYPE /* SUN_CKM_ECDH1_DERIVE */ 77 } ecc_mech_type_t; 78 79 /* 80 * Context for ECDSA mechanism. 81 */ 82 typedef struct ecc_ctx { 83 ecc_mech_type_t mech_type; 84 crypto_key_t *key; 85 size_t keychunk_size; 86 ECParams ecparams; 87 } ecc_ctx_t; 88 89 /* 90 * Context for ECDSA_SHA1 mechanism. 91 */ 92 typedef struct digest_ecc_ctx { 93 ecc_mech_type_t mech_type; 94 crypto_key_t *key; 95 size_t keychunk_size; 96 ECParams ecparams; 97 union { 98 SHA1_CTX sha1ctx; 99 } dctx_u; 100 } digest_ecc_ctx_t; 101 102 #define sha1_ctx dctx_u.sha1ctx 103 104 /* 105 * Mechanism info structure passed to KCF during registration. 106 */ 107 static crypto_mech_info_t ecc_mech_info_tab[] = { 108 /* EC_KEY_PAIR_GEN */ 109 {SUN_CKM_EC_KEY_PAIR_GEN, EC_KEY_PAIR_GEN_MECH_INFO_TYPE, 110 CRYPTO_FG_GENERATE_KEY_PAIR, EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, 111 CRYPTO_KEYSIZE_UNIT_IN_BITS}, 112 /* ECDH */ 113 {SUN_CKM_ECDH1_DERIVE, ECDH1_DERIVE_MECH_INFO_TYPE, CRYPTO_FG_DERIVE, 114 EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 115 /* ECDSA */ 116 {SUN_CKM_ECDSA, ECDSA_MECH_INFO_TYPE, 117 CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY | 118 CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC, 119 EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 120 /* ECDSA_SHA1 */ 121 {SUN_CKM_ECDSA_SHA1, ECDSA_SHA1_MECH_INFO_TYPE, 122 CRYPTO_FG_SIGN | CRYPTO_FG_VERIFY | 123 CRYPTO_FG_SIGN_ATOMIC | CRYPTO_FG_VERIFY_ATOMIC, 124 EC_MIN_KEY_LEN, EC_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS} 125 }; 126 127 static void ecc_provider_status(crypto_provider_handle_t, uint_t *); 128 129 static crypto_control_ops_t ecc_control_ops = { 130 ecc_provider_status 131 }; 132 133 static int ecc_sign_init(crypto_ctx_t *, crypto_mechanism_t *, 134 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 135 static int ecc_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 136 crypto_req_handle_t); 137 static int ecc_sign_update(crypto_ctx_t *, crypto_data_t *, 138 crypto_req_handle_t); 139 static int ecc_sign_final(crypto_ctx_t *, crypto_data_t *, 140 crypto_req_handle_t); 141 static int ecc_sign_atomic(crypto_provider_handle_t, crypto_session_id_t, 142 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *, 143 crypto_spi_ctx_template_t, crypto_req_handle_t); 144 145 static crypto_sign_ops_t ecc_sign_ops = { 146 ecc_sign_init, 147 ecc_sign, 148 ecc_sign_update, 149 ecc_sign_final, 150 ecc_sign_atomic, 151 NULL, 152 NULL, 153 NULL 154 }; 155 156 static int ecc_verify_init(crypto_ctx_t *, crypto_mechanism_t *, 157 crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 158 static int ecc_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 159 crypto_req_handle_t); 160 static int ecc_verify_update(crypto_ctx_t *, crypto_data_t *, 161 crypto_req_handle_t); 162 static int ecc_verify_final(crypto_ctx_t *, crypto_data_t *, 163 crypto_req_handle_t); 164 static int ecc_verify_atomic(crypto_provider_handle_t, crypto_session_id_t, 165 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 166 crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 167 168 static crypto_verify_ops_t ecc_verify_ops = { 169 ecc_verify_init, 170 ecc_verify, 171 ecc_verify_update, 172 ecc_verify_final, 173 ecc_verify_atomic, 174 NULL, 175 NULL, 176 NULL 177 }; 178 179 static int ecc_nostore_key_generate_pair(crypto_provider_handle_t, 180 crypto_session_id_t, crypto_mechanism_t *, crypto_object_attribute_t *, 181 uint_t, crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *, 182 uint_t, crypto_object_attribute_t *, uint_t, crypto_req_handle_t); 183 static int ecc_nostore_key_derive(crypto_provider_handle_t, 184 crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 185 crypto_object_attribute_t *, uint_t, crypto_object_attribute_t *, 186 uint_t, crypto_req_handle_t); 187 188 static crypto_nostore_key_ops_t ecc_nostore_key_ops = { 189 NULL, 190 ecc_nostore_key_generate_pair, 191 ecc_nostore_key_derive 192 }; 193 194 static crypto_ops_t ecc_crypto_ops = { 195 &ecc_control_ops, 196 NULL, 197 NULL, 198 NULL, 199 &ecc_sign_ops, 200 &ecc_verify_ops, 201 NULL, 202 NULL, 203 NULL, 204 NULL, 205 NULL, 206 NULL, 207 NULL, 208 NULL, 209 NULL, 210 &ecc_nostore_key_ops, 211 NULL, 212 }; 213 214 static crypto_provider_info_t ecc_prov_info = { 215 CRYPTO_SPI_VERSION_4, 216 "EC Software Provider", 217 CRYPTO_SW_PROVIDER, 218 {&modlinkage}, 219 NULL, 220 &ecc_crypto_ops, 221 sizeof (ecc_mech_info_tab)/sizeof (crypto_mech_info_t), 222 ecc_mech_info_tab 223 }; 224 225 static crypto_kcf_provider_handle_t ecc_prov_handle = 0; 226 227 static int ecc_sign_common(ecc_ctx_t *, crypto_data_t *, crypto_data_t *, 228 crypto_req_handle_t); 229 static int ecc_verify_common(ecc_ctx_t *, crypto_data_t *, crypto_data_t *, 230 crypto_req_handle_t); 231 static int find_attr(crypto_object_attribute_t *, uint_t, uint64_t); 232 static int get_template_attr_ulong(crypto_object_attribute_t *, 233 uint_t, uint64_t, ulong_t *); 234 static void ecc_free_context(crypto_ctx_t *); 235 static void free_ecparams(ECParams *, boolean_t); 236 static void free_ecprivkey(ECPrivateKey *); 237 238 int 239 _init(void) 240 { 241 int ret; 242 243 if ((ret = mod_install(&modlinkage)) != 0) 244 return (ret); 245 246 /* Register with KCF. If the registration fails, remove the module. */ 247 if (crypto_register_provider(&ecc_prov_info, &ecc_prov_handle)) { 248 (void) mod_remove(&modlinkage); 249 return (EACCES); 250 } 251 252 return (0); 253 } 254 255 int 256 _fini(void) 257 { 258 /* Unregister from KCF if module is registered */ 259 if (ecc_prov_handle != 0) { 260 if (crypto_unregister_provider(ecc_prov_handle)) 261 return (EBUSY); 262 263 ecc_prov_handle = 0; 264 } 265 266 return (mod_remove(&modlinkage)); 267 } 268 269 int 270 _info(struct modinfo *modinfop) 271 { 272 return (mod_info(&modlinkage, modinfop)); 273 } 274 275 /* ARGSUSED */ 276 static void 277 ecc_provider_status(crypto_provider_handle_t provider, uint_t *status) 278 { 279 *status = CRYPTO_PROVIDER_READY; 280 } 281 282 /* 283 * Return the index of an attribute of specified type found in 284 * the specified array of attributes. If the attribute cannot 285 * found, return -1. 286 */ 287 static int 288 find_attr(crypto_object_attribute_t *attr, uint_t nattr, uint64_t attr_type) 289 { 290 int i; 291 292 for (i = 0; i < nattr; i++) 293 if (attr[i].oa_value != NULL && attr[i].oa_type == attr_type) 294 return (i); 295 return (-1); 296 } 297 298 /* 299 * Common function used by the get_template_attr_*() family of 300 * functions. Returns the value of the specified attribute of specified 301 * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID 302 * if the length of the attribute does not match the specified length, 303 * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found. 304 */ 305 static int 306 get_template_attr_scalar_common(crypto_object_attribute_t *template, 307 uint_t nattr, uint64_t attr_type, void *value, size_t value_len) 308 { 309 size_t oa_value_len; 310 size_t offset = 0; 311 int attr_idx; 312 313 if ((attr_idx = find_attr(template, nattr, attr_type)) == -1) 314 return (CRYPTO_ARGUMENTS_BAD); 315 316 oa_value_len = template[attr_idx].oa_value_len; 317 if (oa_value_len != value_len) { 318 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 319 } 320 321 do_copy: 322 bcopy(template[attr_idx].oa_value, (uchar_t *)value + offset, 323 oa_value_len); 324 325 return (CRYPTO_SUCCESS); 326 } 327 328 /* 329 * Get the value of a ulong_t attribute from the specified template. 330 */ 331 static int 332 get_template_attr_ulong(crypto_object_attribute_t *template, 333 uint_t nattr, uint64_t attr_type, ulong_t *attr_value) 334 { 335 return (get_template_attr_scalar_common(template, nattr, 336 attr_type, attr_value, sizeof (ulong_t))); 337 } 338 339 /* 340 * Called from init routines to do basic sanity checks. Init routines, 341 * e.g. sign_init should fail rather than subsequent operations. 342 */ 343 static int 344 check_mech_and_key(ecc_mech_type_t mech_type, crypto_key_t *key, ulong_t class) 345 { 346 int rv = CRYPTO_SUCCESS; 347 uchar_t *foo; 348 ssize_t point_len; 349 ssize_t value_len; 350 351 if (mech_type != ECDSA_SHA1_MECH_INFO_TYPE && 352 mech_type != ECDSA_MECH_INFO_TYPE) 353 return (CRYPTO_MECHANISM_INVALID); 354 355 if (key->ck_format != CRYPTO_KEY_ATTR_LIST) { 356 return (CRYPTO_KEY_TYPE_INCONSISTENT); 357 } 358 359 switch (class) { 360 case CKO_PUBLIC_KEY: 361 if ((rv = crypto_get_key_attr(key, CKA_EC_POINT, &foo, 362 &point_len)) != CRYPTO_SUCCESS) { 363 return (CRYPTO_TEMPLATE_INCOMPLETE); 364 } 365 if (point_len < CRYPTO_BITS2BYTES(EC_MIN_KEY_LEN) * 2 + 1 || 366 point_len > CRYPTO_BITS2BYTES(EC_MAX_KEY_LEN) * 2 + 1) 367 return (CRYPTO_KEY_SIZE_RANGE); 368 break; 369 370 case CKO_PRIVATE_KEY: 371 if ((rv = crypto_get_key_attr(key, CKA_VALUE, &foo, 372 &value_len)) != CRYPTO_SUCCESS) { 373 return (CRYPTO_TEMPLATE_INCOMPLETE); 374 } 375 if (value_len < CRYPTO_BITS2BYTES(EC_MIN_KEY_LEN) || 376 value_len > CRYPTO_BITS2BYTES(EC_MAX_KEY_LEN)) 377 return (CRYPTO_KEY_SIZE_RANGE); 378 break; 379 380 default: 381 return (CRYPTO_TEMPLATE_INCONSISTENT); 382 } 383 384 return (rv); 385 } 386 387 /* 388 * This function guarantees to return non-zero random numbers. 389 * This is needed as the /dev/urandom kernel interface, 390 * random_get_pseudo_bytes(), may return zeros. 391 */ 392 int 393 ecc_knzero_random_generator(uint8_t *ran_out, size_t ran_len) 394 { 395 int rv; 396 size_t ebc = 0; /* count of extra bytes in extrarand */ 397 size_t i = 0; 398 uint8_t extrarand[32]; 399 size_t extrarand_len; 400 401 if ((rv = random_get_pseudo_bytes(ran_out, ran_len)) != 0) 402 return (rv); 403 404 /* 405 * Walk through the returned random numbers pointed by ran_out, 406 * and look for any random number which is zero. 407 * If we find zero, call random_get_pseudo_bytes() to generate 408 * another 32 random numbers pool. Replace any zeros in ran_out[] 409 * from the random number in pool. 410 */ 411 while (i < ran_len) { 412 if (ran_out[i] != 0) { 413 i++; 414 continue; 415 } 416 417 /* 418 * Note that it is 'while' so we are guaranteed a 419 * non-zero value on exit. 420 */ 421 if (ebc == 0) { 422 /* refresh extrarand */ 423 extrarand_len = sizeof (extrarand); 424 if ((rv = random_get_pseudo_bytes(extrarand, 425 extrarand_len)) != 0) { 426 return (rv); 427 } 428 429 ebc = extrarand_len; 430 } 431 /* Replace zero with byte from extrarand. */ 432 -- ebc; 433 434 /* 435 * The new random byte zero/non-zero will be checked in 436 * the next pass through the loop. 437 */ 438 ran_out[i] = extrarand[ebc]; 439 } 440 441 return (CRYPTO_SUCCESS); 442 } 443 444 static void 445 ecc_free_context(crypto_ctx_t *ctx) 446 { 447 ecc_ctx_t *ctxp = ctx->cc_provider_private; 448 449 if (ctxp != NULL) { 450 bzero(ctxp->key, ctxp->keychunk_size); 451 kmem_free(ctxp->key, ctxp->keychunk_size); 452 453 free_ecparams(&ctxp->ecparams, B_FALSE); 454 455 if (ctxp->mech_type == ECDSA_MECH_INFO_TYPE) 456 kmem_free(ctxp, sizeof (ecc_ctx_t)); 457 else 458 kmem_free(ctxp, sizeof (digest_ecc_ctx_t)); 459 460 ctx->cc_provider_private = NULL; 461 } 462 } 463 464 /* ARGSUSED */ 465 static int 466 ecc_sign_verify_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 467 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 468 crypto_req_handle_t req) 469 { 470 int rv; 471 int kmflag; 472 ecc_ctx_t *ctxp; 473 digest_ecc_ctx_t *dctxp; 474 ecc_mech_type_t mech_type = mechanism->cm_type; 475 uchar_t *params; 476 ssize_t params_len; 477 ECParams *ecparams; 478 SECKEYECParams params_item; 479 480 if (crypto_get_key_attr(key, CKA_EC_PARAMS, (void *) ¶ms, 481 ¶ms_len)) { 482 return (CRYPTO_ARGUMENTS_BAD); 483 } 484 485 /* ASN1 check */ 486 if (params[0] != 0x06 || 487 params[1] != params_len - 2) { 488 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 489 } 490 params_item.data = params; 491 params_item.len = (uint_t)params_len; 492 kmflag = crypto_kmflag(req); 493 if (EC_DecodeParams(¶ms_item, &ecparams, kmflag) != SECSuccess) { 494 /* bad curve OID */ 495 return (CRYPTO_ARGUMENTS_BAD); 496 } 497 498 /* 499 * Allocate an ECC context. 500 */ 501 switch (mech_type) { 502 case ECDSA_SHA1_MECH_INFO_TYPE: 503 dctxp = kmem_zalloc(sizeof (digest_ecc_ctx_t), kmflag); 504 ctxp = (ecc_ctx_t *)dctxp; 505 break; 506 default: 507 ctxp = kmem_zalloc(sizeof (ecc_ctx_t), kmflag); 508 break; 509 } 510 511 if (ctxp == NULL) { 512 free_ecparams(ecparams, B_TRUE); 513 return (CRYPTO_HOST_MEMORY); 514 } 515 516 if ((rv = crypto_copy_key_to_ctx(key, &ctxp->key, &ctxp->keychunk_size, 517 kmflag)) != CRYPTO_SUCCESS) { 518 switch (mech_type) { 519 case ECDSA_SHA1_MECH_INFO_TYPE: 520 kmem_free(dctxp, sizeof (digest_ecc_ctx_t)); 521 break; 522 default: 523 kmem_free(ctxp, sizeof (ecc_ctx_t)); 524 break; 525 } 526 free_ecparams(ecparams, B_TRUE); 527 return (rv); 528 } 529 ctxp->mech_type = mech_type; 530 ctxp->ecparams = *ecparams; 531 kmem_free(ecparams, sizeof (ECParams)); 532 533 switch (mech_type) { 534 case ECDSA_SHA1_MECH_INFO_TYPE: 535 SHA1Init(&(dctxp->sha1_ctx)); 536 break; 537 } 538 539 ctx->cc_provider_private = ctxp; 540 541 return (CRYPTO_SUCCESS); 542 } 543 544 /* ARGSUSED */ 545 static int 546 ecc_sign_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 547 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 548 crypto_req_handle_t req) 549 { 550 int rv; 551 552 ecc_mech_type_t mech_type = mechanism->cm_type; 553 554 if ((rv = check_mech_and_key(mech_type, key, 555 CKO_PRIVATE_KEY)) != CRYPTO_SUCCESS) 556 return (rv); 557 558 rv = ecc_sign_verify_common_init(ctx, mechanism, key, 559 ctx_template, req); 560 561 return (rv); 562 } 563 564 /* ARGSUSED */ 565 static int 566 ecc_verify_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 567 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 568 crypto_req_handle_t req) 569 { 570 int rv; 571 572 ecc_mech_type_t mech_type = mechanism->cm_type; 573 574 if ((rv = check_mech_and_key(mech_type, key, 575 CKO_PUBLIC_KEY)) != CRYPTO_SUCCESS) 576 return (rv); 577 578 rv = ecc_sign_verify_common_init(ctx, mechanism, key, 579 ctx_template, req); 580 581 return (rv); 582 } 583 584 #define SHA1_DIGEST_SIZE 20 585 586 #define INIT_RAW_CRYPTO_DATA(data, base, len, cd_len) \ 587 (data).cd_format = CRYPTO_DATA_RAW; \ 588 (data).cd_offset = 0; \ 589 (data).cd_raw.iov_base = (char *)base; \ 590 (data).cd_raw.iov_len = len; \ 591 (data).cd_length = cd_len; 592 593 static int 594 ecc_digest_svrfy_common(digest_ecc_ctx_t *ctxp, crypto_data_t *data, 595 crypto_data_t *signature, uchar_t flag, crypto_req_handle_t req) 596 { 597 int rv = CRYPTO_FAILED; 598 uchar_t digest[SHA1_DIGEST_LENGTH]; 599 crypto_data_t der_cd; 600 ecc_mech_type_t mech_type; 601 602 ASSERT(flag & CRYPTO_DO_SIGN || flag & CRYPTO_DO_VERIFY); 603 ASSERT(data != NULL || (flag & CRYPTO_DO_FINAL)); 604 605 mech_type = ctxp->mech_type; 606 if (mech_type != ECDSA_SHA1_MECH_INFO_TYPE) 607 return (CRYPTO_MECHANISM_INVALID); 608 609 /* Don't digest if only returning length of signature. */ 610 if (signature->cd_length > 0) { 611 if (mech_type == ECDSA_SHA1_MECH_INFO_TYPE) { 612 rv = crypto_digest_data(data, &(ctxp->sha1_ctx), 613 digest, (void (*)())SHA1Update, 614 (void (*)())SHA1Final, flag | CRYPTO_DO_SHA1); 615 if (rv != CRYPTO_SUCCESS) 616 return (rv); 617 } 618 } 619 620 INIT_RAW_CRYPTO_DATA(der_cd, digest, SHA1_DIGEST_SIZE, 621 SHA1_DIGEST_SIZE); 622 623 if (flag & CRYPTO_DO_SIGN) { 624 rv = ecc_sign_common((ecc_ctx_t *)ctxp, &der_cd, signature, 625 req); 626 } else 627 rv = ecc_verify_common((ecc_ctx_t *)ctxp, &der_cd, signature, 628 req); 629 630 return (rv); 631 } 632 633 /* 634 * This is a single-part signing routine. It does not 635 * compute a hash before signing. 636 */ 637 static int 638 ecc_sign_common(ecc_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 639 crypto_req_handle_t req) 640 { 641 int rv = CRYPTO_FAILED; 642 SECStatus ss; 643 uchar_t *param; 644 uchar_t *private; 645 ssize_t param_len; 646 ssize_t private_len; 647 uchar_t tmp_data[EC_MAX_DIGEST_LEN]; 648 uchar_t signed_data[EC_MAX_SIG_LEN]; 649 ECPrivateKey ECkey; 650 SECItem signature_item; 651 SECItem digest_item; 652 crypto_key_t *key = ctx->key; 653 int kmflag; 654 655 if ((rv = crypto_get_key_attr(key, CKA_EC_PARAMS, ¶m, 656 ¶m_len)) != CRYPTO_SUCCESS) { 657 return (rv); 658 } 659 660 if (data->cd_length > sizeof (tmp_data)) 661 return (CRYPTO_DATA_LEN_RANGE); 662 663 if ((rv = crypto_get_input_data(data, &digest_item.data, tmp_data)) 664 != CRYPTO_SUCCESS) { 665 return (rv); 666 } 667 digest_item.len = data->cd_length; 668 669 /* structure assignment */ 670 ECkey.ecParams = ctx->ecparams; 671 672 if ((rv = crypto_get_key_attr(key, CKA_VALUE, &private, 673 &private_len)) != CRYPTO_SUCCESS) { 674 return (rv); 675 } 676 ECkey.privateValue.data = private; 677 ECkey.privateValue.len = (uint_t)private_len; 678 679 signature_item.data = signed_data; 680 signature_item.len = sizeof (signed_data); 681 682 kmflag = crypto_kmflag(req); 683 if ((ss = ECDSA_SignDigest(&ECkey, &signature_item, &digest_item, 684 kmflag)) != SECSuccess) { 685 if (ss == SECBufferTooSmall) 686 return (CRYPTO_BUFFER_TOO_SMALL); 687 688 return (CRYPTO_FAILED); 689 } 690 691 if (rv == CRYPTO_SUCCESS) { 692 /* copy out the signature */ 693 if ((rv = crypto_put_output_data(signed_data, 694 signature, signature_item.len)) != CRYPTO_SUCCESS) 695 return (rv); 696 697 signature->cd_length = signature_item.len; 698 } 699 700 return (rv); 701 } 702 703 /* ARGSUSED */ 704 static int 705 ecc_sign(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 706 crypto_req_handle_t req) 707 { 708 int rv; 709 ecc_ctx_t *ctxp; 710 711 ASSERT(ctx->cc_provider_private != NULL); 712 ctxp = ctx->cc_provider_private; 713 714 switch (ctxp->mech_type) { 715 case ECDSA_SHA1_MECH_INFO_TYPE: 716 rv = ecc_digest_svrfy_common((digest_ecc_ctx_t *)ctxp, data, 717 signature, CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE | 718 CRYPTO_DO_FINAL, req); 719 break; 720 default: 721 rv = ecc_sign_common(ctxp, data, signature, req); 722 break; 723 } 724 725 if (rv != CRYPTO_BUFFER_TOO_SMALL) 726 ecc_free_context(ctx); 727 728 return (rv); 729 } 730 731 /* ARGSUSED */ 732 static int 733 ecc_sign_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req) 734 { 735 int rv; 736 digest_ecc_ctx_t *ctxp; 737 ecc_mech_type_t mech_type; 738 739 ASSERT(ctx->cc_provider_private != NULL); 740 ctxp = ctx->cc_provider_private; 741 mech_type = ctxp->mech_type; 742 743 if (mech_type == ECDSA_MECH_INFO_TYPE) { 744 ecc_free_context(ctx); 745 return (CRYPTO_MECHANISM_INVALID); 746 } 747 748 if (mech_type == ECDSA_SHA1_MECH_INFO_TYPE) 749 rv = crypto_digest_data(data, &(ctxp->sha1_ctx), NULL, 750 (void (*)())SHA1Update, (void (*)())SHA1Final, 751 CRYPTO_DO_SHA1 | CRYPTO_DO_UPDATE); 752 753 if (rv != CRYPTO_SUCCESS) 754 ecc_free_context(ctx); 755 756 return (rv); 757 } 758 759 /* ARGSUSED */ 760 static int 761 ecc_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature, 762 crypto_req_handle_t req) 763 { 764 int rv; 765 digest_ecc_ctx_t *ctxp; 766 767 ASSERT(ctx->cc_provider_private != NULL); 768 ctxp = ctx->cc_provider_private; 769 770 rv = ecc_digest_svrfy_common(ctxp, NULL, signature, CRYPTO_DO_SIGN | 771 CRYPTO_DO_FINAL, req); 772 if (rv != CRYPTO_BUFFER_TOO_SMALL) 773 ecc_free_context(ctx); 774 775 return (rv); 776 } 777 778 /* ARGSUSED */ 779 static int 780 ecc_sign_atomic(crypto_provider_handle_t provider, 781 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 782 crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 783 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 784 { 785 int rv; 786 ecc_mech_type_t mech_type = mechanism->cm_type; 787 uchar_t *params; 788 ssize_t params_len; 789 ECParams *ecparams; 790 SECKEYECParams params_item; 791 int kmflag; 792 793 if ((rv = check_mech_and_key(mech_type, key, 794 CKO_PRIVATE_KEY)) != CRYPTO_SUCCESS) 795 return (rv); 796 797 if (crypto_get_key_attr(key, CKA_EC_PARAMS, (void *) ¶ms, 798 ¶ms_len)) { 799 return (CRYPTO_ARGUMENTS_BAD); 800 } 801 802 /* ASN1 check */ 803 if (params[0] != 0x06 || 804 params[1] != params_len - 2) { 805 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 806 } 807 params_item.data = params; 808 params_item.len = (uint_t)params_len; 809 kmflag = crypto_kmflag(req); 810 if (EC_DecodeParams(¶ms_item, &ecparams, kmflag) != SECSuccess) { 811 /* bad curve OID */ 812 return (CRYPTO_ARGUMENTS_BAD); 813 } 814 815 if (mechanism->cm_type == ECDSA_MECH_INFO_TYPE) { 816 ecc_ctx_t ctx; 817 818 ctx.mech_type = mech_type; 819 /* structure assignment */ 820 ctx.ecparams = *ecparams; 821 ctx.key = key; 822 rv = ecc_sign_common(&ctx, data, signature, req); 823 } else { 824 digest_ecc_ctx_t dctx; 825 826 dctx.mech_type = mech_type; 827 /* structure assignment */ 828 dctx.ecparams = *ecparams; 829 dctx.key = key; 830 SHA1Init(&(dctx.sha1_ctx)); 831 832 rv = ecc_digest_svrfy_common(&dctx, data, signature, 833 CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE | CRYPTO_DO_FINAL, req); 834 } 835 free_ecparams(ecparams, B_TRUE); 836 837 return (rv); 838 } 839 840 static int 841 ecc_verify_common(ecc_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 842 crypto_req_handle_t req) 843 { 844 int rv = CRYPTO_FAILED; 845 uchar_t *param; 846 uchar_t *public; 847 ssize_t param_len; 848 ssize_t public_len; 849 uchar_t tmp_data[EC_MAX_DIGEST_LEN]; 850 uchar_t signed_data[EC_MAX_SIG_LEN]; 851 ECPublicKey ECkey; 852 SECItem signature_item; 853 SECItem digest_item; 854 crypto_key_t *key = ctx->key; 855 int kmflag; 856 857 if ((rv = crypto_get_key_attr(key, CKA_EC_PARAMS, ¶m, 858 ¶m_len)) != CRYPTO_SUCCESS) { 859 return (rv); 860 } 861 862 if (signature->cd_length > sizeof (signed_data)) { 863 return (CRYPTO_SIGNATURE_LEN_RANGE); 864 } 865 866 if ((rv = crypto_get_input_data(signature, &signature_item.data, 867 signed_data)) != CRYPTO_SUCCESS) { 868 return (rv); 869 } 870 signature_item.len = signature->cd_length; 871 872 if (data->cd_length > sizeof (tmp_data)) 873 return (CRYPTO_DATA_LEN_RANGE); 874 875 if ((rv = crypto_get_input_data(data, &digest_item.data, tmp_data)) 876 != CRYPTO_SUCCESS) { 877 return (rv); 878 } 879 digest_item.len = data->cd_length; 880 881 /* structure assignment */ 882 ECkey.ecParams = ctx->ecparams; 883 884 if ((rv = crypto_get_key_attr(key, CKA_EC_POINT, &public, 885 &public_len)) != CRYPTO_SUCCESS) { 886 return (rv); 887 } 888 ECkey.publicValue.data = public; 889 ECkey.publicValue.len = (uint_t)public_len; 890 891 kmflag = crypto_kmflag(req); 892 if (ECDSA_VerifyDigest(&ECkey, &signature_item, &digest_item, kmflag) 893 != SECSuccess) { 894 rv = CRYPTO_SIGNATURE_INVALID; 895 } else { 896 rv = CRYPTO_SUCCESS; 897 } 898 899 return (rv); 900 } 901 902 /* ARGSUSED */ 903 static int 904 ecc_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 905 crypto_req_handle_t req) 906 { 907 int rv; 908 ecc_ctx_t *ctxp; 909 910 ASSERT(ctx->cc_provider_private != NULL); 911 ctxp = ctx->cc_provider_private; 912 913 switch (ctxp->mech_type) { 914 case ECDSA_SHA1_MECH_INFO_TYPE: 915 rv = ecc_digest_svrfy_common((digest_ecc_ctx_t *)ctxp, data, 916 signature, CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE | 917 CRYPTO_DO_FINAL, req); 918 break; 919 default: 920 rv = ecc_verify_common(ctxp, data, signature, req); 921 break; 922 } 923 924 ecc_free_context(ctx); 925 return (rv); 926 } 927 928 /* ARGSUSED */ 929 static int 930 ecc_verify_update(crypto_ctx_t *ctx, crypto_data_t *data, 931 crypto_req_handle_t req) 932 { 933 int rv; 934 digest_ecc_ctx_t *ctxp; 935 936 ASSERT(ctx->cc_provider_private != NULL); 937 ctxp = ctx->cc_provider_private; 938 939 switch (ctxp->mech_type) { 940 case ECDSA_SHA1_MECH_INFO_TYPE: 941 rv = crypto_digest_data(data, &(ctxp->sha1_ctx), NULL, 942 (void (*)())SHA1Update, (void (*)())SHA1Final, 943 CRYPTO_DO_SHA1 | CRYPTO_DO_UPDATE); 944 break; 945 default: 946 rv = CRYPTO_MECHANISM_INVALID; 947 } 948 949 if (rv != CRYPTO_SUCCESS) 950 ecc_free_context(ctx); 951 952 return (rv); 953 } 954 955 /* ARGSUSED */ 956 static int 957 ecc_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature, 958 crypto_req_handle_t req) 959 { 960 int rv; 961 digest_ecc_ctx_t *ctxp; 962 963 ASSERT(ctx->cc_provider_private != NULL); 964 ctxp = ctx->cc_provider_private; 965 966 rv = ecc_digest_svrfy_common(ctxp, NULL, signature, 967 CRYPTO_DO_VERIFY | CRYPTO_DO_FINAL, req); 968 969 ecc_free_context(ctx); 970 971 return (rv); 972 } 973 974 975 /* ARGSUSED */ 976 static int 977 ecc_verify_atomic(crypto_provider_handle_t provider, 978 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 979 crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 980 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 981 { 982 int rv; 983 ecc_mech_type_t mech_type = mechanism->cm_type; 984 uchar_t *params; 985 ssize_t params_len; 986 ECParams *ecparams; 987 SECKEYECParams params_item; 988 int kmflag; 989 990 if ((rv = check_mech_and_key(mech_type, key, 991 CKO_PUBLIC_KEY)) != CRYPTO_SUCCESS) 992 return (rv); 993 994 if (crypto_get_key_attr(key, CKA_EC_PARAMS, (void *) ¶ms, 995 ¶ms_len)) { 996 return (CRYPTO_ARGUMENTS_BAD); 997 } 998 999 /* ASN1 check */ 1000 if (params[0] != 0x06 || 1001 params[1] != params_len - 2) { 1002 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 1003 } 1004 params_item.data = params; 1005 params_item.len = (uint_t)params_len; 1006 kmflag = crypto_kmflag(req); 1007 if (EC_DecodeParams(¶ms_item, &ecparams, kmflag) != SECSuccess) { 1008 /* bad curve OID */ 1009 return (CRYPTO_ARGUMENTS_BAD); 1010 } 1011 1012 if (mechanism->cm_type == ECDSA_MECH_INFO_TYPE) { 1013 ecc_ctx_t ctx; 1014 1015 ctx.mech_type = mech_type; 1016 /* structure assignment */ 1017 ctx.ecparams = *ecparams; 1018 ctx.key = key; 1019 rv = ecc_verify_common(&ctx, data, signature, req); 1020 } else { 1021 digest_ecc_ctx_t dctx; 1022 1023 dctx.mech_type = mech_type; 1024 /* structure assignment */ 1025 dctx.ecparams = *ecparams; 1026 dctx.key = key; 1027 SHA1Init(&(dctx.sha1_ctx)); 1028 1029 rv = ecc_digest_svrfy_common(&dctx, data, signature, 1030 CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE | CRYPTO_DO_FINAL, req); 1031 } 1032 free_ecparams(ecparams, B_TRUE); 1033 return (rv); 1034 } 1035 1036 /* ARGSUSED */ 1037 static int 1038 ecc_nostore_key_generate_pair(crypto_provider_handle_t provider, 1039 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1040 crypto_object_attribute_t *pub_template, uint_t pub_attribute_count, 1041 crypto_object_attribute_t *pri_template, uint_t pri_attribute_count, 1042 crypto_object_attribute_t *pub_out_template, uint_t pub_out_attribute_count, 1043 crypto_object_attribute_t *pri_out_template, uint_t pri_out_attribute_count, 1044 crypto_req_handle_t req) 1045 { 1046 int rv = CRYPTO_SUCCESS; 1047 ECPrivateKey *privKey; /* contains both public and private values */ 1048 ECParams *ecparams; 1049 SECKEYECParams params_item; 1050 ulong_t pub_key_type = ~0UL, pub_class = ~0UL; 1051 ulong_t pri_key_type = ~0UL, pri_class = ~0UL; 1052 int params_idx, value_idx, point_idx; 1053 uchar_t *params = NULL; 1054 unsigned params_len; 1055 uchar_t *value = NULL; 1056 uchar_t *point = NULL; 1057 int valuelen; 1058 int pointlen; 1059 int xylen; 1060 int kmflag; 1061 1062 if (mechanism->cm_type != EC_KEY_PAIR_GEN_MECH_INFO_TYPE) { 1063 return (CRYPTO_MECHANISM_INVALID); 1064 } 1065 1066 /* optional */ 1067 (void) get_template_attr_ulong(pub_template, 1068 pub_attribute_count, CKA_CLASS, &pub_class); 1069 1070 /* optional */ 1071 (void) get_template_attr_ulong(pri_template, 1072 pri_attribute_count, CKA_CLASS, &pri_class); 1073 1074 /* optional */ 1075 (void) get_template_attr_ulong(pub_template, 1076 pub_attribute_count, CKA_KEY_TYPE, &pub_key_type); 1077 1078 /* optional */ 1079 (void) get_template_attr_ulong(pri_template, 1080 pri_attribute_count, CKA_KEY_TYPE, &pri_key_type); 1081 1082 if (pub_class != ~0UL && pub_class != CKO_PUBLIC_KEY) { 1083 return (CRYPTO_TEMPLATE_INCONSISTENT); 1084 } 1085 pub_class = CKO_PUBLIC_KEY; 1086 1087 if (pri_class != ~0UL && pri_class != CKO_PRIVATE_KEY) { 1088 return (CRYPTO_TEMPLATE_INCONSISTENT); 1089 } 1090 pri_class = CKO_PRIVATE_KEY; 1091 1092 if (pub_key_type != ~0UL && pub_key_type != CKK_EC) { 1093 return (CRYPTO_TEMPLATE_INCONSISTENT); 1094 } 1095 pub_key_type = CKK_EC; 1096 1097 if (pri_key_type != ~0UL && pri_key_type != CKK_EC) { 1098 return (CRYPTO_TEMPLATE_INCONSISTENT); 1099 } 1100 pri_key_type = CKK_EC; 1101 1102 /* public output template must contain CKA_EC_POINT attribute */ 1103 if ((point_idx = find_attr(pub_out_template, pub_out_attribute_count, 1104 CKA_EC_POINT)) == -1) { 1105 return (CRYPTO_TEMPLATE_INCOMPLETE); 1106 } 1107 1108 /* private output template must contain CKA_VALUE attribute */ 1109 if ((value_idx = find_attr(pri_out_template, pri_out_attribute_count, 1110 CKA_VALUE)) == -1) { 1111 return (CRYPTO_TEMPLATE_INCOMPLETE); 1112 } 1113 1114 if ((params_idx = find_attr(pub_template, pub_attribute_count, 1115 CKA_EC_PARAMS)) == -1) { 1116 return (CRYPTO_TEMPLATE_INCOMPLETE); 1117 } 1118 1119 params = (uchar_t *)pub_template[params_idx].oa_value; 1120 params_len = pub_template[params_idx].oa_value_len; 1121 1122 value = (uchar_t *)pri_out_template[value_idx].oa_value; 1123 valuelen = (int)pri_out_template[value_idx].oa_value_len; 1124 point = (uchar_t *)pub_out_template[point_idx].oa_value; 1125 pointlen = (int)pub_out_template[point_idx].oa_value_len; 1126 1127 /* ASN1 check */ 1128 if (params[0] != 0x06 || 1129 params[1] != params_len - 2) { 1130 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 1131 } 1132 params_item.data = params; 1133 params_item.len = params_len; 1134 kmflag = crypto_kmflag(req); 1135 if (EC_DecodeParams(¶ms_item, &ecparams, kmflag) != SECSuccess) { 1136 /* bad curve OID */ 1137 return (CRYPTO_ARGUMENTS_BAD); 1138 } 1139 1140 if (EC_NewKey(ecparams, &privKey, kmflag) != SECSuccess) { 1141 free_ecparams(ecparams, B_TRUE); 1142 return (CRYPTO_FAILED); 1143 } 1144 1145 xylen = privKey->publicValue.len; 1146 /* ASSERT that xylen - 1 is divisible by 2 */ 1147 if (xylen > pointlen) { 1148 rv = CRYPTO_BUFFER_TOO_SMALL; 1149 goto out; 1150 } 1151 1152 if (privKey->privateValue.len > valuelen) { 1153 rv = CRYPTO_BUFFER_TOO_SMALL; 1154 goto out; 1155 } 1156 bcopy(privKey->privateValue.data, value, privKey->privateValue.len); 1157 pri_out_template[value_idx].oa_value_len = privKey->privateValue.len; 1158 1159 bcopy(privKey->publicValue.data, point, xylen); 1160 pub_out_template[point_idx].oa_value_len = xylen; 1161 1162 out: 1163 free_ecprivkey(privKey); 1164 free_ecparams(ecparams, B_TRUE); 1165 return (rv); 1166 } 1167 1168 /* ARGSUSED */ 1169 static int 1170 ecc_nostore_key_derive(crypto_provider_handle_t provider, 1171 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1172 crypto_key_t *base_key, crypto_object_attribute_t *in_attrs, 1173 uint_t in_attr_count, crypto_object_attribute_t *out_attrs, 1174 uint_t out_attr_count, crypto_req_handle_t req) 1175 { 1176 int rv = CRYPTO_SUCCESS; 1177 int params_idx, value_idx = -1, out_value_idx = -1; 1178 ulong_t key_type; 1179 ulong_t key_len; 1180 crypto_object_attribute_t *attrs; 1181 ECParams *ecparams; 1182 SECKEYECParams params_item; 1183 CK_ECDH1_DERIVE_PARAMS *mech_param; 1184 SECItem public_value_item, private_value_item, secret_item; 1185 int kmflag; 1186 1187 if (mechanism->cm_type != ECDH1_DERIVE_MECH_INFO_TYPE) { 1188 return (CRYPTO_MECHANISM_INVALID); 1189 } 1190 1191 ASSERT(IS_P2ALIGNED(mechanism->cm_param, sizeof (uint64_t))); 1192 /* LINTED: pointer alignment */ 1193 mech_param = (CK_ECDH1_DERIVE_PARAMS *)mechanism->cm_param; 1194 if (mech_param->kdf != CKD_NULL) { 1195 return (CRYPTO_MECHANISM_PARAM_INVALID); 1196 } 1197 1198 if ((base_key->ck_format != CRYPTO_KEY_ATTR_LIST) || 1199 (base_key->ck_count == 0)) { 1200 return (CRYPTO_ARGUMENTS_BAD); 1201 } 1202 1203 if ((rv = get_template_attr_ulong(in_attrs, in_attr_count, 1204 CKA_KEY_TYPE, &key_type)) != CRYPTO_SUCCESS) { 1205 return (rv); 1206 } 1207 1208 switch (key_type) { 1209 case CKK_DES: 1210 key_len = DES_KEYSIZE; 1211 break; 1212 case CKK_DES2: 1213 key_len = DES2_KEYSIZE; 1214 break; 1215 case CKK_DES3: 1216 key_len = DES3_KEYSIZE; 1217 break; 1218 case CKK_RC4: 1219 case CKK_AES: 1220 case CKK_GENERIC_SECRET: 1221 if ((rv = get_template_attr_ulong(in_attrs, in_attr_count, 1222 CKA_VALUE_LEN, &key_len)) != CRYPTO_SUCCESS) { 1223 return (rv); 1224 } 1225 break; 1226 default: 1227 key_len = 0; 1228 } 1229 1230 attrs = base_key->ck_attrs; 1231 if ((value_idx = find_attr(attrs, base_key->ck_count, 1232 CKA_VALUE)) == -1) { 1233 return (CRYPTO_TEMPLATE_INCOMPLETE); 1234 } 1235 1236 if ((params_idx = find_attr(attrs, base_key->ck_count, 1237 CKA_EC_PARAMS)) == -1) { 1238 return (CRYPTO_TEMPLATE_INCOMPLETE); 1239 } 1240 1241 private_value_item.data = (uchar_t *)attrs[value_idx].oa_value; 1242 private_value_item.len = attrs[value_idx].oa_value_len; 1243 1244 params_item.len = attrs[params_idx].oa_value_len; 1245 params_item.data = (uchar_t *)attrs[params_idx].oa_value; 1246 1247 /* ASN1 check */ 1248 if (params_item.data[0] != 0x06 || 1249 params_item.data[1] != params_item.len - 2) { 1250 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 1251 } 1252 kmflag = crypto_kmflag(req); 1253 if (EC_DecodeParams(¶ms_item, &ecparams, kmflag) != SECSuccess) { 1254 /* bad curve OID */ 1255 return (CRYPTO_ARGUMENTS_BAD); 1256 } 1257 1258 public_value_item.data = (uchar_t *)mech_param->pPublicData; 1259 public_value_item.len = mech_param->ulPublicDataLen; 1260 1261 if ((out_value_idx = find_attr(out_attrs, out_attr_count, 1262 CKA_VALUE)) == -1) { 1263 rv = CRYPTO_TEMPLATE_INCOMPLETE; 1264 goto out; 1265 } 1266 secret_item.data = NULL; 1267 secret_item.len = 0; 1268 1269 if (ECDH_Derive(&public_value_item, ecparams, &private_value_item, 1270 B_FALSE, &secret_item, kmflag) != SECSuccess) { 1271 free_ecparams(ecparams, B_TRUE); 1272 return (CRYPTO_FAILED); 1273 } else { 1274 rv = CRYPTO_SUCCESS; 1275 } 1276 1277 if (key_len == 0) 1278 key_len = secret_item.len; 1279 1280 if (key_len > secret_item.len) { 1281 rv = CRYPTO_ATTRIBUTE_VALUE_INVALID; 1282 goto out; 1283 } 1284 if (key_len > out_attrs[out_value_idx].oa_value_len) { 1285 rv = CRYPTO_BUFFER_TOO_SMALL; 1286 goto out; 1287 } 1288 bcopy(secret_item.data + secret_item.len - key_len, 1289 (uchar_t *)out_attrs[out_value_idx].oa_value, key_len); 1290 out_attrs[out_value_idx].oa_value_len = key_len; 1291 out: 1292 free_ecparams(ecparams, B_TRUE); 1293 SECITEM_FreeItem(&secret_item, B_FALSE); 1294 return (rv); 1295 } 1296 1297 static void 1298 free_ecparams(ECParams *params, boolean_t freeit) 1299 { 1300 SECITEM_FreeItem(¶ms->fieldID.u.prime, B_FALSE); 1301 SECITEM_FreeItem(¶ms->curve.a, B_FALSE); 1302 SECITEM_FreeItem(¶ms->curve.b, B_FALSE); 1303 SECITEM_FreeItem(¶ms->curve.seed, B_FALSE); 1304 SECITEM_FreeItem(¶ms->base, B_FALSE); 1305 SECITEM_FreeItem(¶ms->order, B_FALSE); 1306 SECITEM_FreeItem(¶ms->DEREncoding, B_FALSE); 1307 SECITEM_FreeItem(¶ms->curveOID, B_FALSE); 1308 if (freeit) 1309 kmem_free(params, sizeof (ECParams)); 1310 } 1311 1312 static void 1313 free_ecprivkey(ECPrivateKey *key) 1314 { 1315 free_ecparams(&key->ecParams, B_FALSE); 1316 SECITEM_FreeItem(&key->publicValue, B_FALSE); 1317 bzero(key->privateValue.data, key->privateValue.len); 1318 SECITEM_FreeItem(&key->privateValue, B_FALSE); 1319 SECITEM_FreeItem(&key->version, B_FALSE); 1320 kmem_free(key, sizeof (ECPrivateKey)); 1321 } 1322