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>
diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h
index 3778f44..616c554 100644
--- a/include/mbedtls/cipher.h
+++ b/include/mbedtls/cipher.h
@@ -991,6 +991,11 @@
* 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 @@
* 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
diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function
index 9e3e026..ac0264e 100644
--- a/tests/suites/test_suite_cipher.function
+++ b/tests/suites/test_suite_cipher.function
@@ -921,6 +921,7 @@
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 @@
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 @@
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 */