Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xtest: add pkcs11_1031 for CKM_RSA_X_509 sign/verify (take 2) #762

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
304 changes: 304 additions & 0 deletions host/xtest/pkcs11_1000.c
Original file line number Diff line number Diff line change
Expand Up @@ -10021,3 +10021,307 @@ static void xtest_pkcs11_test_1030(ADBG_Case_t *c)
}
ADBG_CASE_DEFINE(pkcs11, 1030, xtest_pkcs11_test_1030,
"PKCS11: Test AES-GCM Encryption/Decryption");

static int test_rsa_raw_operations(ADBG_Case_t *c,
CK_SESSION_HANDLE session,
uint32_t rsa_bits)
{
CK_RV rv = CKR_GENERAL_ERROR;
CK_OBJECT_HANDLE public_key = CK_INVALID_HANDLE;
CK_OBJECT_HANDLE private_key = CK_INVALID_HANDLE;
CK_MECHANISM mechanism = {
CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0
};
CK_MECHANISM sign_mechanism = {
CKM_RSA_X_509, NULL, 0
};
CK_ULONG modulus_bits = 0;
CK_BYTE id[] = { 123 };

CK_ATTRIBUTE public_key_template[] = {
{ CKA_ENCRYPT, &(CK_BBOOL){ CK_FALSE }, sizeof(CK_BBOOL) },
{ CKA_VERIFY, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
{ CKA_WRAP, &(CK_BBOOL){ CK_FALSE }, sizeof(CK_BBOOL) },
{ CKA_MODULUS_BITS, &modulus_bits, sizeof(CK_ULONG) },
};

CK_ATTRIBUTE private_key_template[] = {
{ CKA_TOKEN, &(CK_BBOOL){ CK_FALSE }, sizeof(CK_BBOOL) },
{ CKA_PRIVATE, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
{ CKA_SUBJECT, subject_common_name,
sizeof(subject_common_name) },
{ CKA_ID, id, sizeof(id) },
{ CKA_SENSITIVE, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
{ CKA_DECRYPT, &(CK_BBOOL){ CK_FALSE }, sizeof(CK_BBOOL) },
{ CKA_SIGN, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
{ CKA_UNWRAP, &(CK_BBOOL){ CK_FALSE }, sizeof(CK_BBOOL) }
};

CK_BYTE in_data[1024] = { 0 };
CK_ULONG in_data_size = 0;
CK_BYTE signature[1024] = { 0 };
CK_ULONG signature_len = 0;

Do_ADBG_BeginSubCase(c, "Test CKM_RSA_X_509 %u - Sign/Verify",
rsa_bits);

Do_ADBG_BeginSubCase(c, "Generate key pair and data");

modulus_bits = rsa_bits;
rv = C_GenerateKeyPair(session, &mechanism, public_key_template,
ARRAY_SIZE(public_key_template),
private_key_template,
ARRAY_SIZE(private_key_template),
&public_key, &private_key);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err;

/*
* Implementation of the PKCS#11 TA requires that messages
* signed with raw RSA (CKM_RSA_X_509) have the size of the
* private key. There is no constraint regarding the padding
* scheme. Lets's use a well sized buffer of random data,
* but clear the leading bit to ensure the message value
* is not bigger than the key modulus.
*/
in_data_size = rsa_bits / 8;

rv = C_GenerateRandom(session, in_data, in_data_size);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;

in_data[0] &= 0x7f;

Do_ADBG_EndSubCase(c, "Generate key pair and data");

Do_ADBG_BeginSubCase(c, "Sign with invalid data");

/* Test with data wider than expected */
rv = C_SignInit(session, &sign_mechanism, private_key);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;

signature_len = sizeof(signature);
rv = C_Sign(session, in_data, in_data_size + 32, signature,
&signature_len);
if (!ADBG_EXPECT_CK_RESULT(c, CKR_DATA_LEN_RANGE, rv))
goto err_destr_obj;

/* Test with data shorter than expected */
rv = C_SignInit(session, &sign_mechanism, private_key);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;

signature_len = sizeof(signature);
rv = C_Sign(session, in_data, in_data_size - 32, signature,
&signature_len);
if (!ADBG_EXPECT_CK_RESULT(c, CKR_DATA_LEN_RANGE, rv))
goto err_destr_obj;

/* Test unintialized C_Sign() operation */
signature_len = sizeof(signature);
rv = C_Sign(session, in_data, in_data_size, signature, &signature_len);
if (!ADBG_EXPECT_CK_RESULT(c, CKR_OPERATION_NOT_INITIALIZED, rv))
goto err_destr_obj;

Do_ADBG_EndSubCase(c, "Sign with invalid data");

Do_ADBG_BeginSubCase(c, "Sign/Verify with valid data/signature");

/*
* Test C_Sign() with buffer too short, the C_Sign() operaiton should remain
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

operation

* initialized and final C_Sign() call is expected to succeed.
*/
rv = C_SignInit(session, &sign_mechanism, private_key);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;

signature_len = 0;
rv = C_Sign(session, in_data, in_data_size, NULL, &signature_len);
if (!ADBG_EXPECT_CK_OK(c, rv) ||
!ADBG_EXPECT_COMPARE_UNSIGNED(c, signature_len, ==, in_data_size))
goto err_destr_obj;

signature_len = sizeof(signature);
rv = C_Sign(session, in_data, in_data_size, NULL, &signature_len);
if (!ADBG_EXPECT_CK_OK(c, rv) ||
!ADBG_EXPECT_COMPARE_UNSIGNED(c, signature_len, ==, in_data_size))
goto err_destr_obj;

signature_len = 0;
rv = C_Sign(session, in_data, in_data_size, signature, &signature_len);
if (!ADBG_EXPECT_CK_RESULT(c, CKR_BUFFER_TOO_SMALL, rv) ||
!ADBG_EXPECT_COMPARE_UNSIGNED(c, signature_len, ==, in_data_size))
goto err_destr_obj;

signature_len = 32;
rv = C_Sign(session, in_data, in_data_size, signature, &signature_len);
if (!ADBG_EXPECT_CK_RESULT(c, CKR_BUFFER_TOO_SMALL, rv) ||
!ADBG_EXPECT_COMPARE_UNSIGNED(c, signature_len, ==, in_data_size))
goto err_destr_obj;

/* Test effective C_Sign() and C_Verify() operations */
signature_len = sizeof(signature);
rv = C_Sign(session, in_data, in_data_size, signature, &signature_len);
if (!ADBG_EXPECT_CK_OK(c, rv) ||
!ADBG_EXPECT_COMPARE_UNSIGNED(c, signature_len, ==, in_data_size))
goto err_destr_obj;

rv = C_VerifyInit(session, &sign_mechanism, public_key);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;

rv = C_Verify(session, in_data, in_data_size, signature, signature_len);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;

Do_ADBG_EndSubCase(c, "Sign/Verify with valid data/signature");

Do_ADBG_BeginSubCase(c, "Verify with altered signature/message");

/* Test signature wider than expect */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expected

rv = C_VerifyInit(session, &sign_mechanism, public_key);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;

rv = C_Verify(session, in_data, in_data_size, signature,
signature_len + 4);
if (!ADBG_EXPECT_CK_RESULT(c, CKR_SIGNATURE_LEN_RANGE, rv))
goto err_destr_obj;

/* Test signature shorter than expect */
rv = C_VerifyInit(session, &sign_mechanism, public_key);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;

rv = C_Verify(session, in_data, in_data_size, signature,
signature_len - 4);
if (!ADBG_EXPECT_CK_RESULT(c, CKR_SIGNATURE_LEN_RANGE, rv))
goto err_destr_obj;

/* Test altered signature */
rv = C_VerifyInit(session, &sign_mechanism, public_key);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;

signature[32] ^= 1;
rv = C_Verify(session, in_data, in_data_size, signature, signature_len);
if (!ADBG_EXPECT_CK_RESULT(c, CKR_SIGNATURE_INVALID, rv))
goto err_destr_obj;
signature[32] ^= 1;

/* Test altered message */
rv = C_VerifyInit(session, &sign_mechanism, public_key);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_obj;

in_data[32] ^= 1;
rv = C_Verify(session, in_data, in_data_size, signature, signature_len);
if (!ADBG_EXPECT_CK_RESULT(c, CKR_SIGNATURE_INVALID, rv))
goto err_destr_obj;
in_data[32] ^= 1;

/* Test unintialized C_Verify() operation */
rv = C_Verify(session, in_data, in_data_size, signature, signature_len);
if (!ADBG_EXPECT_CK_RESULT(c, CKR_OPERATION_NOT_INITIALIZED, rv))
goto err_destr_obj;

Do_ADBG_EndSubCase(c, "Verify with altered signature/message");

Do_ADBG_BeginSubCase(c, "Destroy key pair");

rv = C_DestroyObject(session, private_key);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto err_destr_pub_obj;

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

Do_ADBG_EndSubCase(c, "Destroy key pair");

Do_ADBG_EndSubCase(c, "Test CKM_RSA_X_509 %u - Sign/Verify", rsa_bits);

return 1;

err_destr_obj:
ADBG_EXPECT_CK_OK(c, C_DestroyObject(session, private_key));
err_destr_pub_obj:
ADBG_EXPECT_CK_OK(c, C_DestroyObject(session, public_key));
err:
Do_ADBG_EndSubCase(c, NULL);
Do_ADBG_EndSubCase(c, "Test CKM_RSA_X_509 %u - Sign/Verify", rsa_bits);

return 0;
}

static void xtest_pkcs11_test_1031(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_MECHANISM_INFO mechanism_info = { };
int ret = 0;

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

rv = init_test_token_pin_auth(slot);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto close_lib;

rv = init_user_test_token_pin_auth(slot);
if (!ADBG_EXPECT_CK_OK(c, rv))
goto close_lib;

rv = C_GetMechanismInfo(slot, CKM_RSA_X_509, &mechanism_info);

if (rv == CKR_MECHANISM_INVALID) {
Do_ADBG_Log("CKM_RSA_X_509 not supported, skip raw RSA tests");
goto close_lib;
}

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

if ((mechanism_info.flags & (CKF_SIGN | CKF_VERIFY)) !=
(CKF_SIGN | CKF_VERIFY)) {
Do_ADBG_Log("CKM_RSA_X_509 sign/verify not supported, skip raw RSA tests");
goto close_lib;
}

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

/* Login to Test Token */
rv = C_Login(session, CKU_USER, test_token_user_pin,
sizeof(test_token_user_pin));
if (!ADBG_EXPECT_CK_OK(c, rv))
goto out;

ret = test_rsa_raw_operations(c, session, 1024);
if (!ret)
goto out;

ret = test_rsa_raw_operations(c, session, 2048);
if (!ret)
goto out;

if (level > 0) {
ret = test_rsa_raw_operations(c, session, 3072);
if (!ret)
goto out;
ret = test_rsa_raw_operations(c, session, 4096);
if (!ret)
goto out;
}
out:
ADBG_EXPECT_CK_OK(c, C_CloseSession(session));
close_lib:
ADBG_EXPECT_CK_OK(c, close_lib());
}
ADBG_CASE_DEFINE(pkcs11, 1031, xtest_pkcs11_test_1031,
"PKCS11: raw RSA signing");
Loading