CK_RV do_GetSlotInfo(void) { CK_FLAGS flags; CK_SESSION_HANDLE session; CK_RV rc = 0; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_SLOT_ID slot_id = SLOT_ID; CK_SLOT_INFO info; testcase_begin("testing C_GetSlotInfo"); testcase_rw_session(); testcase_user_login(); /* Test expected values */ testcase_new_assertion(); rc = funcs->C_GetSlotInfo(slot_id, &info); if (rc != CKR_OK) { testcase_fail("C_GetSlotInfo() rc = %s", p11_get_ckr(rc)); goto testcase_cleanup; } else testcase_pass("Slot info of in-use slot received successfully"); /* Test for invalid slot */ testcase_new_assertion(); rc = funcs->C_GetSlotInfo(999, &info); if (rc != CKR_SLOT_ID_INVALID) { testcase_fail("C_GetSlotInfo returned %s instead of" " CKR_SLOT_ID_INVALID.", p11_get_ckr(rc)); rc = CKR_FUNCTION_FAILED; // dont confuse loop in main goto testcase_cleanup; } else { testcase_pass("C_GetSlotInfo correctly returned " "CKR_SLOT_ID_INVALID."); rc = 0; // don't confuse loop in main } testcase_cleanup: testcase_user_logout(); if ((funcs->C_CloseSession(session)) != CKR_OK) testcase_error("C_CloseSessions failed."); return rc; }
CK_RV do_GetInfo(void) { CK_FLAGS flags; CK_SESSION_HANDLE session; CK_RV rc = 0; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_INFO info; // Do some setup and login to the token testcase_begin("C_GetInfo function check"); testcase_rw_session(); testcase_user_login(); testcase_new_assertion(); rc = funcs->C_GetInfo(&info); if (rc != CKR_OK){ testcase_fail("C_GetInfo() rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } testcase_pass("Library info successfully sourced"); testcase_cleanup: testcase_user_logout(); if ((funcs->C_CloseSession(session)) != CKR_OK) testcase_error("C_CloseSession() failed."); return rc; }
CK_RV do_GetMechanismInfo(void) { CK_FLAGS flags; CK_SESSION_HANDLE session; CK_RV rc = 0; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_SLOT_ID slot_id = SLOT_ID; CK_MECHANISM_INFO info; CK_ULONG i, count; CK_MECHANISM_TYPE *mech_list = NULL; testcase_begin("testing C_GetMechanismInfo"); testcase_rw_session(); testcase_user_login(); testcase_new_assertion(); rc = funcs->C_GetMechanismList(slot_id, NULL, &count); if (rc != CKR_OK) { testcase_error("C_GetMechanismList #1 rc=%s", p11_get_ckr(rc)); return rc; } mech_list = (CK_MECHANISM_TYPE *)malloc(count * sizeof(CK_MECHANISM_TYPE)); if (!mech_list) { rc = CKR_HOST_MEMORY; goto testcase_cleanup; } rc = funcs->C_GetMechanismList(slot_id, mech_list, &count); if (rc != CKR_OK) { testcase_error("C_GetMechanismList #2 rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } for (i = 0; i < count; i++) { rc = funcs->C_GetMechanismInfo(slot_id, mech_list[i], &info); if (rc != CKR_OK) break; } if (rc != CKR_OK) testcase_fail("C_GetMechanismInfo rc=%s", p11_get_ckr(rc)); else testcase_pass("C_GetMechanismInfo was successful."); testcase_cleanup: if (mech_list) free(mech_list); testcase_user_logout(); if ((funcs->C_CloseSession(session)) != CKR_OK) testcase_error("C_CloseSessions rc=%s", p11_get_ckr(rc)); return rc; }
CK_RV do_InitToken(void) { CK_BYTE label[32]; int len; CK_CHAR so_pin[PKCS11_MAX_PIN_LEN]; CK_RV rc = 0; testcase_begin("testing C_InitToken"); memcpy(label, "L13 ", 32); for (len = 0; len < 31;len++) { if (label[len] == '\0') { label[len] = ' '; break; } } testcase_new_assertion(); /* test with invalid SO PIN */ rc = funcs->C_InitToken(SLOT_ID, NULL, strlen((char *)so_pin), label); if (rc != CKR_ARGUMENTS_BAD) { testcase_fail("C_InitToken returned %s instead of " "CKR_ARGUMENTS_BAD", p11_get_ckr(rc)); goto testcase_cleanup; } else testcase_pass("C_InitToken correctly return CKR_ARGUMENS_BAD."); /* test with invalid slot id */ testcase_new_assertion(); rc = funcs->C_InitToken(99, so_pin, strlen((char *)so_pin), label); if (rc != CKR_SLOT_ID_INVALID) { testcase_fail("C_InitToken returned %s instead of " "CKR_SLOT_ID_INVALID.", p11_get_ckr(rc)); rc = CKR_FUNCTION_FAILED; } else { testcase_pass("C_InitToken correctly returned CKR_SLOT_ID_INVALID."); rc = CKR_OK; } testcase_cleanup: return rc; }
CK_RV do_GetTokenInfo(void) { CK_FLAGS flags; CK_SESSION_HANDLE session; CK_RV rc = 0; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_SLOT_ID slot_id = SLOT_ID; CK_TOKEN_INFO info; testcase_begin("testing C_GetTokenInfo()"); testcase_rw_session(); testcase_user_login(); testcase_new_assertion(); rc = funcs->C_GetTokenInfo(slot_id, &info); if (rc != CKR_OK) { testcase_fail("C_GetTokenInfo rc=%s", p11_get_ckr(rc)); return rc; } else testcase_pass("C_GetTokenInfo returned successfully"); /* Test with an invalid slot id */ testcase_new_assertion(); rc = funcs->C_GetTokenInfo(999, &info); if (rc != CKR_SLOT_ID_INVALID) { testcase_fail("C_GetTokenInfo() rc = %s", p11_get_ckr(rc)); goto testcase_cleanup; } testcase_pass("C_GetTokenInfo returned error when given invalid slot."); testcase_cleanup: testcase_user_logout(); if ((funcs->C_CloseSession(session)) != CKR_OK) testcase_error("C_CloseSessions failed."); return rc; }
/** Tests triple DES encryption & decryption using generated keys **/ CK_RV do_EncryptDecryptDES3(struct generated_test_suite_info *tsuite) { int j; CK_BYTE original[BIG_REQUEST]; CK_BYTE crypt[BIG_REQUEST + DES3_BLOCK_SIZE]; CK_BYTE decrypt[BIG_REQUEST + DES3_BLOCK_SIZE]; CK_ULONG crypt_len, decrypt_len, original_len; CK_SLOT_ID slot_id = SLOT_ID; CK_SESSION_HANDLE session; CK_MECHANISM mech, mechkey; CK_OBJECT_HANDLE h_key; CK_FLAGS flags; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_RV rc; /** begin test **/ testcase_begin("%s Encryption/Decryption tests with key generation.", tsuite->name); testcase_rw_session(); testcase_user_login(); /** skip test if the slot does not support this mechanism **/ if (! mech_supported(slot_id, tsuite->mech.mechanism)){ testcase_skip("Slot %u doesn't support %s (%u)", (unsigned int) slot_id, mech_to_str(tsuite->mech.mechanism), (unsigned int)tsuite->mech.mechanism); goto testcase_cleanup; } /** clear buffers **/ memset(original,0,sizeof(original)); memset(crypt,0,sizeof(crypt)); memset(decrypt,0,sizeof(decrypt)); /** generate test data **/ original_len = sizeof(original); crypt_len = sizeof(crypt); decrypt_len = sizeof(decrypt); for (j=0; j < original_len; j++) original[j] = j % 255; /** set mechanism for key gen **/ mechkey = des3_keygen; /** generate key **/ rc = funcs->C_GenerateKey(session, &mechkey, NULL, 0, &h_key); if (rc != CKR_OK) { testcase_error("C_GenerateKey rc=%s", p11_get_ckr(rc)); goto error; } /** set mech for crypto **/ mech = tsuite->mech; /** initialize single encryption **/ rc = funcs->C_EncryptInit(session, &mech, h_key); if (rc != CKR_OK) { testcase_error("C_EncryptInit rc=%s", p11_get_ckr(rc)); goto error; } /** do single encryption **/ rc = funcs->C_Encrypt(session, original, original_len, crypt, &crypt_len); if (rc != CKR_OK) { testcase_error("C_Encrypt rc=%s", p11_get_ckr(rc)); goto error; } /** initialize single decryption **/ rc = funcs->C_DecryptInit(session, &mech, h_key); if (rc != CKR_OK) { testcase_error("C_DecryptInit rc=%s", p11_get_ckr(rc)); goto error; } /** do single decryption **/ rc = funcs->C_Decrypt(session, crypt, crypt_len, decrypt, &decrypt_len); if (rc != CKR_OK) { testcase_error("C_Decrypt rc=%s", p11_get_ckr(rc)); goto error; } /** compare encryption/decryption results with expected results. **/ testcase_new_assertion(); if (decrypt_len != original_len) { testcase_fail("decrypted data length does not match original data " "length.\nexpected length=%ld, but found length=%ld\n", original_len, decrypt_len); } else if(memcmp(decrypt, original, original_len)){ testcase_fail("decrypted data does not match original data"); } else { testcase_pass("%s Encryption/Decryption test passed.", tsuite->name); } /** clean up **/ rc = funcs->C_DestroyObject(session, h_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject rc=%s", p11_get_ckr(rc)); } goto testcase_cleanup; error: rc = funcs->C_DestroyObject(session, h_key); if (rc != CKR_OK) testcase_error("C_DestroyObject rc=%s.", p11_get_ckr(rc)); testcase_cleanup: testcase_user_logout(); rc = funcs->C_CloseAllSessions(slot_id); if (rc != CKR_OK) { testcase_error("C_CloseAllSessions rc=%s", p11_get_ckr(rc)); } return rc; }
/** Tests triple DES decryption with published test vectors. **/ CK_RV do_DecryptDES3(struct published_test_suite_info *tsuite) { int i; // test vector index CK_BYTE expected[BIG_REQUEST]; // decrypted data CK_BYTE actual[BIG_REQUEST]; // decryption buffer CK_ULONG expected_len, actual_len; CK_SLOT_ID slot_id = SLOT_ID; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_SESSION_HANDLE session; CK_MECHANISM mech; CK_OBJECT_HANDLE h_key; CK_RV rc; CK_FLAGS flags; /** begin testsuite **/ testsuite_begin("%s Decryption.", tsuite->name); testcase_rw_session(); testcase_user_login(); /** skip test if the slot does not support this mechanism **/ if (! mech_supported(slot_id, tsuite->mechanism)){ testsuite_skip( tsuite->tvcount, "Slot %u doesn't support %s (%u)", (unsigned int) slot_id, mech_to_str(tsuite->mechanism), (unsigned int)tsuite->mechanism ); goto testcase_cleanup; } /** iterate over test vectors **/ for (i = 0; i < tsuite->tvcount; i++){ /** begin test **/ testcase_begin( "%s Decryption with test vector %d.", tsuite->name, i ); rc = CKR_OK; // set rc /** clear buffers **/ memset(expected, 0, sizeof(expected)); memset(actual, 0, sizeof(actual)); /** get plaintext (expected result) **/ expected_len = tsuite->tv[i].plen; memcpy(expected, tsuite->tv[i].plaintext, expected_len); /** get ciphertext **/ actual_len = tsuite->tv[i].clen; memcpy(actual, tsuite->tv[i].ciphertext, actual_len); /** get mechanism **/ mech.mechanism = tsuite->mechanism; mech.ulParameterLen = tsuite->tv[i].ivlen; mech.pParameter = tsuite->tv[i].iv; /** create key handle. **/ rc = create_DES3Key( session, tsuite->tv[i].key, tsuite->tv[i].klen, &h_key); if (rc != CKR_OK) { testcase_error("C_CreateObject rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } /** initialize single (in-place) decryption **/ rc = funcs->C_DecryptInit(session, &mech, h_key); if (rc != CKR_OK) { testcase_error("C_DecryptInit rc=%s", p11_get_ckr(rc)); goto error; } /** do single (in-place) decryption **/ rc = funcs->C_Decrypt( session, actual, actual_len, actual, &actual_len ); if (rc != CKR_OK){ testcase_error("C_Decrypt rc=%s", p11_get_ckr(rc)); goto error; } /** compare decryption results with expected results. **/ testcase_new_assertion(); if (actual_len != expected_len) { testcase_fail("decrypted data length does not match " "test vector's decrypted data length.\nexpected length=" "%ld, but found length=%ld\n", expected_len, actual_len ); } else if (memcmp(actual, expected, expected_len)) { testcase_fail( "decrypted data does not match test " "vector's decrypted data.\n" ); } else { testcase_pass( "%s Decryption with test vector %d " "passed.", tsuite->name, i ); } /** clean up **/ rc = funcs->C_DestroyObject(session, h_key); if (rc != CKR_OK) { testcase_error( "C_DestroyObject rc=%s.", p11_get_ckr(rc) ); goto testcase_cleanup; } } goto testcase_cleanup; error: rc = funcs->C_DestroyObject(session, h_key); if (rc != CKR_OK) testcase_error("C_DestroyObject rc=%s", p11_get_ckr(rc)); testcase_cleanup: testcase_user_logout(); rc = funcs->C_CloseAllSessions(slot_id); if (rc != CKR_OK) { testcase_error("C_CloseAllSessions rc=%s", p11_get_ckr(rc)); } return rc; }
CK_RV do_EncryptDecryptAES(struct generated_test_suite_info *tsuite) { int i; CK_BYTE original[BIG_REQUEST]; CK_BYTE crypt[BIG_REQUEST + AES_BLOCK_SIZE]; CK_BYTE decrypt[BIG_REQUEST + AES_BLOCK_SIZE]; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG j; CK_ULONG user_pin_len; CK_ULONG orig_len, crypt_len, decrypt_len; CK_SESSION_HANDLE session; CK_MECHANISM mechkey, mech; CK_OBJECT_HANDLE h_key; CK_FLAGS flags; CK_RV rc = 0; CK_SLOT_ID slot_id = SLOT_ID; testsuite_begin("%s Encryption/Decryption.",tsuite->name); testcase_rw_session(); testcase_user_login(); /** skip tests if the slot doesn't support this mechanism **/ if (! mech_supported(slot_id, tsuite->mech.mechanism)){ testsuite_skip(3, "Slot %u doesn't support %u", (unsigned int) slot_id, (unsigned int) tsuite->mech.mechanism); goto testcase_cleanup; } /** iterate over test key sizes **/ for (i = 0; i < 3; i++) { testcase_begin("%s Encryption/Decryption with key len=%ld.", tsuite->name, key_lens[i]); /** generate key **/ mechkey = aes_keygen; rc = generate_AESKey(session, key_lens[i], &mechkey, &h_key); if (rc != CKR_OK) { testcase_error("C_GenerateKey rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } /** clear buffers **/ memset(original,0,sizeof(original)); memset(crypt,0,sizeof(crypt)); memset(decrypt,0,sizeof(decrypt)); /** generate data **/ orig_len = sizeof(original); for (j=0; j < orig_len; j++) original[j] = j % 255; /** set crypto mech **/ mech = tsuite->mech; /** single encryption **/ rc = funcs->C_EncryptInit(session, &mech, h_key); if (rc != CKR_OK) { testcase_error("C_EncryptInit rc=%s", p11_get_ckr(rc)); goto error; } crypt_len = sizeof(crypt); rc = funcs->C_Encrypt(session, original, orig_len, crypt, &crypt_len); if (rc != CKR_OK) { testcase_error("C_Encrypt rc=%s", p11_get_ckr(rc)); goto error; } /** single decryption **/ rc = funcs->C_DecryptInit(session, &mech, h_key); if (rc != CKR_OK) { testcase_error("C_DecryptInit rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } decrypt_len = sizeof(decrypt); rc = funcs->C_Decrypt(session, crypt, crypt_len, decrypt, &decrypt_len); if (rc != CKR_OK) { testcase_error("C_Decrypt rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } /** compare actual results with expected results **/ testcase_new_assertion(); if (decrypt_len != orig_len) { testcase_fail("decrypted data length does not " "match original data length.\nexpected " "length=%ld, but found length=%ld\n", orig_len, decrypt_len); } else if (memcmp(decrypt, original, orig_len)){ testcase_fail("decrypted data does not match " "original data"); } else { testcase_pass("%s Encryption/Decryption with " "key length %ld passed.", tsuite->name, key_lens[i]); } } /** clean up **/ rc = funcs->C_DestroyObject(session, h_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject rc=%s", p11_get_ckr(rc)); } goto testcase_cleanup; error: rc = funcs->C_DestroyObject(session, h_key); if (rc != CKR_OK) testcase_error("C_DestroyObject rc=%s.", p11_get_ckr(rc)); testcase_cleanup: testcase_user_logout(); rc = funcs->C_CloseAllSessions(slot_id); if (rc != CKR_OK) { testcase_error("C_CloseAllSessions rc=%s", p11_get_ckr(rc)); } return rc; }
/** Tests messge digest with published test vectors. **/ CK_RV do_Digest(struct digest_test_suite_info *tsuite) { int i; CK_BYTE data[MAX_DATA_SIZE]; CK_ULONG data_len; CK_BYTE actual[MAX_HASH_SIZE]; CK_ULONG actual_len; CK_BYTE expected[MAX_HASH_SIZE]; CK_ULONG expected_len; CK_MECHANISM mech; CK_SESSION_HANDLE session; CK_SLOT_ID slot_id = SLOT_ID; CK_ULONG flags; CK_RV rc; /** begin test suite **/ testsuite_begin("%s Digest.", tsuite->name); testcase_rw_session(); /** skip test if mech is not supported with this slot **/ if (! mech_supported(slot_id, tsuite->mech.mechanism)) { testsuite_skip(tsuite->tvcount, "mechanism %s is not supported with slot %ld", tsuite->name, slot_id); goto testcase_cleanup; } /** iterate over test vectors **/ for(i = 0; i < tsuite->tvcount; i++) { rc = CKR_OK; // set rc /** clear buffers **/ memset(data, 0, sizeof(data)); memset(actual, 0, sizeof(actual)); memset(expected, 0, sizeof(expected)); /** get test vector info **/ data_len = tsuite->tv[i].data_len; expected_len = tsuite->tv[i].hash_len; memcpy(data, tsuite->tv[i].data, data_len); memcpy(expected, tsuite->tv[i].hash, expected_len); /** get mech **/ mech = tsuite->mech; /** initialize single digest **/ rc = funcs->C_DigestInit(session, &mech); if (rc != CKR_OK) { testcase_error("C_DigestInit rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } actual_len = sizeof(actual); // set digest buffer size /** do single digest **/ rc = funcs->C_Digest(session, data, data_len, actual, &actual_len); if (rc != CKR_OK) { testcase_error("C_Digest rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } /** compare digest results with expected results **/ testcase_new_assertion(); if (actual_len != expected_len) { testcase_fail("hashed data length does not match test vector's" " hashed data length.\nexpected length=%ld, found " "length=%ld.", expected_len, actual_len); } else if (memcmp(actual, expected, expected_len)) { testcase_fail("hashed data does not match test vector's" " hashed data."); } else { testcase_pass("%s Digest with test vector %d passed.", tsuite->name, i); } } testcase_cleanup: rc = funcs->C_CloseAllSessions(slot_id); if (rc != CKR_OK) { testcase_error("C_CloseAllSessions rc=%s", p11_get_ckr(rc)); } return rc; }
/* API Routines exercised that take /var/lock/LCK..opencryptoki spinlock. * C_OpenSession * C_CloseSession * * API routines exercised that result in stdll taking * /var/lock/opencryptoki_stdll spinlock. * C_CreateObject * C_GetAttributeValue * C_SetAttributeValue * * 1) create a certificate object with no CKA_SERIAL_NUMBER or CKA_ISSUER * 2) add CKA_SERIAL_NUMBER and CKA_ISSUER and modify CKA_ID. * verify this works. * 3) try to modify CKA_VALUE and CKA_ID in a single call to * C_SetAttributeValue. verify that this fails correctly and that * the object is not modified. */ CK_RV do_SetAttributeValues(void) { CK_SLOT_ID slot_id; CK_FLAGS flags; CK_SESSION_HANDLE h_session; CK_RV rc = 0, loc_rc = 0; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_BYTE true = TRUE; CK_OBJECT_HANDLE h_cert; CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE; CK_CERTIFICATE_TYPE cert_type = CKC_X_509; CK_BYTE cert_subject[] = "Certificate subject"; CK_BYTE cert_id[] = "Certificate ID"; CK_BYTE cert_value[] = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"; CK_ATTRIBUTE cert_attribs[] = { {CKA_CLASS, &cert_class, sizeof(cert_class) }, {CKA_TOKEN, &true, sizeof(true) }, {CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type) }, {CKA_SUBJECT, &cert_subject, sizeof(cert_subject) }, {CKA_ID, &cert_id, sizeof(cert_id) }, {CKA_VALUE, &cert_value, sizeof(cert_value) } }; CK_BYTE cert_id2[] = "New ID"; CK_BYTE cert_issuer[] = "Certificate Issuer"; CK_BYTE cert_ser_no[] = "Serial Number: 12345"; CK_ATTRIBUTE update_attr[] = { {CKA_SERIAL_NUMBER, &cert_ser_no, sizeof(cert_ser_no) }, {CKA_ISSUER, &cert_issuer, sizeof(cert_issuer) }, {CKA_ID, &cert_id2, sizeof(cert_id2) } }; CK_BYTE cert_value2[] = "Invalid Value"; CK_BYTE cert_id3[] = "ID #3"; CK_ATTRIBUTE invalid_attr[] = { {CKA_VALUE, &cert_value2, sizeof(cert_value2) }, {CKA_ID, &cert_id3, sizeof(cert_id3) } }; testcase_begin("starting..."); if (get_user_pin(user_pin)) return CKR_FUNCTION_FAILED; user_pin_len = (CK_ULONG)strlen((char *)user_pin); slot_id = SLOT_ID; /* create a USER R/W session */ flags = CKF_SERIAL_SESSION | CKF_RW_SESSION; rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &h_session); if (rc != CKR_OK) { testcase_fail("C_OpenSession() rc = %s", p11_get_ckr(rc)); return rc; } rc = funcs->C_Login(h_session, CKU_USER, user_pin, user_pin_len); if (rc != CKR_OK) { testcase_fail("C_Login() rc = %s", p11_get_ckr(rc)); return rc; } /* create the object */ rc = funcs->C_CreateObject(h_session, cert_attribs, 6, &h_cert); if (rc != CKR_OK) { testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc)); return rc; } /* Add CKA_SERIAL_NUMBER and CKA_ISSUER and change the * existing CKA_ID */ rc = funcs->C_SetAttributeValue(h_session, h_cert, update_attr, 3); if (rc != CKR_OK) { testcase_fail("C_SetAttributeValue() rc = %s", p11_get_ckr(rc)); goto done; } else { CK_BYTE buf1[100]; CK_BYTE buf2[100]; CK_BYTE buf3[100]; CK_ATTRIBUTE check1[] = { {CKA_ISSUER, &buf1, sizeof(buf1)}, {CKA_SERIAL_NUMBER, &buf2, sizeof(buf2)}, {CKA_ID, &buf3, sizeof(buf3)} }; rc = funcs->C_GetAttributeValue(h_session, h_cert, (CK_ATTRIBUTE *)&check1, 3); if (rc != CKR_OK) { testcase_fail("C_GetAttributeValue() rc = %s", p11_get_ckr(rc)); goto done; } if (memcmp(check1[0].pValue, cert_issuer, check1[0].ulValueLen) != 0) { testcase_fail("CKA_ISSUER mismatch"); rc = -1; goto done; } if (memcmp(check1[1].pValue, cert_ser_no, check1[1].ulValueLen) != 0) { testcase_fail("CKA_SERIAL_NUMBER mismatch"); return -1; } if (memcmp(check1[2].pValue, cert_id2, check1[2].ulValueLen) != 0) { testcase_fail("CKA_ID mismatch"); rc = -1; goto done; } } /* the next template tries to update a CK_ID (valid) and * CKA_VALUE (read-only). the entire operation should fail -- no * attributes should get modified */ rc = funcs->C_SetAttributeValue(h_session, h_cert, invalid_attr, 2); if (rc != CKR_ATTRIBUTE_READ_ONLY) { testcase_fail("C_SetAttributeValue() rc = %s (expected CKR_ATTRIBUTE_READ_ONLY)", p11_get_ckr(rc)); goto done; } else { CK_BYTE buf1[100]; CK_ATTRIBUTE check1[] = { {CKA_ID, &buf1, sizeof(buf1)} }; rc = funcs->C_GetAttributeValue(h_session, h_cert, check1, 1); if (rc != CKR_OK) { testcase_fail("C_GetAttributeValue() rc = %s", p11_get_ckr(rc)); goto done; } if (memcmp(check1[0].pValue, cert_id2, check1[0].ulValueLen) != 0) { testcase_fail("CKA_ID mismatch"); rc = -1; goto done; } } testcase_pass("Looks okay..."); done: /* now destroy the objects but don't clobber rc */ loc_rc = funcs->C_DestroyObject(h_session, h_cert); if (loc_rc != CKR_OK) testcase_error("C_DestroyObject() loc_rc = %s", p11_get_ckr(loc_rc)); /* done...close the session */ loc_rc = funcs->C_CloseAllSessions(slot_id); if (loc_rc != CKR_OK) testcase_error("C_CloseAllSessions() loc_rc = %s", p11_get_ckr(loc_rc)); return rc; }
/* API Routines exercised that take /var/lock/LCK..opencryptoki spinlock. * C_OpenSession * C_CloseSession * * API routines exercised that result in stdll taking * /var/lock/opencryptoki_stdll spinlock. * C_CreateObject * C_CopyObject * C_DestroyObject * C_GetAttributeValue * C_GetObjectSize * * 1) create a data object with no CKA_APPLICATION attribute * 2) create a copy of the object specifying the CKA_APPLICATION attribute * 3) extract the CK_VALUE attribute from the copy. Ensure matches the original * 4) extract the CKA_APPLICATION attribute from the original. ensure empty. * 5) extract the CKA_APPLICATION attribute from the copy. ensure is correct. * 6) attempt to extract CK_PRIME from the original. ensure fails correctly. * 7) attempt to extract CK_PRIME from a non-existant object. ensure fails * correctly. * 8) get the size of the original object and copied objects * 9) destroy the original object. ensure this succeeds. * A) destroy a non-existant object. ensure this fails correctly. * B) get the size of the original object. ensure this fails correctly. */ CK_RV do_CopyObject(void) { CK_SLOT_ID slot_id; CK_FLAGS flags; CK_SESSION_HANDLE h_session; CK_RV rc = 0, loc_rc = 0; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_ULONG obj_size; CK_BYTE true = TRUE; CK_OBJECT_HANDLE h_data; CK_OBJECT_CLASS data_class = CKO_DATA; CK_BYTE data_application[] = "Test Application"; CK_BYTE data_value[] = "1234567890abcedfghijklmnopqrstuvwxyz"; CK_ATTRIBUTE data_attribs[] = { {CKA_CLASS, &data_class, sizeof(data_class) }, {CKA_TOKEN, &true, sizeof(true) }, {CKA_VALUE, &data_value, sizeof(data_value) } }; CK_OBJECT_HANDLE h_copy; CK_ATTRIBUTE copy_attribs[] = { {CKA_APPLICATION, &data_application, sizeof(data_application) } }; CK_BYTE buf1[100]; CK_ATTRIBUTE verify_attribs[] = { {CKA_APPLICATION, &buf1, sizeof(buf1) } }; CK_BYTE buf2[100]; CK_ATTRIBUTE prime_attribs[] = { {CKA_PRIME, &buf2, sizeof(buf2) } }; testcase_begin("starting..."); if (get_user_pin(user_pin)) return CKR_FUNCTION_FAILED; user_pin_len = (CK_ULONG)strlen((char *)user_pin); slot_id = SLOT_ID; /* create a USER R/W session */ flags = CKF_SERIAL_SESSION | CKF_RW_SESSION; rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &h_session); if (rc != CKR_OK) { testcase_fail("C_OpenSession() rc = %s", p11_get_ckr(rc)); return rc; } rc = funcs->C_Login(h_session, CKU_USER, user_pin, user_pin_len); if (rc != CKR_OK) { testcase_fail("C_Login() rc = %s", p11_get_ckr(rc)); return rc; } /* create the object */ rc = funcs->C_CreateObject(h_session, data_attribs, 3, &h_data); if (rc != CKR_OK) { testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc)); return rc; } /* create the copy */ rc = funcs->C_CopyObject(h_session, h_data, copy_attribs, 1, &h_copy); if (rc != CKR_OK) { testcase_fail("C_CopyObject() rc = %s", p11_get_ckr(rc)); goto destroy_1; } /* now, try to extract the CKA_APPLICATION attribute from the original * this will pull in the token's default value for CKA_APPLICATION which */ verify_attribs[0].ulValueLen = sizeof(buf1); rc = funcs->C_GetAttributeValue(h_session, h_data, verify_attribs, 1); if (rc != CKR_OK) { testcase_fail("C_GetAttributeValue() rc=%s", p11_get_ckr(rc)); goto destroy; } /* now, try to extract the CKA_APPLICATION attribute from the copy */ verify_attribs[0].ulValueLen = sizeof(buf1); rc = funcs->C_GetAttributeValue(h_session, h_copy, verify_attribs, 1); if (rc != CKR_OK) { testcase_fail("C_GetAttributeValue() rc=%s", p11_get_ckr(rc)); goto destroy; } if (memcmp(&data_application, verify_attribs[0].pValue, sizeof(data_application)) != 0) { testcase_fail("extracted attribute doesn't match"); rc = -1; goto destroy; } /* now, try to extract CKA_PRIME from the original. * this should not exist */ prime_attribs[0].ulValueLen = sizeof(buf2); rc = funcs->C_GetAttributeValue(h_session, h_data, prime_attribs, 1); if (rc != CKR_ATTRIBUTE_TYPE_INVALID) { testcase_fail("C_GetAttributeValue() rc = %s (expected CKR_ATTRIBUTE_TYPE_INVALID)", p11_get_ckr(rc)); goto destroy; } /* now, try to extract CKA_PRIME from a bogus object handle. * this should not exist */ rc = funcs->C_GetAttributeValue(h_session, 98765, prime_attribs, 1); if (rc != CKR_OBJECT_HANDLE_INVALID) { testcase_fail("C_GetAttributeValue() rc = %s (expected CKR_OBJECT_HANDLE_INVALID)", p11_get_ckr(rc)); goto destroy; } /* now, get the size of the original object */ rc = funcs->C_GetObjectSize(h_session, h_data, &obj_size); if (rc != CKR_OK) { testcase_fail("C_GetObjectSize() rc = %s", p11_get_ckr(rc)); goto destroy; } testcase_pass("Looks okay..."); destroy: /* now, destroy the original object and the copy */ loc_rc = funcs->C_DestroyObject(h_session, h_copy); if (loc_rc != CKR_OK) testcase_error("C_DestroyObject() loc_rc = %s", p11_get_ckr(loc_rc)); destroy_1: loc_rc = funcs->C_DestroyObject(h_session, h_data); if (loc_rc != CKR_OK) testcase_error("C_DestroyObject() loc_rc = %s", p11_get_ckr(loc_rc)); loc_rc = funcs->C_CloseAllSessions(slot_id); if (loc_rc != CKR_OK) testcase_error("C_CloseAllSessions() loc_rc=%s", p11_get_ckr(loc_rc)); return rc; }
CK_RV do_SetPIN(void) { CK_SLOT_ID slot_id; CK_FLAGS flags; CK_SESSION_HANDLE session; CK_CHAR old_pin[PKCS11_MAX_PIN_LEN]; CK_CHAR new_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG old_len; CK_ULONG new_len; CK_RV rc; testcase_begin("Testing C_SetPIN"); // first, try to get the user PIN if (get_user_pin(old_pin)) return CKR_FUNCTION_FAILED; old_len = (CK_ULONG)strlen((char *)old_pin); memcpy(new_pin, "ABCDEF", 6); new_len = 6; slot_id = SLOT_ID; /* try to call C_SetPIN from a R/O public session, it should fail. */ flags = CKF_SERIAL_SESSION; testcase_new_assertion(); rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &session); if (rc != CKR_OK) { testcase_error("C_OpenSession #1 rc=%s", p11_get_ckr(rc)); return rc; } rc = funcs->C_SetPIN(session, old_pin, old_len, new_pin, new_len); if (rc != CKR_SESSION_READ_ONLY) { testcase_fail("C_SetPIN #1 returned %s instead of " "CKR_SESSION_READ_ONLY.", p11_get_ckr(rc)); rc = CKR_FUNCTION_FAILED; goto testcase_cleanup; } else testcase_pass("C_SetPIN successful in pubic session."); if (funcs->C_CloseSession(session) != CKR_OK) { testcase_error("C_CloseSession #1 failed."); goto testcase_cleanup; } /* try to call C_SetPIN from a R/W public session, it should work. */ flags = CKF_SERIAL_SESSION | CKF_RW_SESSION; rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &session); if (rc != CKR_OK) { testcase_error("C_OpenSession #1 rc=%s", p11_get_ckr(rc)); return rc; } rc = funcs->C_SetPIN(session, old_pin, old_len, new_pin, new_len); if (rc != CKR_OK) { testcase_fail("C_SetPIN failed: rc = %s", p11_get_ckr(rc)); } else testcase_pass("C_SetPIN successful in r/w pubic session."); if (funcs->C_CloseSession(session) != CKR_OK) { testcase_error("C_CloseSession #1 failed."); goto testcase_cleanup; } if (rc != CKR_OK) // above C_SetPIN failed so leave goto testcase_cleanup; /* open a new session and try logging in with new pin */ flags = CKF_SERIAL_SESSION | CKF_RW_SESSION; rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &session); if (rc != CKR_OK) { testcase_error("C_OpenSession #1 rc=%s", p11_get_ckr(rc)); return rc; } testcase_new_assertion(); rc = funcs->C_Login(session, CKU_USER, new_pin, new_len); if (rc != CKR_OK) { testcase_fail("C_Login #1 failed: rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } else testcase_pass("Successfully logged in with new pin."); /* try to call C_SetPIN from a normal user session, r/w user. * set back to original user pin. this should work. */ testcase_new_assertion(); rc = funcs->C_SetPIN(session, new_pin, new_len, old_pin, old_len); if (rc != CKR_OK) testcase_fail("C_SetPIN #2 rc=%s", p11_get_ckr(rc)); else testcase_pass("C_SetPIN successful."); if ((funcs->C_Logout(session)) != CKR_OK) { testcase_error("C_Logout #1 falied: rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } if (rc != CKR_OK) // above C_SetPIN failed. goto testcase_cleanup; /* * done with user tests...now try with the SO */ if (get_so_pin(old_pin)) return CKR_FUNCTION_FAILED; /* try to call C_SetPIN from a normal user session */ testcase_new_assertion(); rc = funcs->C_Login(session, CKU_SO, old_pin, old_len); if (rc != CKR_OK) { testcase_error("C_Login #3failed: rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } rc = funcs->C_SetPIN(session, old_pin, old_len, new_pin, new_len); if (rc != CKR_OK) testcase_fail("C_SetPIN #4 failed: rc=%s", p11_get_ckr(rc)); else testcase_pass("C_SetPIN successfully set SO PIN."); if ((funcs->C_Logout(session)) != CKR_OK) { testcase_error("C_Logout #3 failed."); goto testcase_cleanup; } if (rc != CKR_OK) // above C_SetPIN failed goto testcase_cleanup; /* now login with new pin. should work. */ testcase_new_assertion(); rc = funcs->C_Login(session, CKU_SO, new_pin, new_len); if (rc != CKR_OK) { testcase_fail("C_Login #5 failed: rc=%s", p11_get_ckr(rc)); } else testcase_pass("C_Login #5 was successful."); /* change the PIN back to the original so the rest of this program * doesn't break */ if (funcs->C_SetPIN(session, new_pin, new_len, old_pin, old_len) != CKR_OK) testcase_error("C_SetPIN #5 failed to set back to the original " "SO PIN, rc=%s", p11_get_ckr(rc)); if ((funcs->C_Logout(session)) != CKR_OK) testcase_error("C_Logout #4 failed."); testcase_cleanup: if (funcs->C_CloseSession(session) != CKR_OK) testcase_error("C_CloseSession #1 failed."); return rc; }
CK_RV do_GetSlotList(void) { CK_FLAGS flags; CK_SESSION_HANDLE session; CK_RV rc = 0; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_BBOOL tokenPresent; CK_SLOT_ID_PTR pSlotList = NULL; CK_ULONG ulCount = 0; tokenPresent = TRUE; testcase_begin("testing C_GetSlotList"); testcase_rw_session(); testcase_user_login(); testcase_new_assertion(); /* pkcs#11v2.20, Section 11.5 * If pSlotList is NULL_PTR, then all that C_GetSlotList does is * return (in *pulCount) the number of slots, without actually * returning a list of slots. */ rc = funcs->C_GetSlotList(tokenPresent, NULL, &ulCount); if (rc != CKR_OK) { testcase_fail("C_GetSlotList rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } if (ulCount) testcase_pass("C_GetSlotList received slot count."); else testcase_fail("C_GetSlotList did not receive slot count."); pSlotList = (CK_SLOT_ID *)malloc(ulCount * sizeof(CK_SLOT_ID)); if (!pSlotList) { testcase_error("malloc failed to allocate memory for list\n"); rc = CKR_HOST_MEMORY; goto testcase_cleanup; } testcase_new_assertion(); /* Get the slots */ rc = funcs->C_GetSlotList(tokenPresent, pSlotList, &ulCount); if (rc != CKR_OK) { testcase_fail("C_GetSlotList rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } testcase_pass("Slot list returned successfully"); testcase_cleanup: if (pSlotList) free(pSlotList); testcase_user_logout(); if ((funcs->C_CloseSession(session)) != CKR_OK) testcase_error("C_CloseSession failed."); return rc; }
CK_RV do_InitPIN(void) { CK_SLOT_ID slot_id; CK_FLAGS flags; CK_SESSION_HANDLE session; CK_CHAR so_pin[PKCS11_MAX_PIN_LEN]; CK_CHAR user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG so_pin_len; CK_ULONG user_pin_len; CK_RV rc; testcase_begin("Testing C_InitPIN"); if (get_user_pin(user_pin)) return CKR_FUNCTION_FAILED; user_pin_len = (CK_ULONG)strlen((char *)user_pin); if (get_so_pin(so_pin)) return CKR_FUNCTION_FAILED; so_pin_len = (CK_ULONG)strlen((char *)so_pin); slot_id = SLOT_ID; flags = CKF_SERIAL_SESSION | CKF_RW_SESSION; // try to call C_InitPIN from a public session testcase_new_assertion(); rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &session); if (rc != CKR_OK) { testcase_error("C_OpenSession rc=%s", p11_get_ckr(rc)); return rc; } rc = funcs->C_InitPIN(session, user_pin, user_pin_len); if (rc != CKR_USER_NOT_LOGGED_IN) { testcase_fail("C_InitPIN returned %s instead of " "CKR_USER_NOT_LOGGED_IN", p11_get_ckr(rc)); goto testcase_cleanup; } else testcase_pass("C_InitPin correctly returned CKR_USER_NOT_LOGGED_IN."); // try to call C_InitPIN from an SO session testcase_new_assertion(); rc = funcs->C_Login(session, CKU_SO, so_pin, so_pin_len); if (rc != CKR_OK) { testcase_error("C_Login #1 failed: rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } rc = funcs->C_InitPIN(session, user_pin, user_pin_len); if (rc != CKR_OK) testcase_fail("C_InitPIN failed: rc=%s", p11_get_ckr(rc)); else testcase_pass("C_InitPIN #1 was successful."); if ((funcs->C_Logout(session)) != CKR_OK) { testcase_error("C_Logout #1 failed."); if (rc != CKR_OK) goto testcase_cleanup; } // try to call C_InitPIN from a normal user session testcase_new_assertion(); rc = funcs->C_Login( session, CKU_USER, user_pin, user_pin_len ); if (rc != CKR_OK) { testcase_error("C_Login failed: rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } rc = funcs->C_InitPIN(session, user_pin, user_pin_len); if (rc != CKR_USER_NOT_LOGGED_IN) { testcase_fail("C_InitPIN returned %s instead of " "CKR_USER_NOT_LOGGED_IN.", p11_get_ckr(rc)); rc = CKR_FUNCTION_FAILED; } else { testcase_pass("C_InitPIN #2 was successful."); rc = CKR_OK; } if ((funcs->C_Logout(session)) != CKR_OK) testcase_error("C_Logout #2 rc=%s", p11_get_ckr(rc)); testcase_cleanup: if (funcs->C_CloseAllSessions(slot_id) != CKR_OK) testcase_error("C_CloseAllSessions #1 rc=%s", p11_get_ckr(rc)); return rc; }
CK_RV do_GetMechanismList(void) { CK_FLAGS flags; CK_SESSION_HANDLE session; CK_RV rc = 0; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_SLOT_ID slot_id = SLOT_ID; CK_ULONG count; CK_MECHANISM_TYPE *mech_list = NULL; testcase_begin("testing C_GetMechanismList"); testcase_rw_session(); testcase_user_login(); /* pkcs11v2.20, page 111 * If pMechanismList is NULL_PTR, then all that C_GetMechanismList * does is return (in *pulCount) the number of mechanisms, without * actually returning a list of mechanisms. The contents of * *pulCount on entry to C_GetMechanismList has no meaning in this * case, and the call returns the value CKR_OK. */ testcase_new_assertion(); rc = funcs->C_GetMechanismList(slot_id, NULL, &count); if (rc != CKR_OK) { testcase_fail("C_GetMechanismList 1 rc=%s",p11_get_ckr(rc)); return rc; } if (count) testcase_pass("C_GetMechanismList returned mechanism count."); else testcase_fail("C_GetMechanismList did not not return " "mechanism count."); mech_list = (CK_MECHANISM_TYPE *)malloc( count * sizeof(CK_MECHANISM_TYPE) ); if (!mech_list) { testcase_fail(); rc = CKR_HOST_MEMORY; goto testcase_cleanup; } testcase_new_assertion(); rc = funcs->C_GetMechanismList(slot_id, mech_list, &count); if (rc != CKR_OK) { testcase_fail("C_GetMechanismList 2 rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } else testcase_pass("Mechanism listing from current slot"); /* Test for invalid slot */ testcase_new_assertion(); rc = funcs->C_GetMechanismList(999, NULL, &count); if (rc != CKR_SLOT_ID_INVALID) { testcase_fail("C_GetMechanismList() returned %s instead of" " CKR_SLOT_ID_INVALID.", p11_get_ckr(rc)); rc = CKR_FUNCTION_FAILED; goto testcase_cleanup; } else { testcase_pass("C_GetMechanismList correctly returned " "CKR_SLOT_ID_INVALID."); rc = CKR_OK; } testcase_cleanup: if (mech_list) free(mech_list); testcase_user_logout(); if ((funcs->C_CloseSession(session)) != CKR_OK) testcase_error("C_CloseSessions failed."); return rc; }
/* This function should test: * C_Sign, mechanism chosen by caller * * 1. Get message from test vector * 2. Get expected signature from test vector * 3. Sign message * 4. Compare expected signature with actual signature * */ CK_RV do_SignRSA(struct PUBLISHED_TEST_SUITE_INFO *tsuite) { int i; CK_BYTE message[MAX_MESSAGE_SIZE]; CK_BYTE actual[MAX_SIGNATURE_SIZE]; CK_BYTE expected[MAX_SIGNATURE_SIZE]; CK_ULONG message_len, actual_len, expected_len; CK_MECHANISM mech; CK_OBJECT_HANDLE priv_key; CK_SLOT_ID slot_id = SLOT_ID; CK_SESSION_HANDLE session; CK_FLAGS flags; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_RV rc, loc_rc; // begin testsuite testsuite_begin("%s Sign. ", tsuite->name); testcase_rw_session(); testcase_user_login(); // skip tests if the slot doesn't support this mechanism **/ if (! mech_supported(slot_id, tsuite->mech.mechanism)){ testsuite_skip(tsuite->tvcount, "Slot %u doesn't support %u", (unsigned int) slot_id, (unsigned int) tsuite->mech.mechanism ); goto testcase_cleanup; } // iterate over test vectors for (i = 0; i < tsuite->tvcount; i++){ testcase_begin("%s Sign with test vector %d.", tsuite->name, i); rc = CKR_OK; // set return value // special case for ica // prime1, prime2, exp1, exp2, coef // must be size mod_len/2 or smaller // skip test if prime1, or prime2, or exp1, // or exp2 or coef are too long if (is_ica_token(slot_id)) { // check sizes if ((tsuite->tv[i].prime1_len > (tsuite->tv[i].mod_len/2)) || (tsuite->tv[i].prime2_len > (tsuite->tv[i].mod_len/2)) || (tsuite->tv[i].exp1_len > (tsuite->tv[i].mod_len/2)) || (tsuite->tv[i].exp2_len > (tsuite->tv[i].mod_len/2)) || (tsuite->tv[i].coef_len > (tsuite->tv[i].mod_len/2))) { testcase_skip("ICA Token cannot be used with " "this test vector."); continue; } } // clear buffers memset(message, 0, MAX_MESSAGE_SIZE); memset(actual, 0, MAX_SIGNATURE_SIZE); memset(expected, 0, MAX_SIGNATURE_SIZE); actual_len = MAX_SIGNATURE_SIZE; // set buffer size // get message message_len = tsuite->tv[i].msg_len; memcpy(message, tsuite->tv[i].msg, message_len); // get (expected) signature expected_len = tsuite->tv[i].sig_len; memcpy(expected, tsuite->tv[i].sig, expected_len); // create (private) key handle rc = create_RSAPrivateKey(session, tsuite->tv[i].mod, tsuite->tv[i].pub_exp, tsuite->tv[i].priv_exp, tsuite->tv[i].prime1, tsuite->tv[i].prime2, tsuite->tv[i].exp1, tsuite->tv[i].exp2, tsuite->tv[i].coef, tsuite->tv[i].mod_len, tsuite->tv[i].pubexp_len, tsuite->tv[i].privexp_len, tsuite->tv[i].prime1_len, tsuite->tv[i].prime2_len, tsuite->tv[i].exp1_len, tsuite->tv[i].exp2_len, tsuite->tv[i].coef_len, &priv_key); if (rc != CKR_OK) { testcase_error("create_RSAPrivateKey(), rc=%s", p11_get_ckr(rc)); goto error; } // set mechanism mech = tsuite->mech; // initialize signing rc = funcs->C_SignInit(session, &mech, priv_key); if (rc != CKR_OK) { testcase_error("C_SignInit(), rc=%s.", p11_get_ckr(rc)); goto error; } // do signing rc = funcs->C_Sign(session, message, message_len, actual, &actual_len); if (rc != CKR_OK) { testcase_error("C_Sign(), rc=%s.", p11_get_ckr(rc)); goto error; } // check results testcase_new_assertion(); if (actual_len != expected_len) { testcase_fail("%s Sign with test vector %d failed. " "Expected len=%ld, found len=%ld.", tsuite->name, i, expected_len, actual_len); } else if (memcmp(actual, expected, expected_len)) { testcase_fail("%s Sign with test vector %d failed. " "Signature data does not match test vector " "signature.", tsuite->name, i); } else { testcase_pass("C_Sign."); } // clean up rc = funcs->C_DestroyObject(session, priv_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(rc)); goto testcase_cleanup; } } goto testcase_cleanup; error: loc_rc = funcs->C_DestroyObject(session, priv_key); if (loc_rc != CKR_OK) { testcase_error("C_DestroyObject, rc=%s.", p11_get_ckr(loc_rc)); } testcase_cleanup: testcase_user_logout(); loc_rc = funcs->C_CloseAllSessions(slot_id); if (loc_rc != CKR_OK) { testcase_error("C_CloseAllSessions, rc=%s.", p11_get_ckr(rc)); } return rc; }
CK_RV do_HWFeatureSearch(void) { unsigned int i, got_it = 0; CK_RV rc, loc_rc; CK_ULONG find_count; CK_SLOT_ID slot_id; CK_BBOOL false = FALSE; CK_BBOOL true = TRUE; CK_SESSION_HANDLE h_session; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; /* A counter object */ CK_OBJECT_CLASS counter1_class = CKO_HW_FEATURE; CK_HW_FEATURE_TYPE feature1_type = CKH_MONOTONIC_COUNTER; CK_UTF8CHAR counter1_label[] = "Monotonic counter"; CK_CHAR counter1_value[16]; CK_ATTRIBUTE counter1_template[] = { {CKA_CLASS, &counter1_class, sizeof(counter1_class)}, {CKA_HW_FEATURE_TYPE, &feature1_type, sizeof(feature1_type)}, {CKA_LABEL, counter1_label, sizeof(counter1_label)-1}, {CKA_VALUE, counter1_value, sizeof(counter1_value)}, {CKA_RESET_ON_INIT, &true, sizeof(true)}, {CKA_HAS_RESET, &false, sizeof(false)} }; /* A clock object */ CK_OBJECT_CLASS clock_class = CKO_HW_FEATURE; CK_HW_FEATURE_TYPE clock_type = CKH_CLOCK; CK_UTF8CHAR clock_label[] = "Clock"; CK_CHAR clock_value[16]; CK_ATTRIBUTE clock_template[] = { {CKA_CLASS, &clock_class, sizeof(clock_class)}, {CKA_HW_FEATURE_TYPE, &clock_type, sizeof(clock_type)}, {CKA_LABEL, clock_label, sizeof(clock_label)-1}, {CKA_VALUE, clock_value, sizeof(clock_value)} }; /* A data object */ CK_OBJECT_CLASS obj1_class = CKO_DATA; CK_UTF8CHAR obj1_label[] = "Object 1"; CK_BYTE obj1_data[] = "Object 1's data"; CK_ATTRIBUTE obj1_template[] = { {CKA_CLASS, &obj1_class, sizeof(obj1_class)}, {CKA_TOKEN, &true, sizeof(true)}, {CKA_LABEL, obj1_label, sizeof(obj1_label)-1}, {CKA_VALUE, obj1_data, sizeof(obj1_data)} }; /* A secret key object */ CK_OBJECT_CLASS obj2_class = CKO_SECRET_KEY; CK_KEY_TYPE obj2_type = CKK_AES; CK_UTF8CHAR obj2_label[] = "Object 2"; CK_BYTE obj2_data[AES_KEY_SIZE_128]; CK_ATTRIBUTE obj2_template[] = { {CKA_CLASS, &obj2_class, sizeof(obj2_class)}, {CKA_TOKEN, &true, sizeof(true)}, {CKA_KEY_TYPE, &obj2_type, sizeof(obj2_type)}, {CKA_LABEL, obj2_label, sizeof(obj2_label)-1}, {CKA_VALUE, obj2_data, sizeof(obj2_data)} }; CK_OBJECT_HANDLE h_counter1, h_clock, h_obj1, h_obj2, obj_list[10]; CK_ATTRIBUTE find_tmpl[] = { {CKA_CLASS, &counter1_class, sizeof(counter1_class)} }; slot_id = SLOT_ID; testcase_begin("starting..."); if (get_user_pin(user_pin)) return CKR_FUNCTION_FAILED; user_pin_len = (CK_ULONG)strlen((char *)user_pin); /* Open a session with the token */ if( (rc = funcs->C_OpenSession(slot_id, (CKF_SERIAL_SESSION|CKF_RW_SESSION), NULL_PTR, NULL_PTR, &h_session)) != CKR_OK ) { testcase_fail("C_OpenSession() rc = %s", p11_get_ckr(rc)); return rc; } // Login correctly rc = funcs->C_Login(h_session, CKU_USER, user_pin, user_pin_len); if( rc != CKR_OK ) { testcase_fail("C_Login() rc = %s", p11_get_ckr(rc)); goto session_close; } /* Create the 3 test objects */ if( (rc = funcs->C_CreateObject(h_session, obj1_template, 4, &h_obj1)) != CKR_OK) { testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc)); goto session_close; } if( (rc = funcs->C_CreateObject(h_session, obj2_template, 5, &h_obj2)) != CKR_OK) { testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc)); goto destroy_1; } /* try and create a monotonic object. This should fail * since it is a read only feature. */ if( (rc = funcs->C_CreateObject(h_session, counter1_template, 6, &h_counter1)) != CKR_ATTRIBUTE_READ_ONLY) { testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc)); goto destroy_2; } if( (rc = funcs->C_CreateObject(h_session, clock_template, 4, &h_clock)) != CKR_OK) { testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc)); goto destroy_2; } /* Now find the hardware feature objects */ rc = funcs->C_FindObjectsInit(h_session, find_tmpl, 1 ); if (rc != CKR_OK) { testcase_fail("C_FindObjectsInit() rc = %s", p11_get_ckr(rc)); goto destroy; } rc = funcs->C_FindObjects(h_session, obj_list, 10, &find_count ); if (rc != CKR_OK) { testcase_fail("C_FindObjects() rc = %s", p11_get_ckr(rc)); goto destroy; } got_it = 0; /* Make sure we got the right ones */ for(i=0; i < find_count; i++) { if(obj_list[i] == h_clock) { got_it++; } } if (got_it != 1) { testcase_fail("could not find the corect object handle"); rc = -1; goto destroy; } rc = funcs->C_FindObjectsFinal(h_session ); if (rc != CKR_OK) { testcase_fail("C_FindObjectsFinal() rc = %s", p11_get_ckr(rc)); } testcase_pass("Looks okay..."); destroy: /* Destroy the created objects, don't clobber the rc */ loc_rc = funcs->C_DestroyObject(h_session, h_clock); if( loc_rc != CKR_OK ) testcase_error("C_DestroyObject() rc = %s", p11_get_ckr(loc_rc)); destroy_2: loc_rc = funcs->C_DestroyObject(h_session, h_obj2); if( loc_rc != CKR_OK ) testcase_error("C_DestroyObject() rc = %s", p11_get_ckr(loc_rc)); destroy_1: loc_rc = funcs->C_DestroyObject(h_session, h_obj1); if( loc_rc != CKR_OK ) testcase_error("C_DestroyObject() rc = %s", p11_get_ckr(loc_rc)); loc_rc = funcs->C_Logout(h_session); if( loc_rc != CKR_OK ) testcase_error("C_Logout() rc = %s", p11_get_ckr(loc_rc)); session_close: /* Close the session */ if( (loc_rc = funcs->C_CloseSession(h_session)) != CKR_OK ) testcase_error("C_CloseSession() rc = %s", p11_get_ckr(loc_rc)); return rc; }
/* This function should test: * RSA Key Generation, using CKM_PKCS_KEY_PAIR_GEN * RSA Public-Key Wrap * RSA Private-Key Unwrap * */ CK_RV do_WrapUnwrapRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) { int i; CK_OBJECT_HANDLE publ_key, priv_key, secret_key, unwrapped_key; CK_BYTE_PTR wrapped_key; CK_ULONG wrapped_keylen, unwrapped_keylen; CK_MECHANISM wrap_mech, keygen_mech; char *s; CK_SESSION_HANDLE session; CK_FLAGS flags; CK_SLOT_ID slot_id = SLOT_ID; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_RV rc, loc_rc; // begin test suite testsuite_begin("%s Wrap Unwrap.", tsuite->name); testcase_rw_session(); testcase_user_login(); // skip all tests if the slot doesn't support this mechanism if (! mech_supported(slot_id, tsuite->mech.mechanism)){ testsuite_skip(tsuite->tvcount, "Slot %u doesn't support %u", (unsigned int) slot_id, (unsigned int) tsuite->mech.mechanism ); goto testcase_cleanup; } // skip all tests if the slot doesn't support wrapping else if (! wrap_supported(slot_id, tsuite->mech)) { testsuite_skip(tsuite->tvcount, "Slot %u doesn't support key wrapping", (unsigned int) slot_id); goto testcase_cleanup; } // skip all tests if the slot doesn't support unwrapping else if (! unwrap_supported(slot_id, tsuite->mech)) { testsuite_skip(tsuite->tvcount, "Slot %u doesn't support key unwrapping", (unsigned int) slot_id); goto testcase_cleanup; } for (i = 0; i < tsuite->tvcount; i++) { // wrap templates & unwrap templates CK_ATTRIBUTE secret_value[] = { {CKA_VALUE, NULL, 0} }; CK_ATTRIBUTE unwrapped_value[] = { {CKA_VALUE, NULL, 0} }; CK_ULONG s_valuelen = 0; CK_ATTRIBUTE secret_value_len[] = { {CKA_VALUE_LEN, &s_valuelen, sizeof(s_valuelen)} }; CK_ULONG u_valuelen = 0; CK_ATTRIBUTE unwrapped_value_len[] = { {CKA_VALUE_LEN, &u_valuelen, sizeof(u_valuelen)} }; CK_ATTRIBUTE unwrap_tmpl[] = { {CKA_CLASS, NULL, 0}, {CKA_KEY_TYPE, NULL, 0}, {CKA_VALUE_LEN, NULL, 0} }; CK_ULONG unwrap_tmpl_len; // get public exponent from test vector if ( p11_ahex_dump(&s, tsuite->tv[i].publ_exp, tsuite->tv[i].publ_exp_len) == NULL) { testcase_error("p11_ahex_dump() failed"); rc = -1; goto testcase_cleanup; } // begin test testcase_begin("%s Wrap Unwrap with test vector %d, " "\npubl_exp='%s', mod_bits='%lu', keylen='%lu', " "keytype='%s'", tsuite->name, i, s, tsuite->tv[i].modbits, tsuite->tv[i].keylen, p11_get_ckm(tsuite->tv[i].keytype.mechanism)); // free memory free(s); // get key gen mechanism keygen_mech = tsuite->tv[i].keytype; // get wrapping mechanism wrap_mech = tsuite->mech; // skip this test if the slot doesn't support this // keygen mechanism if (! mech_supported(slot_id, keygen_mech.mechanism)) { testcase_skip(); continue; } // initialize buffer lengths wrapped_keylen = PKCS11_MAX_PIN_LEN; // generate RSA key pair rc = generate_RSA_PKCS_KeyPair(session, tsuite->tv[i].modbits, tsuite->tv[i].publ_exp, tsuite->tv[i].publ_exp_len, &publ_key, &priv_key); if (rc != CKR_OK) { testcase_error("C_GenerateKeyPair() rc = %s", p11_get_ckr(rc)); goto testcase_cleanup; } // generate secret key rc = generate_SecretKey(session, tsuite->tv[i].keylen, &keygen_mech, &secret_key); if (rc != CKR_OK) { testcase_error("generate_SecretKey(), rc=%s", p11_get_ckr(rc)); goto error; } // extract CKA_CLASS and CKA_KEY_TYPE from generated key // we will use this for unwrapping // extract sizes first rc = funcs->C_GetAttributeValue(session, secret_key, unwrap_tmpl, 2); if (rc != CKR_OK) { testcase_error("C_GetAttributeValue(), rc=%s", p11_get_ckr(rc)); goto error; } // allocate memory for extraction unwrap_tmpl[0].pValue = calloc(sizeof(CK_BYTE), unwrap_tmpl[0].ulValueLen); unwrap_tmpl[1].pValue = calloc(sizeof(CK_BYTE), unwrap_tmpl[1].ulValueLen); if ( (unwrap_tmpl[0].pValue == NULL) || (unwrap_tmpl[1].pValue == NULL) ) { testcase_error("Error allocating %lu bytes" "for unwrap template attributes", unwrap_tmpl[0].ulValueLen + unwrap_tmpl[1].ulValueLen); rc = -1; goto error; } // now extract values rc = funcs->C_GetAttributeValue(session, secret_key, unwrap_tmpl, 2); if (rc != CKR_OK) { testcase_error("C_GetAttributeValue(), rc=%s", p11_get_ckr(rc)); goto error; } // wrap key (length only) rc = funcs->C_WrapKey(session, &wrap_mech, publ_key, secret_key, NULL, &wrapped_keylen); if (rc != CKR_OK) { testcase_error("C_WrapKey(), rc=%s.", p11_get_ckr(rc)); goto error; } // allocate memory for wrapped_key wrapped_key = calloc(sizeof(CK_BYTE), wrapped_keylen); if (wrapped_key == NULL) { testcase_error("Can't allocate memory " "for %lu bytes.", sizeof(CK_BYTE) * wrapped_keylen); rc = -1; goto error; } // wrap key rc = funcs->C_WrapKey(session, &wrap_mech, publ_key, secret_key, wrapped_key, &wrapped_keylen); if (rc != CKR_OK) { testcase_error("C_WrapKey, rc=%s", p11_get_ckr(rc)); goto error; } unwrapped_keylen = tsuite->tv[i].keylen; // variable key length specific case: // According to PKCS#11 v2.2 section 12.1.12 // CKM_RSA_X_509 does not wrap the key type, key length, // or any other information about the key; the application // must convey these separately, and supply them when // unwrapping the key. if (keygen_mech.mechanism == CKM_AES_KEY_GEN) { unwrapped_keylen = tsuite->tv[i].keylen; unwrap_tmpl[2].type = CKA_VALUE_LEN; unwrap_tmpl[2].ulValueLen = sizeof(unwrapped_keylen); unwrap_tmpl[2].pValue = &unwrapped_keylen; unwrap_tmpl_len = 3; } else { unwrap_tmpl_len = 2; } // unwrap key rc = funcs->C_UnwrapKey(session, &wrap_mech, priv_key, wrapped_key, wrapped_keylen, unwrap_tmpl, unwrap_tmpl_len, &unwrapped_key); if (rc != CKR_OK) { testcase_error("C_UnwrapKey, rc=%s", p11_get_ckr(rc)); goto error; } testcase_new_assertion(); // get secret CKA_VALUE_LEN (if applicable) // then compare to expected value if (keygen_mech.mechanism == CKM_GENERIC_SECRET_KEY_GEN || keygen_mech.mechanism == CKM_RC4_KEY_GEN || keygen_mech.mechanism == CKM_RC5_KEY_GEN || keygen_mech.mechanism == CKM_AES_KEY_GEN) { rc = funcs->C_GetAttributeValue(session, secret_key, secret_value_len, 1); if (rc != CKR_OK) { testcase_error("C_GetAttributeValue(), rc=%s", p11_get_ckr(rc)); goto error; } rc = funcs->C_GetAttributeValue(session, unwrapped_key, unwrapped_value_len, 1); if (rc != CKR_OK) { testcase_error("C_GetAttributeValue(), rc=%s", p11_get_ckr(rc)); goto error; } // check results if ( * ((CK_ULONG_PTR) secret_value_len[0].pValue) != * ((CK_ULONG_PTR) unwrapped_value_len[0].pValue)) { testcase_fail("CKA_VALUE_LEN value differs " "(original %lu, unwrapped %lu)", *((CK_ULONG_PTR) secret_value_len), *((CK_ULONG_PTR) unwrapped_value_len)); goto error; } } // get size of secret key's CKA_VALUE rc = funcs->C_GetAttributeValue(session, secret_key, secret_value, 1); if (rc != CKR_OK) { testcase_error("C_GetAttributeValue(), rc=%s.", p11_get_ckr(rc)); goto error; } // get size of unwrapped key's CKA_VALUE rc = funcs->C_GetAttributeValue(session, unwrapped_key, unwrapped_value, 1); if (rc != CKR_OK) { testcase_error("C_GetAttributeValue(), rc=%s.", p11_get_ckr(rc)); goto error; } // allocate memory for extraction secret_value[0].pValue = calloc(sizeof(CK_BYTE), secret_value[0].ulValueLen); if (secret_value[0].pValue == NULL) { testcase_error("Error allocating %lu bytes " "for Secret Key Value.", secret_value[0].ulValueLen); goto error; } unwrapped_value[0].pValue = calloc(sizeof(CK_BYTE), unwrapped_value[0].ulValueLen); if (unwrapped_value[0].pValue == NULL) { testcase_error("Error allocating %lu bytes " "for Unwrapped Key Value.", unwrapped_value[0].ulValueLen); goto error; } // get secret CKA_VALUE rc = funcs->C_GetAttributeValue(session, secret_key, secret_value, 1); if (rc != CKR_OK) { testcase_error("C_GetAttributeValue(), rc=%s.", p11_get_ckr(rc)); goto error; } // get unwrapped CKA_VALUE rc = funcs->C_GetAttributeValue(session, unwrapped_key, unwrapped_value, 1); if (rc != CKR_OK) { testcase_error("C_GetAttributeValue(), rc=%s.", p11_get_ckr(rc)); goto error; } // compare secret and unwrapped CKA_VALUE if (memcmp(secret_value[0].pValue, unwrapped_value[0].pValue, secret_value[0].ulValueLen)) { testcase_fail("Unwrapped key differs in CKA_VALUE."); } else { testcase_pass("C_Wrap and C_Unwrap."); } // free memory if (unwrap_tmpl[0].pValue) { free(unwrap_tmpl[0].pValue); } if (unwrap_tmpl[1].pValue) { free(unwrap_tmpl[1].pValue); } if (secret_value[0].pValue) { free(secret_value[0].pValue); } if (unwrapped_value[0].pValue) { free(unwrapped_value[0].pValue); } if (wrapped_key) { free(wrapped_key); } // clean up rc = funcs->C_DestroyObject(session, secret_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(rc)); goto testcase_cleanup; } rc = funcs->C_DestroyObject(session, publ_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(rc)); goto testcase_cleanup; } rc = funcs->C_DestroyObject(session, priv_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(rc)); goto testcase_cleanup; } } goto testcase_cleanup; error: loc_rc = funcs->C_DestroyObject(session, secret_key); if (loc_rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc)); } loc_rc = funcs->C_DestroyObject(session, publ_key); if (loc_rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc)); } loc_rc = funcs->C_DestroyObject(session, priv_key); if (loc_rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc)); } testcase_cleanup: testcase_user_logout(); loc_rc = funcs->C_CloseAllSessions(slot_id); if (loc_rc != CKR_OK) { testcase_error("C_CloseAllSessions(), rc=%s.", p11_get_ckr(rc)); } return rc; }
/* API Routines exercised that take /var/lock/LCK..opencryptoki spinlock. * C_OpenSession * C_CloseSession * * API Routines exercised that cause stdll to take /var/lock/opencryptoki_stdll * spinlock. * C_CreateObject * C_Login * * 1) create a data object * 2) create a certificate * 3) create a key object */ CK_RV do_CreateSessionObject(void) { CK_SLOT_ID slot_id; CK_FLAGS flags; CK_SESSION_HANDLE h_session; CK_RV rc = 0; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_BYTE true = TRUE; CK_BYTE false = FALSE; CK_OBJECT_HANDLE h_data; CK_OBJECT_CLASS data_class = CKO_DATA; CK_BYTE data_application[] = "Test Application"; CK_BYTE data_value[] = "1234567890abcedfghijklmnopqrstuvwxyz"; CK_ATTRIBUTE data_attribs[] = { {CKA_CLASS, &data_class, sizeof(data_class) }, {CKA_TOKEN, &false, sizeof(false) }, {CKA_APPLICATION, &data_application, sizeof(data_application) }, {CKA_VALUE, &data_value, sizeof(data_value) } }; CK_OBJECT_HANDLE h_cert; CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE; CK_CERTIFICATE_TYPE cert_type = CKC_X_509; CK_BYTE cert_subject[] = "Certificate subject"; CK_BYTE cert_id[] = "Certificate ID"; CK_BYTE cert_value[] = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"; CK_ATTRIBUTE cert_attribs[] = { {CKA_CLASS, &cert_class, sizeof(cert_class) }, {CKA_TOKEN, &false, sizeof(false) }, {CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type) }, {CKA_SUBJECT, &cert_subject, sizeof(cert_subject) }, {CKA_ID, &cert_id, sizeof(cert_id) }, {CKA_VALUE, &cert_value, sizeof(cert_value) } }; CK_OBJECT_HANDLE h_key; CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY; CK_KEY_TYPE key_type = CKK_RSA; CK_BYTE key_modulus[] = "1234567890987654321"; CK_BYTE key_exponent[] = "123"; CK_ATTRIBUTE key_attribs[] = { {CKA_CLASS, &key_class, sizeof(key_class) }, {CKA_KEY_TYPE, &key_type, sizeof(key_type) }, {CKA_WRAP, &true, sizeof(true) }, {CKA_MODULUS, &key_modulus, sizeof(key_modulus) }, {CKA_PUBLIC_EXPONENT, &key_exponent, sizeof(key_exponent) } }; testcase_begin("starting..."); if (get_user_pin(user_pin)) return CKR_FUNCTION_FAILED; user_pin_len = (CK_ULONG)strlen((char *)user_pin); slot_id = SLOT_ID; // create a USER R/W session // flags = CKF_SERIAL_SESSION | CKF_RW_SESSION; rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &h_session); if (rc != CKR_OK) { testcase_fail("C_OpenSession() rc = %s", p11_get_ckr(rc)); return rc; } rc = funcs->C_Login(h_session, CKU_USER, user_pin, user_pin_len); if (rc != CKR_OK) { testcase_fail("C_Login() rc = %s", p11_get_ckr(rc)); return rc; } // // now, create the objects // rc = funcs->C_CreateObject(h_session, data_attribs, 4, &h_data); if (rc != CKR_OK) { testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc)); return rc; } rc = funcs->C_CreateObject(h_session, cert_attribs, 6, &h_cert); if (rc != CKR_OK) { testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc)); return rc; } rc = funcs->C_CreateObject(h_session, key_attribs, 5, &h_key); if (rc != CKR_OK) { testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc)); return rc; } // done...close the session and verify the object is deleted // rc = funcs->C_CloseAllSessions(slot_id); if (rc != CKR_OK) { testcase_fail("C_CloseAllSessions() rc=%s", p11_get_ckr(rc)); return rc; } testcase_pass("looks okay..."); return rc; }
CK_RV do_DestroyObjects(void) { CK_FLAGS flags; CK_SESSION_HANDLE session; CK_RV rc = 0; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_OBJECT_HANDLE keyobj[8]; CK_OBJECT_HANDLE obj_list[10]; CK_ULONG i, num_objs=0, find_count, found=0; CK_MECHANISM mech; CK_BBOOL true = TRUE; CK_KEY_TYPE aes_type = CKK_AES; CK_OBJECT_CLASS key_class = CKO_SECRET_KEY; CK_CHAR aes_value[] = "This is a fake aes key."; CK_CHAR test_id[5] = "abcde"; CK_ULONG aesgen_keylen = 32; CK_ATTRIBUTE aes_tmpl[] = { {CKA_CLASS, &key_class, sizeof(key_class)}, {CKA_KEY_TYPE, &aes_type, sizeof(aes_type)}, {CKA_ID, &test_id, sizeof(test_id)}, {CKA_VALUE, &aes_value, sizeof(aes_value)} }; CK_ATTRIBUTE aesgen_tmpl[] = { {CKA_CLASS, &key_class, sizeof(key_class)}, {CKA_KEY_TYPE, &aes_type, sizeof(aes_type)}, {CKA_ID, &test_id, sizeof(test_id)}, {CKA_VALUE_LEN, &aesgen_keylen, sizeof(aesgen_keylen)}, {CKA_TOKEN, &true, sizeof(true)} }; CK_ATTRIBUTE find_tmpl[] = { {CKA_KEY_TYPE, &aes_type, sizeof(aes_type)}, {CKA_ID, &test_id, sizeof(test_id)} }; testcase_begin("starting..."); testcase_rw_session(); testcase_user_login(); /* Create a few session key objects */ for (i = 0; i < 4; i++) { rc = funcs->C_CreateObject(session, aes_tmpl, 4, &keyobj[num_objs]); if (rc != CKR_OK) { testcase_error("C_CreateObject() rc = %s", p11_get_ckr(rc)); goto testcase_cleanup; } num_objs++; } /* Generate a few token key objects */ mech.mechanism = CKM_AES_KEY_GEN; mech.ulParameterLen = 0; mech.pParameter = NULL; for (i = 4; i < 8; i++) { rc = funcs->C_GenerateKey(session, &mech, aesgen_tmpl, 5, &keyobj[num_objs]); if (rc != CKR_OK) { testcase_error("C_GenerateObject() rc = %s", p11_get_ckr(rc)); goto testcase_cleanup; } num_objs++; } /* Now delete 2 session key objects */ rc = funcs->C_DestroyObject(session, keyobj[7]); if (rc != CKR_OK) { testcase_fail("C_FindObjects() rc = %s", p11_get_ckr(rc)); goto testcase_cleanup; } num_objs--; rc = funcs->C_DestroyObject(session, keyobj[6]); if (rc != CKR_OK) { testcase_fail("C_FindObjects() rc = %s", p11_get_ckr(rc)); goto testcase_cleanup; } num_objs--; /* Now see if only 2 session key objects were destroyed */ rc = funcs->C_FindObjectsInit(session, find_tmpl, 2); if (rc != CKR_OK) { testcase_error("C_FindObjectsInit() rc = %s", p11_get_ckr(rc)); goto testcase_cleanup; } rc = funcs->C_FindObjects(session, obj_list, 10, &find_count); if (rc != CKR_OK) { testcase_error("C_FindObjects() rc = %s", p11_get_ckr(rc)); goto testcase_cleanup; } rc = funcs->C_FindObjectsFinal(session); if (rc != CKR_OK) { testcase_error("C_FindObjectsFinal() rc = %s", p11_get_ckr(rc)); goto testcase_cleanup; } /* Testcase 1: step thru and see if objects were deleted. */ if (find_count != 6) { testcase_fail("Did not find 6 objects!"); goto testcase_cleanup; } for (i = 0; i < find_count; i++) { if ((obj_list[i] == keyobj[6]) || (obj_list[i] == keyobj[7])) found++; } if (found) { testcase_fail("Objects were not deleted."); goto testcase_cleanup; } else testcase_pass("The 2 objects were successfully deleted."); /* Testcase 2: Now make sure the other objects are still there */ for (i = 0; i < find_count; i++) { if ((obj_list[i] == keyobj[0]) || (obj_list[i] == keyobj[1]) || (obj_list[i] == keyobj[2]) || (obj_list[i] == keyobj[3]) || (obj_list[i] == keyobj[4]) || (obj_list[i] == keyobj[5])) found++; } if (found != 6) { testcase_fail("Some Objects were not found!"); goto testcase_cleanup; } else testcase_pass("The other objects are intact."); /* Testcase 3: Remove all the objects */ find_count = 0; /* Now delete the rest of the objects */ for (i = 0; i < num_objs; i++) funcs->C_DestroyObject(session, keyobj[i]); /* Now see if all the objects were deleted. */ rc = funcs->C_FindObjectsInit(session, find_tmpl, 2); if (rc != CKR_OK) { testcase_fail("C_FindObjectsInit() rc = %s", p11_get_ckr(rc)); goto testcase_cleanup; } rc = funcs->C_FindObjects(session, obj_list, 10, &find_count); if (rc != CKR_OK) { testcase_fail("C_FindObjects() rc = %s", p11_get_ckr(rc)); goto testcase_cleanup; } rc = funcs->C_FindObjectsFinal(session); if (rc != CKR_OK) { testcase_fail("C_FindObjectsFinal() rc = %s", p11_get_ckr(rc)); goto testcase_cleanup; } if (find_count) { testcase_fail("The remaining objects were not deleted."); goto testcase_cleanup; } else testcase_pass("All objects were deleted."); testcase_cleanup: if (num_objs) { for (i = 0; i < num_objs; i++) funcs->C_DestroyObject(session, keyobj[i]); } testcase_user_logout(); rc = funcs->C_CloseSession(session); if (rc != CKR_OK) { testcase_error("C_CloseSession rc=%s", p11_get_ckr(rc)); } return rc; }
/* API Routines exercised that take /var/lock/LCK..opencryptoki spinlock. * C_OpenSession * C_CloseSession * * API routines exercised that result in stdll taking * /var/lock/opencryptoki_stdll spinlock. * C_FindObjectsInit * C_FindObjects * C_CreateObject * * 1) Create 3 certificates as PUBLIC token objects * 2) Search for a particular CKA_ID. Verify that this works. * 3) Do FindObjects with a NULL template. Verify that all 3 token objects * are found. * 4) Search for a particular CKA_ID. Verify it works. * 5) Search for a non-existant CKA_ID. Verify it returns nothing. * 6) Close all sessions. Then create a new session. * 7) Search for a particular CKA_ID. Verify it works. * 8) Search for a non-existant CKA_ID. Verify it returns nothing. * 9) Destroy all 3 token objects */ CK_RV do_CreateTokenObjects(void) { int i, got_it = 0; CK_SLOT_ID slot_id; CK_FLAGS flags; CK_SESSION_HANDLE h_session; CK_RV rc = 0, loc_rc = 0; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_BYTE true = TRUE; CK_BYTE false = FALSE; CK_OBJECT_HANDLE h_cert1; CK_OBJECT_CLASS cert1_class = CKO_CERTIFICATE; CK_CERTIFICATE_TYPE cert1_type = CKC_X_509; CK_BYTE cert1_subject[] = "Certificate subject #1"; CK_BYTE cert1_id[] = "Certificate ID #1"; CK_BYTE cert1_value[] = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"; CK_ATTRIBUTE cert1_attribs[] = { {CKA_CLASS, &cert1_class, sizeof(cert1_class) }, {CKA_TOKEN, &true, sizeof(true) }, {CKA_CERTIFICATE_TYPE, &cert1_type, sizeof(cert1_type) }, {CKA_SUBJECT, &cert1_subject, sizeof(cert1_subject) }, {CKA_ID, &cert1_id, sizeof(cert1_id) }, {CKA_VALUE, &cert1_value, sizeof(cert1_value) }, {CKA_PRIVATE, &false, sizeof(false) } }; CK_OBJECT_HANDLE h_cert2; CK_OBJECT_CLASS cert2_class = CKO_CERTIFICATE; CK_CERTIFICATE_TYPE cert2_type = CKC_X_509; CK_BYTE cert2_subject[] = "Certificate subject #2"; CK_BYTE cert2_id[] = "Certificate ID #2"; CK_BYTE cert2_value[] = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"; CK_ATTRIBUTE cert2_attribs[] = { {CKA_CLASS, &cert2_class, sizeof(cert2_class) }, {CKA_TOKEN, &true, sizeof(true) }, {CKA_CERTIFICATE_TYPE, &cert2_type, sizeof(cert2_type) }, {CKA_SUBJECT, &cert2_subject, sizeof(cert2_subject) }, {CKA_ID, &cert2_id, sizeof(cert2_id) }, {CKA_VALUE, &cert2_value, sizeof(cert2_value) }, {CKA_PRIVATE, &false, sizeof(false) } }; CK_OBJECT_HANDLE h_cert3; CK_OBJECT_CLASS cert3_class = CKO_CERTIFICATE; CK_CERTIFICATE_TYPE cert3_type = CKC_X_509; CK_BYTE cert3_subject[] = "Certificate subject #3"; CK_BYTE cert3_id[] = "Certificate ID #3"; CK_BYTE cert3_value[] = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"; CK_ATTRIBUTE cert3_attribs[] = { {CKA_CLASS, &cert3_class, sizeof(cert3_class) }, {CKA_TOKEN, &true, sizeof(true) }, {CKA_CERTIFICATE_TYPE, &cert3_type, sizeof(cert3_type) }, {CKA_SUBJECT, &cert3_subject, sizeof(cert3_subject) }, {CKA_ID, &cert3_id, sizeof(cert3_id) }, {CKA_VALUE, &cert3_value, sizeof(cert3_value) }, {CKA_PRIVATE, &false, sizeof(false) } }; CK_BYTE find1_id[] = "Certificate ID #2"; CK_ATTRIBUTE find1_attribs[] = { {CKA_ID, &find1_id, sizeof(find1_id)} }; CK_BYTE find2_id[] = "Certificate ID #123456"; CK_ATTRIBUTE find2_attribs[] = { {CKA_ID, &find2_id, sizeof(find2_id)} }; CK_OBJECT_HANDLE obj_list[10]; CK_ULONG find_count; testcase_begin("starting..."); if (get_user_pin(user_pin)) return CKR_FUNCTION_FAILED; user_pin_len = (CK_ULONG)strlen((char *)user_pin); slot_id = SLOT_ID; /* create a USER R/W session */ flags = CKF_SERIAL_SESSION | CKF_RW_SESSION; rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &h_session); if (rc != CKR_OK) { testcase_fail("C_OpenSession() rc = %s", p11_get_ckr(rc)); return rc; } rc = funcs->C_Login(h_session, CKU_USER, user_pin, user_pin_len); if (rc != CKR_OK) { testcase_fail("C_Login() rc = %s", p11_get_ckr(rc)); return rc; } /* create the token objects */ rc = funcs->C_CreateObject(h_session, cert1_attribs, 7, &h_cert1); if (rc != CKR_OK) { testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc)); return rc; } rc = funcs->C_CreateObject(h_session, cert2_attribs, 7, &h_cert2); if (rc != CKR_OK) { testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc)); goto destroy_1; } rc = funcs->C_CreateObject(h_session, cert3_attribs, 7, &h_cert3); if (rc != CKR_OK) { testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc)); goto destroy_2; } /* now, search for the 2nd object */ rc = funcs->C_FindObjectsInit(h_session, find1_attribs, 1); if (rc != CKR_OK) { testcase_fail("C_FindObjectsInit() rc = %s", p11_get_ckr(rc)); goto destroy; } rc = funcs->C_FindObjects(h_session, obj_list, 10, &find_count); if (rc != CKR_OK) { testcase_fail("C_FindObjects() rc = %s", p11_get_ckr(rc)); goto destroy; } /* step through list and find 2nd object's handle */ for (i=0; i<find_count; i++) { if (obj_list[i] == h_cert2) got_it++; } if (got_it == 0) { testcase_fail("could not find 2nd object's handle"); rc = -1; goto destroy; } rc = funcs->C_FindObjectsFinal(h_session); if (rc != CKR_OK) { testcase_fail("C_FindObjectsFinal() rc = %s", p11_get_ckr(rc)); goto destroy; } /* now, search for a non-existant attribute */ rc = funcs->C_FindObjectsInit(h_session, find2_attribs, 1); if (rc != CKR_OK) { testcase_fail("C_FindObjectsInit() rc = %s", p11_get_ckr(rc)); goto destroy; } rc = funcs->C_FindObjects(h_session, obj_list, 10, &find_count); if (rc != CKR_OK) { testcase_fail("C_FindObjects() rc = %s", p11_get_ckr(rc)); goto destroy; } if (find_count != 0) { testcase_fail("found %ld objects when none where expected", find_count); rc = -1; goto destroy; } rc = funcs->C_FindObjectsFinal(h_session); if (rc != CKR_OK) { testcase_fail("C_FindObjectsFinal() rc = %s", p11_get_ckr(rc)); goto destroy; } /* done...close all sessions and open a new one */ rc = funcs->C_CloseAllSessions( slot_id ); if (rc != CKR_OK) { testcase_fail("C_CloseAllSessions() rc = %s", p11_get_ckr(rc)); goto destroy; } /* create a USER R/W session */ flags = CKF_SERIAL_SESSION | CKF_RW_SESSION; rc = funcs->C_OpenSession(slot_id, flags, NULL, NULL, &h_session); if (rc != CKR_OK) { testcase_fail("C_OpenSession() rc = %s", p11_get_ckr(rc)); goto destroy; } rc = funcs->C_Login(h_session, CKU_USER, user_pin, user_pin_len); if (rc != CKR_OK) { testcase_fail("C_Login() rc = %s", p11_get_ckr(rc)); goto destroy; } /* now, search for the 2nd object */ rc = funcs->C_FindObjectsInit(h_session, find1_attribs, 1); if (rc != CKR_OK) { testcase_fail("C_FindObjectsInit() rc = %s", p11_get_ckr(rc)); goto destroy; } rc = funcs->C_FindObjects(h_session, obj_list, 10, &find_count); if (rc != CKR_OK) { testcase_fail("C_FindObjects() rc = %s", p11_get_ckr(rc)); goto destroy; } /* step through list and find 2nd object's handle */ for (i=0; i<find_count; i++) { if (obj_list[i] == h_cert2) got_it++; } if (got_it == 0) { testcase_fail("could not find 2nd object's handle in new session"); rc = -1; goto destroy; } rc = funcs->C_FindObjectsFinal(h_session); if (rc != CKR_OK) { testcase_fail("C_FindObjectsFinal() rc = %s", p11_get_ckr(rc)); goto destroy; } /* now, search for a non-existant attribute */ rc = funcs->C_FindObjectsInit(h_session, find2_attribs, 1); if (rc != CKR_OK) { testcase_fail("C_FindObjectsInit() rc = %s", p11_get_ckr(rc)); goto destroy; } rc = funcs->C_FindObjects(h_session, obj_list, 10, &find_count); if (rc != CKR_OK) { testcase_fail("C_FindObjects() rc = %s", p11_get_ckr(rc)); goto destroy; } if (find_count != 0) { testcase_fail("found %ld objects when none where expected", find_count); rc = -1; goto destroy; } rc = funcs->C_FindObjectsFinal(h_session); if (rc != CKR_OK) { testcase_fail("C_FindObjectsFinal() rc = %s", p11_get_ckr(rc)); goto destroy; } testcase_pass("Looks okay..."); /* Destroy the created objects, don't clobber the rc */ destroy: loc_rc = funcs->C_DestroyObject(h_session, h_cert3); if (loc_rc != CKR_OK) testcase_error("C_DestroyObject() loc_rc = %s", p11_get_ckr(loc_rc)); destroy_2: loc_rc = funcs->C_DestroyObject(h_session, h_cert2); if (loc_rc != CKR_OK) testcase_error("C_DestroyObject() loc_rc = %s", p11_get_ckr(loc_rc)); destroy_1: loc_rc = funcs->C_DestroyObject(h_session, h_cert1); if (loc_rc != CKR_OK) testcase_error("C_DestroyObject() loc_rc = %s", p11_get_ckr(loc_rc)); /* done...close the session */ loc_rc = funcs->C_CloseAllSessions(slot_id); if (loc_rc != CKR_OK) testcase_error("C_CloseAllSessions() loc_rc = %s", p11_get_ckr(loc_rc)); return rc; }
/* This function should test: * C_Verify, mechanism chosen by caller * * 1. Get message from test vector * 2. Get signature from test vector * 3. Verify signature * */ CK_RV do_VerifyRSA(struct PUBLISHED_TEST_SUITE_INFO *tsuite) { int i; CK_BYTE actual[MAX_SIGNATURE_SIZE]; CK_BYTE message[MAX_MESSAGE_SIZE]; CK_ULONG message_len; CK_BYTE signature[MAX_SIGNATURE_SIZE]; CK_ULONG signature_len; CK_MECHANISM mech; CK_OBJECT_HANDLE publ_key; CK_SLOT_ID slot_id = SLOT_ID; CK_SESSION_HANDLE session; CK_FLAGS flags; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_RV rc, loc_rc; // begin testsuite testsuite_begin("%s Verify.", tsuite->name); testcase_rw_session(); testcase_user_login(); // skip tests if the slot doesn't support this mechanism if (! mech_supported(slot_id, tsuite->mech.mechanism)){ testsuite_skip(tsuite->tvcount, "Slot %u doesn't support %u", (unsigned int) slot_id, (unsigned int) tsuite->mech.mechanism ); goto testcase_cleanup; } // iterate over test vectors for (i = 0; i < tsuite->tvcount; i++){ testcase_begin("%s Verify with test vector %d.", tsuite->name, i); rc = CKR_OK; // set return value // clear buffers memset(message, 0, MAX_MESSAGE_SIZE); memset(signature, 0, MAX_SIGNATURE_SIZE); memset(actual, 0, MAX_SIGNATURE_SIZE); // get message message_len = tsuite->tv[i].msg_len; memcpy(message, tsuite->tv[i].msg, message_len); // get signature signature_len = tsuite->tv[i].sig_len; memcpy(signature, tsuite->tv[i].sig, signature_len); // create (public) key handle rc = create_RSAPublicKey(session, tsuite->tv[i].mod, tsuite->tv[i].pub_exp, tsuite->tv[i].mod_len, tsuite->tv[i].pubexp_len, &publ_key); if (rc != CKR_OK) { testcase_error("create_RSAPublicKey(), rc=%s", p11_get_ckr(rc)); goto error; } // set mechanism mech = tsuite->mech; // initialize verify rc = funcs->C_VerifyInit(session, &mech, publ_key); if (rc != CKR_OK) { testcase_error("C_VerifyInit(), rc=%s", p11_get_ckr(rc)); goto error; } // do verify rc = funcs->C_Verify(session, message, message_len, signature, signature_len); // check result testcase_new_assertion(); if (rc == CKR_OK){ testcase_pass("C_Verify."); } else { testcase_fail("%s Sign Verify with test vector %d " "failed.", tsuite->name, i); } // clean up rc = funcs->C_DestroyObject(session, publ_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(rc)); goto testcase_cleanup; } } goto testcase_cleanup; error: loc_rc = funcs->C_DestroyObject(session, publ_key); if (loc_rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc)); } testcase_cleanup: testcase_user_logout(); rc = funcs->C_CloseAllSessions(slot_id); if (rc != CKR_OK) { testcase_error("C_CloseAllSessions rc=%s", p11_get_ckr(rc)); } return rc; }
/** Tests signature verification with published test vectors. **/ CK_RV do_SignVerify_HMAC(struct HMAC_TEST_SUITE_INFO *tsuite) { int i; CK_MECHANISM mech; CK_BYTE key[MAX_KEY_SIZE]; CK_ULONG key_len; CK_BYTE data[MAX_DATA_SIZE]; CK_ULONG data_len; CK_BYTE actual[MAX_HASH_SIZE]; CK_ULONG actual_len; CK_BYTE expected[MAX_HASH_SIZE]; CK_ULONG expected_len; CK_SESSION_HANDLE session; CK_SLOT_ID slot_id = SLOT_ID; CK_ULONG flags; CK_RV rc; CK_OBJECT_HANDLE h_key; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; /** begin testsuite **/ testsuite_begin("%s Sign Verify.", tsuite->name); testcase_rw_session(); testcase_user_login(); rc = CKR_OK; // set rc /** skip test if mech is not supported with this slot **/ if (! mech_supported(SLOT_ID, tsuite->mech.mechanism)) { testsuite_skip(tsuite->tvcount, "mechanism %s is not supported with slot %ld", tsuite->name, slot_id); goto testcase_cleanup; } /** iterate over test vectors **/ for(i = 0; i < tsuite->tvcount; i++) { /** begin test **/ testcase_begin("Sign Verify %s with test vector %d.", tsuite->name, i); /** clear buffers **/ memset(key, 0, sizeof(key)); memset(data, 0, sizeof(data)); memset(actual, 0, sizeof(actual)); memset(expected, 0, sizeof(expected)); /** get test vector info **/ key_len = tsuite->tv[i].key_len; data_len = tsuite->tv[i].data_len; actual_len = sizeof(actual); expected_len = tsuite->tv[i].hash_len; memcpy(key, tsuite->tv[i].key, key_len); memcpy(data, tsuite->tv[i].data, data_len); memcpy(expected, tsuite->tv[i].result, expected_len); /** get mechanism **/ mech = tsuite->mech; /** create key object **/ rc = create_GenericSecretKey(session, key, key_len, &h_key); if(rc != CKR_OK) { testcase_error("create_GenericSecretKey rc=%s", p11_get_ckr(rc)); goto error; } /** initialize signing **/ rc = funcs->C_SignInit(session, &mech, h_key); if (rc != CKR_OK) { testcase_error("C_SignInit rc=%s", p11_get_ckr(rc)); goto error; } /** do signing **/ rc = funcs->C_Sign(session, data, data_len, actual, &actual_len); if (rc != CKR_OK) { testcase_error("C_Sign rc=%s", p11_get_ckr(rc)); goto error; } /** initilaize verification **/ rc = funcs->C_VerifyInit(session, &mech, h_key); if (rc != CKR_OK) { testcase_error("C_VerifyInit rc=%s", p11_get_ckr(rc)); goto error; } /** do verification **/ rc = funcs->C_Verify(session, data, data_len, actual, actual_len); if (rc != CKR_OK) { testcase_error("C_Verify rc=%s", p11_get_ckr(rc)); goto error; } /** compare sign/verify results with expected results **/ testcase_new_assertion(); if(actual_len != expected_len) { testcase_fail("hashed data length does not match test " "vector's hashed data length\nexpected length=" "%ld, found length=%ld", expected_len, actual_len); } else if(memcmp(actual, expected, expected_len)) { testcase_fail("hashed data does not match test " "vector's hashed data"); } else { testcase_pass("%s Sign Verify with test vector %d " "passed.", tsuite->name, i); } /** clean up **/ rc = funcs->C_DestroyObject(session, h_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject rc=%s.", p11_get_ckr(rc)); goto testcase_cleanup; } } goto testcase_cleanup; error: rc = funcs->C_DestroyObject(session, h_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject rc=%s", p11_get_ckr(rc)); } testcase_cleanup: testcase_user_logout(); rc = funcs->C_CloseAllSessions(slot_id); if (rc != CKR_OK) { testcase_error("C_CloseAllSessions rc=%s", p11_get_ckr(rc)); } return rc; }
/* This function should test: * RSA Key Generation, usign CKM_RSA_PKCS_KEY_PAIR_GEN * RSA Sign, mechanism chosen by caller * RSA Verify, mechanism chosen by caller * * 1. Generate RSA Key Pair * 2. Generate message * 3. Sign message * 4. Verify signature * */ CK_RV do_SignVerifyRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) { int i; // test vector index int j; // message byte index CK_BYTE message[MAX_MESSAGE_SIZE]; CK_ULONG message_len; CK_BYTE signature[MAX_SIGNATURE_SIZE]; CK_ULONG signature_len; CK_MECHANISM mech; CK_OBJECT_HANDLE publ_key, priv_key; CK_SLOT_ID slot_id = SLOT_ID; CK_SESSION_HANDLE session; CK_FLAGS flags; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_RV rc, loc_rc; char *s; // begin testsuite testsuite_begin("%s Sign Verify.", tsuite->name); testcase_rw_session(); testcase_user_login(); // skip tests if the slot doesn't support this mechanism if (! mech_supported(slot_id, tsuite->mech.mechanism)){ testsuite_skip(tsuite->tvcount, "Slot %u doesn't support %u", (unsigned int) slot_id, (unsigned int) tsuite->mech.mechanism ); goto testcase_cleanup; } // iterate over test vectors for (i = 0; i < tsuite->tvcount; i++){ // get public exponent from test vector if ( p11_ahex_dump(&s, tsuite->tv[i].publ_exp, tsuite->tv[i].publ_exp_len) == NULL) { testcase_error("p11_ahex_dump() failed"); rc = -1; goto testcase_cleanup; } // begin test testcase_begin("%s Sign and Verify with test vector %d, " "\npubl_exp='%s', mod_bits='%lu', keylen='%lu'.", tsuite->name, i, s, tsuite->tv[i].modbits, tsuite->tv[i].keylen); if (!keysize_supported(slot_id, tsuite->mech.mechanism, tsuite->tv[i].modbits)) { testcase_skip("Token in slot %ld cannot be used with " "modbits.='%ld'", SLOT_ID,tsuite->tv[i].modbits); continue; } if (is_ep11_token(slot_id)) { if (! is_valid_ep11_pubexp(tsuite->tv[i].publ_exp, tsuite->tv[i].publ_exp_len)) { testcase_skip("EP11 Token cannot " "be used with publ_exp.='%s'",s); continue; } } if (is_cca_token(slot_id)) { if (! is_valid_cca_pubexp(tsuite->tv[i].publ_exp, tsuite->tv[i].publ_exp_len)) { testcase_skip("CCA Token cannot " "be used with publ_exp='%s'.",s); continue; } } if (is_tpm_token(slot_id)) { if ((! is_valid_tpm_pubexp(tsuite->tv[i].publ_exp, tsuite->tv[i].publ_exp_len)) || (!is_valid_tpm_modbits(tsuite->tv[i].modbits))) { testcase_skip("TPM Token cannot " "be used with publ_exp='%s'.",s); continue; } } // free memory free(s); rc = CKR_OK; // set rc // clear buffers memset(message, 0, MAX_MESSAGE_SIZE); memset(signature, 0, MAX_SIGNATURE_SIZE); // get test vector parameters message_len = tsuite->tv[i].inputlen; // generate key pair rc = generate_RSA_PKCS_KeyPair(session, tsuite->tv[i].modbits, tsuite->tv[i].publ_exp, tsuite->tv[i].publ_exp_len, &publ_key, &priv_key); if (rc != CKR_OK) { testcase_error("generate_RSA_PKCS_KeyPair(), " "rc=%s", p11_get_ckr(rc)); goto error; } // generate message for (j = 0; j < message_len; j++) { message[j] = (j + 1) % 255; } // get mech mech = tsuite->mech; // initialize Sign (length only) rc = funcs->C_SignInit(session, &mech, priv_key); if (rc != CKR_OK){ testcase_error("C_SignInit(), rc=%s", p11_get_ckr(rc)); goto error; } // set buffer size signature_len = MAX_SIGNATURE_SIZE; // do Sign rc = funcs->C_Sign(session, message, message_len, signature, &signature_len); if (rc != CKR_OK) { testcase_error("C_Sign(), rc=%s signature len=%ld", p11_get_ckr(rc), signature_len); goto error; } // initialize Verify rc = funcs->C_VerifyInit(session, &mech, publ_key); if (rc != CKR_OK) { testcase_error("C_VerifyInit(), rc=%s", p11_get_ckr(rc)); } // do Verify rc = funcs->C_Verify(session, message, message_len, signature, signature_len); // check results testcase_new_assertion(); if (rc == CKR_OK) { testcase_pass("C_Verify."); } else { testcase_fail("C_Verify(), rc=%s", p11_get_ckr(rc)); } // clean up rc = funcs->C_DestroyObject(session, publ_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(rc)); } rc = funcs->C_DestroyObject(session, priv_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(rc)); } } goto testcase_cleanup; error: loc_rc = funcs->C_DestroyObject(session, publ_key); if (loc_rc != CKR_OK) { testcase_error("C_DestroyObject, rc=%s.", p11_get_ckr(loc_rc)); } loc_rc = funcs->C_DestroyObject(session, priv_key); if (loc_rc != CKR_OK) { testcase_error("C_DestroyObject, rc=%s.", p11_get_ckr(loc_rc)); } testcase_cleanup: testcase_user_logout(); rc = funcs->C_CloseAllSessions(slot_id); if (rc != CKR_OK) { testcase_error("C_CloesAllSessions, rc=%s", p11_get_ckr(rc)); } return rc; }
CK_RV do_DecryptUpdateAES(struct published_test_suite_info *tsuite) { int i; CK_BYTE actual[BIG_REQUEST]; // decryption buffer CK_BYTE expected[BIG_REQUEST]; // decrypted data CK_ULONG actual_len, expected_len, original_len, k; CK_ULONG user_pin_len; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_SESSION_HANDLE session; CK_MECHANISM mech; CK_OBJECT_HANDLE h_key; CK_RV rc; CK_FLAGS flags; CK_SLOT_ID slot_id = SLOT_ID; testsuite_begin("%s Multipart Decryption.", tsuite->name); testcase_rw_session(); testcase_user_login(); /** skip tests if the slot doesn't support this mechanism **/ if (! mech_supported(slot_id, tsuite->mech.mechanism)){ testsuite_skip(tsuite->tvcount, "Slot %u doesn't support %u", (unsigned int) slot_id, (unsigned int)tsuite->mech.mechanism); goto testcase_cleanup; } for (i = 0; i < tsuite->tvcount; i++) { testcase_begin("%s Multipart Decryption with published test " "vector %d.", tsuite->name, i); /** create key handle **/ rc = create_AESKey(session, tsuite->tv[i].key, tsuite->tv[i].klen, &h_key); if (rc != CKR_OK) { testcase_error("C_CreateObject rc=%s", p11_get_ckr(rc)); goto error; } /** get mech **/ mech = tsuite->mech; /** clear buffers **/ memset(expected, 0, sizeof(expected)); memset(actual, 0, sizeof(actual)); /** get plaintext (expected results) **/ expected_len = tsuite->tv[i].plen; memcpy(expected, tsuite->tv[i].plaintext, expected_len); /** get plaintext **/ original_len = tsuite->tv[i].clen; actual_len = original_len; memcpy(actual, tsuite->tv[i].ciphertext, actual_len); /** multipart (in-place) decryption **/ rc = funcs->C_DecryptInit(session, &mech, h_key); if (rc != CKR_OK) { testcase_error("C_DecryptInit rc=%s", p11_get_ckr(rc)); goto error; } k = original_len; actual_len = 0; while (actual_len < original_len) { rc = funcs->C_DecryptUpdate(session, &actual[actual_len], AES_BLOCK_SIZE, &actual[actual_len], &k); if (rc != CKR_OK) { testcase_error("C_DecryptUpdate rc=%s", p11_get_ckr(rc)); goto error; } actual_len += k; k = original_len - k; } /** according to pkcs11 spec, nothing should be returned in final. **/ rc = funcs->C_DecryptFinal(session, &actual[actual_len], &k); if (rc != CKR_OK) { testcase_error("C_EncryptFinal rc=%s", p11_get_ckr(rc)); goto error; } /** compare decryption results with expected results. **/ testcase_new_assertion(); if (actual_len != expected_len) { testcase_fail("decrypted multipart data length does " "not match test vector's decrypted data " "length.\n\nexpected length=%ld, but found " "length=%ld\n", expected_len, actual_len); } else if (memcmp(actual, expected, expected_len)) { testcase_fail("decrypted multipart data does not match" " test vector's decrypted data.\n"); } else { testcase_pass("%s Multipart Decryption with test " "vector %d passed.", tsuite->name, i); } } /** clean up **/ rc = funcs->C_DestroyObject(session, h_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } goto testcase_cleanup; error: rc = funcs->C_DestroyObject(session, h_key); if (rc != CKR_OK) testcase_error("C_DestroyObject rc=%s", p11_get_ckr(rc)); testcase_cleanup: testcase_user_logout(); rc = funcs->C_CloseAllSessions(slot_id); if (rc != CKR_OK) { testcase_error("C_CloseAllSessions rc=%s", p11_get_ckr(rc)); } return rc; }
/* This function should test: * RSA Key Generation, CKM_RSA_PKCS_KEY_PAIR_GEN * RSA Encryption, mechanism chosen by caller * RSA Decryption, mechanism chosen by caller * * 1. Generate RSA Key Pair * 2. Generate plaintext * 3. Encrypt plaintext * 4. Decrypt encrypted data * 5. Compare plaintext with decrypted data * */ CK_RV do_EncryptDecryptRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) { int i, j; CK_BYTE original[BIG_REQUEST]; CK_ULONG original_len; CK_BYTE crypt[BIG_REQUEST]; CK_ULONG crypt_len; CK_BYTE decrypt[BIG_REQUEST]; CK_ULONG decrypt_len; CK_MECHANISM mech; CK_OBJECT_HANDLE publ_key, priv_key; CK_SLOT_ID slot_id = SLOT_ID; CK_SESSION_HANDLE session; CK_FLAGS flags; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_RV rc, loc_rc; char *s; // begin testsuite testsuite_begin("%s Encrypt Decrypt.", tsuite->name); testcase_rw_session(); testcase_user_login(); // skip tests if the slot doesn't support this mechanism if (! mech_supported(slot_id, tsuite->mech.mechanism)) { testsuite_skip(tsuite->tvcount, "Slot %u doesn't support %u", (unsigned int) slot_id, (unsigned int) tsuite->mech.mechanism ); goto testcase_cleanup; } // iterate over test vectors for (i = 0; i < tsuite->tvcount; i++) { // get public exponent from test vector if ( p11_ahex_dump(&s, tsuite->tv[i].publ_exp, tsuite->tv[i].publ_exp_len) == NULL) { testcase_error("p11_ahex_dump() failed"); rc = -1; goto testcase_cleanup; } // begin testcase testcase_begin("%s Encrypt and Decrypt with test vector %d." "\npubl_exp='%s', modbits=%ld, publ_exp_len=%ld, " "inputlen=%ld.", tsuite->name, i, s, tsuite->tv[i].modbits, tsuite->tv[i].publ_exp_len, tsuite->tv[i].inputlen); rc = CKR_OK; // set rc if (!keysize_supported(slot_id, tsuite->mech.mechanism, tsuite->tv[i].modbits)) { testcase_skip("Token in slot %ld cannot be used with " "modbits.='%ld'", SLOT_ID,tsuite->tv[i].modbits); continue; } if (is_ep11_token(slot_id)) { if (! is_valid_ep11_pubexp(tsuite->tv[i].publ_exp, tsuite->tv[i].publ_exp_len)) { testcase_skip("EP11 Token cannot " "be used with publ_exp.='%s'",s); continue; } } // cca special cases: // cca token can only use the following public exponents // 0x03 or 0x010001 (65537) // so skip test if invalid public exponent is used if (is_cca_token(slot_id)) { if (! is_valid_cca_pubexp(tsuite->tv[i].publ_exp, tsuite->tv[i].publ_exp_len) ) { testcase_skip("CCA Token cannot " "be used with publ_exp.='%s'",s); continue; } } // tpm special cases: // tpm token can only use public exponent 0x010001 (65537) // so skip test if invalid public exponent is used if (is_tpm_token(slot_id)) { if ((! is_valid_tpm_pubexp(tsuite->tv[i].publ_exp, tsuite->tv[i].publ_exp_len) ) || (! is_valid_tpm_modbits(tsuite->tv[i].modbits))) { testcase_skip("TPM Token cannot " "be used with publ_exp.='%s'",s); continue; } } free(s); // clear buffers memset(original, 0, BIG_REQUEST); memset(crypt, 0, BIG_REQUEST); memset(decrypt, 0, BIG_REQUEST); // get test vector parameters original_len = tsuite->tv[i].inputlen; // generate key pair rc = generate_RSA_PKCS_KeyPair(session, tsuite->tv[i].modbits, tsuite->tv[i].publ_exp, tsuite->tv[i].publ_exp_len, &publ_key, &priv_key); if (rc != CKR_OK) { testcase_error("generate_RSA_PKCS_KeyPair(), " "rc=%s", p11_get_ckr(rc)); goto error; } // generate plaintext for (j = 0; j < original_len; j++) { original[j] = (j + 1) % 255; } // set cipher buffer length crypt_len = BIG_REQUEST; decrypt_len = BIG_REQUEST; // get mech mech = tsuite->mech; // initialize (public key) encryption rc = funcs->C_EncryptInit(session, &mech, publ_key); if (rc != CKR_OK) { testcase_error("C_EncryptInit, rc=%s", p11_get_ckr(rc)); } // do (public key) encryption rc = funcs->C_Encrypt(session, original, original_len, crypt, &crypt_len); if (rc != CKR_OK) { testcase_error("C_Encrypt, rc=%s", p11_get_ckr(rc)); goto error; } // initialize (private key) decryption rc = funcs->C_DecryptInit(session, &mech, priv_key); if (rc != CKR_OK) { testcase_error("C_DecryptInit, rc=%s", p11_get_ckr(rc)); goto error; } // do (private key) decryption rc = funcs->C_Decrypt(session, crypt, crypt_len, decrypt, &decrypt_len); if (rc != CKR_OK) { testcase_error("C_Decrypt, rc=%s", p11_get_ckr(rc)); goto error; } // FIXME: there shouldn't be any padding here // remove padding if mech is CKM_RSA_X_509 if (mech.mechanism == CKM_RSA_X_509) { memmove(decrypt, decrypt + decrypt_len - original_len, original_len); decrypt_len = original_len; } // check results testcase_new_assertion(); if (decrypt_len != original_len) { testcase_fail("decrypted length does not match" "original data length.\n expected length = %ld," "but found length=%ld.\n", original_len, decrypt_len); } else if (memcmp(decrypt, original, original_len)) { testcase_fail("decrypted data does not match " "original data."); } else { testcase_pass("C_Encrypt and C_Decrypt."); } // clean up rc = funcs->C_DestroyObject(session, publ_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(rc)); goto error; } rc = funcs->C_DestroyObject(session, priv_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(rc)); goto error; } } goto testcase_cleanup; error: loc_rc = funcs->C_DestroyObject(session, publ_key); if (loc_rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc)); } loc_rc = funcs->C_DestroyObject(session, priv_key); if (loc_rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc)); } testcase_cleanup: testcase_user_logout(); loc_rc = funcs->C_CloseAllSessions(slot_id); if (loc_rc != CKR_OK) { testcase_error("C_CloseAllSessions, rc=%s", p11_get_ckr(loc_rc)); } return rc; }
/** Tests triple DES multipart decryption with published test vectors **/ CK_RV do_DecryptUpdateDES3(struct published_test_suite_info *tsuite) { int i; // test vector index CK_BYTE expected[BIG_REQUEST]; CK_BYTE cipher[BIG_REQUEST]; CK_BYTE plaintext[BIG_REQUEST]; CK_ULONG expected_len, p_len, cipher_len, k; CK_SLOT_ID slot_id = SLOT_ID; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_SESSION_HANDLE session; CK_MECHANISM mech; CK_OBJECT_HANDLE h_key; CK_RV rc; CK_FLAGS flags; /** begin testsuite **/ testsuite_begin("%s Decryption.", tsuite->name); testcase_rw_session(); testcase_user_login(); /** skip test if the slot does not support this mechanism **/ if (! mech_supported(slot_id, tsuite->mechanism)){ testsuite_skip(tsuite->tvcount, "Slot %u doesn't support %s (%u)", (unsigned int) slot_id, mech_to_str(tsuite->mechanism), (unsigned int) tsuite->mechanism); goto testcase_cleanup; } /** iterate over test vectors **/ for (i = 0; i < tsuite->tvcount; i++){ /** begin test **/ testcase_begin("%s Decryption with test vector %d.", tsuite->name, i); rc = CKR_OK; // set rc /** clear buffers **/ memset(expected, 0, sizeof(expected)); memset(cipher, 0, sizeof(cipher)); memset(plaintext, 0, sizeof(plaintext)); p_len = sizeof(plaintext); /** get plaintext (expected results) **/ expected_len = tsuite->tv[i].plen; memcpy(expected, tsuite->tv[i].plaintext, expected_len); /** get ciphertext **/ cipher_len = k = tsuite->tv[i].clen; memcpy(cipher, tsuite->tv[i].ciphertext, cipher_len); /** get mech **/ mech.mechanism = tsuite->mechanism; mech.ulParameterLen = tsuite->tv[i].ivlen; mech.pParameter = tsuite->tv[i].iv; /** create key handle. **/ rc = create_DES3Key(session, tsuite->tv[i].key, tsuite->tv[i].klen, &h_key); if (rc != CKR_OK) { testcase_error("C_CreateObject rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } /** initialize multipart (in-place) decryption **/ rc = funcs->C_DecryptInit(session, &mech, h_key); if (rc != CKR_OK) { testcase_error("C_DecryptInit rc=%s", p11_get_ckr(rc)); goto error; } /* do multipart encryption * for chunks, -1 is NULL, and 0 is empty string, * and a value > 0 is amount of data from test vector's * plaintext data. The is way we test input in various sizes. */ if (tsuite->tv[i].num_chunks) { int j; CK_ULONG outlen, len; CK_BYTE *data_chunk = NULL; k = 0; p_len = 0; outlen = sizeof(plaintext); for (j = 0; j < tsuite->tv[i].num_chunks; j++) { if (tsuite->tv[i].chunks[j] == -1) { len = 0; data_chunk = NULL; } else if (tsuite->tv[i].chunks[j] == 0) { len = 0; data_chunk = (CK_BYTE *)""; } else { len = tsuite->tv[i].chunks[j]; data_chunk = cipher + k; } rc = funcs->C_DecryptUpdate(session, data_chunk, len, &plaintext[p_len], &outlen); if (rc != CKR_OK) { testcase_error("C_DecryptUpdate rc=%s", p11_get_ckr(rc)); goto error; } k += len; p_len += outlen; outlen = sizeof(plaintext) - p_len; } } else { p_len = sizeof(plaintext); rc = funcs->C_DecryptUpdate(session, cipher, cipher_len, plaintext, &p_len); if (rc != CKR_OK) { testcase_error("C_DecryptUpdate rc=%s", p11_get_ckr(rc)); goto error; } } k = sizeof(plaintext) - p_len; rc = funcs->C_DecryptFinal(session, &plaintext[p_len], &k); if (rc != CKR_OK) { testcase_error("C_DecryptFinal rc=%s", p11_get_ckr(rc)); goto error; } /** compare decryption results with expected results. **/ testcase_new_assertion(); if (p_len != expected_len) { testcase_fail("decrypted multipart data length does " "not match test vector's decrypted data " "length.\nexpected length=%ld, but " "found length=%ld\n", expected_len,p_len); } else if (memcmp(plaintext, expected, expected_len)) { testcase_fail("decrypted multipart data does not " "match test vector's decrypted data.\n"); } else { testcase_pass("%s Multipart Decryption with test " "vector %d passed.", tsuite->name, i); } /** clean up **/ rc = funcs->C_DestroyObject(session, h_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject rc=%s.", p11_get_ckr(rc)); goto testcase_cleanup; } } goto testcase_cleanup; error: rc = funcs->C_DestroyObject(session, h_key); if (rc != CKR_OK) testcase_error("C_DestroyObject rc=%s", p11_get_ckr(rc)); testcase_cleanup: testcase_user_logout(); rc = funcs->C_CloseAllSessions(slot_id); if (rc != CKR_OK) { testcase_error("C_CloseAllSessions rc=%s", p11_get_ckr(rc)); } return rc; }
/* This function should test: * RSA Key Generation, using CKM_PKCS_KEY_PAIR_GEN * RSA Public-Key Wrap * RSA Private-Key Unwrap * */ CK_RV do_WrapUnwrapRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) { int i = 0, j = 0; CK_OBJECT_HANDLE publ_key, priv_key, secret_key, unwrapped_key; CK_BYTE_PTR wrapped_key = NULL; CK_ULONG wrapped_keylen, unwrapped_keylen; CK_MECHANISM wrap_mech, keygen_mech, mech; CK_BYTE clear[32]; CK_BYTE cipher[32]; CK_BYTE re_cipher[32]; CK_ULONG cipher_len = 32; CK_ULONG re_cipher_len = 32; char *s; CK_SESSION_HANDLE session; CK_FLAGS flags; CK_SLOT_ID slot_id = SLOT_ID; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_RV rc, loc_rc; // begin test suite testsuite_begin("%s Wrap Unwrap.", tsuite->name); testcase_rw_session(); testcase_user_login(); // skip all tests if the slot doesn't support this mechanism if (! mech_supported(slot_id, tsuite->mech.mechanism)){ testsuite_skip(tsuite->tvcount, "Slot %u doesn't support %u", (unsigned int) slot_id, (unsigned int) tsuite->mech.mechanism ); goto testcase_cleanup; } // skip all tests if the slot doesn't support wrapping else if (! wrap_supported(slot_id, tsuite->mech)) { testsuite_skip(tsuite->tvcount, "Slot %u doesn't support key wrapping", (unsigned int) slot_id); goto testcase_cleanup; } // skip all tests if the slot doesn't support unwrapping else if (! unwrap_supported(slot_id, tsuite->mech)) { testsuite_skip(tsuite->tvcount, "Slot %u doesn't support key unwrapping", (unsigned int) slot_id); goto testcase_cleanup; } for (i = 0; i < tsuite->tvcount; i++) { // wrap templates & unwrap templates CK_ATTRIBUTE unwrap_tmpl[] = { {CKA_CLASS, NULL, 0}, {CKA_KEY_TYPE, NULL, 0}, {CKA_VALUE_LEN, NULL, 0} }; CK_ULONG unwrap_tmpl_len; // get public exponent from test vector if ( p11_ahex_dump(&s, tsuite->tv[i].publ_exp, tsuite->tv[i].publ_exp_len) == NULL) { testcase_error("p11_ahex_dump() failed"); rc = -1; goto testcase_cleanup; } // begin test testcase_begin("%s Wrap Unwrap with test vector %d, " "\npubl_exp='%s', mod_bits='%lu', keylen='%lu', " "keytype='%s'", tsuite->name, i, s, tsuite->tv[i].modbits, tsuite->tv[i].keylen, p11_get_ckm(tsuite->tv[i].keytype.mechanism)); // free memory free(s); // get key gen mechanism keygen_mech = tsuite->tv[i].keytype; // get wrapping mechanism wrap_mech = tsuite->mech; // skip this test if the slot doesn't support this // keygen mechanism if (! mech_supported(slot_id, keygen_mech.mechanism)) { testcase_skip(); continue; } if (!keysize_supported(slot_id, tsuite->mech.mechanism, tsuite->tv[i].modbits)) { testcase_skip("Token in slot %ld cannot be used with " "modbits.='%ld'", SLOT_ID,tsuite->tv[i].modbits); continue; } if (is_ep11_token(slot_id)) { if (! is_valid_ep11_pubexp(tsuite->tv[i].publ_exp, tsuite->tv[i].publ_exp_len)) { testcase_skip("EP11 Token cannot " "be used with publ_exp.='%s'",s); continue; } } // initialize buffer lengths wrapped_keylen = PKCS11_MAX_PIN_LEN; // generate RSA key pair rc = generate_RSA_PKCS_KeyPair(session, tsuite->tv[i].modbits, tsuite->tv[i].publ_exp, tsuite->tv[i].publ_exp_len, &publ_key, &priv_key); if (rc != CKR_OK) { testcase_error("C_GenerateKeyPair() rc = %s", p11_get_ckr(rc)); goto testcase_cleanup; } // generate secret key rc = generate_SecretKey(session, tsuite->tv[i].keylen, &keygen_mech, &secret_key); if (rc != CKR_OK) { testcase_error("generate_SecretKey(), rc=%s", p11_get_ckr(rc)); goto error; } // extract CKA_CLASS and CKA_KEY_TYPE from generated key // we will use this for unwrapping // extract sizes first rc = funcs->C_GetAttributeValue(session, secret_key, unwrap_tmpl, 2); if (rc != CKR_OK) { testcase_error("C_GetAttributeValue(), rc=%s", p11_get_ckr(rc)); goto error; } // allocate memory for extraction unwrap_tmpl[0].pValue = calloc(sizeof(CK_BYTE), unwrap_tmpl[0].ulValueLen); unwrap_tmpl[1].pValue = calloc(sizeof(CK_BYTE), unwrap_tmpl[1].ulValueLen); if ( (unwrap_tmpl[0].pValue == NULL) || (unwrap_tmpl[1].pValue == NULL) ) { testcase_error("Error allocating %lu bytes" "for unwrap template attributes", unwrap_tmpl[0].ulValueLen + unwrap_tmpl[1].ulValueLen); rc = -1; goto error; } // now extract values rc = funcs->C_GetAttributeValue(session, secret_key, unwrap_tmpl, 2); if (rc != CKR_OK) { testcase_error("C_GetAttributeValue(), rc=%s", p11_get_ckr(rc)); goto error; } // wrap key (length only) rc = funcs->C_WrapKey(session, &wrap_mech, publ_key, secret_key, NULL, &wrapped_keylen); if (rc != CKR_OK) { testcase_error("C_WrapKey(), rc=%s.", p11_get_ckr(rc)); goto error; } // allocate memory for wrapped_key wrapped_key = calloc(sizeof(CK_BYTE), wrapped_keylen); if (wrapped_key == NULL) { testcase_error("Can't allocate memory " "for %lu bytes.", sizeof(CK_BYTE) * wrapped_keylen); rc = -1; goto error; } // wrap key rc = funcs->C_WrapKey(session, &wrap_mech, publ_key, secret_key, wrapped_key, &wrapped_keylen); if (rc != CKR_OK) { testcase_error("C_WrapKey, rc=%s", p11_get_ckr(rc)); goto error; } unwrapped_keylen = tsuite->tv[i].keylen; // variable key length specific case: // According to PKCS#11 v2.2 section 12.1.12 // CKM_RSA_X_509 does not wrap the key type, key length, // or any other information about the key; the application // must convey these separately, and supply them when // unwrapping the key. if (((keygen_mech.mechanism == CKM_AES_KEY_GEN) || (keygen_mech.mechanism == CKM_GENERIC_SECRET_KEY_GEN)) && (wrap_mech.mechanism == CKM_RSA_X_509)) { unwrapped_keylen = tsuite->tv[i].keylen; unwrap_tmpl[2].type = CKA_VALUE_LEN; unwrap_tmpl[2].ulValueLen = sizeof(unwrapped_keylen); unwrap_tmpl[2].pValue = &unwrapped_keylen; unwrap_tmpl_len = 3; } else { unwrap_tmpl_len = 2; } // unwrap key rc = funcs->C_UnwrapKey(session, &wrap_mech, priv_key, wrapped_key, wrapped_keylen, unwrap_tmpl, unwrap_tmpl_len, &unwrapped_key); if (rc != CKR_OK) { testcase_error("C_UnwrapKey, rc=%s", p11_get_ckr(rc)); goto error; } testcase_new_assertion(); // encode/decode with secrect key and peer secret key for (j = 0; j < 32; j++) clear[j] = j; switch (keygen_mech.mechanism) { case CKM_AES_KEY_GEN: mech.mechanism = CKM_AES_ECB; break; case CKM_GENERIC_SECRET_KEY_GEN: case CKM_DES3_KEY_GEN: mech.mechanism = CKM_DES3_ECB; break; case CKM_DES_KEY_GEN: mech.mechanism = CKM_DES_ECB; break; case CKM_CDMF_KEY_GEN: mech.mechanism = CKM_CDMF_ECB; break; default: testcase_error("unknowm mech"); goto error; } mech.ulParameterLen = 0; mech.pParameter = NULL; rc = funcs->C_EncryptInit(session, &mech, secret_key); if (rc != CKR_OK) { testcase_error("C_EncryptInit secret_key: rc = %s", p11_get_ckr(rc)); goto error; } rc = funcs->C_Encrypt(session, clear, 32, cipher, &cipher_len); if (rc != CKR_OK) { testcase_error("C_Encrypt secret_key: rc = %s", p11_get_ckr(rc)); goto error; } rc = funcs->C_DecryptInit(session,&mech,unwrapped_key); if (rc != CKR_OK) { testcase_error("C_DecryptInit unwrapped_key: rc = %s", p11_get_ckr(rc)); goto error; } rc = funcs->C_Decrypt(session, cipher, cipher_len, re_cipher, &re_cipher_len); if (rc != CKR_OK) { testcase_error("C_Decrypt unwrapped_key: rc = %s", p11_get_ckr(rc)); testcase_fail("Unwrapped key differs in CKA_VALUE."); goto error; } if (memcmp(clear, re_cipher, 32) != 0) { testcase_fail("ERROR:data mismatch\n"); goto error; } else testcase_pass("C_Wrap and C_Unwrap."); // clean up if (wrapped_key) free(wrapped_key); rc = funcs->C_DestroyObject(session, secret_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(rc)); goto testcase_cleanup; } rc = funcs->C_DestroyObject(session, publ_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(rc)); goto testcase_cleanup; } rc = funcs->C_DestroyObject(session, priv_key); if (rc != CKR_OK) { testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(rc)); goto testcase_cleanup; } } goto testcase_cleanup; error: if (wrapped_key) free(wrapped_key); funcs->C_DestroyObject(session, secret_key); funcs->C_DestroyObject(session, publ_key); funcs->C_DestroyObject(session, priv_key); testcase_cleanup: testcase_user_logout(); loc_rc = funcs->C_CloseAllSessions(slot_id); if (loc_rc != CKR_OK) { testcase_error("C_CloseAllSessions(), rc=%s.", p11_get_ckr(rc)); } return rc; }
/** Tests triple DES multipart encryption & multipart decryption using generated keys. **/ CK_RV do_EncryptDecryptUpdateDES3(struct generated_test_suite_info *tsuite) { int i,j,k; CK_BYTE original[BIG_REQUEST]; CK_BYTE crypt[BIG_REQUEST + DES3_BLOCK_SIZE]; CK_BYTE decrypt[BIG_REQUEST + DES3_BLOCK_SIZE]; CK_ULONG crypt_len, decrypt_len, original_len, tmp; CK_SLOT_ID slot_id = SLOT_ID; CK_SESSION_HANDLE session; CK_MECHANISM mech, mechkey; CK_OBJECT_HANDLE h_key; CK_FLAGS flags; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_RV rc; /** begin test **/ testcase_begin("%s Multipart Encryption/Decryption tests with key generation.", tsuite->name); testcase_rw_session(); testcase_user_login(); /** skip test if the slot does not support this mechanism **/ if (! mech_supported(slot_id, tsuite->mech.mechanism)){ testcase_skip("Slot %u doesn't support %s (%u)", (unsigned int) slot_id, mech_to_str(tsuite->mech.mechanism), (unsigned int) tsuite->mech.mechanism); goto testcase_cleanup; } /** clear buffers **/ memset(original,0,sizeof(original)); memset(crypt,0,sizeof(crypt)); memset(decrypt,0,sizeof(decrypt)); /** generate test data **/ original_len = sizeof(original); crypt_len = sizeof(crypt); decrypt_len = sizeof(decrypt); for (j=0; j < original_len; j++) original[j] = j % 255; /** set mechanism for key gen **/ mechkey = des3_keygen; /** generate key **/ rc = funcs->C_GenerateKey( session, &mechkey, NULL, 0, &h_key ); if (rc != CKR_OK) { testcase_error("C_GenerateKey rc=%s", p11_get_ckr(rc)); goto error; } /** set mech for crypto **/ mech = tsuite->mech; /** initialize multipart encryption **/ rc = funcs->C_EncryptInit( session, &mech, h_key ); if (rc != CKR_OK) { testcase_error("C_EncryptInit rc=%s", p11_get_ckr(rc)); goto error; } /* do multipart (in-place) encryption for all mechs but CBC_PAD since * it pads and pkcs padding can make it unclear about what is * output at what stage. (See pkcs11v2.20 Section 11.2) */ if (mech.mechanism != CKM_DES3_CBC_PAD) { memcpy(crypt, original, original_len); k = 0; while (k < original_len) { rc = funcs->C_EncryptUpdate(session, &crypt[k], DES3_BLOCK_SIZE, &crypt[k], &crypt_len); if (rc != CKR_OK) { testcase_error("C_EncryptUpdate rc=%s", p11_get_ckr(rc)); goto error; } k += crypt_len; // encrypted amount crypt_len = sizeof(crypt) - k; // space in out buf } } else { i = k = 0; // i indexes source buffer // k indexes destination buffer tmp = 0; while (i < original_len) { tmp = crypt_len - k; // room is left in mpcrypt rc = funcs->C_EncryptUpdate(session, &original[i], DES3_BLOCK_SIZE, &crypt[k], &tmp); if (rc != CKR_OK) { testcase_error("C_EncryptUpdate rc=%s", p11_get_ckr(rc)); goto error; } k += tmp; i += DES3_BLOCK_SIZE; } crypt_len -= k; } rc = funcs->C_EncryptFinal(session, &crypt[k], &crypt_len); if (rc != CKR_OK) { testcase_error("C_EncryptFinal rc=%s", p11_get_ckr(rc)); goto error; } crypt_len += k; /** initialize multipart decryption **/ rc = funcs->C_DecryptInit( session, &mech, h_key ); if (rc != CKR_OK) { testcase_error("C_DecryptInit rc=%s", p11_get_ckr(rc)); goto error; } /* do multipart (in-place) encryption for all mechs but CBC_PAD since * it pads and pkcs padding can make it unclear about what is * output at what stage. (See pkcs11v2.20 Section 11.2) */ if (mech.mechanism != CKM_DES3_CBC_PAD) { memcpy(decrypt, crypt, crypt_len); decrypt_len = crypt_len; k = 0; while (k < crypt_len) { rc = funcs->C_DecryptUpdate(session, &decrypt[k], DES3_BLOCK_SIZE, &decrypt[k], &decrypt_len); if (rc != CKR_OK) { testcase_error("C_DecryptUpdate rc=%s", p11_get_ckr(rc)); goto error; } k += decrypt_len; decrypt_len = crypt_len - k; } } else { i = k = 0; while (i < crypt_len) { tmp = decrypt_len - k; // room left in mpdecrypt rc = funcs->C_DecryptUpdate(session, &crypt[i], DES3_BLOCK_SIZE, &decrypt[k], &tmp); if (rc != CKR_OK) { testcase_error("C_DecryptUpdate rc=%s", p11_get_ckr(rc)); goto error; } k += tmp; i += DES3_BLOCK_SIZE; } decrypt_len = sizeof(decrypt) - k; } rc = funcs->C_DecryptFinal(session, &decrypt[k], &decrypt_len); if (rc != CKR_OK) { testcase_error("C_DecryptFinal rc=%s", p11_get_ckr(rc)); goto error; } decrypt_len += k; /** compare multipart encryption/decryption results with expected results. **/ testcase_new_assertion(); if (decrypt_len != original_len) { testcase_fail("decrypted multipart data length does not match " "original data length.\nexpected length=%ld, but " "found length=%ld\n", original_len, decrypt_len); } else if(memcmp(decrypt, original, original_len)){ testcase_fail("decrypted multipart data does not match " "original data"); } else { testcase_pass("%s Multipart Encryption/Decryption test passed.", tsuite->name); } error: rc = funcs->C_DestroyObject(session, h_key); if (rc != CKR_OK) testcase_error("C_DestroyObject rc=%s.", p11_get_ckr(rc)); testcase_cleanup: testcase_user_logout(); rc = funcs->C_CloseAllSessions(slot_id); if (rc != CKR_OK) { testcase_error("C_CloseAllSessions rc=%s", p11_get_ckr(rc)); } return rc; }
CK_RV do_GetObjectSize(void) { CK_FLAGS flags; CK_SESSION_HANDLE session; CK_RV rc = 0; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_OBJECT_HANDLE keyobj; CK_BBOOL false = FALSE; CK_KEY_TYPE aes_type = CKK_AES; CK_OBJECT_CLASS key_class = CKO_SECRET_KEY; CK_CHAR aes_value[] = "This is a fake aes key."; CK_ATTRIBUTE aes_tmpl[] = { {CKA_CLASS, &key_class, sizeof(key_class)}, {CKA_KEY_TYPE, &aes_type, sizeof(aes_type)}, {CKA_VALUE, &aes_value, sizeof(aes_value)}, {CKA_SENSITIVE, &false, sizeof(false)} }; CK_ULONG obj_size = 0; // Do some setup and login to the token testcase_begin("starting..."); testcase_rw_session(); testcase_user_login(); // Create an AES Key Object. rc = funcs->C_CreateObject(session, aes_tmpl, 4, &keyobj); if (rc != CKR_OK) { testcase_error("C_CreateObject() rc = %s", p11_get_ckr(rc)); goto testcase_cleanup; } /* now, get the size of the object */ rc = funcs->C_GetObjectSize(session, keyobj, &obj_size); if (rc != CKR_OK) { testcase_fail("C_GetObjectSize() rc = %s", p11_get_ckr(rc)); return rc; } printf("\nSize of object = %lu\n", obj_size); /** Destroy the object */ rc = funcs->C_DestroyObject(session, keyobj); if (rc != CKR_OK) { testcase_fail("C_DestroyObject() rc = %s", p11_get_ckr(rc)); return rc; } /* now, get the size of a non-existent object */ rc = funcs->C_GetObjectSize(session, keyobj, &obj_size); if (rc != CKR_OBJECT_HANDLE_INVALID) { testcase_fail("C_GetObjectSize () rc = %s (expected CKR_OBJECT_HANDLE_INVALID)", p11_get_ckr(rc)); return rc; } printf("C_GetObjectSize test passed\n"); testcase_cleanup: funcs->C_DestroyObject(session, keyobj); testcase_user_logout(); rc = funcs->C_CloseSession(session); if (rc != CKR_OK) { testcase_error("C_CloseSessions rc=%s", p11_get_ckr(rc)); } return rc; }