ARMmbed / ARMmbed/mbed-crypto

psa_cipher_update with AES-CTR fails when used in-place for a non-block-aligned size

Open
#63 4 comments 0 reactions 0 assignees View on GitHub
bug Jira status: OPEN mirrored type: bug
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.