/*
* 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 <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <memory.h>
#include "pkcs11types.h"
#include "regress.h"
#include "digest.h"
#include "common.c"
#define DIGEST_UPDATE_SIZE 32
/** Tests messge digest with published test vectors. **/
CK_RV do_Digest(struct digest_test_suite_info *tsuite)
{
unsigned 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++) {
/** begin test **/
testcase_begin("Starting %s Digest with test vector %d.",
tsuite->name, 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.\n expected"
" 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;
}
/** Tests multipart message digest with published test vectors. **/
CK_RV do_DigestUpdate(struct digest_test_suite_info * tsuite)
{
unsigned int i;
CK_BYTE data[MAX_DATA_SIZE];
CK_ULONG data_len, data_done;
CK_BYTE actual[MAX_HASH_SIZE];
CK_ULONG actual_len;
CK_BYTE expected[MAX_HASH_SIZE];
CK_ULONG len, expected_len;
CK_MECHANISM mech;
CK_SESSION_HANDLE session;
CK_SLOT_ID slot_id = SLOT_ID;
CK_ULONG flags;
CK_RV rc;
/** begin test **/
testsuite_begin("Starting %s Multipart 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++) {
/** begin test **/
testcase_begin("Starting %s Multipart Digest with test vector %d.",
tsuite->name, 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_done = 0;
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 mechanism **/
mech = tsuite->mech;
/** initialize multipart 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);
/* do multipart digest
* if test vector contains chunks, use that.
* Otherwise, just call update on entire data.
*
* Note: for chunks, -1 is NULL, and 0 is empty string,
* and a value > 0 is amount of data from test vector's
* plaintext data. This way we test chunks that
* are NULL or empty string when updating.
*/
if (tsuite->tv[i].num_chunks) {
int j;
CK_BYTE *data_chunk = NULL;
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 = data + data_done;
}
rc = funcs->C_DigestUpdate(session, data_chunk, len);
if (rc != CKR_OK) {
testcase_error("C_DigestUpdate rc=%s", p11_get_ckr(rc));
goto testcase_cleanup;
}
data_done += len;
}
} else {
rc = funcs->C_DigestUpdate(session, data, data_len);
if (rc != CKR_OK) {
testcase_error("C_DigestUpdate rc=%s", p11_get_ckr(rc));
goto testcase_cleanup;
}
}
/** finalize multipart digest **/
rc = funcs->C_DigestFinal(session, actual, &actual_len);
if (rc != CKR_OK) {
testcase_error("C_DigestFinal rc=%s", p11_get_ckr(rc));
goto testcase_cleanup;
}
/** compare multipart digest results with expected results **/
testcase_new_assertion();
if (actual_len != expected_len) {
testcase_fail("hashed multipart data length does not "
"match test vector's hashed data length.\n");
} else if (memcmp(actual, expected, expected_len)) {
testcase_fail("hashed multipart data does not match "
"test vector's hashed data.\n");
} else {
testcase_pass("%s Multipart 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;
}
/** Tests signature verification with published test vectors. **/
CK_RV do_Sign_FIPS_HMAC_GENERAL(struct HMAC_TEST_SUITE_INFO * tsuite)
{
unsigned int i;
CK_MECHANISM mech;
CK_BYTE key[MAX_KEY_SIZE], data[MAX_DATA_SIZE];
CK_ULONG key_len, data_len, actual_mac_len, expected_mac_len, mac_size;
CK_BYTE actual_mac[MAX_HASH_SIZE], expected_mac[MAX_HASH_SIZE];
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.", 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 %s with test vector %d.", tsuite->name, i);
/** get mechanism and set parameter **/
mech = tsuite->mech;
mac_size = tsuite->tv[i].mac_len;
mech.ulParameterLen = sizeof(CK_ULONG);
mech.pParameter = &mac_size;
/** clear buffers **/
memset(key, 0, sizeof(key));
memset(data, 0, sizeof(data));
memset(actual_mac, 0, sizeof(actual_mac));
memset(expected_mac, 0, sizeof(expected_mac));
/** get test vector info **/
data_len = tsuite->tv[i].data_len;
actual_mac_len = sizeof(actual_mac);
expected_mac_len = tsuite->tv[i].mac_len;
key_len = tsuite->tv[i].key_len;
memcpy(key, tsuite->tv[i].key, key_len);
memcpy(data, tsuite->tv[i].data, data_len);
memcpy(expected_mac, tsuite->tv[i].mac, expected_mac_len);
/** 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_mac,
&actual_mac_len);
if (rc != CKR_OK) {
testcase_error("C_Sign rc=%s", p11_get_ckr(rc));
goto error;
}
/** compare sign/verify results with expected results **/
testcase_new_assertion();
if (actual_mac_len != expected_mac_len) {
testcase_fail("hashed data length does not match test "
"vector's hashed data length\nexpected "
"length=%ld, found length=%ld",
expected_mac_len, actual_mac_len);
goto error;
} else if (memcmp(actual_mac, expected_mac, expected_mac_len)) {
testcase_fail("hashed data does not match test "
"vector's hashed data");
goto error;
} else {
testcase_pass("%s Sign with test vector %d passed",
tsuite->name, i);
}
error:
/** 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;
}
}
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_Verify_FIPS_HMAC_GENERAL(struct HMAC_TEST_SUITE_INFO * tsuite)
{
unsigned int i;
CK_MECHANISM mech;
CK_BYTE key[MAX_KEY_SIZE], data[MAX_DATA_SIZE];
CK_ULONG key_len, data_len, expected_mac_len, mac_size;
CK_BYTE expected_mac[MAX_HASH_SIZE];
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 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("Verify %s with test vector %d.", tsuite->name, i);
/** get mechanism and set parameter **/
mech = tsuite->mech;
mac_size = tsuite->tv[i].mac_len;
mech.ulParameterLen = sizeof(CK_ULONG);
mech.pParameter = &mac_size;
/** clear buffers **/
memset(key, 0, sizeof(key));
memset(data, 0, sizeof(data));
memset(expected_mac, 0, sizeof(expected_mac));
/** get test vector info **/
data_len = tsuite->tv[i].data_len;
expected_mac_len = tsuite->tv[i].mac_len;
key_len = tsuite->tv[i].key_len;
memcpy(key, tsuite->tv[i].key, key_len);
memcpy(data, tsuite->tv[i].data, data_len);
memcpy(expected_mac, tsuite->tv[i].mac, expected_mac_len);
/** 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;
}
/** 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;
}
/** see if signature verifies **/
testcase_new_assertion();
/** do verification **/
rc = funcs->C_Verify(session, data, data_len, expected_mac,
expected_mac_len);
if (rc != CKR_OK)
testcase_fail("C_Verify rc=%s", p11_get_ckr(rc));
else
testcase_pass("%s C_Verify with test vector %d passed",
tsuite->name, i);
error:
/** 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;
}
}
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 generation with published test vectors. **/
CK_RV do_Sign_FIPS_HMAC(struct HMAC_TEST_SUITE_INFO * tsuite)
{
unsigned int i;
CK_MECHANISM mech;
CK_BYTE key[MAX_KEY_SIZE], data[MAX_DATA_SIZE];
CK_ULONG key_len, data_len, actual_mac_len, expected_mac_len;
CK_BYTE actual_mac[MAX_HASH_SIZE], expected_mac[MAX_HASH_SIZE];
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.", 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 %s with test vector %d.", tsuite->name, i);
/** get mechanism **/
mech = tsuite->mech;
/* only run hmac testcases with appropriate mac length */
switch (mech.mechanism) {
case CKM_SHA_1_HMAC:
if (tsuite->tv[i].mac_len != 20) {
testcase_skip("Skip, this testcase is not" " for SHA1 HMAC");
continue;
}
break;
case CKM_SHA224_HMAC:
if (tsuite->tv[i].mac_len != 28) {
testcase_skip("Skip, this testcase is not" " for SHA224 HMAC");
continue;
}
break;
case CKM_SHA256_HMAC:
if (tsuite->tv[i].mac_len != 32) {
testcase_skip("Skip, this testcase is not" " for SHA256 HMAC");
continue;
}
break;
case CKM_SHA384_HMAC:
if (tsuite->tv[i].mac_len != 48) {
testcase_skip("Skip, this testcase is not" " for SHA384 HMAC");
continue;
}
break;
case CKM_SHA512_HMAC:
if (tsuite->tv[i].mac_len != 64) {
testcase_skip("Skip, this testcase is not" " for SHA512 HMAC");
continue;
}
break;
default:
testcase_error("Invalid Mechanism\n");
goto testcase_cleanup;
}
/** clear buffers **/
memset(key, 0, sizeof(key));
memset(data, 0, sizeof(data));
memset(actual_mac, 0, sizeof(actual_mac));
memset(expected_mac, 0, sizeof(expected_mac));
/** get test vector info **/
data_len = tsuite->tv[i].data_len;
actual_mac_len = sizeof(actual_mac);
expected_mac_len = tsuite->tv[i].mac_len;
key_len = tsuite->tv[i].key_len;
memcpy(key, tsuite->tv[i].key, key_len);
memcpy(data, tsuite->tv[i].data, data_len);
memcpy(expected_mac, tsuite->tv[i].mac, expected_mac_len);
/** 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_mac,
&actual_mac_len);
if (rc != CKR_OK) {
testcase_error("C_Sign rc=%s", p11_get_ckr(rc));
goto error;
}
/** compare sign results with expected results **/
testcase_new_assertion();
if (actual_mac_len != expected_mac_len) {
testcase_fail("hashed data length does not match test "
"vector's hashed data length\nexpected "
"length=%ld, found length=%ld",
expected_mac_len, actual_mac_len);
} else if (memcmp(actual_mac, expected_mac, expected_mac_len)) {
testcase_fail("hashed data does not match test "
"vector's hashed data");
} else {
testcase_pass("%s C_Sign with test vector %d passed.",
tsuite->name, i);
}
error:
/** 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;
}
}
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 generation with published test vectors. **/
CK_RV do_Verify_FIPS_HMAC(struct HMAC_TEST_SUITE_INFO * tsuite)
{
unsigned int i;
CK_MECHANISM mech;
CK_BYTE key[MAX_KEY_SIZE], data[MAX_DATA_SIZE];
CK_ULONG key_len, data_len, expected_mac_len;
CK_BYTE expected_mac[MAX_HASH_SIZE];
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 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("Verify %s with test vector %d.", tsuite->name, i);
/** get mechanism **/
mech = tsuite->mech;
/* only run hmac testcases with appropriate mac length */
switch (mech.mechanism) {
case CKM_SHA_1_HMAC:
if (tsuite->tv[i].mac_len != 20) {
testcase_skip("Skip, this testcase is not" " for SHA1 HMAC");
continue;
}
break;
case CKM_SHA224_HMAC:
if (tsuite->tv[i].mac_len != 28) {
testcase_skip("Skip, this testcase is not" " for SHA224 HMAC");
continue;
}
break;
case CKM_SHA256_HMAC:
if (tsuite->tv[i].mac_len != 32) {
testcase_skip("Skip, this testcase is not" " for SHA256 HMAC");
continue;
}
break;
case CKM_SHA384_HMAC:
if (tsuite->tv[i].mac_len != 48) {
testcase_skip("Skip, this testcase is not" " for SHA384 HMAC");
continue;
}
break;
case CKM_SHA512_HMAC:
if (tsuite->tv[i].mac_len != 64) {
testcase_skip("Skip, this testcase is not" " for SHA512 HMAC");
continue;
}
break;
default:
testcase_error("Invalid Mechanism\n");
goto testcase_cleanup;
}
/** clear buffers **/
memset(key, 0, sizeof(key));
memset(data, 0, sizeof(data));
memset(expected_mac, 0, sizeof(expected_mac));
/** get test vector info **/
data_len = tsuite->tv[i].data_len;
expected_mac_len = tsuite->tv[i].mac_len;
key_len = tsuite->tv[i].key_len;
memcpy(key, tsuite->tv[i].key, key_len);
memcpy(data, tsuite->tv[i].data, data_len);
memcpy(expected_mac, tsuite->tv[i].mac, expected_mac_len);
/** 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;
}
/** 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;
}
testcase_new_assertion();
/** do verification **/
rc = funcs->C_Verify(session, data, data_len, expected_mac,
expected_mac_len);
if (rc != CKR_OK)
testcase_fail("C_Verify rc=%s", p11_get_ckr(rc));
else
testcase_pass("%s C_Verify with test vector %d passed.",
tsuite->name, i);
error:
/** 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;
}
}
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 generation with published test vectors. **/
CK_RV do_SignUpdate_FIPS_HMAC(struct HMAC_TEST_SUITE_INFO * tsuite)
{
unsigned int i;
CK_MECHANISM mech;
CK_BYTE key[MAX_KEY_SIZE], data[MAX_DATA_SIZE];
CK_ULONG key_len, data_len, actual_mac_len, expected_mac_len;
CK_BYTE actual_mac[MAX_HASH_SIZE], expected_mac[MAX_HASH_SIZE];
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 SignUpdate.", 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("Multipart SignUpdate %s with test vector %d.",
tsuite->name, i);
/** get mechanism and set parameter **/
mech = tsuite->mech;
/* only run hmac testcases with appropriate mac length */
switch (mech.mechanism) {
case CKM_SHA_1_HMAC:
if (tsuite->tv[i].mac_len != 20) {
testcase_skip("Skip, testcase not applicable" " to SHA1 HMAC");
continue;
}
break;
case CKM_SHA224_HMAC:
if (tsuite->tv[i].mac_len != 28) {
testcase_skip("Skip, testcase not applicable"
" to SHA224 HMAC");
continue;
}
break;
case CKM_SHA256_HMAC:
if (tsuite->tv[i].mac_len != 32) {
testcase_skip("Skip, testcase not applicable"
" to SHA256 HMAC");
continue;
}
break;
case CKM_SHA384_HMAC:
if (tsuite->tv[i].mac_len != 48) {
testcase_skip("Skip, testcase not applicable"
" to SHA384 HMAC");
continue;
}
break;
case CKM_SHA512_HMAC:
if (tsuite->tv[i].mac_len != 64) {
testcase_skip("Skip, testcase not applicable"
" to SHA512 HMAC");
continue;
}
break;
default:
testcase_error("Invalid Mechanism\n");
goto testcase_cleanup;
}
/** clear buffers **/
memset(key, 0, sizeof(key));
memset(data, 0, sizeof(data));
memset(actual_mac, 0, sizeof(actual_mac));
memset(expected_mac, 0, sizeof(expected_mac));
/** get test vector info **/
data_len = tsuite->tv[i].data_len;
actual_mac_len = sizeof(actual_mac);
expected_mac_len = tsuite->tv[i].mac_len;
key_len = tsuite->tv[i].key_len;
memcpy(key, tsuite->tv[i].key, key_len);
memcpy(data, tsuite->tv[i].data, data_len);
memcpy(expected_mac, tsuite->tv[i].mac, expected_mac_len);
/** 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;
}
/* for chunks, -1 is NULL, and 0 is empty string,
* and a value > 0 is amount of data from test vector's
* plaintext data. This way we test vary-sized chunks.
*/
if (tsuite->tv[i].num_chunks) {
int j, k = 0;
CK_ULONG len;
CK_BYTE *data_chunk = NULL;
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 = data + k;
}
rc = funcs->C_SignUpdate(session, data_chunk, len);
if (rc != CKR_OK) {
testcase_error("C_SignUpdate rc=%s", p11_get_ckr(rc));
goto error;
}
k += len;
}
} else {
rc = funcs->C_SignUpdate(session, data, data_len);
if (rc != CKR_OK) {
testcase_error("C_SignUpdate rc=%s", p11_get_ckr(rc));
goto error;
}
}
rc = funcs->C_SignFinal(session, actual_mac, &actual_mac_len);
if (rc != CKR_OK) {
testcase_error("C_SignFinal rc=%s", p11_get_ckr(rc));
goto error;
}
/** compare results with expected results **/
testcase_new_assertion();
if (actual_mac_len != expected_mac_len) {
testcase_fail("hashed data length does not match test "
"vector's hashed data length\nexpected "
"length=%ld, found length=%ld",
expected_mac_len, actual_mac_len);
} else if (memcmp(actual_mac, expected_mac, expected_mac_len)) {
testcase_fail("hashed data does not match test "
"vector's hashed data");
} else {
testcase_pass("%s Sign with test vector %d passed.",
tsuite->name, i);
}
error:
/** 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;
}
}
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_VerifyUpdate_FIPS_HMAC(struct HMAC_TEST_SUITE_INFO * tsuite)
{
unsigned int i;
CK_MECHANISM mech;
CK_BYTE key[MAX_KEY_SIZE], data[MAX_DATA_SIZE];
CK_ULONG key_len, data_len, expected_mac_len;
CK_BYTE expected_mac[MAX_HASH_SIZE];
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 VerifyUpdate.", 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("Multipart VerifyUpdate %s with test vector %d.",
tsuite->name, i);
/** get mechanism and set parameter **/
mech = tsuite->mech;
/* only run hmac testcases with appropriate mac length */
switch (mech.mechanism) {
case CKM_SHA_1_HMAC:
if (tsuite->tv[i].mac_len != 20) {
testcase_skip("Skip, testcase not applicable" " to SHA1 HMAC");
continue;
}
break;
case CKM_SHA224_HMAC:
if (tsuite->tv[i].mac_len != 28) {
testcase_skip("Skip, testcase not applicable"
" to SHA224 HMAC");
continue;
}
break;
case CKM_SHA256_HMAC:
if (tsuite->tv[i].mac_len != 32) {
testcase_skip("Skip, testcase not applicable"
" to SHA256 HMAC");
continue;
}
break;
case CKM_SHA384_HMAC:
if (tsuite->tv[i].mac_len != 48) {
testcase_skip("Skip, testcase not applicable"
" to SHA384 HMAC");
continue;
}
break;
case CKM_SHA512_HMAC:
if (tsuite->tv[i].mac_len != 64) {
testcase_skip("Skip, testcase not applicable"
" to SHA512 HMAC");
continue;
}
break;
default:
testcase_error("Invalid Mechanism\n");
goto testcase_cleanup;
}
/** clear buffers **/
memset(key, 0, sizeof(key));
memset(data, 0, sizeof(data));
memset(expected_mac, 0, sizeof(expected_mac));
/** get test vector info **/
data_len = tsuite->tv[i].data_len;
expected_mac_len = tsuite->tv[i].mac_len;
key_len = tsuite->tv[i].key_len;
memcpy(key, tsuite->tv[i].key, key_len);
memcpy(data, tsuite->tv[i].data, data_len);
memcpy(expected_mac, tsuite->tv[i].mac, expected_mac_len);
/** 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_VerifyInit(session, &mech, h_key);
if (rc != CKR_OK) {
testcase_error("C_SignInit rc=%s", p11_get_ckr(rc));
goto error;
}
/* for chunks, -1 is NULL, and 0 is empty string,
* and a value > 0 is amount of data from test vector's
* plaintext data. This way we test vary-sized chunks.
*/
if (tsuite->tv[i].num_chunks) {
int j, k = 0;
CK_ULONG len;
CK_BYTE *data_chunk = NULL;
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 = data + k;
}
rc = funcs->C_VerifyUpdate(session, data_chunk, len);
if (rc != CKR_OK) {
testcase_error("C_VerifyUpdate rc=%s", p11_get_ckr(rc));
goto error;
}
k += len;
}
} else {
rc = funcs->C_VerifyUpdate(session, data, data_len);
if (rc != CKR_OK) {
testcase_error("C_SignUpdate rc=%s", p11_get_ckr(rc));
goto error;
}
}
testcase_new_assertion();
rc = funcs->C_VerifyFinal(session, expected_mac, expected_mac_len);
if (rc != CKR_OK)
testcase_fail("C_VerifyFinal rc=%s", p11_get_ckr(rc));
else
testcase_pass("%s Verfied with test vector %d passed.",
tsuite->name, i);
error:
/** 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;
}
}
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)
{
unsigned 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);
/** get mechanism **/
mech = tsuite->mech;
/* for ep11, check if key len is supported */
key_len = tsuite->tv[i].key_len;
if ((is_ep11_token(SLOT_ID) || is_cca_token(SLOT_ID)) &&
(!check_supp_keysize(SLOT_ID, mech.mechanism, key_len * 8))) {
testcase_skip("keysize %d is not supported in slot %ld",
(unsigned int) key_len, slot_id);
continue;
}
/** 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 **/
data_len = tsuite->tv[i].data_len;
actual_len = sizeof(actual);
expected_len = tsuite->tv[i].mac_len;
memcpy(key, tsuite->tv[i].key, key_len);
memcpy(data, tsuite->tv[i].data, data_len);
memcpy(expected, tsuite->tv[i].mac, expected_len);
/** 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);
}
error:
/** 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;
}
}
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_Update(struct HMAC_TEST_SUITE_INFO * tsuite)
{
int len1 = 0, len2 = 0;
unsigned 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("Multipart Sign Verify %s with test vector %d.",
tsuite->name, i);
/** get mechanism **/
mech = tsuite->mech;
/* for ep11, check if key len is supported */
key_len = tsuite->tv[i].key_len;
if ((is_ep11_token(SLOT_ID) || is_cca_token(SLOT_ID)) &&
(!check_supp_keysize(SLOT_ID, mech.mechanism, key_len * 8))) {
testcase_skip("keysize %d is not supported in slot %ld",
(unsigned int) key_len, slot_id);
continue;
}
/** 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 **/
data_len = tsuite->tv[i].data_len;
actual_len = sizeof(actual);
expected_len = tsuite->tv[i].mac_len;
memcpy(key, tsuite->tv[i].key, key_len);
memcpy(data, tsuite->tv[i].data, data_len);
memcpy(expected, tsuite->tv[i].mac, expected_len);
/** 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 multipart signing **/
if (data_len > 0) {
/* do in 2 parts */
if (data_len < 20) {
len1 = data_len;
} else {
len1 = data_len - 20;
len2 = 20;
}
rc = funcs->C_SignUpdate(session, data, len1);
if (rc != CKR_OK) {
testcase_error("C_SignUpdate rc=%s", p11_get_ckr(rc));
goto error;
}
if (len2) {
rc = funcs->C_SignUpdate(session, data + len1, len2);
if (rc != CKR_OK) {
testcase_error("C_SignUpdate rc=%s", p11_get_ckr(rc));
goto error;
}
}
}
rc = funcs->C_SignFinal(session, actual, &actual_len);
if (rc != CKR_OK) {
testcase_error("C_SignFinal 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 **/
if (data_len > 0) {
rc = funcs->C_VerifyUpdate(session, data, len1);
if (rc != CKR_OK) {
testcase_error("C_VerifyUpdate rc=%s", p11_get_ckr(rc));
goto error;
}
if (len2) {
rc = funcs->C_VerifyUpdate(session, data + len1, len2);
if (rc != CKR_OK) {
testcase_error("C_VerifyUpdate rc=%s", p11_get_ckr(rc));
goto error;
}
}
}
rc = funcs->C_VerifyFinal(session, actual, actual_len);
if (rc != CKR_OK) {
testcase_error("C_VerifyFinal 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 Multipart with test vector %d "
"passed.", tsuite->name, i);
}
error:
/** 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;
}
}
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 tests generating a generic secret key to be used
* with hmac sign and verify.
*/
CK_RV do_HMAC_SignVerify_WithGenKey(void)
{
CK_MECHANISM secret_mech = { CKM_GENERIC_SECRET_KEY_GEN, 0, 0 };
CK_MECHANISM hash_mech = { CKM_SHA_1_HMAC, 0, 0 };
CK_ULONG key_len = 20;
CK_BYTE data[] = { "Hi There" };
CK_ULONG data_len = 8;
CK_BYTE actual[MAX_HASH_SIZE];
CK_ULONG actual_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 test **/
testsuite_begin("do_HMAC_SignVerify_WithGenKey");
testcase_begin("Generate Generic Secret Key And Sign/Verify with it.");
testcase_rw_session();
testcase_user_login();
rc = CKR_OK; // set rc
/* skip test if mech is not supported with this slot,
* checking for generic secret key mechanism
* and also sha1-hmac mechanism
*/
if (!mech_supported(SLOT_ID, secret_mech.mechanism)) {
testsuite_skip(1, "mechanism %ld not supported with slot %ld",
secret_mech.mechanism, slot_id);
goto testcase_cleanup;
}
if (!mech_supported(SLOT_ID, hash_mech.mechanism)) {
testsuite_skip(1, "mechanism %ld not supported with slot %ld",
hash_mech.mechanism, slot_id);
goto testcase_cleanup;
}
/** clear buffers **/
memset(actual, 0, sizeof(actual));
/** get test vector info **/
actual_len = sizeof(actual);
/** generate key object **/
rc = generate_SecretKey(session, key_len, &secret_mech, &h_key);
if (rc != CKR_OK) {
testcase_error("generate_SecretKey rc=%s", p11_get_ckr(rc));
goto testcase_cleanup;
}
/** initialize signing **/
rc = funcs->C_SignInit(session, &hash_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;
}
/* Ensure the generated key can verify what it signed */
testcase_new_assertion();
/** initilaize verification **/
rc = funcs->C_VerifyInit(session, &hash_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_fail("C_Verify rc=%s", p11_get_ckr(rc));
else
testcase_pass("Sign Verify with generated generic secret key "
"passed.");
error:
if (funcs->C_DestroyObject(session, h_key) != CKR_OK)
testcase_error("C_DestroyObject rc=%s.", p11_get_ckr(rc));
testcase_cleanup:
testcase_user_logout();
if (funcs->C_CloseAllSessions(slot_id) != CKR_OK)
testcase_error("C_CloseAllSessions rc=%s", p11_get_ckr(rc));
return rc;
}
CK_RV digest_funcs()
{
CK_RV rc;
unsigned int i;
/** Digest tests **/
for (i = 0; i < NUM_DIGEST_TEST_SUITES; i++) {
rc = do_Digest(&digest_test_suites[i]);
if (rc && !no_stop) {
return rc;
}
}
/** Multipart Digest tests **/
for (i = 0; i < NUM_DIGEST_TEST_SUITES; i++) {
rc = do_DigestUpdate(&digest_test_suites[i]);
if (rc && !no_stop) {
return rc;
}
}
/** RFC HMAC tests **/
for (i = 0; i < NUM_OF_HMAC_TEST_SUITES; i++) {
rc = do_SignVerify_HMAC(&hmac_test_suites[i]);
if (rc && !no_stop)
return rc;
}
/** FIPS HMAC tests **/
for (i = 0; i < NUM_OF_FIPS_HMAC_TEST_SUITES; i++) {
rc = do_Sign_FIPS_HMAC(&fips_hmac_test_suites[i]);
if (rc && !no_stop)
break;
rc = do_Verify_FIPS_HMAC(&fips_hmac_test_suites[i]);
if (rc && !no_stop)
break;
rc = do_Sign_FIPS_HMAC_GENERAL(&fips_hmac_general_test_suites[i]);
if (rc && !no_stop)
break;
rc = do_Verify_FIPS_HMAC_GENERAL(&fips_hmac_general_test_suites[i]);
if (rc && !no_stop)
break;
}
/** HMAC Multipart tests **/
/* ica and tpm tokens do not yet support multipart hmac right now. */
if (!(is_ica_token(SLOT_ID)) && !(is_tpm_token(SLOT_ID))) {
for (i = 0; i < NUM_OF_FIPS_HMAC_TEST_SUITES; i++) {
rc = do_SignUpdate_FIPS_HMAC(&fips_hmac_test_suites[i]);
if (rc && !no_stop)
break;
rc = do_VerifyUpdate_FIPS_HMAC(&fips_hmac_test_suites[i]);
if (rc && !no_stop)
break;
}
}
/* HMAC test with a generated generic secret key */
rc = do_HMAC_SignVerify_WithGenKey();
return rc;
}
int main(int argc, char **argv)
{
CK_C_INITIALIZE_ARGS cinit_args;
int rc;
CK_BBOOL no_init;
CK_RV rv;
SLOT_ID = 0;
no_init = FALSE;
rc = do_ParseArgs(argc, argv);
if (rc != 1)
return rc;
printf("Using slot #%lu...\n\n", SLOT_ID);
printf("With option: no_init: %d\n", no_init);
rc = do_GetFunctionList();
if (!rc) {
PRINT_ERR("ERROR do_GetFunctionList() Failed , rc = 0x%0x\n", rc);
return rc;
}
memset(&cinit_args, 0x0, sizeof(cinit_args));
cinit_args.flags = CKF_OS_LOCKING_OK;
// SAB Add calls to ALL functions before the C_Initialize gets hit
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;
}
testcase_setup(0); //TODO
rv = digest_funcs();
testcase_print_result();
funcs->C_Finalize(NULL);
/* make sure we return non-zero if rv is non-zero */
return ((rv == 0) || (rv % 256) ? (int)rv : -1);
}