Zeroize local AES variables before exiting the function
This issue has been reported by Tuba Yavuz, Farhaan Fowze, Ken (Yihang) Bai,
Grant Hernandez, and Kevin Butler (University of Florida) and
Dave Tian (Purdue University).
In AES encrypt and decrypt some variables were left on the stack. The value
of these variables can be used to recover the last round key. To follow best
practice and to limit the impact of buffer overread vulnerabilities (like
Heartbleed) we need to zeroize them before exiting the function.
diff --git a/ChangeLog b/ChangeLog
index 16982a0..ee94c6c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,16 @@
= mbed TLS 2.7.x branch released xxxx-xx-xx
+Security
+ * Zeroize local variables in mbedtls_internal_aes_encrypt() and
+ mbedtls_internal_aes_decrypt() before exiting the function. The value of
+ these variables can be used to recover the last round key. To follow best
+ practice and to limit the impact of buffer overread vulnerabilities (like
+ Heartbleed) we need to zeroize them before exiting the function.
+ Issue reported by Tuba Yavuz, Farhaan Fowze, Ken (Yihang) Bai,
+ Grant Hernandez, and Kevin Butler (University of Florida) and
+ Dave Tian (Purdue University).
+
Changes
* Add unit tests for AES-GCM when called through mbedtls_cipher_auth_xxx()
from the cipher abstraction layer. Fixes #2198.
diff --git a/library/aes.c b/library/aes.c
index 3d2eac8..beeecae 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -761,6 +761,18 @@
PUT_UINT32_LE( X2, output, 8 );
PUT_UINT32_LE( X3, output, 12 );
+ mbedtls_zeroize( &X0, sizeof( X0 ) );
+ mbedtls_zeroize( &X1, sizeof( X1 ) );
+ mbedtls_zeroize( &X2, sizeof( X2 ) );
+ mbedtls_zeroize( &X3, sizeof( X3 ) );
+
+ mbedtls_zeroize( &Y0, sizeof( Y0 ) );
+ mbedtls_zeroize( &Y1, sizeof( Y1 ) );
+ mbedtls_zeroize( &Y2, sizeof( Y2 ) );
+ mbedtls_zeroize( &Y3, sizeof( Y3 ) );
+
+ mbedtls_zeroize( &RK, sizeof( RK ) );
+
return( 0 );
}
#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
@@ -829,6 +841,18 @@
PUT_UINT32_LE( X2, output, 8 );
PUT_UINT32_LE( X3, output, 12 );
+ mbedtls_zeroize( &X0, sizeof( X0 ) );
+ mbedtls_zeroize( &X1, sizeof( X1 ) );
+ mbedtls_zeroize( &X2, sizeof( X2 ) );
+ mbedtls_zeroize( &X3, sizeof( X3 ) );
+
+ mbedtls_zeroize( &Y0, sizeof( Y0 ) );
+ mbedtls_zeroize( &Y1, sizeof( Y1 ) );
+ mbedtls_zeroize( &Y2, sizeof( Y2 ) );
+ mbedtls_zeroize( &Y3, sizeof( Y3 ) );
+
+ mbedtls_zeroize( &RK, sizeof( RK ) );
+
return( 0 );
}
#endif /* !MBEDTLS_AES_DECRYPT_ALT */