New function mbedtls_cipher_finish_padded
New function `mbedtls_cipher_finish_padded()`, similar to
`mbedtls_cipher_finish()`, but reporting padding errors through a separate
output parameter. This makes it easier to avoid leaking the presence of a
padding error, especially through timing. Thus the new function is
recommended to defend against padding oracle attacks.
In this commit, implement this function naively, with timing that depends on
whether an error happened. A subsequent commit will make this function
constant-time.
Copy the test decrypt_test_vec and decrypt_test_vec_cf test cases into
variants that call `mbedtls_cipher_finish_padded()`.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/library/cipher.c b/library/cipher.c
index 2ae01dd..f3e2f91 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -1124,6 +1124,23 @@
return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
}
+int mbedtls_cipher_finish_padded(mbedtls_cipher_context_t *ctx,
+ unsigned char *output, size_t *olen,
+ size_t *invalid_padding)
+{
+ *invalid_padding = 0;
+ int ret = mbedtls_cipher_finish(ctx, output, olen);
+#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) || \
+ defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) || \
+ defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN)
+ if (ret == MBEDTLS_ERR_CIPHER_INVALID_PADDING) {
+ ret = 0;
+ *invalid_padding = SIZE_MAX;
+ }
+#endif
+ return ret;
+}
+
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx,
mbedtls_cipher_padding_t mode)