You've already forked opencryptoki
mirror of
https://github.com/opencryptoki/opencryptoki.git
synced 2026-10-24 05:39:17 +03:00
Add tests for CKM_TLS_PRE_MASTER_KEY_GEN and CKM_TLS_KEY_AND_MAC_DERIVE. Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
964 lines
28 KiB
C
964 lines
28 KiB
C
/*
|
|
* 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 <memory.h>
|
|
|
|
#include "pkcs11types.h"
|
|
#include "regress.h"
|
|
#include "common.c"
|
|
#include "mech_to_str.h"
|
|
|
|
static CK_BBOOL true = TRUE;
|
|
static CK_BBOOL false = FALSE;
|
|
|
|
//
|
|
//
|
|
CK_RV do_SignVerify_SSL3_MD5_MAC(CK_SESSION_HANDLE session)
|
|
{
|
|
CK_MECHANISM mech;
|
|
CK_ULONG mac_size;
|
|
CK_ULONG i;
|
|
CK_RV rc = CKR_OK;
|
|
|
|
CK_OBJECT_HANDLE h_key;
|
|
CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
|
|
CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
|
|
CK_BBOOL false = FALSE;
|
|
CK_BYTE hash[MD5_HASH_LEN];
|
|
CK_BYTE data[50];
|
|
CK_BYTE data2[500];
|
|
CK_BYTE key_data[48];
|
|
CK_ULONG hash_len;
|
|
CK_ULONG data_len;
|
|
CK_ATTRIBUTE key_attribs[] = {
|
|
{CKA_CLASS, &key_class, sizeof(key_class)},
|
|
{CKA_KEY_TYPE, &key_type, sizeof(key_type)},
|
|
{CKA_TOKEN, &false, sizeof(false)},
|
|
{CKA_VALUE, &key_data, sizeof(key_data)}
|
|
};
|
|
CK_SLOT_ID slot_id = SLOT_ID;
|
|
|
|
testcase_begin("starting do_SignVerify_SSL3_MD5_MAC...\n");
|
|
|
|
mac_size = 16;
|
|
|
|
mech.mechanism = CKM_SSL3_MD5_MAC;
|
|
mech.ulParameterLen = sizeof(CK_ULONG);
|
|
mech.pParameter = &mac_size;
|
|
|
|
|
|
/** skip test if the slot doesn't support this mechanism **/
|
|
if (!mech_supported(slot_id, mech.mechanism)) {
|
|
testsuite_skip(48, "Slot %u doesn't support %s (0x%x)",
|
|
(unsigned int) slot_id,
|
|
mech_to_str(mech.mechanism),
|
|
(unsigned int) mech.mechanism);
|
|
goto skipped;
|
|
}
|
|
|
|
for (i = 0; i < 48; i++)
|
|
key_data[i] = i;
|
|
|
|
memset(data, 0xb, 50);
|
|
data_len = 50;
|
|
|
|
rc = funcs->C_CreateObject(session, key_attribs, 4, &h_key);
|
|
if (rc != CKR_OK) {
|
|
if (is_rejected_by_policy(rc, session)) {
|
|
testcase_skip("key import is not allowed by policy");
|
|
return CKR_OK;
|
|
}
|
|
testcase_error("C_CreateObject() rc = %s", p11_get_ckr(rc));
|
|
return rc;
|
|
}
|
|
|
|
testcase_new_assertion();
|
|
rc = funcs->C_SignInit(session, &mech, h_key);
|
|
if (rc != CKR_OK) {
|
|
testcase_error("C_SignInit() rc = %s", p11_get_ckr(rc));
|
|
goto done;
|
|
}
|
|
|
|
hash_len = sizeof(hash);
|
|
rc = funcs->C_Sign(session, data, data_len, hash, &hash_len);
|
|
if (rc != CKR_OK) {
|
|
testcase_fail("C_Sign() rc = %s", p11_get_ckr(rc));
|
|
goto done;
|
|
}
|
|
|
|
if (hash_len != mac_size) {
|
|
testcase_fail("Error: C_Sign generated bad MAC length\n");
|
|
goto done;
|
|
} else {
|
|
testcase_pass("Successfully signed.");
|
|
}
|
|
|
|
testcase_new_assertion();
|
|
rc = funcs->C_VerifyInit(session, &mech, h_key);
|
|
if (rc != CKR_OK) {
|
|
testcase_error("C_VerifyInit() rc = %s", p11_get_ckr(rc));
|
|
goto done;
|
|
}
|
|
|
|
rc = funcs->C_Verify(session, data, data_len, hash, hash_len);
|
|
if (rc != CKR_OK)
|
|
testcase_fail("C_Verify() rc = %s", p11_get_ckr(rc));
|
|
else
|
|
testcase_pass("Successfully verified.");
|
|
|
|
rc = funcs->C_DestroyObject(session, h_key);
|
|
if (rc != CKR_OK) {
|
|
testcase_error("C_DestroyObject() rc = %s", p11_get_ckr(rc));
|
|
goto done;
|
|
}
|
|
// TESTCASE #2
|
|
|
|
for (i = 0; i < 48; i++)
|
|
key_data[i] = i;
|
|
|
|
memset(data2, 0xb, 500);
|
|
data_len = 500;
|
|
|
|
rc = funcs->C_CreateObject(session, key_attribs, 4, &h_key);
|
|
if (rc != CKR_OK) {
|
|
testcase_error("C_CreateObject() rc = %s", p11_get_ckr(rc));
|
|
goto done;
|
|
}
|
|
|
|
testcase_new_assertion();
|
|
rc = funcs->C_SignInit(session, &mech, h_key);
|
|
if (rc != CKR_OK) {
|
|
testcase_error("C_SignInit() rc = %s", p11_get_ckr(rc));
|
|
goto done;
|
|
}
|
|
|
|
for (i = 0; i < 500; i += 100) {
|
|
rc = funcs->C_SignUpdate(session, &data2[i], 100);
|
|
if (rc != CKR_OK) {
|
|
testcase_error("Iteration #%lu, C_SignUpdate() rc = %s", i / 100,
|
|
p11_get_ckr(rc));
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
hash_len = sizeof(hash);
|
|
rc = funcs->C_SignFinal(session, hash, &hash_len);
|
|
if (rc != CKR_OK) {
|
|
testcase_error("C_SignFinal() rc = %s", p11_get_ckr(rc));
|
|
goto done;
|
|
}
|
|
|
|
if (hash_len != mac_size) {
|
|
testcase_fail("Error: C_SignUpdate/Final generated bad MAC length\n");
|
|
goto done;
|
|
} else {
|
|
testcase_pass("Sucessfully signed in multipart.");
|
|
}
|
|
|
|
testcase_new_assertion();
|
|
rc = funcs->C_VerifyInit(session, &mech, h_key);
|
|
if (rc != CKR_OK) {
|
|
testcase_error("C_VerifyInit() rc = %s", p11_get_ckr(rc));
|
|
goto done;
|
|
}
|
|
|
|
for (i = 0; i < 500; i += 100) {
|
|
rc = funcs->C_VerifyUpdate(session, &data2[i], 100);
|
|
if (rc != CKR_OK) {
|
|
testcase_error("Iteration #%lu, C_VerifyUpdate() rc = %s", i / 100,
|
|
p11_get_ckr(rc));
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
rc = funcs->C_VerifyFinal(session, hash, hash_len);
|
|
if (rc != CKR_OK)
|
|
testcase_fail("C_VerifyFinal rc = %s", p11_get_ckr(rc));
|
|
else
|
|
testcase_pass("Successfully verified signature in multipart.");
|
|
|
|
done:
|
|
if (funcs->C_DestroyObject(session, h_key) != CKR_OK)
|
|
testcase_error("C_DestroyObject failed.");
|
|
|
|
skipped:
|
|
return rc;
|
|
}
|
|
|
|
|
|
//
|
|
//
|
|
CK_RV do_SignVerify_SSL3_SHA1_MAC(CK_SESSION_HANDLE session)
|
|
{
|
|
CK_MECHANISM mech;
|
|
CK_ULONG mac_size;
|
|
CK_ULONG i;
|
|
CK_RV rc = CKR_OK;
|
|
|
|
CK_OBJECT_HANDLE h_key;
|
|
CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
|
|
CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
|
|
CK_BBOOL false = FALSE;
|
|
CK_BYTE hash[SHA1_HASH_LEN];
|
|
CK_BYTE data[50];
|
|
CK_BYTE key_data[48];
|
|
CK_ULONG hash_len;
|
|
CK_ULONG data_len;
|
|
CK_ATTRIBUTE key_attribs[] = {
|
|
{CKA_CLASS, &key_class, sizeof(key_class)},
|
|
{CKA_KEY_TYPE, &key_type, sizeof(key_type)},
|
|
{CKA_TOKEN, &false, sizeof(false)},
|
|
{CKA_VALUE, &key_data, sizeof(key_data)}
|
|
};
|
|
CK_SLOT_ID slot_id = SLOT_ID;
|
|
|
|
testcase_begin("starting do_SignVerify_SSL3_SHA1_MAC...\n");
|
|
|
|
mac_size = 20;
|
|
|
|
mech.mechanism = CKM_SSL3_SHA1_MAC;
|
|
mech.ulParameterLen = sizeof(CK_ULONG);
|
|
mech.pParameter = &mac_size;
|
|
|
|
/** skip test if the slot doesn't support this mechanism **/
|
|
if (!mech_supported(slot_id, mech.mechanism)) {
|
|
testsuite_skip(48, "Slot %u doesn't support %s (0x%x)",
|
|
(unsigned int) slot_id,
|
|
mech_to_str(mech.mechanism),
|
|
(unsigned int) mech.mechanism);
|
|
goto skipped;
|
|
}
|
|
|
|
for (i = 0; i < 48; i++)
|
|
key_data[i] = i;
|
|
|
|
memset(data, 0xb, 50);
|
|
data_len = 50;
|
|
|
|
rc = funcs->C_CreateObject(session, key_attribs, 4, &h_key);
|
|
if (rc != CKR_OK) {
|
|
if (is_rejected_by_policy(rc, session)) {
|
|
testcase_skip("key import is not allowed by policy");
|
|
return CKR_OK;
|
|
}
|
|
testcase_error("C_CreateObject() rc = %s", p11_get_ckr(rc));
|
|
return rc;
|
|
}
|
|
|
|
testcase_new_assertion();
|
|
rc = funcs->C_SignInit(session, &mech, h_key);
|
|
if (rc != CKR_OK) {
|
|
testcase_fail("C_SignInit() rc = %s", p11_get_ckr(rc));
|
|
goto done;
|
|
}
|
|
|
|
hash_len = sizeof(hash);
|
|
rc = funcs->C_Sign(session, data, data_len, hash, &hash_len);
|
|
if (rc != CKR_OK) {
|
|
testcase_fail("C_Sign() rc = %s", p11_get_ckr(rc));
|
|
goto done;
|
|
}
|
|
|
|
if (hash_len != mac_size) {
|
|
testcase_fail("Error: C_Sign generated bad MAC length\n");
|
|
goto done;
|
|
} else {
|
|
testcase_pass("Successfully signed.");
|
|
}
|
|
|
|
testcase_new_assertion();
|
|
rc = funcs->C_VerifyInit(session, &mech, h_key);
|
|
if (rc != CKR_OK) {
|
|
testcase_error("C_VerifyInit() rc = %s", p11_get_ckr(rc));
|
|
goto done;
|
|
}
|
|
|
|
rc = funcs->C_Verify(session, data, data_len, hash, hash_len);
|
|
if (rc != CKR_OK)
|
|
testcase_fail("C_Verify() rc = %s", p11_get_ckr(rc));
|
|
else
|
|
testcase_pass("Successfully verified signature.");
|
|
|
|
done:
|
|
if (funcs->C_DestroyObject(session, h_key) != CKR_OK)
|
|
testcase_error("C_DestroyObject() failed.");
|
|
|
|
skipped:
|
|
return rc;
|
|
}
|
|
|
|
|
|
//
|
|
//
|
|
CK_RV do_SSL3_PreMasterKeyGen(CK_SESSION_HANDLE session)
|
|
{
|
|
CK_MECHANISM mech;
|
|
CK_VERSION version;
|
|
CK_OBJECT_HANDLE h_key;
|
|
CK_RV rc = CKR_OK;
|
|
CK_SLOT_ID slot_id = SLOT_ID;
|
|
|
|
testcase_begin("starting do_SSL3_PreMasterKeyGen...\n");
|
|
|
|
version.major = 3;
|
|
version.minor = 0;
|
|
|
|
mech.mechanism = CKM_SSL3_PRE_MASTER_KEY_GEN;
|
|
mech.pParameter = &version;
|
|
mech.ulParameterLen = sizeof(CK_VERSION);
|
|
|
|
/** skip test if the slot doesn't support this mechanism **/
|
|
if (!mech_supported(slot_id, mech.mechanism)) {
|
|
testsuite_skip(1, "Slot %u doesn't support %s (0x%x)",
|
|
(unsigned int) slot_id,
|
|
mech_to_str(mech.mechanism),
|
|
(unsigned int) mech.mechanism);
|
|
goto done;
|
|
}
|
|
|
|
testcase_new_assertion();
|
|
rc = funcs->C_GenerateKey(session, &mech, NULL, 0, &h_key);
|
|
if (rc != CKR_OK) {
|
|
if (is_rejected_by_policy(rc, session)) {
|
|
testcase_skip("key generation is not allowed by policy");
|
|
return CKR_OK;
|
|
}
|
|
testcase_fail("C_GenerateKey() rc = %s", p11_get_ckr(rc));
|
|
} else {
|
|
testcase_pass("Successfully generated a generic secret key.");
|
|
}
|
|
|
|
if (funcs->C_DestroyObject(session, h_key) != CKR_OK)
|
|
testcase_error("C_DestroyObject() failed");
|
|
|
|
done:
|
|
return rc;
|
|
}
|
|
|
|
|
|
//
|
|
//
|
|
CK_RV do_SSL3_MasterKeyDerive(CK_SESSION_HANDLE session)
|
|
{
|
|
CK_MECHANISM mech;
|
|
CK_OBJECT_HANDLE h_pm_secret = CK_INVALID_HANDLE;
|
|
CK_OBJECT_HANDLE h_mk = CK_INVALID_HANDLE;
|
|
CK_RV rc = CKR_OK;
|
|
|
|
CK_VERSION version = { 3, 0 };
|
|
CK_ATTRIBUTE pm_tmpl[] = {
|
|
{CKA_SENSITIVE, &false, sizeof(CK_BBOOL)},
|
|
{CKA_EXTRACTABLE, &true, sizeof(CK_BBOOL)}
|
|
};
|
|
|
|
CK_BYTE client_random_data[256];
|
|
CK_BYTE server_random_data[256];
|
|
CK_ATTRIBUTE m_tmpl[] = {
|
|
{CKA_SENSITIVE, &true, sizeof(CK_BBOOL)},
|
|
{CKA_EXTRACTABLE, &false, sizeof(CK_BBOOL)}
|
|
};
|
|
|
|
CK_SSL3_MASTER_KEY_DERIVE_PARAMS mk_params;
|
|
CK_ULONG i;
|
|
|
|
CK_OBJECT_CLASS class;
|
|
CK_KEY_TYPE keyType;
|
|
CK_ATTRIBUTE test_tmpl[] = {
|
|
{CKA_CLASS, &class, sizeof(class)},
|
|
{CKA_KEY_TYPE, &keyType, sizeof(keyType)}
|
|
};
|
|
CK_SLOT_ID slot_id = SLOT_ID;
|
|
|
|
testcase_begin("starting do_SSL3_MasterKeyDerive...\n");
|
|
|
|
// generate the pre-master secret key
|
|
//
|
|
mech.mechanism = CKM_SSL3_PRE_MASTER_KEY_GEN;
|
|
mech.pParameter = &version;
|
|
mech.ulParameterLen = sizeof(CK_VERSION);
|
|
|
|
/** skip test if the slot doesn't support this mechanism **/
|
|
if (!mech_supported(slot_id, mech.mechanism)) {
|
|
testsuite_skip(32, "Slot %u doesn't support %s (0x%x)",
|
|
(unsigned int) slot_id,
|
|
mech_to_str(mech.mechanism),
|
|
(unsigned int) mech.mechanism);
|
|
goto skipped;
|
|
}
|
|
|
|
testcase_new_assertion();
|
|
rc = funcs->C_GenerateKey(session, &mech, pm_tmpl, 2, &h_pm_secret);
|
|
if (rc != CKR_OK) {
|
|
if (is_rejected_by_policy(rc, session)) {
|
|
testcase_skip("key generation is not allowed by policy");
|
|
return CKR_OK;
|
|
}
|
|
testcase_fail("C_GenerateKey() rc= %s", p11_get_ckr(rc));
|
|
goto done;
|
|
} else {
|
|
testcase_pass("Successfully generated a generic secret key.");
|
|
}
|
|
|
|
// derive a master key
|
|
//
|
|
|
|
for (i = 0; i < 32; i++) {
|
|
client_random_data[i] = i;
|
|
server_random_data[i] = 32 - i;
|
|
}
|
|
|
|
mk_params.pVersion = &version;
|
|
|
|
mk_params.RandomInfo.pClientRandom = client_random_data;
|
|
mk_params.RandomInfo.pServerRandom = server_random_data;
|
|
mk_params.RandomInfo.ulClientRandomLen = 32;
|
|
mk_params.RandomInfo.ulServerRandomLen = 32;
|
|
|
|
mech.mechanism = CKM_SSL3_MASTER_KEY_DERIVE;
|
|
mech.pParameter = &mk_params;
|
|
mech.ulParameterLen = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS);
|
|
|
|
testcase_new_assertion();
|
|
rc = funcs->C_DeriveKey(session, &mech, h_pm_secret, m_tmpl, 2, &h_mk);
|
|
if (rc != CKR_OK) {
|
|
if (is_rejected_by_policy(rc, session)) {
|
|
testcase_skip("Key derivation is not allowed by policy");
|
|
goto done;
|
|
}
|
|
testcase_fail("C_DeriveKey() rc= %s", p11_get_ckr(rc));
|
|
goto done;
|
|
} else {
|
|
testcase_pass("Successfully derived a key from pre-master.");
|
|
}
|
|
|
|
/*
|
|
* This mechanism provides the following attributes:
|
|
* CKA_CLASS = CKO_SECRET_KEY
|
|
* CKA_KEY_TYPE = CKK_GENERIC_SECRET
|
|
* CKA_VALUE_LEN = 48
|
|
* Check that the newly derived key has these.
|
|
*/
|
|
testcase_new_assertion();
|
|
rc = funcs->C_GetAttributeValue(session, h_pm_secret, test_tmpl, 2);
|
|
if (rc != CKR_OK) {
|
|
testcase_error("C_GetAttributeValue() rc= %s", p11_get_ckr(rc));
|
|
goto done;
|
|
}
|
|
if (*(CK_OBJECT_CLASS *) test_tmpl[0].pValue != CKO_SECRET_KEY) {
|
|
testcase_fail("Derived key has incorrect class.");
|
|
goto done;
|
|
}
|
|
|
|
if (*(CK_KEY_TYPE *) test_tmpl[1].pValue != CKK_GENERIC_SECRET) {
|
|
testcase_fail("Derived key has incorrect key type.");
|
|
goto done;
|
|
} else {
|
|
testcase_pass("Derived key has correct attributes.");
|
|
}
|
|
|
|
done:
|
|
if (funcs->C_DestroyObject(session, h_mk) != CKR_OK)
|
|
testcase_error("C_DestroyObject rc=%s", p11_get_ckr(rc));
|
|
|
|
if (funcs->C_DestroyObject(session, h_pm_secret) != CKR_OK)
|
|
testcase_error("C_DestroyObject() failed");
|
|
|
|
skipped:
|
|
return rc;
|
|
}
|
|
|
|
CK_RV do_SSL3_MultipleKeysDerive(CK_SESSION_HANDLE session)
|
|
{
|
|
CK_MECHANISM mech;
|
|
CK_OBJECT_HANDLE h_pm_secret;
|
|
CK_RV rc = CKR_OK;
|
|
CK_ULONG i;
|
|
|
|
CK_VERSION version = { 3, 0 };
|
|
CK_BBOOL true_value = TRUE;
|
|
CK_BBOOL false_value = FALSE;
|
|
CK_ATTRIBUTE pm_tmpl[] = {
|
|
{CKA_TOKEN, &true_value, sizeof(true_value)},
|
|
};
|
|
|
|
CK_BYTE client_random_data[32];
|
|
CK_BYTE server_random_data[32];
|
|
CK_ATTRIBUTE incomplete_tmpl[] = {
|
|
{CKA_TOKEN, &false_value, sizeof(false_value)},
|
|
{CKA_SENSITIVE, &false_value, sizeof(false_value)},
|
|
{CKA_EXTRACTABLE, &true_value, sizeof(true_value)}
|
|
};
|
|
|
|
CK_OBJECT_CLASS class = CKO_SECRET_KEY;
|
|
CK_KEY_TYPE key_type = CKK_AES;
|
|
CK_ULONG key_len = 16;
|
|
CK_ATTRIBUTE complete_tmpl[] = {
|
|
{CKA_CLASS, &class, sizeof(class)},
|
|
{CKA_KEY_TYPE, &key_type, sizeof(key_type)},
|
|
{CKA_VALUE_LEN, &key_len, sizeof(CK_ULONG)},
|
|
{CKA_TOKEN, &false_value, sizeof(false_value)},
|
|
{CKA_SENSITIVE, &false_value, sizeof(false_value)},
|
|
{CKA_EXTRACTABLE, &true_value, sizeof(true_value)}
|
|
};
|
|
|
|
CK_BYTE iv_client[128 / 8] = { 0, };
|
|
CK_BYTE iv_server[128 / 8] = { 0, };
|
|
|
|
CK_SSL3_KEY_MAT_OUT param_out = {
|
|
.hClientMacSecret = 0,
|
|
.hServerMacSecret = 0,
|
|
.hClientKey = 0,
|
|
.hServerKey = 0,
|
|
.pIVClient = iv_client,
|
|
.pIVServer = iv_server,
|
|
};
|
|
|
|
CK_SSL3_KEY_MAT_PARAMS params = {
|
|
.ulMacSizeInBits = 128,
|
|
.ulKeySizeInBits = key_len * 8,
|
|
.ulIVSizeInBits = 128,
|
|
.bIsExport = FALSE,
|
|
.RandomInfo =
|
|
{
|
|
.pClientRandom = client_random_data,
|
|
.ulClientRandomLen = sizeof(client_random_data),
|
|
.pServerRandom = server_random_data,
|
|
.ulServerRandomLen = sizeof(server_random_data),
|
|
},
|
|
.pReturnedKeyMaterial = ¶m_out,
|
|
};
|
|
CK_SLOT_ID slot_id = SLOT_ID;
|
|
|
|
testcase_begin("starting do_SSL3_MultipleKeysDerive...\n");
|
|
|
|
// generate the pre-master secret key
|
|
//
|
|
mech.mechanism = CKM_SSL3_PRE_MASTER_KEY_GEN;
|
|
mech.pParameter = &version;
|
|
mech.ulParameterLen = sizeof(CK_VERSION);
|
|
|
|
/** skip test if the slot doesn't support this mechanism **/
|
|
if (!mech_supported(slot_id, mech.mechanism)) {
|
|
testsuite_skip(3, "Slot %u doesn't support %s (0x%x)",
|
|
(unsigned int) slot_id,
|
|
mech_to_str(mech.mechanism),
|
|
(unsigned int) mech.mechanism);
|
|
goto skipped;
|
|
}
|
|
|
|
testcase_new_assertion();
|
|
rc = funcs->C_GenerateKey(session, &mech, pm_tmpl,
|
|
sizeof(pm_tmpl) / sizeof(*pm_tmpl), &h_pm_secret);
|
|
if (rc != CKR_OK) {
|
|
if (is_rejected_by_policy(rc, session)) {
|
|
testcase_skip("Key generation is not allowed by policy");
|
|
goto done;
|
|
}
|
|
testcase_fail("C_GenerateKey() rc= %s", p11_get_ckr(rc));
|
|
goto done;
|
|
} else {
|
|
testcase_pass("Successfully generated a generic secret key.");
|
|
}
|
|
|
|
for (i = 0; i < sizeof(client_random_data); i++) {
|
|
client_random_data[i] = i;
|
|
server_random_data[i] = sizeof(client_random_data) - i;
|
|
}
|
|
|
|
mech.mechanism = CKM_SSL3_KEY_AND_MAC_DERIVE;
|
|
mech.pParameter = ¶ms;
|
|
mech.ulParameterLen = sizeof(params);
|
|
|
|
/*
|
|
* Try deriving the key without required attributes...
|
|
*/
|
|
testcase_new_assertion();
|
|
rc = funcs->C_DeriveKey(session, &mech, h_pm_secret, incomplete_tmpl,
|
|
sizeof(incomplete_tmpl) / sizeof(*incomplete_tmpl),
|
|
NULL);
|
|
if (is_rejected_by_policy(rc, session)) {
|
|
testcase_skip("key derivation is not allowed by policy");
|
|
goto done;
|
|
}
|
|
if (rc != CKR_TEMPLATE_INCOMPLETE) {
|
|
testcase_fail("C_DeriveKey did not recognize missing attributes.");
|
|
goto done;
|
|
} else {
|
|
testcase_pass("Success, could not derive key without required "
|
|
"attributes.");
|
|
}
|
|
|
|
/*
|
|
* Now derive key with required attributes...
|
|
*/
|
|
|
|
testcase_new_assertion();
|
|
rc = funcs->C_DeriveKey(session, &mech, h_pm_secret, complete_tmpl,
|
|
sizeof(complete_tmpl) / sizeof(*complete_tmpl),
|
|
NULL);
|
|
if (rc != CKR_OK) {
|
|
if (is_rejected_by_policy(rc, session)) {
|
|
testcase_skip("key derivation is not allowed by policy");
|
|
goto done;
|
|
}
|
|
testcase_fail("C_DeriveKey() rc= %s", p11_get_ckr(rc));
|
|
goto done;
|
|
} else {
|
|
testcase_pass("Successfully derived a keys from pre-master.");
|
|
}
|
|
|
|
|
|
if (funcs->C_DestroyObject(session, param_out.hClientMacSecret))
|
|
testcase_error("C_DestroyObject rc=%s", p11_get_ckr(rc));
|
|
if (funcs->C_DestroyObject(session, param_out.hServerMacSecret))
|
|
testcase_error("C_DestroyObject rc=%s", p11_get_ckr(rc));
|
|
if (funcs->C_DestroyObject(session, param_out.hClientKey))
|
|
testcase_error("C_DestroyObject rc=%s", p11_get_ckr(rc));
|
|
if (funcs->C_DestroyObject(session, param_out.hServerKey))
|
|
testcase_error("C_DestroyObject rc=%s", p11_get_ckr(rc));
|
|
|
|
done:
|
|
if (funcs->C_DestroyObject(session, h_pm_secret) != CKR_OK)
|
|
testcase_error("C_DestroyObject() failed");
|
|
|
|
skipped:
|
|
return rc;
|
|
}
|
|
|
|
CK_RV do_TLS_PreMasterKeyGen(CK_SESSION_HANDLE session)
|
|
{
|
|
CK_MECHANISM mech;
|
|
CK_VERSION version;
|
|
CK_OBJECT_HANDLE h_key;
|
|
CK_RV rc = CKR_OK;
|
|
CK_SLOT_ID slot_id = SLOT_ID;
|
|
|
|
testcase_begin("starting do_TLS_PreMasterKeyGen...\n");
|
|
|
|
version.major = 3;
|
|
version.minor = 3;
|
|
|
|
mech.mechanism = CKM_TLS_PRE_MASTER_KEY_GEN;
|
|
mech.pParameter = &version;
|
|
mech.ulParameterLen = sizeof(CK_VERSION);
|
|
|
|
/** skip test if the slot doesn't support this mechanism **/
|
|
if (!mech_supported(slot_id, mech.mechanism)) {
|
|
testsuite_skip(1, "Slot %u doesn't support %s (0x%x)",
|
|
(unsigned int) slot_id,
|
|
mech_to_str(mech.mechanism),
|
|
(unsigned int) mech.mechanism);
|
|
goto done;
|
|
}
|
|
|
|
testcase_new_assertion();
|
|
rc = funcs->C_GenerateKey(session, &mech, NULL, 0, &h_key);
|
|
if (rc != CKR_OK) {
|
|
if (is_rejected_by_policy(rc, session)) {
|
|
testcase_skip("key generation is not allowed by policy");
|
|
return CKR_OK;
|
|
}
|
|
testcase_fail("C_GenerateKey() rc = %s", p11_get_ckr(rc));
|
|
} else {
|
|
testcase_pass("Successfully generated a generic secret key.");
|
|
}
|
|
|
|
if (funcs->C_DestroyObject(session, h_key) != CKR_OK)
|
|
testcase_error("C_DestroyObject() failed");
|
|
|
|
done:
|
|
return rc;
|
|
}
|
|
|
|
CK_RV do_TLS_MultipleKeysDerive(CK_SESSION_HANDLE session)
|
|
{
|
|
CK_MECHANISM mech;
|
|
CK_OBJECT_HANDLE h_pm_secret;
|
|
CK_RV rc = CKR_OK;
|
|
CK_ULONG i;
|
|
|
|
CK_VERSION version = { 3, 3 };
|
|
CK_BBOOL true_value = TRUE;
|
|
CK_BBOOL false_value = FALSE;
|
|
CK_ATTRIBUTE pm_tmpl[] = {
|
|
{CKA_TOKEN, &true_value, sizeof(true_value)},
|
|
};
|
|
|
|
CK_BYTE client_random_data[32];
|
|
CK_BYTE server_random_data[32];
|
|
CK_ATTRIBUTE incomplete_tmpl[] = {
|
|
{CKA_TOKEN, &false_value, sizeof(false_value)},
|
|
{CKA_SENSITIVE, &false_value, sizeof(false_value)},
|
|
{CKA_EXTRACTABLE, &true_value, sizeof(true_value)}
|
|
};
|
|
|
|
CK_OBJECT_CLASS class = CKO_SECRET_KEY;
|
|
CK_KEY_TYPE key_type = CKK_AES;
|
|
CK_ULONG key_len = 16;
|
|
CK_ATTRIBUTE complete_tmpl[] = {
|
|
{CKA_CLASS, &class, sizeof(class)},
|
|
{CKA_KEY_TYPE, &key_type, sizeof(key_type)},
|
|
{CKA_VALUE_LEN, &key_len, sizeof(CK_ULONG)},
|
|
{CKA_TOKEN, &false_value, sizeof(false_value)},
|
|
{CKA_SENSITIVE, &false_value, sizeof(false_value)},
|
|
{CKA_EXTRACTABLE, &true_value, sizeof(true_value)}
|
|
};
|
|
|
|
CK_BYTE iv_client[128 / 8] = { 0, };
|
|
CK_BYTE iv_server[128 / 8] = { 0, };
|
|
|
|
CK_SSL3_KEY_MAT_OUT param_out = {
|
|
.hClientMacSecret = 0,
|
|
.hServerMacSecret = 0,
|
|
.hClientKey = 0,
|
|
.hServerKey = 0,
|
|
.pIVClient = iv_client,
|
|
.pIVServer = iv_server,
|
|
};
|
|
|
|
CK_SSL3_KEY_MAT_PARAMS params = {
|
|
.ulMacSizeInBits = 128,
|
|
.ulKeySizeInBits = key_len * 8,
|
|
.ulIVSizeInBits = 128,
|
|
.bIsExport = FALSE,
|
|
.RandomInfo =
|
|
{
|
|
.pClientRandom = client_random_data,
|
|
.ulClientRandomLen = sizeof(client_random_data),
|
|
.pServerRandom = server_random_data,
|
|
.ulServerRandomLen = sizeof(server_random_data),
|
|
},
|
|
.pReturnedKeyMaterial = ¶m_out,
|
|
};
|
|
CK_SLOT_ID slot_id = SLOT_ID;
|
|
|
|
testcase_begin("starting do_TLS_MultipleKeysDerive...\n");
|
|
|
|
// generate the pre-master secret key
|
|
//
|
|
mech.mechanism = CKM_TLS_PRE_MASTER_KEY_GEN;
|
|
mech.pParameter = &version;
|
|
mech.ulParameterLen = sizeof(CK_VERSION);
|
|
|
|
/** skip test if the slot doesn't support this mechanism **/
|
|
if (!mech_supported(slot_id, mech.mechanism)) {
|
|
testsuite_skip(3, "Slot %u doesn't support %s (0x%x)",
|
|
(unsigned int) slot_id,
|
|
mech_to_str(mech.mechanism),
|
|
(unsigned int) mech.mechanism);
|
|
goto skipped;
|
|
}
|
|
|
|
testcase_new_assertion();
|
|
rc = funcs->C_GenerateKey(session, &mech, pm_tmpl,
|
|
sizeof(pm_tmpl) / sizeof(*pm_tmpl), &h_pm_secret);
|
|
if (rc != CKR_OK) {
|
|
if (is_rejected_by_policy(rc, session)) {
|
|
testcase_skip("Key generation is not allowed by policy");
|
|
goto done;
|
|
}
|
|
testcase_fail("C_GenerateKey() rc= %s", p11_get_ckr(rc));
|
|
goto done;
|
|
} else {
|
|
testcase_pass("Successfully generated a generic secret key.");
|
|
}
|
|
|
|
for (i = 0; i < sizeof(client_random_data); i++) {
|
|
client_random_data[i] = i;
|
|
server_random_data[i] = sizeof(client_random_data) - i;
|
|
}
|
|
|
|
mech.mechanism = CKM_TLS_KEY_AND_MAC_DERIVE;
|
|
mech.pParameter = ¶ms;
|
|
mech.ulParameterLen = sizeof(params);
|
|
|
|
/*
|
|
* Try deriving the key without required attributes...
|
|
*/
|
|
testcase_new_assertion();
|
|
rc = funcs->C_DeriveKey(session, &mech, h_pm_secret, incomplete_tmpl,
|
|
sizeof(incomplete_tmpl) / sizeof(*incomplete_tmpl),
|
|
NULL);
|
|
if (is_rejected_by_policy(rc, session)) {
|
|
testcase_skip("key derivation is not allowed by policy");
|
|
goto done;
|
|
}
|
|
if (rc != CKR_TEMPLATE_INCOMPLETE) {
|
|
testcase_fail("C_DeriveKey did not recognize missing attributes.");
|
|
goto done;
|
|
} else {
|
|
testcase_pass("Success, could not derive key without required "
|
|
"attributes.");
|
|
}
|
|
|
|
/*
|
|
* Now derive key with required attributes...
|
|
*/
|
|
|
|
testcase_new_assertion();
|
|
rc = funcs->C_DeriveKey(session, &mech, h_pm_secret, complete_tmpl,
|
|
sizeof(complete_tmpl) / sizeof(*complete_tmpl),
|
|
NULL);
|
|
if (rc != CKR_OK) {
|
|
if (is_rejected_by_policy(rc, session)) {
|
|
testcase_skip("key derivation is not allowed by policy");
|
|
goto done;
|
|
}
|
|
testcase_fail("C_DeriveKey() rc= %s", p11_get_ckr(rc));
|
|
goto done;
|
|
} else {
|
|
testcase_pass("Successfully derived a keys from pre-master.");
|
|
}
|
|
|
|
|
|
if (funcs->C_DestroyObject(session, param_out.hClientMacSecret))
|
|
testcase_error("C_DestroyObject rc=%s", p11_get_ckr(rc));
|
|
if (funcs->C_DestroyObject(session, param_out.hServerMacSecret))
|
|
testcase_error("C_DestroyObject rc=%s", p11_get_ckr(rc));
|
|
if (funcs->C_DestroyObject(session, param_out.hClientKey))
|
|
testcase_error("C_DestroyObject rc=%s", p11_get_ckr(rc));
|
|
if (funcs->C_DestroyObject(session, param_out.hServerKey))
|
|
testcase_error("C_DestroyObject rc=%s", p11_get_ckr(rc));
|
|
|
|
done:
|
|
if (funcs->C_DestroyObject(session, h_pm_secret) != CKR_OK)
|
|
testcase_error("C_DestroyObject() failed");
|
|
|
|
skipped:
|
|
return rc;
|
|
}
|
|
|
|
CK_RV ssl3_functions(void)
|
|
{
|
|
CK_RV rc;
|
|
SYSTEMTIME t1, t2;
|
|
CK_SLOT_ID slot_id = SLOT_ID;
|
|
CK_SESSION_HANDLE session;
|
|
CK_FLAGS flags;
|
|
CK_BYTE user_pin[PKCS11_MAX_PIN_LEN];
|
|
CK_ULONG user_pin_len;
|
|
|
|
testcase_rw_session();
|
|
testcase_user_login();
|
|
|
|
GetSystemTime(&t1);
|
|
rc = do_SSL3_PreMasterKeyGen(session);
|
|
if (rc && !no_stop)
|
|
goto testcase_cleanup;
|
|
GetSystemTime(&t2);
|
|
process_time(t1, t2);
|
|
|
|
GetSystemTime(&t1);
|
|
rc = do_SSL3_MasterKeyDerive(session);
|
|
if (rc && !no_stop)
|
|
goto testcase_cleanup;
|
|
GetSystemTime(&t2);
|
|
process_time(t1, t2);
|
|
|
|
GetSystemTime(&t1);
|
|
rc = do_SSL3_MultipleKeysDerive(session);
|
|
if (rc && !no_stop)
|
|
goto testcase_cleanup;
|
|
GetSystemTime(&t2);
|
|
process_time(t1, t2);
|
|
|
|
GetSystemTime(&t1);
|
|
rc = do_SignVerify_SSL3_SHA1_MAC(session);
|
|
if (rc && !no_stop)
|
|
goto testcase_cleanup;
|
|
GetSystemTime(&t2);
|
|
process_time(t1, t2);
|
|
|
|
GetSystemTime(&t1);
|
|
rc = do_SignVerify_SSL3_MD5_MAC(session);
|
|
if (rc && !no_stop)
|
|
return rc;
|
|
GetSystemTime(&t2);
|
|
process_time(t1, t2);
|
|
|
|
GetSystemTime(&t1);
|
|
rc = do_TLS_PreMasterKeyGen(session);
|
|
if (rc && !no_stop)
|
|
goto testcase_cleanup;
|
|
GetSystemTime(&t2);
|
|
process_time(t1, t2);
|
|
|
|
GetSystemTime(&t1);
|
|
rc = do_TLS_MultipleKeysDerive(session);
|
|
if (rc && !no_stop)
|
|
goto testcase_cleanup;
|
|
GetSystemTime(&t2);
|
|
process_time(t1, t2);
|
|
|
|
testcase_cleanup:
|
|
testcase_user_logout();
|
|
rc = funcs->C_CloseAllSessions(slot_id);
|
|
if (rc != CKR_OK) {
|
|
testcase_error("C_CloseSessions rc=%s", p11_get_ckr(rc));
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
CK_C_INITIALIZE_ARGS cinit_args;
|
|
int rc;
|
|
CK_RV rv;
|
|
|
|
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();
|
|
|
|
rv = ssl3_functions();
|
|
|
|
testcase_print_result();
|
|
|
|
funcs->C_Finalize(NULL);
|
|
|
|
return testcase_return(rv);
|
|
}
|