psa_cipher_update with AES-CTR fails when used in-place for a non-block-aligned size
- Dominant language
- C
- Stars
- 108
- Forks
- 95
- PR merge metrics
- No merged PRs in 30d
Description
### Description
Expected behavior: a call to `psa_cipher_update` on AES-CTR used with the nominal sequence of operations succeeds to encrypt 36 bytes.
Actual behavior: `psa_cipher_update` returns `PSA_ERROR_INVALID_ARGUMENT`.
Reported internally by @davidsaada, encountered with mbedcrypto-1.0.0d2 on Mbed OS. I reproduced it with the latest development (72f40c6686f4276dd17c0f68e4dc4d374b74b4ca) on Linux.
```c
#include
#include
#include
#include
int encrypt_test()
{
const int enc_block_size = 16;
psa_key_handle_t enc_handle;
psa_cipher_operation_t operation;
char *data = "Data value of key 3 is the following";
size_t data_size = strlen(data);
unsigned char encrypt_key[enc_block_size];
unsigned char iv_buf[enc_block_size];
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
size_t out_len;
memset(encrypt_key, 0xa5, enc_block_size);
memset(iv_buf, 0, enc_block_size);
iv_buf[0] = 1;
psa_status_t psa_ret = psa_crypto_init();
if (psa_ret != PSA_SUCCESS) {
goto fail;
}
psa_ret = psa_allocate_key(&enc_handle);
if (psa_ret != PSA_SUCCESS) {
goto fail;
}
psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_ENCRYPT, PSA_ALG_CTR);
psa_ret = psa_set_key_policy(enc_handle, &policy);
if (psa_ret != PSA_SUCCESS) {
goto fail;
}
psa_ret = psa_import_key(enc_handle, PSA_KEY_TYPE_AES, encrypt_key, enc_block_size);
if (psa_ret != PSA_SUCCESS) {
goto fail;
}
memset(&operation, 0, sizeof(operation));
psa_ret = psa_cipher_encrypt_setup(&operation, enc_handle, PSA_ALG_CTR);
if (psa_ret != PSA_SUCCESS) {
goto fail;
}
psa_ret = psa_cipher_set_iv(&operation, iv_buf, enc_block_size);
if (psa_ret != PSA_SUCCESS) {
goto fail;
}
psa_ret = psa_cipher_update(&operation, (const unsigned char *) data, data_size, (unsigned char *) data, data_size, &out_len);
if (psa_ret != PSA_SUCCESS) {
goto fail;
}
psa_cipher_abort(&operation);
psa_destroy_key(enc_handle);
return PSA_SUCCESS;
fail:
printf("Operation failed. err %d\n", psa_ret);
return psa_ret;
}
int main(void)
{
return !!encrypt_test();
}
```
### Issue request type
[ ] Question
[ ] Enhancement
[x] Bug
Contributor guide
Research direction
Start by compiling and running the supplied C reproducer against the latest development revision, focusing on the psa_cipher_update entry point with AES-CTR, a 36-byte input, and identical input and output buffers. Done means the in-place call returns PSA_SUCCESS and encrypts the non-block-aligned input without PSA_ERROR_INVALID_ARGUMENT.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- cryptography
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 20/100