From patchwork Mon Nov 11 01:59:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "plaisthos (Code Review)" X-Patchwork-Id: 3938 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:41ba:b0:5d9:9f4c:3bc7 with SMTP id a26csp2279877mad; Sun, 10 Nov 2024 18:04:17 -0800 (PST) X-Forwarded-Encrypted: i=2; AJvYcCVaFPBqtiPeHKoY8rpQxTpFLjWdF0xdelZjRZhzb9gmIVxPFsb0BkejWuHCBBihuCBvqmnI3hAns3k=@openvpn.net X-Received: by 2002:a05:6e02:9b:b0:3a6:aee2:1696 with SMTP id e9e14a558f8ab-3a6f1a590aemr109007875ab.21.1731290416958; Sun, 10 Nov 2024 18:00:16 -0800 (PST) X-Google-Smtp-Source: AGHT+IH1qVTvmAVVro2HYUV71uUbUtUJ+XXu2bvNEXMVnpXZNVGWmG4sHTfJzOLAyel+paSGKPkp X-Received: by 2002:a05:6e02:9b:b0:3a6:aee2:1696 with SMTP id e9e14a558f8ab-3a6f1a590aemr109006245ab.21.1731290413360; Sun, 10 Nov 2024 18:00:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1731290413; cv=none; d=google.com; s=arc-20240605; b=EcXliZU7CACZgK09xcQrSBAas/wI3PGp0Kt14FTvz8zOty9hp89XI0Piopc2uK3CqT ZGZ7UfGxImPoK25qj/MpmKQ6OdXD8QEkHe6yEiQ4CPXXd3mFeam4eTO12u9gzB/ci7s5 VFUn4kB0wWs+JdhXGST+sBLm7LeKecsGoqWrZZ1/Mtidt/YCBnTEtr95bWUJYTb73sTi 4ZXhD1wmMzBcF8RYbgMft9jsCn78OpVKvI/0KUufrYTX/eIhiBtEEQ4DyHjVjaAckjMr kApyYuP//xdwzvnHk3sKG8iy7NCiWAALwWTnNIup8ZbvI7yie3giC3J6nRPK7ZcASjXy ftNg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:cc:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject:user-agent :mime-version:message-id:references:auto-submitted:to:date:from :dkim-signature:dkim-signature:dkim-signature; bh=J+lWfKvx3nLIFKop8y0Y6JcLWydkatdJOpEFGqXOMBs=; fh=lm0MLPW7DntlrDqRECIiC9JlE1uPxhepE0URYHIf+eE=; b=AR+L8hJtJjzXM7msKcBzGWlOcH4pIAIcadk54qU1YlsWySXK+LvCffDMCoh98vXRxN ZaLrqzmnayOKHE0SAwDPeBGrLdEgP2g8VvWbhfDPB9LNGlXiI7UYa45ls74yFNGIQ7OY SAkfYD3jSNux1LVHuWr8a1uj1mvGSAcjd5JlLWJGR2ADTIjCZ2GfbifJ3kHg54v2+VYO YAjoMG41O4SsbswaXj81/hmCb6OFvckS6ZGGNYC8RzW6p6ORW17Dq1QpAMm68A6hCShK qNv1XuSkc0DJE5MEORWcSmc31d+Na7TsZN6WLaZYDbM38mWfZ+An32dS/jdJFrbo5nGv bTVQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=XpbvMa+9; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b="WQSbc/t/"; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=BoDDFbH1; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=openvpn.net; dara=fail header.i=@openvpn.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 8926c6da1cb9f-4de786fefc2si356759173.35.2024.11.10.18.00.13 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 10 Nov 2024 18:00:13 -0800 (PST) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=XpbvMa+9; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b="WQSbc/t/"; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=BoDDFbH1; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=openvpn.net; dara=fail header.i=@openvpn.net Received: from [127.0.0.1] (helo=sfs-ml-3.v29.lw.sourceforge.com) by sfs-ml-3.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1tAJik-0003Xl-7r; Mon, 11 Nov 2024 02:00:01 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-3.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1tAJif-0003Xc-RK for openvpn-devel@lists.sourceforge.net; Mon, 11 Nov 2024 01:59:57 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Type:Content-Transfer-Encoding:MIME-Version :Message-ID:Reply-To:References:Subject:List-Unsubscribe:List-Id:Cc:To:Date: From:Sender:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:List-Help: List-Subscribe:List-Post:List-Owner:List-Archive; bh=1M5zKgYjyCm21XsESs1S+USAF9j9FVx0ZkrJofXzq7w=; b=XpbvMa+9LLm+JglS2qGtCXXkA6 Am2NqsBqmjitfXL87UBHMJ1eRUf6/ilSMH4/IZH0r+G3wt6hbd7FCzf3b5ADtILKKf/yYb+3MkcwX AuXc7USy/v1Yv4JZDLg6roAQVls3QEhHjTdpcgW0xft5c5orfDDGSuHGl3q+CNIqg9dc=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Type:Content-Transfer-Encoding:MIME-Version:Message-ID:Reply-To: References:Subject:List-Unsubscribe:List-Id:Cc:To:Date:From:Sender:Content-ID :Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To: Resent-Cc:Resent-Message-ID:In-Reply-To:List-Help:List-Subscribe:List-Post: List-Owner:List-Archive; bh=1M5zKgYjyCm21XsESs1S+USAF9j9FVx0ZkrJofXzq7w=; b=W QSbc/t/Pz/xoJo3oRx/UcO1EVslGRp2osEgiEolfAMbYf48E+Vl7hCT+0gmO3d7MjqNDw+2zvzZyo E5j0O2/yvv/Dbw4sE3emVuf/xJCt1yeyHFBVYpr1MCs8akvpvb5qmWhE4BbQYkYUHgl6FjbY1CdDo PzZCKnXhotW6w/YY=; Received: from mail-wr1-f45.google.com ([209.85.221.45]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.95) id 1tAJid-0001YM-DB for openvpn-devel@lists.sourceforge.net; Mon, 11 Nov 2024 01:59:57 +0000 Received: by mail-wr1-f45.google.com with SMTP id ffacd0b85a97d-37d808ae924so2402876f8f.0 for ; Sun, 10 Nov 2024 17:59:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvpn.net; s=google; t=1731290384; x=1731895184; darn=lists.sourceforge.net; h=user-agent:content-disposition:content-transfer-encoding :mime-version:message-id:reply-to:references:subject :list-unsubscribe:list-id:auto-submitted:cc:to:date:from:from:to:cc :subject:date:message-id:reply-to; bh=1M5zKgYjyCm21XsESs1S+USAF9j9FVx0ZkrJofXzq7w=; b=BoDDFbH1mIGZk9C0wIMIxzd+FiSzDYDO7JsivtpmKQjLQB9HpRQObaxyLmX+mjnI0G RDhmkdeQd8KIzYlg2odRARGyT24u3+fwxpv555TXv1B9pXbe9C8J9hzYJPJkngwBfWH9 WdMPERl60mR3NofORlmOa/ivXFrKGEzL4ePysNrgg030zkGdRgR2VVX8pmw20wuScQn6 dSpphXjElWBL6DvyoyKDukqPfJ29zu98/jcfmqtri9pdtukTC70LaUcnBR/ixkFCdOrf bWyMr0dOBJoH9aFwcEScd3w+iaBUULQyBEuVroNZ42fNfX/mRbN9yXdRzDthONBIKh08 oAMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731290384; x=1731895184; h=user-agent:content-disposition:content-transfer-encoding :mime-version:message-id:reply-to:references:subject :list-unsubscribe:list-id:auto-submitted:cc:to:date:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=1M5zKgYjyCm21XsESs1S+USAF9j9FVx0ZkrJofXzq7w=; b=bVi9lyce4rOci7CFmoVLJJI75MZFI9/jcBCz933bLrFCXIxLOXSARLZtdj+TdMuyXu hjRWChN1UluY/hLSPVUbh7vzfzJcXocaRnSh9M8cfmw0qanuXo1XanjK+/Iq15sprnBj OkctHHpGaCM3LTT7D4oC48ljLlaXjM4+EHGEpYmWRffFF/BcQWobUxlLsIx2kxin26wh tMvsVIjbsgYis3gbwIqnrsVf68uXGdZiaOI3pnhcSPx3syiMKj+obhaRw2GFdb44SniU yN540vLZ34gjbfveYQmaQ/MJJKwaQUiFt5Aef39expCC4Nm5Ajaf8ZhjZvrhE+ImczTR tiqw== X-Gm-Message-State: AOJu0YwL4Q0K48mC7bm6q6h+6vBQUM86BCAMAOTzk/nthBPZqfBfC9D6 BdueuwjU0DxfRbhOmWHHsPv5a6yguiq1XSuQzzmPXvWH99pIkAIelIPc8OgbBxSpDT252Ao06TF 0 X-Received: by 2002:a5d:6dab:0:b0:374:c92e:f6b1 with SMTP id ffacd0b85a97d-381f186b53cmr9535600f8f.23.1731290383920; Sun, 10 Nov 2024 17:59:43 -0800 (PST) Received: from gerrit.openvpn.in (ec2-18-159-0-78.eu-central-1.compute.amazonaws.com. [18.159.0.78]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-381eda0517csm11556083f8f.96.2024.11.10.17.59.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 10 Nov 2024 17:59:42 -0800 (PST) From: "plaisthos (Code Review)" X-Google-Original-From: "plaisthos (Code Review)" X-Gerrit-PatchSet: 1 Date: Mon, 11 Nov 2024 01:59:41 +0000 To: flichtenheld Auto-Submitted: auto-generated X-Gerrit-MessageType: newchange X-Gerrit-Change-Id: I057f007577f10c6ac917ee4620ee3d2559187dc7 X-Gerrit-Change-Number: 796 X-Gerrit-Project: openvpn X-Gerrit-ChangeURL: X-Gerrit-Commit: 2e245bcbbe910be83c9841195b20a3c9c9267672 References: Message-ID: MIME-Version: 1.0 User-Agent: Gerrit/3.8.2 X-Spam-Score: -0.9 (/) X-Spam-Report: Spam detection software, running on the system "util-spamd-2.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Attention is currently required from: flichtenheld. Hello flichtenheld, I'd like you to do a code review. Please visit Content analysis details: (-0.9 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.221.45 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.7 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.221.45 listed in wl.mailspike.net] 0.0 WEIRD_PORT URI: Uses non-standard port number for HTTP 0.0 HTML_MESSAGE BODY: HTML included in message -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.0 T_KAM_HTML_FONT_INVALID Test for Invalidly Named or Formatted Colors in HTML X-Headers-End: 1tAJid-0001YM-DB Subject: [Openvpn-devel] [M] Change in openvpn[master]: Trigger renegotiation of data key if getting close to the AEAD usage ... X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: arne-openvpn@rfc2549.org, openvpn-devel@lists.sourceforge.net, frank@lichtenheld.com Cc: openvpn-devel Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1815389576619136145?= X-GMAIL-MSGID: =?utf-8?q?1815389576619136145?= X-getmail-filter-classifier: gerrit message type newchange 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/+/796?usp=email to review the following change. Change subject: Trigger renegotiation of data key if getting close to the AEAD usage limit ...................................................................... Trigger renegotiation of data key if getting close to the AEAD usage limit This implements the limitation of AEAD key usage[1] with a confidentiality margin of 2^-57, the same as TLS 1.3. In this implementation, unlike TLS 1.3 that counts the number of records, we count the actual number of packets and plaintext blocks. TLS 1.3 can reasonable assume that for large data transfers, full records are used and therefore the maximum record size of 2**14 (2*10 blocks) is used to calculate the number of records before a new key needs to be used. For a VPN OpenVPN, the same calculation would either require using a pessimistic assumption of using a MTU size of 65k which limits us to 2^24 packets, which equals only 24 GB with more common MTU/MSS of 1400 or requiring a dynamic calculation which includes the actual MTU that we allow to send. For 1500 the calculation yields 2*29.4 which is a quite significant higher number of packets (923 GB at 1400 MSS/MTU). To avoid this dynamic calculation and also avoiding needing to know the MSS/MTU size in the crypto layer, this implementation foregoes the simplification of counting just packets but will count blocks and packets instead and determines the limit from that. This also has the side effects that connection with a lot of small packets (like TCP ACKs) mixed with large packets will be able to keep using the same much longer until requiring a renegotiation. This patch will set the limit where to trigger the renegotiation at 7/8 of the [1] https://www.ietf.org/archive/id/draft-irtf-cfrg-aead-limits-08.html Change-Id: Idccc93f303d29869ef4ed10b6bb56f37efedf623 Testing instructions: The easiest way to test if this patch works as intended is to manually change the return value of cipher_get_aead_limits to some silly low value like 2048. After a bit of VPN traffic, a soft reset should occur that indicates being over the TLS: soft reset sec=41/3600 bytes=59720/-1 pkts=78/0 aead_limit_send=1883/1792 aead_limit_recv=1937/1792 Here the send limit is over the limit (1792 = 2048 * 8/7). Change-Id: I0d2c763fd1dcdacdd8993731fc4979e258d1da4e Change-Id: I057f007577f10c6ac917ee4620ee3d2559187dc7 Signed-off-by: Arne Schwabe --- M Changes.rst M src/openvpn/crypto.c M src/openvpn/crypto.h M src/openvpn/ssl.c M src/openvpn/ssl_common.h M tests/unit_tests/openvpn/test_crypto.c 6 files changed, 159 insertions(+), 5 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/96/796/1 diff --git a/Changes.rst b/Changes.rst index a6cc3be..34542a5 100644 --- a/Changes.rst +++ b/Changes.rst @@ -22,6 +22,14 @@ For more details see [lwipovpn on Gihtub](https://github.com/OpenVPN/lwipovpn). +Enforcement of AES-GCM usage limit + OpenVPN will now enforce the usage limits on AES-GCM with the same + confidentiality margin as TLS 1.3 does. This mean that renegotiation will + be triggered after roughly 2^28 to 2^31 packets depending of the packet + size. More details about usage limit of AES-GCM can be found here: + + https://datatracker.ietf.org/doc/draft-irtf-cfrg-aead-limits/ + Deprecated features ------------------- ``secret`` support has been removed by default. diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c index 8f34eaa..d136663 100644 --- a/src/openvpn/crypto.c +++ b/src/openvpn/crypto.c @@ -37,6 +37,7 @@ #include "platform.h" #include "memdbg.h" +#include /* * Encryption and Compression Routines. @@ -134,6 +135,11 @@ ASSERT(cipher_ctx_update(ctx->cipher, BEND(&work), &outlen, BPTR(buf), BLEN(buf))); ASSERT(buf_inc_len(&work, outlen)); + /* update number of plaintext blocks encrypted. Use the x + (n-1)/n trick + * to round up the result to the number of blocked used */ + const int blocksize = AEAD_LIMIT_BLOCKSIZE; + opt->key_ctx_bi.encrypt.plaintext_blocks += (outlen + (blocksize - 1))/blocksize; + /* Flush the encryption buffer */ ASSERT(cipher_ctx_final(ctx->cipher, BEND(&work), &outlen)); ASSERT(buf_inc_len(&work, outlen)); @@ -321,6 +327,38 @@ } } +int64_t +cipher_get_aead_limits(const char *ciphername) +{ + if (!cipher_kt_mode_aead(ciphername)) + { + return 0; + } + + if (cipher_kt_name(ciphername) == cipher_kt_name("CHACHA20-POLY1305")) + { + return 0; + } + + /* Assume all other ciphers require the limit */ + + /* We focus here on the equation + * + * q + s <= p^(1/2) * 2^(129/2) - 1 + * q <= (p^(1/2) * 2^(129/2) - 1) / (L + 1) + * + * as is the one that is limiting us. + * + * With p = 2^-57 this becomes + * + * q + s <= (p^36 - 1) + * + */ + int64_t rs = (1ull << 36) - 1; + + return rs; +} + bool crypto_check_replay(struct crypto_options *opt, const struct packet_id_net *pin, const char *error_prefix, @@ -462,6 +500,11 @@ CRYPT_ERROR("packet decryption failed"); } + /* update number of plaintext blocks decrypted. Use the x + (n-1)/n trick + * to round up the result to the number of blocked used. */ + const int blocksize = AEAD_LIMIT_BLOCKSIZE; + opt->key_ctx_bi.decrypt.plaintext_blocks += (outlen + (blocksize - 1))/blocksize; + ASSERT(buf_inc_len(&work, outlen)); if (!cipher_ctx_final_check_tag(ctx->cipher, BPTR(&work) + outlen, &outlen, tag_ptr, tag_size)) diff --git a/src/openvpn/crypto.h b/src/openvpn/crypto.h index 074dad6..7b0f713 100644 --- a/src/openvpn/crypto.h +++ b/src/openvpn/crypto.h @@ -166,6 +166,9 @@ uint8_t implicit_iv[OPENVPN_MAX_IV_LENGTH]; /**< The implicit part of the IV */ size_t implicit_iv_len; /**< The length of implicit_iv */ + /** Counter for the number of plaintext encrypted using this cipher + * in number of 128 bit blocks (only used for AEAD ciphers) */ + uint64_t plaintext_blocks; }; #define KEY_DIRECTION_BIDIRECTIONAL 0 /* same keys for both directions */ @@ -596,6 +599,24 @@ } /** + * Check if the cipher is an AEAD cipher and needs to be limited to a certain + * number of number of block + packets. Return -1 if ciphername is not an AEAD + * cipher or no limit (e.g. Chacha20-Poly1305) is needed. + * + * For reference see the OpenVPN RFC draft and + * https://www.ietf.org/archive/id/draft-irtf-cfrg-aead-limits-08.html + */ +int64_t +cipher_get_aead_limits(const char *ciphername); + +/** + * Blocksize used for the AEAD limit caluclation + * + * Since cipher_ctx_block_size() is reliable and will return 1 in many + * cases use a hardcoded blocksize instead */ +#define AEAD_LIMIT_BLOCKSIZE 16 + +/** * Checks if the current TLS library supports the TLS 1.0 PRF with MD5+SHA1 * that OpenVPN uses when TLS Keying Material Export is not available. * @@ -603,4 +624,20 @@ */ bool check_tls_prf_working(void); +/** + * Checks if the usage limit for an AEAD cipher is reached + * + * This method abstracts the calculation to make the calling function easier + * to read. + */ +static inline bool +aead_usage_limit_reached(const int64_t limit, const struct key_ctx *key_ctx, + int64_t higest_pid) +{ + /* This is the q + s <= p^(1/2) * 2^(129/2) - 1 calculation where + * q is the number of protected messages (highest_pid) + * s Total plaintext length in all messages (in blocks) */ + return (limit > 0 && key_ctx->plaintext_blocks + higest_pid > limit); +} + #endif /* CRYPTO_H */ diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index ab55365..a8cc83b 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -131,6 +131,26 @@ } } +static int64_t +tls_get_limit_aead(const char *ciphername) +{ + int64_t limit = cipher_get_aead_limits(ciphername); + + if (limit == 0) + { + return 0; + } + + /* set limit to 7/8 of the limit so the renogiation has can succeeds before + * we go over the limit */ + limit = limit * 7/8; + + msg(D_SHOW_KEYS, "Note: AEAD cipher %s will be limited to a sum of %" + PRIi64 " for block and packets before renegotiation", + ciphername, limit); + return limit; +} + void tls_init_control_channel_frame_parameters(struct frame *frame, int tls_mtu) { @@ -1576,6 +1596,8 @@ tls_limit_reneg_bytes(session->opt->key_type.cipher, &session->opt->renegotiate_bytes); + session->opt->aead_usage_limit = tls_get_limit_aead(session->opt->key_type.cipher); + /* set the state of the keys for the session to generated */ ks->state = S_GENERATED_KEYS; @@ -2996,6 +3018,18 @@ return true; } + /* Check the AEAD usage limit of cleartext blocks + packets */ + const struct key_ctx_bi *key_ctx_bi = &ks->crypto_options.key_ctx_bi; + const int64_t usage_limit = session->opt->aead_usage_limit; + + if (aead_usage_limit_reached(usage_limit, &key_ctx_bi->encrypt, + ks->crypto_options.packet_id.send.id) + || aead_usage_limit_reached(usage_limit, &key_ctx_bi->decrypt, + ks->crypto_options.packet_id.rec.id)) + { + return true; + } + return false; } /* @@ -3026,12 +3060,19 @@ /* Should we trigger a soft reset? -- new key, keeps old key for a while */ if (ks->state >= S_GENERATED_KEYS && should_trigger_renegotiation(session, ks)) - { + { msg(D_TLS_DEBUG_LOW, "TLS: soft reset sec=%d/%d bytes=" counter_format - "/%" PRIi64 " pkts=" counter_format "/%" PRIi64, + "/%" PRIi64 " pkts=" counter_format "/%" PRIi64 + " aead_limit_send=%" PRIu64 "/%" PRIu64 + " aead_limit_recv=%" PRIu64 "/%" PRIu64, (int) (now - ks->established), session->opt->renegotiate_seconds, ks->n_bytes, session->opt->renegotiate_bytes, - ks->n_packets, session->opt->renegotiate_packets); + ks->n_packets, session->opt->renegotiate_packets, + ks->crypto_options.key_ctx_bi.encrypt.plaintext_blocks + ks->n_packets, + session->opt->aead_usage_limit, + ks->crypto_options.key_ctx_bi.decrypt.plaintext_blocks + ks->n_packets, + session->opt->aead_usage_limit + ); key_state_soft_reset(session); } diff --git a/src/openvpn/ssl_common.h b/src/openvpn/ssl_common.h index 5840e2d..ce1cd9e 100644 --- a/src/openvpn/ssl_common.h +++ b/src/openvpn/ssl_common.h @@ -333,6 +333,9 @@ interval_t packet_timeout; int64_t renegotiate_bytes; int64_t renegotiate_packets; + /** This limit for AEAD cipher, this is the sum of packets + blocks + * that are allowed to be used */ + int64_t aead_usage_limit; interval_t renegotiate_seconds; /* cert verification parms */ diff --git a/tests/unit_tests/openvpn/test_crypto.c b/tests/unit_tests/openvpn/test_crypto.c index fdc8fbd..135cd15 100644 --- a/tests/unit_tests/openvpn/test_crypto.c +++ b/tests/unit_tests/openvpn/test_crypto.c @@ -448,6 +448,27 @@ gc_free(&gc); } +void +crypto_test_aead_limits(void **state) +{ + /* if ChaCha20-Poly1305 is not supported by the crypto library or in the + * current mode (FIPS), this will still return -1 */ + assert_int_equal(cipher_get_aead_limits("CHACHA20-POLY1305"), 0); + + int64_t aeslimit = cipher_get_aead_limits("AES-128-GCM"); + + assert_int_equal(aeslimit, (1ull << 36) - 1); + + /* Check if this matches our exception for 1600 size packets */ + int64_t L = 101; + /* 2 ^ 29.34, using the result here to avoid linking to libm */ + assert_int_equal(aeslimit / L, 680390858); + + /* and for 9000, 2^26.86 */ + L = 563; + assert_int_equal(aeslimit / L, 122059461); +} + int main(void) { @@ -458,8 +479,9 @@ cmocka_unit_test(crypto_test_tls_prf), cmocka_unit_test(crypto_test_hmac), cmocka_unit_test(test_occ_mtu_calculation), - cmocka_unit_test(test_mssfix_mtu_calculation) - }; + cmocka_unit_test(test_mssfix_mtu_calculation), + cmocka_unit_test(crypto_test_aead_limits) + }; #if defined(ENABLE_CRYPTO_OPENSSL) OpenSSL_add_all_algorithms();