@@ -405,7 +405,13 @@
{
static const char error_prefix[] = "AEAD Decrypt error";
struct packet_id_net pin = { 0 };
- const struct key_ctx *ctx = &opt->key_ctx_bi.decrypt;
+ struct key_ctx *ctx = &opt->key_ctx_bi.decrypt;
+
+ if (cipher_decrypt_verify_fail_exceeded(ctx))
+ {
+ CRYPT_DROP("Decryption failed verification limit reached.");
+ }
+
int outlen;
struct gc_arena gc;
@@ -416,6 +422,8 @@
ASSERT(buf->len > 0);
ASSERT(ctx->cipher);
+
+
dmsg(D_PACKET_CONTENT, "DECRYPT FROM: %s",
format_hex(BPTR(buf), BLEN(buf), 80, &gc));
@@ -511,6 +519,7 @@
if (!cipher_ctx_final_check_tag(ctx->cipher, BPTR(&work) + outlen,
&outlen, tag_ptr, tag_size))
{
+ ctx->failed_verifications++;
CRYPT_DROP("packet tag authentication failed");
}
ASSERT(buf_inc_len(&work, outlen));
@@ -181,6 +181,8 @@
* with the current key in number of 128 bit blocks (only used for
* AEAD ciphers) */
uint64_t plaintext_blocks;
+ /** number of failed verification using this cipher */
+ uint64_t failed_verifications;
};
#define KEY_DIRECTION_BIDIRECTIONAL 0 /* same keys for both directions */
@@ -623,6 +625,29 @@
cipher_get_aead_limits(const char *ciphername);
/**
+ * Check if the number of failed decryption is over the acceptable limit.
+ * We
+ */
+static inline bool
+cipher_decrypt_verify_fail_exceeded(const struct key_ctx *ctx)
+{
+ /* Use 2**36, same as TLS 1.3 */
+ return ctx->failed_verifications > (1ull << 36);
+}
+
+/**
+ * Check if the number of failed decryption is approaching the limit and we
+ * should try to move to a new key
+ */
+static inline bool
+cipher_decrypt_verify_fail_warn(const struct key_ctx *ctx)
+{
+ /* Use 2**35, half the amount after which we refuse to decrypt */
+ return ctx->failed_verifications > (1ull << 35);
+}
+
+
+/**
* Blocksize used for the AEAD limit caluclation
*
* Since cipher_ctx_block_size() is not reliable and will return 1 in many
@@ -3042,6 +3042,11 @@
return true;
}
+ if (cipher_decrypt_verify_fail_warn(&key_ctx_bi->decrypt))
+ {
+ return true;
+ }
+
return false;
}
/*
Attention is currently required from: flichtenheld. Hello flichtenheld, I'd like you to do a code review. Please visit http://gerrit.openvpn.net/c/openvpn/+/843?usp=email to review the following change. Change subject: Do not attempt to decrypt packets anymore after 2**36 failed decryptions ...................................................................... Do not attempt to decrypt packets anymore after 2**36 failed decryptions To avoid attacks (especially on Chacha20-Poly1305) we do not allow decryption anymore after 2**36 failed verifications. Change-Id: I81440ac28a1ad553652e201234e5ddfe03a8c190 Signed-off-by: Arne Schwabe <arne@rfc2549.org> --- M src/openvpn/crypto.c M src/openvpn/crypto.h M src/openvpn/ssl.c 3 files changed, 40 insertions(+), 1 deletion(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/43/843/1