1 /* 2 * The Initial Developer of the Original Code is International 3 * Business Machines Corporation. Portions created by IBM 4 * Corporation are Copyright (C) 2005 International Business 5 * Machines Corporation. All Rights Reserved. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the Common Public License as published by 9 * IBM Corporation; either version 1 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * Common Public License for more details. 16 * 17 * You should have received a copy of the Common Public License 18 * along with this program; if not, a copy can be viewed at 19 * http://www.opensource.org/licenses/cpl1.0.php. 20 */ 21 /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include "tpmtok_int.h" 28 29 extern CK_RV 30 token_specific_rsa_verify_recover( 31 TSS_HCONTEXT hContext, 32 CK_BYTE *in_data, 33 CK_ULONG in_data_len, 34 CK_BYTE *out_data, 35 CK_ULONG *out_data_len, 36 OBJECT *key_obj); 37 38 CK_RV 39 ckm_rsa_key_pair_gen(TSS_HCONTEXT hContext, 40 TEMPLATE * publ_tmpl, 41 TEMPLATE * priv_tmpl) 42 { 43 CK_RV rc; 44 45 rc = token_specific.t_rsa_generate_keypair( 46 hContext, publ_tmpl, priv_tmpl); 47 48 return (rc); 49 } 50 51 static CK_RV 52 ckm_rsa_encrypt( 53 TSS_HCONTEXT hContext, 54 CK_BYTE * in_data, 55 CK_ULONG in_data_len, 56 CK_BYTE * out_data, 57 CK_ULONG * out_data_len, 58 OBJECT * key_obj) 59 { 60 CK_ATTRIBUTE * attr = NULL; 61 CK_OBJECT_CLASS keyclass; 62 CK_RV rc; 63 64 rc = template_attribute_find(key_obj->template, CKA_CLASS, &attr); 65 if (rc == FALSE) { 66 return (CKR_FUNCTION_FAILED); 67 } else 68 keyclass = *(CK_OBJECT_CLASS *)attr->pValue; 69 70 if (keyclass != CKO_PUBLIC_KEY) { 71 return (CKR_FUNCTION_FAILED); 72 } 73 74 rc = token_specific.t_rsa_encrypt(hContext, 75 in_data, in_data_len, 76 out_data, out_data_len, key_obj); 77 78 return (rc); 79 } 80 81 static CK_RV 82 ckm_rsa_decrypt( 83 TSS_HCONTEXT hContext, 84 CK_BYTE * in_data, 85 CK_ULONG in_data_len, 86 CK_BYTE * out_data, 87 CK_ULONG * out_data_len, 88 OBJECT * key_obj) { 89 CK_ATTRIBUTE * attr = NULL; 90 CK_OBJECT_CLASS keyclass; 91 CK_RV rc; 92 93 94 rc = template_attribute_find(key_obj->template, CKA_CLASS, &attr); 95 if (rc == FALSE) { 96 return (CKR_FUNCTION_FAILED); 97 } 98 else 99 keyclass = *(CK_OBJECT_CLASS *)attr->pValue; 100 101 // this had better be a private key 102 // 103 if (keyclass != CKO_PRIVATE_KEY) { 104 return (CKR_FUNCTION_FAILED); 105 } 106 rc = token_specific.t_rsa_decrypt(hContext, 107 in_data, in_data_len, 108 out_data, out_data_len, key_obj); 109 110 return (rc); 111 } 112 113 static CK_RV 114 ckm_rsa_sign( 115 TSS_HCONTEXT hContext, 116 CK_BYTE * in_data, 117 CK_ULONG in_data_len, 118 CK_BYTE * out_data, 119 CK_ULONG * out_data_len, 120 OBJECT * key_obj) { 121 CK_ATTRIBUTE * attr = NULL; 122 CK_OBJECT_CLASS keyclass; 123 CK_RV rc; 124 125 126 rc = template_attribute_find(key_obj->template, CKA_CLASS, &attr); 127 if (rc == FALSE) { 128 return (CKR_FUNCTION_FAILED); 129 } else { 130 keyclass = *(CK_OBJECT_CLASS *)attr->pValue; 131 } 132 133 if (keyclass != CKO_PRIVATE_KEY) { 134 return (CKR_FUNCTION_FAILED); 135 } 136 rc = token_specific.t_rsa_sign( 137 hContext, in_data, in_data_len, out_data, 138 out_data_len, key_obj); 139 140 return (rc); 141 } 142 143 static CK_RV 144 ckm_rsa_verify( 145 TSS_HCONTEXT hContext, 146 CK_BYTE * in_data, 147 CK_ULONG in_data_len, 148 CK_BYTE * out_data, 149 CK_ULONG out_data_len, 150 OBJECT * key_obj) { 151 CK_ATTRIBUTE * attr = NULL; 152 CK_OBJECT_CLASS keyclass; 153 CK_RV rc; 154 155 156 rc = template_attribute_find(key_obj->template, CKA_CLASS, &attr); 157 if (rc == FALSE) { 158 return (CKR_FUNCTION_FAILED); 159 } 160 else 161 keyclass = *(CK_OBJECT_CLASS *)attr->pValue; 162 163 if (keyclass != CKO_PUBLIC_KEY) { 164 return (CKR_FUNCTION_FAILED); 165 } 166 rc = token_specific.t_rsa_verify(hContext, 167 in_data, in_data_len, out_data, 168 out_data_len, key_obj); 169 170 return (rc); 171 } 172 173 /*ARGSUSED*/ 174 CK_RV 175 rsa_pkcs_encrypt(SESSION *sess, 176 CK_BBOOL length_only, 177 ENCR_DECR_CONTEXT *ctx, 178 CK_BYTE *in_data, 179 CK_ULONG in_data_len, 180 CK_BYTE *out_data, 181 CK_ULONG *out_data_len) 182 { 183 OBJECT *key_obj = NULL; 184 CK_ATTRIBUTE *attr = NULL; 185 CK_ULONG modulus_bytes; 186 CK_BBOOL flag; 187 CK_RV rc; 188 189 190 rc = object_mgr_find_in_map1(sess->hContext, ctx->key, &key_obj); 191 if (rc != CKR_OK) { 192 return (rc); 193 } 194 flag = template_attribute_find(key_obj->template, CKA_MODULUS, &attr); 195 if (flag == FALSE) { 196 return (CKR_FUNCTION_FAILED); 197 } else { 198 modulus_bytes = attr->ulValueLen; 199 } 200 201 if (length_only == TRUE) { 202 *out_data_len = modulus_bytes; 203 return (CKR_OK); 204 } 205 206 if (*out_data_len < modulus_bytes) { 207 *out_data_len = modulus_bytes; 208 return (CKR_BUFFER_TOO_SMALL); 209 } 210 211 rc = ckm_rsa_encrypt(sess->hContext, in_data, in_data_len, out_data, 212 out_data_len, key_obj); 213 return (rc); 214 } 215 216 /*ARGSUSED*/ 217 CK_RV 218 rsa_pkcs_decrypt(SESSION *sess, 219 CK_BBOOL length_only, 220 ENCR_DECR_CONTEXT *ctx, 221 CK_BYTE *in_data, 222 CK_ULONG in_data_len, 223 CK_BYTE *out_data, 224 CK_ULONG *out_data_len) 225 { 226 OBJECT *key_obj = NULL; 227 CK_ATTRIBUTE *attr = NULL; 228 CK_ULONG modulus_bytes; 229 CK_BBOOL flag; 230 CK_RV rc; 231 232 233 rc = object_mgr_find_in_map1(sess->hContext, ctx->key, &key_obj); 234 if (rc != CKR_OK) { 235 return (rc); 236 } 237 flag = template_attribute_find(key_obj->template, CKA_MODULUS, &attr); 238 if (flag == FALSE) 239 return (CKR_FUNCTION_FAILED); 240 else 241 modulus_bytes = attr->ulValueLen; 242 243 if (in_data_len != modulus_bytes) { 244 return (CKR_ENCRYPTED_DATA_LEN_RANGE); 245 } 246 if (length_only == TRUE) { 247 *out_data_len = modulus_bytes - 11; 248 return (CKR_OK); 249 } 250 251 rc = ckm_rsa_decrypt(sess->hContext, in_data, 252 modulus_bytes, out_data, 253 out_data_len, key_obj); 254 255 if (rc == CKR_DATA_LEN_RANGE) { 256 return (CKR_ENCRYPTED_DATA_LEN_RANGE); 257 } 258 return (rc); 259 } 260 261 CK_RV 262 rsa_pkcs_sign(SESSION *sess, 263 CK_BBOOL length_only, 264 SIGN_VERIFY_CONTEXT *ctx, 265 CK_BYTE *in_data, 266 CK_ULONG in_data_len, 267 CK_BYTE *out_data, 268 CK_ULONG *out_data_len) 269 { 270 OBJECT *key_obj = NULL; 271 CK_ATTRIBUTE *attr = NULL; 272 CK_ULONG modulus_bytes; 273 CK_BBOOL flag; 274 CK_RV rc; 275 276 277 if (! sess || ! ctx || ! out_data_len) { 278 return (CKR_FUNCTION_FAILED); 279 } 280 rc = object_mgr_find_in_map1(sess->hContext, ctx->key, &key_obj); 281 if (rc != CKR_OK) { 282 return (rc); 283 } 284 flag = template_attribute_find(key_obj->template, CKA_MODULUS, &attr); 285 if (flag == FALSE) 286 return (CKR_FUNCTION_FAILED); 287 else 288 modulus_bytes = attr->ulValueLen; 289 290 if (length_only == TRUE) { 291 *out_data_len = modulus_bytes; 292 return (CKR_OK); 293 } 294 295 if (*out_data_len < modulus_bytes) { 296 *out_data_len = modulus_bytes; 297 return (CKR_BUFFER_TOO_SMALL); 298 } 299 300 rc = ckm_rsa_sign(sess->hContext, in_data, in_data_len, out_data, 301 out_data_len, key_obj); 302 return (rc); 303 } 304 305 /*ARGSUSED*/ 306 CK_RV 307 rsa_pkcs_verify(SESSION * sess, 308 SIGN_VERIFY_CONTEXT * ctx, 309 CK_BYTE * in_data, 310 CK_ULONG in_data_len, 311 CK_BYTE * signature, 312 CK_ULONG sig_len) 313 { 314 OBJECT *key_obj = NULL; 315 CK_ATTRIBUTE *attr = NULL; 316 CK_ULONG modulus_bytes; 317 CK_BBOOL flag; 318 CK_RV rc; 319 320 rc = object_mgr_find_in_map1(sess->hContext, ctx->key, &key_obj); 321 if (rc != CKR_OK) { 322 return (rc); 323 } 324 flag = template_attribute_find(key_obj->template, CKA_MODULUS, &attr); 325 if (flag == FALSE) { 326 return (CKR_FUNCTION_FAILED); 327 } 328 else 329 modulus_bytes = attr->ulValueLen; 330 331 // check input data length restrictions 332 // 333 if (sig_len != modulus_bytes) { 334 return (CKR_SIGNATURE_LEN_RANGE); 335 } 336 // verify is a public key operation --> encrypt 337 // 338 rc = ckm_rsa_verify(sess->hContext, in_data, in_data_len, signature, 339 sig_len, key_obj); 340 341 return (rc); 342 } 343 344 CK_RV 345 rsa_pkcs_verify_recover(SESSION *sess, 346 CK_BBOOL length_only, 347 SIGN_VERIFY_CONTEXT *ctx, 348 CK_BYTE *signature, 349 CK_ULONG sig_len, 350 CK_BYTE *out_data, 351 CK_ULONG *out_data_len) 352 { 353 OBJECT *key_obj = NULL; 354 CK_ATTRIBUTE *attr = NULL; 355 CK_ULONG modulus_bytes; 356 CK_BBOOL flag; 357 CK_RV rc; 358 359 if (! sess || ! ctx || ! out_data_len) { 360 return (CKR_FUNCTION_FAILED); 361 } 362 rc = object_mgr_find_in_map1(sess->hContext, ctx->key, &key_obj); 363 if (rc != CKR_OK) { 364 return (rc); 365 } 366 flag = template_attribute_find(key_obj->template, CKA_MODULUS, &attr); 367 if (flag == FALSE) { 368 return (CKR_FUNCTION_FAILED); 369 } 370 else 371 modulus_bytes = attr->ulValueLen; 372 373 if (sig_len != modulus_bytes) { 374 return (CKR_SIGNATURE_LEN_RANGE); 375 } 376 if (length_only == TRUE) { 377 *out_data_len = modulus_bytes; 378 return (CKR_OK); 379 } 380 381 rc = token_specific_rsa_verify_recover(sess->hContext, 382 signature, modulus_bytes, out_data, out_data_len, key_obj); 383 384 return (rc); 385 } 386 387 CK_RV 388 rsa_hash_pkcs_sign(SESSION * sess, 389 CK_BBOOL length_only, 390 SIGN_VERIFY_CONTEXT * ctx, 391 CK_BYTE * in_data, 392 CK_ULONG in_data_len, 393 CK_BYTE * signature, 394 CK_ULONG * sig_len) 395 { 396 CK_BYTE * ber_data = NULL; 397 CK_BYTE * octet_str = NULL; 398 CK_BYTE * oid = NULL; 399 CK_BYTE * tmp = NULL; 400 401 CK_ULONG buf1[16]; 402 403 CK_BYTE hash[SHA1_DIGEST_LENGTH]; 404 DIGEST_CONTEXT digest_ctx; 405 SIGN_VERIFY_CONTEXT sign_ctx; 406 CK_MECHANISM digest_mech; 407 CK_MECHANISM sign_mech; 408 CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; 409 CK_RV rc; 410 411 if (! sess || ! ctx || ! in_data) { 412 return (CKR_FUNCTION_FAILED); 413 } 414 (void) memset(&digest_ctx, 0x0, sizeof (digest_ctx)); 415 (void) memset(&sign_ctx, 0x0, sizeof (sign_ctx)); 416 417 if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { 418 digest_mech.mechanism = CKM_MD5; 419 oid = ber_AlgMd5; 420 oid_len = ber_AlgMd5Len; 421 hash_len = MD5_DIGEST_LENGTH; 422 } else { 423 digest_mech.mechanism = CKM_SHA_1; 424 oid = ber_AlgSha1; 425 oid_len = ber_AlgSha1Len; 426 hash_len = SHA1_DIGEST_LENGTH; 427 } 428 429 digest_mech.ulParameterLen = 0; 430 digest_mech.pParameter = NULL; 431 432 rc = digest_mgr_init(sess, &digest_ctx, &digest_mech); 433 if (rc != CKR_OK) { 434 goto error; 435 } 436 rc = digest_mgr_digest(sess, length_only, &digest_ctx, in_data, 437 in_data_len, hash, &hash_len); 438 if (rc != CKR_OK) 439 goto error; 440 441 rc = ber_encode_OCTET_STRING(FALSE, &octet_str, &octet_str_len, 442 hash, hash_len); 443 if (rc != CKR_OK) { 444 goto error; 445 } 446 tmp = (CK_BYTE *)buf1; 447 (void) memcpy(tmp, oid, oid_len); 448 (void) memcpy(tmp + oid_len, octet_str, octet_str_len); 449 450 rc = ber_encode_SEQUENCE(FALSE, &ber_data, &ber_data_len, 451 tmp, (oid_len + octet_str_len)); 452 if (rc != CKR_OK) 453 goto error; 454 455 sign_mech.mechanism = CKM_RSA_PKCS; 456 sign_mech.ulParameterLen = 0; 457 sign_mech.pParameter = NULL; 458 459 rc = sign_mgr_init(sess, &sign_ctx, &sign_mech, FALSE, ctx->key); 460 if (rc != CKR_OK) 461 goto error; 462 463 rc = sign_mgr_sign(sess, length_only, &sign_ctx, ber_data, 464 ber_data_len, signature, sig_len); 465 466 error: 467 if (octet_str) free(octet_str); 468 if (ber_data) free(ber_data); 469 (void) digest_mgr_cleanup(&digest_ctx); 470 (void) sign_mgr_cleanup(&sign_ctx); 471 return (rc); 472 } 473 474 CK_RV 475 rsa_hash_pkcs_sign_update( 476 SESSION * sess, 477 SIGN_VERIFY_CONTEXT * ctx, 478 CK_BYTE * in_data, 479 CK_ULONG in_data_len) 480 { 481 RSA_DIGEST_CONTEXT * context = NULL; 482 CK_MECHANISM digest_mech; 483 CK_RV rc; 484 485 if (! sess || ! ctx || ! in_data) 486 return (CKR_FUNCTION_FAILED); 487 488 context = (RSA_DIGEST_CONTEXT *)ctx->context; 489 490 if (context->flag == FALSE) { 491 if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) 492 digest_mech.mechanism = CKM_MD5; 493 else 494 digest_mech.mechanism = CKM_SHA_1; 495 496 digest_mech.ulParameterLen = 0; 497 digest_mech.pParameter = NULL; 498 499 rc = digest_mgr_init(sess, &context->hash_context, 500 &digest_mech); 501 if (rc != CKR_OK) { 502 goto error; 503 } 504 context->flag = TRUE; 505 } 506 507 rc = digest_mgr_digest_update(sess, &context->hash_context, 508 in_data, in_data_len); 509 if (rc != CKR_OK) { 510 goto error; 511 } 512 return (CKR_OK); 513 error: 514 (void) digest_mgr_cleanup(&context->hash_context); 515 return (rc); 516 } 517 518 CK_RV 519 rsa_hash_pkcs_verify(SESSION * sess, 520 SIGN_VERIFY_CONTEXT * ctx, 521 CK_BYTE * in_data, 522 CK_ULONG in_data_len, 523 CK_BYTE * signature, 524 CK_ULONG sig_len) 525 { 526 CK_BYTE * ber_data = NULL; 527 CK_BYTE * octet_str = NULL; 528 CK_BYTE * oid = NULL; 529 CK_BYTE * tmp = NULL; 530 531 CK_ULONG buf1[16]; 532 CK_BYTE hash[SHA1_DIGEST_LENGTH]; 533 DIGEST_CONTEXT digest_ctx; 534 SIGN_VERIFY_CONTEXT verify_ctx; 535 CK_MECHANISM digest_mech; 536 CK_MECHANISM verify_mech; 537 CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; 538 CK_RV rc; 539 540 if (! sess || ! ctx || ! in_data) { 541 return (CKR_FUNCTION_FAILED); 542 } 543 (void) memset(&digest_ctx, 0x0, sizeof (digest_ctx)); 544 (void) memset(&verify_ctx, 0x0, sizeof (verify_ctx)); 545 546 if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { 547 digest_mech.mechanism = CKM_MD5; 548 oid = ber_AlgMd5; 549 oid_len = ber_AlgMd5Len; 550 hash_len = MD5_DIGEST_LENGTH; 551 } else { 552 digest_mech.mechanism = CKM_SHA_1; 553 oid = ber_AlgSha1; 554 oid_len = ber_AlgSha1Len; 555 hash_len = SHA1_DIGEST_LENGTH; 556 } 557 558 digest_mech.ulParameterLen = 0; 559 digest_mech.pParameter = NULL; 560 561 rc = digest_mgr_init(sess, &digest_ctx, &digest_mech); 562 if (rc != CKR_OK) { 563 goto done; 564 } 565 rc = digest_mgr_digest(sess, FALSE, &digest_ctx, in_data, 566 in_data_len, hash, &hash_len); 567 if (rc != CKR_OK) { 568 goto done; 569 } 570 rc = ber_encode_OCTET_STRING(FALSE, &octet_str, &octet_str_len, 571 hash, hash_len); 572 if (rc != CKR_OK) 573 goto done; 574 tmp = (CK_BYTE *)buf1; 575 (void) memcpy(tmp, oid, oid_len); 576 (void) memcpy(tmp + oid_len, octet_str, octet_str_len); 577 578 rc = ber_encode_SEQUENCE(FALSE, &ber_data, &ber_data_len, tmp, 579 (oid_len + octet_str_len)); 580 if (rc != CKR_OK) { 581 goto done; 582 } 583 584 verify_mech.mechanism = CKM_RSA_PKCS; 585 verify_mech.ulParameterLen = 0; 586 verify_mech.pParameter = NULL; 587 588 rc = verify_mgr_init(sess, &verify_ctx, &verify_mech, FALSE, ctx->key); 589 if (rc != CKR_OK) { 590 goto done; 591 } 592 rc = verify_mgr_verify(sess, &verify_ctx, ber_data, 593 ber_data_len, signature, sig_len); 594 done: 595 if (octet_str) free(octet_str); 596 if (ber_data) free(ber_data); 597 598 (void) digest_mgr_cleanup(&digest_ctx); 599 (void) sign_mgr_cleanup(&verify_ctx); 600 return (rc); 601 } 602 603 CK_RV 604 rsa_hash_pkcs_verify_update(SESSION * sess, 605 SIGN_VERIFY_CONTEXT * ctx, 606 CK_BYTE *in_data, 607 CK_ULONG in_data_len) 608 { 609 RSA_DIGEST_CONTEXT * context = NULL; 610 CK_MECHANISM digest_mech; 611 CK_RV rc; 612 613 if (! sess || ! ctx || ! in_data) { 614 return (CKR_FUNCTION_FAILED); 615 } 616 context = (RSA_DIGEST_CONTEXT *)ctx->context; 617 618 if (context->flag == FALSE) { 619 if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) 620 digest_mech.mechanism = CKM_MD5; 621 else 622 digest_mech.mechanism = CKM_SHA_1; 623 624 digest_mech.ulParameterLen = 0; 625 digest_mech.pParameter = NULL; 626 627 rc = digest_mgr_init(sess, &context->hash_context, 628 &digest_mech); 629 if (rc != CKR_OK) 630 goto error; 631 context->flag = TRUE; 632 } 633 634 rc = digest_mgr_digest_update(sess, &context->hash_context, 635 in_data, in_data_len); 636 if (rc != CKR_OK) 637 goto error; 638 return (CKR_OK); 639 error: 640 (void) digest_mgr_cleanup(&context->hash_context); 641 return (rc); 642 } 643 644 CK_RV 645 rsa_hash_pkcs_sign_final(SESSION * sess, 646 CK_BBOOL length_only, 647 SIGN_VERIFY_CONTEXT * ctx, 648 CK_BYTE * signature, 649 CK_ULONG * sig_len) 650 { 651 CK_BYTE * ber_data = NULL; 652 CK_BYTE * octet_str = NULL; 653 CK_BYTE * oid = NULL; 654 CK_BYTE * tmp = NULL; 655 656 CK_ULONG buf1[16]; 657 CK_BYTE hash[SHA1_DIGEST_LENGTH]; 658 RSA_DIGEST_CONTEXT * context = NULL; 659 CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; 660 CK_MECHANISM sign_mech; 661 SIGN_VERIFY_CONTEXT sign_ctx; 662 CK_RV rc; 663 664 if (! sess || ! ctx || ! sig_len) { 665 return (CKR_FUNCTION_FAILED); 666 } 667 668 if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { 669 oid = ber_AlgMd5; 670 oid_len = ber_AlgMd5Len; 671 hash_len = MD5_DIGEST_LENGTH; 672 } else { 673 oid = ber_AlgSha1; 674 oid_len = ber_AlgSha1Len; 675 hash_len = SHA1_DIGEST_LENGTH; 676 } 677 678 (void) memset(&sign_ctx, 0x0, sizeof (sign_ctx)); 679 680 context = (RSA_DIGEST_CONTEXT *)ctx->context; 681 682 rc = digest_mgr_digest_final(sess, 683 &context->hash_context, hash, &hash_len); 684 if (rc != CKR_OK) { 685 goto done; 686 } 687 688 rc = ber_encode_OCTET_STRING(FALSE, &octet_str, &octet_str_len, 689 hash, hash_len); 690 if (rc != CKR_OK) { 691 goto done; 692 } 693 tmp = (CK_BYTE *)buf1; 694 (void) memcpy(tmp, oid, oid_len); 695 (void) memcpy(tmp + oid_len, octet_str, octet_str_len); 696 697 rc = ber_encode_SEQUENCE(FALSE, &ber_data, &ber_data_len, 698 tmp, (oid_len + octet_str_len)); 699 if (rc != CKR_OK) { 700 goto done; 701 } 702 sign_mech.mechanism = CKM_RSA_PKCS; 703 sign_mech.ulParameterLen = 0; 704 sign_mech.pParameter = NULL; 705 706 rc = sign_mgr_init(sess, &sign_ctx, &sign_mech, FALSE, ctx->key); 707 if (rc != CKR_OK) { 708 goto done; 709 } 710 rc = sign_mgr_sign(sess, length_only, &sign_ctx, ber_data, 711 ber_data_len, signature, sig_len); 712 713 if (length_only == TRUE || rc == CKR_BUFFER_TOO_SMALL) { 714 (void) sign_mgr_cleanup(&sign_ctx); 715 return (rc); 716 } 717 718 done: 719 if (octet_str) free(octet_str); 720 if (ber_data) free(ber_data); 721 722 (void) digest_mgr_cleanup(&context->hash_context); 723 (void) sign_mgr_cleanup(&sign_ctx); 724 return (rc); 725 } 726 727 CK_RV 728 rsa_hash_pkcs_verify_final(SESSION * sess, 729 SIGN_VERIFY_CONTEXT * ctx, 730 CK_BYTE * signature, 731 CK_ULONG sig_len) 732 { 733 CK_BYTE * ber_data = NULL; 734 CK_BYTE * octet_str = NULL; 735 CK_BYTE * oid = NULL; 736 CK_BYTE * tmp = NULL; 737 738 CK_ULONG buf1[16]; 739 CK_BYTE hash[SHA1_DIGEST_LENGTH]; 740 RSA_DIGEST_CONTEXT * context = NULL; 741 CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len; 742 CK_MECHANISM verify_mech; 743 SIGN_VERIFY_CONTEXT verify_ctx; 744 CK_RV rc; 745 746 if (! sess || ! ctx || ! signature) { 747 return (CKR_FUNCTION_FAILED); 748 } 749 if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) { 750 oid = ber_AlgMd5; 751 oid_len = ber_AlgMd5Len; 752 hash_len = MD5_DIGEST_LENGTH; 753 } else { 754 oid = ber_AlgSha1; 755 oid_len = ber_AlgSha1Len; 756 hash_len = SHA1_DIGEST_LENGTH; 757 } 758 759 (void) memset(&verify_ctx, 0x0, sizeof (verify_ctx)); 760 761 context = (RSA_DIGEST_CONTEXT *)ctx->context; 762 763 rc = digest_mgr_digest_final(sess, &context->hash_context, 764 hash, &hash_len); 765 if (rc != CKR_OK) { 766 goto done; 767 } 768 rc = ber_encode_OCTET_STRING(FALSE, &octet_str, &octet_str_len, 769 hash, hash_len); 770 if (rc != CKR_OK) { 771 goto done; 772 } 773 tmp = (CK_BYTE *)buf1; 774 (void) memcpy(tmp, oid, oid_len); 775 (void) memcpy(tmp + oid_len, octet_str, octet_str_len); 776 777 rc = ber_encode_SEQUENCE(FALSE, &ber_data, &ber_data_len, 778 tmp, (oid_len + octet_str_len)); 779 if (rc != CKR_OK) { 780 goto done; 781 } 782 verify_mech.mechanism = CKM_RSA_PKCS; 783 verify_mech.ulParameterLen = 0; 784 verify_mech.pParameter = NULL; 785 786 rc = verify_mgr_init(sess, &verify_ctx, &verify_mech, FALSE, ctx->key); 787 if (rc != CKR_OK) { 788 goto done; 789 } 790 rc = verify_mgr_verify(sess, &verify_ctx, ber_data, 791 ber_data_len, signature, sig_len); 792 done: 793 if (octet_str) free(octet_str); 794 if (ber_data) free(ber_data); 795 (void) digest_mgr_cleanup(&context->hash_context); 796 (void) verify_mgr_cleanup(&verify_ctx); 797 return (rc); 798 } 799