In DTLS, if a mac or decrypt error is detected, just drop the datagram and don't send an alert

This commit is contained in:
John Safranek 2016-06-14 14:36:08 -07:00
parent d05754f9db
commit 35f43f9216
1 changed files with 24 additions and 3 deletions

View File

@ -7834,7 +7834,8 @@ static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input,
/* check tag sent along with packet */
if (ConstantCompare(input + msgLen, tag, ssl->specs.aead_mac_size) != 0) {
WOLFSSL_MSG("MAC did not match");
SendAlert(ssl, alert_fatal, bad_record_mac);
if (!ssl->options.dtls)
SendAlert(ssl, alert_fatal, bad_record_mac);
return VERIFY_MAC_ERROR;
}
@ -8098,7 +8099,8 @@ static INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input,
input + sz - ssl->specs.aead_mac_size,
ssl->specs.aead_mac_size,
additional, AEAD_AUTH_DATA_SZ) < 0) {
SendAlert(ssl, alert_fatal, bad_record_mac);
if (!ssl->options.dtls)
SendAlert(ssl, alert_fatal, bad_record_mac);
ret = VERIFY_MAC_ERROR;
}
ForceZero(nonce, AESGCM_NONCE_SZ);
@ -8139,7 +8141,8 @@ static INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input,
input + sz - ssl->specs.aead_mac_size,
ssl->specs.aead_mac_size,
additional, AEAD_AUTH_DATA_SZ) < 0) {
SendAlert(ssl, alert_fatal, bad_record_mac);
if (!ssl->options.dtls)
SendAlert(ssl, alert_fatal, bad_record_mac);
ret = VERIFY_MAC_ERROR;
}
ForceZero(nonce, AESGCM_NONCE_SZ);
@ -8929,6 +8932,15 @@ int ProcessReply(WOLFSSL* ssl)
if (ret < 0) {
WOLFSSL_MSG("Decrypt failed");
WOLFSSL_ERROR(ret);
#ifdef WOLFSSL_DTLS
/* If in DTLS mode, if the decrypt fails for any
* reason, pretend the datagram never happened. */
if (ssl->options.dtls) {
ssl->options.processReply = doProcessInit;
ssl->buffers.inputBuffer.idx =
ssl->buffers.inputBuffer.length;
}
#endif /* WOLFSSL_DTLS */
return DECRYPT_ERROR;
}
if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
@ -10535,6 +10547,15 @@ int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek)
if (ssl->error == WANT_READ || ssl->error == WC_PENDING_E)
ssl->error = 0;
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
/* In DTLS mode, we forgive some errors and allow the session
* to continue despite them. */
if (ssl->error == VERIFY_MAC_ERROR || ssl->error == DECRYPT_ERROR)
ssl->error = 0;
}
#endif /* WOLFSSL_DTLS */
if (ssl->error != 0 && ssl->error != WANT_WRITE) {
WOLFSSL_MSG("User calling wolfSSL_read in error state, not allowed");
return ssl->error;