DTLS Bad MAC Checks

1. Make the decrypt and verify MAC failure cases behave the same with
   respect to DTLS messages. It should pretend the message never happened.
2. Allow the echoclient to survive the echoserver sending a message with
   a bad MAC.
3. Allow the server to survive the client sending a message with a bad MAC.
This commit is contained in:
John Safranek
2017-07-31 11:24:42 -07:00
parent fb53fac1c1
commit 36a539760a
3 changed files with 44 additions and 4 deletions

View File

@@ -25,10 +25,12 @@
#endif
#include <cyassl/ctaocrypt/settings.h>
/* let's use cyassl layer AND cyassl openssl layer */
#include <cyassl/ssl.h>
#include <cyassl/openssl/ssl.h>
#ifdef CYASSL_DTLS
#include <cyassl/error-ssl.h>
#endif
#if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
#include <stdio.h>
@@ -266,6 +268,14 @@ void echoclient_test(void* args)
fflush(fout) ;
sendSz -= ret;
}
#ifdef CYASSL_DTLS
else if (wolfSSL_dtls(ssl) && err == DECRYPT_ERROR) {
/* This condition is OK. The packet should be dropped
* silently when there is a decrypt or MAC error on
* a DTLS record. */
sendSz = 0;
}
#endif
else {
printf("SSL_read msg error %d, %s\n", err,
ERR_error_string(err, buffer));

View File

@@ -47,6 +47,9 @@
#endif
#include <cyassl/openssl/ssl.h>
#include <cyassl/test.h>
#ifdef CYASSL_DTLS
#include <cyassl/error-ssl.h>
#endif
#include "examples/server/server.h"
@@ -294,6 +297,12 @@ static void ServerRead(WOLFSSL* ssl, char* input, int inputLen)
if (ret < 0) break;
}
else
#endif
#ifdef CYASSL_DTLS
if (wolfSSL_dtls(ssl) && err == DECRYPT_ERROR) {
printf("Dropped client's message due to a bad MAC\n");
}
else
#endif
if (err != SSL_ERROR_WANT_READ) {
printf("SSL_read input error %d, %s\n", err,

View File

@@ -11706,6 +11706,9 @@ int ProcessReply(WOLFSSL* ssl)
ssl->options.processReply = doProcessInit;
ssl->buffers.inputBuffer.idx =
ssl->buffers.inputBuffer.length;
#ifdef WOLFSSL_DTLS_DROP_STATS
ssl->macDropCount++;
#endif /* WOLFSSL_DTLS_DROP_STATS */
}
#endif /* WOLFSSL_DTLS */
@@ -11732,9 +11735,18 @@ int ProcessReply(WOLFSSL* ssl)
if (ret < 0) {
WOLFSSL_MSG("VerifyMac failed");
WOLFSSL_ERROR(ret);
#ifdef WOLFSSL_DTLS_DROP_STATS
ssl->macDropCount++;
#endif /* WOLFSSL_DTLS_DROP_STATS */
#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;
#ifdef WOLFSSL_DTLS_DROP_STATS
ssl->macDropCount++;
#endif /* WOLFSSL_DTLS_DROP_STATS */
}
#endif /* WOLFSSL_DTLS */
return DECRYPT_ERROR;
}
}
@@ -13537,6 +13549,15 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
if (ssl->error == WANT_WRITE || 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 */
#ifdef WOLFSSL_EARLY_DATA
if (ssl->earlyData) {
if (ssl->options.handShakeState == HANDSHAKE_DONE) {