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