diff --git a/.github/workflows/alpine-architecture-tests.yml b/.github/workflows/alpine-architecture-tests.yml index 459d51b..3dd3739 100644 --- a/.github/workflows/alpine-architecture-tests.yml +++ b/.github/workflows/alpine-architecture-tests.yml @@ -7,7 +7,7 @@ on: branches: [ '*' ] env: - WOLFSSL_VERSION: v5.8.0-stable + WOLFSSL_VERSION: v5.8.4-stable jobs: alpine-architecture-tests: diff --git a/.github/workflows/nss-cmsutil-test.yml b/.github/workflows/nss-cmsutil-test.yml index e41fd0f..955949c 100644 --- a/.github/workflows/nss-cmsutil-test.yml +++ b/.github/workflows/nss-cmsutil-test.yml @@ -10,7 +10,7 @@ on: env: NSPR_VERSION: NSPR_4_36_BRANCH NSS_VERSION: NSS_3_112_RTM - WOLFSSL_VERSION: v5.8.0-stable + WOLFSSL_VERSION: v5.8.4-stable NSS_DEBUG_PKCS11_MODULE: wolfPKCS11 NSPR_LOG_MODULES: all:5 NSPR_LOG_FILE: /logs/nss.log @@ -238,10 +238,10 @@ jobs: # Step 2: Generate user certificate and key pair directly in NSS echo " Generating user certificate and key pair in NSS database..." - + # Create random seed for key generation dd if=/dev/urandom of=noise.bin bs=20 count=1 2>/dev/null - + # Generate certificate request with key pair (creates DER format) printf '\n\n' | certutil -R -s "CN=Test User,O=NSS Test,C=US" \ -o user-req.der -d /nss-test/nssdb -z noise.bin diff --git a/.github/workflows/nss-curl-test.yml b/.github/workflows/nss-curl-test.yml index 9637e37..9987e3f 100644 --- a/.github/workflows/nss-curl-test.yml +++ b/.github/workflows/nss-curl-test.yml @@ -9,7 +9,7 @@ on: env: NSPR_VERSION: NSPR_4_36_BRANCH NSS_VERSION: NSS_3_112_RTM - WOLFSSL_VERSION: v5.8.0-stable + WOLFSSL_VERSION: v5.8.4-stable CURL_VERSION: 8.0.0 NSS_DEBUG_PKCS11_MODULE: "wolfPKCS11" NSPR_LOG_MODULES: all:5 @@ -51,7 +51,7 @@ jobs: ca-certificates \ libnss3-tools sudo rm -rf /var/lib/apt/lists/* - + - name: Cache NSPR id: cache-nspr uses: actions/cache@v4 @@ -87,7 +87,7 @@ jobs: run: | mkdir -p /tmp/src cd /tmp/src - + # Clone official Mozilla NSS with specific tag hg clone https://hg.mozilla.org/projects/nss -r ${{ env.NSS_VERSION }} @@ -211,7 +211,7 @@ jobs: run: | sudo mkdir -p /etc/pki/nssdb cd /etc/pki - + # Initialize NSS database sudo certutil -N -d sql:/etc/pki/nssdb --empty-password diff --git a/.github/workflows/nss-pdfsig-test.yml b/.github/workflows/nss-pdfsig-test.yml index fdac970..a774cc2 100644 --- a/.github/workflows/nss-pdfsig-test.yml +++ b/.github/workflows/nss-pdfsig-test.yml @@ -9,7 +9,7 @@ on: env: NSPR_VERSION: NSPR_4_36_BRANCH NSS_VERSION: NSS_3_112_RTM - WOLFSSL_VERSION: v5.8.0-stable + WOLFSSL_VERSION: v5.8.4-stable jobs: test-nss-pdf-signing: diff --git a/.github/workflows/nss-pk12util-debian-test.yml b/.github/workflows/nss-pk12util-debian-test.yml index 929db12..5d19db2 100644 --- a/.github/workflows/nss-pk12util-debian-test.yml +++ b/.github/workflows/nss-pk12util-debian-test.yml @@ -8,7 +8,7 @@ on: workflow_dispatch: env: - WOLFSSL_VERSION: v5.8.0-stable + WOLFSSL_VERSION: v5.8.2-stable # make deb seems to be broken with v5.8.4-stable NSS_DEBUG_PKCS11_MODULE: wolfPKCS11 NSPR_LOG_MODULES: all:5 NSPR_LOG_FILE: /logs/nss.log diff --git a/.github/workflows/nss-pk12util-test.yml b/.github/workflows/nss-pk12util-test.yml index 890c33e..f871c80 100644 --- a/.github/workflows/nss-pk12util-test.yml +++ b/.github/workflows/nss-pk12util-test.yml @@ -10,7 +10,7 @@ on: env: NSPR_VERSION: NSPR_4_36_BRANCH NSS_VERSION: NSS_3_112_RTM - WOLFSSL_VERSION: v5.8.0-stable + WOLFSSL_VERSION: v5.8.4-stable NSS_DEBUG_PKCS11_MODULE: wolfPKCS11 NSPR_LOG_MODULES: all:5 NSPR_LOG_FILE: /logs/nss.log diff --git a/.github/workflows/nss-ssltap-test.yml b/.github/workflows/nss-ssltap-test.yml index 2c97bd0..6e1ad1b 100644 --- a/.github/workflows/nss-ssltap-test.yml +++ b/.github/workflows/nss-ssltap-test.yml @@ -10,7 +10,7 @@ on: env: NSPR_VERSION: NSPR_4_36_BRANCH NSS_VERSION: NSS_3_112_RTM - WOLFSSL_VERSION: v5.8.0-stable + WOLFSSL_VERSION: v5.8.4-stable NSS_DEBUG_PKCS11_MODULE: wolfPKCS11 NSPR_LOG_MODULES: all:5 NSPR_LOG_FILE: /logs/nss.log diff --git a/.github/workflows/nss.yml b/.github/workflows/nss.yml index 3c2726f..62559b4 100644 --- a/.github/workflows/nss.yml +++ b/.github/workflows/nss.yml @@ -10,7 +10,7 @@ on: env: NSPR_VERSION: NSPR_4_36_BRANCH NSS_VERSION: NSS_3_112_RTM - WOLFSSL_VERSION: v5.8.0-stable + WOLFSSL_VERSION: v5.8.4-stable #NSS_DEBUG_PKCS11_MODULE: wolfPKCS11 #NSPR_LOG_MODULES: all:5 #NSPR_LOG_FILE: /logs/nss.log diff --git a/.github/workflows/storage-upgrade-test-tpm.yml b/.github/workflows/storage-upgrade-test-tpm.yml index d7011d0..6192af9 100644 --- a/.github/workflows/storage-upgrade-test-tpm.yml +++ b/.github/workflows/storage-upgrade-test-tpm.yml @@ -5,7 +5,7 @@ on: branches: [ '*' ] env: - WOLFSSL_VERSION: v5.8.0-stable + WOLFSSL_VERSION: v5.8.4-stable jobs: storage-upgrade-test-tpm: diff --git a/.github/workflows/storage-upgrade-test.yml b/.github/workflows/storage-upgrade-test.yml index b525790..615a5d4 100644 --- a/.github/workflows/storage-upgrade-test.yml +++ b/.github/workflows/storage-upgrade-test.yml @@ -5,7 +5,7 @@ on: branches: [ '*' ] env: - WOLFSSL_VERSION: v5.8.0-stable + WOLFSSL_VERSION: v5.8.4-stable jobs: storage-upgrade-test: @@ -20,7 +20,7 @@ jobs: # - name: v1.3.0 # ref: v1.3.0-stable # branch-dir: v1.3.0-stable-branch - + steps: # Checkout the PR branch - name: Checkout PR branch @@ -52,7 +52,7 @@ jobs: repository: wolfssl/wolfssl path: wolfssl ref: ${{ env.WOLFSSL_VERSION }} - + - name: Build wolfssl if: steps.cache-wolfssl.outputs.cache-hit != 'true' working-directory: ./wolfssl @@ -109,15 +109,15 @@ jobs: - name: Copy storage files from ${{ matrix.base-ref.name }} to PR run: | echo "=== Copying storage files from ${{ matrix.base-ref.name }} to PR branch ===" - + # Create directories if they don't exist mkdir -p pr-branch/store - + # Copy store files if [ -d "${{ matrix.base-ref.branch-dir }}/store" ]; then cp -rv ${{ matrix.base-ref.branch-dir }}/store/* pr-branch/store/ 2>/dev/null || echo "No files in ${{ matrix.base-ref.branch-dir }}/store/" fi - + echo "=== Storage file copy completed ===" - name: Test storage format compatibility (${{ matrix.base-ref.name }} → PR) @@ -125,14 +125,14 @@ jobs: run: | echo "=== Testing storage format compatibility with PR branch ===" echo "This tests that the PR can read storage files created by ${{ matrix.base-ref.name }} branch" - + # List the copied files for verification echo "Files in store directory:" ls -la store/* 2>/dev/null || echo "No wp* files in store/" - + # Run the tests with the copied storage files ./tests/pkcs11test - + echo "=== Storage format upgrade test (${{ matrix.base-ref.name }} → PR) completed successfully ===" # Upload artifacts for debugging if needed diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index f11f56a..4e8f0c3 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -90,7 +90,18 @@ jobs: uses: ./.github/workflows/build-workflow.yml with: config: --enable-pbkdf2 --with-pbkdf2-iterations=1000 - + pkcs11v3only: + uses: ./.github/workflows/build-workflow.yml + with: + config: --enable-pkcs11v30 --disable-pkcs11v32 + pkcs11v32: + uses: ./.github/workflows/build-workflow.yml + with: + config: --enable-pkcs11v32 + pkcs11v32-static: + uses: ./.github/workflows/build-workflow.yml + with: + config: --enable-pkcs11v32 --disable-shared debug: uses: ./.github/workflows/build-workflow.yml with: diff --git a/.gitignore b/.gitignore index 0eca1c4..a3d7a8d 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ tests/object_id_uniqueness_test tests/rsa_session_persistence_test tests/debug_test tests/token_path_test +tests/pkcs11v3test examples/add_aes_key examples/add_hmac_key examples/add_rsa_key @@ -61,6 +62,7 @@ test/* .project .settings add_cert_file +.cache tests/wp11_rsakey_* tests/wp11_dhkey_* diff --git a/Docker/firefox/Dockerfile b/Docker/firefox/Dockerfile index cb3d049..e6fdc91 100644 --- a/Docker/firefox/Dockerfile +++ b/Docker/firefox/Dockerfile @@ -1,6 +1,6 @@ FROM ubuntu:24.04 -ARG WOLFSSL_TAG=v5.8.0-stable +ARG WOLFSSL_TAG=v5.8.4-stable ARG FIREFOX_TAG=78c455227887c316bdde0be2738e31fcecb4547d # geckodriver should be updated when updating the Firefox version ARG GECKODRIVER_TAG=v0.36.0 diff --git a/configure.ac b/configure.ac index a574875..e9bca01 100644 --- a/configure.ac +++ b/configure.ac @@ -481,6 +481,30 @@ then AM_CFLAGS="$AM_CFLAGS -DWOLFPKCS11_DEFAULT_TOKEN_PATH=\"$WOLFPKCS11_DEFAULT_TOKEN_PATH\"" fi +AC_ARG_ENABLE([pkcs11v30], + [AS_HELP_STRING([--enable-pkcs11v30],[Enable PKCS#11 Version 3.0 support (default: enabled)])], + [ ENABLED_PKCS11V3_0=$enableval ], + [ ENABLED_PKCS11V3_0=yes ] + ) +if test "$ENABLED_PKCS11V3_0" = "yes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFPKCS11_PKCS11_V3_0" +fi + +AC_ARG_ENABLE([pkcs11v32], + [AS_HELP_STRING([--enable-pkcs11v32],[Enable PKCS#11 Version 3.2 support (default: disabled)])], + [ ENABLED_PKCS11V3_2=$enableval ], + [ ENABLED_PKCS11V3_2=no ] + ) +if test "$ENABLED_PKCS11V3_2" = "yes" +then + if test "$ENABLED_PKCS11V3_0" = "no" + then + ENABLED_PKCS11V3_0=yes + fi + AM_CFLAGS="$AM_CFLAGS -DWOLFPKCS11_PKCS11_V3_2" +fi + AM_CONDITIONAL([BUILD_STATIC],[test "x$enable_shared" = "xno"]) @@ -657,3 +681,5 @@ echo " * ECC: $ENABLED_ECC" echo " * HKDF: $ENABLED_HKDF" echo " * NSS modifications: $ENABLED_NSS" echo " * Default token path: $WOLFPKCS11_DEFAULT_TOKEN_PATH" +echo " * PKCS#11 Version 3.0: $ENABLED_PKCS11V3_0" +echo " * PKCS#11 Version 3.2: $ENABLED_PKCS11V3_2" diff --git a/src/crypto.c b/src/crypto.c index 80cabea..6dc25d3 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -7958,3 +7958,447 @@ CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession, WOLFPKCS11_LEAVE("C_GenerateRandom", rv); return rv; } + +#if defined (WOLFPKCS11_PKCS11_V3_0) + +CK_RV C_MessageEncryptInit(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pMechanism; + (void)hKey; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_EncryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pPlaintext, + CK_ULONG ulPlaintextLen, CK_BYTE_PTR pCiphertext, + CK_ULONG_PTR pulCiphertextLen) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pParameter; + (void)ulParameterLen; + (void)pAssociatedData; + (void)ulAssociatedDataLen; + (void)pPlaintext; + (void)ulPlaintextLen; + (void)pCiphertext; + (void)pulCiphertextLen; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_EncryptMessageBegin(CK_SESSION_HANDLE hSession, + CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, + CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pParameter; + (void)ulParameterLen; + (void)pAssociatedData; + (void)ulAssociatedDataLen; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_EncryptMessageNext(CK_SESSION_HANDLE hSession, + CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, + CK_BYTE_PTR pPlaintextPart, + CK_ULONG ulPlaintextPartLen, + CK_BYTE_PTR pCiphertextPart, + CK_ULONG_PTR pulCiphertextPartLen, + CK_FLAGS flags) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pParameter; + (void)ulParameterLen; + (void)pPlaintextPart; + (void)ulPlaintextPartLen; + (void)pCiphertextPart; + (void)pulCiphertextPartLen; + (void)flags; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_MessageEncryptFinal(CK_SESSION_HANDLE hSession) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_MessageDecryptInit(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pMechanism; + (void)hKey; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_DecryptMessage(CK_SESSION_HANDLE hSession, + CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, + CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen, + CK_BYTE_PTR pCiphertext, + CK_ULONG ulCiphertextLen, + CK_BYTE_PTR pPlaintext, + CK_ULONG_PTR pulPlaintextLen) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pParameter; + (void)ulParameterLen; + (void)pAssociatedData; + (void)ulAssociatedDataLen; + (void)pCiphertext; + (void)ulCiphertextLen; + (void)pPlaintext; + (void)pulPlaintextLen; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_DecryptMessageBegin(CK_SESSION_HANDLE hSession, + CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, + CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pParameter; + (void)ulParameterLen; + (void)pAssociatedData; + (void)ulAssociatedDataLen; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_DecryptMessageNext(CK_SESSION_HANDLE hSession, + CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, + CK_BYTE_PTR pCiphertextPart, + CK_ULONG ulCiphertextPartLen, + CK_BYTE_PTR pPlaintextPart, + CK_ULONG_PTR pulPlaintextPartLen, + CK_FLAGS flags) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pParameter; + (void)ulParameterLen; + (void)pCiphertextPart; + (void)ulCiphertextPartLen; + (void)pPlaintextPart; + (void)pulPlaintextPartLen; + (void)flags; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_MessageDecryptFinal(CK_SESSION_HANDLE hSession) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_MessageSignInit(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pMechanism; + (void)hKey; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_SignMessage(CK_SESSION_HANDLE hSession, + CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pParameter; + (void)ulParameterLen; + (void)pData; + (void)ulDataLen; + (void)pSignature; + (void)pulSignatureLen; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_SignMessageBegin(CK_SESSION_HANDLE hSession, + CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pParameter; + (void)ulParameterLen; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_SignMessageNext(CK_SESSION_HANDLE hSession, + CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pParameter; + (void)ulParameterLen; + (void)pData; + (void)ulDataLen; + (void)pSignature; + (void)pulSignatureLen; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_MessageSignFinal(CK_SESSION_HANDLE hSession) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_MessageVerifyInit(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pMechanism; + (void)hKey; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_VerifyMessage(CK_SESSION_HANDLE hSession, + CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pParameter; + (void)ulParameterLen; + (void)pData; + (void)ulDataLen; + (void)pSignature; + (void)ulSignatureLen; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_VerifyMessageBegin(CK_SESSION_HANDLE hSession, + CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pParameter; + (void)ulParameterLen; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_VerifyMessageNext(CK_SESSION_HANDLE hSession, + CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pParameter; + (void)ulParameterLen; + (void)pData; + (void)ulDataLen; + (void)pSignature; + (void)ulSignatureLen; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_MessageVerifyFinal(CK_SESSION_HANDLE hSession) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +#endif /* defined WOLFPKCS11_PKCS11_V3_0 */ + +#if defined (WOLFPKCS11_PKCS11_V3_2) + +CK_RV C_EncapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hPublicKey, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey, + CK_BYTE_PTR pCiphertext, CK_ULONG_PTR pulCiphertextLen) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pMechanism; + (void)hPublicKey; + (void)pTemplate; + (void)ulAttributeCount; + (void)phKey; + (void)pCiphertext; + (void)pulCiphertextLen; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_DecapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hPrivateKey, CK_BYTE_PTR pCiphertext, + CK_ULONG ulCiphertextLen, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pMechanism; + (void)hPrivateKey; + (void)pCiphertext; + (void)ulCiphertextLen; + (void)pTemplate; + (void)ulAttributeCount; + (void)phKey; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_VerifySignatureInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pMechanism; + (void)hKey; + (void)pSignature; + (void)ulSignatureLen; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_VerifySignature(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pData; + (void)ulDataLen; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_VerifySignatureUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pPart; + (void)ulPartLen; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_VerifySignatureFinal(CK_SESSION_HANDLE hSession) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +#endif /* defined WOLFPKCS11_PKCS11_V3_2 */ diff --git a/src/internal.c b/src/internal.c index dac23e3..010fae9 100644 --- a/src/internal.c +++ b/src/internal.c @@ -8720,6 +8720,19 @@ static int RsaObject_GetAttr(WP11_Object* object, CK_ATTRIBUTE_TYPE type, static int GetEcParams(ecc_key* key, byte* data, CK_ULONG* len) { int ret = 0; +#if defined(HAVE_OID_ENCODING) + word32 dataLen = (word32)*len; + byte* out = (data != NULL) ? (data + 2) : NULL; + ret = wc_EncodeObjectId(key->dp->oid, key->dp->oidSz, out, &dataLen); + if (ret != 0) { + return ret; + } + if (data != NULL) { + data[0] = ASN_OBJECT_ID; + data[1] = dataLen; + } + *len = dataLen + 2; +#else const byte* oid = NULL; word32 oidSz = 0; @@ -8737,6 +8750,7 @@ static int GetEcParams(ecc_key* key, byte* data, CK_ULONG* len) XMEMCPY(data + 2, oid, oidSz); } } +#endif return ret; } diff --git a/src/slot.c b/src/slot.c index 21af4d3..e013d6c 100644 --- a/src/slot.c +++ b/src/slot.c @@ -2015,3 +2015,93 @@ CK_RV C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, WOLFPKCS11_LEAVE("C_WaitForSlotEvent", rv); return rv; } + +#if defined (WOLFPKCS11_PKCS11_V3_0) + +CK_RV C_LoginUser(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, + CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, + CK_UTF8CHAR_PTR pUsername, CK_ULONG ulUsernameLen) +{ + CK_RV rv; + + WOLFPKCS11_ENTER("C_LoginUser"); + + /* Ignore username for the moment and just login with the PIN. */ + (void)pUsername; + (void)ulUsernameLen; + rv = C_Login(hSession, userType, pPin, ulPinLen); + + WOLFPKCS11_LEAVE("C_LoginUser", rv); + return rv; +} + +CK_RV C_SessionCancel(CK_SESSION_HANDLE hSession, CK_FLAGS flags) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)flags; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +#endif /* defined WOLFPKCS11_PKCS11_V3_0 */ + +#if defined (WOLFPKCS11_PKCS11_V3_2) + +CK_RV C_GetSessionValidationFlags(CK_SESSION_HANDLE hSession, CK_ULONG type, + CK_FLAGS * pFlags) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)type; + (void)pFlags; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_AsyncComplete(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, + CK_ASYNC_DATA_PTR pResult) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pFunctionName; + (void)pResult; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_AsyncGetID(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, + CK_ULONG_PTR pulID) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pFunctionName; + (void)pulID; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV C_AsyncJoin(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, + CK_ULONG ulID, CK_BYTE_PTR pData, CK_ULONG ulData) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + + (void)hSession; + (void)pFunctionName; + (void)ulID; + (void)pData; + (void)ulData; + + return CKR_FUNCTION_NOT_SUPPORTED; +} + +#endif /* defined WOLFPKCS11_PKCS11_V3_2 */ diff --git a/src/wolfpkcs11.c b/src/wolfpkcs11.c index d0134c9..fc6cd08 100644 --- a/src/wolfpkcs11.c +++ b/src/wolfpkcs11.c @@ -28,7 +28,7 @@ /* Function list table. */ static CK_FUNCTION_LIST wolfpkcs11FunctionList = { - { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, + { 2, 40 }, C_Initialize, C_Finalize, @@ -100,6 +100,222 @@ static CK_FUNCTION_LIST wolfpkcs11FunctionList = { C_WaitForSlotEvent }; +#if defined (WOLFPKCS11_PKCS11_V3_0) + +CK_RV C_GetInfoV3_0(CK_INFO_PTR pInfo); + +static CK_FUNCTION_LIST_3_0 wolfpkcs11FunctionList_3_0 = { + { 3, 0 }, + + C_Initialize, + C_Finalize, + C_GetInfoV3_0, + C_GetFunctionList, + C_GetSlotList, + C_GetSlotInfo, + C_GetTokenInfo, + C_GetMechanismList, + C_GetMechanismInfo, + C_InitToken, + C_InitPIN, + C_SetPIN, + C_OpenSession, + C_CloseSession, + C_CloseAllSessions, + C_GetSessionInfo, + C_GetOperationState, + C_SetOperationState, + C_Login, + C_Logout, + C_CreateObject, + C_CopyObject, + C_DestroyObject, + C_GetObjectSize, + C_GetAttributeValue, + C_SetAttributeValue, + C_FindObjectsInit, + C_FindObjects, + C_FindObjectsFinal, + C_EncryptInit, + C_Encrypt, + C_EncryptUpdate, + C_EncryptFinal, + C_DecryptInit, + C_Decrypt, + C_DecryptUpdate, + C_DecryptFinal, + C_DigestInit, + C_Digest, + C_DigestUpdate, + C_DigestKey, + C_DigestFinal, + C_SignInit, + C_Sign, + C_SignUpdate, + C_SignFinal, + C_SignRecoverInit, + C_SignRecover, + C_VerifyInit, + C_Verify, + C_VerifyUpdate, + C_VerifyFinal, + C_VerifyRecoverInit, + C_VerifyRecover, + C_DigestEncryptUpdate, + C_DecryptDigestUpdate, + C_SignEncryptUpdate, + C_DecryptVerifyUpdate, + C_GenerateKey, + C_GenerateKeyPair, + C_WrapKey, + C_UnwrapKey, + C_DeriveKey, + C_SeedRandom, + C_GenerateRandom, + C_GetFunctionStatus, + C_CancelFunction, + C_WaitForSlotEvent, + C_GetInterfaceList, + C_GetInterface, + C_LoginUser, + C_SessionCancel, + C_MessageEncryptInit, + C_EncryptMessage, + C_EncryptMessageBegin, + C_EncryptMessageNext, + C_MessageEncryptFinal, + C_MessageDecryptInit, + C_DecryptMessage, + C_DecryptMessageBegin, + C_DecryptMessageNext, + C_MessageDecryptFinal, + C_MessageSignInit, + C_SignMessage, + C_SignMessageBegin, + C_SignMessageNext, + C_MessageSignFinal, + C_MessageVerifyInit, + C_VerifyMessage, + C_VerifyMessageBegin, + C_VerifyMessageNext, + C_MessageVerifyFinal +}; + +#endif /* defined WOLFPKCS11_PKCS11_V3_0 */ + +#if defined (WOLFPKCS11_PKCS11_V3_2) + +CK_RV C_GetInfoV3_2(CK_INFO_PTR pInfo); + +static CK_FUNCTION_LIST_3_2 wolfpkcs11FunctionList_3_2 = { + { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, + + C_Initialize, + C_Finalize, + C_GetInfoV3_2, + C_GetFunctionList, + C_GetSlotList, + C_GetSlotInfo, + C_GetTokenInfo, + C_GetMechanismList, + C_GetMechanismInfo, + C_InitToken, + C_InitPIN, + C_SetPIN, + C_OpenSession, + C_CloseSession, + C_CloseAllSessions, + C_GetSessionInfo, + C_GetOperationState, + C_SetOperationState, + C_Login, + C_Logout, + C_CreateObject, + C_CopyObject, + C_DestroyObject, + C_GetObjectSize, + C_GetAttributeValue, + C_SetAttributeValue, + C_FindObjectsInit, + C_FindObjects, + C_FindObjectsFinal, + C_EncryptInit, + C_Encrypt, + C_EncryptUpdate, + C_EncryptFinal, + C_DecryptInit, + C_Decrypt, + C_DecryptUpdate, + C_DecryptFinal, + C_DigestInit, + C_Digest, + C_DigestUpdate, + C_DigestKey, + C_DigestFinal, + C_SignInit, + C_Sign, + C_SignUpdate, + C_SignFinal, + C_SignRecoverInit, + C_SignRecover, + C_VerifyInit, + C_Verify, + C_VerifyUpdate, + C_VerifyFinal, + C_VerifyRecoverInit, + C_VerifyRecover, + C_DigestEncryptUpdate, + C_DecryptDigestUpdate, + C_SignEncryptUpdate, + C_DecryptVerifyUpdate, + C_GenerateKey, + C_GenerateKeyPair, + C_WrapKey, + C_UnwrapKey, + C_DeriveKey, + C_SeedRandom, + C_GenerateRandom, + C_GetFunctionStatus, + C_CancelFunction, + C_WaitForSlotEvent, + C_GetInterfaceList, + C_GetInterface, + C_LoginUser, + C_SessionCancel, + C_MessageEncryptInit, + C_EncryptMessage, + C_EncryptMessageBegin, + C_EncryptMessageNext, + C_MessageEncryptFinal, + C_MessageDecryptInit, + C_DecryptMessage, + C_DecryptMessageBegin, + C_DecryptMessageNext, + C_MessageDecryptFinal, + C_MessageSignInit, + C_SignMessage, + C_SignMessageBegin, + C_SignMessageNext, + C_MessageSignFinal, + C_MessageVerifyInit, + C_VerifyMessage, + C_VerifyMessageBegin, + C_VerifyMessageNext, + C_MessageVerifyFinal, + C_EncapsulateKey, + C_DecapsulateKey, + C_VerifySignatureInit, + C_VerifySignature, + C_VerifySignatureUpdate, + C_VerifySignatureFinal, + C_GetSessionValidationFlags, + C_AsyncComplete, + C_AsyncGetID, + C_AsyncJoin +}; + +#endif /* defined WOLFPKCS11_PKCS11_V3_2 */ + /** * Return the function list for accessing Crypto-Ki API. * @@ -175,8 +391,7 @@ static CK_RV ParseNssConfigString(char *nssArgs, nssArgs++; valueLen = nssArgs - valueStart; } - - + if (valueLen == 0) continue; if (*nssArgs != ' ' && *nssArgs != '\0') @@ -193,7 +408,87 @@ static CK_RV ParseNssConfigString(char *nssArgs, return CKR_OK; } +#endif /* defined WOLFPKCS11_NSS && !defined WOLFPKCS11_NO_STORE */ + +#if defined (WOLFPKCS11_PKCS11_V3_0) + +#if defined (WOLFPKCS11_PKCS11_V3_2) + #define NUM_INTERFACES 3 +#else + #define NUM_INTERFACES 2 +#endif + +#define DEFAULT_INTERFACE 0 + +CK_INTERFACE interfaces[NUM_INTERFACES] = { +#if defined (WOLFPKCS11_PKCS11_V3_2) + {(CK_UTF8CHAR_PTR)"PKCS 11", (void *)&wolfpkcs11FunctionList_3_2, 0}, #endif + {(CK_UTF8CHAR_PTR)"PKCS 11", (void *)&wolfpkcs11FunctionList_3_0, 0}, + {(CK_UTF8CHAR_PTR)"PKCS 11", (void *)&wolfpkcs11FunctionList, 0} +}; + +CK_RV C_GetInterfaceList(CK_INTERFACE_PTR pInterfacesList, CK_ULONG_PTR pulCount) +{ + if (pulCount == NULL) + return CKR_ARGUMENTS_BAD; + + if (pInterfacesList == NULL_PTR) { + *pulCount = NUM_INTERFACES; + return CKR_OK; + } + + if (*pulCount < NUM_INTERFACES) { + *pulCount = NUM_INTERFACES; + return CKR_BUFFER_TOO_SMALL; + } + + memcpy(pInterfacesList, interfaces, NUM_INTERFACES * sizeof(CK_INTERFACE)); + *pulCount = NUM_INTERFACES; + + return CKR_OK; +} + +CK_RV C_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, CK_VERSION_PTR pVersion, + CK_INTERFACE_PTR_PTR ppInterface, CK_FLAGS flags) +{ + int i; + + if (ppInterface == NULL) { + return CKR_ARGUMENTS_BAD; + } + + if (pInterfaceName == NULL_PTR) { + /* return default interface */ + *ppInterface = &interfaces[DEFAULT_INTERFACE]; + return CKR_OK; + } + + for (i = 0; i < NUM_INTERFACES; i++) { + CK_VERSION_PTR interface_version = (CK_VERSION_PTR)interfaces[i].pFunctionList; + + if (strcmp((char*)pInterfaceName, (char*)interfaces[i].pInterfaceName) != 0) + continue; + + /* If version is not null, it must match */ + if (pVersion != NULL_PTR && (pVersion->major != interface_version->major || + pVersion->minor != interface_version->minor)) { + continue; + } + + /* If any flags specified, it must be supported by the interface */ + if ((flags & interfaces[i].flags) != flags) + continue; + + *ppInterface = &interfaces[i]; + + return CKR_OK; + } + + return CKR_ARGUMENTS_BAD; +} + +#endif /* defined WOLFPKCS11_PKCS11_V3_0 */ /** * Initialize the Crypto-Ki library. @@ -266,12 +561,33 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved) /* Information about the Crypto-Ki library. */ static CK_INFO wolfpkcs11Info = { + { 2, 40 }, + "wolfpkcs11", + 0, + "Implementation using wolfCrypt", + { WOLFPKCS11_MAJOR_VERSION, WOLFPKCS11_MINOR_VERSION } +}; + +#if defined (WOLFPKCS11_PKCS11_V3_0) +static CK_INFO wolfpkcs11Info_3_0 = { + { 3, 0 }, + "wolfpkcs11", + 0, + "Implementation using wolfCrypt", + { WOLFPKCS11_MAJOR_VERSION, WOLFPKCS11_MINOR_VERSION } +}; +#endif /* defined WOLFPKCS11_PKCS11_V3_0 */ + +#if defined (WOLFPKCS11_PKCS11_V3_2) +static CK_INFO wolfpkcs11Info_3_2 = { { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, "wolfpkcs11", 0, "Implementation using wolfCrypt", { WOLFPKCS11_MAJOR_VERSION, WOLFPKCS11_MINOR_VERSION } }; +#endif /* defined WOLFPKCS11_PKCS11_V3_2 */ + /** * Get information on the library. @@ -302,3 +618,31 @@ CK_RV C_GetInfo(CK_INFO_PTR pInfo) WOLFPKCS11_LEAVE("C_GetInfo", ret); return ret; } + +#if defined (WOLFPKCS11_PKCS11_V3_0) +CK_RV C_GetInfoV3_0(CK_INFO_PTR pInfo) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + if (pInfo == NULL) + return CKR_ARGUMENTS_BAD; + + XMEMCPY(pInfo, &wolfpkcs11Info_3_0, sizeof(wolfpkcs11Info_3_0)); + + return CKR_OK; +} +#endif /* defined WOLFPKCS11_PKCS11_V3_0 */ + +#if defined (WOLFPKCS11_PKCS11_V3_2) +CK_RV C_GetInfoV3_2(CK_INFO_PTR pInfo) +{ + if (!WP11_Library_IsInitialized()) + return CKR_CRYPTOKI_NOT_INITIALIZED; + if (pInfo == NULL) + return CKR_ARGUMENTS_BAD; + + XMEMCPY(pInfo, &wolfpkcs11Info_3_2, sizeof(wolfpkcs11Info_3_2)); + + return CKR_OK; +} +#endif /* defined WOLFPKCS11_PKCS11_V3_2 */ diff --git a/tests/include.am b/tests/include.am index ad3ad4b..7590a71 100644 --- a/tests/include.am +++ b/tests/include.am @@ -36,6 +36,11 @@ noinst_PROGRAMS += tests/object_id_uniqueness_test tests_object_id_uniqueness_test_SOURCES = tests/object_id_uniqueness_test.c tests_object_id_uniqueness_test_LDADD = +check_PROGRAMS += tests/pkcs11v3test +noinst_PROGRAMS += tests/pkcs11v3test +tests_pkcs11v3test_SOURCES = tests/pkcs11v3test.c +tests_pkcs11v3test_LDADD = + if BUILD_STATIC tests_pkcs11test_LDADD += src/libwolfpkcs11.la tests_pkcs11mtt_LDADD += src/libwolfpkcs11.la @@ -44,6 +49,7 @@ tests_token_path_test_LDADD += src/libwolfpkcs11.la tests_rsa_session_persistence_test_LDADD += src/libwolfpkcs11.la tests_debug_test_LDADD += src/libwolfpkcs11.la tests_object_id_uniqueness_test_LDADD += src/libwolfpkcs11.la +tests_pkcs11v3test_LDADD += src/libwolfpkcs11.la else tests_object_id_uniqueness_test_LDADD += src/libwolfpkcs11.la endif diff --git a/tests/pkcs11v3test.c b/tests/pkcs11v3test.c new file mode 100644 index 0000000..febb9ef --- /dev/null +++ b/tests/pkcs11v3test.c @@ -0,0 +1,930 @@ +/* pkcs11v3test.c - unit tests + * + * Copyright (C) 2006-2026 wolfSSL Inc. + * + * This file is part of wolfPKCS11. + * + * wolfPKCS11 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfPKCS11 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif +#include +#include + +#ifndef WOLFPKCS11_USER_SETTINGS + #include +#endif +#include + +#ifndef HAVE_PKCS11_STATIC +#include +#endif + +#include "unit.h" +#include "testdata.h" +#include + + +#define TEST_FLAG_INIT 0x01 +#define TEST_FLAG_TOKEN 0x02 +#define TEST_FLAG_SESSION 0x04 + +#define PKCS11TEST_CASE(func, flags) \ + TEST_CASE(func, flags, pkcs11_open_session, pkcs11_close_session, \ + sizeof(CK_SESSION_HANDLE)) +#define PKCS11TEST_FUNC_NO_INIT_DECL(func) \ + PKCS11TEST_CASE(func, 0) +#define PKCS11TEST_FUNC_NO_TOKEN_DECL(func) \ + PKCS11TEST_CASE(func, TEST_FLAG_INIT) +#define PKCS11TEST_FUNC_TOKEN_DECL(func) \ + PKCS11TEST_CASE(func, TEST_FLAG_INIT | TEST_FLAG_TOKEN) +#define PKCS11TEST_FUNC_SESS_DECL(func) \ + PKCS11TEST_CASE(func, TEST_FLAG_INIT | TEST_FLAG_TOKEN | TEST_FLAG_SESSION) + + +#ifdef WOLFPKCS11_PKCS11_V3_0 + +#ifndef HAVE_PKCS11_STATIC +static void* dlib; +#endif +static CK_FUNCTION_LIST* funcList; + +#ifdef DEBUG_WOLFPKCS11 +#ifndef HAVE_PKCS11_STATIC +void (*wolfPKCS11_Debugging_On_fp)(void) = NULL; +void (*wolfPKCS11_Debugging_Off_fp)(void) = NULL; +#endif +#endif +static int slot = 0; +static const char* tokenName = "wolfpkcs11"; + +/* FIPS requires pin to be at least 14 characters, since it is used for + * the HMAC key */ +static byte* soPin = (byte*)"password123456"; +static int soPinLen = 14; +static byte* userPin = (byte*)"wolfpkcs11-test"; +static int userPinLen; + +static CK_RV test_get_interface_list(void* args) +{ + CK_RV ret = CKR_OK; + CK_ULONG count = 0; + CK_INTERFACE* interfaces = NULL; +#ifndef HAVE_PKCS11_STATIC + void* func; +#endif + +#ifdef WOLFPKCS11_PKCS11_V3_2 + static const CK_ULONG interfaceCount = 3; +#else + static const CK_ULONG interfaceCount = 2; +#endif + + (void)args; + +#ifndef HAVE_PKCS11_STATIC + func = (void*)(CK_C_GetInterfaceList)dlsym(dlib, "C_GetInterfaceList"); + if (func == NULL) { + fprintf(stderr, "Failed to get interface list function\n"); + ret = -1; + } + + if (ret == CKR_OK) { + ret = ((CK_C_GetInterfaceList)func)(NULL, NULL); + CHECK_CKR_FAIL(ret, CKR_ARGUMENTS_BAD, "Get Interface List"); + } + if (ret == CKR_OK) { + ret = ((CK_C_GetInterfaceList)func)(NULL, &count); + CHECK_CKR(ret, "Get Interface List"); + if (count != interfaceCount) { + fprintf(stderr, "Expected %ld interfaces, got %ld\n", + interfaceCount, count); + ret = -1; + } + } +#else + if (ret == CKR_OK) { + ret = C_GetInterfaceList(NULL, NULL); + CHECK_CKR_FAIL(ret, CKR_ARGUMENTS_BAD, "Get Interface List"); + } + if (ret == CKR_OK) { + ret = C_GetInterfaceList(NULL, &count); + CHECK_CKR(ret, "Get Interface List"); + if (count != interfaceCount) { + fprintf(stderr, "Expected %ld interfaces, got %ld\n", + interfaceCount, count); + ret = -1; + } + } +#endif + + if (ret == CKR_OK) { + interfaces = (CK_INTERFACE*)malloc(interfaceCount * + sizeof(CK_INTERFACE)); + if (interfaces == NULL) { + fprintf(stderr, "Failed to allocate memory for interfaces\n"); + ret = -1; + } + } + +#ifndef HAVE_PKCS11_STATIC + if (ret == CKR_OK) { + count = 1; + ret = ((CK_C_GetInterfaceList)func)(interfaces, &count); + CHECK_CKR_FAIL(ret, CKR_BUFFER_TOO_SMALL, "Get Interface List"); + } + if (ret == CKR_OK) { + count = interfaceCount; + ret = ((CK_C_GetInterfaceList)func)(interfaces, &count); + CHECK_CKR(ret, "Get Interface List"); + } +#else + if (ret == CKR_OK) { + count = 1; + ret = C_GetInterfaceList(interfaces, &count); + CHECK_CKR_FAIL(ret, CKR_BUFFER_TOO_SMALL, "Get Interface List"); + } + if (ret == CKR_OK) { + count = interfaceCount; + ret = C_GetInterfaceList(interfaces, &count); + CHECK_CKR(ret, "Get Interface List"); + } +#endif + + if (interfaces != NULL) { + free(interfaces); + } + return ret; +} + +static CK_RV test_get_interface(void* args) +{ + CK_RV ret = CKR_OK; + CK_INTERFACE* interface = NULL; + CK_VERSION version; + CK_FLAGS flags = 0; + CK_UTF8CHAR_PTR interfaceName = NULL; +#ifndef HAVE_PKCS11_STATIC + void* func; +#endif + + (void)args; + +#ifndef HAVE_PKCS11_STATIC + func = (void*)(CK_C_GetInterface)dlsym(dlib, "C_GetInterface"); + if (func == NULL) { + fprintf(stderr, "Failed to get interface function\n"); + ret = -1; + } + if (ret == CKR_OK) { + ret = ((CK_C_GetInterface)func)(interfaceName, NULL, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_ARGUMENTS_BAD, "Get Interface"); + } + if (ret == CKR_OK) { + ret = ((CK_C_GetInterface)func)(interfaceName, NULL, &interface, 0); + CHECK_CKR(ret, "Get Interface"); + } + if (ret == CKR_OK) { + interfaceName = (CK_UTF8CHAR_PTR)"FAIL"; + ret = ((CK_C_GetInterface)func)(interfaceName, NULL, &interface, flags); + CHECK_CKR_FAIL(ret, CKR_ARGUMENTS_BAD, "Get Interface"); + } + if (ret == CKR_OK) { + interfaceName = (CK_UTF8CHAR_PTR)"PKCS 11"; + ret = ((CK_C_GetInterface)func)(interfaceName, NULL, &interface, flags); + CHECK_CKR(ret, "Get Interface"); + } + if (ret == CKR_OK) { + version.major = 2; + version.minor = 40; + ret = ((CK_C_GetInterface)func)(interfaceName, &version, &interface, + flags); + CHECK_CKR(ret, "Get Interface"); + } + if (ret == CKR_OK) { + version.major = 2; + version.minor = 20; + ret = ((CK_C_GetInterface)func)(interfaceName, &version, &interface, + flags); + CHECK_CKR_FAIL(ret, CKR_ARGUMENTS_BAD, "Get Interface"); + } + if (ret == CKR_OK) { + version.major = 3; + version.minor = 0; + ret = ((CK_C_GetInterface)func)(interfaceName, &version, &interface, + flags); + CHECK_CKR(ret, "Get Interface"); + } +#ifdef WOLFPKCS11_PKCS11_V3_2 + if (ret == CKR_OK) { + version.major = 3; + version.minor = 2; + ret = ((CK_C_GetInterface)func)(interfaceName, &version, &interface, + flags); + CHECK_CKR(ret, "Get Interface"); + } +#endif /* WOLFPKCS11_PKCS11_V3_2 */ +#else + if (ret == CKR_OK) { + ret = C_GetInterface(interfaceName, NULL, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_ARGUMENTS_BAD, "Get Interface"); + } + if (ret == CKR_OK) { + ret = C_GetInterface(interfaceName, NULL, &interface, 0); + CHECK_CKR(ret, "Get Interface"); + } + if (ret == CKR_OK) { + interfaceName = (CK_UTF8CHAR_PTR)"FAIL"; + ret = C_GetInterface(interfaceName, NULL, &interface, flags); + CHECK_CKR_FAIL(ret, CKR_ARGUMENTS_BAD, "Get Interface"); + } + if (ret == CKR_OK) { + interfaceName = (CK_UTF8CHAR_PTR)"PKCS 11"; + ret = C_GetInterface(interfaceName, NULL, &interface, flags); + CHECK_CKR(ret, "Get Interface"); + } + if (ret == CKR_OK) { + version.major = 2; + version.minor = 40; + ret = C_GetInterface(interfaceName, &version, &interface, flags); + CHECK_CKR(ret, "Get Interface"); + } + if (ret == CKR_OK) { + version.major = 2; + version.minor = 20; + ret = C_GetInterface(interfaceName, &version, &interface, flags); + CHECK_CKR_FAIL(ret, CKR_ARGUMENTS_BAD, "Get Interface"); + } + if (ret == CKR_OK) { + version.major = 3; + version.minor = 0; + ret = C_GetInterface(interfaceName, &version, &interface, flags); + CHECK_CKR(ret, "Get Interface"); + } +#ifdef WOLFPKCS11_PKCS11_V3_2 + if (ret == CKR_OK) { + version.major = 3; + version.minor = 2; + ret = C_GetInterface(interfaceName, &version, &interface, flags); + CHECK_CKR(ret, "Get Interface"); + } +#endif /* WOLFPKCS11_PKCS11_V3_2 */ +#endif /* HAVE_PKCS11_STATIC */ + + funcList = (CK_FUNCTION_LIST*)interface->pFunctionList; + if (funcList == NULL) { + fprintf(stderr, "Failed to get function list\n"); + ret = -1; + } + return ret; +} + +static CK_RV test_get_info(void* args) +{ + CK_RV ret = CKR_OK; + CK_INFO info; + CK_VERSION version; + CK_INTERFACE* interface = NULL; +#ifndef HAVE_PKCS11_STATIC + void* func; +#endif + + (void)args; + +#ifndef HAVE_PKCS11_STATIC + func = (void*)(CK_C_GetInterface)dlsym(dlib, "C_GetInterface"); + if (func == NULL) { + fprintf(stderr, "Failed to get interface function\n"); + ret = -1; + } +#endif + /* Load V2.40 interface */ + if (ret == CKR_OK) { + version.major = 2; + version.minor = 40; +#ifndef HAVE_PKCS11_STATIC + ret = ((CK_C_GetInterface)func)((CK_UTF8CHAR_PTR)"PKCS 11", &version, + &interface, (CK_FLAGS)0); +#else + ret = C_GetInterface((CK_UTF8CHAR_PTR)"PKCS 11", &version, &interface, + (CK_FLAGS)0); +#endif + CHECK_CKR(ret, "Get Interface"); + } + + /* Check Get Info */ + if (ret == CKR_OK) { + funcList = (CK_FUNCTION_LIST*)interface->pFunctionList; + ret = funcList->C_GetInfo(NULL); + CHECK_CKR_FAIL(ret, CKR_ARGUMENTS_BAD, "Get Info no pointer"); + } + if (ret == CKR_OK) { + ret = funcList->C_GetInfo(&info); + CHECK_CKR(ret, "Get Info"); + } + if (ret == CKR_OK) { + if (info.cryptokiVersion.major != 2 || + info.cryptokiVersion.minor != 40) { + fprintf(stderr, "Expected version 2.40, got %d.%d\n", + info.cryptokiVersion.major, info.cryptokiVersion.minor); + ret = -1; + } + } + + /* Load V3.0 interface */ + if (ret == CKR_OK) { + version.major = 3; + version.minor = 0; +#ifndef HAVE_PKCS11_STATIC + ret = ((CK_C_GetInterface)func)((CK_UTF8CHAR_PTR)"PKCS 11", &version, + &interface, (CK_FLAGS)0); +#else + ret = C_GetInterface((CK_UTF8CHAR_PTR)"PKCS 11", &version, &interface, + (CK_FLAGS)0); +#endif + CHECK_CKR(ret, "Get Interface"); + } + + /* Check Get Info */ + if (ret == CKR_OK) { + funcList = (CK_FUNCTION_LIST*)interface->pFunctionList; + ret = funcList->C_GetInfo(NULL); + CHECK_CKR_FAIL(ret, CKR_ARGUMENTS_BAD, "Get Info no pointer"); + } + if (ret == CKR_OK) { + ret = funcList->C_GetInfo(&info); + CHECK_CKR(ret, "Get Info"); + } + if (ret == CKR_OK) { + if (info.cryptokiVersion.major != 3 || + info.cryptokiVersion.minor != 0) { + fprintf(stderr, "Expected version 3.0, got %d.%d\n", + info.cryptokiVersion.major, info.cryptokiVersion.minor); + ret = -1; + } + } + +#ifdef WOLFPKCS11_PKCS11_V3_2 + /* Load V3.2 interface */ + if (ret == CKR_OK) { + version.major = 3; + version.minor = 2; +#ifndef HAVE_PKCS11_STATIC + ret = ((CK_C_GetInterface)func)((CK_UTF8CHAR_PTR)"PKCS 11", &version, + &interface, (CK_FLAGS)0); +#else + ret = C_GetInterface((CK_UTF8CHAR_PTR)"PKCS 11", &version, &interface, + (CK_FLAGS)0); +#endif + CHECK_CKR(ret, "Get Interface"); + } + + if (ret == CKR_OK) { + funcList = (CK_FUNCTION_LIST*)interface->pFunctionList; + ret = funcList->C_GetInfo(NULL); + CHECK_CKR_FAIL(ret, CKR_ARGUMENTS_BAD, "Get Info no pointer"); + } + if (ret == CKR_OK) { + ret = funcList->C_GetInfo(&info); + CHECK_CKR(ret, "Get Info"); + } + if (ret == CKR_OK) { + if (info.cryptokiVersion.major != 3 || + info.cryptokiVersion.minor != 2) { + fprintf(stderr, "Expected version 3.2, got %d.%d\n", + info.cryptokiVersion.major, info.cryptokiVersion.minor); + ret = -1; + } + } +#endif + + return ret; +} + +static CK_RV test_function_not_supported(void* args) +{ + CK_RV ret = CKR_OK; + CK_SESSION_HANDLE session = *(CK_SESSION_HANDLE*)args; +#ifdef WOLFPKCS11_PKCS11_V3_2 + CK_FUNCTION_LIST_3_2* funcListExt = (CK_FUNCTION_LIST_3_2*)funcList; +#else + CK_FUNCTION_LIST_3_0* funcListExt = (CK_FUNCTION_LIST_3_0*)funcList; +#endif + + if (ret == CKR_OK) { + ret = funcListExt->C_SessionCancel(session, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "SessionCancel"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_MessageEncryptInit(session, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "MessageEncryptInit"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_EncryptMessage(session, NULL, 0, NULL, 0, NULL, 0, + NULL, NULL); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "EncryptMessage"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_EncryptMessageBegin(session, NULL, 0, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "EncryptMessageBegin"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_EncryptMessageNext(session, NULL, 0, NULL, 0, NULL, + 0, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "EncryptMessageNext"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_MessageEncryptFinal(session); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "MessageEncryptFinal"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_MessageDecryptInit(session, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "MessageDecryptInit"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_DecryptMessage(session, NULL, 0, NULL, 0, NULL, 0, + NULL, NULL); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "DecryptMessage"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_DecryptMessageBegin(session, NULL, 0, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "DecryptMessageBegin"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_DecryptMessageNext(session, NULL, 0, NULL, 0, NULL, + 0, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "DecryptMessageNext"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_MessageDecryptFinal(session); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "MessageDecryptFinal"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_MessageSignInit(session, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "MessageSignInit"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_SignMessage(session, NULL, 0, NULL, 0, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "SignMessage"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_SignMessageBegin(session, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "SignMessageBegin"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_SignMessageNext(session, NULL, 0, NULL, 0, + NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "SignMessageNext"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_MessageSignFinal(session); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "MessageSignFinal"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_MessageVerifyInit(session, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "MessageVerifyInit"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_VerifyMessage(session, NULL, 0, NULL, 0, + NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "VerifyMessage"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_VerifyMessageBegin(session, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "VerifyMessageBegin"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_VerifyMessageNext(session, NULL, 0, NULL, 0, + NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "VerifyMessageNext"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_MessageVerifyFinal(session); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "MessageVerifyFinal"); + } + +#ifdef WOLFPKCS11_PKCS11_V3_2 + if (ret == CKR_OK) { + ret = funcListExt->C_EncapsulateKey(session, NULL, 0, NULL, 0, NULL, + NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "EncapsulateKey"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_DecapsulateKey(session, NULL, 0, NULL, 0, NULL, + 0, NULL); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "DecapsulateKey"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_VerifySignatureInit(session, NULL, 0, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "VerifySignatureInit"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_VerifySignature(session, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "VerifySignature"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_VerifySignatureUpdate(session, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, + "VerifySignatureUpdate"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_VerifySignatureFinal(session); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "VerifySignatureFinal"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_GetSessionValidationFlags(session, 0, NULL); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, + "GetSessionValidationFlags"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_AsyncComplete(session, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "AsyncComplete"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_AsyncGetID(session, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "AsyncGetID"); + } + if (ret == CKR_OK) { + ret = funcListExt->C_AsyncJoin(session, NULL, 0, NULL, 0); + CHECK_CKR_FAIL(ret, CKR_FUNCTION_NOT_SUPPORTED, "AsyncJoin"); + } +#endif + + return ret; +} + +static CK_RV pkcs11_lib_init(void) +{ + CK_RV ret; + CK_C_INITIALIZE_ARGS args; + + XMEMSET(&args, 0x00, sizeof(args)); + args.flags = CKF_OS_LOCKING_OK; + ret = funcList->C_Initialize(NULL); + CHECK_CKR(ret, "Initialize"); + + return ret; +} + +static CK_RV pkcs11_init_token(void) +{ + CK_RV ret; + unsigned char label[32]; + + XMEMSET(label, ' ', sizeof(label)); + XMEMCPY(label, tokenName, XSTRLEN(tokenName)); + + ret = funcList->C_InitToken(slot, soPin, soPinLen, label); + CHECK_CKR(ret, "Init Token"); + + return ret; +} + +static void pkcs11_final(int closeDl) +{ + if (funcList != NULL) { + funcList->C_Finalize(NULL); + } + if (closeDl) { + #ifndef HAVE_PKCS11_STATIC + dlclose(dlib); + #endif + } +} + +static CK_RV pkcs11_set_user_pin(int slotId) +{ + CK_RV ret; + CK_SESSION_HANDLE session = CK_INVALID_HANDLE; + int flags = CKF_SERIAL_SESSION | CKF_RW_SESSION; + + ret = funcList->C_OpenSession(slotId, flags, NULL, NULL, &session); + CHECK_CKR(ret, "Set User PIN - Open Session"); + if (ret == CKR_OK) { + ret = funcList->C_Login(session, CKU_SO, soPin, soPinLen); + CHECK_CKR(ret, "Set User PIN - Login"); + if (ret == CKR_OK) { + ret = funcList->C_InitPIN(session, userPin, userPinLen); + CHECK_CKR(ret, "Set User PIN - Init PIN"); + } + funcList->C_CloseSession(session); + } + + if (ret != CKR_OK) + fprintf(stderr, "FAILED: Setting user PIN\n"); + return ret; +} + +static CK_RV pkcs11_open_session(int flags, void* args) +{ + CK_SESSION_HANDLE* session = (CK_SESSION_HANDLE*)args; + CK_RV ret = CKR_OK; + int sessFlags = CKF_SERIAL_SESSION | CKF_RW_SESSION; + + if (flags & TEST_FLAG_SESSION) { + ret = funcList->C_OpenSession(slot, sessFlags, NULL, NULL, session); + CHECK_CKR(ret, "Open Session"); + if (ret == CKR_OK && userPinLen != 0) { + ret = funcList->C_Login(*session, CKU_USER, userPin, userPinLen); + CHECK_CKR(ret, "Login"); + } + } + + return ret; +} + +static void pkcs11_close_session(int flags, void* args) +{ + CK_SESSION_HANDLE* session = (CK_SESSION_HANDLE*)args; + + if (flags & TEST_FLAG_SESSION) { + if (userPinLen != 0) + funcList->C_Logout(*session); + funcList->C_CloseSession(*session); + } +} + +static TEST_FUNC testFunc[] = { + PKCS11TEST_FUNC_NO_INIT_DECL(test_get_interface_list), + PKCS11TEST_FUNC_NO_INIT_DECL(test_get_interface), + PKCS11TEST_FUNC_TOKEN_DECL(test_get_info), + PKCS11TEST_FUNC_SESS_DECL(test_function_not_supported), +}; +static int testFuncCnt = sizeof(testFunc) / sizeof(*testFunc); + +static CK_RV pkcs11_test(int slotId, int setPin, int onlySet, int closeDl) +{ + CK_RV ret; + int i; + int attempted = 0, passed = 0, skipped = 0; + int inited = 0; + + /* Set it global. */ + slot = slotId; + + /* Do tests before library initialization. */ + ret = run_tests(testFunc, testFuncCnt, onlySet, 0); + + /* Initialize library. */ + if (ret == CKR_OK) + ret = pkcs11_lib_init(); + + /* Do tests after library initialization but without SO PIN. */ + if (ret == CKR_OK) { + inited = 1; + ret = run_tests(testFunc, testFuncCnt, onlySet, TEST_FLAG_INIT); + } + + if (ret == CKR_OK) + ret = pkcs11_init_token(); + + /* Do tests after library initialization but without session. */ + if (ret == CKR_OK) { + ret = run_tests(testFunc, testFuncCnt, onlySet, TEST_FLAG_INIT | + TEST_FLAG_TOKEN); + } + + /* Set user PIN. */ + if (ret == CKR_OK) { + if (setPin) + ret = pkcs11_set_user_pin(slotId); + } + /* Do tests with session. */ + if (ret == CKR_OK) { + ret = run_tests(testFunc, testFuncCnt, onlySet, TEST_FLAG_INIT | + TEST_FLAG_TOKEN | TEST_FLAG_SESSION); + } + + /* Check for pass and fail. */ + for (i = 0; i < testFuncCnt; i++) { + if (testFunc[i].attempted) { + attempted++; + if (testFunc[i].ret == CKR_SKIPPED) { + skipped++; + } + else if (testFunc[i].ret != CKR_OK) { +#ifdef DEBUG_WOLFPKCS11 + if (ret == CKR_OK) + fprintf(stderr, "\nFAILED tests:\n"); + fprintf(stderr, "%d: %s\n", i + 1, testFunc[i].name); +#endif + ret = testFunc[i].ret; + } + else + passed++; + } + } + fprintf(stderr, "Result: attempted: %d, passed: %d", attempted, passed); + if (skipped != 0) { + fprintf(stderr, ", skipped %d", skipped); + } + fprintf(stderr, "\n"); + if (ret == CKR_OK) + fprintf(stderr, "Success\n"); + else + fprintf(stderr, "Failures\n"); + + if (inited) + pkcs11_final(closeDl); + + return ret; +} + + +static CK_RV pkcs11_init(const char* library) +{ + CK_RV ret = CKR_OK; + + (void) library; + +#ifndef HAVE_PKCS11_STATIC + dlib = dlopen(library, RTLD_NOW | RTLD_LOCAL); + if (dlib == NULL) { + fprintf(stderr, "dlopen error: %s\n", dlerror()); + ret = -1; + } + +#ifdef DEBUG_WOLFPKCS11 + wolfPKCS11_Debugging_On_fp = (void (*)(void))dlsym(dlib, + "wolfPKCS11_Debugging_On"); + wolfPKCS11_Debugging_Off_fp = (void (*)(void))dlsym(dlib, + "wolfPKCS11_Debugging_Off"); + /* These functions are optional, so don't fail if they're not found */ +#endif + +#endif + + return ret; +} + +#endif /* WOLFPKCS11_PKCS11_V3_0 */ + +/* Display the usage options of the benchmark program. */ +static void Usage(void) +{ + printf("pkcs11v3test\n"); + printf("-? Help, print this usage\n"); + printf("-lib PKCS#11 library to test\n"); + printf("-slot Slot number to use\n"); + printf("-token Name of token\n"); + printf("-soPin Security Officer PIN\n"); + printf("-userPin User PIN\n"); + printf("-no-close Do not close the PKCS#11 library before exit\n"); + printf("-list List all tests that can be run\n"); + UnitUsage(); + printf(" Test case number to try\n"); +} + +#ifndef NO_MAIN_DRIVER +int main(int argc, char* argv[]) +#else +int pkcs11v3test_test(int argc, char* argv[]) +#endif +{ +#ifdef WOLFPKCS11_PKCS11_V3_0 + int ret; + CK_RV rv; + int slotId = WOLFPKCS11_DLL_SLOT; + const char* libName = WOLFPKCS11_DLL_FILENAME; + int setPin = 1; + int testCase; + int onlySet = 0; + int closeDl = 1; + int i; + +#ifndef WOLFPKCS11_NO_ENV + XSETENV("WOLFPKCS11_TOKEN_PATH", "./store/pkcs11v3test", 1); +#endif + + argc--; + argv++; + while (argc > 0) { + if (string_matches(*argv, "-?")) { + Usage(); + return 0; + } + UNIT_PARSE_ARGS(argc, argv) + else if (string_matches(*argv, "-lib")) { + argc--; + argv++; + if (argc == 0) { + fprintf(stderr, "Library name not supplied\n"); + return 1; + } + libName = *argv; + } + else if (string_matches(*argv, "-case")) { + argc--; + argv++; + if (argc == 0) { + fprintf(stderr, "Test case number not supplied\n"); + return 1; + } + testCase = atoi(*argv); + if (testCase <= 0 || testCase > testFuncCnt) { + fprintf(stderr, "Test case out of range: %s\n", *argv); + return 1; + } + testFunc[testCase - 1].run = 1; + onlySet = 1; + } + else if (string_matches(*argv, "-token")) { + argc--; + argv++; + if (argc == 0) { + fprintf(stderr, "Token name not supplied\n"); + return 1; + } + tokenName = *argv; + } + else if (string_matches(*argv, "-soPin")) { + argc--; + argv++; + if (argc == 0) { + fprintf(stderr, "SO PIN not supplied\n"); + return 1; + } + soPin = (byte*)*argv; + soPinLen = (int)XSTRLEN((const char*)soPin); + } + else if (string_matches(*argv, "-userPin")) { + argc--; + argv++; + if (argc == 0) { + fprintf(stderr, "User PIN not supplied\n"); + return 1; + } + userPin = (byte*)*argv; + } + else if (string_matches(*argv, "-no-close")) { + closeDl = 0; + } + else if (string_matches(*argv, "-list")) { + for (i = 0; i < testFuncCnt; i++) + fprintf(stderr, "%d: %s\n", i + 1, testFunc[i].name); + return 0; + } + else if (isdigit((int)argv[0][0])) { + testCase = atoi(*argv); + if (testCase <= 0 || testCase > testFuncCnt) { + fprintf(stderr, "Test case out of range: %s\n", *argv); + return 1; + } + testFunc[testCase - 1].run = 1; + onlySet = 1; + } + else { + for (i = 0; i < testFuncCnt; i++) { + if (string_matches(*argv, testFunc[i].name)) { + testFunc[i].run = 1; + onlySet = 1; + break; + } + } + if (i == testFuncCnt) { + fprintf(stderr, "Test case name doesn't match: %s\n", *argv); + return 1; + } + } + + argc--; + argv++; + } + + userPinLen = (int)XSTRLEN((const char*)userPin); + + rv = pkcs11_init(libName); + if (rv == CKR_OK) { + rv = pkcs11_test(slotId, setPin, onlySet, closeDl); + } + + if (rv == CKR_OK) + ret = 0; + else + ret = 1; + return ret; +#else + (void)argc; + (void)argv; + fprintf(stdout, "%s: PKCS#11 v3.0 not compiled in!\n", argv[0]); + return 0; +#endif /* WOLFPKCS11_PKCS11_V3_0 */ +} diff --git a/wolfpkcs11/pkcs11.h b/wolfpkcs11/pkcs11.h index 575bb96..4e172b1 100644 --- a/wolfpkcs11/pkcs11.h +++ b/wolfpkcs11/pkcs11.h @@ -73,8 +73,8 @@ extern "C" { #define CK_NULL_PTR NULL_PTR -#define CRYPTOKI_VERSION_MAJOR 2 -#define CRYPTOKI_VERSION_MINOR 40 +#define CRYPTOKI_VERSION_MAJOR 3 +#define CRYPTOKI_VERSION_MINOR 2 #define CK_INVALID_HANDLE 0UL @@ -805,13 +805,47 @@ typedef struct CK_TLS_MAC_PARAMS { } CK_TLS_MAC_PARAMS; typedef CK_TLS_MAC_PARAMS* CK_TLS_MAC_PARAMS_PTR; +typedef struct CK_ASYNC_DATA { + CK_ULONG ulVersion; + CK_BYTE_PTR pValue; + CK_ULONG ulValue; + CK_OBJECT_HANDLE hObject; + CK_OBJECT_HANDLE hAdditionalObject; +} CK_ASYNC_DATA; +typedef CK_ASYNC_DATA* CK_ASYNC_DATA_PTR; + + /* Function list types. */ typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST; +typedef struct CK_FUNCTION_LIST_3_0 CK_FUNCTION_LIST_3_0; +typedef struct CK_FUNCTION_LIST_3_2 CK_FUNCTION_LIST_3_2; + typedef CK_FUNCTION_LIST* CK_FUNCTION_LIST_PTR; +typedef CK_FUNCTION_LIST_3_0* CK_FUNCTION_LIST_3_0_PTR; +typedef CK_FUNCTION_LIST_3_2* CK_FUNCTION_LIST_3_2_PTR; + typedef CK_FUNCTION_LIST_PTR* CK_FUNCTION_LIST_PTR_PTR; +typedef CK_FUNCTION_LIST_3_0_PTR* CK_FUNCTION_LIST_3_0_PTR_PTR; +typedef CK_FUNCTION_LIST_3_2_PTR* CK_FUNCTION_LIST_3_2_PTR_PTR; typedef CK_RV (*CK_C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR ppFunctionList); +typedef struct CK_INTERFACE { + CK_UTF8CHAR_PTR pInterfaceName; + CK_VOID_PTR pFunctionList; + CK_FLAGS flags; +} CK_INTERFACE; + +typedef CK_INTERFACE* CK_INTERFACE_PTR; +typedef CK_INTERFACE_PTR* CK_INTERFACE_PTR_PTR; + +typedef CK_RV (*CK_C_GetInterfaceList)(CK_INTERFACE_PTR pInterfacesList, + CK_ULONG_PTR pulCount); +typedef CK_RV (*CK_C_GetInterface)(CK_UTF8CHAR_PTR pInterfaceName, + CK_VERSION_PTR pVersion, + CK_INTERFACE_PTR_PTR ppInterface, + CK_FLAGS flags); + WP11_API CK_RV C_Initialize(CK_VOID_PTR pInitArgs); WP11_API CK_RV C_Finalize(CK_VOID_PTR pReserved); @@ -991,6 +1025,101 @@ WP11_API CK_RV C_CancelFunction(CK_SESSION_HANDLE hSession); WP11_API CK_RV C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved); +/* PKCS#11 V 3.0 functions */ +WP11_API CK_RV C_GetInterfaceList(CK_INTERFACE_PTR pInterfacesList, + CK_ULONG_PTR pulCount); +WP11_API CK_RV C_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, + CK_VERSION_PTR pVersion, + CK_INTERFACE_PTR_PTR ppInterface, + CK_FLAGS flags); +CK_RV C_LoginUser(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, + CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, + CK_UTF8CHAR_PTR pUsername, CK_ULONG ulUsernameLen); +CK_RV C_SessionCancel(CK_SESSION_HANDLE hSession, CK_FLAGS flags); +CK_RV C_MessageEncryptInit(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); +CK_RV C_EncryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pPlaintext, + CK_ULONG ulPlaintextLen, CK_BYTE_PTR pCiphertext, + CK_ULONG_PTR pulCiphertextLen); +CK_RV C_EncryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen); +CK_RV C_EncryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pPlaintextPart, + CK_ULONG ulPlaintextPartLen, CK_BYTE_PTR pCiphertextPart, + CK_ULONG_PTR pulCiphertextPartLen, CK_FLAGS flags); +CK_RV C_MessageEncryptFinal(CK_SESSION_HANDLE hSession); +CK_RV C_MessageDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); +CK_RV C_DecryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pCiphertext, + CK_ULONG ulCiphertextLen, CK_BYTE_PTR pPlaintext, + CK_ULONG_PTR pulPlaintextLen); +CK_RV C_DecryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen); +CK_RV C_DecryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pCiphertextPart, + CK_ULONG ulCiphertextPartLen, CK_BYTE_PTR pPlaintextPart, + CK_ULONG_PTR pulPlaintextPartLen, CK_FLAGS flags); +CK_RV C_MessageDecryptFinal(CK_SESSION_HANDLE hSession); +CK_RV C_MessageSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); +CK_RV C_SignMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen); +CK_RV C_SignMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen); +CK_RV C_SignMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen); +CK_RV C_MessageSignFinal(CK_SESSION_HANDLE hSession); +CK_RV C_MessageVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); +CK_RV C_VerifyMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen); +CK_RV C_VerifyMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen); +CK_RV C_VerifyMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen); +CK_RV C_MessageVerifyFinal(CK_SESSION_HANDLE hSession); + +/* PKCS#11 V 3.2 functions */ +CK_RV C_EncapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hPublicKey, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey, + CK_BYTE_PTR pCiphertext, CK_ULONG_PTR pulCiphertextLen); +CK_RV C_DecapsulateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hPrivateKey, CK_BYTE_PTR pCiphertext, + CK_ULONG ulCiphertextLen, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey); +CK_RV C_VerifySignatureInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen); +CK_RV C_VerifySignature(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen); +CK_RV C_VerifySignatureUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen); +CK_RV C_VerifySignatureFinal(CK_SESSION_HANDLE hSession); +CK_RV C_GetSessionValidationFlags(CK_SESSION_HANDLE hSession, CK_ULONG type, + CK_FLAGS * pFlags); +CK_RV C_AsyncComplete(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, + CK_ASYNC_DATA_PTR pResult); +CK_RV C_AsyncGetID(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, + CK_ULONG_PTR pulID); +CK_RV C_AsyncJoin(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, + CK_ULONG ulID, CK_BYTE_PTR pData, CK_ULONG ulData); + struct CK_FUNCTION_LIST { CK_VERSION version; @@ -1175,6 +1304,534 @@ struct CK_FUNCTION_LIST { }; +struct CK_FUNCTION_LIST_3_0 { + CK_VERSION version; + + CK_RV (*C_Initialize)(CK_VOID_PTR pInitArgs); + CK_RV (*C_Finalize)(CK_VOID_PTR pReserved); + CK_RV (*C_GetInfo)(CK_INFO_PTR pInfo); + CK_RV (*C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR ppFunctionList); + CK_RV (*C_GetSlotList)(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, + CK_ULONG_PTR pulCount); + CK_RV (*C_GetSlotInfo)(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo); + CK_RV (*C_GetTokenInfo)(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo); + CK_RV (*C_GetMechanismList)(CK_SLOT_ID slotID, + CK_MECHANISM_TYPE_PTR pMechanismList, + CK_ULONG_PTR pulCount); + CK_RV (*C_GetMechanismInfo)(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, + CK_MECHANISM_INFO_PTR pInfo); + CK_RV (*C_InitToken)(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, + CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pLabel); + CK_RV (*C_InitPIN)(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, + CK_ULONG ulPinLen); + CK_RV (*C_SetPIN)(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, + CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, + CK_ULONG ulNewLen); + CK_RV (*C_OpenSession)(CK_SLOT_ID slotID, CK_FLAGS flags, + CK_VOID_PTR pApplication, CK_NOTIFY Notify, + CK_SESSION_HANDLE_PTR phSession); + CK_RV (*C_CloseSession)(CK_SESSION_HANDLE hSession); + CK_RV (*C_CloseAllSessions)(CK_SLOT_ID slotID); + CK_RV (*C_GetSessionInfo)(CK_SESSION_HANDLE hSession, + CK_SESSION_INFO_PTR pInfo); + CK_RV (*C_GetOperationState)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pOperationState, + CK_ULONG_PTR pulOperationStateLen); + CK_RV (*C_SetOperationState)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pOperationState, + CK_ULONG ulOperationStateLen, + CK_OBJECT_HANDLE hEncryptionKey, + CK_OBJECT_HANDLE hAuthenticationKey); + CK_RV (*C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, + CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen); + CK_RV (*C_Logout)(CK_SESSION_HANDLE hSession); + CK_RV (*C_CreateObject)(CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phObject); + CK_RV (*C_CopyObject)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phNewObject); + CK_RV (*C_DestroyObject)(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject); + CK_RV (*C_GetObjectSize)(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize); + CK_RV (*C_GetAttributeValue)(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount); + CK_RV (*C_SetAttributeValue)(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount); + CK_RV (*C_FindObjectsInit)(CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount); + CK_RV (*C_FindObjects)(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE_PTR phObject, + CK_ULONG ulMaxObjectCount, + CK_ULONG_PTR pulObjectCount); + CK_RV (*C_FindObjectsFinal)(CK_SESSION_HANDLE hSession); + CK_RV (*C_EncryptInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); + CK_RV (*C_Encrypt)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, + CK_ULONG_PTR pulEncryptedDataLen); + CK_RV (*C_EncryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen); + CK_RV (*C_EncryptFinal)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pLastEncryptedPart, + CK_ULONG_PTR pulLastEncryptedPartLen); + CK_RV (*C_DecryptInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); + CK_RV (*C_Decrypt)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, + CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, + CK_ULONG_PTR pulDataLen); + CK_RV (*C_DecryptUpdate)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, + CK_ULONG_PTR pulPartLen); + CK_RV (*C_DecryptFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, + CK_ULONG_PTR pulLastPartLen); + CK_RV (*C_DigestInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism); + CK_RV (*C_Digest)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, + CK_ULONG_PTR pulDigestLen); + CK_RV (*C_DigestUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen); + CK_RV (*C_DigestKey)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey); + CK_RV (*C_DigestFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, + CK_ULONG_PTR pulDigestLen); + CK_RV (*C_SignInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_Sign)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen); + CK_RV (*C_SignUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen); + CK_RV (*C_SignFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen); + CK_RV (*C_SignRecoverInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_SignRecover)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen); + CK_RV (*C_VerifyInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); + CK_RV (*C_Verify)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen); + CK_RV (*C_VerifyUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen); + CK_RV (*C_VerifyFinal)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen); + CK_RV (*C_VerifyRecoverInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_VerifyRecover)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, + CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen); + CK_RV (*C_DigestEncryptUpdate)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, CK_ULONG ulPartLen, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen); + CK_RV (*C_DecryptDigestUpdate)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, + CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen); + CK_RV (*C_SignEncryptUpdate)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, CK_ULONG ulPartLen, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen); + CK_RV (*C_DecryptVerifyUpdate)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, + CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen); + CK_RV (*C_GenerateKey)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phKey); + CK_RV (*C_GenerateKeyPair)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pPublicKeyTemplate, + CK_ULONG ulPublicKeyAttributeCount, + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, + CK_ULONG ulPrivateKeyAttributeCount, + CK_OBJECT_HANDLE_PTR phPublicKey, + CK_OBJECT_HANDLE_PTR phPrivateKey); + CK_RV (*C_WrapKey)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, + CK_BYTE_PTR pWrappedKey, + CK_ULONG_PTR pulWrappedKeyLen); + CK_RV (*C_UnwrapKey)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hUnwrappingKey, + CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey); + CK_RV (*C_DeriveKey)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hBaseKey, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey); + CK_RV (*C_SeedRandom)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, + CK_ULONG ulSeedLen); + CK_RV (*C_GenerateRandom)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen); + CK_RV (*C_GetFunctionStatus)(CK_SESSION_HANDLE hSession); + CK_RV (*C_CancelFunction)(CK_SESSION_HANDLE hSession); + CK_RV (*C_WaitForSlotEvent)(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, + CK_VOID_PTR pReserved); + + /* PKCS#11 V 3.0 functions */ + CK_RV (*C_GetInterfaceList)(CK_INTERFACE_PTR pInterfacesList, + CK_ULONG_PTR pulCount); + CK_RV (*C_GetInterface)(CK_UTF8CHAR_PTR pInterfaceName, + CK_VERSION_PTR pVersion, + CK_INTERFACE_PTR_PTR ppInterface, + CK_FLAGS flags); + CK_RV (*C_LoginUser)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, + CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, + CK_UTF8CHAR_PTR pUsername, CK_ULONG ulUsernameLen); + CK_RV (*C_SessionCancel)(CK_SESSION_HANDLE hSession, CK_FLAGS flags); + CK_RV (*C_MessageEncryptInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_EncryptMessage)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pPlaintext, + CK_ULONG ulPlaintextLen, CK_BYTE_PTR pCiphertext, + CK_ULONG_PTR pulCiphertextLen); + CK_RV (*C_EncryptMessageBegin)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen); + CK_RV (*C_EncryptMessageNext)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pPlaintextPart, + CK_ULONG ulPlaintextPartLen, CK_BYTE_PTR pCiphertextPart, + CK_ULONG_PTR pulCiphertextPartLen, CK_FLAGS flags); + CK_RV (*C_MessageEncryptFinal)(CK_SESSION_HANDLE hSession); + CK_RV (*C_MessageDecryptInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_DecryptMessage)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pCiphertext, + CK_ULONG ulCiphertextLen, CK_BYTE_PTR pPlaintext, + CK_ULONG_PTR pulPlaintextLen); + CK_RV (*C_DecryptMessageBegin)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen); + CK_RV (*C_DecryptMessageNext)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pCiphertextPart, + CK_ULONG ulCiphertextPartLen, CK_BYTE_PTR pPlaintextPart, + CK_ULONG_PTR pulPlaintextPartLen, CK_FLAGS flags); + CK_RV (*C_MessageDecryptFinal)(CK_SESSION_HANDLE hSession); + CK_RV (*C_MessageSignInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_SignMessage)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen); + CK_RV (*C_SignMessageBegin)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen); + CK_RV (*C_SignMessageNext)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen); + CK_RV (*C_MessageSignFinal)(CK_SESSION_HANDLE hSession); + CK_RV (*C_MessageVerifyInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_VerifyMessage)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen); + CK_RV (*C_VerifyMessageBegin)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen); + CK_RV (*C_VerifyMessageNext)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen); + CK_RV (*C_MessageVerifyFinal)(CK_SESSION_HANDLE hSession); +}; + +struct CK_FUNCTION_LIST_3_2 { + CK_VERSION version; + + CK_RV (*C_Initialize)(CK_VOID_PTR pInitArgs); + CK_RV (*C_Finalize)(CK_VOID_PTR pReserved); + CK_RV (*C_GetInfo)(CK_INFO_PTR pInfo); + CK_RV (*C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR ppFunctionList); + CK_RV (*C_GetSlotList)(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, + CK_ULONG_PTR pulCount); + CK_RV (*C_GetSlotInfo)(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo); + CK_RV (*C_GetTokenInfo)(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo); + CK_RV (*C_GetMechanismList)(CK_SLOT_ID slotID, + CK_MECHANISM_TYPE_PTR pMechanismList, + CK_ULONG_PTR pulCount); + CK_RV (*C_GetMechanismInfo)(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, + CK_MECHANISM_INFO_PTR pInfo); + CK_RV (*C_InitToken)(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, + CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pLabel); + CK_RV (*C_InitPIN)(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, + CK_ULONG ulPinLen); + CK_RV (*C_SetPIN)(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, + CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, + CK_ULONG ulNewLen); + CK_RV (*C_OpenSession)(CK_SLOT_ID slotID, CK_FLAGS flags, + CK_VOID_PTR pApplication, CK_NOTIFY Notify, + CK_SESSION_HANDLE_PTR phSession); + CK_RV (*C_CloseSession)(CK_SESSION_HANDLE hSession); + CK_RV (*C_CloseAllSessions)(CK_SLOT_ID slotID); + CK_RV (*C_GetSessionInfo)(CK_SESSION_HANDLE hSession, + CK_SESSION_INFO_PTR pInfo); + CK_RV (*C_GetOperationState)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pOperationState, + CK_ULONG_PTR pulOperationStateLen); + CK_RV (*C_SetOperationState)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pOperationState, + CK_ULONG ulOperationStateLen, + CK_OBJECT_HANDLE hEncryptionKey, + CK_OBJECT_HANDLE hAuthenticationKey); + CK_RV (*C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, + CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen); + CK_RV (*C_Logout)(CK_SESSION_HANDLE hSession); + CK_RV (*C_CreateObject)(CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phObject); + CK_RV (*C_CopyObject)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phNewObject); + CK_RV (*C_DestroyObject)(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject); + CK_RV (*C_GetObjectSize)(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize); + CK_RV (*C_GetAttributeValue)(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount); + CK_RV (*C_SetAttributeValue)(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount); + CK_RV (*C_FindObjectsInit)(CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount); + CK_RV (*C_FindObjects)(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE_PTR phObject, + CK_ULONG ulMaxObjectCount, + CK_ULONG_PTR pulObjectCount); + CK_RV (*C_FindObjectsFinal)(CK_SESSION_HANDLE hSession); + CK_RV (*C_EncryptInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); + CK_RV (*C_Encrypt)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, + CK_ULONG_PTR pulEncryptedDataLen); + CK_RV (*C_EncryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen); + CK_RV (*C_EncryptFinal)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pLastEncryptedPart, + CK_ULONG_PTR pulLastEncryptedPartLen); + CK_RV (*C_DecryptInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); + CK_RV (*C_Decrypt)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, + CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, + CK_ULONG_PTR pulDataLen); + CK_RV (*C_DecryptUpdate)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, + CK_ULONG_PTR pulPartLen); + CK_RV (*C_DecryptFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart, + CK_ULONG_PTR pulLastPartLen); + CK_RV (*C_DigestInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism); + CK_RV (*C_Digest)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, + CK_ULONG_PTR pulDigestLen); + CK_RV (*C_DigestUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen); + CK_RV (*C_DigestKey)(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey); + CK_RV (*C_DigestFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, + CK_ULONG_PTR pulDigestLen); + CK_RV (*C_SignInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_Sign)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen); + CK_RV (*C_SignUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen); + CK_RV (*C_SignFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen); + CK_RV (*C_SignRecoverInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_SignRecover)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen); + CK_RV (*C_VerifyInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey); + CK_RV (*C_Verify)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen); + CK_RV (*C_VerifyUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen); + CK_RV (*C_VerifyFinal)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen); + CK_RV (*C_VerifyRecoverInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_VerifyRecover)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, + CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen); + CK_RV (*C_DigestEncryptUpdate)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, CK_ULONG ulPartLen, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen); + CK_RV (*C_DecryptDigestUpdate)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, + CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen); + CK_RV (*C_SignEncryptUpdate)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, CK_ULONG ulPartLen, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen); + CK_RV (*C_DecryptVerifyUpdate)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, + CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen); + CK_RV (*C_GenerateKey)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phKey); + CK_RV (*C_GenerateKeyPair)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pPublicKeyTemplate, + CK_ULONG ulPublicKeyAttributeCount, + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, + CK_ULONG ulPrivateKeyAttributeCount, + CK_OBJECT_HANDLE_PTR phPublicKey, + CK_OBJECT_HANDLE_PTR phPrivateKey); + CK_RV (*C_WrapKey)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, + CK_BYTE_PTR pWrappedKey, + CK_ULONG_PTR pulWrappedKeyLen); + CK_RV (*C_UnwrapKey)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hUnwrappingKey, + CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey); + CK_RV (*C_DeriveKey)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hBaseKey, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey); + CK_RV (*C_SeedRandom)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, + CK_ULONG ulSeedLen); + CK_RV (*C_GenerateRandom)(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen); + CK_RV (*C_GetFunctionStatus)(CK_SESSION_HANDLE hSession); + CK_RV (*C_CancelFunction)(CK_SESSION_HANDLE hSession); + CK_RV (*C_WaitForSlotEvent)(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, + CK_VOID_PTR pReserved); + + /* PKCS#11 V 3.0 functions */ + CK_RV (*C_GetInterfaceList)(CK_INTERFACE_PTR pInterfacesList, + CK_ULONG_PTR pulCount); + CK_RV (*C_GetInterface)(CK_UTF8CHAR_PTR pInterfaceName, + CK_VERSION_PTR pVersion, + CK_INTERFACE_PTR_PTR ppInterface, + CK_FLAGS flags); + CK_RV (*C_LoginUser)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, + CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, + CK_UTF8CHAR_PTR pUsername, CK_ULONG ulUsernameLen); + CK_RV (*C_SessionCancel)(CK_SESSION_HANDLE hSession, CK_FLAGS flags); + CK_RV (*C_MessageEncryptInit)(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_EncryptMessage)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pPlaintext, + CK_ULONG ulPlaintextLen, CK_BYTE_PTR pCiphertext, + CK_ULONG_PTR pulCiphertextLen); + CK_RV (*C_EncryptMessageBegin)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen); + CK_RV (*C_EncryptMessageNext)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pPlaintextPart, + CK_ULONG ulPlaintextPartLen, CK_BYTE_PTR pCiphertextPart, + CK_ULONG_PTR pulCiphertextPartLen, CK_FLAGS flags); + CK_RV (*C_MessageEncryptFinal)(CK_SESSION_HANDLE hSession); + CK_RV (*C_MessageDecryptInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_DecryptMessage)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pCiphertext, + CK_ULONG ulCiphertextLen, CK_BYTE_PTR pPlaintext, + CK_ULONG_PTR pulPlaintextLen); + CK_RV (*C_DecryptMessageBegin)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen); + CK_RV (*C_DecryptMessageNext)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pCiphertextPart, + CK_ULONG ulCiphertextPartLen, CK_BYTE_PTR pPlaintextPart, + CK_ULONG_PTR pulPlaintextPartLen, CK_FLAGS flags); + CK_RV (*C_MessageDecryptFinal)(CK_SESSION_HANDLE hSession); + CK_RV (*C_MessageSignInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_SignMessage)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen); + CK_RV (*C_SignMessageBegin)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen); + CK_RV (*C_SignMessageNext)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen); + CK_RV (*C_MessageSignFinal)(CK_SESSION_HANDLE hSession); + CK_RV (*C_MessageVerifyInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey); + CK_RV (*C_VerifyMessage)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen); + CK_RV (*C_VerifyMessageBegin)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen); + CK_RV (*C_VerifyMessageNext)(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter, + CK_ULONG ulParameterLen, CK_BYTE_PTR pData, + CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen); + CK_RV (*C_MessageVerifyFinal)(CK_SESSION_HANDLE hSession); + + /* PKCS#11 V 3.2 functions */ + CK_RV (*C_EncapsulateKey)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hPublicKey, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey, + CK_BYTE_PTR pCiphertext, CK_ULONG_PTR pulCiphertextLen); + CK_RV (*C_DecapsulateKey)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hPrivateKey, CK_BYTE_PTR pCiphertext, + CK_ULONG ulCiphertextLen, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey); + CK_RV (*C_VerifySignatureInit)(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen); + CK_RV (*C_VerifySignature)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, + CK_ULONG ulDataLen); + CK_RV (*C_VerifySignatureUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, + CK_ULONG ulPartLen); + CK_RV (*C_VerifySignatureFinal)(CK_SESSION_HANDLE hSession); + CK_RV (*C_GetSessionValidationFlags)(CK_SESSION_HANDLE hSession, CK_ULONG type, + CK_FLAGS * pFlags); + CK_RV (*C_AsyncComplete)(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, + CK_ASYNC_DATA_PTR pResult); + CK_RV (*C_AsyncGetID)(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, + CK_ULONG_PTR pulID); + CK_RV (*C_AsyncJoin)(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pFunctionName, + CK_ULONG ulID, CK_BYTE_PTR pData, CK_ULONG ulData); +}; + /* Debug control functions */ #ifdef DEBUG_WOLFPKCS11 WP11_API void wolfPKCS11_Debugging_On(void);