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 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/types.h> 29 #include <sys/systm.h> 30 #include <sys/param.h> 31 #include <sys/modctl.h> 32 #include <sys/ddi.h> 33 #include <sys/crypto/spi.h> 34 #include <sys/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_impl.h" 46 #include "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 int 235 _init(void) 236 { 237 int ret; 238 239 /* 240 * Register with KCF. If the registration fails, return error. 241 */ 242 if ((ret = crypto_register_provider(&ecc_prov_info, 243 &ecc_prov_handle)) != CRYPTO_SUCCESS) { 244 cmn_err(CE_WARN, "ecc _init: crypto_register_provider()" 245 "failed (0x%x)", ret); 246 return (EACCES); 247 } 248 249 if ((ret = mod_install(&modlinkage)) != 0) { 250 int rv; 251 252 ASSERT(ecc_prov_handle != NULL); 253 /* We should not return if the unregister returns busy. */ 254 while ((rv = crypto_unregister_provider(ecc_prov_handle)) 255 == CRYPTO_BUSY) { 256 cmn_err(CE_WARN, "ecc _init: " 257 "crypto_unregister_provider() " 258 "failed (0x%x). Retrying.", rv); 259 /* wait 10 seconds and try again. */ 260 delay(10 * drv_usectohz(1000000)); 261 } 262 } 263 264 return (ret); 265 } 266 267 int 268 _fini(void) 269 { 270 int ret; 271 272 /* 273 * Unregister from KCF if previous registration succeeded. 274 */ 275 if (ecc_prov_handle != NULL) { 276 if ((ret = crypto_unregister_provider(ecc_prov_handle)) != 277 CRYPTO_SUCCESS) { 278 cmn_err(CE_WARN, "ecc _fini: " 279 "crypto_unregister_provider() " 280 "failed (0x%x)", ret); 281 return (EBUSY); 282 } 283 ecc_prov_handle = NULL; 284 } 285 286 return (mod_remove(&modlinkage)); 287 } 288 289 int 290 _info(struct modinfo *modinfop) 291 { 292 return (mod_info(&modlinkage, modinfop)); 293 } 294 295 /* ARGSUSED */ 296 static void 297 ecc_provider_status(crypto_provider_handle_t provider, uint_t *status) 298 { 299 *status = CRYPTO_PROVIDER_READY; 300 } 301 302 /* 303 * Utility routine to look up a attribute of type, 'type', 304 * in the key. 305 */ 306 static int 307 get_key_attr(crypto_key_t *key, crypto_attr_type_t type, 308 uchar_t **value, ssize_t *value_len) 309 { 310 int i; 311 312 ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST); 313 for (i = 0; i < key->ck_count; i++) { 314 if (key->ck_attrs[i].oa_type == type) { 315 *value = (uchar_t *)key->ck_attrs[i].oa_value; 316 *value_len = key->ck_attrs[i].oa_value_len; 317 return (CRYPTO_SUCCESS); 318 } 319 } 320 321 return (CRYPTO_FAILED); 322 } 323 324 /* 325 * Return the index of an attribute of specified type found in 326 * the specified array of attributes. If the attribute cannot 327 * found, return -1. 328 */ 329 static int 330 find_attr(crypto_object_attribute_t *attr, uint_t nattr, uint64_t attr_type) 331 { 332 int i; 333 334 for (i = 0; i < nattr; i++) 335 if (attr[i].oa_value != NULL && attr[i].oa_type == attr_type) 336 return (i); 337 return (-1); 338 } 339 340 /* 341 * Common function used by the get_template_attr_*() family of 342 * functions. Returns the value of the specified attribute of specified 343 * length. Returns CRYPTO_SUCCESS on success, CRYPTO_ATTRIBUTE_VALUE_INVALID 344 * if the length of the attribute does not match the specified length, 345 * or CRYPTO_ARGUMENTS_BAD if the attribute cannot be found. 346 */ 347 static int 348 get_template_attr_scalar_common(crypto_object_attribute_t *template, 349 uint_t nattr, uint64_t attr_type, void *value, size_t value_len) 350 { 351 size_t oa_value_len; 352 size_t offset = 0; 353 int attr_idx; 354 355 if ((attr_idx = find_attr(template, nattr, attr_type)) == -1) 356 return (CRYPTO_ARGUMENTS_BAD); 357 358 oa_value_len = template[attr_idx].oa_value_len; 359 if (oa_value_len != value_len) { 360 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 361 } 362 363 do_copy: 364 bcopy(template[attr_idx].oa_value, (uchar_t *)value + offset, 365 oa_value_len); 366 367 return (CRYPTO_SUCCESS); 368 } 369 370 /* 371 * Get the value of a ulong_t attribute from the specified template. 372 */ 373 static int 374 get_template_attr_ulong(crypto_object_attribute_t *template, 375 uint_t nattr, uint64_t attr_type, ulong_t *attr_value) 376 { 377 return (get_template_attr_scalar_common(template, nattr, 378 attr_type, attr_value, sizeof (ulong_t))); 379 } 380 381 /* 382 * Called from init routines to do basic sanity checks. Init routines, 383 * e.g. sign_init should fail rather than subsequent operations. 384 */ 385 static int 386 check_mech_and_key(ecc_mech_type_t mech_type, crypto_key_t *key, ulong_t class) 387 { 388 int rv = CRYPTO_SUCCESS; 389 uchar_t *foo; 390 ssize_t point_len; 391 ssize_t value_len; 392 393 if (mech_type != ECDSA_SHA1_MECH_INFO_TYPE && 394 mech_type != ECDSA_MECH_INFO_TYPE) 395 return (CRYPTO_MECHANISM_INVALID); 396 397 if (key->ck_format != CRYPTO_KEY_ATTR_LIST) { 398 return (CRYPTO_KEY_TYPE_INCONSISTENT); 399 } 400 401 switch (class) { 402 case CKO_PUBLIC_KEY: 403 if ((rv = get_key_attr(key, CKA_EC_POINT, &foo, &point_len)) 404 != CRYPTO_SUCCESS) { 405 return (CRYPTO_TEMPLATE_INCOMPLETE); 406 } 407 if (point_len < CRYPTO_BITS2BYTES(EC_MIN_KEY_LEN) * 2 + 1 || 408 point_len > CRYPTO_BITS2BYTES(EC_MAX_KEY_LEN) * 2 + 1) 409 return (CRYPTO_KEY_SIZE_RANGE); 410 break; 411 412 case CKO_PRIVATE_KEY: 413 if ((rv = get_key_attr(key, CKA_VALUE, &foo, &value_len)) 414 != CRYPTO_SUCCESS) { 415 return (CRYPTO_TEMPLATE_INCOMPLETE); 416 } 417 if (value_len < CRYPTO_BITS2BYTES(EC_MIN_KEY_LEN) || 418 value_len > CRYPTO_BITS2BYTES(EC_MAX_KEY_LEN)) 419 return (CRYPTO_KEY_SIZE_RANGE); 420 break; 421 422 default: 423 return (CRYPTO_TEMPLATE_INCONSISTENT); 424 } 425 426 return (rv); 427 } 428 429 /* 430 * This function guarantees to return non-zero random numbers. 431 * This is needed as the /dev/urandom kernel interface, 432 * random_get_pseudo_bytes(), may return zeros. 433 */ 434 int 435 ecc_knzero_random_generator(uint8_t *ran_out, size_t ran_len) 436 { 437 int rv; 438 size_t ebc = 0; /* count of extra bytes in extrarand */ 439 size_t i = 0; 440 uint8_t extrarand[32]; 441 size_t extrarand_len; 442 443 if ((rv = random_get_pseudo_bytes(ran_out, ran_len)) != 0) 444 return (rv); 445 446 /* 447 * Walk through the returned random numbers pointed by ran_out, 448 * and look for any random number which is zero. 449 * If we find zero, call random_get_pseudo_bytes() to generate 450 * another 32 random numbers pool. Replace any zeros in ran_out[] 451 * from the random number in pool. 452 */ 453 while (i < ran_len) { 454 if (ran_out[i] != 0) { 455 i++; 456 continue; 457 } 458 459 /* 460 * Note that it is 'while' so we are guaranteed a 461 * non-zero value on exit. 462 */ 463 if (ebc == 0) { 464 /* refresh extrarand */ 465 extrarand_len = sizeof (extrarand); 466 if ((rv = random_get_pseudo_bytes(extrarand, 467 extrarand_len)) != 0) { 468 return (rv); 469 } 470 471 ebc = extrarand_len; 472 } 473 /* Replace zero with byte from extrarand. */ 474 -- ebc; 475 476 /* 477 * The new random byte zero/non-zero will be checked in 478 * the next pass through the loop. 479 */ 480 ran_out[i] = extrarand[ebc]; 481 } 482 483 return (CRYPTO_SUCCESS); 484 } 485 486 typedef enum cmd_type { 487 COPY_FROM_DATA, 488 COPY_TO_DATA, 489 COMPARE_TO_DATA, 490 SHA1_DIGEST_DATA 491 } cmd_type_t; 492 493 /* 494 * Utility routine to apply the command, 'cmd', to the 495 * data in the uio structure. 496 */ 497 static int 498 process_uio_data(crypto_data_t *data, uchar_t *buf, int len, 499 cmd_type_t cmd, void *digest_ctx) 500 { 501 uio_t *uiop = data->cd_uio; 502 off_t offset = data->cd_offset; 503 size_t length = len; 504 uint_t vec_idx; 505 size_t cur_len; 506 uchar_t *datap; 507 508 ASSERT(data->cd_format == CRYPTO_DATA_UIO); 509 if (uiop->uio_segflg != UIO_SYSSPACE) { 510 return (CRYPTO_ARGUMENTS_BAD); 511 } 512 513 /* 514 * Jump to the first iovec containing data to be 515 * processed. 516 */ 517 for (vec_idx = 0; vec_idx < uiop->uio_iovcnt && 518 offset >= uiop->uio_iov[vec_idx].iov_len; 519 offset -= uiop->uio_iov[vec_idx++].iov_len) 520 ; 521 522 if (vec_idx == uiop->uio_iovcnt) { 523 /* 524 * The caller specified an offset that is larger than 525 * the total size of the buffers it provided. 526 */ 527 return (CRYPTO_DATA_LEN_RANGE); 528 } 529 530 while (vec_idx < uiop->uio_iovcnt && length > 0) { 531 cur_len = MIN(uiop->uio_iov[vec_idx].iov_len - 532 offset, length); 533 534 datap = (uchar_t *)(uiop->uio_iov[vec_idx].iov_base + 535 offset); 536 switch (cmd) { 537 case COPY_FROM_DATA: 538 bcopy(datap, buf, cur_len); 539 buf += cur_len; 540 break; 541 case COPY_TO_DATA: 542 bcopy(buf, datap, cur_len); 543 buf += cur_len; 544 break; 545 case COMPARE_TO_DATA: 546 if (bcmp(datap, buf, cur_len)) 547 return (CRYPTO_SIGNATURE_INVALID); 548 buf += cur_len; 549 break; 550 case SHA1_DIGEST_DATA: 551 SHA1Update(digest_ctx, datap, cur_len); 552 break; 553 } 554 555 length -= cur_len; 556 vec_idx++; 557 offset = 0; 558 } 559 560 if (vec_idx == uiop->uio_iovcnt && length > 0) { 561 /* 562 * The end of the specified iovec's was reached but 563 * the length requested could not be processed. 564 */ 565 switch (cmd) { 566 case COPY_TO_DATA: 567 data->cd_length = len; 568 return (CRYPTO_BUFFER_TOO_SMALL); 569 default: 570 return (CRYPTO_DATA_LEN_RANGE); 571 } 572 } 573 574 return (CRYPTO_SUCCESS); 575 } 576 577 /* 578 * Utility routine to apply the command, 'cmd', to the 579 * data in the mblk structure. 580 */ 581 static int 582 process_mblk_data(crypto_data_t *data, uchar_t *buf, int len, 583 cmd_type_t cmd, void *digest_ctx) 584 { 585 off_t offset = data->cd_offset; 586 size_t length = len; 587 mblk_t *mp; 588 size_t cur_len; 589 uchar_t *datap; 590 591 ASSERT(data->cd_format == CRYPTO_DATA_MBLK); 592 /* 593 * Jump to the first mblk_t containing data to be processed. 594 */ 595 for (mp = data->cd_mp; mp != NULL && offset >= MBLKL(mp); 596 offset -= MBLKL(mp), mp = mp->b_cont) 597 ; 598 if (mp == NULL) { 599 /* 600 * The caller specified an offset that is larger 601 * than the total size of the buffers it provided. 602 */ 603 return (CRYPTO_DATA_LEN_RANGE); 604 } 605 606 /* 607 * Now do the processing on the mblk chain. 608 */ 609 while (mp != NULL && length > 0) { 610 cur_len = MIN(MBLKL(mp) - offset, length); 611 612 datap = (uchar_t *)(mp->b_rptr + offset); 613 switch (cmd) { 614 case COPY_FROM_DATA: 615 bcopy(datap, buf, cur_len); 616 buf += cur_len; 617 break; 618 case COPY_TO_DATA: 619 bcopy(buf, datap, cur_len); 620 buf += cur_len; 621 break; 622 case COMPARE_TO_DATA: 623 if (bcmp(datap, buf, cur_len)) 624 return (CRYPTO_SIGNATURE_INVALID); 625 buf += cur_len; 626 break; 627 case SHA1_DIGEST_DATA: 628 SHA1Update(digest_ctx, datap, cur_len); 629 break; 630 } 631 632 length -= cur_len; 633 offset = 0; 634 mp = mp->b_cont; 635 } 636 637 if (mp == NULL && length > 0) { 638 /* 639 * The end of the mblk was reached but the length 640 * requested could not be processed. 641 */ 642 switch (cmd) { 643 case COPY_TO_DATA: 644 data->cd_length = len; 645 return (CRYPTO_BUFFER_TOO_SMALL); 646 default: 647 return (CRYPTO_DATA_LEN_RANGE); 648 } 649 } 650 651 return (CRYPTO_SUCCESS); 652 } 653 654 /* 655 * Utility routine to copy a buffer to a crypto_data structure. 656 */ 657 static int 658 put_output_data(uchar_t *buf, crypto_data_t *output, int len) 659 { 660 switch (output->cd_format) { 661 case CRYPTO_DATA_RAW: 662 if (output->cd_raw.iov_len < len) { 663 output->cd_length = len; 664 return (CRYPTO_BUFFER_TOO_SMALL); 665 } 666 bcopy(buf, (uchar_t *)(output->cd_raw.iov_base + 667 output->cd_offset), len); 668 break; 669 670 case CRYPTO_DATA_UIO: 671 return (process_uio_data(output, buf, len, COPY_TO_DATA, NULL)); 672 673 case CRYPTO_DATA_MBLK: 674 return (process_mblk_data(output, buf, len, 675 COPY_TO_DATA, NULL)); 676 677 default: 678 return (CRYPTO_ARGUMENTS_BAD); 679 } 680 681 return (CRYPTO_SUCCESS); 682 } 683 684 /* 685 * Utility routine to get data from a crypto_data structure. 686 * 687 * '*dptr' contains a pointer to a buffer on return. 'buf' 688 * is allocated by the caller and is ignored for CRYPTO_DATA_RAW case. 689 */ 690 static int 691 get_input_data(crypto_data_t *input, uchar_t **dptr, uchar_t *buf) 692 { 693 int rv; 694 695 switch (input->cd_format) { 696 case CRYPTO_DATA_RAW: 697 if (input->cd_raw.iov_len < input->cd_length) 698 return (CRYPTO_ARGUMENTS_BAD); 699 *dptr = (uchar_t *)(input->cd_raw.iov_base + 700 input->cd_offset); 701 break; 702 703 case CRYPTO_DATA_UIO: 704 if ((rv = process_uio_data(input, buf, input->cd_length, 705 COPY_FROM_DATA, NULL)) != CRYPTO_SUCCESS) 706 return (rv); 707 *dptr = buf; 708 break; 709 710 case CRYPTO_DATA_MBLK: 711 if ((rv = process_mblk_data(input, buf, input->cd_length, 712 COPY_FROM_DATA, NULL)) != CRYPTO_SUCCESS) 713 return (rv); 714 *dptr = buf; 715 break; 716 717 default: 718 return (CRYPTO_ARGUMENTS_BAD); 719 } 720 721 return (CRYPTO_SUCCESS); 722 } 723 724 static int 725 copy_key_to_ctx(crypto_key_t *in_key, ecc_ctx_t *ctx, int kmflag) 726 { 727 int i, count; 728 size_t len; 729 caddr_t attr_val; 730 crypto_object_attribute_t *k_attrs = NULL; 731 732 ASSERT(in_key->ck_format == CRYPTO_KEY_ATTR_LIST); 733 734 count = in_key->ck_count; 735 /* figure out how much memory to allocate for everything */ 736 len = sizeof (crypto_key_t) + 737 count * sizeof (crypto_object_attribute_t); 738 for (i = 0; i < count; i++) { 739 len += roundup(in_key->ck_attrs[i].oa_value_len, 740 sizeof (caddr_t)); 741 } 742 743 /* one big allocation for everything */ 744 ctx->key = kmem_alloc(len, kmflag); 745 if (ctx->key == NULL) 746 return (CRYPTO_HOST_MEMORY); 747 /* LINTED: pointer alignment */ 748 k_attrs = (crypto_object_attribute_t *)((caddr_t)(ctx->key) + 749 sizeof (crypto_key_t)); 750 751 attr_val = (caddr_t)k_attrs + 752 count * sizeof (crypto_object_attribute_t); 753 for (i = 0; i < count; i++) { 754 k_attrs[i].oa_type = in_key->ck_attrs[i].oa_type; 755 bcopy(in_key->ck_attrs[i].oa_value, attr_val, 756 in_key->ck_attrs[i].oa_value_len); 757 k_attrs[i].oa_value = attr_val; 758 k_attrs[i].oa_value_len = in_key->ck_attrs[i].oa_value_len; 759 attr_val += roundup(k_attrs[i].oa_value_len, sizeof (caddr_t)); 760 } 761 762 ctx->keychunk_size = len; /* save the size to be freed */ 763 ctx->key->ck_format = CRYPTO_KEY_ATTR_LIST; 764 ctx->key->ck_count = count; 765 ctx->key->ck_attrs = k_attrs; 766 767 return (CRYPTO_SUCCESS); 768 } 769 770 static void 771 ecc_free_context(crypto_ctx_t *ctx) 772 { 773 ecc_ctx_t *ctxp = ctx->cc_provider_private; 774 775 if (ctxp != NULL) { 776 bzero(ctxp->key, ctxp->keychunk_size); 777 kmem_free(ctxp->key, ctxp->keychunk_size); 778 779 free_ecparams(&ctxp->ecparams, B_FALSE); 780 781 if (ctxp->mech_type == ECDSA_MECH_INFO_TYPE) 782 kmem_free(ctxp, sizeof (ecc_ctx_t)); 783 else 784 kmem_free(ctxp, sizeof (digest_ecc_ctx_t)); 785 786 ctx->cc_provider_private = NULL; 787 } 788 } 789 790 /* ARGSUSED */ 791 static int 792 ecc_sign_verify_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 793 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 794 crypto_req_handle_t req) 795 { 796 int rv; 797 int kmflag; 798 ecc_ctx_t *ctxp; 799 digest_ecc_ctx_t *dctxp; 800 ecc_mech_type_t mech_type = mechanism->cm_type; 801 uchar_t *params; 802 ssize_t params_len; 803 ECParams *ecparams; 804 SECKEYECParams params_item; 805 806 if (get_key_attr(key, CKA_EC_PARAMS, (void *) ¶ms, 807 ¶ms_len)) { 808 return (CRYPTO_ARGUMENTS_BAD); 809 } 810 811 /* ASN1 check */ 812 if (params[0] != 0x06 || 813 params[1] != params_len - 2) { 814 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 815 } 816 params_item.data = params; 817 params_item.len = (uint_t)params_len; 818 kmflag = crypto_kmflag(req); 819 if (EC_DecodeParams(¶ms_item, &ecparams, kmflag) != SECSuccess) { 820 /* bad curve OID */ 821 return (CRYPTO_ARGUMENTS_BAD); 822 } 823 824 /* 825 * Allocate an ECC context. 826 */ 827 switch (mech_type) { 828 case ECDSA_SHA1_MECH_INFO_TYPE: 829 dctxp = kmem_zalloc(sizeof (digest_ecc_ctx_t), kmflag); 830 ctxp = (ecc_ctx_t *)dctxp; 831 break; 832 default: 833 ctxp = kmem_zalloc(sizeof (ecc_ctx_t), kmflag); 834 break; 835 } 836 837 if (ctxp == NULL) { 838 free_ecparams(ecparams, B_TRUE); 839 return (CRYPTO_HOST_MEMORY); 840 } 841 842 if ((rv = copy_key_to_ctx(key, ctxp, kmflag)) != CRYPTO_SUCCESS) { 843 switch (mech_type) { 844 case ECDSA_SHA1_MECH_INFO_TYPE: 845 kmem_free(dctxp, sizeof (digest_ecc_ctx_t)); 846 break; 847 default: 848 kmem_free(ctxp, sizeof (ecc_ctx_t)); 849 break; 850 } 851 free_ecparams(ecparams, B_TRUE); 852 return (rv); 853 } 854 ctxp->mech_type = mech_type; 855 ctxp->ecparams = *ecparams; 856 kmem_free(ecparams, sizeof (ECParams)); 857 858 switch (mech_type) { 859 case ECDSA_SHA1_MECH_INFO_TYPE: 860 SHA1Init(&(dctxp->sha1_ctx)); 861 break; 862 } 863 864 ctx->cc_provider_private = ctxp; 865 866 return (CRYPTO_SUCCESS); 867 } 868 869 /* ARGSUSED */ 870 static int 871 ecc_sign_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 872 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 873 crypto_req_handle_t req) 874 { 875 int rv; 876 877 ecc_mech_type_t mech_type = mechanism->cm_type; 878 879 if ((rv = check_mech_and_key(mech_type, key, 880 CKO_PRIVATE_KEY)) != CRYPTO_SUCCESS) 881 return (rv); 882 883 rv = ecc_sign_verify_common_init(ctx, mechanism, key, 884 ctx_template, req); 885 886 return (rv); 887 } 888 889 /* ARGSUSED */ 890 static int 891 ecc_verify_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 892 crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 893 crypto_req_handle_t req) 894 { 895 int rv; 896 897 ecc_mech_type_t mech_type = mechanism->cm_type; 898 899 if ((rv = check_mech_and_key(mech_type, key, 900 CKO_PUBLIC_KEY)) != CRYPTO_SUCCESS) 901 return (rv); 902 903 rv = ecc_sign_verify_common_init(ctx, mechanism, key, 904 ctx_template, req); 905 906 return (rv); 907 } 908 909 #define SHA1_DIGEST_SIZE 20 910 911 #define INIT_RAW_CRYPTO_DATA(data, base, len, cd_len) \ 912 (data).cd_format = CRYPTO_DATA_RAW; \ 913 (data).cd_offset = 0; \ 914 (data).cd_raw.iov_base = (char *)base; \ 915 (data).cd_raw.iov_len = len; \ 916 (data).cd_length = cd_len; 917 918 #define DO_UPDATE 0x01 919 #define DO_FINAL 0x02 920 #define DO_SHA1 0x08 921 #define DO_SIGN 0x10 922 #define DO_VERIFY 0x20 923 924 static int 925 digest_data(crypto_data_t *data, void *dctx, uchar_t *digest, 926 uchar_t flag) 927 { 928 int rv, dlen; 929 uchar_t *dptr; 930 931 ASSERT(flag & DO_SHA1); 932 if (data == NULL) { 933 ASSERT((flag & DO_UPDATE) == 0); 934 goto dofinal; 935 } 936 937 dlen = data->cd_length; 938 939 if (flag & DO_UPDATE) { 940 941 switch (data->cd_format) { 942 case CRYPTO_DATA_RAW: 943 dptr = (uchar_t *)(data->cd_raw.iov_base + 944 data->cd_offset); 945 946 if (flag & DO_SHA1) 947 SHA1Update(dctx, dptr, dlen); 948 949 break; 950 951 case CRYPTO_DATA_UIO: 952 if (flag & DO_SHA1) 953 rv = process_uio_data(data, NULL, dlen, 954 SHA1_DIGEST_DATA, dctx); 955 956 if (rv != CRYPTO_SUCCESS) 957 return (rv); 958 959 break; 960 961 case CRYPTO_DATA_MBLK: 962 if (flag & DO_SHA1) 963 rv = process_mblk_data(data, NULL, dlen, 964 SHA1_DIGEST_DATA, dctx); 965 966 if (rv != CRYPTO_SUCCESS) 967 return (rv); 968 969 break; 970 } 971 } 972 973 dofinal: 974 if (flag & DO_FINAL) { 975 if (flag & DO_SHA1) 976 SHA1Final(digest, dctx); 977 } 978 979 return (CRYPTO_SUCCESS); 980 } 981 982 static int 983 ecc_digest_svrfy_common(digest_ecc_ctx_t *ctxp, crypto_data_t *data, 984 crypto_data_t *signature, uchar_t flag, crypto_req_handle_t req) 985 { 986 int rv = CRYPTO_FAILED; 987 uchar_t digest[SHA1_DIGEST_LENGTH]; 988 crypto_data_t der_cd; 989 ecc_mech_type_t mech_type; 990 991 ASSERT(flag & DO_SIGN || flag & DO_VERIFY); 992 ASSERT(data != NULL || (flag & DO_FINAL)); 993 994 mech_type = ctxp->mech_type; 995 if (mech_type != ECDSA_SHA1_MECH_INFO_TYPE) 996 return (CRYPTO_MECHANISM_INVALID); 997 998 /* Don't digest if only returning length of signature. */ 999 if (signature->cd_length > 0) { 1000 if (mech_type == ECDSA_SHA1_MECH_INFO_TYPE) { 1001 rv = digest_data(data, &(ctxp->sha1_ctx), 1002 digest, flag | DO_SHA1); 1003 if (rv != CRYPTO_SUCCESS) 1004 return (rv); 1005 } 1006 } 1007 1008 INIT_RAW_CRYPTO_DATA(der_cd, digest, SHA1_DIGEST_SIZE, 1009 SHA1_DIGEST_SIZE); 1010 1011 if (flag & DO_SIGN) { 1012 rv = ecc_sign_common((ecc_ctx_t *)ctxp, &der_cd, signature, 1013 req); 1014 } else 1015 rv = ecc_verify_common((ecc_ctx_t *)ctxp, &der_cd, signature, 1016 req); 1017 1018 return (rv); 1019 } 1020 1021 /* 1022 * This is a single-part signing routine. It does not 1023 * compute a hash before signing. 1024 */ 1025 static int 1026 ecc_sign_common(ecc_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 1027 crypto_req_handle_t req) 1028 { 1029 int rv = CRYPTO_FAILED; 1030 SECStatus ss; 1031 uchar_t *param; 1032 uchar_t *private; 1033 ssize_t param_len; 1034 ssize_t private_len; 1035 uchar_t tmp_data[EC_MAX_DIGEST_LEN]; 1036 uchar_t signed_data[EC_MAX_SIG_LEN]; 1037 ECPrivateKey ECkey; 1038 SECItem signature_item; 1039 SECItem digest_item; 1040 crypto_key_t *key = ctx->key; 1041 int kmflag; 1042 1043 if ((rv = get_key_attr(key, CKA_EC_PARAMS, ¶m, 1044 ¶m_len)) != CRYPTO_SUCCESS) { 1045 return (rv); 1046 } 1047 1048 if (data->cd_length > sizeof (tmp_data)) 1049 return (CRYPTO_DATA_LEN_RANGE); 1050 1051 if ((rv = get_input_data(data, &digest_item.data, tmp_data)) 1052 != CRYPTO_SUCCESS) { 1053 return (rv); 1054 } 1055 digest_item.len = data->cd_length; 1056 1057 /* structure assignment */ 1058 ECkey.ecParams = ctx->ecparams; 1059 1060 if ((rv = get_key_attr(key, CKA_VALUE, &private, 1061 &private_len)) != CRYPTO_SUCCESS) { 1062 return (rv); 1063 } 1064 ECkey.privateValue.data = private; 1065 ECkey.privateValue.len = (uint_t)private_len; 1066 1067 signature_item.data = signed_data; 1068 signature_item.len = sizeof (signed_data); 1069 1070 kmflag = crypto_kmflag(req); 1071 if ((ss = ECDSA_SignDigest(&ECkey, &signature_item, &digest_item, 1072 kmflag)) != SECSuccess) { 1073 if (ss == SECBufferTooSmall) 1074 return (CRYPTO_BUFFER_TOO_SMALL); 1075 1076 return (CRYPTO_FAILED); 1077 } 1078 1079 if (rv == CRYPTO_SUCCESS) { 1080 /* copy out the signature */ 1081 if ((rv = put_output_data(signed_data, 1082 signature, signature_item.len)) != CRYPTO_SUCCESS) 1083 return (rv); 1084 1085 signature->cd_length = signature_item.len; 1086 } 1087 1088 return (rv); 1089 } 1090 1091 /* ARGSUSED */ 1092 static int 1093 ecc_sign(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 1094 crypto_req_handle_t req) 1095 { 1096 int rv; 1097 ecc_ctx_t *ctxp; 1098 1099 ASSERT(ctx->cc_provider_private != NULL); 1100 ctxp = ctx->cc_provider_private; 1101 1102 switch (ctxp->mech_type) { 1103 case ECDSA_SHA1_MECH_INFO_TYPE: 1104 rv = ecc_digest_svrfy_common((digest_ecc_ctx_t *)ctxp, data, 1105 signature, DO_SIGN | DO_UPDATE | DO_FINAL, req); 1106 break; 1107 default: 1108 rv = ecc_sign_common(ctxp, data, signature, req); 1109 break; 1110 } 1111 1112 if (rv != CRYPTO_BUFFER_TOO_SMALL) 1113 ecc_free_context(ctx); 1114 1115 return (rv); 1116 } 1117 1118 /* ARGSUSED */ 1119 static int 1120 ecc_sign_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req) 1121 { 1122 int rv; 1123 digest_ecc_ctx_t *ctxp; 1124 ecc_mech_type_t mech_type; 1125 1126 ASSERT(ctx->cc_provider_private != NULL); 1127 ctxp = ctx->cc_provider_private; 1128 mech_type = ctxp->mech_type; 1129 1130 if (mech_type == ECDSA_MECH_INFO_TYPE) { 1131 ecc_free_context(ctx); 1132 return (CRYPTO_MECHANISM_INVALID); 1133 } 1134 1135 if (mech_type == ECDSA_SHA1_MECH_INFO_TYPE) 1136 rv = digest_data(data, &(ctxp->sha1_ctx), 1137 NULL, DO_SHA1 | DO_UPDATE); 1138 1139 if (rv != CRYPTO_SUCCESS) 1140 ecc_free_context(ctx); 1141 1142 return (rv); 1143 } 1144 1145 /* ARGSUSED */ 1146 static int 1147 ecc_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature, 1148 crypto_req_handle_t req) 1149 { 1150 int rv; 1151 digest_ecc_ctx_t *ctxp; 1152 1153 ASSERT(ctx->cc_provider_private != NULL); 1154 ctxp = ctx->cc_provider_private; 1155 1156 rv = ecc_digest_svrfy_common(ctxp, NULL, signature, DO_SIGN | DO_FINAL, 1157 req); 1158 if (rv != CRYPTO_BUFFER_TOO_SMALL) 1159 ecc_free_context(ctx); 1160 1161 return (rv); 1162 } 1163 1164 /* ARGSUSED */ 1165 static int 1166 ecc_sign_atomic(crypto_provider_handle_t provider, 1167 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1168 crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 1169 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 1170 { 1171 int rv; 1172 ecc_mech_type_t mech_type = mechanism->cm_type; 1173 uchar_t *params; 1174 ssize_t params_len; 1175 ECParams *ecparams; 1176 SECKEYECParams params_item; 1177 int kmflag; 1178 1179 if ((rv = check_mech_and_key(mech_type, key, 1180 CKO_PRIVATE_KEY)) != CRYPTO_SUCCESS) 1181 return (rv); 1182 1183 if (get_key_attr(key, CKA_EC_PARAMS, (void *) ¶ms, 1184 ¶ms_len)) { 1185 return (CRYPTO_ARGUMENTS_BAD); 1186 } 1187 1188 /* ASN1 check */ 1189 if (params[0] != 0x06 || 1190 params[1] != params_len - 2) { 1191 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 1192 } 1193 params_item.data = params; 1194 params_item.len = (uint_t)params_len; 1195 kmflag = crypto_kmflag(req); 1196 if (EC_DecodeParams(¶ms_item, &ecparams, kmflag) != SECSuccess) { 1197 /* bad curve OID */ 1198 return (CRYPTO_ARGUMENTS_BAD); 1199 } 1200 1201 if (mechanism->cm_type == ECDSA_MECH_INFO_TYPE) { 1202 ecc_ctx_t ctx; 1203 1204 ctx.mech_type = mech_type; 1205 /* structure assignment */ 1206 ctx.ecparams = *ecparams; 1207 ctx.key = key; 1208 rv = ecc_sign_common(&ctx, data, signature, req); 1209 } else { 1210 digest_ecc_ctx_t dctx; 1211 1212 dctx.mech_type = mech_type; 1213 /* structure assignment */ 1214 dctx.ecparams = *ecparams; 1215 dctx.key = key; 1216 SHA1Init(&(dctx.sha1_ctx)); 1217 1218 rv = ecc_digest_svrfy_common(&dctx, data, signature, 1219 DO_SIGN | DO_UPDATE | DO_FINAL, req); 1220 } 1221 free_ecparams(ecparams, B_TRUE); 1222 1223 return (rv); 1224 } 1225 1226 static int 1227 ecc_verify_common(ecc_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 1228 crypto_req_handle_t req) 1229 { 1230 int rv = CRYPTO_FAILED; 1231 uchar_t *param; 1232 uchar_t *public; 1233 ssize_t param_len; 1234 ssize_t public_len; 1235 uchar_t tmp_data[EC_MAX_DIGEST_LEN]; 1236 uchar_t signed_data[EC_MAX_SIG_LEN]; 1237 ECPublicKey ECkey; 1238 SECItem signature_item; 1239 SECItem digest_item; 1240 crypto_key_t *key = ctx->key; 1241 int kmflag; 1242 1243 if ((rv = get_key_attr(key, CKA_EC_PARAMS, ¶m, 1244 ¶m_len)) != CRYPTO_SUCCESS) { 1245 return (rv); 1246 } 1247 1248 if (signature->cd_length > sizeof (signed_data)) { 1249 return (CRYPTO_SIGNATURE_LEN_RANGE); 1250 } 1251 1252 if ((rv = get_input_data(signature, &signature_item.data, 1253 signed_data)) != CRYPTO_SUCCESS) { 1254 return (rv); 1255 } 1256 signature_item.len = signature->cd_length; 1257 1258 if (data->cd_length > sizeof (tmp_data)) 1259 return (CRYPTO_DATA_LEN_RANGE); 1260 1261 if ((rv = get_input_data(data, &digest_item.data, tmp_data)) 1262 != CRYPTO_SUCCESS) { 1263 return (rv); 1264 } 1265 digest_item.len = data->cd_length; 1266 1267 /* structure assignment */ 1268 ECkey.ecParams = ctx->ecparams; 1269 1270 if ((rv = get_key_attr(key, CKA_EC_POINT, &public, 1271 &public_len)) != CRYPTO_SUCCESS) { 1272 return (rv); 1273 } 1274 ECkey.publicValue.data = public; 1275 ECkey.publicValue.len = (uint_t)public_len; 1276 1277 kmflag = crypto_kmflag(req); 1278 if (ECDSA_VerifyDigest(&ECkey, &signature_item, &digest_item, kmflag) 1279 != SECSuccess) { 1280 rv = CRYPTO_SIGNATURE_INVALID; 1281 } else { 1282 rv = CRYPTO_SUCCESS; 1283 } 1284 1285 return (rv); 1286 } 1287 1288 /* ARGSUSED */ 1289 static int 1290 ecc_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 1291 crypto_req_handle_t req) 1292 { 1293 int rv; 1294 ecc_ctx_t *ctxp; 1295 1296 ASSERT(ctx->cc_provider_private != NULL); 1297 ctxp = ctx->cc_provider_private; 1298 1299 switch (ctxp->mech_type) { 1300 case ECDSA_SHA1_MECH_INFO_TYPE: 1301 rv = ecc_digest_svrfy_common((digest_ecc_ctx_t *)ctxp, data, 1302 signature, DO_VERIFY | DO_UPDATE | DO_FINAL, req); 1303 break; 1304 default: 1305 rv = ecc_verify_common(ctxp, data, signature, req); 1306 break; 1307 } 1308 1309 ecc_free_context(ctx); 1310 return (rv); 1311 } 1312 1313 /* ARGSUSED */ 1314 static int 1315 ecc_verify_update(crypto_ctx_t *ctx, crypto_data_t *data, 1316 crypto_req_handle_t req) 1317 { 1318 int rv; 1319 digest_ecc_ctx_t *ctxp; 1320 1321 ASSERT(ctx->cc_provider_private != NULL); 1322 ctxp = ctx->cc_provider_private; 1323 1324 switch (ctxp->mech_type) { 1325 case ECDSA_SHA1_MECH_INFO_TYPE: 1326 rv = digest_data(data, &(ctxp->sha1_ctx), 1327 NULL, DO_SHA1 | DO_UPDATE); 1328 break; 1329 default: 1330 rv = CRYPTO_MECHANISM_INVALID; 1331 } 1332 1333 if (rv != CRYPTO_SUCCESS) 1334 ecc_free_context(ctx); 1335 1336 return (rv); 1337 } 1338 1339 /* ARGSUSED */ 1340 static int 1341 ecc_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature, 1342 crypto_req_handle_t req) 1343 { 1344 int rv; 1345 digest_ecc_ctx_t *ctxp; 1346 1347 ASSERT(ctx->cc_provider_private != NULL); 1348 ctxp = ctx->cc_provider_private; 1349 1350 rv = ecc_digest_svrfy_common(ctxp, NULL, signature, 1351 DO_VERIFY | DO_FINAL, req); 1352 1353 ecc_free_context(ctx); 1354 1355 return (rv); 1356 } 1357 1358 1359 /* ARGSUSED */ 1360 static int 1361 ecc_verify_atomic(crypto_provider_handle_t provider, 1362 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1363 crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 1364 crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 1365 { 1366 int rv; 1367 ecc_mech_type_t mech_type = mechanism->cm_type; 1368 uchar_t *params; 1369 ssize_t params_len; 1370 ECParams *ecparams; 1371 SECKEYECParams params_item; 1372 int kmflag; 1373 1374 if ((rv = check_mech_and_key(mech_type, key, 1375 CKO_PUBLIC_KEY)) != CRYPTO_SUCCESS) 1376 return (rv); 1377 1378 if (get_key_attr(key, CKA_EC_PARAMS, (void *) ¶ms, 1379 ¶ms_len)) { 1380 return (CRYPTO_ARGUMENTS_BAD); 1381 } 1382 1383 /* ASN1 check */ 1384 if (params[0] != 0x06 || 1385 params[1] != params_len - 2) { 1386 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 1387 } 1388 params_item.data = params; 1389 params_item.len = (uint_t)params_len; 1390 kmflag = crypto_kmflag(req); 1391 if (EC_DecodeParams(¶ms_item, &ecparams, kmflag) != SECSuccess) { 1392 /* bad curve OID */ 1393 return (CRYPTO_ARGUMENTS_BAD); 1394 } 1395 1396 if (mechanism->cm_type == ECDSA_MECH_INFO_TYPE) { 1397 ecc_ctx_t ctx; 1398 1399 ctx.mech_type = mech_type; 1400 /* structure assignment */ 1401 ctx.ecparams = *ecparams; 1402 ctx.key = key; 1403 rv = ecc_verify_common(&ctx, data, signature, req); 1404 } else { 1405 digest_ecc_ctx_t dctx; 1406 1407 dctx.mech_type = mech_type; 1408 /* structure assignment */ 1409 dctx.ecparams = *ecparams; 1410 dctx.key = key; 1411 SHA1Init(&(dctx.sha1_ctx)); 1412 1413 rv = ecc_digest_svrfy_common(&dctx, data, signature, 1414 DO_VERIFY | DO_UPDATE | DO_FINAL, req); 1415 } 1416 free_ecparams(ecparams, B_TRUE); 1417 return (rv); 1418 } 1419 1420 /* ARGSUSED */ 1421 static int 1422 ecc_nostore_key_generate_pair(crypto_provider_handle_t provider, 1423 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1424 crypto_object_attribute_t *pub_template, uint_t pub_attribute_count, 1425 crypto_object_attribute_t *pri_template, uint_t pri_attribute_count, 1426 crypto_object_attribute_t *pub_out_template, uint_t pub_out_attribute_count, 1427 crypto_object_attribute_t *pri_out_template, uint_t pri_out_attribute_count, 1428 crypto_req_handle_t req) 1429 { 1430 int rv = CRYPTO_SUCCESS; 1431 ECPrivateKey *privKey; /* contains both public and private values */ 1432 ECParams *ecparams; 1433 SECKEYECParams params_item; 1434 ulong_t pub_key_type = ~0UL, pub_class = ~0UL; 1435 ulong_t pri_key_type = ~0UL, pri_class = ~0UL; 1436 int params_idx, value_idx, point_idx; 1437 uchar_t *params = NULL; 1438 unsigned params_len; 1439 uchar_t *value = NULL; 1440 uchar_t *point = NULL; 1441 int valuelen; 1442 int pointlen; 1443 int xylen; 1444 int kmflag; 1445 1446 if (mechanism->cm_type != EC_KEY_PAIR_GEN_MECH_INFO_TYPE) { 1447 return (CRYPTO_MECHANISM_INVALID); 1448 } 1449 1450 /* optional */ 1451 (void) get_template_attr_ulong(pub_template, 1452 pub_attribute_count, CKA_CLASS, &pub_class); 1453 1454 /* optional */ 1455 (void) get_template_attr_ulong(pri_template, 1456 pri_attribute_count, CKA_CLASS, &pri_class); 1457 1458 /* optional */ 1459 (void) get_template_attr_ulong(pub_template, 1460 pub_attribute_count, CKA_KEY_TYPE, &pub_key_type); 1461 1462 /* optional */ 1463 (void) get_template_attr_ulong(pri_template, 1464 pri_attribute_count, CKA_KEY_TYPE, &pri_key_type); 1465 1466 if (pub_class != ~0UL && pub_class != CKO_PUBLIC_KEY) { 1467 return (CRYPTO_TEMPLATE_INCONSISTENT); 1468 } 1469 pub_class = CKO_PUBLIC_KEY; 1470 1471 if (pri_class != ~0UL && pri_class != CKO_PRIVATE_KEY) { 1472 return (CRYPTO_TEMPLATE_INCONSISTENT); 1473 } 1474 pri_class = CKO_PRIVATE_KEY; 1475 1476 if (pub_key_type != ~0UL && pub_key_type != CKK_EC) { 1477 return (CRYPTO_TEMPLATE_INCONSISTENT); 1478 } 1479 pub_key_type = CKK_EC; 1480 1481 if (pri_key_type != ~0UL && pri_key_type != CKK_EC) { 1482 return (CRYPTO_TEMPLATE_INCONSISTENT); 1483 } 1484 pri_key_type = CKK_EC; 1485 1486 /* public output template must contain CKA_EC_POINT attribute */ 1487 if ((point_idx = find_attr(pub_out_template, pub_out_attribute_count, 1488 CKA_EC_POINT)) == -1) { 1489 return (CRYPTO_TEMPLATE_INCOMPLETE); 1490 } 1491 1492 /* private output template must contain CKA_VALUE attribute */ 1493 if ((value_idx = find_attr(pri_out_template, pri_out_attribute_count, 1494 CKA_VALUE)) == -1) { 1495 return (CRYPTO_TEMPLATE_INCOMPLETE); 1496 } 1497 1498 if ((params_idx = find_attr(pub_template, pub_attribute_count, 1499 CKA_EC_PARAMS)) == -1) { 1500 return (CRYPTO_TEMPLATE_INCOMPLETE); 1501 } 1502 1503 params = (uchar_t *)pub_template[params_idx].oa_value; 1504 params_len = pub_template[params_idx].oa_value_len; 1505 1506 value = (uchar_t *)pri_out_template[value_idx].oa_value; 1507 valuelen = (int)pri_out_template[value_idx].oa_value_len; 1508 point = (uchar_t *)pub_out_template[point_idx].oa_value; 1509 pointlen = (int)pub_out_template[point_idx].oa_value_len; 1510 1511 /* ASN1 check */ 1512 if (params[0] != 0x06 || 1513 params[1] != params_len - 2) { 1514 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 1515 } 1516 params_item.data = params; 1517 params_item.len = params_len; 1518 kmflag = crypto_kmflag(req); 1519 if (EC_DecodeParams(¶ms_item, &ecparams, kmflag) != SECSuccess) { 1520 /* bad curve OID */ 1521 return (CRYPTO_ARGUMENTS_BAD); 1522 } 1523 1524 if (EC_NewKey(ecparams, &privKey, kmflag) != SECSuccess) { 1525 free_ecparams(ecparams, B_TRUE); 1526 return (CRYPTO_FAILED); 1527 } 1528 1529 xylen = privKey->publicValue.len; 1530 /* ASSERT that xylen - 1 is divisible by 2 */ 1531 if (xylen > pointlen) { 1532 rv = CRYPTO_BUFFER_TOO_SMALL; 1533 goto out; 1534 } 1535 1536 if (privKey->privateValue.len > valuelen) { 1537 rv = CRYPTO_BUFFER_TOO_SMALL; 1538 goto out; 1539 } 1540 bcopy(privKey->privateValue.data, value, privKey->privateValue.len); 1541 pri_out_template[value_idx].oa_value_len = privKey->privateValue.len; 1542 1543 bcopy(privKey->publicValue.data, point, xylen); 1544 pub_out_template[point_idx].oa_value_len = xylen; 1545 1546 out: 1547 free_ecprivkey(privKey); 1548 free_ecparams(ecparams, B_TRUE); 1549 return (rv); 1550 } 1551 1552 /* ARGSUSED */ 1553 static int 1554 ecc_nostore_key_derive(crypto_provider_handle_t provider, 1555 crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1556 crypto_key_t *base_key, crypto_object_attribute_t *in_attrs, 1557 uint_t in_attr_count, crypto_object_attribute_t *out_attrs, 1558 uint_t out_attr_count, crypto_req_handle_t req) 1559 { 1560 int rv = CRYPTO_SUCCESS; 1561 int params_idx, value_idx = -1, out_value_idx = -1; 1562 ulong_t key_type; 1563 ulong_t key_len; 1564 crypto_object_attribute_t *attrs; 1565 ECParams *ecparams; 1566 SECKEYECParams params_item; 1567 CK_ECDH1_DERIVE_PARAMS *mech_param; 1568 SECItem public_value_item, private_value_item, secret_item; 1569 int kmflag; 1570 1571 if (mechanism->cm_type != ECDH1_DERIVE_MECH_INFO_TYPE) { 1572 return (CRYPTO_MECHANISM_INVALID); 1573 } 1574 1575 ASSERT(IS_P2ALIGNED(mechanism->cm_param, sizeof (uint64_t))); 1576 /* LINTED: pointer alignment */ 1577 mech_param = (CK_ECDH1_DERIVE_PARAMS *)mechanism->cm_param; 1578 if (mech_param->kdf != CKD_NULL) { 1579 return (CRYPTO_MECHANISM_PARAM_INVALID); 1580 } 1581 1582 if ((base_key->ck_format != CRYPTO_KEY_ATTR_LIST) || 1583 (base_key->ck_count == 0)) { 1584 return (CRYPTO_ARGUMENTS_BAD); 1585 } 1586 1587 if ((rv = get_template_attr_ulong(in_attrs, in_attr_count, 1588 CKA_KEY_TYPE, &key_type)) != CRYPTO_SUCCESS) { 1589 return (rv); 1590 } 1591 1592 switch (key_type) { 1593 case CKK_DES: 1594 key_len = DES_KEYSIZE; 1595 break; 1596 case CKK_DES2: 1597 key_len = DES2_KEYSIZE; 1598 break; 1599 case CKK_DES3: 1600 key_len = DES3_KEYSIZE; 1601 break; 1602 case CKK_RC4: 1603 case CKK_AES: 1604 case CKK_GENERIC_SECRET: 1605 if ((rv = get_template_attr_ulong(in_attrs, in_attr_count, 1606 CKA_VALUE_LEN, &key_len)) != CRYPTO_SUCCESS) { 1607 return (rv); 1608 } 1609 break; 1610 default: 1611 key_len = 0; 1612 } 1613 1614 attrs = base_key->ck_attrs; 1615 if ((value_idx = find_attr(attrs, base_key->ck_count, 1616 CKA_VALUE)) == -1) { 1617 return (CRYPTO_TEMPLATE_INCOMPLETE); 1618 } 1619 1620 if ((params_idx = find_attr(attrs, base_key->ck_count, 1621 CKA_EC_PARAMS)) == -1) { 1622 return (CRYPTO_TEMPLATE_INCOMPLETE); 1623 } 1624 1625 private_value_item.data = (uchar_t *)attrs[value_idx].oa_value; 1626 private_value_item.len = attrs[value_idx].oa_value_len; 1627 1628 params_item.len = attrs[params_idx].oa_value_len; 1629 params_item.data = (uchar_t *)attrs[params_idx].oa_value; 1630 1631 /* ASN1 check */ 1632 if (params_item.data[0] != 0x06 || 1633 params_item.data[1] != params_item.len - 2) { 1634 return (CRYPTO_ATTRIBUTE_VALUE_INVALID); 1635 } 1636 kmflag = crypto_kmflag(req); 1637 if (EC_DecodeParams(¶ms_item, &ecparams, kmflag) != SECSuccess) { 1638 /* bad curve OID */ 1639 return (CRYPTO_ARGUMENTS_BAD); 1640 } 1641 1642 public_value_item.data = (uchar_t *)mech_param->pPublicData; 1643 public_value_item.len = mech_param->ulPublicDataLen; 1644 1645 if ((out_value_idx = find_attr(out_attrs, out_attr_count, 1646 CKA_VALUE)) == -1) { 1647 rv = CRYPTO_TEMPLATE_INCOMPLETE; 1648 goto out; 1649 } 1650 secret_item.data = NULL; 1651 secret_item.len = 0; 1652 1653 if (ECDH_Derive(&public_value_item, ecparams, &private_value_item, 1654 B_FALSE, &secret_item, kmflag) != SECSuccess) { 1655 free_ecparams(ecparams, B_TRUE); 1656 return (CRYPTO_FAILED); 1657 } else { 1658 rv = CRYPTO_SUCCESS; 1659 } 1660 1661 if (key_len == 0) 1662 key_len = secret_item.len; 1663 1664 if (key_len > secret_item.len) { 1665 rv = CRYPTO_ATTRIBUTE_VALUE_INVALID; 1666 goto out; 1667 } 1668 if (key_len > out_attrs[out_value_idx].oa_value_len) { 1669 rv = CRYPTO_BUFFER_TOO_SMALL; 1670 goto out; 1671 } 1672 bcopy(secret_item.data + secret_item.len - key_len, 1673 (uchar_t *)out_attrs[out_value_idx].oa_value, key_len); 1674 out_attrs[out_value_idx].oa_value_len = key_len; 1675 out: 1676 free_ecparams(ecparams, B_TRUE); 1677 SECITEM_FreeItem(&secret_item, B_FALSE); 1678 return (rv); 1679 } 1680 1681 static void 1682 free_ecparams(ECParams *params, boolean_t freeit) 1683 { 1684 SECITEM_FreeItem(¶ms->fieldID.u.prime, B_FALSE); 1685 SECITEM_FreeItem(¶ms->curve.a, B_FALSE); 1686 SECITEM_FreeItem(¶ms->curve.b, B_FALSE); 1687 SECITEM_FreeItem(¶ms->curve.seed, B_FALSE); 1688 SECITEM_FreeItem(¶ms->base, B_FALSE); 1689 SECITEM_FreeItem(¶ms->order, B_FALSE); 1690 SECITEM_FreeItem(¶ms->DEREncoding, B_FALSE); 1691 SECITEM_FreeItem(¶ms->curveOID, B_FALSE); 1692 if (freeit) 1693 kmem_free(params, sizeof (ECParams)); 1694 } 1695 1696 static void 1697 free_ecprivkey(ECPrivateKey *key) 1698 { 1699 free_ecparams(&key->ecParams, B_FALSE); 1700 SECITEM_FreeItem(&key->publicValue, B_FALSE); 1701 bzero(key->privateValue.data, key->privateValue.len); 1702 SECITEM_FreeItem(&key->privateValue, B_FALSE); 1703 SECITEM_FreeItem(&key->version, B_FALSE); 1704 kmem_free(key, sizeof (ECPrivateKey)); 1705 } 1706