Mbed TLS is now part of TrustedFirmware.org.

bogus AES-CTR input validation in mbedtls_cipher_update()

Sep 4, 2017 05:20
Antonio Q.

Hello, I am still new to mbedtls and cryptography therefore I might just be overlooking something big.

I am trying to use AES-CTR to encrypt some data using the same buffer for input and output. The length of the data I am encrypting is not multiple of the block size.

As far as I understood about AES-CTR, the above operation should be allowed.

However, when encrypting using the generic layer via mbedtls_cipher_update() I get MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA. By reading the function, I guessed that the culprit should be the following check:

314     if( input == output &&
315        ( ctx->unprocessed_len != 0 || ilen % block_size ) )
316     {
317         return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
318     }

The check above clearly evaluates to true in my case (input and output are the same and the input len is NOT multiple of the block size).

Is this expected? Shouldn't this check exclude the case of AES-CTR? When using mbedtls_aes_crypt_ctr() directly I can encrypt/decrypt as expected (there is no such check in that function).

Sep 4, 2017 08:33
Ron Eldor

Hi Antonio,
I have moved this issue to the "Bug reports" section, as this is is a bug, as you rightfully claim.
AES-CTR is a stream cipher mode, which allows buffers that are not a multiple of AES block size( 16 ). I have opened a github issue in your name, for tracking this further.
Regards, Mbed TLS Team member

Sep 4, 2017 11:58
Antonio Q.

Hi Ron, thanks for taking care of this. I just subscribed to the bug on GH.

Is the second part of my concern also valid? i.e. should AES-CTR be allowed to operate when output == input ?

Sep 5, 2017 07:24
Ron Eldor

Hi Antonio,
Yes, inplace operations are allowed for AES-CTR. In fact, this issue happens only on inplace operation.
Mbed TLS Team member

Sep 5, 2017 07:35
Antonio Q.

Yeah, thanks for confirming.