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