summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergiy Kibrik <Sergiy_Kibrik@epam.com>2022-11-14 23:07:07 +0200
committerJérôme Forissier <jerome@forissier.org>2023-01-09 14:34:37 +0100
commit942159ad861121c1e4c739f9ff5f163e563c0e8d (patch)
tree0a9541c0b2ec6ead8f1360ac35fab4fbf8f6d2e2
parentfa802a491d3d8acd090034e759b7c274db30c3d3 (diff)
xtest: pkcs11: Add test for RSA AES key wrap mechanism
Adds basic tests to exercise CKM_RSA_AES_KEY_WRAP operations: * test wrap/unwrap of AES key: - generate sample AES keys of different sizes - wrap sample key using RSA public key - unwrap sample key using RSA private key * test wrap/unwrap of RSA private key: - create sample RSA private key - wrap sample key using RSA public key - unwrap sample key using RSA private key * test unwrapping of externally (by openssl) wrapped AES key To speed up tests execution all tests avoid RSA keypairs generation, but use pre-generated keypairs from the data header. Signed-off-by: Sergiy Kibrik <Sergiy_Kibrik@epam.com> Acked-by: Etienne Carriere <etienne.carriere@linaro.org>
-rw-r--r--host/xtest/pkcs11_1000.c451
-rw-r--r--host/xtest/regression_4000_data.h76
2 files changed, 527 insertions, 0 deletions
diff --git a/host/xtest/pkcs11_1000.c b/host/xtest/pkcs11_1000.c
index 64430f8..8796ba6 100644
--- a/host/xtest/pkcs11_1000.c
+++ b/host/xtest/pkcs11_1000.c
@@ -8016,3 +8016,454 @@ err_close_lib:
ADBG_CASE_DEFINE(pkcs11, 1025, xtest_pkcs11_test_1025,
"PKCS11: EDDSA key generation and signing");
+
+#define RSA_AES_MAX_KEY_SIZE 32
+
+#define RSA_AES_WRAP_KEY(vect) \
+ { \
+ .modulus = vect ## _modulus, \
+ .modulus_len = ARRAY_SIZE(vect ## _modulus), \
+ .pub_exp = vect ## _pub_exp, \
+ .pub_exp_len = ARRAY_SIZE(vect ## _pub_exp), \
+ .priv_exp = vect ## _priv_exp, \
+ .priv_exp_len = ARRAY_SIZE(vect ## _priv_exp), \
+ .prime1 = vect ## _prime1, \
+ .prime1_len = ARRAY_SIZE(vect ## _prime1), \
+ .prime2 = vect ## _prime2, \
+ .prime2_len = ARRAY_SIZE(vect ## _prime2), \
+ }
+
+#define RSA_AES_WRAP_RSA(vect) \
+ { .rsa = RSA_AES_WRAP_KEY(vect) }
+
+#define RSA_AES_WRAP_AES(_size) { .aes = { .size = (_size) } }
+
+static struct rsa_aes_wrap_test {
+ CK_KEY_TYPE target_type;
+ union {
+ struct {
+ const uint8_t *modulus;
+ size_t modulus_len;
+
+ const uint8_t *pub_exp;
+ size_t pub_exp_len;
+
+ const uint8_t *priv_exp;
+ size_t priv_exp_len;
+
+ const uint8_t *prime1;
+ size_t prime1_len;
+ const uint8_t *prime2;
+ size_t prime2_len;
+ } rsa;
+ struct {
+ CK_ULONG size;
+ } aes;
+ } target;
+
+ struct {
+ const uint8_t *modulus;
+ size_t modulus_len;
+
+ const uint8_t *pub_exp;
+ size_t pub_exp_len;
+
+ const uint8_t *priv_exp;
+ size_t priv_exp_len;
+
+ const uint8_t *prime1;
+ size_t prime1_len;
+ const uint8_t *prime2;
+ size_t prime2_len;
+ } key;
+} rsa_aes_wrap_tests[] = {
+ { CKK_AES, RSA_AES_WRAP_AES(128), RSA_AES_WRAP_KEY(ac_rsassa_vect2) },
+ { CKK_AES, RSA_AES_WRAP_AES(256), RSA_AES_WRAP_KEY(ac_rsassa_vect18) },
+ { CKK_AES, RSA_AES_WRAP_AES(192), RSA_AES_WRAP_KEY(ac_rsassa_vect19) },
+ { CKK_RSA, RSA_AES_WRAP_RSA(ac_rsassa_vect1),
+ RSA_AES_WRAP_KEY(ac_rsassa_vect2) },
+ { CKK_RSA, RSA_AES_WRAP_RSA(ac_rsassa_vect1),
+ RSA_AES_WRAP_KEY(ac_rsassa_vect19) },
+ { CKK_RSA, RSA_AES_WRAP_RSA(ac_rsassa_vect2),
+ RSA_AES_WRAP_KEY(ac_rsassa_vect18) },
+ { CKK_RSA, RSA_AES_WRAP_RSA(ac_rsassa_vect18),
+ RSA_AES_WRAP_KEY(ac_rsassa_vect2) },
+ { CKK_RSA, RSA_AES_WRAP_RSA(ac_rsassa_vect19),
+ RSA_AES_WRAP_KEY(ac_rsassa_vect2) },
+ { CKK_RSA, RSA_AES_WRAP_RSA(ac_rsassa_vect19),
+ RSA_AES_WRAP_KEY(ac_rsassa_vect18) },
+ { CKK_RSA, RSA_AES_WRAP_RSA(ac_rsassa_vect18),
+ RSA_AES_WRAP_KEY(ac_rsassa_vect19) },
+};
+
+static CK_RV test_rsa_aes_wrap(ADBG_Case_t *c, CK_SESSION_HANDLE session,
+ struct rsa_aes_wrap_test *t)
+{
+ CK_RV rv = CKR_GENERAL_ERROR;
+ CK_OBJECT_HANDLE wrapping_key = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE unwrapping_key = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE target_key = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE unwrapped_key = CK_INVALID_HANDLE;
+ CK_ULONG target_size = t->target_type == CKK_AES ?
+ t->target.aes.size / 8 :
+ t->target.rsa.modulus_len;
+ CK_ULONG target_bits = target_size * 8;
+
+ CK_ATTRIBUTE wrapping_key_template[] = {
+ { CKA_CLASS, &(CK_OBJECT_CLASS){ CKO_PUBLIC_KEY },
+ sizeof(CK_OBJECT_CLASS) },
+ { CKA_KEY_TYPE, &(CK_KEY_TYPE){ CKK_RSA },
+ sizeof(CK_KEY_TYPE) },
+ { CKA_ENCRYPT, &(CK_BBOOL){ CK_FALSE }, sizeof(CK_BBOOL) },
+ { CKA_VERIFY, &(CK_BBOOL){ CK_FALSE }, sizeof(CK_BBOOL) },
+ { CKA_WRAP, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_MODULUS, (CK_VOID_PTR)t->key.modulus,
+ t->key.modulus_len },
+ { CKA_PUBLIC_EXPONENT, (CK_VOID_PTR)t->key.pub_exp,
+ t->key.pub_exp_len },
+ };
+
+ CK_ATTRIBUTE unwrapping_key_template[] = {
+ { CKA_CLASS, &(CK_OBJECT_CLASS){ CKO_PRIVATE_KEY },
+ sizeof(CK_OBJECT_CLASS) },
+ { CKA_KEY_TYPE, &(CK_KEY_TYPE){ CKK_RSA },
+ sizeof(CK_KEY_TYPE) },
+ { CKA_TOKEN, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_SIGN, &(CK_BBOOL){ CK_FALSE }, sizeof(CK_BBOOL) },
+ { CKA_DECRYPT, &(CK_BBOOL){ CK_FALSE }, sizeof(CK_BBOOL) },
+ { CKA_SENSITIVE, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_EXTRACTABLE, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_UNWRAP, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_MODULUS, (CK_VOID_PTR)t->key.modulus,
+ t->key.modulus_len },
+ { CKA_PRIVATE_EXPONENT, (CK_VOID_PTR)t->key.priv_exp,
+ t->key.priv_exp_len },
+ { CKA_PUBLIC_EXPONENT, (CK_VOID_PTR)t->key.pub_exp,
+ t->key.pub_exp_len },
+ { CKA_PRIME_1, (CK_VOID_PTR)t->key.prime1,
+ t->key.prime1_len },
+ { CKA_PRIME_2, (CK_VOID_PTR)t->key.prime2,
+ t->key.prime2_len },
+ };
+
+ CK_ATTRIBUTE aes_key_template[] = {
+ { CKA_VALUE_LEN, &target_size, sizeof(CK_ULONG) },
+ { CKA_ENCRYPT, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_DECRYPT, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_EXTRACTABLE, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ };
+
+ CK_ATTRIBUTE target_key_template[] = {
+ { CKA_CLASS, &(CK_OBJECT_CLASS){ CKO_PRIVATE_KEY },
+ sizeof(CK_OBJECT_CLASS) },
+ { CKA_KEY_TYPE, &(CK_KEY_TYPE){ CKK_RSA },
+ sizeof(CK_KEY_TYPE) },
+ { CKA_TOKEN, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_SIGN, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_DECRYPT, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_SENSITIVE, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_EXTRACTABLE, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_MODULUS, (CK_VOID_PTR)t->target.rsa.modulus,
+ t->target.rsa.modulus_len },
+ { CKA_PRIVATE_EXPONENT, (CK_VOID_PTR)t->target.rsa.priv_exp,
+ t->target.rsa.priv_exp_len },
+ { CKA_PUBLIC_EXPONENT, (CK_VOID_PTR)t->target.rsa.pub_exp,
+ t->target.rsa.pub_exp_len },
+ { CKA_PRIME_1, (CK_VOID_PTR)t->target.rsa.prime1,
+ t->target.rsa.prime1_len },
+ { CKA_PRIME_2, (CK_VOID_PTR)t->target.rsa.prime2,
+ t->target.rsa.prime2_len },
+ };
+
+ CK_ATTRIBUTE unwrapped_aes_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_ENCRYPT, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_DECRYPT, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_EXTRACTABLE, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_SENSITIVE, &(CK_BBOOL){ CK_FALSE}, sizeof(CK_BBOOL) },
+ };
+
+ CK_ATTRIBUTE unwrapped_rsa_key_template[] = {
+ { CKA_CLASS, &(CK_OBJECT_CLASS){ CKO_PRIVATE_KEY },
+ sizeof(CK_OBJECT_CLASS) },
+ { CKA_KEY_TYPE, &(CK_KEY_TYPE){ CKK_RSA },
+ sizeof(CK_KEY_TYPE) },
+ { CKA_ENCRYPT, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_DECRYPT, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_EXTRACTABLE, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_SENSITIVE, &(CK_BBOOL){ CK_FALSE}, sizeof(CK_BBOOL) },
+ };
+
+ CK_ATTRIBUTE *unwrapped_key_template = (t->target_type == CKK_AES) ?
+ unwrapped_aes_key_template :
+ unwrapped_rsa_key_template;
+ CK_ULONG unwrapped_key_template_size = t->target_type == CKK_AES ?
+ ARRAY_SIZE(unwrapped_aes_key_template) :
+ ARRAY_SIZE(unwrapped_rsa_key_template);
+
+ CK_RSA_PKCS_OAEP_PARAMS oaep_params = {
+ CKM_SHA256, CKG_MGF1_SHA256, CKZ_DATA_SPECIFIED, NULL, 0,
+ };
+ CK_RSA_AES_KEY_WRAP_PARAMS rsa_aes_params = {
+ 256, &oaep_params,
+ };
+ CK_MECHANISM rsa_aes_key_wrap_mechanism = {
+ CKM_RSA_AES_KEY_WRAP, &rsa_aes_params, sizeof(rsa_aes_params),
+ };
+
+ CK_BYTE aes_val[RSA_AES_MAX_KEY_SIZE] = { 0 };
+ CK_ULONG key_len = 0;
+ CK_ATTRIBUTE aes_get_template[] = {
+ { CKA_VALUE_LEN, &key_len, sizeof(key_len) },
+ { CKA_VALUE, aes_val, sizeof(aes_val) },
+ };
+
+ CK_BYTE unwrapped_val[RSA_AES_MAX_KEY_SIZE] = { 0 };
+ CK_ULONG unwrapped_key_len = 0;
+ CK_ATTRIBUTE aes_get_template_unwrapped[] = {
+ { CKA_VALUE_LEN, &unwrapped_key_len,
+ sizeof(unwrapped_key_len) },
+ { CKA_VALUE, unwrapped_val, sizeof(unwrapped_val) },
+ };
+
+ CK_BYTE unwrapped_rsa_modulus[512] = { 0 };
+ CK_BYTE unwrapped_rsa_private_exponent[512] = { 0 };
+ CK_ATTRIBUTE rsa_template_unwrapped[] = {
+ { CKA_MODULUS, NULL, 0 },
+ { CKA_MODULUS, unwrapped_rsa_modulus,
+ sizeof(unwrapped_rsa_modulus) },
+ { CKA_PRIVATE_EXPONENT, NULL, 0 },
+ { CKA_PRIVATE_EXPONENT, unwrapped_rsa_private_exponent,
+ sizeof(unwrapped_rsa_private_exponent) },
+ };
+ CK_BYTE buf[5120] = { 0 };
+ CK_ULONG size = 0;
+
+ assert(t != NULL);
+ assert(t->target_type == CKK_RSA || t->target_type == CKK_AES);
+
+ Do_ADBG_BeginSubCase(c,
+ "Test RSA AES wrap/unwrap of %lu %s key with %lu RSA",
+ target_bits, (t->target_type == CKK_AES) ? "AES" : "RSA",
+ t->key.modulus_len * 8);
+
+ rv = C_CreateObject(session, wrapping_key_template,
+ ARRAY_SIZE(wrapping_key_template),
+ &wrapping_key);
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out;
+
+ rv = C_CreateObject(session, unwrapping_key_template,
+ ARRAY_SIZE(unwrapping_key_template),
+ &unwrapping_key);
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out;
+
+ if (t->target_type == CKK_AES) {
+ rv = C_GenerateKey(session, &cktest_aes_keygen_mechanism,
+ aes_key_template,
+ ARRAY_SIZE(aes_key_template),
+ &target_key);
+ } else {
+ rv = C_CreateObject(session, target_key_template,
+ ARRAY_SIZE(target_key_template),
+ &target_key);
+ }
+
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out;
+
+ size = sizeof(buf);
+ rv = C_WrapKey(session, &rsa_aes_key_wrap_mechanism, wrapping_key,
+ target_key, buf, &size);
+
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out;
+ if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, size, <=, sizeof(buf))) {
+ rv = CKR_ENCRYPTED_DATA_INVALID;
+ goto out;
+ }
+
+ if (t->target_type == CKK_AES) {
+ rv = C_GetAttributeValue(session, target_key, aes_get_template,
+ ARRAY_SIZE(aes_get_template));
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out;
+ }
+
+ rv = C_UnwrapKey(session, &rsa_aes_key_wrap_mechanism, unwrapping_key,
+ buf, size, unwrapped_key_template,
+ unwrapped_key_template_size, &unwrapped_key);
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out;
+
+ if (t->target_type == CKK_AES) {
+ rv = C_GetAttributeValue(session, unwrapped_key,
+ aes_get_template_unwrapped,
+ ARRAY_SIZE(aes_get_template_unwrapped));
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out;
+ if (!ADBG_EXPECT_BUFFER(c, unwrapped_val, unwrapped_key_len,
+ aes_val, key_len)) {
+ rv = CKR_DATA_INVALID;
+ goto out;
+ }
+ } else {
+ rv = C_GetAttributeValue(session, unwrapped_key,
+ rsa_template_unwrapped,
+ ARRAY_SIZE(rsa_template_unwrapped));
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out;
+
+ if (!ADBG_EXPECT_BUFFER(c, t->target.rsa.modulus,
+ t->target.rsa.modulus_len,
+ unwrapped_rsa_modulus,
+ rsa_template_unwrapped[0].ulValueLen) ||
+ !ADBG_EXPECT_BUFFER(c, t->target.rsa.priv_exp,
+ t->target.rsa.priv_exp_len,
+ unwrapped_rsa_private_exponent,
+ rsa_template_unwrapped[2].ulValueLen)) {
+ rv = CKR_DATA_INVALID;
+ goto out;
+ }
+ }
+out:
+ if (unwrapped_key != CK_INVALID_HANDLE)
+ ADBG_EXPECT_CK_OK(c, C_DestroyObject(session, unwrapped_key));
+ if (target_key != CK_INVALID_HANDLE)
+ ADBG_EXPECT_CK_OK(c, C_DestroyObject(session, target_key));
+ if (unwrapping_key != CK_INVALID_HANDLE)
+ ADBG_EXPECT_CK_OK(c, C_DestroyObject(session, unwrapping_key));
+ if (wrapping_key != CK_INVALID_HANDLE)
+ ADBG_EXPECT_CK_OK(c, C_DestroyObject(session, wrapping_key));
+ Do_ADBG_EndSubCase(c, NULL);
+ return rv;
+}
+
+static void xtest_pkcs11_test_1026(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 private_key = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE unwrapped_key = CK_INVALID_HANDLE;
+
+ CK_ATTRIBUTE 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_ENCRYPT, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_DECRYPT, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_EXTRACTABLE, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_SENSITIVE, &(CK_BBOOL){ CK_FALSE}, sizeof(CK_BBOOL) },
+ };
+
+ CK_RSA_PKCS_OAEP_PARAMS oaep_params = {
+ CKM_SHA256, CKG_MGF1_SHA256, CKZ_DATA_SPECIFIED, NULL, 0,
+ };
+ CK_RSA_AES_KEY_WRAP_PARAMS rsa_aes_params = {
+ 256, &oaep_params,
+ };
+ CK_MECHANISM rsa_aes_key_wrap_mechanism = {
+ CKM_RSA_AES_KEY_WRAP, &rsa_aes_params, sizeof(rsa_aes_params),
+ };
+
+ uint8_t unwrapped_val[RSA_AES_MAX_KEY_SIZE] = { 0 };
+ CK_ULONG unwrapped_key_len = 0;
+ CK_ATTRIBUTE get_template_unwrapped[] = {
+ { CKA_VALUE_LEN, &unwrapped_key_len,
+ sizeof(unwrapped_key_len) },
+ { CKA_VALUE, unwrapped_val, sizeof(unwrapped_val) },
+ };
+
+ CK_ULONG i = 0;
+
+ CK_ATTRIBUTE private_key_template[] = {
+ { CKA_CLASS, &(CK_OBJECT_CLASS){ CKO_PRIVATE_KEY },
+ sizeof(CK_OBJECT_CLASS) },
+ { CKA_KEY_TYPE, &(CK_KEY_TYPE){ CKK_RSA }, sizeof(CK_KEY_TYPE) },
+ { CKA_TOKEN, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_SIGN, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_DECRYPT, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_SENSITIVE, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_EXTRACTABLE, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_UNWRAP, &(CK_BBOOL){ CK_TRUE }, sizeof(CK_BBOOL) },
+ { CKA_MODULUS, (CK_VOID_PTR)ac_rsassa_vect2_modulus,
+ sizeof(ac_rsassa_vect2_modulus) },
+ { CKA_PRIVATE_EXPONENT, (CK_VOID_PTR)ac_rsassa_vect2_priv_exp,
+ sizeof(ac_rsassa_vect2_priv_exp) },
+ { CKA_PUBLIC_EXPONENT, (CK_VOID_PTR)ac_rsassa_vect2_pub_exp,
+ sizeof(ac_rsassa_vect2_pub_exp) },
+ { CKA_PRIME_1, (CK_VOID_PTR)ac_rsassa_vect2_prime1,
+ sizeof(ac_rsassa_vect2_prime1) },
+ { CKA_PRIME_2, (CK_VOID_PTR)ac_rsassa_vect2_prime2,
+ sizeof(ac_rsassa_vect2_prime2) },
+ };
+
+ rv = init_lib_and_find_token_slot(&slot);
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ return;
+
+ rv = init_test_token(slot);
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto close_lib;
+
+ rv = init_user_test_token(slot);
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto close_lib;
+
+ rv = C_OpenSession(slot, session_flags, NULL, 0, &session);
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto close_lib;
+
+ rv = C_Login(session, CKU_USER, test_token_user_pin,
+ sizeof(test_token_user_pin));
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto close_session;
+
+ for (i = 0; i < ARRAY_SIZE(rsa_aes_wrap_tests); i++) {
+ rv = test_rsa_aes_wrap(c, session, &rsa_aes_wrap_tests[i]);
+ if (rv != CKR_OK)
+ goto logout;
+ }
+
+ Do_ADBG_BeginSubCase(c, "Test external key unwrap with RSA AES");
+ rv = C_CreateObject(session, private_key_template,
+ ARRAY_SIZE(private_key_template), &private_key);
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out;
+
+ rv = C_UnwrapKey(session, &rsa_aes_key_wrap_mechanism, private_key,
+ (CK_VOID_PTR)pkcs11_rsa_aes_wrapped_key,
+ ARRAY_SIZE(pkcs11_rsa_aes_wrapped_key), key_template,
+ ARRAY_SIZE(key_template), &unwrapped_key);
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out;
+
+ rv = C_GetAttributeValue(session, unwrapped_key, get_template_unwrapped,
+ ARRAY_SIZE(get_template_unwrapped));
+ ADBG_EXPECT_CK_OK(c, rv);
+ ADBG_EXPECT_BUFFER(c, unwrapped_val, unwrapped_key_len,
+ pkcs11_rsa_aes_tagret_key,
+ ARRAY_SIZE(pkcs11_rsa_aes_tagret_key));
+out:
+ if (unwrapped_key != CK_INVALID_HANDLE)
+ ADBG_EXPECT_CK_OK(c, C_DestroyObject(session, unwrapped_key));
+ if (private_key != CK_INVALID_HANDLE)
+ ADBG_EXPECT_CK_OK(c, C_DestroyObject(session, private_key));
+ Do_ADBG_EndSubCase(c, NULL);
+logout:
+ ADBG_EXPECT_CK_OK(c, C_Logout(session));
+close_session:
+ ADBG_EXPECT_CK_OK(c, C_CloseSession(session));
+close_lib:
+ ADBG_EXPECT_CK_OK(c, close_lib());
+}
+
+ADBG_CASE_DEFINE(pkcs11, 1026, xtest_pkcs11_test_1026,
+ "PKCS11: RSA AES Key Wrap/Unwrap tests");
diff --git a/host/xtest/regression_4000_data.h b/host/xtest/regression_4000_data.h
index 20edbf9..238dffd 100644
--- a/host/xtest/regression_4000_data.h
+++ b/host/xtest/regression_4000_data.h
@@ -8742,4 +8742,80 @@ static const uint8_t ed25519ph_rfc_8032_7_3_out[] = {
0xaa, 0xd1, 0x1c, 0x2a, 0x26, 0x08, 0x34, 0x06
};
+/*
+ * RSA AES wrapped key
+ * Test data generated as follows:
+ * - generate target AES-256 key (target.aes)
+ * - generate wrapping RSA keypair (we use ac_rsassa_vect2 in this case)
+ * - generate intermediate AES-256 KEK
+ * - wrap target key using KEK (RFC 5649):
+ * openssl enc \
+ * -id-aes256-wrap-pad \
+ * -iv A65959A6 \
+ * -K $( hexdump -v -e '/1 "%02x"' < kek.aes ) \
+ * -in target.aes \
+ * -out target_wrapped.enc
+ * - encrypt KEK using wrapping RSA public key:
+ * openssl pkeyutl \
+ * -encrypt \
+ * -pubin \
+ * -inkey vect2_pub.key \
+ * -in kek.aes -out kek_wrapped.enc \
+ * -pkeyopt rsa_padding_mode:oaep \
+ * -pkeyopt rsa_oaep_md:sha256 \
+ * -pkeyopt rsa_mgf1_md:sha256
+ *
+ * - concatenate both:
+ * cat kek_wrapped.enc target_wrapped.enc > pkcs11_rsa_aes_wrapped_key
+ */
+static const uint8_t pkcs11_rsa_aes_wrapped_key[] = {
+ 0x5c, 0x1f, 0x2d, 0x4f, 0xe9, 0x72, 0xf2, 0x67,
+ 0xc7, 0x82, 0x78, 0x28, 0x15, 0xe0, 0x25, 0x75,
+ 0xc5, 0xf0, 0x5c, 0x0b, 0x11, 0x78, 0xbc, 0x3e,
+ 0xf7, 0x3d, 0x8e, 0x33, 0x44, 0x2a, 0xb5, 0x81,
+ 0xc6, 0x4c, 0x06, 0xea, 0x8a, 0xfa, 0x34, 0x86,
+ 0x17, 0x07, 0x87, 0x80, 0x0f, 0x8e, 0x47, 0xe6,
+ 0xaf, 0x48, 0x6c, 0x8b, 0x29, 0x98, 0xb4, 0x69,
+ 0xe2, 0x91, 0x03, 0x51, 0xea, 0x90, 0xa4, 0x66,
+ 0x5c, 0x07, 0xa2, 0xa3, 0x4c, 0x02, 0x3b, 0x71,
+ 0x0c, 0xf2, 0x57, 0x4a, 0x4f, 0x63, 0x14, 0xce,
+ 0x63, 0x17, 0x15, 0xa4, 0x1d, 0x4e, 0x38, 0x53,
+ 0x56, 0x11, 0x56, 0xcc, 0x2e, 0x80, 0xb3, 0xc1,
+ 0xf2, 0x1a, 0x54, 0xd5, 0x5b, 0x80, 0xb5, 0xd8,
+ 0xd7, 0x29, 0x37, 0x76, 0x79, 0xbd, 0xa9, 0xfa,
+ 0x8f, 0x8c, 0x8d, 0x8d, 0xd8, 0xe2, 0x94, 0xe5,
+ 0xf0, 0x62, 0x62, 0x0c, 0x8c, 0x28, 0x5e, 0x77,
+ 0xb6, 0xf3, 0xa9, 0x64, 0x76, 0xe6, 0xd7, 0x9f,
+ 0x0b, 0xe7, 0x17, 0xba, 0x23, 0xe5, 0x13, 0x6f,
+ 0xf8, 0x0f, 0x51, 0xd6, 0x2a, 0x2c, 0x75, 0xb4,
+ 0xd8, 0x1b, 0x13, 0xc8, 0xd4, 0x7f, 0x2a, 0x2c,
+ 0x2c, 0x34, 0x58, 0x6e, 0x26, 0x7a, 0x6c, 0xa9,
+ 0x77, 0x18, 0xb1, 0xbd, 0xb5, 0x0a, 0xdd, 0x46,
+ 0xd6, 0x31, 0x80, 0x51, 0xc1, 0x7c, 0x6b, 0x74,
+ 0x4d, 0x91, 0x9e, 0xbf, 0xce, 0x3a, 0x39, 0xbb,
+ 0x79, 0xab, 0x5f, 0x9e, 0xb5, 0xab, 0x76, 0x37,
+ 0xea, 0x11, 0xf6, 0xe1, 0x50, 0xcb, 0x74, 0xf9,
+ 0x1c, 0x91, 0x5f, 0xf6, 0xc9, 0xd5, 0x9b, 0xc1,
+ 0xfc, 0x76, 0x5a, 0x58, 0xfb, 0xaa, 0x88, 0xcc,
+ 0xaa, 0x4e, 0x31, 0x8e, 0xe5, 0x3d, 0x22, 0xc3,
+ 0xcb, 0x21, 0x3b, 0xd5, 0x95, 0x3a, 0x09, 0xd8,
+ 0xce, 0x7f, 0x39, 0x9b, 0x38, 0x8c, 0x51, 0x61,
+ 0x87, 0x18, 0x7e, 0xf5, 0x5a, 0x0b, 0x70, 0x2b,
+ 0x35, 0xd3, 0x18, 0x0f, 0xc9, 0xe7, 0xc4, 0xf3,
+ 0x9d, 0x14, 0x20, 0x85, 0x64, 0xb1, 0xfb, 0x3b,
+ 0xc0, 0xc1, 0x21, 0x08, 0x8f, 0x2f, 0x3f, 0xb9,
+ 0xde, 0xe9, 0x11, 0x57, 0xaf, 0x35, 0x65, 0xa0,
+ 0x5b, 0x9c, 0x62, 0xfb, 0xc9, 0x80, 0x8b, 0xcc
+};
+
+/*
+ * Sample AES-256 key
+ */
+static const uint8_t pkcs11_rsa_aes_tagret_key[] = {
+ 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
+ 0x76, 0x65, 0x72, 0x79, 0x20, 0x73, 0x65, 0x63,
+ 0x72, 0x65, 0x74, 0x20, 0x41, 0x45, 0x53, 0x20,
+ 0x32, 0x35, 0x36, 0x20, 0x6b, 0x65, 0x79, 0x0a
+};
+
#endif /*XTEST_4000_DATA_H*/