/* * 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 */ /* File: speed.c * * Performance tests for Opencryptoki * * RSA keygen (with keylength 1024, 2048, 4096) * RSA sign and verify (with keylength 1024, 2048, 4096) * RSA encrypt and decrypt (with keylength 1024, 2048, 4096) * DES3 encrypt and decrypt (with modes ECB and CBC) * AES encrypt and decrypt (with modes ECB and CBC, with keylength 128, 192, * 256), SHA1, SHA256, SHA512 */ #include #include #include #include #include #include #include "pkcs11types.h" #include "regress.h" #include "common.c" #define SHA1_HASH_LEN 20 #define SHA256_HASH_LEN 32 #define SHA512_HASH_LEN 64 #define MAX_HASH_LEN SHA512_HASH_LEN // the GetSystemTime and SYSTEMTIME implementation // from regress.h only has a ms resolution // and produces absolut inacceptable measurements. // So we use gettimeofday() and struct timeval // with us resolution instead. #ifdef SYSTEMTIME #undef SYSTEMTIME #endif #define SYSTEMTIME struct timeval #ifdef GetSystemTime #undef GetSystemTime #endif #define GetSystemTime(x) gettimeofday((x),NULL) static inline unsigned long delta_time_us(struct timeval *t1, struct timeval *t2) { unsigned long d; struct timeval td; timersub(t2, t1, &td); d = td.tv_sec * 1000 * 1000 + td.tv_usec; return (d ? d : 1); // return 1us if delta is 0 } // keylength: 512, 1024, 2048, 4096 int do_RSA_PKCS_EncryptDecrypt(int keylength) { CK_SLOT_ID slot_id; CK_SESSION_HANDLE session; CK_MECHANISM mech; CK_FLAGS flags; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_RV rv, rc; CK_OBJECT_HANDLE publ_key, priv_key; CK_BYTE data1[100]; CK_BYTE data2[512]; CK_BYTE encdata[512]; CK_ULONG len1, len2, encdata_len; CK_ULONG i; CK_ULONG iterations = 2000; SYSTEMTIME t1, t2; CK_ULONG diff, avg_time, min_time, max_time, tot_time; CK_ULONG bits = keylength; CK_BYTE pub_exp[] = { 0x01, 0x00, 0x01 }; CK_ATTRIBUTE pub_tmpl[] = { {CKA_MODULUS_BITS, &bits, sizeof(bits)}, {CKA_PUBLIC_EXPONENT, &pub_exp, sizeof(pub_exp)} }; testcase_begin("RSA PKCS Encrypt with keylen=%d datalen=%d", keylength, (int) sizeof(data1)); slot_id = SLOT_ID; testcase_rw_session(); testcase_user_login(); mech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; mech.ulParameterLen = 0; mech.pParameter = NULL; rc = funcs->C_GenerateKeyPair(session, &mech, pub_tmpl, 2, NULL, 0, &publ_key, &priv_key); if (rc != CKR_OK) { testcase_error("C_GenerateKeyPair rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } len1 = sizeof(data1); encdata_len = sizeof(encdata); for (i = 0; i < len1; i++) data1[i] = (unsigned char) i; mech.mechanism = CKM_RSA_PKCS; mech.ulParameterLen = 0; mech.pParameter = NULL; tot_time = 0; max_time = 0; min_time = 0xFFFFFFFF; for (i = 0; i < iterations + 2; i++) { GetSystemTime(&t1); rc = funcs->C_EncryptInit(session, &mech, publ_key); if (rc != CKR_OK) { testcase_error("C_EncryptInit rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } encdata_len = sizeof(encdata); rc = funcs->C_Encrypt(session, data1, len1, encdata, &encdata_len); if (rc != CKR_OK) { testcase_error("C_Encrypt rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } GetSystemTime(&t2); diff = delta_time_us(&t1, &t2); tot_time += diff; if (diff < min_time) min_time = diff; if (diff > max_time) max_time = diff; } tot_time -= min_time; tot_time -= max_time; avg_time = tot_time / iterations; // us -> ms tot_time /= 1000; min_time /= 1000; max_time /= 1000; avg_time /= 1000; printf("%ld iterations: total=%ldms min=%ldms max=%ldms avg=%ldms " "op/s=%.3f\n\n", iterations, tot_time, min_time, max_time, avg_time, (double) (iterations * 1000) / (double) tot_time); printf("RSA PKCS Decrypt with keylen=%d datalen=%d\n", keylength, (int) encdata_len); tot_time = 0; max_time = 0; min_time = 0xFFFFFFFF; for (i = 0; i < iterations + 2; i++) { GetSystemTime(&t1); rc = funcs->C_DecryptInit(session, &mech, priv_key); if (rc != CKR_OK) { testcase_error("C_DecryptInit rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } len2 = sizeof(data2); rc = funcs->C_Decrypt(session, encdata, encdata_len, data2, &len2); if (rc != CKR_OK) { testcase_error("C_Decrypt rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } if (len2 != len1) { testcase_error("len1=%lu and len2=%lu do not match ?!?", len1, len2); rc = CKR_FUNCTION_FAILED;; goto testcase_cleanup; } GetSystemTime(&t2); diff = delta_time_us(&t1, &t2); tot_time += diff; if (diff < min_time) min_time = diff; if (diff > max_time) max_time = diff; } tot_time -= min_time; tot_time -= max_time; avg_time = tot_time / iterations; // us -> ms tot_time /= 1000; min_time /= 1000; max_time /= 1000; avg_time /= 1000; printf("%ld iterations: total=%ldms min=%ldms max=%ldms avg=%ldms " "op/s=%.3f\n\n", iterations, tot_time, min_time, max_time, avg_time, (double) (iterations * 1000) / (double) tot_time); testcase_cleanup: rv = funcs->C_CloseAllSessions(slot_id); if (rv != CKR_OK) { testcase_error("C_CloseAllSessions rv=%s", p11_get_ckr(rv)); return FALSE; } return TRUE; } // keylength: 512, 1024, 2048, 4096 int do_RSA_KeyGen(int keylength) { CK_SESSION_HANDLE session; CK_MECHANISM mech; CK_FLAGS flags; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_RV rv, rc; CK_ULONG iterations = 10; SYSTEMTIME t1, t2; CK_ULONG diff, avg_time, max_time, min_time, tot_time, i; CK_ULONG bits = 2048; CK_OBJECT_HANDLE publ_key, priv_key; CK_BYTE pub_exp[] = { 0x01, 0x00, 0x01 }; CK_ATTRIBUTE pub_tmpl[] = { {CKA_MODULUS_BITS, &bits, sizeof(bits)}, {CKA_PUBLIC_EXPONENT, &pub_exp, sizeof(pub_exp)} }; testcase_begin("RSA KeyGen with keylen=%d", keylength); testcase_rw_session(); testcase_user_login(); mech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; mech.ulParameterLen = 0; mech.pParameter = NULL; rc = funcs->C_GenerateKeyPair(session, &mech, pub_tmpl, 2, NULL, 0, &publ_key, &priv_key); if (rc != CKR_OK) { testcase_error("C_GenerateKeyPair rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } min_time = 0xFFFFFFFF; max_time = 0x00000000; tot_time = 0x00000000; for (i = 0; i < iterations + 2; i++) { GetSystemTime(&t1); rc = funcs->C_GenerateKeyPair(session, &mech, pub_tmpl, 2, NULL, 0, &publ_key, &priv_key); if (rc != CKR_OK) { testcase_error("C_GenerateKeyPair rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } GetSystemTime(&t2); diff = delta_time_us(&t1, &t2); tot_time += diff; if (diff < min_time) min_time = diff; if (diff > max_time) max_time = diff; } tot_time -= min_time; tot_time -= max_time; avg_time = tot_time / iterations; // us -> ms tot_time /= 1000; min_time /= 1000; max_time /= 1000; avg_time /= 1000; printf("%ld iterations: total=%ldms min=%ldms max=%ldms avg=%ldms " "op/s=%.3f\n\n", iterations, tot_time, min_time, max_time, avg_time, (double) (iterations * 1000) / (double) tot_time); testcase_cleanup: rv = funcs->C_CloseSession(session); if (rv != CKR_OK) { testcase_error("C_CloseSession rv=%s", p11_get_ckr(rv)); return FALSE; } return TRUE; } // keylength: 512, 1024, 2048, 4096 int do_RSA_PKCS_SignVerify(int keylength) { CK_SLOT_ID slot_id; CK_SESSION_HANDLE session; CK_MECHANISM mech; CK_FLAGS flags; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_RV rv, rc; CK_ULONG i, len1, sig_len; CK_BYTE signature[512]; CK_BYTE data1[100]; CK_OBJECT_HANDLE publ_key, priv_key; SYSTEMTIME t1, t2; CK_ULONG diff, avg_time, min_time, max_time, tot_time; CK_ULONG iterations = 1000; CK_ULONG bits = keylength; CK_BYTE pub_exp[] = { 0x01, 0x00, 0x01 }; CK_ATTRIBUTE pub_tmpl[] = { {CKA_MODULUS_BITS, &bits, sizeof(bits)}, {CKA_PUBLIC_EXPONENT, &pub_exp, sizeof(pub_exp)} }; slot_id = SLOT_ID; testcase_begin("RSA PKCS Sign with keylen=%d datalen=%d", keylength, (int) sizeof(data1)); testcase_rw_session(); testcase_user_login(); mech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; mech.ulParameterLen = 0; mech.pParameter = NULL; rc = funcs->C_GenerateKeyPair(session, &mech, pub_tmpl, 2, NULL, 0, &publ_key, &priv_key); if (rc != CKR_OK) { testcase_error("C_GenerateKeyPair rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } // sign some data len1 = sizeof(data1); sig_len = sizeof(signature); for (i = 0; i < len1; i++) data1[i] = (unsigned char) i; mech.mechanism = CKM_RSA_PKCS; mech.ulParameterLen = 0; mech.pParameter = NULL; tot_time = 0; max_time = 0; min_time = 0xFFFFFFFF; for (i = 0; i < iterations + 2; i++) { GetSystemTime(&t1); rc = funcs->C_SignInit(session, &mech, priv_key); if (rc != CKR_OK) { testcase_error("C_SignInit rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } sig_len = sizeof(signature); rc = funcs->C_Sign(session, data1, len1, signature, &sig_len); if (rc != CKR_OK) { testcase_error("C_Sign rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } GetSystemTime(&t2); diff = delta_time_us(&t1, &t2); tot_time += diff; if (diff < min_time) min_time = diff; if (diff > max_time) max_time = diff; } tot_time -= min_time; tot_time -= max_time; avg_time = tot_time / iterations; // us -> ms tot_time /= 1000; min_time /= 1000; max_time /= 1000; avg_time /= 1000; printf("%ld iterations: total=%ldms min=%ldms max=%ldms avg=%ldms " "op/s=%.3f\n\n", iterations, tot_time, min_time, max_time, avg_time, (double) (iterations * 1000) / (double) tot_time); printf("RSA PKCS Verify with keylen=%d datalen=%d\n", keylength, (int) sizeof(data1)); tot_time = 0; max_time = 0; min_time = 0xFFFFFFFF; for (i = 0; i < iterations + 2; i++) { GetSystemTime(&t1); rc = funcs->C_VerifyInit(session, &mech, publ_key); if (rc != CKR_OK) { testcase_error("C_VerifyInit rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } rc = funcs->C_Verify(session, data1, len1, signature, sig_len); if (rc != CKR_OK) { testcase_error("C_Verify rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } GetSystemTime(&t2); diff = delta_time_us(&t1, &t2); tot_time += diff; if (diff < min_time) min_time = diff; if (diff > max_time) max_time = diff; } tot_time -= min_time; tot_time -= max_time; avg_time = tot_time / iterations; // us -> ms tot_time /= 1000; min_time /= 1000; max_time /= 1000; avg_time /= 1000; printf("%ld iterations: total=%ldms min=%ldms max=%ldms avg=%ldms " "op/s=%.3f\n\n", iterations, tot_time, min_time, max_time, avg_time, (double) (iterations * 1000) / (double) tot_time); testcase_cleanup: rv = funcs->C_CloseAllSessions(slot_id); if (rv != CKR_OK) { testcase_error("C_CloseAllSession rv=%s", p11_get_ckr(rv)); return FALSE; } return TRUE; } // mode: ECB CBC int do_DES3_EncrDecr(const char *mode) { CK_SLOT_ID slot_id; CK_SESSION_HANDLE session; CK_MECHANISM mech; CK_FLAGS flags; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_RV rv, rc; CK_OBJECT_HANDLE h_key; CK_BYTE original[BIG_REQUEST]; CK_BYTE cipher[BIG_REQUEST]; CK_BYTE clear[BIG_REQUEST]; CK_ULONG orig_len, cipher_len, clear_len; CK_BYTE init_v[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; SYSTEMTIME t1, t2; CK_ULONG i, iterations = 10000; CK_ULONG avg_time, tot_time, min_time, max_time, diff; slot_id = SLOT_ID; testcase_begin("DES3 Encrypt with mode=%s datalen=%d\n", mode, BIG_REQUEST); if (is_cca_token(SLOT_ID) && strcmp(mode, "ECB") == 0) { testcase_skip("Slot %u doesn't support DES3 ECB En/Decrypt\n", (unsigned) SLOT_ID); return TRUE; } testcase_rw_session(); testcase_user_login(); mech.mechanism = CKM_DES3_KEY_GEN; mech.ulParameterLen = 0; mech.pParameter = NULL; // generate a DES3 key rc = funcs->C_GenerateKey(session, &mech, NULL, 0, &h_key); if (rc != CKR_OK) { testcase_error("C_GenerateKey rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } // clear buffers memset(clear, 0, BIG_REQUEST); memset(original, 0, BIG_REQUEST); memset(cipher, 0, BIG_REQUEST); // encrypt some data orig_len = BIG_REQUEST; for (i = 0; i < orig_len; i++) original[i] = i % 255; if (strcmp(mode, "ECB") == 0) { mech.mechanism = CKM_DES3_ECB; mech.ulParameterLen = 0; mech.pParameter = NULL; } else if (strcmp(mode, "CBC") == 0) { mech.mechanism = CKM_DES3_CBC; mech.ulParameterLen = 8; mech.pParameter = init_v; } else { testcase_error("unknown mode %s in do_DES3_EncrDecr()", mode); rc = CKR_MECHANISM_INVALID; goto testcase_cleanup; } tot_time = 0; max_time = 0; min_time = 0xFFFFFFFF; for (i = 0; i < iterations + 2; i++) { GetSystemTime(&t1); rc = funcs->C_EncryptInit(session, &mech, h_key); if (rc != CKR_OK) { testcase_error("C_EncryptInit rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } cipher_len = BIG_REQUEST; rc = funcs->C_Encrypt(session, original, orig_len, cipher, &cipher_len); if (rc != CKR_OK) { testcase_error("C_Encrypt rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } GetSystemTime(&t2); diff = delta_time_us(&t1, &t2); tot_time += diff; if (diff < min_time) min_time = diff; if (diff > max_time) max_time = diff; } tot_time -= min_time; tot_time -= max_time; avg_time = tot_time / iterations; // us -> ms tot_time /= 1000; printf("%ld iterations: total=%ldms min=%ldus max=%ldus avg=%ldus " "op/s=%.3f %.3fMB/s\n\n", iterations, tot_time, min_time, max_time, avg_time, (double) (iterations * 1000) / (double) tot_time, (((double) (iterations * 1000) / (double) (1024 * 1024)) * BIG_REQUEST) / (double) tot_time); printf("DES3 Decrypt with mode=%s datalen=%d\n", mode, BIG_REQUEST); tot_time = 0; max_time = 0; min_time = 0xFFFFFFFF; for (i = 0; i < iterations + 2; i++) { GetSystemTime(&t1); 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; } clear_len = BIG_REQUEST; rc = funcs->C_Decrypt(session, cipher, cipher_len, clear, &clear_len); if (rc != CKR_OK) { testcase_error("C_Decrypt rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } GetSystemTime(&t2); diff = delta_time_us(&t1, &t2); tot_time += diff; if (diff < min_time) min_time = diff; if (diff > max_time) max_time = diff; } tot_time -= min_time; tot_time -= max_time; avg_time = tot_time / iterations; // us -> ms tot_time /= 1000; printf("%ld iterations: total=%ldms min=%ldus max=%ldus avg=%ldus " "op/s=%.3f %.3fMB/s\n\n", iterations, tot_time, min_time, max_time, avg_time, (double) (iterations * 1000) / (double) tot_time, (((double) (iterations * 1000) / (double) (1024 * 1024)) * BIG_REQUEST) / (double) tot_time); testcase_cleanup: rv = funcs->C_CloseAllSessions(slot_id); if (rv != CKR_OK) { testcase_error("C_CloseAllSessions rc=%s", p11_get_ckr(rv)); return FALSE; } return TRUE; } // keylength: 128...256 // mode: ECB CBC int do_AES_EncrDecr(int keylength, const char *mode) { CK_SLOT_ID slot_id; CK_SESSION_HANDLE session; CK_MECHANISM mech; CK_FLAGS flags; CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; CK_ULONG user_pin_len; CK_RV rv, rc; CK_OBJECT_HANDLE h_key; CK_BYTE original[BIG_REQUEST]; CK_BYTE cipher[BIG_REQUEST]; CK_BYTE clear[BIG_REQUEST]; CK_ULONG orig_len, cipher_len, clear_len; CK_ULONG key_len = keylength / 8; CK_BYTE init_v[16] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }; CK_ULONG i, iterations = 50000; SYSTEMTIME t1, t2; CK_ULONG avg_time, tot_time, min_time, max_time, diff; testcase_begin("AES Encrypt with mode=%s keylen=%ld datalen=%d\n", mode, key_len * 8, BIG_REQUEST); slot_id = SLOT_ID; testcase_rw_session(); testcase_user_login(); mech.mechanism = CKM_AES_KEY_GEN; mech.ulParameterLen = 0; mech.pParameter = NULL; rc = generate_AESKey(session, key_len, &mech, &h_key); if (rc != CKR_OK) { testcase_error("C_GenerateKey rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } // clear buffers memset(original, 0, BIG_REQUEST); memset(clear, 0, BIG_REQUEST); memset(cipher, 0, BIG_REQUEST); // encrypt some data orig_len = BIG_REQUEST; for (i = 0; i < orig_len; i++) original[i] = i % 255; if (strcmp(mode, "ECB") == 0) { mech.mechanism = CKM_AES_ECB; mech.ulParameterLen = 0; mech.pParameter = NULL; } else if (strcmp(mode, "CBC") == 0) { mech.mechanism = CKM_AES_CBC; mech.ulParameterLen = 16; mech.pParameter = init_v; } else { testcase_error("unknown mode %s in do_AES_EncrDecr()", mode); rc = CKR_MECHANISM_INVALID; goto testcase_cleanup; } tot_time = 0; max_time = 0; min_time = 0xFFFFFFFF; for (i = 0; i < iterations + 2; i++) { GetSystemTime(&t1); rc = funcs->C_EncryptInit(session, &mech, h_key); if (rc != CKR_OK) { testcase_error("C_EncryptInit rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } cipher_len = BIG_REQUEST; rc = funcs->C_Encrypt(session, original, orig_len, cipher, &cipher_len); if (rc != CKR_OK) { testcase_error("C_Encrypt rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } GetSystemTime(&t2); diff = delta_time_us(&t1, &t2); tot_time += diff; if (diff < min_time) min_time = diff; if (diff > max_time) max_time = diff; } tot_time -= min_time; tot_time -= max_time; avg_time = tot_time / iterations; // us -> ms tot_time /= 1000; printf("%ld iterations: total=%ldms min=%ldus max=%ldus avg=%ldus " "op/s=%.3f %.3fMB/s\n\n", iterations, tot_time, min_time, max_time, avg_time, (double) (iterations * 1000) / (double) tot_time, (((double) (iterations * 1000) / (double) (1024 * 1024)) * BIG_REQUEST) / (double) tot_time); printf("AES Decrypt with mode=%s keylen=%ld datalen=%d\n", mode, key_len * 8, BIG_REQUEST); tot_time = 0; max_time = 0; min_time = 0xFFFFFFFF; for (i = 0; i < iterations + 2; i++) { GetSystemTime(&t1); 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; } clear_len = BIG_REQUEST; rc = funcs->C_Decrypt(session, cipher, cipher_len, clear, &clear_len); if (rc != CKR_OK) { testcase_error("C_Decrypt rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } GetSystemTime(&t2); diff = delta_time_us(&t1, &t2); tot_time += diff; if (diff < min_time) min_time = diff; if (diff > max_time) max_time = diff; } tot_time -= min_time; tot_time -= max_time; avg_time = tot_time / iterations; // us -> ms tot_time /= 1000; printf("%ld iterations: total=%ldms min=%ldus max=%ldus avg=%ldus " "op/s=%.3f %.3fMB/s\n\n", iterations, tot_time, min_time, max_time, avg_time, (double) (iterations * 1000) / (double) tot_time, (((double) (iterations * 1000) / (double) (1024 * 1024)) * BIG_REQUEST) / (double) tot_time); testcase_cleanup: rv = funcs->C_CloseAllSessions(slot_id); if (rv != CKR_OK) { testcase_error("C_CloseAllSessions rc=%s", p11_get_ckr(rv)); return FALSE; } return TRUE; } int do_SHA(const char *mode) { CK_SLOT_ID slot_id; CK_SESSION_HANDLE session; CK_MECHANISM mech; CK_FLAGS flags; CK_RV rc, rv; CK_BYTE data[BIG_REQUEST]; CK_BYTE hash[MAX_HASH_LEN]; CK_ULONG data_len, hash_len, h_len; SYSTEMTIME t1, t2; CK_ULONG diff, avg_time, tot_time, min_time, max_time; CK_ULONG i, iterations = 20000; printf("SHA (%s) with datalen=%d\n", mode, BIG_REQUEST); slot_id = SLOT_ID; testcase_rw_session(); mech.ulParameterLen = 0; mech.pParameter = NULL; if (strcmp(mode, "SHA1") == 0) { mech.mechanism = CKM_SHA_1; hash_len = SHA1_HASH_LEN; } else if (strcmp(mode, "SHA256") == 0) { mech.mechanism = CKM_SHA256; hash_len = SHA256_HASH_LEN; } else if (strcmp(mode, "SHA512") == 0) { mech.mechanism = CKM_SHA512; hash_len = SHA512_HASH_LEN; } else { testcase_error("unknown mode %s in do_SHA()", mode); rc = CKR_MECHANISM_INVALID; goto testcase_cleanup; } // generate some data to hash // data_len = BIG_REQUEST; memset(data, 0, data_len); for (i = 0; i < data_len; i++) data[i] = i % 255; tot_time = 0; max_time = 0; min_time = 0xFFFFFFFF; for (i = 0; i < iterations + 2; i++) { GetSystemTime(&t1); rc = funcs->C_DigestInit(session, &mech); if (rc != CKR_OK) { testcase_error("C_DigestInit rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } h_len = sizeof(hash); rc = funcs->C_Digest(session, data, data_len, hash, &h_len); if (rc != CKR_OK) { testcase_error("C_Digest rc=%s", p11_get_ckr(rc)); goto testcase_cleanup; } if (h_len != hash_len) { testcase_error ("returned hashlen %ld doesn't match to expected len %ld\n", h_len, hash_len); rc = CKR_FUNCTION_FAILED; goto testcase_cleanup; } GetSystemTime(&t2); diff = delta_time_us(&t1, &t2); tot_time += diff; if (diff < min_time) min_time = diff; if (diff > max_time) max_time = diff; } tot_time -= min_time; tot_time -= max_time; avg_time = tot_time / iterations; // us -> ms tot_time /= 1000; printf("%ld iterations: total=%ldms min=%ldus max=%ldus avg=%ldus " "op/s=%.3f %.3fMB/s\n\n", iterations, tot_time, min_time, max_time, avg_time, (double) (iterations * 1000) / (double) tot_time, (((double) (iterations * 1000) / (double) (1024 * 1024)) * BIG_REQUEST) / (double) tot_time); testcase_cleanup: rv = funcs->C_CloseAllSessions(slot_id); if (rv != CKR_OK) { testcase_error("C_CloseAllSessions rv=%s", p11_get_ckr(rv)); return FALSE; } return TRUE; } int do_DummyFunction(void) { #if DUMMY CK_SLOT_ID slot_id; CK_ULONG i, diff, avg_time, min_time, max_time; CK_ULONG iterations = 1000; SYSTEMTIME t1, t2; testcase_begin("do_DummyFunction..."); slot_id = SLOT_ID; tot_time = 0; max_time = 0; min_time = 0xFFFFFFFF; for (i = 0; i < iterations + 2; i++) { GetSystemTime(&t1); DummyFunction(slot_id); GetSystemTime(&t2); diff = delta_time_us(&t1, &t2); tot_time += diff; if (diff < min_time) min_time = diff; if (diff > max_time) max_time = diff; } tot_time -= min_time; tot_time -= max_time; avg_time = tot_time / iterations; // us -> ms tot_time /= 1000; min_time /= 1000; max_time /= 1000; printf("%ld iterations: total=%ldms min=%ldms max=%ldms avg=%ldms " "op/s=%.3f\n\n", iterations, tot_time, min_time, max_time, avg_time, (double) (iterations * 1000) / (double) tot_time); #endif return TRUE; } void speed_usage(char *fct) { printf("usage: %s -slot ", fct); printf(" [-rsa_keygen] [-rsa_signverify]"); printf(" [-rsa_endecrypt] [-des3] [-aes] [-sha]"); printf(" [-h] \n\n"); return; } int main(int argc, char **argv) { CK_C_INITIALIZE_ARGS cinit_args; int rc, i; int do_rsa_keygen = 0; int do_rsa_signverify = 0; int do_rsa_endecrypt = 0; int do_des3_endecrypt = 0; int do_aes_endecrypt = 0; int do_sha = 0; SLOT_ID = 1000; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-slot") == 0) { SLOT_ID = atoi(argv[i + 1]); i++; continue; } if (strcmp(argv[i], "-rsa_keygen") == 0) { do_rsa_keygen = 1; } else if (strcmp(argv[i], "-rsa_signverify") == 0) { do_rsa_signverify = 1; } else if (strcmp(argv[i], "-rsa_endecrypt") == 0) { do_rsa_endecrypt = 1; } else if (strcmp(argv[i], "-des3") == 0) { do_des3_endecrypt = 1; } else if (strcmp(argv[i], "-aes") == 0) { do_aes_endecrypt = 1; } else if (strcmp(argv[i], "-sha") == 0) { do_sha = 1; } else if (strcmp(argv[i], "-h") == 0) { speed_usage(argv[0]); return 0; } else { printf("unknown option '%s'\n", argv[i]); speed_usage(argv[0]); return 1; } } // error if slot has not been identified. if (SLOT_ID == 1000) { printf("Please specify the slot to be tested.\n"); speed_usage(argv[0]); return 1; } if (do_rsa_keygen + do_rsa_signverify + do_rsa_endecrypt + do_des3_endecrypt + do_aes_endecrypt + do_sha == 0) { do_rsa_keygen = 1; do_rsa_signverify = 1; do_rsa_endecrypt = 1; do_des3_endecrypt = 1; do_aes_endecrypt = 1; do_sha = 1; } printf("Using slot #%lu...\n\n", SLOT_ID); rc = do_GetFunctionList(); if (!rc) return rc; memset(&cinit_args, 0x0, sizeof(cinit_args)); cinit_args.flags = CKF_OS_LOCKING_OK; funcs->C_Initialize(&cinit_args); if (do_rsa_keygen) { rc = do_RSA_KeyGen(1024); if (!rc) return rc; rc = do_RSA_KeyGen(2048); if (!rc) return rc; rc = do_RSA_KeyGen(4096); if (!rc) return rc; } if (do_rsa_signverify) { rc = do_RSA_PKCS_SignVerify(1024); if (!rc) return rc; rc = do_RSA_PKCS_SignVerify(2048); if (!rc) return rc; rc = do_RSA_PKCS_SignVerify(4096); if (!rc) return rc; } if (do_rsa_endecrypt) { rc = do_RSA_PKCS_EncryptDecrypt(1024); if (!rc) return rc; rc = do_RSA_PKCS_EncryptDecrypt(2048); if (!rc) return rc; rc = do_RSA_PKCS_EncryptDecrypt(4096); if (!rc) return rc; } if (do_des3_endecrypt) { rc = do_DES3_EncrDecr("ECB"); if (!rc) return rc; rc = do_DES3_EncrDecr("CBC"); if (!rc) return rc; } if (do_aes_endecrypt) { rc = do_AES_EncrDecr(128, "ECB"); if (!rc) return rc; rc = do_AES_EncrDecr(128, "CBC"); if (!rc) return rc; rc = do_AES_EncrDecr(192, "ECB"); if (!rc) return rc; rc = do_AES_EncrDecr(192, "CBC"); if (!rc) return rc; rc = do_AES_EncrDecr(256, "ECB"); if (!rc) return rc; rc = do_AES_EncrDecr(256, "CBC"); if (!rc) return rc; } if (do_sha) { rc = do_SHA("SHA1"); if (!rc) return rc; rc = do_SHA("SHA256"); if (!rc) return rc; rc = do_SHA("SHA512"); if (!rc) return rc; } funcs->C_Finalize(NULL); return 0; }