/* * COPYRIGHT (c) International Business Machines Corp. 2020 * * This program is provided under the terms of the Common Public License, * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this * software constitutes recipient's acceptance of CPL-1.0 terms which can be * found in the file LICENSE file or at * https://opensource.org/licenses/cpl1.0.php */ /* File: tok2tok_transport.c * * Test driver. In-depth regression test for PKCS #11 */ #include #include #include #include #include #include #include #include #include "pkcs11types.h" #include "regress.h" #include "mech_to_str.h" #include "ec_curves.h" #include "common.c" CK_RSA_PKCS_OAEP_PARAMS oaep_params_sha1 = { .hashAlg = CKM_SHA_1, .mgf = CKG_MGF1_SHA1, .source = 0, .pSourceData = NULL, .ulSourceDataLen = 0, }; CK_RSA_PKCS_OAEP_PARAMS oaep_params_sha1_source = { .hashAlg = CKM_SHA_1, .mgf = CKG_MGF1_SHA1, .source = CKZ_DATA_SPECIFIED, .pSourceData = "abc", .ulSourceDataLen = 3, }; CK_RSA_PKCS_OAEP_PARAMS oaep_params_sha256 = { .hashAlg = CKM_SHA256, .mgf = CKG_MGF1_SHA256, .source = 0, .pSourceData = NULL, .ulSourceDataLen = 0, }; CK_RSA_PKCS_OAEP_PARAMS oaep_params_sha256_source = { .hashAlg = CKM_SHA256, .mgf = CKG_MGF1_SHA256, .source = CKZ_DATA_SPECIFIED, .pSourceData = "abc", .ulSourceDataLen = 3, }; CK_BYTE aes_iv[16] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }; CK_BYTE des_iv[8] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 }; struct wrapping_mech_info { char *name; CK_MECHANISM wrapping_mech; CK_MECHANISM wrapping_key_gen_mech; CK_ULONG rsa_modbits; CK_ULONG rsa_publ_exp_len; CK_BYTE rsa_publ_exp[4]; CK_ULONG sym_keylen; }; struct wrapping_mech_info wrapping_tests[] = { { .name = "Wrap/Unwrap with RSA 512 PKCS", .wrapping_mech = { CKM_RSA_PKCS, 0, 0 }, .wrapping_key_gen_mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, 0, 0 }, .rsa_modbits = 512, .rsa_publ_exp_len = 3, .rsa_publ_exp = {0x01, 0x00, 0x01}, }, { .name = "Wrap/Unwrap with RSA 1024 PKCS", .wrapping_mech = { CKM_RSA_PKCS, 0, 0 }, .wrapping_key_gen_mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, 0, 0 }, .rsa_modbits = 1024, .rsa_publ_exp_len = 3, .rsa_publ_exp = {0x01, 0x00, 0x01}, }, { .name = "Wrap/Unwrap with RSA 2048 PKCS", .wrapping_mech = { CKM_RSA_PKCS, 0, 0 }, .wrapping_key_gen_mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, 0, 0 }, .rsa_modbits = 2048, .rsa_publ_exp_len = 3, .rsa_publ_exp = {0x01, 0x00, 0x01}, }, { .name = "Wrap/Unwrap with RSA 1024 PKCS OAEP (SHA1)", .wrapping_mech = { CKM_RSA_PKCS_OAEP, &oaep_params_sha1, sizeof(CK_RSA_PKCS_OAEP_PARAMS) }, .wrapping_key_gen_mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, 0, 0 }, .rsa_modbits = 1024, .rsa_publ_exp_len = 3, .rsa_publ_exp = {0x01, 0x00, 0x01}, }, { .name = "Wrap/Unwrap with RSA 1024 PKCS OAEP (SHA1, source data)", .wrapping_mech = { CKM_RSA_PKCS_OAEP, &oaep_params_sha1_source, sizeof(CK_RSA_PKCS_OAEP_PARAMS) }, .wrapping_key_gen_mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, 0, 0 }, .rsa_modbits = 1024, .rsa_publ_exp_len = 3, .rsa_publ_exp = {0x01, 0x00, 0x01}, }, { .name = "Wrap/Unwrap with RSA 1024 PKCS OAEP (SHA256)", .wrapping_mech = { CKM_RSA_PKCS_OAEP, &oaep_params_sha256, sizeof(CK_RSA_PKCS_OAEP_PARAMS) }, .wrapping_key_gen_mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, 0, 0 }, .rsa_modbits = 1024, .rsa_publ_exp_len = 3, .rsa_publ_exp = {0x01, 0x00, 0x01}, }, { .name = "Wrap/Unwrap with RSA 1024 PKCS OAEP (SHA256, source data)", .wrapping_mech = { CKM_RSA_PKCS_OAEP, &oaep_params_sha256_source, sizeof(CK_RSA_PKCS_OAEP_PARAMS) }, .wrapping_key_gen_mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, 0, 0 }, .rsa_modbits = 1024, .rsa_publ_exp_len = 3, .rsa_publ_exp = {0x01, 0x00, 0x01}, }, { .name = "Wrap/Unwrap with AES 128 ECB", .wrapping_mech = { CKM_AES_ECB, 0, 0 }, .wrapping_key_gen_mech = { CKM_AES_KEY_GEN, 0, 0 }, .sym_keylen = 16, }, { .name = "Wrap/Unwrap with AES 192 ECB", .wrapping_mech = { CKM_AES_ECB, 0, 0 }, .wrapping_key_gen_mech = { CKM_AES_KEY_GEN, 0, 0 }, .sym_keylen = 24, }, { .name = "Wrap/Unwrap with AES 256 ECB", .wrapping_mech = { CKM_AES_ECB, 0, 0 }, .wrapping_key_gen_mech = { CKM_AES_KEY_GEN, 0, 0 }, .sym_keylen = 32, }, { .name = "Wrap/Unwrap with AES 128 CBC", .wrapping_mech = { CKM_AES_CBC, aes_iv, sizeof(aes_iv) }, .wrapping_key_gen_mech = { CKM_AES_KEY_GEN, 0, 0 }, .sym_keylen = 16, }, { .name = "Wrap/Unwrap with AES 192 CBC", .wrapping_mech = { CKM_AES_CBC, aes_iv, sizeof(aes_iv) }, .wrapping_key_gen_mech = { CKM_AES_KEY_GEN, 0, 0 }, .sym_keylen = 24, }, { .name = "Wrap/Unwrap with AES 256 CBC", .wrapping_mech = { CKM_AES_CBC, aes_iv, sizeof(aes_iv) }, .wrapping_key_gen_mech = { CKM_AES_KEY_GEN, 0, 0 }, .sym_keylen = 32, }, { .name = "Wrap/Unwrap with AES 128 CBC PAD", .wrapping_mech = { CKM_AES_CBC_PAD, aes_iv, sizeof(aes_iv) }, .wrapping_key_gen_mech = { CKM_AES_KEY_GEN, 0, 0 }, .sym_keylen = 16, }, { .name = "Wrap/Unwrap with AES 192 CBC PAD", .wrapping_mech = { CKM_AES_CBC_PAD, aes_iv, sizeof(aes_iv) }, .wrapping_key_gen_mech = { CKM_AES_KEY_GEN, 0, 0 }, .sym_keylen = 24, }, { .name = "Wrap/Unwrap with AES 256 CBC PAD", .wrapping_mech = { CKM_AES_CBC_PAD, aes_iv, sizeof(aes_iv) }, .wrapping_key_gen_mech = { CKM_AES_KEY_GEN, 0, 0 }, .sym_keylen = 32, }, { .name = "Wrap/Unwrap with DES ECB", .wrapping_mech = { CKM_DES_ECB, 0, 0 }, .wrapping_key_gen_mech = { CKM_DES_KEY_GEN, 0, 0 }, }, { .name = "Wrap/Unwrap with DES CBC", .wrapping_mech = { CKM_DES_CBC, des_iv, sizeof(des_iv) }, .wrapping_key_gen_mech = { CKM_DES_KEY_GEN, 0, 0 }, }, { .name = "Wrap/Unwrap with DES CBC PAD", .wrapping_mech = { CKM_DES_CBC_PAD, des_iv, sizeof(des_iv) }, .wrapping_key_gen_mech = { CKM_DES_KEY_GEN, 0, 0 }, }, { .name = "Wrap/Unwrap with DES2 ECB", .wrapping_mech = { CKM_DES3_ECB, 0, 0 }, .wrapping_key_gen_mech = { CKM_DES2_KEY_GEN, 0, 0 }, }, { .name = "Wrap/Unwrap with DES2 CBC", .wrapping_mech = { CKM_DES3_CBC, des_iv, sizeof(des_iv) }, .wrapping_key_gen_mech = { CKM_DES2_KEY_GEN, 0, 0 }, }, { .name = "Wrap/Unwrap with DES2 CBC PAD", .wrapping_mech = { CKM_DES3_CBC_PAD, des_iv, sizeof(des_iv) }, .wrapping_key_gen_mech = { CKM_DES2_KEY_GEN, 0, 0 }, }, { .name = "Wrap/Unwrap with DES3 ECB", .wrapping_mech = { CKM_DES3_ECB, 0, 0 }, .wrapping_key_gen_mech = { CKM_DES3_KEY_GEN, 0, 0 }, }, { .name = "Wrap/Unwrap with DES3 CBC", .wrapping_mech = { CKM_DES3_CBC, des_iv, sizeof(des_iv) }, .wrapping_key_gen_mech = { CKM_DES3_KEY_GEN, 0, 0 }, }, { .name = "Wrap/Unwrap with DES3 CBC PAD", .wrapping_mech = { CKM_DES3_CBC_PAD, des_iv, sizeof(des_iv) }, .wrapping_key_gen_mech = { CKM_DES3_KEY_GEN, 0, 0 }, }, }; #define NUM_WRAPPING_TESTS sizeof(wrapping_tests) / \ sizeof(struct wrapping_mech_info) CK_BYTE prime256v1[] = OCK_PRIME256V1; struct wrapped_mech_info { char *name; CK_MECHANISM wrapped_key_gen_mech; CK_ULONG rsa_modbits; CK_ULONG rsa_publ_exp_len; CK_BYTE rsa_publ_exp[4]; CK_ULONG sym_keylen; CK_BYTE *ec_params; CK_ULONG ec_params_len; CK_MECHANISM operation_mech; }; struct wrapped_mech_info wrapped_key_tests[] = { { .name = "key type AES 128", .wrapped_key_gen_mech = { CKM_AES_KEY_GEN, 0, 0 }, .operation_mech = { CKM_AES_ECB, 0, 0 }, .sym_keylen = 16, }, { .name = "key type AES 192", .wrapped_key_gen_mech = { CKM_AES_KEY_GEN, 0, 0 }, .operation_mech = { CKM_AES_ECB, 0, 0 }, .sym_keylen = 24, }, { .name = "key type AES 256", .wrapped_key_gen_mech = { CKM_AES_KEY_GEN, 0, 0 }, .operation_mech = { CKM_AES_ECB, 0, 0 }, .sym_keylen = 32, }, { .name = "key type DES3", .wrapped_key_gen_mech = { CKM_DES3_KEY_GEN, 0, 0 }, .operation_mech = { CKM_DES3_ECB, 0, 0 }, }, { .name = "key type DES2", .wrapped_key_gen_mech = { CKM_DES2_KEY_GEN, 0, 0 }, .operation_mech = { CKM_DES3_ECB, 0, 0 }, }, { .name = "key type DES", .wrapped_key_gen_mech = { CKM_DES_KEY_GEN, 0, 0 }, .operation_mech = { CKM_DES_ECB, 0, 0 }, }, { .name = "key type GENERIC SECRET", .wrapped_key_gen_mech = { CKM_GENERIC_SECRET_KEY_GEN, 0, 0 }, .operation_mech = { CKM_SHA_1_HMAC, 0, 0 }, .sym_keylen = 32, }, { .name = "key type RSA PKCS 512", .wrapped_key_gen_mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, 0, 0 }, .operation_mech = { CKM_RSA_PKCS, 0, 0 }, .rsa_modbits = 512, .rsa_publ_exp_len = 3, .rsa_publ_exp = {0x01, 0x00, 0x01}, }, { .name = "key type RSA PKCS 1024", .wrapped_key_gen_mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, 0, 0 }, .operation_mech = { CKM_RSA_PKCS, 0, 0 }, .rsa_modbits = 1024, .rsa_publ_exp_len = 3, .rsa_publ_exp = {0x01, 0x00, 0x01}, }, { .name = "key type RSA PKCS 2048", .wrapped_key_gen_mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, 0, 0 }, .operation_mech = { CKM_RSA_PKCS, 0, 0 }, .rsa_modbits = 2048, .rsa_publ_exp_len = 3, .rsa_publ_exp = {0x01, 0x00, 0x01}, }, { .name = "key type EC", .wrapped_key_gen_mech = { CKM_EC_KEY_PAIR_GEN, 0, 0 }, .operation_mech = { CKM_ECDSA, 0, 0 }, .ec_params = prime256v1, .ec_params_len = sizeof(prime256v1), }, }; #define NUM_WRAPPED_KEY_TESTS sizeof(wrapped_key_tests) / \ sizeof(struct wrapped_mech_info) CK_SLOT_ID slot_id1 = 1, slot_id2 = 2; CK_SESSION_HANDLE session1 = CK_INVALID_HANDLE; CK_SESSION_HANDLE session2 = CK_INVALID_HANDLE; CK_OBJECT_HANDLE sym_wrap_key1 = CK_INVALID_HANDLE; CK_OBJECT_HANDLE sym_wrap_key2 = CK_INVALID_HANDLE; CK_OBJECT_HANDLE publ_wrap_key1 = CK_INVALID_HANDLE; CK_OBJECT_HANDLE publ_wrap_key2 = CK_INVALID_HANDLE; CK_OBJECT_HANDLE priv_wrap_key2 = CK_INVALID_HANDLE; CK_RV do_perform_operation(CK_MECHANISM *mech, CK_SLOT_ID slot1, CK_SESSION_HANDLE sess1, CK_OBJECT_HANDLE sym_key1, CK_OBJECT_HANDLE publ_key1, CK_SLOT_ID slot2, CK_SESSION_HANDLE sess2, CK_OBJECT_HANDLE sym_key2, CK_OBJECT_HANDLE priv_key2) { CK_RV rc; CK_MECHANISM_INFO mech_info; CK_BBOOL encr = FALSE, decr = FALSE, sign = FALSE, verify = FALSE; CK_ULONG input_size, cipher_size, output_size; CK_BYTE input_data[32] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}; CK_BYTE cipher_data[512]; CK_BYTE output_data[512]; CK_OBJECT_HANDLE encr_key, decr_key, sign_key, verify_key; /* Check if Encrypt/Decrypt or Sign/Verify is supported */ rc = funcs->C_GetMechanismInfo(slot1, mech->mechanism, &mech_info); if (rc != CKR_OK) { testcase_error("C_GetMechanismInfo on slot %lu, rc=%s", slot1, p11_get_ckr(rc)); return rc; } encr = (mech_info.flags & CKF_ENCRYPT) != 0; sign = (mech_info.flags & CKF_SIGN) != 0; rc = funcs->C_GetMechanismInfo(slot2, mech->mechanism, &mech_info); if (rc != CKR_OK) { testcase_error("C_GetMechanismInfo on slot %lu, rc=%s", slot2, p11_get_ckr(rc)); return rc; } decr = (mech_info.flags & CKF_DECRYPT) != 0; verify = (mech_info.flags & CKF_VERIFY) != 0; if (encr && decr) { /* Perform Encrypt/Decrypt operation */ switch (mech->mechanism) { case CKM_AES_ECB: input_size = 16; encr_key = sym_key1; decr_key = sym_key2; break; case CKM_DES_ECB: case CKM_DES3_ECB: input_size = 8; encr_key = sym_key1; decr_key = sym_key2; break; case CKM_RSA_PKCS: input_size = 16; encr_key = publ_key1; decr_key = priv_key2; break; default: testcase_error("Operation not supported by testcase"); return CKR_FUNCTION_NOT_SUPPORTED; } rc = funcs->C_EncryptInit(sess1, mech, encr_key); if (rc != CKR_OK) { testcase_error("C_EncryptInit on slot %lu rc=%s", slot1, p11_get_ckr(rc)); return rc; } cipher_size = sizeof(cipher_data); rc = funcs->C_Encrypt(sess1, input_data, input_size, cipher_data, &cipher_size); if (rc != CKR_OK) { testcase_error("C_Encrypt on slot %lu rc=%s", slot1, p11_get_ckr(rc)); return rc; } rc = funcs->C_DecryptInit(sess2, mech, decr_key); if (rc != CKR_OK) { testcase_error("C_DecryptInit on slot %lu rc=%s", slot2, p11_get_ckr(rc)); return rc; } output_size = sizeof(output_data); rc = funcs->C_Decrypt(sess2, cipher_data, cipher_size, output_data, &output_size); if (rc != CKR_OK) { testcase_error("C_Decrypt on slot %lu rc=%s", slot2, p11_get_ckr(rc)); return rc; } if (output_size != input_size) { testcase_error("Decrypted data has different size then original " "data: orig: %lu decr: %lu", input_size, output_size); return CKR_FUNCTION_FAILED; } if (memcmp(input_data, output_data, input_size) != 0) { testcase_error("Decrypted data is different then original data"); return CKR_FUNCTION_FAILED; } } else if (sign && verify) { /* Perform Sign/Verify operation */ switch (mech->mechanism) { case CKM_SHA_1_HMAC: sign_key = sym_key2; verify_key = sym_key1; input_size = 20; break; case CKM_RSA_PKCS: case CKM_ECDSA: sign_key = priv_key2; verify_key = publ_key1; input_size = 20; break; default: testcase_error("Operation not supported by testcase"); return CKR_FUNCTION_NOT_SUPPORTED; } rc = funcs->C_SignInit(sess2, mech, sign_key); if (rc != CKR_OK) { testcase_error("C_SignInit on slot %lu rc=%s", slot2, p11_get_ckr(rc)); return rc; } output_size = sizeof(output_data); rc = funcs->C_Sign(sess2, input_data, input_size, output_data, &output_size); if (rc != CKR_OK) { testcase_error("C_Sign on slot %lu rc=%s", slot2, p11_get_ckr(rc)); return rc; } rc = funcs->C_VerifyInit(sess1, mech, verify_key); if (rc != CKR_OK) { testcase_error("C_VerifyInit on slot %lu rc=%s", slot1, p11_get_ckr(rc)); return rc; } rc = funcs->C_Verify(sess1, input_data, input_size, output_data, output_size); if (rc != CKR_OK) { testcase_error("C_Verify on slot %lu rc=%s", slot1, p11_get_ckr(rc)); return rc; } } else { testcase_error("Neither Encrypt/Decrypt, nor Sign/Verify supported"); return CKR_FUNCTION_NOT_SUPPORTED; } return CKR_OK; } CK_RV do_wrap_key_test(struct wrapped_mech_info *tsuite, CK_MECHANISM *wrap_mech) { CK_RV loc_rc, rc = CKR_OK; CK_OBJECT_HANDLE publ_key = CK_INVALID_HANDLE; CK_OBJECT_HANDLE priv_key = CK_INVALID_HANDLE; CK_OBJECT_HANDLE sym_key = CK_INVALID_HANDLE; CK_OBJECT_HANDLE unwrapped_key = CK_INVALID_HANDLE; CK_BYTE wrapped_key[4096]; CK_ULONG wrapped_key_size = sizeof(wrapped_key); CK_OBJECT_CLASS key_class; CK_KEY_TYPE key_type; CK_ULONG key_len, unwrapped_keylen; CK_ATTRIBUTE unwrap_tmpl[] = { {CKA_CLASS, &key_class, sizeof(CK_OBJECT_CLASS)}, {CKA_KEY_TYPE, &key_type, sizeof(CK_KEY_TYPE)}, {CKA_VALUE_LEN, &key_len, sizeof(CK_ULONG)} }; CK_ULONG unwrap_tmpl_num; CK_ATTRIBUTE getattr_tmpl[] = { {CKA_VALUE_LEN, &unwrapped_keylen, sizeof(CK_ULONG)} }; char *s = NULL; CK_RSA_PKCS_OAEP_PARAMS *oaep; testcase_begin("Wrap/Unwrap of %s with %s", tsuite->name, mech_to_str(wrap_mech->mechanism)); if (!mech_supported(slot_id1, tsuite->wrapped_key_gen_mech.mechanism)) { testcase_skip("Slot %u doesn't support %s (%u)", (unsigned int)slot_id1, mech_to_str(tsuite->wrapped_key_gen_mech.mechanism), (unsigned int)tsuite->wrapped_key_gen_mech.mechanism); goto testcase_cleanup; } if (!mech_supported(slot_id2, tsuite->wrapped_key_gen_mech.mechanism)) { testcase_skip("Slot %u doesn't support %s (%u)", (unsigned int)slot_id2, mech_to_str(tsuite->wrapped_key_gen_mech.mechanism), (unsigned int)tsuite->wrapped_key_gen_mech.mechanism); goto testcase_cleanup; } if (!mech_supported(slot_id1, tsuite->operation_mech.mechanism)) { testcase_skip("Slot %u doesn't support %s (%u)", (unsigned int)slot_id1, mech_to_str(tsuite->operation_mech.mechanism), (unsigned int)tsuite->operation_mech.mechanism); goto testcase_cleanup; } if (!mech_supported(slot_id2, tsuite->operation_mech.mechanism)) { testcase_skip("Slot %u doesn't support %s (%u)", (unsigned int)slot_id2, mech_to_str(tsuite->operation_mech.mechanism), (unsigned int)tsuite->operation_mech.mechanism); goto testcase_cleanup; } if (is_ep11_token(slot_id2) && wrap_mech->mechanism == CKM_AES_CBC && ((tsuite->wrapped_key_gen_mech.mechanism == CKM_AES_KEY_GEN && tsuite->sym_keylen == 24) || tsuite->wrapped_key_gen_mech.mechanism == CKM_DES3_KEY_GEN)) { testcase_skip("EP11 token in slot %lu doesn't support to unwrap " "AES-192 or DES3 keys with CKM_AES_CBC", slot_id2); goto testcase_cleanup; } /* Generate the to be wrapped key in slot 1 */ switch (tsuite->wrapped_key_gen_mech.mechanism) { case CKM_RSA_PKCS_KEY_PAIR_GEN: if (p11_ahex_dump(&s, tsuite->rsa_publ_exp, tsuite->rsa_publ_exp_len) == NULL) { testcase_error("p11_ahex_dump() failed"); rc = CKR_FUNCTION_FAILED; goto testcase_cleanup; } if (!keysize_supported(slot_id1, tsuite->wrapped_key_gen_mech.mechanism, tsuite->rsa_modbits)) { testcase_skip("Token in slot %lu cannot be used with " "modbits.='%ld'", slot_id1, tsuite->rsa_modbits); goto testcase_cleanup; } if (!keysize_supported(slot_id2, tsuite->wrapped_key_gen_mech.mechanism, tsuite->rsa_modbits)) { testcase_skip("Token in slot %lu cannot be used with " "modbits.='%ld'", slot_id2, tsuite->rsa_modbits); goto testcase_cleanup; } if (is_ep11_token(slot_id1) || is_ep11_token(slot_id2)) { if (!is_valid_ep11_pubexp(tsuite->rsa_publ_exp, tsuite->rsa_publ_exp_len)) { testcase_skip("EP11 Token in cannot be used with " "publ_exp.='%s'", s); goto testcase_cleanup; } } if (is_cca_token(slot_id1) || is_cca_token(slot_id2)) { if (!is_valid_cca_pubexp(tsuite->rsa_publ_exp, tsuite->rsa_publ_exp_len)) { testcase_skip("CCA Token in scannot be used with " "publ_exp.='%s'", s); goto testcase_cleanup; } } if (is_tpm_token(slot_id1) || is_tpm_token(slot_id2)) { if (!is_valid_tpm_pubexp(tsuite->rsa_publ_exp, tsuite->rsa_publ_exp_len) || !is_valid_tpm_modbits(tsuite->rsa_modbits)) { testcase_skip("TPM Token cannot " "be used with " "publ_exp.='%s'", s); goto testcase_cleanup; } } if (is_icsf_token(slot_id1) || is_icsf_token(slot_id2)) { if (!is_valid_icsf_pubexp(tsuite->rsa_publ_exp, tsuite->rsa_publ_exp_len) || tsuite->rsa_modbits < 1024) { testcase_skip("ICSF Token cannot be used with " "publ_exp='%s'.", s); goto testcase_cleanup; } } rc = generate_RSA_PKCS_KeyPair(session1, tsuite->rsa_modbits, tsuite->rsa_publ_exp, tsuite->rsa_publ_exp_len, &publ_key, &priv_key); break; case CKM_AES_KEY_GEN: rc = generate_AESKey(session1, tsuite->sym_keylen, &tsuite->wrapped_key_gen_mech, &sym_key); break; case CKM_DES3_KEY_GEN: case CKM_DES2_KEY_GEN: case CKM_DES_KEY_GEN: rc = funcs->C_GenerateKey(session1, &tsuite->wrapped_key_gen_mech, NULL, 0, &sym_key); break; case CKM_GENERIC_SECRET_KEY_GEN: rc = generate_SecretKey(session1, tsuite->sym_keylen, &tsuite->wrapped_key_gen_mech, &sym_key); break; case CKM_EC_KEY_PAIR_GEN: rc = generate_EC_KeyPair(session1, tsuite->ec_params, tsuite->ec_params_len, &publ_key, &priv_key); break; default: testcase_error("Testcase does not support %s (%u)", mech_to_str(tsuite->wrapped_key_gen_mech.mechanism), (unsigned int)tsuite->wrapped_key_gen_mech.mechanism); goto testcase_cleanup; } if (rc != CKR_OK) { testcase_error("generate to be wrapped key with mech %s (%u) in slot " "%lu failed, rc=%s", mech_to_str(tsuite->wrapped_key_gen_mech.mechanism), (unsigned int)tsuite->wrapped_key_gen_mech.mechanism, slot_id1, p11_get_ckr(rc)); goto testcase_cleanup; } /* Test the key with a crypto operation on slot 1 */ rc = do_perform_operation(&tsuite->operation_mech, slot_id1, session1, sym_key, publ_key, slot_id1, session1, sym_key, priv_key); if (rc != CKR_OK) goto testcase_cleanup; /* Wrap the key on slot 1 */ rc = funcs->C_WrapKey(session1, wrap_mech, sym_wrap_key1 != CK_INVALID_HANDLE ? sym_wrap_key1 : publ_wrap_key1, sym_key != CK_INVALID_HANDLE ? sym_key : priv_key, wrapped_key, &wrapped_key_size); if (rc != CKR_OK) { if (rc == CKR_KEY_NOT_WRAPPABLE) { testcase_skip("Key not wrappable"); rc = CKR_OK; goto testcase_cleanup; } if (rc == CKR_MECHANISM_PARAM_INVALID && wrap_mech->mechanism == CKM_RSA_PKCS_OAEP) { oaep = (CK_RSA_PKCS_OAEP_PARAMS *)wrap_mech->pParameter; if (is_cca_token(slot_id1) && oaep->source == CKZ_DATA_SPECIFIED) { testcase_skip("CCA does not support RSA OAEP with source data"); rc = CKR_OK; goto testcase_cleanup; } if (is_cca_token(slot_id1) && oaep->hashAlg != CKM_SHA_1 && oaep->hashAlg != CKM_SHA256) { testcase_skip("CCA does not support RSA OAEP with a hash other " "than SHA1 or SHA256"); rc = CKR_OK; goto testcase_cleanup; } if (is_ep11_token(slot_id1) && oaep->hashAlg != CKM_SHA_1 && oaep->mgf != CKG_MGF1_SHA1) { testcase_skip("EP11 may not support RSA OAEP with a hash other " "than SHA1 on older firmware levels"); rc = CKR_OK; goto testcase_cleanup; } } if (rc == CKR_ARGUMENTS_BAD) { if (is_ep11_token(slot_id1) && publ_wrap_key1 != CK_INVALID_HANDLE && (wrap_mech->mechanism == CKM_RSA_PKCS || wrap_mech->mechanism == CKM_RSA_PKCS_OAEP)) { testcase_skip("EP11 does not support to wrap asymmetric keys " "with RSA"); rc = CKR_OK; goto testcase_cleanup; } } testcase_error("wrap with mech %s (%u) in slot %lu failed, rc=%s", mech_to_str(wrap_mech->mechanism), (unsigned int)wrap_mech->mechanism, slot_id1, p11_get_ckr(rc)); goto testcase_cleanup; } /* Get class and key type from original key */ switch (tsuite->wrapped_key_gen_mech.mechanism) { case CKM_AES_KEY_GEN: case CKM_GENERIC_SECRET_KEY_GEN: unwrap_tmpl_num = 3; break; default: unwrap_tmpl_num = 2; break; } rc = funcs->C_GetAttributeValue(session1, sym_key != CK_INVALID_HANDLE ? sym_key : priv_key, unwrap_tmpl, unwrap_tmpl_num); if (rc != CKR_OK) { testcase_error("C_GetAttributeValue() on slot %lu, rc=%s.", slot_id1, p11_get_ckr(rc)); goto testcase_cleanup; } /* Unwrap the key on slot 2 */ rc = funcs->C_UnwrapKey(session2, wrap_mech, sym_wrap_key2 != CK_INVALID_HANDLE ? sym_wrap_key2 : priv_wrap_key2, wrapped_key, wrapped_key_size, unwrap_tmpl, unwrap_tmpl_num, &unwrapped_key); if (rc != CKR_OK) { if (rc == CKR_KEY_NOT_WRAPPABLE || rc == CKR_WRAPPED_KEY_INVALID) { testcase_skip("Key not (un-)wrappable"); rc = CKR_OK; goto testcase_cleanup; } if (rc == CKR_MECHANISM_PARAM_INVALID && wrap_mech->mechanism == CKM_RSA_PKCS_OAEP) { oaep = (CK_RSA_PKCS_OAEP_PARAMS *)wrap_mech->pParameter; if (is_cca_token(slot_id2) && oaep->source == CKZ_DATA_SPECIFIED) { testcase_skip("CCA does not support RSA OAEP with source data"); rc = CKR_OK; goto testcase_cleanup; } if (is_cca_token(slot_id2) && oaep->hashAlg != CKM_SHA_1 && oaep->hashAlg != CKM_SHA256) { testcase_skip("CCA does not support RSA OAEP with a hash other " "than SHA1 or SHA256"); rc = CKR_OK; goto testcase_cleanup; } if (is_ep11_token(slot_id2) && oaep->hashAlg != CKM_SHA_1 && oaep->mgf != CKG_MGF1_SHA1) { testcase_skip("EP11 may not support RSA OAEP with a hash other " "than SHA1 on older firmware levels"); rc = CKR_OK; goto testcase_cleanup; } } if (rc == CKR_MECHANISM_INVALID && is_ep11_token(slot_id2) && wrap_mech->mechanism == CKM_DES3_CBC) { testcase_skip("EP11 does not support unwrap with DES3 CBC"); rc = CKR_OK; goto testcase_cleanup; } testcase_error("unwrap with mech %s (%u) in slot %lu failed, rc=%s", mech_to_str(wrap_mech->mechanism), (unsigned int)wrap_mech->mechanism, slot_id2, p11_get_ckr(rc)); goto testcase_cleanup; } if (key_type == CKK_AES || key_type == CKK_GENERIC_SECRET) { /* Check if the unwrapped key has the desired key length */ rc = funcs->C_GetAttributeValue(session2, unwrapped_key, getattr_tmpl, 1); if (rc != CKR_OK) { testcase_error("C_GetAttributeValue() on slot %lu, rc=%s.", slot_id2, p11_get_ckr(rc)); goto testcase_cleanup; } if (unwrapped_keylen != key_len) { testcase_error("Unwrapped key size (%lu) differers from original " "(%lu)", unwrapped_keylen, key_len); rc = CKR_UNWRAPPING_KEY_SIZE_RANGE; goto testcase_cleanup; } } /* Test the unwrapped key with a crypto operation on slot 2 */ rc = do_perform_operation(&tsuite->operation_mech, slot_id1, session1, sym_key, publ_key, slot_id2, session2, unwrapped_key, unwrapped_key); if (rc != CKR_OK) goto testcase_cleanup; testcase_new_assertion(); testcase_pass("Wrap/Unwrap of %s with %s", tsuite->name, mech_to_str(wrap_mech->mechanism)); testcase_cleanup: if (sym_key != CK_INVALID_HANDLE) { loc_rc = funcs->C_DestroyObject(session1, sym_key); if (loc_rc != CKR_OK) testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc)); } if (publ_key != CK_INVALID_HANDLE) { loc_rc = funcs->C_DestroyObject(session1, publ_key); if (loc_rc != CKR_OK) testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc)); } if (priv_key != CK_INVALID_HANDLE) { loc_rc = funcs->C_DestroyObject(session1, priv_key); if (loc_rc != CKR_OK) testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc)); } if (unwrapped_key != CK_INVALID_HANDLE) { loc_rc = funcs->C_DestroyObject(session2, unwrapped_key); if (loc_rc != CKR_OK) testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc)); } if (s != NULL) free(s); if (rc != CKR_OK) testcase_fail("Wrap/Unwrap of %s with %s", tsuite->name, mech_to_str(wrap_mech->mechanism)); return rc; } CK_RV do_wrapping_test(struct wrapping_mech_info *tsuite) { CK_RV loc_rc, rc = CKR_OK; CK_ULONG i; char *s = NULL; CK_BYTE modulus[512]; CK_BYTE publ_exp[16]; CK_BYTE key[32]; CK_ULONG key_size = 0; CK_BYTE value[32]; CK_ATTRIBUTE rsa_publ_tmpl[] = { {CKA_MODULUS, modulus, sizeof(modulus) }, {CKA_PUBLIC_EXPONENT, publ_exp, sizeof(publ_exp) }, }; CK_ATTRIBUTE sym_tmpl[] = { {CKA_VALUE, value, sizeof(value) }, }; testsuite_begin("%s", tsuite->name); if (!mech_supported(slot_id1, tsuite->wrapping_key_gen_mech.mechanism)) { testsuite_skip(NUM_WRAPPED_KEY_TESTS, "Slot %u doesn't support %s (%u)", (unsigned int)slot_id1, mech_to_str(tsuite->wrapping_key_gen_mech.mechanism), (unsigned int)tsuite->wrapping_key_gen_mech.mechanism); goto testcase_cleanup; } if (!mech_supported(slot_id2, tsuite->wrapping_key_gen_mech.mechanism)) { testsuite_skip(NUM_WRAPPED_KEY_TESTS, "Slot %u doesn't support %s (%u)", (unsigned int)slot_id2, mech_to_str(tsuite->wrapping_key_gen_mech.mechanism), (unsigned int)tsuite->wrapping_key_gen_mech.mechanism); goto testcase_cleanup; } if (!mech_supported(slot_id1, tsuite->wrapping_mech.mechanism)) { testsuite_skip(NUM_WRAPPED_KEY_TESTS, "Slot %u doesn't support %s (%u)", (unsigned int)slot_id1, mech_to_str(tsuite->wrapping_mech.mechanism), (unsigned int)tsuite->wrapping_mech.mechanism); goto testcase_cleanup; } if (!wrap_supported(slot_id1, tsuite->wrapping_mech)) { testsuite_skip(NUM_WRAPPED_KEY_TESTS, "Slot %u doesn't support key " "wrapping with %s (%u)", (unsigned int)slot_id1, mech_to_str(tsuite->wrapping_mech.mechanism), (unsigned int)tsuite->wrapping_mech.mechanism); goto testcase_cleanup; } if (!mech_supported(slot_id2, tsuite->wrapping_mech.mechanism)) { testsuite_skip(NUM_WRAPPED_KEY_TESTS, "Slot %u doesn't support %s (%u)", (unsigned int)slot_id2, mech_to_str(tsuite->wrapping_mech.mechanism), (unsigned int)tsuite->wrapping_mech.mechanism); goto testcase_cleanup; } if (!unwrap_supported(slot_id2, tsuite->wrapping_mech)) { testsuite_skip(NUM_WRAPPED_KEY_TESTS, "Slot %u doesn't support key " "wrapping with %s (%u)", (unsigned int)slot_id2, mech_to_str(tsuite->wrapping_mech.mechanism), (unsigned int)tsuite->wrapping_mech.mechanism); goto testcase_cleanup; } /* * Generate the wrapping key in slot 2. * For symmetric wrapping keys, generate the key from a random clear key * value, to be able to import the same key in the other token. * For RSA wrapping keys, the public key can be extracted and imported in * the other token. */ switch (tsuite->wrapping_key_gen_mech.mechanism) { case CKM_RSA_PKCS_KEY_PAIR_GEN: if (p11_ahex_dump(&s, tsuite->rsa_publ_exp, tsuite->rsa_publ_exp_len) == NULL) { testcase_error("p11_ahex_dump() failed"); rc = CKR_FUNCTION_FAILED; goto testcase_cleanup; } if (!keysize_supported(slot_id1, tsuite->wrapping_key_gen_mech.mechanism, tsuite->rsa_modbits)) { testcase_skip("Token in slot %ld cannot be used with " "modbits.='%ld'", slot_id1, tsuite->rsa_modbits); goto testcase_cleanup; } if (!keysize_supported(slot_id2, tsuite->wrapping_key_gen_mech.mechanism, tsuite->rsa_modbits)) { testcase_skip("Token in slot %ld cannot be used with " "modbits.='%ld'", slot_id2, tsuite->rsa_modbits); goto testcase_cleanup; } if (is_ep11_token(slot_id1) || is_ep11_token(slot_id2)) { if (!is_valid_ep11_pubexp(tsuite->rsa_publ_exp, tsuite->rsa_publ_exp_len)) { testcase_skip("EP11 Token in cannot be used with " "publ_exp.='%s'", s); goto testcase_cleanup; } } if (is_cca_token(slot_id1) || is_cca_token(slot_id2)) { if (!is_valid_cca_pubexp(tsuite->rsa_publ_exp, tsuite->rsa_publ_exp_len)) { testcase_skip("CCA Token in scannot be used with " "publ_exp.='%s'", s); goto testcase_cleanup; } } if (is_tpm_token(slot_id1) || is_tpm_token(slot_id2)) { if (!is_valid_tpm_pubexp(tsuite->rsa_publ_exp, tsuite->rsa_publ_exp_len) || !is_valid_tpm_modbits(tsuite->rsa_modbits)) { testcase_skip("TPM Token cannot " "be used with " "publ_exp.='%s'", s); goto testcase_cleanup; } } if (is_icsf_token(slot_id1) || is_icsf_token(slot_id2)) { if (!is_valid_icsf_pubexp(tsuite->rsa_publ_exp, tsuite->rsa_publ_exp_len) || tsuite->rsa_modbits < 1024) { testcase_skip("ICSF Token cannot be used with " "publ_exp='%s'.", s); goto testcase_cleanup; } } rc = generate_RSA_PKCS_KeyPair(session2, tsuite->rsa_modbits, tsuite->rsa_publ_exp, tsuite->rsa_publ_exp_len, &publ_wrap_key2, &priv_wrap_key2); break; case CKM_AES_KEY_GEN: key_size = 32; rc = funcs->C_GenerateRandom(session2, key, key_size); if (rc != CKR_OK) { testcase_error("C_GenerateRandom(), rc=%s.", p11_get_ckr(rc)); goto testcase_cleanup; } rc = create_AESKey(session2, key, key_size, &sym_wrap_key2); break; case CKM_DES3_KEY_GEN: key_size = 24; rc = funcs->C_GenerateRandom(session2, key, key_size); if (rc != CKR_OK) { testcase_error("C_GenerateRandom(), rc=%s.", p11_get_ckr(rc)); goto testcase_cleanup; } rc = create_DES3Key(session2, key, key_size, &sym_wrap_key2); break; case CKM_DES2_KEY_GEN: key_size = 16; rc = funcs->C_GenerateRandom(session2, key, key_size); if (rc != CKR_OK) { testcase_error("C_GenerateRandom(), rc=%s.", p11_get_ckr(rc)); goto testcase_cleanup; } rc = create_DES2Key(session2, key, key_size, &sym_wrap_key2); break; case CKM_DES_KEY_GEN: key_size = 8; rc = funcs->C_GenerateRandom(session2, key, key_size); if (rc != CKR_OK) { testcase_error("C_GenerateRandom(), rc=%s.", p11_get_ckr(rc)); goto testcase_cleanup; } rc = create_DESKey(session2, key, key_size, &sym_wrap_key2); break; default: testcase_error("Testcase does not support %s (%u)", mech_to_str(tsuite->wrapping_key_gen_mech.mechanism), (unsigned int)tsuite->wrapping_key_gen_mech.mechanism); goto testcase_cleanup; } if (rc != CKR_OK) { testcase_error("generate wrapping key with mech %s (%u) in slot %lu " "failed, rc=%s", mech_to_str(tsuite->wrapping_key_gen_mech.mechanism), (unsigned int)tsuite->wrapping_key_gen_mech.mechanism, slot_id2, p11_get_ckr(rc)); goto testcase_cleanup; } /* Import the wrapping key into slot 1 */ switch (tsuite->wrapping_key_gen_mech.mechanism) { case CKM_RSA_PKCS_KEY_PAIR_GEN: rc = funcs->C_GetAttributeValue(session2, publ_wrap_key2, rsa_publ_tmpl, 2); if (rc != CKR_OK) { testcase_error("C_GetAttributeValue(), rc=%s.", p11_get_ckr(rc)); goto testcase_cleanup; } rc = create_RSAPublicKey(session1, rsa_publ_tmpl[0].pValue, rsa_publ_tmpl[1].pValue, rsa_publ_tmpl[0].ulValueLen, rsa_publ_tmpl[1].ulValueLen, &publ_wrap_key1); break; case CKM_AES_KEY_GEN: memcpy(sym_tmpl[0].pValue, key, key_size); sym_tmpl[0].ulValueLen = key_size; rc = create_AESKey(session1, sym_tmpl[0].pValue, sym_tmpl[0].ulValueLen, &sym_wrap_key1); break; case CKM_DES3_KEY_GEN: memcpy(sym_tmpl[0].pValue, key, key_size); sym_tmpl[0].ulValueLen = key_size; rc = create_DES3Key(session1, sym_tmpl[0].pValue, sym_tmpl[0].ulValueLen, &sym_wrap_key1); break; case CKM_DES2_KEY_GEN: memcpy(sym_tmpl[0].pValue, key, key_size); sym_tmpl[0].ulValueLen = key_size; rc = create_DES2Key(session1, sym_tmpl[0].pValue, sym_tmpl[0].ulValueLen, &sym_wrap_key1); break; case CKM_DES_KEY_GEN: memcpy(sym_tmpl[0].pValue, key, key_size); sym_tmpl[0].ulValueLen = key_size; rc = create_DESKey(session1, sym_tmpl[0].pValue, sym_tmpl[0].ulValueLen, &sym_wrap_key1); break; default: testcase_error("Testcase does not support %s (%u)", mech_to_str(tsuite->wrapping_key_gen_mech.mechanism), (unsigned int)tsuite->wrapping_key_gen_mech.mechanism); goto testcase_cleanup; } if (rc != CKR_OK) { testcase_error("import wrapping key in slot %lu failed, rc=%s", slot_id1, p11_get_ckr(rc)); goto testcase_cleanup; } /* Wrap/unwrap different keys with this wrapping key */ for (i = 0; i< NUM_WRAPPED_KEY_TESTS; i++) { rc = do_wrap_key_test(&wrapped_key_tests[i], &tsuite->wrapping_mech); if (rc != CKR_OK) break; } testcase_cleanup: if (sym_wrap_key1 != CK_INVALID_HANDLE) { loc_rc = funcs->C_DestroyObject(session1, sym_wrap_key1); if (loc_rc != CKR_OK) testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc)); } sym_wrap_key1 = CK_INVALID_HANDLE; if (sym_wrap_key2 != CK_INVALID_HANDLE) { loc_rc = funcs->C_DestroyObject(session2, sym_wrap_key2); if (loc_rc != CKR_OK) testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc)); } sym_wrap_key2 = CK_INVALID_HANDLE; if (publ_wrap_key1 != CK_INVALID_HANDLE) { loc_rc = funcs->C_DestroyObject(session1, publ_wrap_key1); if (loc_rc != CKR_OK) testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc)); } publ_wrap_key1 = CK_INVALID_HANDLE; if (publ_wrap_key2 != CK_INVALID_HANDLE) { loc_rc = funcs->C_DestroyObject(session2, publ_wrap_key2); if (loc_rc != CKR_OK) testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc)); } publ_wrap_key2 = CK_INVALID_HANDLE; if (priv_wrap_key2 != CK_INVALID_HANDLE) { loc_rc = funcs->C_DestroyObject(session2, priv_wrap_key2); if (loc_rc != CKR_OK) testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc)); } priv_wrap_key2 = CK_INVALID_HANDLE; if (s != NULL) free(s); return rc; } CK_RV do_tok2tok_tests() { CK_ULONG i; CK_RV rc; for (i = 0; i < NUM_WRAPPING_TESTS; i++) { rc = do_wrapping_test(&wrapping_tests[i]); if (rc != CKR_OK) break; } return CKR_OK; } int main(int argc, char **argv) { CK_C_INITIALIZE_ARGS cinit_args; int i, ret = 1; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_RV rv; CK_FLAGS flags; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-slot1") == 0) { ++i; slot_id1 = atoi(argv[i]); } else if (strcmp(argv[i], "-slot2") == 0) { ++i; slot_id2 = atoi(argv[i]); } if (strcmp(argv[i], "-h") == 0) { printf("usage: %s [-slot1 ] [-slot2 ] [-h]\n\n", argv[0]); printf("By default, Slot #1 and #2 are used\n\n"); return -1; } } if (get_user_pin(user_pin)) return CKR_FUNCTION_FAILED; user_pin_len = (CK_ULONG) strlen((char *) user_pin); printf("Using slots #%lu and #%lu...\n\n", slot_id1, slot_id2); rv = do_GetFunctionList(); if (rv != TRUE) { testcase_fail("do_GetFunctionList() rc = %s", p11_get_ckr(rv)); goto out; } testcase_setup(0); testcase_begin("Starting..."); // Initialize memset(&cinit_args, 0x0, sizeof(cinit_args)); cinit_args.flags = CKF_OS_LOCKING_OK; if ((rv = funcs->C_Initialize(&cinit_args))) { testcase_fail("C_Initialize() rc = %s", p11_get_ckr(rv)); goto out; } // Open Session and login for slot 1 testcase_new_assertion(); flags = CKF_SERIAL_SESSION | CKF_RW_SESSION; rv = funcs->C_OpenSession(slot_id1, flags, NULL, NULL, &session1); if (rv != CKR_OK) { testcase_fail("C_OpenSession() on slot %lu rc = %s", slot_id1, p11_get_ckr(rv)); goto finalize; } testcase_pass("C_OpenSession on slot %lu", slot_id1); testcase_new_assertion(); rv = funcs->C_Login(session1, CKU_USER, user_pin, user_pin_len); if (rv != CKR_OK) { testcase_fail("C_Login() on slot %lu rc = %s", slot_id1, p11_get_ckr(rv)); goto close_session; } testcase_pass("C_Login as User on slot %lu", slot_id1); // Open Session and login for slot 2 testcase_new_assertion(); flags = CKF_SERIAL_SESSION | CKF_RW_SESSION; rv = funcs->C_OpenSession(slot_id2, flags, NULL, NULL, &session2); if (rv != CKR_OK) { testcase_fail("C_OpenSession() on slot %lu rc = %s", slot_id2, p11_get_ckr(rv)); goto close_session; } testcase_pass("C_OpenSession on slot %lu", slot_id2); testcase_new_assertion(); rv = funcs->C_Login(session2, CKU_USER, user_pin, user_pin_len); if (rv != CKR_OK) { testcase_fail("C_Login() on slot %lu rc = %s\n", slot_id2, p11_get_ckr(rv)); // ignore error } else { testcase_pass("C_Login as User on slot %lu", slot_id2); } rv = do_tok2tok_tests(); if (rv != CKR_OK) goto close_session; ret = 0; close_session: if (session1 != CK_INVALID_HANDLE) { rv = funcs->C_CloseSession(session1); if (rv != CKR_OK) { testcase_fail("C_CloseSession() on slot %lu rc = %s", slot_id1, p11_get_ckr(rv)); } } if (session2 != CK_INVALID_HANDLE) { rv = funcs->C_CloseSession(session2); if (rv != CKR_OK) { testcase_fail("C_CloseSession() on slot %lu rc = %s", slot_id2, p11_get_ckr(rv)); } } finalize: rv = funcs->C_Finalize(NULL); if (rv != CKR_OK) { testcase_fail("C_Finalize() rc = %s", p11_get_ckr(rv)); } out: testcase_print_result(); return ret; }