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