/* * COPYRIGHT (c) International Business Machines Corp. 2005-2017 * * This program is provided under the terms of the Common Public License, * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this * software constitutes recipient's acceptance of CPL-1.0 terms which can be * found in the file LICENSE file or at * https://opensource.org/licenses/cpl1.0.php */ #include #include #include #include #include "pkcs11types.h" #include "regress.h" #include "des.h" #include "common.c" #include "mech_to_str.h" /** Tests DES encryption with published test vectors. **/ CK_RV do_EncryptDES(struct published_test_suite_info *tsuite) { unsigned int i; CK_BYTE expected[BIG_REQUEST]; CK_BYTE actual[BIG_REQUEST]; CK_ULONG expected_len, actual_len; 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; CK_SLOT_ID slot_id = SLOT_ID; /** begin testsuite **/ testsuite_begin("%s Encryption.", tsuite->name); testcase_rw_session(); testcase_user_login(); /** skip test if the slot doesn't 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 testcase **/ testcase_begin("%s Encryption with published test vector " "%d.", tsuite->name, i); rc = CKR_OK; // set rc /** clear buffers **/ memset(expected, 0, sizeof(expected)); memset(actual, 0, sizeof(actual)); /** get ciphertext (expected results) **/ expected_len = tsuite->tv[i].clen; memcpy(expected, tsuite->tv[i].ciphertext, expected_len); /** get plaintext **/ actual_len = tsuite->tv[i].plen; memcpy(actual, tsuite->tv[i].plaintext, actual_len); /** get mech **/ mech.mechanism = tsuite->mechanism; mech.ulParameterLen = tsuite->tv[i].ivlen; mech.pParameter = tsuite->tv[i].iv; /** create key handle. **/ rc = create_DESKey(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 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 (in-place) encryption **/ rc = funcs->C_Encrypt(session, actual, actual_len, actual, &actual_len); if (rc != CKR_OK) { testcase_error("C_Encrypt rc=%s", p11_get_ckr(rc)); goto error; } /** compare encryption results with expected results. **/ testcase_new_assertion(); if (actual_len != expected_len) { testcase_fail("encrypted data length does not " "match test vector's encrypted data " "length.\n\nexpected length=%ld, but found" " length=%ld\n", expected_len, actual_len); } else if (memcmp(actual, expected, expected_len)) { testcase_fail("encrypted data does not match test " "vector's encrypted data"); } else { testcase_pass("%s Encryption 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; 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 DES multipart encryption with published test vectors. **/ CK_RV do_EncryptUpdateDES(struct published_test_suite_info * tsuite) { unsigned int i; CK_BYTE expected[BIG_REQUEST]; CK_BYTE plaintext[BIG_REQUEST]; CK_BYTE crypt[BIG_REQUEST]; CK_ULONG expected_len, p_len, crypt_len = 0, k; 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; CK_SLOT_ID slot_id = SLOT_ID; /** begin testsuite **/ testsuite_begin("%s Multipart Encryption.", tsuite->name); testcase_rw_session(); testcase_user_login(); /** skip test if slot doesn't 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 Multipart Encryption with published " "test vector %d.", tsuite->name, i); rc = CKR_OK; // set rc /** clear buffers **/ memset(expected, 0, sizeof(expected)); memset(crypt, 0, sizeof(crypt)); memset(plaintext, 0, sizeof(plaintext)); /** get ciphertext (expected results) **/ expected_len = tsuite->tv[i].clen; memcpy(expected, tsuite->tv[i].ciphertext, expected_len); /** get plaintext **/ p_len = tsuite->tv[i].plen; memcpy(plaintext, tsuite->tv[i].plaintext, p_len); /** get mech **/ mech.mechanism = tsuite->mechanism; mech.ulParameterLen = tsuite->tv[i].ivlen; mech.pParameter = tsuite->tv[i].iv; /** create key handle **/ rc = create_DESKey(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 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 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. */ k = 0; if (tsuite->tv[i].num_chunks) { int j; CK_ULONG outlen, len; CK_BYTE *data_chunk = NULL; crypt_len = 0; outlen = sizeof(crypt); 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 = plaintext + k; } rc = funcs->C_EncryptUpdate(session, data_chunk, len, &crypt[crypt_len], &outlen); if (rc != CKR_OK) { testcase_error("C_EncryptUpdate rc=%s", p11_get_ckr(rc)); goto error; } k += len; crypt_len += outlen; outlen = sizeof(crypt) - crypt_len; } } else { crypt_len = sizeof(crypt); rc = funcs->C_EncryptUpdate(session, plaintext, p_len, crypt, &crypt_len); if (rc != CKR_OK) { testcase_error("C_EncryptUpdate rc=%s", p11_get_ckr(rc)); goto error; } } /** finalize multipart encryption **/ k = sizeof(crypt) - crypt_len; rc = funcs->C_EncryptFinal(session, &crypt[p_len], &k); if (rc != CKR_OK) { testcase_error("C_EncryptFinal rc=%s", p11_get_ckr(rc)); goto error; } /** compare encryption results with expected results. **/ testcase_new_assertion(); if (crypt_len != expected_len) { testcase_fail("encrypted multipart data length " "does not match test vector's encrypted " "data length.\n\nexpected length=%ld, " "but found length=%ld\n", expected_len, crypt_len); } else if (memcmp(crypt, expected, expected_len)) { testcase_fail("encrypted multipart data does not " "match test vector's encrypted data.\n"); } else { testcase_pass("%s Multipart Encryption with test " "vector %d passed.", tsuite->name, i); } 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; } /** Tests DES decryption with published test vectors. **/ CK_RV do_DecryptDES(struct published_test_suite_info * tsuite) { unsigned int i; CK_BYTE expected[BIG_REQUEST]; CK_BYTE actual[BIG_REQUEST]; CK_ULONG expected_len, actual_len; 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; CK_SLOT_ID slot_id = SLOT_ID; /** begin testsuite **/ testsuite_begin("%s Decryption.", tsuite->name); testcase_rw_session(); testcase_user_login(); rc = CKR_OK; /** query the slot to see if the mech is supported. **/ 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 vector **/ for (i = 0; i < tsuite->tvcount; i++) { /** begin test **/ testcase_begin("%s Decryption with published test vector " "%d.", tsuite->name, i); rc = CKR_OK; /** create key handle. **/ rc = create_DESKey(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; } /** get mech **/ mech.mechanism = tsuite->mechanism; mech.ulParameterLen = tsuite->tv[i].ivlen; mech.pParameter = tsuite->tv[i].iv; /** 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 ciphertext **/ actual_len = tsuite->tv[i].clen; memcpy(actual, tsuite->tv[i].ciphertext, actual_len); /** 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 (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.\n\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; 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 DES multipart decryption with published test vectors. **/ CK_RV do_DecryptUpdateDES(struct published_test_suite_info * tsuite) { unsigned int i; 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_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; CK_SLOT_ID slot_id = SLOT_ID; /** begin testsuite **/ testsuite_begin("%s Multipart Decryption.", tsuite->name); testcase_rw_session(); testcase_user_login(); rc = CKR_OK; // set rc /** skip testsuite if the slot doesn't 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 Multipart Decryption with published " "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)); /** get plaintext (expected results) **/ expected_len = tsuite->tv[i].plen; memcpy(expected, tsuite->tv[i].plaintext, expected_len); /** get ciphertext **/ cipher_len = 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_DESKey(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 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. */ k = 0; if (tsuite->tv[i].num_chunks) { int j; CK_ULONG outlen, len; CK_BYTE *data_chunk = NULL; 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; } } /** finalize multipart decryption **/ k = sizeof(plaintext) - p_len; rc = funcs->C_DecryptFinal(session, &plaintext[k], &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.\n\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; } /** Tests DES encryption & decryption with generated (secure) keys. **/ CK_RV do_EncryptDecryptDES(struct generated_test_suite_info * tsuite) { unsigned int j; CK_BYTE original[BIG_REQUEST]; CK_BYTE crypt[BIG_REQUEST + DES_BLOCK_SIZE]; CK_BYTE decrypt[BIG_REQUEST + DES_BLOCK_SIZE]; CK_ULONG original_len, crypt_len, decrypt_len; 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_SLOT_ID slot_id = SLOT_ID; CK_RV rc; /** begin test **/ testcase_begin("%s Encryption/Decryption with key generation " "test.", tsuite->name); testcase_rw_session(); testcase_user_login(); /** skip test if the slot doesn't 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 generation **/ mechkey = des_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 original data **/ 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 with key " "generation 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)); goto testcase_cleanup; 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 DES multipart encryption & decryption with generated keys. **/ CK_RV do_EncryptDecryptUpdateDES(struct generated_test_suite_info * tsuite) { unsigned int i, j, k; CK_BYTE original[BIG_REQUEST]; CK_BYTE crypt[BIG_REQUEST + DES_BLOCK_SIZE]; CK_BYTE decrypt[BIG_REQUEST + DES_BLOCK_SIZE]; CK_ULONG original_len, crypt_len, decrypt_len; CK_ULONG tmp; 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_SLOT_ID slot_id = SLOT_ID; CK_RV rc; /** begin test **/ testcase_begin("%s Multipart Encryption/Decryption with key " "generation test.", tsuite->name); testcase_rw_session(); testcase_user_login(); /** skip test if the slot doesn't 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); for (j = 0; j < original_len; j++) original[j] = j % 255; /** set mechanism for key gen **/ mechkey = des_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 #1 rc=%s", p11_get_ckr(rc)); goto error; } /** do multipart encryption **/ i = k = 0; // i indexes source buffer // k indexes destination buffer crypt_len = sizeof(crypt); tmp = 0; while (i < original_len) { tmp = crypt_len - k; // room left in mpcrypt rc = funcs->C_EncryptUpdate(session, &original[i], DES_BLOCK_SIZE, &crypt[k], &tmp); if (rc != CKR_OK) { testcase_error("C_EncryptUpdate rc=%s", p11_get_ckr(rc)); goto error; } k += tmp; i += DES_BLOCK_SIZE; } /** finalize multipart encryption **/ crypt_len = sizeof(crypt) - 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 decryption **/ i = k = 0; // i indexes source buffer // k indexes destination buffer decrypt_len = sizeof(decrypt); while (i < crypt_len) { tmp = decrypt_len - k; // room left in mpdecrypt rc = funcs->C_DecryptUpdate(session, &crypt[i], DES_BLOCK_SIZE, &decrypt[k], &tmp); if (rc != CKR_OK) { testcase_error("C_DecryptUpdate rc=%s", p11_get_ckr(rc)); goto error; } k += tmp; i += DES_BLOCK_SIZE; } decrypt_len = sizeof(decrypt) - k; /** finalize multipart decryption **/ rc = funcs->C_DecryptFinal(session, &decrypt[k], &decrypt_len); if (rc != CKR_OK) { testcase_error("C_DecryptFinal rc=%s", p11_get_ckr(rc)); return rc; } decrypt_len += k; /** compare encrypt/decrypt results with original data **/ 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 data does not match original " "data"); } else { testcase_pass("%s Multipart Encryption/Decryption with key" "generation 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 DES encryption & decryption with wrapped/unwrapped keys. **/ CK_RV do_WrapUnwrapDES(struct generated_test_suite_info * tsuite) { unsigned int j; CK_BYTE expected[BIG_REQUEST + DES_BLOCK_SIZE]; CK_BYTE actual[BIG_REQUEST + DES_BLOCK_SIZE]; CK_ULONG expected_len, actual_len, cipher_len; CK_BYTE wrapped_data[BIG_REQUEST + DES_BLOCK_SIZE]; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_SESSION_HANDLE session; CK_MECHANISM mechkey, mech; CK_OBJECT_HANDLE h_key; CK_OBJECT_HANDLE w_key; CK_OBJECT_HANDLE uw_key; CK_ULONG wrapped_data_len; CK_ULONG user_pin_len; CK_ULONG tmpl_count = 2; CK_FLAGS flags; CK_RV rc; CK_OBJECT_CLASS key_class = CKO_SECRET_KEY; CK_KEY_TYPE key_type = CKK_DES; CK_SLOT_ID slot_id = SLOT_ID; CK_ATTRIBUTE template[] = { {CKA_CLASS, &key_class, sizeof(key_class)} , {CKA_KEY_TYPE, &key_type, sizeof(key_type)} }; /** begin test **/ testcase_begin("%s Wrap/Unwrap key test.", tsuite->name); testcase_rw_session(); testcase_user_login(); /** skip test if the slot doesn't 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; } if (!wrap_supported(slot_id, tsuite->mech)) { 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(actual, 0, sizeof(actual)); memset(expected, 0, sizeof(expected)); /** generate data **/ actual_len = expected_len = BIG_REQUEST; cipher_len = BIG_REQUEST + DES_BLOCK_SIZE; for (j = 0; j < actual_len; j++) { actual[j] = j % 255; expected[j] = j % 255; } /** set mechkey for key generation **/ mechkey = des_keygen; /** generate a DES 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; } /** generate wrapping key **/ rc = funcs->C_GenerateKey(session, &mechkey, NULL, 0, &w_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, actual, actual_len, actual, &cipher_len); if (rc != CKR_OK) { testcase_error("C_Encrypt rc=%s", p11_get_ckr(rc)); goto error; } /** wrap key **/ wrapped_data_len = sizeof(wrapped_data); rc = funcs->C_WrapKey(session, &mech, w_key, h_key, (CK_BYTE *) & wrapped_data, &wrapped_data_len); if (rc != CKR_OK) { testcase_error("C_WrapKey rc=%s", p11_get_ckr(rc)); goto error; } /** unwrap key **/ rc = funcs->C_UnwrapKey(session, &mech, w_key, wrapped_data, wrapped_data_len, template, tmpl_count, &uw_key); if (rc != CKR_OK) { testcase_error("C_UnwrapKey rc=%s", p11_get_ckr(rc)); goto error; } /** decrypt data with unwrapped key **/ rc = funcs->C_DecryptInit(session, &mech, uw_key); if (rc != CKR_OK) { testcase_error("C_DecryptInit rc=%s", p11_get_ckr(rc)); goto error; } rc = funcs->C_Decrypt(session, actual, cipher_len, actual, &actual_len); if (rc != CKR_OK) { testcase_error("C_Decrypt rc=%s", p11_get_ckr(rc)); goto error; } /** compare encrypted/decrypted data with original data **/ testcase_new_assertion(); if (actual_len != expected_len) { testcase_fail("expected length=%ld, but found length=%ld" "\n", expected_len, actual_len); rc = CKR_GENERAL_ERROR; } else if (memcmp(actual, expected, actual_len)) { testcase_fail("decrypted data does not match plaintext " "data."); rc = CKR_GENERAL_ERROR; } else { testcase_pass("DES Wrap/UnWrap test for %s 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; } CK_RV des_funcs() { int i; CK_RV rv; /** published (known answer) tests **/ for (i = 0; i < NUM_OF_PUBLISHED_TESTSUITES; i++) { rv = do_EncryptDES(&published_test_suites[i]); if (rv != CKR_OK && (!no_stop)) break; rv = do_DecryptDES(&published_test_suites[i]); if (rv != CKR_OK && (!no_stop)) break; rv = do_EncryptUpdateDES(&published_test_suites[i]); if (rv != CKR_OK && (!no_stop)) break; rv = do_DecryptUpdateDES(&published_test_suites[i]); if (rv != CKR_OK && (!no_stop)) break; } /** generated tests **/ for (i = 0; i < NUM_OF_GENERATED_TESTSUITES; i++) { rv = do_WrapUnwrapDES(&generated_test_suites[i]); if (rv != CKR_OK && (!no_stop)) break; rv = do_EncryptDecryptDES(&generated_test_suites[i]); if (rv != CKR_OK && (!no_stop)) break; rv = do_EncryptDecryptUpdateDES(&generated_test_suites[i]); if (rv != CKR_OK && (!no_stop)) break; } return rv; } int main(int argc, char **argv) { int rc; CK_C_INITIALIZE_ARGS cinit_args; rc = do_ParseArgs(argc, argv); if (rc != 1) { return rc; } printf("Using slot #%lu...\n\n", SLOT_ID); printf("With option: no_stop: %d\n", no_stop); rc = do_GetFunctionList(); if (!rc) { testcase_error("do_GetFunctionList(), rc=%s", p11_get_ckr(rc)); return rc; } memset(&cinit_args, 0x0, sizeof(cinit_args)); cinit_args.flags = CKF_OS_LOCKING_OK; funcs->C_Initialize(&cinit_args); { CK_SESSION_HANDLE hsess = 0; rc = funcs->C_GetFunctionStatus(hsess); if (rc != CKR_FUNCTION_NOT_PARALLEL) { return rc; } rc = funcs->C_CancelFunction(hsess); if (rc != CKR_FUNCTION_NOT_PARALLEL) { return rc; } } rc = 0; testcase_setup(0); //TODO rc = des_funcs(); testcase_print_result(); funcs->C_Finalize(NULL); return rc; }