1 /* 2 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 /* crypto/engine/hw_pk11.c */ 9 /* This product includes software developed by the OpenSSL Project for 10 * use in the OpenSSL Toolkit (http://www.openssl.org/). 11 * 12 * This project also referenced hw_pkcs11-0.9.7b.patch written by 13 * Afchine Madjlessi. 14 */ 15 /* ==================================================================== 16 * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions 20 * are met: 21 * 22 * 1. Redistributions of source code must retain the above copyright 23 * notice, this list of conditions and the following disclaimer. 24 * 25 * 2. Redistributions in binary form must reproduce the above copyright 26 * notice, this list of conditions and the following disclaimer in 27 * the documentation and/or other materials provided with the 28 * distribution. 29 * 30 * 3. All advertising materials mentioning features or use of this 31 * software must display the following acknowledgment: 32 * "This product includes software developed by the OpenSSL Project 33 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 34 * 35 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 36 * endorse or promote products derived from this software without 37 * prior written permission. For written permission, please contact 38 * licensing@OpenSSL.org. 39 * 40 * 5. Products derived from this software may not be called "OpenSSL" 41 * nor may "OpenSSL" appear in their names without prior written 42 * permission of the OpenSSL Project. 43 * 44 * 6. Redistributions of any form whatsoever must retain the following 45 * acknowledgment: 46 * "This product includes software developed by the OpenSSL Project 47 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 50 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 52 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 53 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 54 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 55 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 56 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 58 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 59 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 60 * OF THE POSSIBILITY OF SUCH DAMAGE. 61 * ==================================================================== 62 * 63 * This product includes cryptographic software written by Eric Young 64 * (eay@cryptsoft.com). This product includes software written by Tim 65 * Hudson (tjh@cryptsoft.com). 66 * 67 */ 68 69 #include <stdio.h> 70 #include <assert.h> 71 #include <stdlib.h> 72 #include <string.h> 73 #include <sys/types.h> 74 #include <unistd.h> 75 76 #include <openssl/e_os2.h> 77 #include <openssl/engine.h> 78 #include <openssl/dso.h> 79 #include <openssl/err.h> 80 #include <openssl/bn.h> 81 #include <openssl/md5.h> 82 #include <openssl/pem.h> 83 #include <openssl/rsa.h> 84 #include <openssl/rand.h> 85 #include <openssl/objects.h> 86 #include <openssl/x509.h> 87 #include <cryptlib.h> 88 89 #ifndef OPENSSL_NO_HW 90 #ifndef OPENSSL_NO_HW_PK11 91 92 #undef DEBUG_SLOT_SELECTION 93 94 #include "security/cryptoki.h" 95 #include "security/pkcs11.h" 96 #include "hw_pk11_err.c" 97 98 99 /* The head of the free PK11 session list */ 100 static struct PK11_SESSION_st *free_session = NULL; 101 102 /* Create all secret key objects in a global session so that they are available 103 * to use for other sessions. These other sessions may be opened or closed 104 * without losing the secret key objects */ 105 static CK_SESSION_HANDLE global_session = CK_INVALID_HANDLE; 106 107 /* ENGINE level stuff */ 108 static int pk11_init(ENGINE *e); 109 static int pk11_library_init(ENGINE *e); 110 static int pk11_finish(ENGINE *e); 111 static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); 112 static int pk11_destroy(ENGINE *e); 113 114 /* RAND stuff */ 115 static void pk11_rand_seed(const void *buf, int num); 116 static void pk11_rand_add(const void *buf, int num, double add_entropy); 117 static void pk11_rand_cleanup(void); 118 static int pk11_rand_bytes(unsigned char *buf, int num); 119 static int pk11_rand_status(void); 120 121 /* These functions are also used in other files */ 122 PK11_SESSION *pk11_get_session(); 123 void pk11_return_session(PK11_SESSION *sp); 124 int pk11_destroy_rsa_key_objects(PK11_SESSION *session); 125 int pk11_destroy_dsa_key_objects(PK11_SESSION *session); 126 int pk11_destroy_dh_key_objects(PK11_SESSION *session); 127 128 /* Local helper functions */ 129 static int pk11_free_all_sessions(); 130 static int pk11_setup_session(PK11_SESSION *sp); 131 static int pk11_destroy_cipher_key_objects(PK11_SESSION *session); 132 static int pk11_destroy_object(CK_SESSION_HANDLE session, 133 CK_OBJECT_HANDLE oh); 134 static const char *get_PK11_LIBNAME(void); 135 static void free_PK11_LIBNAME(void); 136 static long set_PK11_LIBNAME(const char *name); 137 138 /* Symmetric cipher and digest support functions */ 139 static int cipher_nid_to_pk11(int nid); 140 static int pk11_usable_ciphers(const int **nids); 141 static int pk11_usable_digests(const int **nids); 142 static int pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, 143 const unsigned char *iv, int enc); 144 static int pk11_cipher_final(PK11_SESSION *sp); 145 static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 146 const unsigned char *in, unsigned int inl); 147 static int pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx); 148 static int pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, 149 const int **nids, int nid); 150 static int pk11_engine_digests(ENGINE *e, const EVP_MD **digest, 151 const int **nids, int nid); 152 static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx, 153 const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp); 154 static void check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key); 155 static int md_nid_to_pk11(int nid); 156 static int pk11_digest_init(EVP_MD_CTX *ctx); 157 static int pk11_digest_update(EVP_MD_CTX *ctx,const void *data, 158 size_t count); 159 static int pk11_digest_final(EVP_MD_CTX *ctx,unsigned char *md); 160 static int pk11_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from); 161 static int pk11_digest_cleanup(EVP_MD_CTX *ctx); 162 163 static int pk11_choose_slot(); 164 static int pk11_count_symmetric_cipher(int slot_id, CK_MECHANISM_TYPE mech, 165 int *current_slot_n_cipher, int *local_cipher_nids, int id); 166 static int pk11_count_digest(int slot_id, CK_MECHANISM_TYPE mech, 167 int *current_slot_n_digest, int *local_digest_nids, int id); 168 169 /* Index for the supported ciphers */ 170 #define PK11_DES_CBC 0 171 #define PK11_DES3_CBC 1 172 #define PK11_AES_CBC 2 173 #define PK11_RC4 3 174 175 /* Index for the supported digests */ 176 #define PK11_MD5 0 177 #define PK11_SHA1 1 178 179 #define PK11_CIPHER_MAX 4 /* Max num of ciphers supported */ 180 #define PK11_DIGEST_MAX 2 /* Max num of digests supported */ 181 182 #define PK11_KEY_LEN_MAX 24 183 184 static int cipher_nids[PK11_CIPHER_MAX]; 185 static int digest_nids[PK11_DIGEST_MAX]; 186 static int cipher_count = 0; 187 static int digest_count = 0; 188 static CK_BBOOL pk11_have_rsa = CK_FALSE; 189 static CK_BBOOL pk11_have_dsa = CK_FALSE; 190 static CK_BBOOL pk11_have_dh = CK_FALSE; 191 static CK_BBOOL pk11_have_random = CK_FALSE; 192 193 typedef struct PK11_CIPHER_st 194 { 195 int id; 196 int nid; 197 int ivmax; 198 int key_len; 199 CK_KEY_TYPE key_type; 200 CK_MECHANISM mech; 201 } PK11_CIPHER; 202 203 static PK11_CIPHER ciphers[] = 204 { 205 {PK11_DES_CBC, NID_des_cbc, 8, 8, CKK_DES, 206 {CKM_DES_CBC, NULL, 0},}, 207 {PK11_DES3_CBC, NID_des_ede3_cbc, 8, 24, CKK_DES3, 208 {CKM_DES3_CBC, NULL, 0},}, 209 {PK11_AES_CBC, NID_aes_128_cbc, 16, 16, CKK_AES, 210 {CKM_AES_CBC, NULL, 0},}, 211 {PK11_RC4, NID_rc4, 0, 16, CKK_RC4, 212 {CKM_RC4, NULL, 0},}, 213 }; 214 215 typedef struct PK11_DIGEST_st 216 { 217 int id; 218 int nid; 219 CK_MECHANISM mech; 220 } PK11_DIGEST; 221 222 static PK11_DIGEST digests[] = 223 { 224 {PK11_MD5, NID_md5, {CKM_MD5, NULL, 0},}, 225 {PK11_SHA1, NID_sha1, {CKM_SHA_1, NULL, 0},}, 226 {0, NID_undef, {0xFFFF, NULL, 0},}, 227 }; 228 229 /* Structure to be used for the cipher_data/md_data in 230 * EVP_CIPHER_CTX/EVP_MD_CTX structures in order to use the same 231 * pk11 session in multiple cipher_update calls 232 */ 233 typedef struct PK11_CIPHER_STATE_st 234 { 235 PK11_SESSION *sp; 236 } PK11_CIPHER_STATE; 237 238 239 /* libcrypto EVP stuff - this is how we get wired to EVP so the engine 240 * gets called when libcrypto requests a cipher NID. 241 * Note how the PK11_CIPHER_STATE is used here. 242 */ 243 244 /* DES CBC EVP */ 245 static const EVP_CIPHER pk11_des_cbc = 246 { 247 NID_des_cbc, 248 8, 8, 8, 249 EVP_CIPH_CBC_MODE, 250 pk11_cipher_init, 251 pk11_cipher_do_cipher, 252 pk11_cipher_cleanup, 253 sizeof(PK11_CIPHER_STATE), 254 EVP_CIPHER_set_asn1_iv, 255 EVP_CIPHER_get_asn1_iv, 256 NULL 257 }; 258 259 /* 3DES CBC EVP */ 260 static const EVP_CIPHER pk11_3des_cbc = 261 { 262 NID_des_ede3_cbc, 263 8, 24, 8, 264 EVP_CIPH_CBC_MODE, 265 pk11_cipher_init, 266 pk11_cipher_do_cipher, 267 pk11_cipher_cleanup, 268 sizeof(PK11_CIPHER_STATE), 269 EVP_CIPHER_set_asn1_iv, 270 EVP_CIPHER_get_asn1_iv, 271 NULL 272 }; 273 274 static const EVP_CIPHER pk11_aes_cbc = 275 { 276 NID_aes_128_cbc, 277 16, 16, 16, 278 EVP_CIPH_CBC_MODE, 279 pk11_cipher_init, 280 pk11_cipher_do_cipher, 281 pk11_cipher_cleanup, 282 sizeof(PK11_CIPHER_STATE), 283 EVP_CIPHER_set_asn1_iv, 284 EVP_CIPHER_get_asn1_iv, 285 NULL 286 }; 287 288 static const EVP_CIPHER pk11_rc4 = 289 { 290 NID_rc4, 291 1,16,0, 292 EVP_CIPH_VARIABLE_LENGTH, 293 pk11_cipher_init, 294 pk11_cipher_do_cipher, 295 pk11_cipher_cleanup, 296 sizeof(PK11_CIPHER_STATE), 297 NULL, 298 NULL, 299 NULL 300 }; 301 302 static const EVP_MD pk11_md5 = 303 { 304 NID_md5, 305 NID_md5WithRSAEncryption, 306 MD5_DIGEST_LENGTH, 307 0, 308 pk11_digest_init, 309 pk11_digest_update, 310 pk11_digest_final, 311 pk11_digest_copy, 312 pk11_digest_cleanup, 313 EVP_PKEY_RSA_method, 314 MD5_CBLOCK, 315 sizeof(PK11_CIPHER_STATE), 316 }; 317 318 static const EVP_MD pk11_sha1 = 319 { 320 NID_sha1, 321 NID_sha1WithRSAEncryption, 322 SHA_DIGEST_LENGTH, 323 0, 324 pk11_digest_init, 325 pk11_digest_update, 326 pk11_digest_final, 327 pk11_digest_copy, 328 pk11_digest_cleanup, 329 EVP_PKEY_RSA_method, 330 SHA_CBLOCK, 331 sizeof(PK11_CIPHER_STATE), 332 }; 333 334 /* Initialization function. Sets up various pk11 library components. 335 */ 336 /* The definitions for control commands specific to this engine 337 */ 338 #define PK11_CMD_SO_PATH ENGINE_CMD_BASE 339 static const ENGINE_CMD_DEFN pk11_cmd_defns[] = 340 { 341 { 342 PK11_CMD_SO_PATH, 343 "SO_PATH", 344 "Specifies the path to the 'pkcs#11' shared library", 345 ENGINE_CMD_FLAG_STRING 346 }, 347 {0, NULL, NULL, 0} 348 }; 349 350 351 static RAND_METHOD pk11_random = 352 { 353 pk11_rand_seed, 354 pk11_rand_bytes, 355 pk11_rand_cleanup, 356 pk11_rand_add, 357 pk11_rand_bytes, 358 pk11_rand_status 359 }; 360 361 362 /* Constants used when creating the ENGINE 363 */ 364 static const char *engine_pk11_id = "pkcs11"; 365 static const char *engine_pk11_name = "PKCS #11 engine support"; 366 367 CK_FUNCTION_LIST_PTR pFuncList = NULL; 368 static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList"; 369 370 /* These are the static string constants for the DSO file name and the function 371 * symbol names to bind to. 372 */ 373 #if defined(__sparcv9) || defined(__x86_64) || defined(__amd64) 374 static const char def_PK11_LIBNAME[] = "/usr/lib/64/libpkcs11.so.1"; 375 #else 376 static const char def_PK11_LIBNAME[] = "/usr/lib/libpkcs11.so.1"; 377 #endif 378 379 /* CRYPTO_LOCK_RSA is defined in OpenSSL for RSA method. Since this pk11 380 * engine replaces RSA method, we may reuse this lock here. 381 */ 382 #define CRYPTO_LOCK_PK11_ENGINE CRYPTO_LOCK_RSA 383 384 static CK_BBOOL true = TRUE; 385 static CK_BBOOL false = FALSE; 386 static CK_SLOT_ID SLOTID = 0; 387 static int pk11_library_initialized = 0; 388 389 static DSO *pk11_dso = NULL; 390 391 /* 392 * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support. 393 */ 394 static int bind_pk11(ENGINE *e) 395 { 396 const RSA_METHOD *rsa = NULL; 397 RSA_METHOD *pk11_rsa = PK11_RSA(); 398 399 if (!pk11_library_initialized) 400 pk11_library_init(e); 401 402 if(!ENGINE_set_id(e, engine_pk11_id) || 403 !ENGINE_set_name(e, engine_pk11_name) || 404 !ENGINE_set_ciphers(e, pk11_engine_ciphers) || 405 !ENGINE_set_digests(e, pk11_engine_digests)) 406 return 0; 407 #ifndef OPENSSL_NO_RSA 408 if(pk11_have_rsa == CK_TRUE) 409 { 410 if(!ENGINE_set_RSA(e, PK11_RSA()) || 411 !ENGINE_set_load_privkey_function(e, pk11_load_privkey) || 412 !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey)) 413 return 0; 414 #ifdef DEBUG_SLOT_SELECTION 415 fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: registered RSA\n"); 416 #endif /* DEBUG_SLOT_SELECTION */ 417 } 418 #endif 419 #ifndef OPENSSL_NO_DSA 420 if(pk11_have_dsa == CK_TRUE) 421 { 422 if (!ENGINE_set_DSA(e, PK11_DSA())) 423 return 0; 424 #ifdef DEBUG_SLOT_SELECTION 425 fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: registered DSA\n"); 426 #endif /* DEBUG_SLOT_SELECTION */ 427 } 428 #endif 429 #ifndef OPENSSL_NO_DH 430 if(pk11_have_dh == CK_TRUE) 431 { 432 if (!ENGINE_set_DH(e, PK11_DH())) 433 return 0; 434 #ifdef DEBUG_SLOT_SELECTION 435 fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: registered DH\n"); 436 #endif /* DEBUG_SLOT_SELECTION */ 437 } 438 #endif 439 if(pk11_have_random) 440 { 441 if(!ENGINE_set_RAND(e, &pk11_random)) 442 return 0; 443 #ifdef DEBUG_SLOT_SELECTION 444 fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: registered random\n"); 445 #endif /* DEBUG_SLOT_SELECTION */ 446 } 447 if(!ENGINE_set_init_function(e, pk11_init) || 448 !ENGINE_set_destroy_function(e, pk11_destroy) || 449 !ENGINE_set_finish_function(e, pk11_finish) || 450 !ENGINE_set_ctrl_function(e, pk11_ctrl) || 451 !ENGINE_set_cmd_defns(e, pk11_cmd_defns)) 452 return 0; 453 454 /* Apache calls OpenSSL function RSA_blinding_on() once during startup 455 * which in turn calls bn_mod_exp. Since we do not implement bn_mod_exp 456 * here, we wire it back to the OpenSSL software implementation. 457 * Since it is used only once, performance is not a concern. */ 458 #ifndef OPENSSL_NO_RSA 459 rsa = RSA_PKCS1_SSLeay(); 460 pk11_rsa->rsa_mod_exp = rsa->rsa_mod_exp; 461 pk11_rsa->bn_mod_exp = rsa->bn_mod_exp; 462 #endif 463 464 /* Ensure the pk11 error handling is set up */ 465 ERR_load_pk11_strings(); 466 467 return 1; 468 } 469 470 /* Dynamic engine support is disabled at a higher level for Solaris 471 */ 472 #ifdef ENGINE_DYNAMIC_SUPPORT 473 static int bind_helper(ENGINE *e, const char *id) 474 { 475 if (id && (strcmp(id, engine_pk11_id) != 0)) 476 return 0; 477 478 if (!bind_pk11(e)) 479 return 0; 480 481 return 1; 482 } 483 484 IMPLEMENT_DYNAMIC_CHECK_FN() 485 IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) 486 487 #else 488 static ENGINE *engine_pk11(void) 489 { 490 ENGINE *ret = ENGINE_new(); 491 492 if (!ret) 493 return NULL; 494 495 if (!bind_pk11(ret)) 496 { 497 ENGINE_free(ret); 498 return NULL; 499 } 500 501 return ret; 502 } 503 504 void ENGINE_load_pk11(void) 505 { 506 ENGINE *e_pk11 = NULL; 507 508 /* Do not use dynamic PKCS#11 library on Solaris due to 509 * security reasons. We will link it in statically 510 */ 511 /* Attempt to load PKCS#11 library 512 */ 513 if (!pk11_dso) 514 pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0); 515 516 if (pk11_dso == NULL) 517 { 518 PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE); 519 return; 520 } 521 522 e_pk11 = engine_pk11(); 523 if (!e_pk11) 524 { 525 DSO_free(pk11_dso); 526 pk11_dso = NULL; 527 return; 528 } 529 530 /* At this point, the pk11 shared library is either dynamically 531 * loaded or statically linked in. So, initialize the pk11 532 * library before calling ENGINE_set_default since the latter 533 * needs cipher and digest algorithm information 534 */ 535 if (!pk11_library_init(e_pk11)) 536 { 537 DSO_free(pk11_dso); 538 pk11_dso = NULL; 539 ENGINE_free(e_pk11); 540 return; 541 } 542 543 ENGINE_add(e_pk11); 544 545 ENGINE_free(e_pk11); 546 ERR_clear_error(); 547 } 548 #endif 549 550 /* These are the static string constants for the DSO file name and 551 * the function symbol names to bind to. 552 */ 553 static const char *PK11_LIBNAME = NULL; 554 555 static const char *get_PK11_LIBNAME(void) 556 { 557 if (PK11_LIBNAME) 558 return PK11_LIBNAME; 559 560 return def_PK11_LIBNAME; 561 } 562 563 static void free_PK11_LIBNAME(void) 564 { 565 if (PK11_LIBNAME) 566 OPENSSL_free((void*)PK11_LIBNAME); 567 568 PK11_LIBNAME = NULL; 569 } 570 571 static long set_PK11_LIBNAME(const char *name) 572 { 573 free_PK11_LIBNAME(); 574 575 return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0); 576 } 577 578 /* Initialization function for the pk11 engine */ 579 static int pk11_init(ENGINE *e) 580 { 581 return pk11_library_init(e); 582 } 583 584 /* Initialization function. Sets up various pk11 library components. 585 * It selects a slot based on predefined critiera. In the process, it also 586 * count how many ciphers and digests to support. Since the cipher and 587 * digest information is needed when setting default engine, this function 588 * needs to be called before calling ENGINE_set_default. 589 */ 590 static int pk11_library_init(ENGINE *e) 591 { 592 CK_C_GetFunctionList p; 593 CK_RV rv = CKR_OK; 594 CK_INFO info; 595 CK_ULONG ul_state_len; 596 char tmp_buf[20]; 597 598 if (pk11_library_initialized) 599 return 1; 600 601 if (pk11_dso == NULL) 602 { 603 PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE); 604 goto err; 605 } 606 607 /* get the C_GetFunctionList function from the loaded library 608 */ 609 p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso, 610 PK11_GET_FUNCTION_LIST); 611 if ( !p ) 612 { 613 PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE); 614 goto err; 615 } 616 617 /* get the full function list from the loaded library 618 */ 619 rv = p(&pFuncList); 620 if (rv != CKR_OK) 621 { 622 PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE); 623 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 624 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 625 goto err; 626 } 627 628 rv = pFuncList->C_Initialize(NULL_PTR); 629 if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) 630 { 631 PK11err(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE); 632 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 633 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 634 goto err; 635 } 636 637 rv = pFuncList->C_GetInfo(&info); 638 if (rv != CKR_OK) 639 { 640 PK11err(PK11_F_LIBRARY_INIT, PK11_R_GETINFO); 641 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 642 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 643 goto err; 644 } 645 646 if (pk11_choose_slot() == 0) 647 goto err; 648 649 if (global_session == CK_INVALID_HANDLE) 650 { 651 /* Open the global_session for the new process */ 652 rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION, 653 NULL_PTR, NULL_PTR, &global_session); 654 if (rv != CKR_OK) 655 { 656 PK11err(PK11_F_LIBRARY_INIT, PK11_R_OPENSESSION); 657 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 658 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 659 goto err; 660 } 661 } 662 663 /* Disable digest if C_GetOperationState is not supported since 664 * this function is required by OpenSSL digest copy function */ 665 if (pFuncList->C_GetOperationState(global_session, NULL, &ul_state_len) 666 == CKR_FUNCTION_NOT_SUPPORTED) 667 digest_count = 0; 668 669 pk11_library_initialized = 1; 670 return 1; 671 672 err: 673 674 return 0; 675 } 676 677 /* Destructor (complements the "ENGINE_pk11()" constructor) 678 */ 679 static int pk11_destroy(ENGINE *e) 680 { 681 free_PK11_LIBNAME(); 682 ERR_unload_pk11_strings(); 683 return 1; 684 } 685 686 /* Termination function to clean up the session, the token, and 687 * the pk11 library. 688 */ 689 static int pk11_finish(ENGINE *e) 690 { 691 692 if (pk11_dso == NULL) 693 { 694 PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED); 695 goto err; 696 } 697 698 assert(pFuncList != NULL); 699 700 if (pk11_free_all_sessions() == 0) 701 goto err; 702 703 pFuncList->C_CloseSession(global_session); 704 705 /* Since we are part of a library (libcrypto.so), calling this 706 * function may have side-effects. 707 pFuncList->C_Finalize(NULL); 708 */ 709 710 if (!DSO_free(pk11_dso)) 711 { 712 PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE); 713 goto err; 714 } 715 pk11_dso = NULL; 716 pFuncList = NULL; 717 pk11_library_initialized = 0; 718 719 return 1; 720 721 err: 722 return 0; 723 } 724 725 /* Standard engine interface function to set the dynamic library path */ 726 static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) 727 { 728 int initialized = ((pk11_dso == NULL) ? 0 : 1); 729 730 switch(cmd) 731 { 732 case PK11_CMD_SO_PATH: 733 if (p == NULL) 734 { 735 PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER); 736 return 0; 737 } 738 739 if (initialized) 740 { 741 PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED); 742 return 0; 743 } 744 745 return set_PK11_LIBNAME((const char*)p); 746 default: 747 break; 748 } 749 750 PK11err(PK11_F_CTRL,PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED); 751 752 return 0; 753 } 754 755 756 /* Required function by the engine random interface. It does nothing here 757 */ 758 static void pk11_rand_cleanup(void) 759 { 760 return; 761 } 762 763 static void pk11_rand_add(const void *buf, int num, double add) 764 { 765 PK11_SESSION *sp; 766 767 if ((sp = pk11_get_session()) == NULL) 768 return; 769 770 /* Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since 771 * the calling functions do not care anyway 772 */ 773 pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num); 774 pk11_return_session(sp); 775 776 return; 777 } 778 779 static void pk11_rand_seed(const void *buf, int num) 780 { 781 pk11_rand_add(buf, num, 0); 782 } 783 784 static int pk11_rand_bytes(unsigned char *buf, int num) 785 { 786 CK_RV rv; 787 PK11_SESSION *sp; 788 789 if ((sp = pk11_get_session()) == NULL) 790 return 0; 791 792 rv = pFuncList->C_GenerateRandom(sp->session, buf, num); 793 if (rv != CKR_OK) 794 { 795 char tmp_buf[20]; 796 PK11err(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM); 797 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 798 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 799 pk11_return_session(sp); 800 return 0; 801 } 802 803 pk11_return_session(sp); 804 return 1; 805 } 806 807 808 /* Required function by the engine random interface. It does nothing here 809 */ 810 static int pk11_rand_status(void) 811 { 812 return 1; 813 } 814 815 816 PK11_SESSION *pk11_get_session() 817 { 818 PK11_SESSION *sp, *sp1; 819 CK_RV rv; 820 char tmp_buf[20]; 821 822 CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE); 823 if ((sp = free_session) == NULL) 824 { 825 if ((sp = OPENSSL_malloc(sizeof(PK11_SESSION))) == NULL) 826 { 827 PK11err(PK11_F_GET_SESSION, 828 PK11_R_MALLOC_FAILURE); 829 goto err; 830 } 831 memset(sp, 0, sizeof(PK11_SESSION)); 832 } 833 else 834 { 835 free_session = sp->next; 836 } 837 838 if (sp->pid != 0 && sp->pid != getpid()) 839 { 840 /* We are a new process and thus need to free any inherated 841 * PK11_SESSION objects. 842 */ 843 while ((sp1 = free_session) != NULL) 844 { 845 free_session = sp1->next; 846 OPENSSL_free(sp1); 847 } 848 849 /* Initialize the process */ 850 rv = pFuncList->C_Initialize(NULL_PTR); 851 if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) 852 { 853 PK11err(PK11_F_GET_SESSION, PK11_R_INITIALIZE); 854 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 855 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 856 OPENSSL_free(sp); 857 sp = NULL; 858 goto err; 859 } 860 861 /* Choose slot here since the slot table is different on 862 * this process. 863 */ 864 if (pk11_choose_slot() == 0) 865 goto err; 866 867 /* Open the global_session for the new process */ 868 rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION, 869 NULL_PTR, NULL_PTR, &global_session); 870 if (rv != CKR_OK) 871 { 872 PK11err(PK11_F_GET_SESSION, PK11_R_OPENSESSION); 873 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 874 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 875 OPENSSL_free(sp); 876 sp = NULL; 877 goto err; 878 } 879 880 /* It is an inherited session and needs re-initialization. 881 */ 882 if (pk11_setup_session(sp) == 0) 883 { 884 OPENSSL_free(sp); 885 sp = NULL; 886 } 887 } 888 else if (sp->pid == 0) 889 { 890 /* It is a new session and needs initialization. 891 */ 892 if (pk11_setup_session(sp) == 0) 893 { 894 OPENSSL_free(sp); 895 sp = NULL; 896 } 897 } 898 899 err: 900 if (sp) 901 sp->next = NULL; 902 903 CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE); 904 905 return sp; 906 } 907 908 909 void pk11_return_session(PK11_SESSION *sp) 910 { 911 if (sp == NULL || sp->pid != getpid()) 912 return; 913 914 915 CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE); 916 917 sp->next = free_session; 918 free_session = sp; 919 920 CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE); 921 } 922 923 924 /* Destroy all objects. This function is called when the engine is finished 925 */ 926 static int pk11_free_all_sessions() 927 { 928 CK_RV rv; 929 PK11_SESSION *sp = NULL; 930 pid_t mypid = getpid(); 931 int ret = 0; 932 933 pk11_destroy_rsa_key_objects(NULL); 934 pk11_destroy_dsa_key_objects(NULL); 935 pk11_destroy_dh_key_objects(NULL); 936 pk11_destroy_cipher_key_objects(NULL); 937 938 CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE); 939 while ((sp = free_session) != NULL) 940 { 941 if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid) 942 { 943 rv = pFuncList->C_CloseSession(sp->session); 944 if (rv != CKR_OK) 945 { 946 char tmp_buf[20]; 947 PK11err(PK11_F_FREE_ALL_SESSIONS, 948 PK11_R_CLOSESESSION); 949 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 950 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 951 } 952 } 953 if (sp->session_cipher != CK_INVALID_HANDLE && sp->pid == mypid) 954 { 955 rv = pFuncList->C_CloseSession(sp->session_cipher); 956 if (rv != CKR_OK) 957 { 958 char tmp_buf[20]; 959 PK11err(PK11_F_FREE_ALL_SESSIONS, 960 PK11_R_CLOSESESSION); 961 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 962 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 963 } 964 } 965 free_session = sp->next; 966 OPENSSL_free(sp); 967 } 968 ret = 1; 969 err: 970 CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE); 971 972 return ret; 973 } 974 975 976 static int pk11_setup_session(PK11_SESSION *sp) 977 { 978 CK_RV rv; 979 sp->session = CK_INVALID_HANDLE; 980 rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION, 981 NULL_PTR, NULL_PTR, &sp->session); 982 if (rv == CKR_CRYPTOKI_NOT_INITIALIZED) 983 { 984 /* 985 * We are probably a child process so force the 986 * reinitialize of the session 987 */ 988 pk11_library_initialized = 0; 989 (void) pk11_library_init(NULL); 990 rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION, 991 NULL_PTR, NULL_PTR, &sp->session); 992 } 993 if (rv != CKR_OK) 994 { 995 char tmp_buf[20]; 996 PK11err(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION); 997 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 998 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 999 return 0; 1000 } 1001 1002 sp->session_cipher = CK_INVALID_HANDLE; 1003 rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION, 1004 NULL_PTR, NULL_PTR, &sp->session_cipher); 1005 if (rv != CKR_OK) 1006 { 1007 char tmp_buf[20]; 1008 1009 (void) pFuncList->C_CloseSession(sp->session); 1010 sp->session = CK_INVALID_HANDLE; 1011 1012 PK11err(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION); 1013 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1014 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1015 return 0; 1016 } 1017 1018 sp->pid = getpid(); 1019 sp->rsa_pub_key = CK_INVALID_HANDLE; 1020 sp->rsa_priv_key = CK_INVALID_HANDLE; 1021 sp->dsa_pub_key = CK_INVALID_HANDLE; 1022 sp->dsa_priv_key = CK_INVALID_HANDLE; 1023 sp->dh_key = CK_INVALID_HANDLE; 1024 sp->cipher_key = CK_INVALID_HANDLE; 1025 sp->rsa = NULL; 1026 sp->dsa = NULL; 1027 sp->dh = NULL; 1028 sp->encrypt = -1; 1029 1030 return 1; 1031 } 1032 1033 int pk11_destroy_rsa_key_objects(PK11_SESSION *session) 1034 { 1035 int ret = 0; 1036 PK11_SESSION *sp = NULL; 1037 PK11_SESSION *local_free_session; 1038 1039 CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE); 1040 if (session) 1041 local_free_session = session; 1042 else 1043 local_free_session = free_session; 1044 while ((sp = local_free_session) != NULL) 1045 { 1046 local_free_session = sp->next; 1047 1048 if (sp->rsa_pub_key != CK_INVALID_HANDLE) 1049 { 1050 if (pk11_destroy_object(sp->session, 1051 sp->rsa_pub_key) == 0) 1052 goto err; 1053 sp->rsa_pub_key = CK_INVALID_HANDLE; 1054 } 1055 1056 if (sp->rsa_priv_key != CK_INVALID_HANDLE) 1057 { 1058 if (pk11_destroy_object(sp->session, 1059 sp->rsa_priv_key) == 0) 1060 goto err; 1061 sp->rsa_priv_key = CK_INVALID_HANDLE; 1062 } 1063 1064 sp->rsa = NULL; 1065 } 1066 ret = 1; 1067 err: 1068 CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE); 1069 1070 return ret; 1071 } 1072 1073 int pk11_destroy_dsa_key_objects(PK11_SESSION *session) 1074 { 1075 int ret = 0; 1076 PK11_SESSION *sp = NULL; 1077 PK11_SESSION *local_free_session; 1078 1079 CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE); 1080 if (session) 1081 local_free_session = session; 1082 else 1083 local_free_session = free_session; 1084 while ((sp = local_free_session) != NULL) 1085 { 1086 local_free_session = sp->next; 1087 1088 if (sp->dsa_pub_key != CK_INVALID_HANDLE) 1089 { 1090 if (pk11_destroy_object(sp->session, 1091 sp->dsa_pub_key) == 0) 1092 goto err; 1093 sp->dsa_pub_key = CK_INVALID_HANDLE; 1094 } 1095 1096 if (sp->dsa_priv_key != CK_INVALID_HANDLE) 1097 { 1098 if (pk11_destroy_object(sp->session, 1099 sp->dsa_priv_key) == 0) 1100 goto err; 1101 sp->dsa_priv_key = CK_INVALID_HANDLE; 1102 } 1103 1104 sp->dsa = NULL; 1105 } 1106 ret = 1; 1107 err: 1108 CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE); 1109 1110 return ret; 1111 } 1112 1113 int pk11_destroy_dh_key_objects(PK11_SESSION *session) 1114 { 1115 int ret = 0; 1116 PK11_SESSION *sp = NULL; 1117 PK11_SESSION *local_free_session; 1118 1119 CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE); 1120 if (session) 1121 local_free_session = session; 1122 else 1123 local_free_session = free_session; 1124 while ((sp = local_free_session) != NULL) 1125 { 1126 local_free_session = sp->next; 1127 1128 if (sp->dh_key != CK_INVALID_HANDLE) 1129 { 1130 if (pk11_destroy_object(sp->session, 1131 sp->dh_key) == 0) 1132 goto err; 1133 sp->dh_key = CK_INVALID_HANDLE; 1134 } 1135 1136 sp->dh = NULL; 1137 } 1138 ret = 1; 1139 err: 1140 CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE); 1141 1142 return ret; 1143 } 1144 1145 static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh) 1146 { 1147 CK_RV rv; 1148 rv = pFuncList->C_DestroyObject(session, oh); 1149 if (rv != CKR_OK) 1150 { 1151 char tmp_buf[20]; 1152 PK11err(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT); 1153 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1154 ERR_add_error_data(2, "PK11 CK_RV=0X", 1155 tmp_buf); 1156 return 0; 1157 } 1158 1159 return 1; 1160 } 1161 1162 1163 /* Symmetric ciphers and digests support functions 1164 */ 1165 1166 static int 1167 cipher_nid_to_pk11(int nid) 1168 { 1169 int i; 1170 1171 for (i = 0; i < PK11_CIPHER_MAX; i++) 1172 if (ciphers[i].nid == nid) 1173 return (ciphers[i].id); 1174 return (-1); 1175 } 1176 1177 static int 1178 pk11_usable_ciphers(const int **nids) 1179 { 1180 if (cipher_count > 0) 1181 *nids = cipher_nids; 1182 else 1183 *nids = NULL; 1184 return (cipher_count); 1185 } 1186 1187 static int 1188 pk11_usable_digests(const int **nids) 1189 { 1190 if (digest_count > 0) 1191 *nids = digest_nids; 1192 else 1193 *nids = NULL; 1194 return (digest_count); 1195 } 1196 1197 static int 1198 pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, 1199 const unsigned char *iv, int enc) 1200 { 1201 CK_RV rv; 1202 int index; 1203 PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data; 1204 PK11_SESSION *sp; 1205 PK11_CIPHER *pcp; 1206 char tmp_buf[20]; 1207 1208 state->sp = NULL; 1209 1210 index = cipher_nid_to_pk11(ctx->cipher->nid); 1211 if (index < 0 || index >= PK11_CIPHER_MAX) 1212 return 0; 1213 1214 pcp = &ciphers[index]; 1215 if (ctx->cipher->iv_len > pcp->ivmax || ctx->key_len != pcp->key_len) 1216 return 0; 1217 1218 if ((sp = pk11_get_session()) == NULL) 1219 return 0; 1220 1221 /* The key object is destroyed here if it is not the current key 1222 */ 1223 check_new_cipher_key(sp, key); 1224 1225 /* If the key is the same and the encryption is also the same, 1226 * then just reuse it 1227 */ 1228 if (sp->cipher_key != CK_INVALID_HANDLE && sp->encrypt == ctx->encrypt) 1229 { 1230 state->sp = sp; 1231 return 1; 1232 } 1233 1234 /* Check if the key has been invalidated. If so, a new key object 1235 * needs to be created. 1236 */ 1237 if (sp->cipher_key == CK_INVALID_HANDLE) 1238 { 1239 sp->cipher_key = pk11_get_cipher_key( 1240 ctx, key, pcp->key_type, sp); 1241 } 1242 1243 if (sp->encrypt != ctx->encrypt && sp->encrypt != -1) 1244 { 1245 /* The previous encryption/decryption 1246 * is different. Need to terminate the previous 1247 * active encryption/decryption here 1248 */ 1249 if (!pk11_cipher_final(sp)) 1250 { 1251 pk11_return_session(sp); 1252 return 0; 1253 } 1254 } 1255 1256 if (sp->cipher_key == CK_INVALID_HANDLE) 1257 { 1258 pk11_return_session(sp); 1259 return 0; 1260 } 1261 1262 if (ctx->cipher->iv_len > 0) 1263 { 1264 pcp->mech.pParameter = (void *) ctx->iv; 1265 pcp->mech.ulParameterLen = ctx->cipher->iv_len; 1266 } 1267 1268 /* If we get here, the encryption needs to be reinitialized */ 1269 if (ctx->encrypt) 1270 { 1271 rv = pFuncList->C_EncryptInit(sp->session_cipher, &pcp->mech, 1272 sp->cipher_key); 1273 1274 if (rv != CKR_OK) 1275 { 1276 PK11err(PK11_F_CIPHER_INIT, PK11_R_ENCRYPTINIT); 1277 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1278 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1279 pk11_return_session(sp); 1280 return 0; 1281 } 1282 } 1283 else 1284 { 1285 rv = pFuncList->C_DecryptInit(sp->session_cipher, &pcp->mech, 1286 sp->cipher_key); 1287 1288 if (rv != CKR_OK) 1289 { 1290 PK11err(PK11_F_CIPHER_INIT, PK11_R_DECRYPTINIT); 1291 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1292 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1293 pk11_return_session(sp); 1294 return 0; 1295 } 1296 } 1297 1298 sp->encrypt = ctx->encrypt; 1299 state->sp = sp; 1300 1301 return 1; 1302 } 1303 1304 /* When reusing the same key in an encryption/decryption session for a 1305 * decryption/encryption session, we need to close the active session 1306 * and recreate a new one. Note that the key is in the global session so 1307 * that it needs not be recreated. 1308 * 1309 * It is more appropriate to use C_En/DecryptFinish here. At the time of this 1310 * development, these two functions in the PKCS#11 libraries used return 1311 * unexpected errors when passing in 0 length output. It may be a good 1312 * idea to try them again if performance is a problem here and fix 1313 * C_En/DecryptFinial if there are bugs there causing the problem. 1314 */ 1315 static int 1316 pk11_cipher_final(PK11_SESSION *sp) 1317 { 1318 CK_RV rv; 1319 char tmp_buf[20]; 1320 1321 rv = pFuncList->C_CloseSession(sp->session_cipher); 1322 if (rv != CKR_OK) 1323 { 1324 PK11err(PK11_F_CIPHER_FINAL, PK11_R_CLOSESESSION); 1325 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1326 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1327 return 0; 1328 } 1329 1330 rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION, 1331 NULL_PTR, NULL_PTR, &sp->session_cipher); 1332 if (rv != CKR_OK) 1333 { 1334 PK11err(PK11_F_CIPHER_FINAL, PK11_R_OPENSESSION); 1335 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1336 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1337 return 0; 1338 } 1339 1340 return 1; 1341 } 1342 1343 /* An engine interface function. The calling function allocates sufficient 1344 * memory for the output buffer "out" to hold the results */ 1345 static int 1346 pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 1347 const unsigned char *in, unsigned int inl) 1348 { 1349 PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data; 1350 PK11_SESSION *sp; 1351 CK_RV rv; 1352 unsigned long outl = inl; 1353 char tmp_buf[20]; 1354 1355 if (state == NULL || state->sp == NULL) 1356 return 0; 1357 1358 sp = (PK11_SESSION *) state->sp; 1359 1360 if (!inl) 1361 return 1; 1362 1363 /* RC4 is the only stream cipher we support */ 1364 if (ctx->cipher->nid != NID_rc4 && (inl % ctx->cipher->block_size) != 0) 1365 return 0; 1366 1367 if (ctx->encrypt) 1368 { 1369 rv = pFuncList->C_EncryptUpdate(sp->session_cipher, 1370 (unsigned char *)in, inl, out, &outl); 1371 1372 if (rv != CKR_OK) 1373 { 1374 PK11err(PK11_F_CIPHER_DO_CIPHER, 1375 PK11_R_ENCRYPTUPDATE); 1376 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1377 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1378 return 0; 1379 } 1380 } 1381 else 1382 { 1383 rv = pFuncList->C_DecryptUpdate(sp->session_cipher, 1384 (unsigned char *)in, inl, out, &outl); 1385 1386 if (rv != CKR_OK) 1387 { 1388 PK11err(PK11_F_CIPHER_DO_CIPHER, 1389 PK11_R_DECRYPTUPDATE); 1390 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1391 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1392 return 0; 1393 } 1394 } 1395 1396 /* for DES_CBC, DES3_CBC, AES_CBC, and RC4, the output size is always 1397 * the same size of input 1398 * The application has guaranteed to call the block ciphers with 1399 * correctly aligned buffers. 1400 */ 1401 if (inl != outl) 1402 return 0; 1403 1404 return 1; 1405 } 1406 1407 /* Return the session to the pool. The C_EncryptFinal and C_DecryptFinal are 1408 * not used. Once a secret key is initialized, it is used until destroyed. 1409 */ 1410 static int 1411 pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx) 1412 { 1413 PK11_CIPHER_STATE *state = ctx->cipher_data; 1414 1415 if (state != NULL && state->sp != NULL) 1416 { 1417 pk11_return_session(state->sp); 1418 state->sp = NULL; 1419 } 1420 1421 return 1; 1422 } 1423 1424 /* Registered by the ENGINE when used to find out how to deal with 1425 * a particular NID in the ENGINE. This says what we'll do at the 1426 * top level - note, that list is restricted by what we answer with 1427 */ 1428 static int 1429 pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, 1430 const int **nids, int nid) 1431 { 1432 if (!cipher) 1433 return (pk11_usable_ciphers(nids)); 1434 1435 switch (nid) 1436 { 1437 case NID_des_ede3_cbc: 1438 *cipher = &pk11_3des_cbc; 1439 break; 1440 case NID_des_cbc: 1441 *cipher = &pk11_des_cbc; 1442 break; 1443 case NID_aes_128_cbc: 1444 *cipher = &pk11_aes_cbc; 1445 break; 1446 case NID_rc4: 1447 *cipher = &pk11_rc4; 1448 break; 1449 default: 1450 *cipher = NULL; 1451 break; 1452 } 1453 return (*cipher != NULL); 1454 } 1455 1456 static int 1457 pk11_engine_digests(ENGINE *e, const EVP_MD **digest, 1458 const int **nids, int nid) 1459 { 1460 if (!digest) 1461 return (pk11_usable_digests(nids)); 1462 1463 switch (nid) 1464 { 1465 case NID_md5: 1466 *digest = &pk11_md5; 1467 break; 1468 case NID_sha1: 1469 *digest = &pk11_sha1; 1470 break; 1471 default: 1472 *digest = NULL; 1473 break; 1474 } 1475 return (*digest != NULL); 1476 } 1477 1478 1479 /* Create a secret key object in a PKCS#11 session 1480 */ 1481 static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx, 1482 const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp) 1483 { 1484 CK_RV rv; 1485 CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE; 1486 CK_ULONG found; 1487 CK_OBJECT_CLASS obj_key = CKO_SECRET_KEY; 1488 CK_ULONG ul_key_attr_count = 6; 1489 char tmp_buf[20]; 1490 1491 CK_ATTRIBUTE a_key_template[] = 1492 { 1493 {CKA_CLASS, (void*) NULL, sizeof(CK_OBJECT_CLASS)}, 1494 {CKA_KEY_TYPE, (void*) NULL, sizeof(CK_KEY_TYPE)}, 1495 {CKA_TOKEN, &false, sizeof(false)}, 1496 {CKA_ENCRYPT, &true, sizeof(true)}, 1497 {CKA_DECRYPT, &true, sizeof(true)}, 1498 {CKA_VALUE, (void*) NULL, 0}, 1499 }; 1500 1501 /* Create secret key object in global_session. All other sessions 1502 * can use the key handles. Here is why: 1503 * OpenSSL will call EncryptInit and EncryptUpdate using a secret key. 1504 * It may then call DecryptInit and DecryptUpdate using the same key. 1505 * To use the same key object, we need to call EncryptFinal with 1506 * a 0 length message. Currently, this does not work for 3DES 1507 * mechanism. To get around this problem, we close the session and 1508 * then create a new session to use the same key object. When a session 1509 * is closed, all the object handles will be invalid. Thus, create key 1510 * objects in a global session, an individual session may be closed to 1511 * terminate the active operation. 1512 */ 1513 CK_SESSION_HANDLE session = global_session; 1514 a_key_template[0].pValue = &obj_key; 1515 a_key_template[1].pValue = &key_type; 1516 a_key_template[5].pValue = (void *) key; 1517 a_key_template[5].ulValueLen = (unsigned long) ctx->key_len; 1518 1519 rv = pFuncList->C_FindObjectsInit(session, a_key_template, 1520 ul_key_attr_count); 1521 1522 if (rv != CKR_OK) 1523 { 1524 PK11err(PK11_F_GET_CIPHER_KEY, PK11_R_FINDOBJECTSINIT); 1525 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1526 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1527 goto err; 1528 } 1529 1530 rv = pFuncList->C_FindObjects(session, &h_key, 1, &found); 1531 1532 if (rv != CKR_OK) 1533 { 1534 PK11err(PK11_F_GET_CIPHER_KEY, PK11_R_FINDOBJECTS); 1535 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1536 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1537 goto err; 1538 } 1539 1540 rv = pFuncList->C_FindObjectsFinal(session); 1541 1542 if (rv != CKR_OK) 1543 { 1544 PK11err(PK11_F_GET_CIPHER_KEY, PK11_R_FINDOBJECTSFINAL); 1545 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1546 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1547 goto err; 1548 } 1549 1550 if (found == 0) 1551 { 1552 rv = pFuncList->C_CreateObject(session, 1553 a_key_template, ul_key_attr_count, &h_key); 1554 if (rv != CKR_OK) 1555 { 1556 PK11err(PK11_F_GET_CIPHER_KEY, 1557 PK11_R_CREATEOBJECT); 1558 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1559 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1560 goto err; 1561 } 1562 } 1563 1564 /* Save the key information used in this session. 1565 * The max can be saved is PK11_KEY_LEN_MAX. 1566 */ 1567 sp->key_len = ctx->key_len > PK11_KEY_LEN_MAX ? 1568 PK11_KEY_LEN_MAX : ctx->key_len; 1569 memcpy(sp->key, key, sp->key_len); 1570 err: 1571 1572 return h_key; 1573 } 1574 1575 static int 1576 md_nid_to_pk11(int nid) 1577 { 1578 int i; 1579 1580 for (i = 0; i < PK11_DIGEST_MAX; i++) 1581 if (digests[i].nid == nid) 1582 return (digests[i].id); 1583 return (-1); 1584 } 1585 1586 static int 1587 pk11_digest_init(EVP_MD_CTX *ctx) 1588 { 1589 CK_RV rv; 1590 int index; 1591 PK11_SESSION *sp; 1592 PK11_DIGEST *pdp; 1593 PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data; 1594 1595 state->sp = NULL; 1596 1597 index = md_nid_to_pk11(ctx->digest->type); 1598 if (index < 0 || index >= PK11_DIGEST_MAX) 1599 return 0; 1600 1601 pdp = &digests[index]; 1602 if ((sp = pk11_get_session()) == NULL) 1603 return 0; 1604 1605 rv = pFuncList->C_DigestInit(sp->session, &pdp->mech); 1606 1607 if (rv != CKR_OK) 1608 { 1609 char tmp_buf[20]; 1610 PK11err(PK11_F_DIGEST_INIT, PK11_R_DIGESTINIT); 1611 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1612 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1613 pk11_return_session(sp); 1614 return 0; 1615 } 1616 1617 state->sp = sp; 1618 1619 return 1; 1620 } 1621 1622 static int 1623 pk11_digest_update(EVP_MD_CTX *ctx,const void *data,size_t count) 1624 { 1625 CK_RV rv; 1626 PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data; 1627 1628 /* 0 length message will cause a failure in C_DigestFinal */ 1629 if (count == 0) 1630 return 1; 1631 1632 if (state == NULL || state->sp == NULL) 1633 return 0; 1634 1635 rv = pFuncList->C_DigestUpdate(state->sp->session, (CK_BYTE *) data, 1636 count); 1637 1638 if (rv != CKR_OK) 1639 { 1640 char tmp_buf[20]; 1641 PK11err(PK11_F_DIGEST_UPDATE, PK11_R_DIGESTUPDATE); 1642 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1643 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1644 pk11_return_session(state->sp); 1645 state->sp = NULL; 1646 return 0; 1647 } 1648 1649 return 1; 1650 } 1651 1652 static int 1653 pk11_digest_final(EVP_MD_CTX *ctx,unsigned char *md) 1654 { 1655 CK_RV rv; 1656 unsigned long len; 1657 PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data; 1658 len = ctx->digest->md_size; 1659 1660 if (state == NULL || state->sp == NULL) 1661 return 0; 1662 1663 rv = pFuncList->C_DigestFinal(state->sp->session, md, &len); 1664 1665 if (rv != CKR_OK) 1666 { 1667 char tmp_buf[20]; 1668 PK11err(PK11_F_DIGEST_FINAL, PK11_R_DIGESTFINAL); 1669 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1670 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1671 pk11_return_session(state->sp); 1672 state->sp = NULL; 1673 return 0; 1674 } 1675 1676 if (ctx->digest->md_size != len) 1677 return 0; 1678 1679 /* Final is called and digest is returned, so return the session 1680 * to the pool 1681 */ 1682 pk11_return_session(state->sp); 1683 state->sp = NULL; 1684 1685 return 1; 1686 } 1687 1688 static int 1689 pk11_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) 1690 { 1691 CK_RV rv; 1692 int ret = 0; 1693 PK11_CIPHER_STATE *state, *state_to; 1694 CK_BYTE_PTR pstate = NULL; 1695 CK_ULONG ul_state_len; 1696 char tmp_buf[20]; 1697 1698 /* The copy-from state */ 1699 state = (PK11_CIPHER_STATE *) from->md_data; 1700 if (state == NULL || state->sp == NULL) 1701 goto err; 1702 1703 /* Initialize the copy-to state */ 1704 if (!pk11_digest_init(to)) 1705 goto err; 1706 state_to = (PK11_CIPHER_STATE *) to->md_data; 1707 1708 /* Get the size of the operation state of the copy-from session */ 1709 rv = pFuncList->C_GetOperationState(state->sp->session, NULL, 1710 &ul_state_len); 1711 1712 if (rv != CKR_OK) 1713 { 1714 PK11err(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE); 1715 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1716 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1717 goto err; 1718 } 1719 if (ul_state_len == 0) 1720 { 1721 goto err; 1722 } 1723 1724 pstate = OPENSSL_malloc(ul_state_len); 1725 if (pstate == NULL) 1726 { 1727 RSAerr(PK11_F_DIGEST_COPY, PK11_R_MALLOC_FAILURE); 1728 goto err; 1729 } 1730 1731 /* Get the operation state of the copy-from session */ 1732 rv = pFuncList->C_GetOperationState(state->sp->session, pstate, 1733 &ul_state_len); 1734 1735 if (rv != CKR_OK) 1736 { 1737 PK11err(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE); 1738 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1739 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1740 goto err; 1741 } 1742 1743 /* Set the operation state of the copy-to session */ 1744 rv = pFuncList->C_SetOperationState(state_to->sp->session, pstate, 1745 ul_state_len, 0, 0); 1746 1747 if (rv != CKR_OK) 1748 { 1749 PK11err(PK11_F_DIGEST_COPY, PK11_R_SET_OPERATION_STATE); 1750 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1751 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1752 goto err; 1753 } 1754 1755 ret = 1; 1756 err: 1757 if (pstate != NULL) 1758 OPENSSL_free(pstate); 1759 1760 return ret; 1761 } 1762 1763 /* Return any pending session state to the pool */ 1764 static int 1765 pk11_digest_cleanup(EVP_MD_CTX *ctx) 1766 { 1767 PK11_CIPHER_STATE *state = ctx->md_data; 1768 1769 if (state != NULL && state->sp != NULL) 1770 { 1771 pk11_return_session(state->sp); 1772 state->sp = NULL; 1773 } 1774 1775 return 1; 1776 } 1777 1778 /* Check if the new key is the same as the key object in the session. 1779 * If the key is the same, no need to create a new key object. Otherwise, 1780 * the old key object needs to be destroyed and a new one will be created 1781 */ 1782 static void check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key) 1783 { 1784 if (memcmp(sp->key, key, sp->key_len) != 0) 1785 pk11_destroy_cipher_key_objects(sp); 1786 } 1787 1788 /* Destroy one or more secret key objects. 1789 */ 1790 static int pk11_destroy_cipher_key_objects(PK11_SESSION *session) 1791 { 1792 int ret = 0; 1793 PK11_SESSION *sp = NULL; 1794 PK11_SESSION *local_free_session; 1795 1796 CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE); 1797 if (session) 1798 local_free_session = session; 1799 else 1800 local_free_session = free_session; 1801 while ((sp = local_free_session) != NULL) 1802 { 1803 local_free_session = sp->next; 1804 1805 if (sp->cipher_key != CK_INVALID_HANDLE) 1806 { 1807 /* The secret key object is created in the 1808 * global_session. See pk11_get_cipher_key 1809 */ 1810 if (pk11_destroy_object(global_session, 1811 sp->cipher_key) == 0) 1812 goto err; 1813 sp->cipher_key = CK_INVALID_HANDLE; 1814 } 1815 } 1816 ret = 1; 1817 err: 1818 CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE); 1819 1820 return ret; 1821 } 1822 1823 1824 /* 1825 * Required mechanisms 1826 * 1827 * CKM_RSA_X_509 1828 * CKM_RSA_PKCS 1829 * CKM_DSA 1830 * 1831 * As long as these required mechanisms are met, it will return success. 1832 * Otherwise, it will return failure and the engine initialization will fail. 1833 * The application will then decide whether to use another engine or 1834 * no engine. 1835 * 1836 * Symmetric ciphers optionally supported 1837 * 1838 * CKM_DES3_CBC 1839 * CKM_DES_CBC 1840 * CKM_AES_CBC 1841 * CKM_RC4 1842 * 1843 * Digests optionally supported 1844 * 1845 * CKM_MD5 1846 * CKM_SHA_1 1847 */ 1848 1849 static int 1850 pk11_choose_slot() 1851 { 1852 CK_SLOT_ID_PTR pSlotList = NULL_PTR; 1853 CK_ULONG ulSlotCount = 0; 1854 CK_MECHANISM_INFO mech_info; 1855 CK_TOKEN_INFO token_info; 1856 int i; 1857 CK_RV rv; 1858 CK_SLOT_ID best_slot_sofar; 1859 CK_BBOOL found_candidate_slot = CK_FALSE; 1860 int slot_n_cipher = 0; 1861 int slot_n_digest = 0; 1862 CK_SLOT_ID current_slot = 0; 1863 int current_slot_n_cipher = 0; 1864 int current_slot_n_digest = 0; 1865 1866 int local_cipher_nids[PK11_CIPHER_MAX]; 1867 int local_digest_nids[PK11_DIGEST_MAX]; 1868 char tmp_buf[20]; 1869 int retval = 0; 1870 1871 /* Get slot list for memory alloction */ 1872 rv = pFuncList->C_GetSlotList(0, NULL_PTR, &ulSlotCount); 1873 1874 if (rv != CKR_OK) 1875 { 1876 PK11err(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST); 1877 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1878 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1879 return retval; 1880 } 1881 1882 if (ulSlotCount == 0) 1883 { 1884 PK11err(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST); 1885 return retval; 1886 } 1887 1888 pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID)); 1889 1890 if (pSlotList == NULL) 1891 { 1892 RSAerr(PK11_F_CHOOSE_SLOT,PK11_R_MALLOC_FAILURE); 1893 return retval; 1894 } 1895 1896 /* Get the slot list for processing */ 1897 rv = pFuncList->C_GetSlotList(0, pSlotList, &ulSlotCount); 1898 if (rv != CKR_OK) 1899 { 1900 PK11err(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST); 1901 snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv); 1902 ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf); 1903 OPENSSL_free(pSlotList); 1904 return retval; 1905 } 1906 1907 for (i = 0; i < ulSlotCount; i++) 1908 { 1909 CK_BBOOL slot_has_rsa = CK_FALSE; 1910 CK_BBOOL slot_has_dsa = CK_FALSE; 1911 CK_BBOOL slot_has_dh = CK_FALSE; 1912 current_slot = pSlotList[i]; 1913 current_slot_n_cipher = 0; 1914 current_slot_n_digest = 0; 1915 memset(local_cipher_nids, 0, sizeof(local_cipher_nids)); 1916 memset(local_digest_nids, 0, sizeof(local_digest_nids)); 1917 1918 #ifdef DEBUG_SLOT_SELECTION 1919 fprintf(stderr, "OPENSSL_PKCS#11_ENGINE: checking slot: %d\n", 1920 current_slot); 1921 #endif 1922 /* Check if slot has random support. */ 1923 rv = pFuncList->C_GetTokenInfo(current_slot, &token_info); 1924 if (rv != CKR_OK) 1925 continue; 1926 1927 if (token_info.flags & CKF_RNG) 1928 pk11_have_random = CK_TRUE; 1929 1930 /* 1931 * Check if this slot is capable of signing and 1932 * verifying with CKM_RSA_PKCS. 1933 */ 1934 rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS, 1935 &mech_info); 1936 1937 if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) && 1938 (mech_info.flags & CKF_VERIFY))) 1939 { 1940 /* 1941 * Check if this slot is capable of encryption, 1942 * decryption, sign, and verify with CKM_RSA_X_509. 1943 */ 1944 rv = pFuncList->C_GetMechanismInfo(current_slot, 1945 CKM_RSA_X_509, &mech_info); 1946 1947 if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) && 1948 (mech_info.flags & CKF_VERIFY) && 1949 (mech_info.flags & CKF_ENCRYPT) && 1950 (mech_info.flags & CKF_VERIFY_RECOVER) && 1951 (mech_info.flags & CKF_DECRYPT))) 1952 slot_has_rsa = CK_TRUE; 1953 } 1954 1955 /* 1956 * Check if this slot is capable of signing and 1957 * verifying with CKM_DSA. 1958 */ 1959 rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA, 1960 &mech_info); 1961 if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) && 1962 (mech_info.flags & CKF_VERIFY))) 1963 slot_has_dsa = CK_TRUE; 1964 1965 /* 1966 * Check if this slot is capable of DH key generataion and 1967 * derivation. 1968 */ 1969 rv = pFuncList->C_GetMechanismInfo(current_slot, 1970 CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info); 1971 1972 if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR)) 1973 { 1974 rv = pFuncList->C_GetMechanismInfo(current_slot, 1975 CKM_DH_PKCS_DERIVE, &mech_info); 1976 if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE)) 1977 slot_has_dh = CK_TRUE; 1978 } 1979 1980 if (!found_candidate_slot && 1981 (slot_has_rsa || slot_has_dsa || slot_has_dh)) 1982 { 1983 #ifdef DEBUG_SLOT_SELECTION 1984 fprintf(stderr, 1985 "OPENSSL_PKCS#11_ENGINE: potential slot: %d\n", 1986 current_slot); 1987 #endif 1988 best_slot_sofar = current_slot; 1989 pk11_have_rsa = slot_has_rsa; 1990 pk11_have_dsa = slot_has_dsa; 1991 pk11_have_dh = slot_has_dh; 1992 found_candidate_slot = CK_TRUE; 1993 #ifdef DEBUG_SLOT_SELECTION 1994 fprintf(stderr, 1995 "OPENSSL_PKCS#11_ENGINE: best so far slot: %d\n", 1996 best_slot_sofar); 1997 #endif 1998 } 1999 2000 /* Count symmetric cipher support. */ 2001 if (!pk11_count_symmetric_cipher(current_slot, CKM_DES_CBC, 2002 ¤t_slot_n_cipher, local_cipher_nids, 2003 PK11_DES_CBC)) 2004 continue; 2005 if (!pk11_count_symmetric_cipher(current_slot, CKM_DES3_CBC, 2006 ¤t_slot_n_cipher, local_cipher_nids, 2007 PK11_DES3_CBC)) 2008 continue; 2009 if (!pk11_count_symmetric_cipher(current_slot, CKM_AES_CBC, 2010 ¤t_slot_n_cipher, local_cipher_nids, 2011 PK11_AES_CBC)) 2012 continue; 2013 if (!pk11_count_symmetric_cipher(current_slot, CKM_RC4, 2014 ¤t_slot_n_cipher, local_cipher_nids, 2015 PK11_RC4)) 2016 continue; 2017 2018 /* Count digest support */ 2019 if (!pk11_count_digest(current_slot, CKM_MD5, 2020 ¤t_slot_n_digest, local_digest_nids, 2021 PK11_MD5)) 2022 continue; 2023 if (!pk11_count_digest(current_slot, CKM_SHA_1, 2024 ¤t_slot_n_digest, local_digest_nids, 2025 PK11_SHA1)) 2026 continue; 2027 2028 /* 2029 * If the current slot supports more ciphers/digests than 2030 * the previous best one we change the current best to this one. 2031 * otherwise leave it where it is. 2032 */ 2033 if (((current_slot_n_cipher > slot_n_cipher) && 2034 (current_slot_n_digest > slot_n_digest)) && 2035 ((slot_has_rsa == pk11_have_rsa) && 2036 (slot_has_dsa == pk11_have_dsa) && 2037 (slot_has_dh == pk11_have_dh))) 2038 { 2039 best_slot_sofar = current_slot; 2040 slot_n_cipher = current_slot_n_cipher; 2041 slot_n_digest = current_slot_n_digest; 2042 2043 memcpy(cipher_nids, local_cipher_nids, 2044 sizeof(local_cipher_nids)); 2045 memcpy(digest_nids, local_digest_nids, 2046 sizeof(local_digest_nids)); 2047 } 2048 2049 } 2050 2051 if (found_candidate_slot) 2052 { 2053 cipher_count = slot_n_cipher; 2054 digest_count = slot_n_digest; 2055 SLOTID = best_slot_sofar; 2056 retval = 1; 2057 } 2058 else 2059 { 2060 cipher_count = 0; 2061 digest_count = 0; 2062 } 2063 2064 #ifdef DEBUG_SLOT_SELECTION 2065 fprintf(stderr, 2066 "OPENSSL_PKCS#11_ENGINE: choose slot: %d\n", SLOTID); 2067 fprintf(stderr, 2068 "OPENSSL_PKCS#11_ENGINE: pk11_have_rsa %d\n", pk11_have_rsa); 2069 fprintf(stderr, 2070 "OPENSSL_PKCS#11_ENGINE: pk11_have_dsa %d\n", pk11_have_dsa); 2071 fprintf(stderr, 2072 "OPENSSL_PKCS#11_ENGINE: pk11_have_dh %d\n", pk11_have_dh); 2073 fprintf(stderr, 2074 "OPENSSL_PKCS#11_ENGINE: pk11_have_random %d\n", pk11_have_random); 2075 #endif /* DEBUG_SLOT_SELECTION */ 2076 2077 if (pSlotList) 2078 free(pSlotList); 2079 2080 return retval; 2081 } 2082 2083 static int pk11_count_symmetric_cipher(int slot_id, CK_MECHANISM_TYPE mech, 2084 int *current_slot_n_cipher, int *local_cipher_nids, int id) 2085 { 2086 CK_MECHANISM_INFO mech_info; 2087 CK_RV rv; 2088 2089 rv = pFuncList->C_GetMechanismInfo(slot_id, mech, &mech_info); 2090 2091 if (rv != CKR_OK) 2092 return 0; 2093 2094 if ((mech_info.flags & CKF_ENCRYPT) && 2095 (mech_info.flags & CKF_DECRYPT)) 2096 { 2097 local_cipher_nids[(*current_slot_n_cipher)++] = ciphers[id].nid; 2098 } 2099 2100 return 1; 2101 } 2102 2103 2104 static int pk11_count_digest(int slot_id, CK_MECHANISM_TYPE mech, 2105 int *current_slot_n_digest, int *local_digest_nids, int id) 2106 { 2107 CK_MECHANISM_INFO mech_info; 2108 CK_RV rv; 2109 2110 rv = pFuncList->C_GetMechanismInfo(slot_id, mech, &mech_info); 2111 2112 if (rv != CKR_OK) 2113 return 0; 2114 2115 if (mech_info.flags & CKF_DIGEST) 2116 { 2117 local_digest_nids[(*current_slot_n_digest)++] = digests[id].nid; 2118 } 2119 2120 return 1; 2121 } 2122 2123 2124 #endif 2125 #endif 2126 2127