Late pad-checking added to prevent [Canvel, B] attack

This commit is contained in:
Simon Rozman 2016-08-15 22:48:08 +02:00
parent 7fa3289e3d
commit 82e910fea4

View File

@ -1283,14 +1283,16 @@ void eap::method_tls::decrypt_message(_In_ tls_message_type_t type, _Inout_ sani
if (!data.empty()) {
size_t size_data = data.size();
bool padding_ok = true;
if (m_state.m_size_enc_block) {
// Check padding.
// Check padding. Do not throw until HMAC is calculated.
// [Canvel, B., "Password Interception in a SSL/TLS Channel"](http://lasecwww.epfl.ch/memo_ssl.shtml)
unsigned char padding = data.back();
size_data -= padding + 1;
size_data = padding + 1 <= size_data ? size_data - (padding + 1) : 0;
for (size_t i = size_data, i_end = data.size() - 1; i < i_end; i++)
if (data[i] != padding)
throw invalid_argument(__FUNCTION__ " Incorrect message padding.");
padding_ok = false;
// Remove padding.
data.resize(size_data);
@ -1317,6 +1319,10 @@ void eap::method_tls::decrypt_message(_In_ tls_message_type_t type, _Inout_ sani
sanitizing_blob hmac;
hash.calculate(hmac);
// // Check padding results.
if (!padding_ok)
throw invalid_argument(__FUNCTION__ " Incorrect message padding.");
// Verify hash.
if (memcmp(&*(data.begin() + size_data), hmac.data(), m_state.m_size_mac_hash) != 0)
throw win_runtime_error(ERROR_DECRYPTION_FAILED, __FUNCTION__ " Integrity check failed.");