Home | History | Annotate | Line # | Download | only in unix
      1 /*	$NetBSD: pk11_api.c,v 1.1 2024/02/18 20:57:57 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0.  If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 /*! \file */
     17 
     18 #include <dlfcn.h>
     19 #include <string.h>
     20 
     21 #include <isc/log.h>
     22 #include <isc/mem.h>
     23 #include <isc/once.h>
     24 #include <isc/print.h>
     25 #include <isc/stdio.h>
     26 #include <isc/thread.h>
     27 #include <isc/util.h>
     28 
     29 #include <pkcs11/pkcs11.h>
     30 
     31 #define KEEP_PKCS11_NAMES
     32 #include <pk11/internal.h>
     33 #include <pk11/pk11.h>
     34 
     35 static void *hPK11 = NULL;
     36 static char loaderrmsg[1024];
     37 
     38 CK_RV
     39 pkcs_C_Initialize(CK_VOID_PTR pReserved) {
     40 	CK_C_Initialize sym;
     41 
     42 	if (hPK11 != NULL) {
     43 		return (CKR_CRYPTOKI_ALREADY_INITIALIZED);
     44 	}
     45 
     46 	hPK11 = dlopen(pk11_get_lib_name(), RTLD_NOW);
     47 
     48 	if (hPK11 == NULL) {
     49 		snprintf(loaderrmsg, sizeof(loaderrmsg),
     50 			 "dlopen(\"%s\") failed: %s\n", pk11_get_lib_name(),
     51 			 dlerror());
     52 		return (CKR_LIBRARY_LOAD_FAILED);
     53 	}
     54 	sym = (CK_C_Initialize)dlsym(hPK11, "C_Initialize");
     55 	if (sym == NULL) {
     56 		return (CKR_FUNCTION_NOT_SUPPORTED);
     57 	}
     58 	return ((*sym)(pReserved));
     59 }
     60 
     61 char *
     62 pk11_get_load_error_message(void) {
     63 	return (loaderrmsg);
     64 }
     65 
     66 CK_RV
     67 pkcs_C_Finalize(CK_VOID_PTR pReserved) {
     68 	CK_C_Finalize sym;
     69 	CK_RV rv;
     70 
     71 	if (hPK11 == NULL) {
     72 		return (CKR_LIBRARY_LOAD_FAILED);
     73 	}
     74 	sym = (CK_C_Finalize)dlsym(hPK11, "C_Finalize");
     75 	if (sym == NULL) {
     76 		return (CKR_FUNCTION_NOT_SUPPORTED);
     77 	}
     78 	rv = (*sym)(pReserved);
     79 	if ((rv == CKR_OK) && (dlclose(hPK11) != 0)) {
     80 		return (CKR_LIBRARY_LOAD_FAILED);
     81 	}
     82 	hPK11 = NULL;
     83 	return (rv);
     84 }
     85 
     86 CK_RV
     87 pkcs_C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList,
     88 		   CK_ULONG_PTR pulCount) {
     89 	static CK_C_GetSlotList sym = NULL;
     90 	static void *pPK11 = NULL;
     91 
     92 	if (hPK11 == NULL) {
     93 		return (CKR_LIBRARY_LOAD_FAILED);
     94 	}
     95 	if ((sym == NULL) || (hPK11 != pPK11)) {
     96 		pPK11 = hPK11;
     97 		sym = (CK_C_GetSlotList)dlsym(hPK11, "C_GetSlotList");
     98 	}
     99 	if (sym == NULL) {
    100 		return (CKR_FUNCTION_NOT_SUPPORTED);
    101 	}
    102 	return ((*sym)(tokenPresent, pSlotList, pulCount));
    103 }
    104 
    105 CK_RV
    106 pkcs_C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) {
    107 	static CK_C_GetTokenInfo sym = NULL;
    108 	static void *pPK11 = NULL;
    109 
    110 	if (hPK11 == NULL) {
    111 		return (CKR_LIBRARY_LOAD_FAILED);
    112 	}
    113 	if ((sym == NULL) || (hPK11 != pPK11)) {
    114 		pPK11 = hPK11;
    115 		sym = (CK_C_GetTokenInfo)dlsym(hPK11, "C_GetTokenInfo");
    116 	}
    117 	if (sym == NULL) {
    118 		return (CKR_FUNCTION_NOT_SUPPORTED);
    119 	}
    120 	return ((*sym)(slotID, pInfo));
    121 }
    122 
    123 CK_RV
    124 pkcs_C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
    125 			CK_MECHANISM_INFO_PTR pInfo) {
    126 	static CK_C_GetMechanismInfo sym = NULL;
    127 	static void *pPK11 = NULL;
    128 
    129 	if (hPK11 == NULL) {
    130 		return (CKR_LIBRARY_LOAD_FAILED);
    131 	}
    132 	if ((sym == NULL) || (hPK11 != pPK11)) {
    133 		pPK11 = hPK11;
    134 		sym = (CK_C_GetMechanismInfo)dlsym(hPK11, "C_GetMechanismInfo");
    135 	}
    136 	if (sym == NULL) {
    137 		return (CKR_FUNCTION_NOT_SUPPORTED);
    138 	}
    139 	return ((*sym)(slotID, type, pInfo));
    140 }
    141 
    142 CK_RV
    143 pkcs_C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication,
    144 		   CK_RV (*Notify)(CK_SESSION_HANDLE hSession,
    145 				   CK_NOTIFICATION event,
    146 				   CK_VOID_PTR pApplication),
    147 		   CK_SESSION_HANDLE_PTR phSession) {
    148 	static CK_C_OpenSession sym = NULL;
    149 	static void *pPK11 = NULL;
    150 
    151 	if (hPK11 == NULL) {
    152 		hPK11 = dlopen(pk11_get_lib_name(), RTLD_NOW);
    153 	}
    154 	if (hPK11 == NULL) {
    155 		snprintf(loaderrmsg, sizeof(loaderrmsg),
    156 			 "dlopen(\"%s\") failed: %s\n", pk11_get_lib_name(),
    157 			 dlerror());
    158 		return (CKR_LIBRARY_LOAD_FAILED);
    159 	}
    160 	if ((sym == NULL) || (hPK11 != pPK11)) {
    161 		pPK11 = hPK11;
    162 		sym = (CK_C_OpenSession)dlsym(hPK11, "C_OpenSession");
    163 	}
    164 	if (sym == NULL) {
    165 		return (CKR_FUNCTION_NOT_SUPPORTED);
    166 	}
    167 	return ((*sym)(slotID, flags, pApplication, Notify, phSession));
    168 }
    169 
    170 CK_RV
    171 pkcs_C_CloseSession(CK_SESSION_HANDLE hSession) {
    172 	static CK_C_CloseSession sym = NULL;
    173 	static void *pPK11 = NULL;
    174 
    175 	if (hPK11 == NULL) {
    176 		return (CKR_LIBRARY_LOAD_FAILED);
    177 	}
    178 	if ((sym == NULL) || (hPK11 != pPK11)) {
    179 		pPK11 = hPK11;
    180 		sym = (CK_C_CloseSession)dlsym(hPK11, "C_CloseSession");
    181 	}
    182 	if (sym == NULL) {
    183 		return (CKR_FUNCTION_NOT_SUPPORTED);
    184 	}
    185 	return ((*sym)(hSession));
    186 }
    187 
    188 CK_RV
    189 pkcs_C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
    190 	     CK_CHAR_PTR pPin, CK_ULONG usPinLen) {
    191 	static CK_C_Login sym = NULL;
    192 	static void *pPK11 = NULL;
    193 
    194 	if (hPK11 == NULL) {
    195 		return (CKR_LIBRARY_LOAD_FAILED);
    196 	}
    197 	if ((sym == NULL) || (hPK11 != pPK11)) {
    198 		pPK11 = hPK11;
    199 		sym = (CK_C_Login)dlsym(hPK11, "C_Login");
    200 	}
    201 	if (sym == NULL) {
    202 		return (CKR_FUNCTION_NOT_SUPPORTED);
    203 	}
    204 	return ((*sym)(hSession, userType, pPin, usPinLen));
    205 }
    206 
    207 CK_RV
    208 pkcs_C_Logout(CK_SESSION_HANDLE hSession) {
    209 	static CK_C_Logout sym = NULL;
    210 	static void *pPK11 = NULL;
    211 
    212 	if (hPK11 == NULL) {
    213 		return (CKR_LIBRARY_LOAD_FAILED);
    214 	}
    215 	if ((sym == NULL) || (hPK11 != pPK11)) {
    216 		pPK11 = hPK11;
    217 		sym = (CK_C_Logout)dlsym(hPK11, "C_Logout");
    218 	}
    219 	if (sym == NULL) {
    220 		return (CKR_FUNCTION_NOT_SUPPORTED);
    221 	}
    222 	return ((*sym)(hSession));
    223 }
    224 
    225 CK_RV
    226 pkcs_C_CreateObject(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
    227 		    CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phObject) {
    228 	static CK_C_CreateObject sym = NULL;
    229 	static void *pPK11 = NULL;
    230 
    231 	if (hPK11 == NULL) {
    232 		return (CKR_LIBRARY_LOAD_FAILED);
    233 	}
    234 	if ((sym == NULL) || (hPK11 != pPK11)) {
    235 		pPK11 = hPK11;
    236 		sym = (CK_C_CreateObject)dlsym(hPK11, "C_CreateObject");
    237 	}
    238 	if (sym == NULL) {
    239 		return (CKR_FUNCTION_NOT_SUPPORTED);
    240 	}
    241 	return ((*sym)(hSession, pTemplate, usCount, phObject));
    242 }
    243 
    244 CK_RV
    245 pkcs_C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) {
    246 	static CK_C_DestroyObject sym = NULL;
    247 	static void *pPK11 = NULL;
    248 
    249 	if (hPK11 == NULL) {
    250 		return (CKR_LIBRARY_LOAD_FAILED);
    251 	}
    252 	if ((sym == NULL) || (hPK11 != pPK11)) {
    253 		pPK11 = hPK11;
    254 		sym = (CK_C_DestroyObject)dlsym(hPK11, "C_DestroyObject");
    255 	}
    256 	if (sym == NULL) {
    257 		return (CKR_FUNCTION_NOT_SUPPORTED);
    258 	}
    259 	return ((*sym)(hSession, hObject));
    260 }
    261 
    262 CK_RV
    263 pkcs_C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
    264 			 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) {
    265 	static CK_C_GetAttributeValue sym = NULL;
    266 	static void *pPK11 = NULL;
    267 
    268 	if (hPK11 == NULL) {
    269 		return (CKR_LIBRARY_LOAD_FAILED);
    270 	}
    271 	if ((sym == NULL) || (hPK11 != pPK11)) {
    272 		pPK11 = hPK11;
    273 		sym = (CK_C_GetAttributeValue)dlsym(hPK11, "C_"
    274 							   "GetAttributeValue");
    275 	}
    276 	if (sym == NULL) {
    277 		return (CKR_FUNCTION_NOT_SUPPORTED);
    278 	}
    279 	return ((*sym)(hSession, hObject, pTemplate, usCount));
    280 }
    281 
    282 CK_RV
    283 pkcs_C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
    284 			 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) {
    285 	static CK_C_SetAttributeValue sym = NULL;
    286 	static void *pPK11 = NULL;
    287 
    288 	if (hPK11 == NULL) {
    289 		return (CKR_LIBRARY_LOAD_FAILED);
    290 	}
    291 	if ((sym == NULL) || (hPK11 != pPK11)) {
    292 		pPK11 = hPK11;
    293 		sym = (CK_C_SetAttributeValue)dlsym(hPK11, "C_"
    294 							   "SetAttributeValue");
    295 	}
    296 	if (sym == NULL) {
    297 		return (CKR_FUNCTION_NOT_SUPPORTED);
    298 	}
    299 	return ((*sym)(hSession, hObject, pTemplate, usCount));
    300 }
    301 
    302 CK_RV
    303 pkcs_C_FindObjectsInit(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
    304 		       CK_ULONG usCount) {
    305 	static CK_C_FindObjectsInit sym = NULL;
    306 	static void *pPK11 = NULL;
    307 
    308 	if (hPK11 == NULL) {
    309 		return (CKR_LIBRARY_LOAD_FAILED);
    310 	}
    311 	if ((sym == NULL) || (hPK11 != pPK11)) {
    312 		pPK11 = hPK11;
    313 		sym = (CK_C_FindObjectsInit)dlsym(hPK11, "C_FindObjectsInit");
    314 	}
    315 	if (sym == NULL) {
    316 		return (CKR_FUNCTION_NOT_SUPPORTED);
    317 	}
    318 	return ((*sym)(hSession, pTemplate, usCount));
    319 }
    320 
    321 CK_RV
    322 pkcs_C_FindObjects(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject,
    323 		   CK_ULONG usMaxObjectCount, CK_ULONG_PTR pusObjectCount) {
    324 	static CK_C_FindObjects sym = NULL;
    325 	static void *pPK11 = NULL;
    326 
    327 	if (hPK11 == NULL) {
    328 		return (CKR_LIBRARY_LOAD_FAILED);
    329 	}
    330 	if ((sym == NULL) || (hPK11 != pPK11)) {
    331 		pPK11 = hPK11;
    332 		sym = (CK_C_FindObjects)dlsym(hPK11, "C_FindObjects");
    333 	}
    334 	if (sym == NULL) {
    335 		return (CKR_FUNCTION_NOT_SUPPORTED);
    336 	}
    337 	return ((*sym)(hSession, phObject, usMaxObjectCount, pusObjectCount));
    338 }
    339 
    340 CK_RV
    341 pkcs_C_FindObjectsFinal(CK_SESSION_HANDLE hSession) {
    342 	static CK_C_FindObjectsFinal sym = NULL;
    343 	static void *pPK11 = NULL;
    344 
    345 	if (hPK11 == NULL) {
    346 		return (CKR_LIBRARY_LOAD_FAILED);
    347 	}
    348 	if ((sym == NULL) || (hPK11 != pPK11)) {
    349 		pPK11 = hPK11;
    350 		sym = (CK_C_FindObjectsFinal)dlsym(hPK11, "C_FindObjectsFinal");
    351 	}
    352 	if (sym == NULL) {
    353 		return (CKR_FUNCTION_NOT_SUPPORTED);
    354 	}
    355 	return ((*sym)(hSession));
    356 }
    357 
    358 CK_RV
    359 pkcs_C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
    360 		   CK_OBJECT_HANDLE hKey) {
    361 	static CK_C_EncryptInit sym = NULL;
    362 	static void *pPK11 = NULL;
    363 
    364 	if (hPK11 == NULL) {
    365 		return (CKR_LIBRARY_LOAD_FAILED);
    366 	}
    367 	if ((sym == NULL) || (hPK11 != pPK11)) {
    368 		pPK11 = hPK11;
    369 		sym = (CK_C_EncryptInit)dlsym(hPK11, "C_EncryptInit");
    370 	}
    371 	if (sym == NULL) {
    372 		return (CKR_FUNCTION_NOT_SUPPORTED);
    373 	}
    374 	return ((*sym)(hSession, pMechanism, hKey));
    375 }
    376 
    377 CK_RV
    378 pkcs_C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
    379 	       CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData,
    380 	       CK_ULONG_PTR pulEncryptedDataLen) {
    381 	static CK_C_Encrypt sym = NULL;
    382 	static void *pPK11 = NULL;
    383 
    384 	if (hPK11 == NULL) {
    385 		return (CKR_LIBRARY_LOAD_FAILED);
    386 	}
    387 	if ((sym == NULL) || (hPK11 != pPK11)) {
    388 		pPK11 = hPK11;
    389 		sym = (CK_C_Encrypt)dlsym(hPK11, "C_Encrypt");
    390 	}
    391 	if (sym == NULL) {
    392 		return (CKR_FUNCTION_NOT_SUPPORTED);
    393 	}
    394 	return ((*sym)(hSession, pData, ulDataLen, pEncryptedData,
    395 		       pulEncryptedDataLen));
    396 }
    397 
    398 CK_RV
    399 pkcs_C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism) {
    400 	static CK_C_DigestInit sym = NULL;
    401 	static void *pPK11 = NULL;
    402 
    403 	if (hPK11 == NULL) {
    404 		return (CKR_LIBRARY_LOAD_FAILED);
    405 	}
    406 	if ((sym == NULL) || (hPK11 != pPK11)) {
    407 		pPK11 = hPK11;
    408 		sym = (CK_C_DigestInit)dlsym(hPK11, "C_DigestInit");
    409 	}
    410 	if (sym == NULL) {
    411 		return (CKR_FUNCTION_NOT_SUPPORTED);
    412 	}
    413 	return ((*sym)(hSession, pMechanism));
    414 }
    415 
    416 CK_RV
    417 pkcs_C_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
    418 		    CK_ULONG ulPartLen) {
    419 	static CK_C_DigestUpdate sym = NULL;
    420 	static void *pPK11 = NULL;
    421 
    422 	if (hPK11 == NULL) {
    423 		return (CKR_LIBRARY_LOAD_FAILED);
    424 	}
    425 	if ((sym == NULL) || (hPK11 != pPK11)) {
    426 		pPK11 = hPK11;
    427 		sym = (CK_C_DigestUpdate)dlsym(hPK11, "C_DigestUpdate");
    428 	}
    429 	if (sym == NULL) {
    430 		return (CKR_FUNCTION_NOT_SUPPORTED);
    431 	}
    432 	return ((*sym)(hSession, pPart, ulPartLen));
    433 }
    434 
    435 CK_RV
    436 pkcs_C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest,
    437 		   CK_ULONG_PTR pulDigestLen) {
    438 	static CK_C_DigestFinal sym = NULL;
    439 	static void *pPK11 = NULL;
    440 
    441 	if (hPK11 == NULL) {
    442 		return (CKR_LIBRARY_LOAD_FAILED);
    443 	}
    444 	if ((sym == NULL) || (hPK11 != pPK11)) {
    445 		pPK11 = hPK11;
    446 		sym = (CK_C_DigestFinal)dlsym(hPK11, "C_DigestFinal");
    447 	}
    448 	if (sym == NULL) {
    449 		return (CKR_FUNCTION_NOT_SUPPORTED);
    450 	}
    451 	return ((*sym)(hSession, pDigest, pulDigestLen));
    452 }
    453 
    454 CK_RV
    455 pkcs_C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
    456 		CK_OBJECT_HANDLE hKey) {
    457 	static CK_C_SignInit sym = NULL;
    458 	static void *pPK11 = NULL;
    459 
    460 	if (hPK11 == NULL) {
    461 		return (CKR_LIBRARY_LOAD_FAILED);
    462 	}
    463 	if ((sym == NULL) || (hPK11 != pPK11)) {
    464 		pPK11 = hPK11;
    465 		sym = (CK_C_SignInit)dlsym(hPK11, "C_SignInit");
    466 	}
    467 	if (sym == NULL) {
    468 		return (CKR_FUNCTION_NOT_SUPPORTED);
    469 	}
    470 	return ((*sym)(hSession, pMechanism, hKey));
    471 }
    472 
    473 CK_RV
    474 pkcs_C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
    475 	    CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) {
    476 	static CK_C_Sign sym = NULL;
    477 	static void *pPK11 = NULL;
    478 
    479 	if (hPK11 == NULL) {
    480 		return (CKR_LIBRARY_LOAD_FAILED);
    481 	}
    482 	if ((sym == NULL) || (hPK11 != pPK11)) {
    483 		pPK11 = hPK11;
    484 		sym = (CK_C_Sign)dlsym(hPK11, "C_Sign");
    485 	}
    486 	if (sym == NULL) {
    487 		return (CKR_FUNCTION_NOT_SUPPORTED);
    488 	}
    489 	return ((*sym)(hSession, pData, ulDataLen, pSignature,
    490 		       pulSignatureLen));
    491 }
    492 
    493 CK_RV
    494 pkcs_C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
    495 		  CK_ULONG ulPartLen) {
    496 	static CK_C_SignUpdate sym = NULL;
    497 	static void *pPK11 = NULL;
    498 
    499 	if (hPK11 == NULL) {
    500 		return (CKR_LIBRARY_LOAD_FAILED);
    501 	}
    502 	if ((sym == NULL) || (hPK11 != pPK11)) {
    503 		pPK11 = hPK11;
    504 		sym = (CK_C_SignUpdate)dlsym(hPK11, "C_SignUpdate");
    505 	}
    506 	if (sym == NULL) {
    507 		return (CKR_FUNCTION_NOT_SUPPORTED);
    508 	}
    509 	return ((*sym)(hSession, pPart, ulPartLen));
    510 }
    511 
    512 CK_RV
    513 pkcs_C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
    514 		 CK_ULONG_PTR pulSignatureLen) {
    515 	static CK_C_SignFinal sym = NULL;
    516 	static void *pPK11 = NULL;
    517 
    518 	if (hPK11 == NULL) {
    519 		return (CKR_LIBRARY_LOAD_FAILED);
    520 	}
    521 	if ((sym == NULL) || (hPK11 != pPK11)) {
    522 		pPK11 = hPK11;
    523 		sym = (CK_C_SignFinal)dlsym(hPK11, "C_SignFinal");
    524 	}
    525 	if (sym == NULL) {
    526 		return (CKR_FUNCTION_NOT_SUPPORTED);
    527 	}
    528 	return ((*sym)(hSession, pSignature, pulSignatureLen));
    529 }
    530 
    531 CK_RV
    532 pkcs_C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
    533 		  CK_OBJECT_HANDLE hKey) {
    534 	static CK_C_VerifyInit sym = NULL;
    535 	static void *pPK11 = NULL;
    536 
    537 	if (hPK11 == NULL) {
    538 		return (CKR_LIBRARY_LOAD_FAILED);
    539 	}
    540 	if ((sym == NULL) || (hPK11 != pPK11)) {
    541 		pPK11 = hPK11;
    542 		sym = (CK_C_VerifyInit)dlsym(hPK11, "C_VerifyInit");
    543 	}
    544 	if (sym == NULL) {
    545 		return (CKR_FUNCTION_NOT_SUPPORTED);
    546 	}
    547 	return ((*sym)(hSession, pMechanism, hKey));
    548 }
    549 
    550 CK_RV
    551 pkcs_C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
    552 	      CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) {
    553 	static CK_C_Verify sym = NULL;
    554 	static void *pPK11 = NULL;
    555 
    556 	if (hPK11 == NULL) {
    557 		return (CKR_LIBRARY_LOAD_FAILED);
    558 	}
    559 	if ((sym == NULL) || (hPK11 != pPK11)) {
    560 		pPK11 = hPK11;
    561 		sym = (CK_C_Verify)dlsym(hPK11, "C_Verify");
    562 	}
    563 	if (sym == NULL) {
    564 		return (CKR_FUNCTION_NOT_SUPPORTED);
    565 	}
    566 	return ((*sym)(hSession, pData, ulDataLen, pSignature, ulSignatureLen));
    567 }
    568 
    569 CK_RV
    570 pkcs_C_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
    571 		    CK_ULONG ulPartLen) {
    572 	static CK_C_VerifyUpdate sym = NULL;
    573 	static void *pPK11 = NULL;
    574 
    575 	if (hPK11 == NULL) {
    576 		return (CKR_LIBRARY_LOAD_FAILED);
    577 	}
    578 	if ((sym == NULL) || (hPK11 != pPK11)) {
    579 		pPK11 = hPK11;
    580 		sym = (CK_C_VerifyUpdate)dlsym(hPK11, "C_VerifyUpdate");
    581 	}
    582 	if (sym == NULL) {
    583 		return (CKR_FUNCTION_NOT_SUPPORTED);
    584 	}
    585 	return ((*sym)(hSession, pPart, ulPartLen));
    586 }
    587 
    588 CK_RV
    589 pkcs_C_VerifyFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
    590 		   CK_ULONG ulSignatureLen) {
    591 	static CK_C_VerifyFinal sym = NULL;
    592 	static void *pPK11 = NULL;
    593 
    594 	if (hPK11 == NULL) {
    595 		return (CKR_LIBRARY_LOAD_FAILED);
    596 	}
    597 	if ((sym == NULL) || (hPK11 != pPK11)) {
    598 		pPK11 = hPK11;
    599 		sym = (CK_C_VerifyFinal)dlsym(hPK11, "C_VerifyFinal");
    600 	}
    601 	if (sym == NULL) {
    602 		return (CKR_FUNCTION_NOT_SUPPORTED);
    603 	}
    604 	return ((*sym)(hSession, pSignature, ulSignatureLen));
    605 }
    606 
    607 CK_RV
    608 pkcs_C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
    609 		   CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
    610 		   CK_OBJECT_HANDLE_PTR phKey) {
    611 	static CK_C_GenerateKey sym = NULL;
    612 	static void *pPK11 = NULL;
    613 
    614 	if (hPK11 == NULL) {
    615 		return (CKR_LIBRARY_LOAD_FAILED);
    616 	}
    617 	if ((sym == NULL) || (hPK11 != pPK11)) {
    618 		pPK11 = hPK11;
    619 		sym = (CK_C_GenerateKey)dlsym(hPK11, "C_GenerateKey");
    620 	}
    621 	if (sym == NULL) {
    622 		return (CKR_FUNCTION_NOT_SUPPORTED);
    623 	}
    624 	return ((*sym)(hSession, pMechanism, pTemplate, ulCount, phKey));
    625 }
    626 
    627 CK_RV
    628 pkcs_C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
    629 		       CK_ATTRIBUTE_PTR pPublicKeyTemplate,
    630 		       CK_ULONG usPublicKeyAttributeCount,
    631 		       CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
    632 		       CK_ULONG usPrivateKeyAttributeCount,
    633 		       CK_OBJECT_HANDLE_PTR phPrivateKey,
    634 		       CK_OBJECT_HANDLE_PTR phPublicKey) {
    635 	static CK_C_GenerateKeyPair sym = NULL;
    636 	static void *pPK11 = NULL;
    637 
    638 	if (hPK11 == NULL) {
    639 		return (CKR_LIBRARY_LOAD_FAILED);
    640 	}
    641 	if ((sym == NULL) || (hPK11 != pPK11)) {
    642 		pPK11 = hPK11;
    643 		sym = (CK_C_GenerateKeyPair)dlsym(hPK11, "C_GenerateKeyPair");
    644 	}
    645 	if (sym == NULL) {
    646 		return (CKR_FUNCTION_NOT_SUPPORTED);
    647 	}
    648 	return ((*sym)(hSession, pMechanism, pPublicKeyTemplate,
    649 		       usPublicKeyAttributeCount, pPrivateKeyTemplate,
    650 		       usPrivateKeyAttributeCount, phPrivateKey, phPublicKey));
    651 }
    652 
    653 CK_RV
    654 pkcs_C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
    655 		 CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
    656 		 CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) {
    657 	static CK_C_DeriveKey sym = NULL;
    658 	static void *pPK11 = NULL;
    659 
    660 	if (hPK11 == NULL) {
    661 		return (CKR_LIBRARY_LOAD_FAILED);
    662 	}
    663 	if ((sym == NULL) || (hPK11 != pPK11)) {
    664 		pPK11 = hPK11;
    665 		sym = (CK_C_DeriveKey)dlsym(hPK11, "C_DeriveKey");
    666 	}
    667 	if (sym == NULL) {
    668 		return (CKR_FUNCTION_NOT_SUPPORTED);
    669 	}
    670 	return ((*sym)(hSession, pMechanism, hBaseKey, pTemplate,
    671 		       ulAttributeCount, phKey));
    672 }
    673 
    674 CK_RV
    675 pkcs_C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
    676 		  CK_ULONG ulSeedLen) {
    677 	static CK_C_SeedRandom sym = NULL;
    678 	static void *pPK11 = NULL;
    679 
    680 	if (hPK11 == NULL) {
    681 		return (CKR_LIBRARY_LOAD_FAILED);
    682 	}
    683 	if ((sym == NULL) || (hPK11 != pPK11)) {
    684 		pPK11 = hPK11;
    685 		sym = (CK_C_SeedRandom)dlsym(hPK11, "C_SeedRandom");
    686 	}
    687 	if (sym == NULL) {
    688 		return (CKR_FUNCTION_NOT_SUPPORTED);
    689 	}
    690 	return ((*sym)(hSession, pSeed, ulSeedLen));
    691 }
    692 
    693 CK_RV
    694 pkcs_C_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR RandomData,
    695 		      CK_ULONG ulRandomLen) {
    696 	static CK_C_GenerateRandom sym = NULL;
    697 	static void *pPK11 = NULL;
    698 
    699 	if (hPK11 == NULL) {
    700 		return (CKR_LIBRARY_LOAD_FAILED);
    701 	}
    702 	if ((sym == NULL) || (hPK11 != pPK11)) {
    703 		pPK11 = hPK11;
    704 		sym = (CK_C_GenerateRandom)dlsym(hPK11, "C_GenerateRandom");
    705 	}
    706 	if (sym == NULL) {
    707 		return (CKR_FUNCTION_NOT_SUPPORTED);
    708 	}
    709 	return ((*sym)(hSession, RandomData, ulRandomLen));
    710 }
    711