diff --git a/tests/suites/test_suite_psa_crypto_constant_time.data b/tests/suites/test_suite_psa_crypto_constant_time.data new file mode 100644 index 0000000000..9b4c64e6c9 --- /dev/null +++ b/tests/suites/test_suite_psa_crypto_constant_time.data @@ -0,0 +1,39 @@ +CT encrypt CHACHA20 +depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20 +ct_cipher_encrypt:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"000000000000004a00000000":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":"af051e40bba0354981329a806a140eafd258a22a6dcb4bb9f6569cb3efe2deaf837bd87ca20b5ba12081a306af0eb35c41a239d20dfc74c81771560d9c9c1e4b224f51f3401bd9e12fde276fb8631ded8c131f823d2c06e27e4fcaec9ef3cf788a3b0aa372600a92b57974cded2b9334794cba40c63e34cdea212c4cf07d41b769a6749f3f630f4122cafe28ec4dc47e26d4346d70b98c73f3e9c53ac40c5945398b6eda1a832c89c167eacd901d7e2bf363" + +CT encrypt AES-CTR +depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:HAVE_CONSTANT_TIME_AES +ct_cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"dd3b5e5319b7591daab1e1a92687feb2":"396ee84fb75fdbb5c2b13c7fe5a654aa" + +CT encrypt AES-CBC-nopad +depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES:HAVE_CONSTANT_TIME_AES +ct_cipher_encrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"49e4e66c89a86b67758df89db9ad6955":"396ee84fb75fdbb5c2b13c7fe5a654aa" + +CT encrypt AES-CBC-PKCS7 +depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES:HAVE_CONSTANT_TIME_AES +ct_cipher_encrypt:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":"a076ec9dfbe47d52afc357336f20743bca7e8a15dc3c776436314293031cd4f3" + +CT decrypt CHACHA20 +depends_on:PSA_WANT_ALG_STREAM_CIPHER:PSA_WANT_KEY_TYPE_CHACHA20 +ct_cipher_decrypt:PSA_ALG_STREAM_CIPHER:PSA_KEY_TYPE_CHACHA20:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"000000000000004a00000000":"af051e40bba0354981329a806a140eafd258a22a6dcb4bb9f6569cb3efe2deaf837bd87ca20b5ba12081a306af0eb35c41a239d20dfc74c81771560d9c9c1e4b224f51f3401bd9e12fde276fb8631ded8c131f823d2c06e27e4fcaec9ef3cf788a3b0aa372600a92b57974cded2b9334794cba40c63e34cdea212c4cf07d41b769a6749f3f630f4122cafe28ec4dc47e26d4346d70b98c73f3e9c53ac40c5945398b6eda1a832c89c167eacd901d7e2bf363":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":0 + +CT decrypt AES-CTR +depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:HAVE_CONSTANT_TIME_AES +ct_cipher_decrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":"dd3b5e5319b7591daab1e1a92687feb2":0 + +CT decrypt AES-CBC-nopad +depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES:HAVE_CONSTANT_TIME_AES +ct_cipher_decrypt:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":"49e4e66c89a86b67758df89db9ad6955":0 + +CT decrypt AES-CBC-PKCS7 good +depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES:HAVE_CONSTANT_TIME_AES +ct_cipher_decrypt:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743bca7e8a15dc3c776436314293031cd4f3":"6bc1bee22e409f96e93d7e117393172a":0 + +CT decrypt AES-CBC-PKCS7 invalid padding @0 +depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES:HAVE_CONSTANT_TIME_AES +ct_cipher_decrypt:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743bf42ddf64c420325affb343d5d5f5d5dc":"6bc1bee22e409f96e93d7e117393172a":1 + +CT decrypt AES-CBC-PKCS7 invalid padding @16 +depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES:HAVE_CONSTANT_TIME_AES +ct_cipher_decrypt:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"a076ec9dfbe47d52afc357336f20743ba3d6a86d0a9d172eeb1b754512d04416":"6bc1bee22e409f96e93d7e117393172a":1 diff --git a/tests/suites/test_suite_psa_crypto_constant_time.function b/tests/suites/test_suite_psa_crypto_constant_time.function new file mode 100644 index 0000000000..fb8368ad31 --- /dev/null +++ b/tests/suites/test_suite_psa_crypto_constant_time.function @@ -0,0 +1,161 @@ +/* BEGIN_HEADER */ +/* Positive test cases for PSA crypto APIs that assert constant-time + * (more accurately constant-flow) behavior. */ + +#include +#include + +/* Our software AES implementation is not constant-time. For constant-time + * testing involving AES, require a hardware-assisted AES that is + * constant-time. + * + * We assume that if the hardware-assisted version is available in the build, + * it will be available at runtime. The AES tests will fail if run on a + * processor without AESNI/AESCE. + */ +#include "aesce.h" +#include "aesni.h" +#if defined(MBEDTLS_AESCE_HAVE_CODE) || defined(MBEDTLS_AESNI_HAVE_CODE) +#define HAVE_CONSTANT_TIME_AES +#endif + +/* END_HEADER */ + +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_PSA_CRYPTO_C + * END_DEPENDENCIES + */ + +/* BEGIN_CASE */ +/* Known answer test for cipher multipart encryption. + * There is no known answer test for one-shot encryption because that + * uses a random IV. */ +void ct_cipher_encrypt(int alg_arg, + int key_type_arg, const data_t *key_data, + const data_t *iv, + const data_t *plaintext, + const data_t *expected_ciphertext) +{ + psa_key_type_t key_type = key_type_arg; + psa_algorithm_t alg = alg_arg; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + unsigned char *output = NULL; + size_t output_size = PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(plaintext->len); + size_t update_length = SIZE_MAX; + size_t finish_length = SIZE_MAX; + + PSA_INIT(); + TEST_CALLOC(output, output_size); + TEST_CF_SECRET(key_data->x, key_data->len); + TEST_CF_SECRET(plaintext->x, plaintext->len); + //TEST_ASSERT(key_data->x[0] != 42); // uncomment to trip constant-flow test + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, key_type); + PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, &key)); + + PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg)); + PSA_ASSERT(psa_cipher_set_iv(&operation, iv->x, iv->len)); + PSA_ASSERT(psa_cipher_update(&operation, + plaintext->x, plaintext->len, + output, output_size, &update_length)); + TEST_LE_U(update_length, output_size); + PSA_ASSERT(psa_cipher_finish(&operation, + output + update_length, + output_size - update_length, + &finish_length)); + + TEST_CF_PUBLIC(output, output_size); + TEST_MEMORY_COMPARE(expected_ciphertext->x, expected_ciphertext->len, + output, update_length + finish_length); + +exit: + mbedtls_free(output); + psa_cipher_abort(&operation); + psa_destroy_key(key); + PSA_DONE(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +/* Known answer for cipher decryption (one-shot and multipart). + * Supports good cases and invalid padding cases. */ +void ct_cipher_decrypt(int alg_arg, + int key_type_arg, const data_t *key_data, + const data_t *iv, + const data_t *ciphertext, + const data_t *expected_plaintext, + int expect_invalid_padding) +{ + psa_key_type_t key_type = key_type_arg; + psa_algorithm_t alg = alg_arg; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + unsigned char *input = NULL; + unsigned char *output = NULL; + size_t output_size = PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE(ciphertext->len); + size_t update_length = SIZE_MAX; + size_t finish_length = SIZE_MAX; + size_t output_length = SIZE_MAX; + psa_status_t status; + + PSA_INIT(); + TEST_CALLOC(output, output_size); + TEST_CF_SECRET(key_data->x, key_data->len); + TEST_CF_SECRET(ciphertext->x, ciphertext->len); + //TEST_ASSERT(key_data->x[0] != 42); // uncomment to trip constant-flow test + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, key_type); + PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, &key)); + + PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg)); + PSA_ASSERT(psa_cipher_set_iv(&operation, iv->x, iv->len)); + PSA_ASSERT(psa_cipher_update(&operation, + ciphertext->x, ciphertext->len, + output, output_size, &update_length)); + TEST_LE_U(update_length, output_size); + status = psa_cipher_finish(&operation, + output + update_length, + output_size - update_length, + &finish_length); + TEST_CF_PUBLIC(output, output_size); + + if (expect_invalid_padding) { + TEST_EQUAL(status, PSA_ERROR_INVALID_PADDING); + } else { + TEST_EQUAL(status, PSA_SUCCESS); + TEST_MEMORY_COMPARE(expected_plaintext->x, expected_plaintext->len, + output, update_length + finish_length); + } + + memset(output, 0, output_size); + TEST_CALLOC(input, iv->len + ciphertext->len); + memcpy(input, iv->x, iv->len); + memcpy(input + iv->len, ciphertext->x, ciphertext->len); + status = psa_cipher_decrypt(key, alg, + input, iv->len + ciphertext->len, + output, output_size, &output_length); + TEST_CF_PUBLIC(output, output_size); + + if (expect_invalid_padding) { + TEST_EQUAL(status, PSA_ERROR_INVALID_PADDING); + } else { + TEST_EQUAL(status, PSA_SUCCESS); + TEST_MEMORY_COMPARE(expected_plaintext->x, expected_plaintext->len, + output, output_length); + } + +exit: + mbedtls_free(input); + mbedtls_free(output); + psa_cipher_abort(&operation); + psa_destroy_key(key); + PSA_DONE(); +} +/* END_CASE */