Skip to content

Commit ee16b95

Browse files
committed
Add support for PKCS#11 Version 3.0 and 3.1
1 parent a631611 commit ee16b95

4 files changed

Lines changed: 508 additions & 25 deletions

File tree

.wolfssl_known_macro_extras

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@ HAVE_INTEL_SPEEDUP
281281
HAVE_MDK_RTX
282282
HAVE_NETX_BSD
283283
HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK
284+
HAVE_PKCS11_STATIC
285+
HAVE_PKCS11_V3_STATIC
284286
HAVE_POCO_LIB
285287
HAVE_RTP_SYS
286288
HAVE_SECURE_GETENV

wolfcrypt/src/wc_pkcs11.c

Lines changed: 222 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ static void pkcs11_val(const char* op, CK_ULONG val)
432432
*/
433433
int wc_Pkcs11_Initialize(Pkcs11Dev* dev, const char* library, void* heap)
434434
{
435-
return wc_Pkcs11_Initialize_ex(dev, library, heap, NULL);
435+
return wc_Pkcs11_Initialize_v3(dev, library, heap, NULL, NULL, NULL);
436436
}
437437

438438
/**
@@ -451,52 +451,249 @@ int wc_Pkcs11_Initialize(Pkcs11Dev* dev, const char* library, void* heap)
451451
*/
452452
int wc_Pkcs11_Initialize_ex(Pkcs11Dev* dev, const char* library, void* heap,
453453
CK_RV* rvp)
454+
{
455+
return wc_Pkcs11_Initialize_v3(dev, library, heap, NULL, NULL, rvp);
456+
}
457+
458+
/**
459+
* Load library, get function list and initialize PKCS#11.
460+
*
461+
* @param [in] dev Device object.
462+
* @param [in] library Library name including path.
463+
* @param [in] heap Heap hint.
464+
* @param [in,out] version On in, desired version of interface.
465+
* On out, actual obtained version of interface.
466+
* @param [in] interfaceName Name of the interface to use.
467+
* @param [out] rvp PKCS#11 return value. Last return value seen.
468+
* May be NULL.
469+
* @return BAD_FUNC_ARG when dev or library are NULL pointers.
470+
* @return BAD_PATH_ERROR when dynamic library cannot be opened.
471+
* @return WC_INIT_E when the initialization PKCS#11 fails.
472+
* @return WC_HW_E when unable to get PKCS#11 function list.
473+
* @return 0 on success.
474+
*/
475+
int wc_Pkcs11_Initialize_v3(Pkcs11Dev* dev, const char* library,
476+
void* heap, int* version, const char* interfaceName, CK_RV* rvp)
454477
{
455478
int ret = 0;
456479
CK_RV rv = CKR_OK;
457-
#ifndef HAVE_PKCS11_STATIC
480+
#if !defined(HAVE_PKCS11_STATIC) && !defined(HAVE_PKCS11_V3_STATIC)
458481
void* func;
459482
#endif
460483
CK_C_INITIALIZE_ARGS args;
484+
CK_VERSION_PTR version_ptr = NULL;
461485

462486
if (dev == NULL || library == NULL)
463487
ret = BAD_FUNC_ARG;
464488

465489
if (ret == 0) {
466490
dev->heap = heap;
467-
#ifndef HAVE_PKCS11_STATIC
491+
#if defined(HAVE_PKCS11_V3_STATIC)
492+
CK_INTERFACE_PTR interface = NULL;
493+
CK_VERSION pkcs11_version = {0, 0};
494+
495+
if (version != NULL) {
496+
if (*version == WC_PCKS11VERSION_2_20) {
497+
pkcs11_version.major = 2;
498+
pkcs11_version.minor = 20;
499+
}
500+
else if (*version == WC_PCKS11VERSION_2_20) {
501+
pkcs11_version.major = 2;
502+
pkcs11_version.minor = 40;
503+
}
504+
else if (*version == WC_PCKS11VERSION_3_0) {
505+
pkcs11_version.major = 3;
506+
pkcs11_version.minor = 0;
507+
}
508+
else if (*version == WC_PCKS11VERSION_3_1) {
509+
pkcs11_version.major = 3;
510+
pkcs11_version.minor = 1;
511+
}
512+
version_ptr = &pkcs11_version;
513+
}
514+
else {
515+
version_ptr = NULL;
516+
}
517+
518+
rv = C_GetInterface((CK_UTF8CHAR_PTR) interfaceName, version_ptr,
519+
&interface, 0);
520+
521+
if (rv == CKR_OK) {
522+
dev->func = interface->pFunctionList;
523+
version_ptr = (CK_VERSION_PTR) interface->pFunctionList;
524+
if (version_ptr->major == 2 && version_ptr->minor == 20) {
525+
dev->version = WC_PCKS11VERSION_2_20;
526+
}
527+
else if (version_ptr->major == 2 &&
528+
version_ptr->minor == 40) {
529+
dev->version = WC_PCKS11VERSION_2_40;
530+
}
531+
else if (version_ptr->major == 3 &&
532+
version_ptr->minor == 0) {
533+
dev->version = WC_PCKS11VERSION_3_0;
534+
}
535+
else if (version_ptr->major == 3 &&
536+
version_ptr->minor == 1) {
537+
dev->version = WC_PCKS11VERSION_3_1;
538+
}
539+
else {
540+
WOLFSSL_MSG_EX("Unsupported PKCS#11 version: %d.%d",
541+
version_ptr->major, version_ptr->minor);
542+
ret = WC_HW_E;
543+
}
544+
}
545+
else {
546+
PKCS11_RV("CK_C_GetInterface", rv);
547+
ret = WC_HW_E;
548+
}
549+
#elif defined(HAVE_PKCS11_STATIC)
550+
rv = C_GetFunctionList(&dev->func);
551+
if (rv == CKR_OK) {
552+
version_ptr = (CK_VERSION_PTR) dev->func;
553+
if (version_ptr->major == 2 &&
554+
version_ptr->minor == 20) {
555+
dev->version = WC_PCKS11VERSION_2_20;
556+
}
557+
else if (version_ptr->major == 2 &&
558+
version_ptr->minor == 40) {
559+
dev->version = WC_PCKS11VERSION_2_40;
560+
}
561+
else {
562+
WOLFSSL_MSG_EX("Unsupported PKCS#11 version: %d.%d",
563+
version_ptr->major,
564+
version_ptr->minor);
565+
ret = WC_HW_E;
566+
}
567+
}
568+
else {
569+
PKCS11_RV("CK_C_GetFunctionList", rv);
570+
ret = WC_HW_E;
571+
}
572+
#else
573+
/* Load dynamic library */
468574
dev->dlHandle = dlopen(library, RTLD_NOW | RTLD_LOCAL);
469575
if (dev->dlHandle == NULL) {
470576
WOLFSSL_MSG(dlerror());
471577
ret = BAD_PATH_ERROR;
472578
}
473-
}
474579

475-
if (ret == 0) {
476-
dev->func = NULL;
477-
func = dlsym(dev->dlHandle, "C_GetFunctionList");
478-
if (func == NULL) {
479-
WOLFSSL_MSG(dlerror());
480-
ret = WC_HW_E;
580+
if (ret == 0) {
581+
/* Check if the library supports PKCS#11 version 3.0 (or above) by
582+
* looking for the C_GetInterface method (only present for >= V3.0).
583+
*/
584+
func = dlsym(dev->dlHandle, "C_GetInterface");
585+
if (func != NULL) {
586+
/* Function is present, use it */
587+
CK_INTERFACE_PTR interface = NULL;
588+
CK_VERSION pkcs11_version = {0, 0};
589+
if (version != NULL) {
590+
if (*version == WC_PCKS11VERSION_2_20) {
591+
pkcs11_version.major = 2;
592+
pkcs11_version.minor = 20;
593+
}
594+
else if (*version == WC_PCKS11VERSION_2_40) {
595+
pkcs11_version.major = 2;
596+
pkcs11_version.minor = 40;
597+
}
598+
else if (*version == WC_PCKS11VERSION_3_0) {
599+
pkcs11_version.major = 3;
600+
pkcs11_version.minor = 0;
601+
}
602+
else if (*version == WC_PCKS11VERSION_3_1) {
603+
pkcs11_version.major = 3;
604+
pkcs11_version.minor = 1;
605+
}
606+
version_ptr = &pkcs11_version;
607+
}
608+
else {
609+
version_ptr = NULL;
610+
}
611+
612+
rv = ((CK_C_GetInterface)func)((CK_UTF8CHAR_PTR) interfaceName,
613+
version_ptr, &interface, 0);
614+
if (rv == CKR_OK) {
615+
dev->func = interface->pFunctionList;
616+
version_ptr = (CK_VERSION_PTR) interface->pFunctionList;
617+
if (version_ptr->major == 2 && version_ptr->minor == 20) {
618+
dev->version = WC_PCKS11VERSION_2_20;
619+
}
620+
else if (version_ptr->major == 2 &&
621+
version_ptr->minor == 40) {
622+
dev->version = WC_PCKS11VERSION_2_40;
623+
}
624+
else if (version_ptr->major == 3 &&
625+
version_ptr->minor == 0) {
626+
dev->version = WC_PCKS11VERSION_3_0;
627+
}
628+
else if (version_ptr->major == 3 &&
629+
version_ptr->minor == 1) {
630+
dev->version = WC_PCKS11VERSION_3_1;
631+
}
632+
else {
633+
WOLFSSL_MSG_EX("Unsupported PKCS#11 version: %d.%d",
634+
version_ptr->major, version_ptr->minor);
635+
ret = WC_HW_E;
636+
}
637+
}
638+
else {
639+
PKCS11_RV("CK_C_GetInterface", rv);
640+
ret = WC_HW_E;
641+
}
642+
}
643+
else {
644+
/* Function not present, try a 2.x library by looking for
645+
* C_GetFunctionList. */
646+
func = dlsym(dev->dlHandle, "C_GetFunctionList");
647+
if (func == NULL) {
648+
#if defined(_WIN32)
649+
WOLFSSL_MSG_EX("GetProcAddress(): %d", GetLastError());
650+
#else
651+
WOLFSSL_MSG(dlerror());
652+
#endif
653+
ret = WC_HW_E;
654+
}
655+
if (ret == 0) {
656+
rv = ((CK_C_GetFunctionList)func)(&dev->func);
657+
if (rv == CKR_OK) {
658+
version_ptr = (CK_VERSION_PTR) dev->func;
659+
if (version_ptr->major == 2 &&
660+
version_ptr->minor == 20) {
661+
dev->version = WC_PCKS11VERSION_2_20;
662+
}
663+
else if (version_ptr->major == 2 &&
664+
version_ptr->minor == 40) {
665+
dev->version = WC_PCKS11VERSION_2_40;
666+
}
667+
else {
668+
WOLFSSL_MSG_EX("Unsupported PKCS#11 version: %d.%d",
669+
version_ptr->major,
670+
version_ptr->minor);
671+
ret = WC_HW_E;
672+
}
673+
}
674+
else {
675+
PKCS11_RV("CK_C_GetFunctionList", rv);
676+
ret = WC_HW_E;
677+
}
678+
}
679+
}
481680
}
482-
}
483-
if (ret == 0) {
484-
rv = ((CK_C_GetFunctionList)func)(&dev->func);
485-
#else
486-
rv = C_GetFunctionList(&dev->func);
487681
#endif
488-
if (rv != CKR_OK) {
489-
PKCS11_RV("CK_C_GetFunctionList", ret);
490-
ret = WC_HW_E;
491-
}
492682
}
493683

684+
if (ret == 0 && version != NULL)
685+
*version = dev->version;
686+
494687
if (ret == 0) {
495688
XMEMSET(&args, 0x00, sizeof(args));
496689
args.flags = CKF_OS_LOCKING_OK;
497690
rv = dev->func->C_Initialize(&args);
498-
if (rv != CKR_OK) {
499-
PKCS11_RV("C_Initialize", ret);
691+
if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) {
692+
WOLFSSL_MSG("PKCS#11 already initialized");
693+
rv = CKR_OK;
694+
}
695+
else if (rv != CKR_OK) {
696+
PKCS11_RV("C_Initialize", rv);
500697
ret = WC_INIT_E;
501698
}
502699
}
@@ -520,15 +717,15 @@ int wc_Pkcs11_Initialize_ex(Pkcs11Dev* dev, const char* library, void* heap,
520717
void wc_Pkcs11_Finalize(Pkcs11Dev* dev)
521718
{
522719
if (dev != NULL
523-
#ifndef HAVE_PKCS11_STATIC
720+
#if !defined(HAVE_PKCS11_STATIC) && !defined(HAVE_PKCS11_V3_STATIC)
524721
&& dev->dlHandle != NULL
525722
#endif
526723
) {
527724
if (dev->func != NULL) {
528725
dev->func->C_Finalize(NULL);
529726
dev->func = NULL;
530727
}
531-
#ifndef HAVE_PKCS11_STATIC
728+
#if !defined(HAVE_PKCS11_STATIC) && !defined(HAVE_PKCS11_V3_STATIC)
532729
dlclose(dev->dlHandle);
533730
dev->dlHandle = NULL;
534731
#endif
@@ -633,6 +830,7 @@ static int Pkcs11Token_Init(Pkcs11Token* token, Pkcs11Dev* dev, int slotId,
633830
token->userPin = NULL_PTR;
634831
token->userPinSz = 0;
635832
token->userPinLogin = 0;
833+
token->version = dev->version;
636834
}
637835

638836
XFREE(slot, dev->heap, DYNAMIC_TYPE_TMP_BUFFER);
@@ -809,6 +1007,7 @@ static int Pkcs11OpenSession(Pkcs11Token* token, Pkcs11Session* session,
8091007
if (ret == 0) {
8101008
session->func = token->func;
8111009
session->slotId = token->slotId;
1010+
session->version = token->version;
8121011
}
8131012

8141013
return ret;

0 commit comments

Comments
 (0)