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