Skip to content

Crypto integration with SPM #9409

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions TESTS/mbed-crypto/sanity/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,115 @@ void test_crypto_key_derivation(void)
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_destroy_key(derived_slot));
}

void test_crypto_key_handles(void)
{
psa_key_id_t id = 999;
psa_key_type_t type = PSA_KEY_TYPE_AES;
size_t bits = 256;
psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING;
psa_key_handle_t key_handle;
psa_key_policy_t policy;

key_handle = 0;
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_allocate_key(&key_handle));
TEST_ASSERT_NOT_EQUAL(0, key_handle);
policy = psa_key_policy_init();
psa_key_policy_set_usage(&policy, usage, alg);
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_set_key_policy(key_handle, &policy));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_generate_key(key_handle, type, bits, NULL, 0));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_close_key(key_handle));

key_handle = 0;
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_allocate_key(&key_handle));
TEST_ASSERT_NOT_EQUAL(0, key_handle);
policy = psa_key_policy_init();
psa_key_policy_set_usage(&policy, usage, alg);
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_set_key_policy(key_handle, &policy));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_generate_key(key_handle, type, bits, NULL, 0));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_destroy_key(key_handle));

key_handle = 0;
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_create_key(PSA_KEY_LIFETIME_PERSISTENT, id, &key_handle));
TEST_ASSERT_NOT_EQUAL(0, key_handle);
policy = psa_key_policy_init();
psa_key_policy_set_usage(&policy, usage, alg);
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_set_key_policy(key_handle, &policy));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_generate_key(key_handle, type, bits, NULL, 0));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_close_key(key_handle));

key_handle = 0;
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_open_key(PSA_KEY_LIFETIME_PERSISTENT, id, &key_handle));
TEST_ASSERT_NOT_EQUAL(0, key_handle);
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_destroy_key(key_handle));

key_handle = 0;
TEST_ASSERT_EQUAL(PSA_ERROR_EMPTY_SLOT, psa_open_key(PSA_KEY_LIFETIME_PERSISTENT, id, &key_handle));
}

void test_crypto_hash_clone(void)
{
psa_algorithm_t alg = PSA_ALG_SHA_256;
unsigned char hash[PSA_HASH_MAX_SIZE];
size_t hash_len;
psa_hash_operation_t source;
psa_hash_operation_t target;
/* SHA-256 hash of an empty string */
static const unsigned char expected_hash[] = {
0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55
};

source = psa_hash_operation_init();
target = psa_hash_operation_init();
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_setup(&source, alg));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_finish(&source, hash, sizeof(hash), &hash_len));
/* should fail because psa_hash_finish has been called on source */
TEST_ASSERT_EQUAL(PSA_ERROR_BAD_STATE, psa_hash_clone(&source, &target));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_abort(&source));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_abort(&target));

source = psa_hash_operation_init();
target = psa_hash_operation_init();
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_setup(&source, alg));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_verify(&source, expected_hash, sizeof(expected_hash)));
/* should fail because psa_hash_verify has been called on source */
TEST_ASSERT_EQUAL(PSA_ERROR_BAD_STATE, psa_hash_clone(&source, &target));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_abort(&source));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_abort(&target));

source = psa_hash_operation_init();
target = psa_hash_operation_init();
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_setup(&source, alg));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_abort(&source));
/* should fail because psa_hash_abort has been called on source */
TEST_ASSERT_EQUAL(PSA_ERROR_BAD_STATE, psa_hash_clone(&source, &target));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_abort(&target));

source = psa_hash_operation_init();
target = psa_hash_operation_init();
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_setup(&source, alg));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_setup(&target, alg));
/* should fail because psa_hash_setup has been called on target */
TEST_ASSERT_EQUAL(PSA_ERROR_BAD_STATE, psa_hash_clone(&source, &target));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_abort(&source));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_abort(&target));

source = psa_hash_operation_init();
target = psa_hash_operation_init();
/* should fail because psa_hash_setup has not been called on source */
TEST_ASSERT_EQUAL(PSA_ERROR_BAD_STATE, psa_hash_clone(&source, &target));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_abort(&source));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_abort(&target));

source = psa_hash_operation_init();
target = psa_hash_operation_init();
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_setup(&source, alg));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_clone(&source, &target));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_abort(&source));
TEST_ASSERT_EQUAL(PSA_SUCCESS, psa_hash_abort(&target));
}

utest::v1::status_t case_setup_handler(const Case *const source, const size_t index_of_case)
{
Expand Down Expand Up @@ -326,6 +435,8 @@ Case cases[] = {
Case("mbed-crypto symmetric cipher encrypt/decrypt", case_setup_handler, test_crypto_symmetric_cipher_encrypt_decrypt, case_teardown_handler),
Case("mbed-crypto asymmetric sign/verify", case_setup_handler, test_crypto_asymmetric_sign_verify, case_teardown_handler),
Case("mbed-crypto key derivation", case_setup_handler, test_crypto_key_derivation, case_teardown_handler),
Case("mbed-crypto key handles", case_setup_handler, test_crypto_key_handles, case_teardown_handler),
Case("mbed-crypto hash clone", case_setup_handler, test_crypto_hash_clone, case_teardown_handler),
};

Specification specification(test_setup, cases);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,24 @@ typedef enum psa_sec_function_s {
PSA_CRYPTO_INVALID,
PSA_CRYPTO_INIT,
PSA_IMPORT_KEY,
PSA_ALLOCATE_KEY,
PSA_CREATE_KEY,
PSA_OPEN_KEY,
PSA_CLOSE_KEY,
PSA_DESTROY_KEY,
PSA_GET_KEY_INFORMATION,
PSA_EXPORT_KEY,
PSA_EXPORT_PUBLIC_KEY,
PSA_KEY_POLICY_INIT,
PSA_KEY_POLICY_SET_USAGE,
PSA_KEY_POLICY_GET_USAGE,
PSA_KEY_POLICY_GET_ALGORITHM,
PSA_SET_KEY_POLICY,
PSA_GET_KEY_POLICY,
PSA_SET_KEY_LIFETIME,
PSA_GET_KEY_LIFETIME,
PSA_HASH_SETUP,
PSA_HASH_UPDATE,
PSA_HASH_FINISH,
PSA_HASH_VERIFY,
PSA_HASH_ABORT,
PSA_HASH_CLONE_BEGIN,
PSA_HASH_CLONE_END,
PSA_MAC_SIGN_SETUP,
PSA_MAC_VERIFY_SETUP,
PSA_MAC_UPDATE,
Expand Down Expand Up @@ -95,52 +96,50 @@ typedef enum psa_sec_function_s {
*/

/** psa_crypto_ipc_s struct used for some of the
* PSA Crypto APIs that need psa_key_slot_t and psa_algorithm_t arguments
* PSA Crypto APIs that need psa_key_handle_t and psa_algorithm_t arguments
* and in order to use the existing infrastructure of the SPM-IPC we provide a struct to
* pack them together.
*/

typedef struct psa_crypto_ipc_s {
psa_sec_function_t func;
psa_key_slot_t key;
psa_key_handle_t handle;
psa_algorithm_t alg;
} psa_crypto_ipc_t;

/** psa_crypto_derivation_ipc_s struct used for some of the
* PSA Crypto APIs that need psa_key_slot_t and psa_algorithm_t arguments
* PSA Crypto APIs that need psa_key_handle_t and psa_algorithm_t arguments
* and in order to use the existing infrastructure of the SPM-IPC we provide a struct to
* pack them together.
*/
typedef struct psa_crypto_derivation_ipc_s {
psa_sec_function_t func;
psa_key_slot_t key;
psa_key_handle_t handle;
psa_algorithm_t alg;
size_t capacity;
} psa_crypto_derivation_ipc_t;

/** psa_key_mng_ipc_s struct used for some of the
* PSA Crypto APIs that need psa_key_slot_t and psa_algorithm_t arguments
* PSA Crypto APIs that need psa_key_handle_t and psa_algorithm_t arguments
* and in order to use the existing infrastructure of the SPM-IPC we provide a struct to
* pack them together.
*/

typedef struct psa_key_mng_ipc_s {
psa_key_slot_t key;
psa_key_handle_t handle;
psa_key_lifetime_t lifetime;
psa_key_type_t type;
psa_sec_function_t func;
} psa_key_mng_ipc_t;

/** psa_crypto_ipc_aead_s struct used for AEAD integrated
* PSA Crypto APIs that need psa_key_slot_t and psa_algorithm_t and extra arguments
* PSA Crypto APIs that need psa_key_handle_t and psa_algorithm_t and extra arguments
* and in order to use the existing infrastructure of the SPM-IPC we provide a struct to
* pack them together.
*/

// Max length supported for nonce is 16 bytes.
#define PSA_AEAD_MAX_NONCE_SIZE 16
typedef struct psa_crypto_ipc_aead_s {
psa_sec_function_t func;
psa_key_slot_t key;
psa_key_handle_t handle;
psa_algorithm_t alg;
uint16_t nonce_size;
size_t additional_data_length;
Expand All @@ -149,19 +148,18 @@ typedef struct psa_crypto_ipc_aead_s {
} psa_crypto_ipc_aead_t;

/** psa_crypto_ipc_asymmetric_s struct used for asymmetric
* PSA Crypto APIs that need psa_key_slot_t and psa_algorithm_t arguments
* PSA Crypto APIs that need psa_key_handle_t and psa_algorithm_t arguments
* and in order to use the existing infrastructure of the SPM-IPC we provide a struct to
* pack them together.
*/
typedef struct psa_crypto_ipc_asymmetric_s {
psa_sec_function_t func;
psa_key_slot_t key;
psa_key_handle_t handle;
psa_algorithm_t alg;
size_t input_length;
size_t salt_length;
} psa_crypto_ipc_asymmetric_t;


/**@}*/

#endif /* PSA_CRYPTO_SPE_PLATFORM_H */
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,34 @@ struct psa_hash_operation_s {
psa_handle_t handle;
};

#define PSA_HASH_OPERATION_INIT { PSA_NULL_HANDLE }
static inline struct psa_hash_operation_s psa_hash_operation_init(void)
{
const struct psa_hash_operation_s v = PSA_HASH_OPERATION_INIT;
return(v);
}

struct psa_mac_operation_s {
psa_handle_t handle;
};

#define PSA_MAC_OPERATION_INIT { PSA_NULL_HANDLE }
static inline struct psa_mac_operation_s psa_mac_operation_init(void)
{
const struct psa_mac_operation_s v = PSA_MAC_OPERATION_INIT;
return(v);
}

struct psa_cipher_operation_s {
psa_handle_t handle;
};

struct psa_aead_operation_s {
psa_handle_t handle;
};
#define PSA_CIPHER_OPERATION_INIT { PSA_NULL_HANDLE }
static inline struct psa_cipher_operation_s psa_cipher_operation_init(void)
{
const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT;
return(v);
}

struct psa_crypto_generator_s {
psa_handle_t handle;
Expand All @@ -59,5 +76,11 @@ struct psa_key_policy_s {
psa_algorithm_t alg;
};

#define PSA_KEY_POLICY_INIT {0, 0}
static inline struct psa_key_policy_s psa_key_policy_init(void)
{
const struct psa_key_policy_s v = PSA_KEY_POLICY_INIT;
return(v);
}

#endif /* PSA_CRYPTO_STRUCT_H */
Loading