Add BUFFER_TOO_SMALL testing

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
Gilles Peskine
2025-08-07 21:25:23 +02:00
parent b6b1a8299b
commit d3e182e7da

View File

@@ -115,6 +115,8 @@ void ct_cipher_encrypt(int alg_arg,
{
psa_key_type_t key_type = key_type_arg;
psa_algorithm_t alg = alg_arg;
size_t sufficient_output_size =
PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(key_type, alg, plaintext->len);
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;
@@ -129,9 +131,51 @@ void ct_cipher_encrypt(int alg_arg,
psa_set_key_type(&attributes, key_type);
PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, &key));
/* Output buffer too small for the actual output */
mbedtls_test_set_step(1);
PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
if (!ct_cipher_multipart(&operation, iv, plaintext,
PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(plaintext->len),
expected_ciphertext->len - 1,
expected_ciphertext,
PSA_ERROR_BUFFER_TOO_SMALL)) {
goto exit;
}
if (expected_ciphertext->len < sufficient_output_size) {
/* For a buffer of intermediate size (between the actual output length
* and the guaranteed sufficient size), either PSA_SUCCESS or
* PSA_ERROR_BUFFER_TOO_SMALL is acceptable. Require what the our
* built-in implementation currently does. */
psa_status_t intermediate_size_status = PSA_SUCCESS;
/* Output buffer size just large enough for the actual output
* but less than the guaranteed sufficient size */
mbedtls_test_set_step(2);
PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
if (!ct_cipher_multipart(&operation, iv, plaintext,
expected_ciphertext->len,
expected_ciphertext,
intermediate_size_status)) {
goto exit;
}
/* Output buffer size large enough for the actual output
* but one less than the guaranteed sufficient size */
mbedtls_test_set_step(3);
PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
if (!ct_cipher_multipart(&operation, iv, plaintext,
sufficient_output_size - 1,
expected_ciphertext,
intermediate_size_status)) {
goto exit;
}
}
/* Guaranteed sufficient output buffer size */
mbedtls_test_set_step(4);
PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
if (!ct_cipher_multipart(&operation, iv, plaintext,
sufficient_output_size,
expected_ciphertext,
PSA_SUCCESS)) {
goto exit;
@@ -170,22 +214,86 @@ void ct_cipher_decrypt(int alg_arg,
TEST_CF_SECRET(ciphertext->x, ciphertext->len);
//TEST_ASSERT(key_data->x[0] != 42); // uncomment to trip constant-flow test
TEST_CALLOC(input.x, input.len);
memcpy(input.x, iv->x, iv->len);
memcpy(input.x + iv->len, ciphertext->x, ciphertext->len);
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));
/* Output buffer too small for the actual output */
mbedtls_test_set_step(1);
PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
if (!ct_cipher_multipart(&operation, iv, ciphertext,
PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE(ciphertext->len),
expected_plaintext->len - 1,
expected_plaintext,
PSA_ERROR_BUFFER_TOO_SMALL)) {
goto exit;
}
if (!ct_cipher_decrypt_oneshot(key, alg, &input,
expected_plaintext->len - 1,
expected_plaintext,
PSA_ERROR_BUFFER_TOO_SMALL)) {
goto exit;
}
if (expected_plaintext->len < sufficient_output_size) {
/* For a buffer of intermediate size (between the actual output length
* and the guaranteed sufficient size), either PSA_SUCCESS (or
* PSA_ERROR_INVALID_PADDING if the padding is invalid) or
* PSA_ERROR_BUFFER_TOO_SMALL is acceptable. Require what the our
* built-in implementation currently does. */
psa_status_t intermediate_size_status = expected_status;
if (alg == PSA_ALG_CBC_PKCS7) {
intermediate_size_status = PSA_ERROR_BUFFER_TOO_SMALL;
}
/* Output buffer size just large enough for the actual output
* but less than the guaranteed sufficient size */
mbedtls_test_set_step(2);
PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
if (!ct_cipher_multipart(&operation, iv, ciphertext,
expected_plaintext->len,
expected_plaintext,
intermediate_size_status)) {
goto exit;
}
if (!ct_cipher_decrypt_oneshot(key, alg, &input,
expected_plaintext->len - 1,
expected_plaintext,
intermediate_size_status)) {
goto exit;
}
/* Output buffer size large enough for the actual output
* but one less than the guaranteed sufficient size */
mbedtls_test_set_step(3);
PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
if (!ct_cipher_multipart(&operation, iv, ciphertext,
sufficient_output_size - 1,
expected_plaintext,
intermediate_size_status)) {
goto exit;
}
if (!ct_cipher_decrypt_oneshot(key, alg, &input,
sufficient_output_size - 1,
expected_plaintext,
intermediate_size_status)) {
goto exit;
}
}
/* Guaranteed sufficient output buffer size */
mbedtls_test_set_step(4);
PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
if (!ct_cipher_multipart(&operation, iv, ciphertext,
sufficient_output_size,
expected_plaintext,
expected_status)) {
goto exit;
}
TEST_CALLOC(input.x, input.len);
memcpy(input.x, iv->x, iv->len);
memcpy(input.x + iv->len, ciphertext->x, ciphertext->len);
if (!ct_cipher_decrypt_oneshot(key, alg, &input,
sufficient_output_size,
expected_plaintext,