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