Skip to content

Commit

Permalink
xtest: pkcs11_1000.c: Test support of object checksum value computation
Browse files Browse the repository at this point in the history
This test involves PKCS11_CKA_CHECK_VALUE when enabled, as per the
spec, the attribute can be either the legitimate value recomputed by
the PKCS#11 token or a zero-sized value called a no-value for when
client does not want the attribute to set in an object. This test
invokes Cryptoki API functions C_GenerateKey(), C_CreateObject(),
C_CopyObject(), C_SetAttributeValue(), C_UnwrapKey() and C_DeriveKey()
to perform check value computation and this test query the value using
C_GetAttributeValue().

Signed-off-by: Marouene Boubakri <[email protected]>
  • Loading branch information
maroueneboubakri committed Dec 13, 2023
1 parent 4fabb34 commit 3c4b526
Showing 1 changed file with 228 additions and 0 deletions.
228 changes: 228 additions & 0 deletions host/xtest/pkcs11_1000.c
Original file line number Diff line number Diff line change
Expand Up @@ -8888,3 +8888,231 @@ static void xtest_pkcs11_test_1028(ADBG_Case_t *c)
}
ADBG_CASE_DEFINE(pkcs11, 1028, xtest_pkcs11_test_1028,
"PKCS11: destroy PKCS#11 objects handled by another session");

/*
* This test involves PKCS11_CKA_CHECK_VALUE when enabled, as per the spec,
* the attribute can be either the legitimate value recomputed by the PKCS#11
* token or a zero-sized value called a no-value for when client does not want
* the attribute to set in an object. This test invokes Cryptoki API functions
* C_GenerateKey(), C_CreateObject(), C_CopyObject(), C_SetAttributeValue(),
* C_UnwrapKey() and C_DeriveKey() to perform check value computation and
* This test query the value using C_GetAttributeValue().
*/
static void xtest_pkcs11_test_1029(ADBG_Case_t *c)
{
CK_RV rv = CKR_GENERAL_ERROR;
CK_SLOT_ID slot = 0;
CK_SESSION_HANDLE session = CK_INVALID_HANDLE;
CK_FLAGS session_flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
CK_OBJECT_HANDLE key_handle = CK_INVALID_HANDLE;
CK_OBJECT_HANDLE key_handle_cp = CK_INVALID_HANDLE;
CK_OBJECT_HANDLE unwrapped_key_handle = CK_INVALID_HANDLE;
CK_OBJECT_HANDLE derived_key_handle = CK_INVALID_HANDLE;
uint8_t ciphertext[16] = { 0 };
CK_ULONG ciphertext_len = 0;
uint8_t plaintext[16] = { 0 };
CK_BYTE kcv[3] = { 0 };
CK_BYTE import_aes128_key[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06
};
CK_BYTE import_aes128_kcv_valid[] = { 0x08, 0xbd, 0x28 };
CK_BYTE import_aes128_kcv_invalid[] = { 0xba, 0xaa, 0xad };
CK_BYTE unwrapped_key_kcv_valid[] = { 0xa2, 0x25, 0x17 };
CK_ATTRIBUTE import_aes_key_template[] = {
{ CKA_TOKEN, &(CK_BBOOL){CK_TRUE}, sizeof(CK_BBOOL) },
{ CKA_PRIVATE, &(CK_BBOOL){ CK_FALSE }, sizeof(CK_BBOOL) },
{ CKA_SENSITIVE, &(CK_BBOOL){ CK_FALSE }, sizeof(CK_BBOOL) },
{ CKA_EXTRACTABLE, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
{ CKA_CLASS, &(CK_OBJECT_CLASS){CKO_SECRET_KEY},
sizeof(CK_OBJECT_CLASS) },
{ CKA_KEY_TYPE, &(CK_KEY_TYPE){CKK_AES}, sizeof(CK_KEY_TYPE) },
{ CKA_ENCRYPT, &(CK_BBOOL){CK_FALSE}, sizeof(CK_BBOOL) },
{ CKA_DECRYPT, &(CK_BBOOL){CK_FALSE}, sizeof(CK_BBOOL) },
{ CKA_DERIVE, &(CK_BBOOL){CK_TRUE}, sizeof(CK_BBOOL) },
{ CKA_WRAP, &(CK_BBOOL){CK_TRUE}, sizeof(CK_BBOOL) },
{ CKA_UNWRAP, &(CK_BBOOL){CK_TRUE}, sizeof(CK_BBOOL) },
{ CKA_VALUE, &import_aes128_key, sizeof(import_aes128_key) },
{ CKA_CHECK_VALUE, &import_aes128_kcv_valid,
sizeof(import_aes128_kcv_valid) },
};
CK_ATTRIBUTE kcv_attr_template[] = {
{ CKA_CHECK_VALUE, &kcv, sizeof(kcv) },
};
CK_ATTRIBUTE cp_attr_template_cka[] = {
{ CKA_CHECK_VALUE, &import_aes128_kcv_invalid,
sizeof(import_aes128_kcv_invalid) },
};
CK_KEY_DERIVATION_STRING_DATA key_derv_param = { 0 };
uint8_t derive_buf[16] = { 0 };
size_t derive_buf_size = sizeof(derive_buf);
CK_MECHANISM mech_derive = { 0 };
CK_ATTRIBUTE derived_key_template[] = {
{ CKA_CLASS, &(CK_OBJECT_CLASS){ CKO_SECRET_KEY },
sizeof(CK_OBJECT_CLASS) },
{ CKA_KEY_TYPE, &(CK_KEY_TYPE){ CKK_GENERIC_SECRET },
sizeof(CK_KEY_TYPE) },
{ CKA_PRIVATE, &(CK_BBOOL){ CK_FALSE }, sizeof(CK_BBOOL) },
{ CKA_SENSITIVE, &(CK_BBOOL){ CK_FALSE }, sizeof(CK_BBOOL) },
{ CKA_EXTRACTABLE, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
{ CKA_VALUE_LEN, &(CK_ULONG){16}, sizeof(CK_ULONG) },
{ CKA_CHECK_VALUE, NULL, 0 },
};
CK_ATTRIBUTE unwrap_template[] = {
{ CKA_CLASS, &(CK_OBJECT_CLASS){ CKO_SECRET_KEY },
sizeof(CK_OBJECT_CLASS) },
{ CKA_KEY_TYPE, &(CK_KEY_TYPE){ CKK_GENERIC_SECRET },
sizeof(CK_KEY_TYPE) },
{ CKA_EXTRACTABLE, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
{ CKA_SENSITIVE, &(CK_BBOOL){ CK_FALSE}, sizeof(CK_BBOOL) },
{ CKA_CHECK_VALUE, &unwrapped_key_kcv_valid,
sizeof(unwrapped_key_kcv_valid)},
};
uint8_t buf[WRAPPED_TEST_KEY_SIZE] = { 0 };
CK_ULONG size = 0;

rv = init_lib_and_find_token_slot(&slot, PIN_AUTH);
if (!ADBG_EXPECT_CK_OK(c, rv))
return;

rv = C_OpenSession(slot, session_flags, NULL, 0, &session);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto close_lib;

Do_ADBG_BeginSubCase(c, "Compute KCV on C_GenerateKey()");

rv = C_GenerateKey(session, &cktest_aes_keygen_mechanism,
cktest_generate_aes_object,
ARRAY_SIZE(cktest_generate_aes_object),
&key_handle);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err;

rv = C_GetAttributeValue(session, key_handle, kcv_attr_template,
ARRAY_SIZE(kcv_attr_template));
if (!ADBG_EXPECT_CK_OK(c, rv))
goto out;

rv = C_EncryptInit(session, &cktest_aes_ecb_mechanism, key_handle);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;

memset(ciphertext, 0, sizeof(ciphertext));
memset(plaintext, 0, sizeof(plaintext));

ciphertext_len = sizeof(ciphertext);

rv = C_Encrypt(session, plaintext, sizeof(plaintext), ciphertext,
&ciphertext_len);

if (!ADBG_EXPECT_CK_OK(c, rv) ||
!ADBG_EXPECT_BUFFER(c, ciphertext, sizeof(kcv),
kcv, sizeof(kcv)))
goto err_destr_obj;

rv = C_DestroyObject(session, key_handle);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err;

Do_ADBG_EndSubCase(c, NULL);

Do_ADBG_BeginSubCase(c, "Set KCV on C_CreateObject()");

rv = C_CreateObject(session, import_aes_key_template,
ARRAY_SIZE(import_aes_key_template), &key_handle);

if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;

Do_ADBG_EndSubCase(c, NULL);

Do_ADBG_BeginSubCase(c, "Compute KCV on C_CopyObject()");

rv = C_CopyObject(session, key_handle, cp_attr_template_cka,
ARRAY_SIZE(cp_attr_template_cka), &key_handle_cp);

if (!ADBG_EXPECT_CK_RESULT(c, CKR_ATTRIBUTE_VALUE_INVALID, rv))
goto err_destr_obj;

Do_ADBG_EndSubCase(c, NULL);

Do_ADBG_BeginSubCase(c, "Compute KCV on C_DeriveKey()");

key_derv_param.pData = derive_buf;
key_derv_param.ulLen = derive_buf_size;
mech_derive.mechanism = CKM_AES_ECB_ENCRYPT_DATA;
mech_derive.pParameter = &key_derv_param;
mech_derive.ulParameterLen = sizeof(key_derv_param);

rv = C_DeriveKey(session, &mech_derive, key_handle,
derived_key_template,
ARRAY_SIZE(derived_key_template),
&derived_key_handle);

if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;

memset(&kcv, 0, sizeof(kcv));
rv = C_GetAttributeValue(session, derived_key_handle, kcv_attr_template,
ARRAY_SIZE(kcv_attr_template));
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;

if (!ADBG_EXPECT_COMPARE_UNSIGNED(c,
kcv_attr_template[0].ulValueLen, ==, 0))
goto err_destr_obj;

Do_ADBG_EndSubCase(c, NULL);

Do_ADBG_BeginSubCase(c, "Compute KCV on C_UnwrapKey()");

size = sizeof(buf);

rv = C_WrapKey(session, &cktest_aes_ecb_mechanism, key_handle,
derived_key_handle, buf, &size);
if (!ADBG_EXPECT_CK_OK(c, rv) ||
!ADBG_EXPECT_COMPARE_UNSIGNED(c, size, <=, sizeof(buf)))
goto err_destr_obj;

rv = C_UnwrapKey(session, &cktest_aes_ecb_mechanism, key_handle, buf,
size, unwrap_template, ARRAY_SIZE(unwrap_template),
&unwrapped_key_handle);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;

Do_ADBG_EndSubCase(c, NULL);

Do_ADBG_BeginSubCase(c, "Destroy KCV using C_SetAttributeValue()");

kcv_attr_template[0].pValue = NULL;
kcv_attr_template[0].ulValueLen = 0;

rv = C_SetAttributeValue(session, unwrapped_key_handle,
kcv_attr_template,
ARRAY_SIZE(kcv_attr_template));
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;

kcv_attr_template[0].pValue = &kcv;
kcv_attr_template[0].ulValueLen = sizeof(kcv);

rv = C_GetAttributeValue(session, unwrapped_key_handle, kcv_attr_template,
ARRAY_SIZE(kcv_attr_template));

if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;
ADBG_EXPECT_COMPARE_UNSIGNED(c, kcv_attr_template[0].ulValueLen, ==, 0);

err_destr_obj:
ADBG_EXPECT_CK_OK(c, C_DestroyObject(session, unwrapped_key_handle));
ADBG_EXPECT_CK_OK(c, C_DestroyObject(session, derived_key_handle));
ADBG_EXPECT_CK_OK(c, C_DestroyObject(session, key_handle));
err:
Do_ADBG_EndSubCase(c, NULL);
out:
ADBG_EXPECT_CK_OK(c, C_CloseSession(session));
close_lib:
ADBG_EXPECT_CK_OK(c, close_lib());
}
ADBG_CASE_DEFINE(pkcs11, 1029, xtest_pkcs11_test_1029,
"PKCS11: Test support for object checksum value computation");

0 comments on commit 3c4b526

Please sign in to comment.