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 bcopy(template[attr_idx].oa_value, (uchar_t *)value + offset, 322 oa_value_len); 323 324 return (CRYPTO_SUCCESS); 325 } 326 327 /* 328 * Get the value of a ulong_t attribute from the specified template. 329 */ 330 static int 331 get_template_attr_ulong(crypto_object_attribute_t *template, 332 uint_t nattr, uint64_t attr_type, ulong_t *attr_value) 333 { 334 return (get_template_attr_scalar_common(template, nattr, 335 attr_type, attr_value, sizeof (ulong_t))); 336 } 337 338 /* 339 * Called from init routines to do basic sanity checks. Init routines, 340 * e.g. sign_init should fail rather than subsequent operations. 341 */ 342 static int 343 check_mech_and_key(ecc_mech_type_t mech_type, crypto_key_t *key, ulong_t class) 344 { 345 int rv = CRYPTO_SUCCESS; 346 uchar_t *foo; 347 ssize_t point_len; 348 ssize_t value_len; 349 350 if (mech_type != ECDSA_SHA1_MECH_INFO_TYPE && 351 mech_type != ECDSA_MECH_INFO_TYPE) 352 return (CRYPTO_MECHANISM_INVALID); 353 354 if (key->ck_format != CRYPTO_KEY_ATTR_LIST) { 355 return (CRYPTO_KEY_TYPE_INCONSISTENT); 356 } 357 358 switch (class) { 359 case CKO_PUBLIC_KEY: 360 if ((rv = crypto_get_key_attr(key, CKA_EC_POINT, &foo, 361 &point_len)) != CRYPTO_SUCCESS) { 362 return (CRYPTO_TEMPLATE_INCOMPLETE); 363 } 364 if (point_len < CRYPTO_BITS2BYTES(EC_MIN_KEY_LEN) * 2 + 1 || 365 point_len > CRYPTO_BITS2BYTES(EC_MAX_KEY_LEN) * 2 + 1) 366 return (CRYPTO_KEY_SIZE_RANGE); 367 break; 368 369 case CKO_PRIVATE_KEY: 370 if ((rv = crypto_get_key_attr(key, CKA_VALUE, &foo, 371 &value_len)) != CRYPTO_SUCCESS) { 372 return (CRYPTO_TEMPLATE_INCOMPLETE); 373 } 374 if (value_len < CRYPTO_BITS2BYTES(EC_MIN_KEY_LEN) || 375 value_len > CRYPTO_BITS2BYTES(EC_MAX_KEY_LEN)) 376 return (CRYPTO_KEY_SIZE_RANGE); 377 break; 378 379 default: 380 return (CRYPTO_TEMPLATE_INCONSISTENT); 381 } 382 383 return (rv); 384 } 385 386 /* 387 * This function guarantees to return non-zero random numbers. 388 * This is needed as the /dev/urandom kernel interface, 389 * random_get_pseudo_bytes(), may return zeros. 390 */ 391 int 392 ecc_knzero_random_generator(uint8_t *ran_out, size_t ran_len) 393 { 394 int rv; 395 size_t ebc = 0; /* count of extra bytes in extrarand */ 396 size_t i = 0; 397 uint8_t extrarand[32]; 398 size_t extrarand_len; 399 400 if ((rv = random_get_pseudo_bytes(ran_out, ran_len)) != 0) 401 return (rv); 402 403 /* 404 * Walk through the returned random numbers pointed by ran_out, 405 * and look for any random number which is zero. 406 * If we find zero, call random_get_pseudo_bytes() to generate 407 * another 32 random numbers pool. Replace any zeros in ran_out[] 408 * from the random number in pool. 409 */ 410 while (i < ran_len) { 411 if (ran_out[i] != 0) { 412 i++; 413 continue; 414 } 415 416 /* 417 * Note that it is 'while' so we are guaranteed a 418 * non-zero value on exit. 419 */ 420 if (ebc == 0) { 421 /* refresh extrarand */ 422 extrarand_len = sizeof (extrarand); 423 if ((rv = random_get_pseudo_bytes(extrarand, 424 extrarand_len)) != 0) { 425 return (rv); 426 } 427 428 ebc = extrarand_len; 429 } 430 /* Replace zero with byte from extrarand. */ 431 -- ebc; 432 433 /* 434 * The new random byte zero/non-zero will be checked in 435 * the next pass through the loop. 436 */ 437 ran_out[i] = extrarand[ebc]; 438 } 439 440 return (CRYPTO_SUCCESS); 441 } 442 443 static void 444 ecc_free_context(crypto_ctx_t *ctx) 445 { 446 ecc_ctx_t *ctxp = ctx->cc_provider_private; 447 448 if (ctxp != NULL) { 449 bzero(ctxp->key, ctxp->keychunk_size); 450 kmem_free(ctxp->key, ctxp->keychunk_size); 451 452 free_ecparams(&ctxp->ecparams, B_FALSE); 453 454 if (ctxp->mech_type == ECDSA_MECH_INFO_TYPE) 455 kmem_free(ctxp, sizeof (ecc_ctx_t)); 456 else 457 kmem_free(ctxp, sizeof (digest_ecc_ctx_t)); 458 459 ctx->cc_provider_private = NULL; 460 } 461 } 462 463 /* ARGSUSED */ 464 static int 465 ecc_sign_verify_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 466 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 467 crypto_req_handle_t req) 468 { 469 int rv; 470 int kmflag; 471 ecc_ctx_t *ctxp; 472 digest_ecc_ctx_t *dctxp; 473 ecc_mech_type_t mech_type = mechanism->cm_type; 474 uchar_t *params; 475 ssize_t params_len; 476 ECParams *ecparams; 477 SECKEYECParams params_item; 478 479 if (crypto_get_key_attr(key, CKA_EC_PARAMS, (void *) ¶ms, 480 ¶ms_len)) { 481 return (CRYPTO_ARGUMENTS_BAD); 482 } 483 484 /* ASN1 check */ 485 if (params[0] != 0x06 || 486 params[1] != params_len - 2) { 487 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 488 } 489 params_item.data = params; 490 params_item.len = (uint_t)params_len; 491 kmflag = crypto_kmflag(req); 492 if (EC_DecodeParams(¶ms_item, &ecparams, kmflag) != SECSuccess) { 493 /* bad curve OID */ 494 return (CRYPTO_ARGUMENTS_BAD); 495 } 496 497 /* 498 * Allocate an ECC context. 499 */ 500 switch (mech_type) { 501 case ECDSA_SHA1_MECH_INFO_TYPE: 502 dctxp = kmem_zalloc(sizeof (digest_ecc_ctx_t), kmflag); 503 ctxp = (ecc_ctx_t *)dctxp; 504 break; 505 default: 506 ctxp = kmem_zalloc(sizeof (ecc_ctx_t), kmflag); 507 break; 508 } 509 510 if (ctxp == NULL) { 511 free_ecparams(ecparams, B_TRUE); 512 return (CRYPTO_HOST_MEMORY); 513 } 514 515 if ((rv = crypto_copy_key_to_ctx(key, &ctxp->key, &ctxp->keychunk_size, 516 kmflag)) != CRYPTO_SUCCESS) { 517 switch (mech_type) { 518 case ECDSA_SHA1_MECH_INFO_TYPE: 519 kmem_free(dctxp, sizeof (digest_ecc_ctx_t)); 520 break; 521 default: 522 kmem_free(ctxp, sizeof (ecc_ctx_t)); 523 break; 524 } 525 free_ecparams(ecparams, B_TRUE); 526 return (rv); 527 } 528 ctxp->mech_type = mech_type; 529 ctxp->ecparams = *ecparams; 530 kmem_free(ecparams, sizeof (ECParams)); 531 532 switch (mech_type) { 533 case ECDSA_SHA1_MECH_INFO_TYPE: 534 SHA1Init(&(dctxp->sha1_ctx)); 535 break; 536 } 537 538 ctx->cc_provider_private = ctxp; 539 540 return (CRYPTO_SUCCESS); 541 } 542 543 /* ARGSUSED */ 544 static int 545 ecc_sign_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 546 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 547 crypto_req_handle_t req) 548 { 549 int rv; 550 551 ecc_mech_type_t mech_type = mechanism->cm_type; 552 553 if ((rv = check_mech_and_key(mech_type, key, 554 CKO_PRIVATE_KEY)) != CRYPTO_SUCCESS) 555 return (rv); 556 557 rv = ecc_sign_verify_common_init(ctx, mechanism, key, 558 ctx_template, req); 559 560 return (rv); 561 } 562 563 /* ARGSUSED */ 564 static int 565 ecc_verify_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 566 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 567 crypto_req_handle_t req) 568 { 569 int rv; 570 571 ecc_mech_type_t mech_type = mechanism->cm_type; 572 573 if ((rv = check_mech_and_key(mech_type, key, 574 CKO_PUBLIC_KEY)) != CRYPTO_SUCCESS) 575 return (rv); 576 577 rv = ecc_sign_verify_common_init(ctx, mechanism, key, 578 ctx_template, req); 579 580 return (rv); 581 } 582 583 #define SHA1_DIGEST_SIZE 20 584 585 #define INIT_RAW_CRYPTO_DATA(data, base, len, cd_len) \ 586 (data).cd_format = CRYPTO_DATA_RAW; \ 587 (data).cd_offset = 0; \ 588 (data).cd_raw.iov_base = (char *)base; \ 589 (data).cd_raw.iov_len = len; \ 590 (data).cd_length = cd_len; 591 592 static int 593 ecc_digest_svrfy_common(digest_ecc_ctx_t *ctxp, crypto_data_t *data, 594 crypto_data_t *signature, uchar_t flag, crypto_req_handle_t req) 595 { 596 int rv = CRYPTO_FAILED; 597 uchar_t digest[SHA1_DIGEST_LENGTH]; 598 crypto_data_t der_cd; 599 ecc_mech_type_t mech_type; 600 601 ASSERT(flag & CRYPTO_DO_SIGN || flag & CRYPTO_DO_VERIFY); 602 ASSERT(data != NULL || (flag & CRYPTO_DO_FINAL)); 603 604 mech_type = ctxp->mech_type; 605 if (mech_type != ECDSA_SHA1_MECH_INFO_TYPE) 606 return (CRYPTO_MECHANISM_INVALID); 607 608 /* Don't digest if only returning length of signature. */ 609 if (signature->cd_length > 0) { 610 if (mech_type == ECDSA_SHA1_MECH_INFO_TYPE) { 611 rv = crypto_digest_data(data, &(ctxp->sha1_ctx), 612 digest, (void (*)())SHA1Update, 613 (void (*)())SHA1Final, flag | CRYPTO_DO_SHA1); 614 if (rv != CRYPTO_SUCCESS) 615 return (rv); 616 } 617 } 618 619 INIT_RAW_CRYPTO_DATA(der_cd, digest, SHA1_DIGEST_SIZE, 620 SHA1_DIGEST_SIZE); 621 622 if (flag & CRYPTO_DO_SIGN) { 623 rv = ecc_sign_common((ecc_ctx_t *)ctxp, &der_cd, signature, 624 req); 625 } else 626 rv = ecc_verify_common((ecc_ctx_t *)ctxp, &der_cd, signature, 627 req); 628 629 return (rv); 630 } 631 632 /* 633 * This is a single-part signing routine. It does not 634 * compute a hash before signing. 635 */ 636 static int 637 ecc_sign_common(ecc_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 638 crypto_req_handle_t req) 639 { 640 int rv = CRYPTO_FAILED; 641 SECStatus ss; 642 uchar_t *param; 643 uchar_t *private; 644 ssize_t param_len; 645 ssize_t private_len; 646 uchar_t tmp_data[EC_MAX_DIGEST_LEN]; 647 uchar_t signed_data[EC_MAX_SIG_LEN]; 648 ECPrivateKey ECkey; 649 SECItem signature_item; 650 SECItem digest_item; 651 crypto_key_t *key = ctx->key; 652 int kmflag; 653 654 if ((rv = crypto_get_key_attr(key, CKA_EC_PARAMS, ¶m, 655 ¶m_len)) != CRYPTO_SUCCESS) { 656 return (rv); 657 } 658 659 if (data->cd_length > sizeof (tmp_data)) 660 return (CRYPTO_DATA_LEN_RANGE); 661 662 if ((rv = crypto_get_input_data(data, &digest_item.data, tmp_data)) 663 != CRYPTO_SUCCESS) { 664 return (rv); 665 } 666 digest_item.len = data->cd_length; 667 668 /* structure assignment */ 669 ECkey.ecParams = ctx->ecparams; 670 671 if ((rv = crypto_get_key_attr(key, CKA_VALUE, &private, 672 &private_len)) != CRYPTO_SUCCESS) { 673 return (rv); 674 } 675 ECkey.privateValue.data = private; 676 ECkey.privateValue.len = (uint_t)private_len; 677 678 signature_item.data = signed_data; 679 signature_item.len = sizeof (signed_data); 680 681 kmflag = crypto_kmflag(req); 682 if ((ss = ECDSA_SignDigest(&ECkey, &signature_item, &digest_item, 683 kmflag)) != SECSuccess) { 684 if (ss == SECBufferTooSmall) 685 return (CRYPTO_BUFFER_TOO_SMALL); 686 687 return (CRYPTO_FAILED); 688 } 689 690 if (rv == CRYPTO_SUCCESS) { 691 /* copy out the signature */ 692 if ((rv = crypto_put_output_data(signed_data, 693 signature, signature_item.len)) != CRYPTO_SUCCESS) 694 return (rv); 695 696 signature->cd_length = signature_item.len; 697 } 698 699 return (rv); 700 } 701 702 /* ARGSUSED */ 703 static int 704 ecc_sign(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 705 crypto_req_handle_t req) 706 { 707 int rv; 708 ecc_ctx_t *ctxp; 709 710 ASSERT(ctx->cc_provider_private != NULL); 711 ctxp = ctx->cc_provider_private; 712 713 switch (ctxp->mech_type) { 714 case ECDSA_SHA1_MECH_INFO_TYPE: 715 rv = ecc_digest_svrfy_common((digest_ecc_ctx_t *)ctxp, data, 716 signature, CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE | 717 CRYPTO_DO_FINAL, req); 718 break; 719 default: 720 rv = ecc_sign_common(ctxp, data, signature, req); 721 break; 722 } 723 724 if (rv != CRYPTO_BUFFER_TOO_SMALL) 725 ecc_free_context(ctx); 726 727 return (rv); 728 } 729 730 /* ARGSUSED */ 731 static int 732 ecc_sign_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req) 733 { 734 int rv; 735 digest_ecc_ctx_t *ctxp; 736 ecc_mech_type_t mech_type; 737 738 ASSERT(ctx->cc_provider_private != NULL); 739 ctxp = ctx->cc_provider_private; 740 mech_type = ctxp->mech_type; 741 742 if (mech_type == ECDSA_MECH_INFO_TYPE) { 743 ecc_free_context(ctx); 744 return (CRYPTO_MECHANISM_INVALID); 745 } 746 747 if (mech_type == ECDSA_SHA1_MECH_INFO_TYPE) 748 rv = crypto_digest_data(data, &(ctxp->sha1_ctx), NULL, 749 (void (*)())SHA1Update, (void (*)())SHA1Final, 750 CRYPTO_DO_SHA1 | CRYPTO_DO_UPDATE); 751 752 if (rv != CRYPTO_SUCCESS) 753 ecc_free_context(ctx); 754 755 return (rv); 756 } 757 758 /* ARGSUSED */ 759 static int 760 ecc_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature, 761 crypto_req_handle_t req) 762 { 763 int rv; 764 digest_ecc_ctx_t *ctxp; 765 766 ASSERT(ctx->cc_provider_private != NULL); 767 ctxp = ctx->cc_provider_private; 768 769 rv = ecc_digest_svrfy_common(ctxp, NULL, signature, CRYPTO_DO_SIGN | 770 CRYPTO_DO_FINAL, req); 771 if (rv != CRYPTO_BUFFER_TOO_SMALL) 772 ecc_free_context(ctx); 773 774 return (rv); 775 } 776 777 /* ARGSUSED */ 778 static int 779 ecc_sign_atomic(crypto_provider_handle_t provider, 780 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 781 crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 782 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 783 { 784 int rv; 785 ecc_mech_type_t mech_type = mechanism->cm_type; 786 uchar_t *params; 787 ssize_t params_len; 788 ECParams *ecparams; 789 SECKEYECParams params_item; 790 int kmflag; 791 792 if ((rv = check_mech_and_key(mech_type, key, 793 CKO_PRIVATE_KEY)) != CRYPTO_SUCCESS) 794 return (rv); 795 796 if (crypto_get_key_attr(key, CKA_EC_PARAMS, (void *) ¶ms, 797 ¶ms_len)) { 798 return (CRYPTO_ARGUMENTS_BAD); 799 } 800 801 /* ASN1 check */ 802 if (params[0] != 0x06 || 803 params[1] != params_len - 2) { 804 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 805 } 806 params_item.data = params; 807 params_item.len = (uint_t)params_len; 808 kmflag = crypto_kmflag(req); 809 if (EC_DecodeParams(¶ms_item, &ecparams, kmflag) != SECSuccess) { 810 /* bad curve OID */ 811 return (CRYPTO_ARGUMENTS_BAD); 812 } 813 814 if (mechanism->cm_type == ECDSA_MECH_INFO_TYPE) { 815 ecc_ctx_t ctx; 816 817 ctx.mech_type = mech_type; 818 /* structure assignment */ 819 ctx.ecparams = *ecparams; 820 ctx.key = key; 821 rv = ecc_sign_common(&ctx, data, signature, req); 822 } else { 823 digest_ecc_ctx_t dctx; 824 825 dctx.mech_type = mech_type; 826 /* structure assignment */ 827 dctx.ecparams = *ecparams; 828 dctx.key = key; 829 SHA1Init(&(dctx.sha1_ctx)); 830 831 rv = ecc_digest_svrfy_common(&dctx, data, signature, 832 CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE | CRYPTO_DO_FINAL, req); 833 } 834 free_ecparams(ecparams, B_TRUE); 835 836 return (rv); 837 } 838 839 static int 840 ecc_verify_common(ecc_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 841 crypto_req_handle_t req) 842 { 843 int rv = CRYPTO_FAILED; 844 uchar_t *param; 845 uchar_t *public; 846 ssize_t param_len; 847 ssize_t public_len; 848 uchar_t tmp_data[EC_MAX_DIGEST_LEN]; 849 uchar_t signed_data[EC_MAX_SIG_LEN]; 850 ECPublicKey ECkey; 851 SECItem signature_item; 852 SECItem digest_item; 853 crypto_key_t *key = ctx->key; 854 int kmflag; 855 856 if ((rv = crypto_get_key_attr(key, CKA_EC_PARAMS, ¶m, 857 ¶m_len)) != CRYPTO_SUCCESS) { 858 return (rv); 859 } 860 861 if (signature->cd_length > sizeof (signed_data)) { 862 return (CRYPTO_SIGNATURE_LEN_RANGE); 863 } 864 865 if ((rv = crypto_get_input_data(signature, &signature_item.data, 866 signed_data)) != CRYPTO_SUCCESS) { 867 return (rv); 868 } 869 signature_item.len = signature->cd_length; 870 871 if (data->cd_length > sizeof (tmp_data)) 872 return (CRYPTO_DATA_LEN_RANGE); 873 874 if ((rv = crypto_get_input_data(data, &digest_item.data, tmp_data)) 875 != CRYPTO_SUCCESS) { 876 return (rv); 877 } 878 digest_item.len = data->cd_length; 879 880 /* structure assignment */ 881 ECkey.ecParams = ctx->ecparams; 882 883 if ((rv = crypto_get_key_attr(key, CKA_EC_POINT, &public, 884 &public_len)) != CRYPTO_SUCCESS) { 885 return (rv); 886 } 887 ECkey.publicValue.data = public; 888 ECkey.publicValue.len = (uint_t)public_len; 889 890 kmflag = crypto_kmflag(req); 891 if (ECDSA_VerifyDigest(&ECkey, &signature_item, &digest_item, kmflag) 892 != SECSuccess) { 893 rv = CRYPTO_SIGNATURE_INVALID; 894 } else { 895 rv = CRYPTO_SUCCESS; 896 } 897 898 return (rv); 899 } 900 901 /* ARGSUSED */ 902 static int 903 ecc_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 904 crypto_req_handle_t req) 905 { 906 int rv; 907 ecc_ctx_t *ctxp; 908 909 ASSERT(ctx->cc_provider_private != NULL); 910 ctxp = ctx->cc_provider_private; 911 912 switch (ctxp->mech_type) { 913 case ECDSA_SHA1_MECH_INFO_TYPE: 914 rv = ecc_digest_svrfy_common((digest_ecc_ctx_t *)ctxp, data, 915 signature, CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE | 916 CRYPTO_DO_FINAL, req); 917 break; 918 default: 919 rv = ecc_verify_common(ctxp, data, signature, req); 920 break; 921 } 922 923 ecc_free_context(ctx); 924 return (rv); 925 } 926 927 /* ARGSUSED */ 928 static int 929 ecc_verify_update(crypto_ctx_t *ctx, crypto_data_t *data, 930 crypto_req_handle_t req) 931 { 932 int rv; 933 digest_ecc_ctx_t *ctxp; 934 935 ASSERT(ctx->cc_provider_private != NULL); 936 ctxp = ctx->cc_provider_private; 937 938 switch (ctxp->mech_type) { 939 case ECDSA_SHA1_MECH_INFO_TYPE: 940 rv = crypto_digest_data(data, &(ctxp->sha1_ctx), NULL, 941 (void (*)())SHA1Update, (void (*)())SHA1Final, 942 CRYPTO_DO_SHA1 | CRYPTO_DO_UPDATE); 943 break; 944 default: 945 rv = CRYPTO_MECHANISM_INVALID; 946 } 947 948 if (rv != CRYPTO_SUCCESS) 949 ecc_free_context(ctx); 950 951 return (rv); 952 } 953 954 /* ARGSUSED */ 955 static int 956 ecc_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature, 957 crypto_req_handle_t req) 958 { 959 int rv; 960 digest_ecc_ctx_t *ctxp; 961 962 ASSERT(ctx->cc_provider_private != NULL); 963 ctxp = ctx->cc_provider_private; 964 965 rv = ecc_digest_svrfy_common(ctxp, NULL, signature, 966 CRYPTO_DO_VERIFY | CRYPTO_DO_FINAL, req); 967 968 ecc_free_context(ctx); 969 970 return (rv); 971 } 972 973 974 /* ARGSUSED */ 975 static int 976 ecc_verify_atomic(crypto_provider_handle_t provider, 977 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 978 crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 979 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 980 { 981 int rv; 982 ecc_mech_type_t mech_type = mechanism->cm_type; 983 uchar_t *params; 984 ssize_t params_len; 985 ECParams *ecparams; 986 SECKEYECParams params_item; 987 int kmflag; 988 989 if ((rv = check_mech_and_key(mech_type, key, 990 CKO_PUBLIC_KEY)) != CRYPTO_SUCCESS) 991 return (rv); 992 993 if (crypto_get_key_attr(key, CKA_EC_PARAMS, (void *) ¶ms, 994 ¶ms_len)) { 995 return (CRYPTO_ARGUMENTS_BAD); 996 } 997 998 /* ASN1 check */ 999 if (params[0] != 0x06 || 1000 params[1] != params_len - 2) { 1001 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 1002 } 1003 params_item.data = params; 1004 params_item.len = (uint_t)params_len; 1005 kmflag = crypto_kmflag(req); 1006 if (EC_DecodeParams(¶ms_item, &ecparams, kmflag) != SECSuccess) { 1007 /* bad curve OID */ 1008 return (CRYPTO_ARGUMENTS_BAD); 1009 } 1010 1011 if (mechanism->cm_type == ECDSA_MECH_INFO_TYPE) { 1012 ecc_ctx_t ctx; 1013 1014 ctx.mech_type = mech_type; 1015 /* structure assignment */ 1016 ctx.ecparams = *ecparams; 1017 ctx.key = key; 1018 rv = ecc_verify_common(&ctx, data, signature, req); 1019 } else { 1020 digest_ecc_ctx_t dctx; 1021 1022 dctx.mech_type = mech_type; 1023 /* structure assignment */ 1024 dctx.ecparams = *ecparams; 1025 dctx.key = key; 1026 SHA1Init(&(dctx.sha1_ctx)); 1027 1028 rv = ecc_digest_svrfy_common(&dctx, data, signature, 1029 CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE | CRYPTO_DO_FINAL, req); 1030 } 1031 free_ecparams(ecparams, B_TRUE); 1032 return (rv); 1033 } 1034 1035 /* ARGSUSED */ 1036 static int 1037 ecc_nostore_key_generate_pair(crypto_provider_handle_t provider, 1038 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1039 crypto_object_attribute_t *pub_template, uint_t pub_attribute_count, 1040 crypto_object_attribute_t *pri_template, uint_t pri_attribute_count, 1041 crypto_object_attribute_t *pub_out_template, uint_t pub_out_attribute_count, 1042 crypto_object_attribute_t *pri_out_template, uint_t pri_out_attribute_count, 1043 crypto_req_handle_t req) 1044 { 1045 int rv = CRYPTO_SUCCESS; 1046 ECPrivateKey *privKey; /* contains both public and private values */ 1047 ECParams *ecparams; 1048 SECKEYECParams params_item; 1049 ulong_t pub_key_type = ~0UL, pub_class = ~0UL; 1050 ulong_t pri_key_type = ~0UL, pri_class = ~0UL; 1051 int params_idx, value_idx, point_idx; 1052 uchar_t *params = NULL; 1053 unsigned params_len; 1054 uchar_t *value = NULL; 1055 uchar_t *point = NULL; 1056 int valuelen; 1057 int pointlen; 1058 int xylen; 1059 int kmflag; 1060 1061 if (mechanism->cm_type != EC_KEY_PAIR_GEN_MECH_INFO_TYPE) { 1062 return (CRYPTO_MECHANISM_INVALID); 1063 } 1064 1065 /* optional */ 1066 (void) get_template_attr_ulong(pub_template, 1067 pub_attribute_count, CKA_CLASS, &pub_class); 1068 1069 /* optional */ 1070 (void) get_template_attr_ulong(pri_template, 1071 pri_attribute_count, CKA_CLASS, &pri_class); 1072 1073 /* optional */ 1074 (void) get_template_attr_ulong(pub_template, 1075 pub_attribute_count, CKA_KEY_TYPE, &pub_key_type); 1076 1077 /* optional */ 1078 (void) get_template_attr_ulong(pri_template, 1079 pri_attribute_count, CKA_KEY_TYPE, &pri_key_type); 1080 1081 if (pub_class != ~0UL && pub_class != CKO_PUBLIC_KEY) { 1082 return (CRYPTO_TEMPLATE_INCONSISTENT); 1083 } 1084 pub_class = CKO_PUBLIC_KEY; 1085 1086 if (pri_class != ~0UL && pri_class != CKO_PRIVATE_KEY) { 1087 return (CRYPTO_TEMPLATE_INCONSISTENT); 1088 } 1089 pri_class = CKO_PRIVATE_KEY; 1090 1091 if (pub_key_type != ~0UL && pub_key_type != CKK_EC) { 1092 return (CRYPTO_TEMPLATE_INCONSISTENT); 1093 } 1094 pub_key_type = CKK_EC; 1095 1096 if (pri_key_type != ~0UL && pri_key_type != CKK_EC) { 1097 return (CRYPTO_TEMPLATE_INCONSISTENT); 1098 } 1099 pri_key_type = CKK_EC; 1100 1101 /* public output template must contain CKA_EC_POINT attribute */ 1102 if ((point_idx = find_attr(pub_out_template, pub_out_attribute_count, 1103 CKA_EC_POINT)) == -1) { 1104 return (CRYPTO_TEMPLATE_INCOMPLETE); 1105 } 1106 1107 /* private output template must contain CKA_VALUE attribute */ 1108 if ((value_idx = find_attr(pri_out_template, pri_out_attribute_count, 1109 CKA_VALUE)) == -1) { 1110 return (CRYPTO_TEMPLATE_INCOMPLETE); 1111 } 1112 1113 if ((params_idx = find_attr(pub_template, pub_attribute_count, 1114 CKA_EC_PARAMS)) == -1) { 1115 return (CRYPTO_TEMPLATE_INCOMPLETE); 1116 } 1117 1118 params = (uchar_t *)pub_template[params_idx].oa_value; 1119 params_len = pub_template[params_idx].oa_value_len; 1120 1121 value = (uchar_t *)pri_out_template[value_idx].oa_value; 1122 valuelen = (int)pri_out_template[value_idx].oa_value_len; 1123 point = (uchar_t *)pub_out_template[point_idx].oa_value; 1124 pointlen = (int)pub_out_template[point_idx].oa_value_len; 1125 1126 /* ASN1 check */ 1127 if (params[0] != 0x06 || 1128 params[1] != params_len - 2) { 1129 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 1130 } 1131 params_item.data = params; 1132 params_item.len = params_len; 1133 kmflag = crypto_kmflag(req); 1134 if (EC_DecodeParams(¶ms_item, &ecparams, kmflag) != SECSuccess) { 1135 /* bad curve OID */ 1136 return (CRYPTO_ARGUMENTS_BAD); 1137 } 1138 1139 if (EC_NewKey(ecparams, &privKey, kmflag) != SECSuccess) { 1140 free_ecparams(ecparams, B_TRUE); 1141 return (CRYPTO_FAILED); 1142 } 1143 1144 xylen = privKey->publicValue.len; 1145 /* ASSERT that xylen - 1 is divisible by 2 */ 1146 if (xylen > pointlen) { 1147 rv = CRYPTO_BUFFER_TOO_SMALL; 1148 goto out; 1149 } 1150 1151 if (privKey->privateValue.len > valuelen) { 1152 rv = CRYPTO_BUFFER_TOO_SMALL; 1153 goto out; 1154 } 1155 bcopy(privKey->privateValue.data, value, privKey->privateValue.len); 1156 pri_out_template[value_idx].oa_value_len = privKey->privateValue.len; 1157 1158 bcopy(privKey->publicValue.data, point, xylen); 1159 pub_out_template[point_idx].oa_value_len = xylen; 1160 1161 out: 1162 free_ecprivkey(privKey); 1163 free_ecparams(ecparams, B_TRUE); 1164 return (rv); 1165 } 1166 1167 /* ARGSUSED */ 1168 static int 1169 ecc_nostore_key_derive(crypto_provider_handle_t provider, 1170 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1171 crypto_key_t *base_key, crypto_object_attribute_t *in_attrs, 1172 uint_t in_attr_count, crypto_object_attribute_t *out_attrs, 1173 uint_t out_attr_count, crypto_req_handle_t req) 1174 { 1175 int rv = CRYPTO_SUCCESS; 1176 int params_idx, value_idx = -1, out_value_idx = -1; 1177 ulong_t key_type; 1178 ulong_t key_len; 1179 crypto_object_attribute_t *attrs; 1180 ECParams *ecparams; 1181 SECKEYECParams params_item; 1182 CK_ECDH1_DERIVE_PARAMS *mech_param; 1183 SECItem public_value_item, private_value_item, secret_item; 1184 int kmflag; 1185 1186 if (mechanism->cm_type != ECDH1_DERIVE_MECH_INFO_TYPE) { 1187 return (CRYPTO_MECHANISM_INVALID); 1188 } 1189 1190 ASSERT(IS_P2ALIGNED(mechanism->cm_param, sizeof (uint64_t))); 1191 /* LINTED: pointer alignment */ 1192 mech_param = (CK_ECDH1_DERIVE_PARAMS *)mechanism->cm_param; 1193 if (mech_param->kdf != CKD_NULL) { 1194 return (CRYPTO_MECHANISM_PARAM_INVALID); 1195 } 1196 1197 if ((base_key->ck_format != CRYPTO_KEY_ATTR_LIST) || 1198 (base_key->ck_count == 0)) { 1199 return (CRYPTO_ARGUMENTS_BAD); 1200 } 1201 1202 if ((rv = get_template_attr_ulong(in_attrs, in_attr_count, 1203 CKA_KEY_TYPE, &key_type)) != CRYPTO_SUCCESS) { 1204 return (rv); 1205 } 1206 1207 switch (key_type) { 1208 case CKK_DES: 1209 key_len = DES_KEYSIZE; 1210 break; 1211 case CKK_DES2: 1212 key_len = DES2_KEYSIZE; 1213 break; 1214 case CKK_DES3: 1215 key_len = DES3_KEYSIZE; 1216 break; 1217 case CKK_RC4: 1218 case CKK_AES: 1219 case CKK_GENERIC_SECRET: 1220 if ((rv = get_template_attr_ulong(in_attrs, in_attr_count, 1221 CKA_VALUE_LEN, &key_len)) != CRYPTO_SUCCESS) { 1222 return (rv); 1223 } 1224 break; 1225 default: 1226 key_len = 0; 1227 } 1228 1229 attrs = base_key->ck_attrs; 1230 if ((value_idx = find_attr(attrs, base_key->ck_count, 1231 CKA_VALUE)) == -1) { 1232 return (CRYPTO_TEMPLATE_INCOMPLETE); 1233 } 1234 1235 if ((params_idx = find_attr(attrs, base_key->ck_count, 1236 CKA_EC_PARAMS)) == -1) { 1237 return (CRYPTO_TEMPLATE_INCOMPLETE); 1238 } 1239 1240 private_value_item.data = (uchar_t *)attrs[value_idx].oa_value; 1241 private_value_item.len = attrs[value_idx].oa_value_len; 1242 1243 params_item.len = attrs[params_idx].oa_value_len; 1244 params_item.data = (uchar_t *)attrs[params_idx].oa_value; 1245 1246 /* ASN1 check */ 1247 if (params_item.data[0] != 0x06 || 1248 params_item.data[1] != params_item.len - 2) { 1249 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 1250 } 1251 kmflag = crypto_kmflag(req); 1252 if (EC_DecodeParams(¶ms_item, &ecparams, kmflag) != SECSuccess) { 1253 /* bad curve OID */ 1254 return (CRYPTO_ARGUMENTS_BAD); 1255 } 1256 1257 public_value_item.data = (uchar_t *)mech_param->pPublicData; 1258 public_value_item.len = mech_param->ulPublicDataLen; 1259 1260 if ((out_value_idx = find_attr(out_attrs, out_attr_count, 1261 CKA_VALUE)) == -1) { 1262 rv = CRYPTO_TEMPLATE_INCOMPLETE; 1263 goto out; 1264 } 1265 secret_item.data = NULL; 1266 secret_item.len = 0; 1267 1268 if (ECDH_Derive(&public_value_item, ecparams, &private_value_item, 1269 B_FALSE, &secret_item, kmflag) != SECSuccess) { 1270 free_ecparams(ecparams, B_TRUE); 1271 return (CRYPTO_FAILED); 1272 } else { 1273 rv = CRYPTO_SUCCESS; 1274 } 1275 1276 if (key_len == 0) 1277 key_len = secret_item.len; 1278 1279 if (key_len > secret_item.len) { 1280 rv = CRYPTO_ATTRIBUTE_VALUE_INVALID; 1281 goto out; 1282 } 1283 if (key_len > out_attrs[out_value_idx].oa_value_len) { 1284 rv = CRYPTO_BUFFER_TOO_SMALL; 1285 goto out; 1286 } 1287 bcopy(secret_item.data + secret_item.len - key_len, 1288 (uchar_t *)out_attrs[out_value_idx].oa_value, key_len); 1289 out_attrs[out_value_idx].oa_value_len = key_len; 1290 out: 1291 free_ecparams(ecparams, B_TRUE); 1292 SECITEM_FreeItem(&secret_item, B_FALSE); 1293 return (rv); 1294 } 1295 1296 static void 1297 free_ecparams(ECParams *params, boolean_t freeit) 1298 { 1299 SECITEM_FreeItem(¶ms->fieldID.u.prime, B_FALSE); 1300 SECITEM_FreeItem(¶ms->curve.a, B_FALSE); 1301 SECITEM_FreeItem(¶ms->curve.b, B_FALSE); 1302 SECITEM_FreeItem(¶ms->curve.seed, B_FALSE); 1303 SECITEM_FreeItem(¶ms->base, B_FALSE); 1304 SECITEM_FreeItem(¶ms->order, B_FALSE); 1305 SECITEM_FreeItem(¶ms->DEREncoding, B_FALSE); 1306 SECITEM_FreeItem(¶ms->curveOID, B_FALSE); 1307 if (freeit) 1308 kmem_free(params, sizeof (ECParams)); 1309 } 1310 1311 static void 1312 free_ecprivkey(ECPrivateKey *key) 1313 { 1314 free_ecparams(&key->ecParams, B_FALSE); 1315 SECITEM_FreeItem(&key->publicValue, B_FALSE); 1316 bzero(key->privateValue.data, key->privateValue.len); 1317 SECITEM_FreeItem(&key->privateValue, B_FALSE); 1318 SECITEM_FreeItem(&key->version, B_FALSE); 1319 kmem_free(key, sizeof (ECPrivateKey)); 1320 } 1321