Note that the decrypted length is sensitive when there was padding

The decrypted length reveals the amount of padding that was eliminated, and
thus reveals partial information about the last ciphertext block.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
Gilles Peskine
2025-07-27 21:20:47 +02:00
parent 6cb9f35d8c
commit 46ebc3a758
2 changed files with 12 additions and 0 deletions

View File

@@ -991,6 +991,11 @@ int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx,
* buffer of at least block_size Bytes.
* \param olen The length of the data written to the \p output buffer.
* This may not be \c NULL.
* Note that when decrypting in a mode with padding,
* the actual output length is sensitive and may be
* used to mount a padding oracle attack (see warning
* above), although less efficiently than through
* the invalid-padding condition.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
@@ -1025,6 +1030,10 @@ int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx,
* buffer of at least block_size Bytes.
* \param[out] olen The length of the data written to the \p output buffer.
* This may not be \c NULL.
* Note that when decrypting in a mode with padding,
* the actual output length is sensitive and may be
* used to mount a padding oracle attack (see warning
* on mbedtls_cipher_finish()).
* \param[out] invalid_padding
* If this function returns \c 0 on decryption,
* \p *invalid_padding is \c 0 if the ciphertext was

View File

@@ -921,6 +921,7 @@ void decrypt_test_vec_cf(int cipher_id, int pad_mode, data_t *key,
total_len += outlen;
int actual_finish_result = mbedtls_cipher_finish(&ctx, output + outlen,
&outlen);
TEST_CF_PUBLIC(&outlen, sizeof(outlen));
TEST_EQUAL(actual_finish_result, expected_finish_result);
if (0 != expected_finish_result) {
/* Check output parameter is set to the least-harmful value on error */
@@ -1083,6 +1084,7 @@ void decrypt_padded_test_vec_cf(int cipher_id, int pad_mode, data_t *key,
int actual_finish_result =
mbedtls_cipher_finish_padded(&ctx, output + outlen, &outlen,
&invalid_padding);
TEST_CF_PUBLIC(&outlen, sizeof(outlen));
switch (expected_finish_result) {
case 0:
TEST_EQUAL(actual_finish_result, 0);
@@ -1439,6 +1441,7 @@ void test_vec_crypt_cf(int cipher_id, int pad_mode, int operation, data_t *key,
mbedtls_cipher_crypt(&ctx, iv->len ? iv->x : NULL, iv->len,
input->x, input->len,
output, &outlen);
TEST_CF_PUBLIC(&outlen, sizeof(outlen));
TEST_EQUAL(expected_finish_result, actual_finish_result);
/* check plaintext only if everything went fine */