From patchwork Thu Dec 12 14:38:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 3994 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:750c:b0:5e7:b9eb:58e8 with SMTP id r12csp1617088mai; Thu, 12 Dec 2024 06:39:21 -0800 (PST) X-Forwarded-Encrypted: i=2; AJvYcCXcEeJBy+gHT2RI/INfREGHd2qHCNtktWObJe8OcnT6S6ny2Rn3iart5WlWkqOCLGYY8GGMfHNJg2U=@openvpn.net X-Google-Smtp-Source: AGHT+IEq6JiuUCQl9p8Z7LGf5gBXsJ42UcPtsS/TaerV3JnIGUVBMzn2HbnqHrKUBZjOnNIphcPA X-Received: by 2002:a05:6808:384c:b0:3eb:53f2:17d8 with SMTP id 5614622812f47-3eb94ed4604mr2215016b6e.9.1734014361457; Thu, 12 Dec 2024 06:39:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1734014361; cv=none; d=google.com; s=arc-20240605; b=M/VBtZaF79HuzKFn0x5n6tfjUvr3/4lJdx1AQ1xmR3OUFKfIYRlSCuiNULm9uldhhQ Kg3X7K5PP3D+7kMRC50xdI/xhyc7pT5zWlF+dFHwzDQsZyFW2+pmSuMW9i09wlpRtR9b sQJJWGnbRbatar7edb3HMuKW2nBqnitysGv5xw3QF8uUidzQ0ZVBBkBu/4MtCMa1A/W4 BtOIMmW7GyQL+JeqzumBmjcJH1PJW6QihDbjAyW7Lr6ZLNtV9fKyPOggkXP+L2WXsjzI 6UJBjkk+tfoMriFPtPRC1a5d+/rKeZWo9WHk+JItkm0WTQxii7pbIVnuyB8zDcF9G69d W8xw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature; bh=9bl3MG1KO2D890LRyeM6tkl/eo0/ZoQpq+KEib2GQ58=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=Lx3wMcwnZorZ8Wx8zkpsAWvvRDTVBT0v5Y7T/QYDYFSKXndNZ9KZM/Xp2zMOUM2hvW cGO2OoNSJv/xqb5nfi6ZnUaxQSlsUHhni27oQetc/LUc9vRAa1DRZzR9y/zsWa5xbNDC jqWroIOP8iRM+6zuyclYqO2NN8rdNoA/UGgLtEL36u0O3VQYvVLpx0ehpKVMBoZk/Zor 2k2ufQEdmt6/2Qy0K1BJaJAtuyQ2iB4fHEYJe7LBWqGEt/NtyrGEOmgIR+FXiKCCZLkQ 7Shbai7YN2r0nCab2GkpIUGXza52YHLN6B2auxEWWPQI8hphf4dmXglrvhMf3V3wFeJI /Zmg==; 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=DEqacm2w; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=lP2m55ex; 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=muc.de Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 5614622812f47-3eb9a63d4c0si791420b6e.245.2024.12.12.06.39.21 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 12 Dec 2024 06:39:21 -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=DEqacm2w; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=lP2m55ex; 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=muc.de Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1tLkLB-0001U2-73; Thu, 12 Dec 2024 14:38:57 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1tLkL9-0001Tl-FT for openvpn-devel@lists.sourceforge.net; Thu, 12 Dec 2024 14:38:55 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=np09KsfOp5VHdtjT3vwkV1C9Uy94R7YDBDENGkc7ats=; b=DEqacm2wgPRA3U98T8ybhGsp6n jAcS2KMkFQenyZ1BhwIlpLhFNkWuRIurbOc6Ws5hkCGSrEgOT/EjEAD5X/Q8wQ3UUW5HzIBcyidYA E0rY4qVggt22EvhavtOHfLUziO25FeSQL3rsISGhgGoe2ZID0s79g/L8pQyqTycAPE8Y=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=np09KsfOp5VHdtjT3vwkV1C9Uy94R7YDBDENGkc7ats=; b=lP2m55exsu5bttUIsbFbBdVs2k g/doi3+Art0HyTFbMFpbkjqeqB17e3kVYc603XiilpoJJkX2noLT86f4UKkG9IrhjH3T4vTscr9rK oVYQfJcAKam2XiPw8rPOKetiHE79YIs4PwoJbdBXgdvIQvH3db5t5uyet/M22nR8+ShQ=; Received: from dhcp-174.greenie.muc.de ([193.149.48.174] helo=blue.greenie.muc.de) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1tLkL7-00070n-Uz for openvpn-devel@lists.sourceforge.net; Thu, 12 Dec 2024 14:38:55 +0000 Received: from blue.greenie.muc.de (localhost [127.0.0.1]) by blue.greenie.muc.de (8.17.1.9/8.17.1.9) with ESMTP id 4BCEclbQ004100 for ; Thu, 12 Dec 2024 15:38:47 +0100 Received: (from gert@localhost) by blue.greenie.muc.de (8.17.1.9/8.17.1.9/Submit) id 4BCEclwa004099 for openvpn-devel@lists.sourceforge.net; Thu, 12 Dec 2024 15:38:47 +0100 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Thu, 12 Dec 2024 15:38:45 +0100 Message-ID: <20241212143845.4090-1-gert@greenie.muc.de> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Score: 0.0 (/) X-Spam-Report: Spam detection software, running on the system "util-spamd-1.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: From: Arne Schwabe This change prepares the extended packet id data where also the packet id part of the IV will be derived using xor. Using xor also in the AEAD case where this degenerates to a concatenation allows usi [...] Content analysis details: (0.0 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 RCVD_IN_VALIDITY_CERTIFIED_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. [193.149.48.174 listed in sa-accredit.habeas.com] 0.0 RCVD_IN_VALIDITY_RPBL_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. [193.149.48.174 listed in bl.score.senderscore.com] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record X-Headers-End: 1tLkL7-00070n-Uz Subject: [Openvpn-devel] [PATCH v10] Use XOR instead of concatenation for calculation of IV from implicit IV 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1817998650369908943?= X-GMAIL-MSGID: =?utf-8?q?1818245842977609283?= From: Arne Schwabe This change prepares the extended packet id data where also the packet id part of the IV will be derived using xor. Using xor also in the AEAD case where this degenerates to a concatenation allows using the same IV generation code later. Change-Id: I74216d776d3e0a8dc987ec7b1671c8e8dcccdbd6 Signed-off-by: Arne Schwabe Acked-by: MaxF Acked-by: Antonio Quartulli Acked-by: Steffan Karger Acked-by: Gert Doering --- This change was reviewed on Gerrit and approved by at least one developer. I request to merge it to master. Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/797 This mail reflects revision 10 of this Change. Acked-by according to Gerrit (reflected above): Gert Doering diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c index 89949d0..faf69fc 100644 --- a/src/openvpn/crypto.c +++ b/src/openvpn/crypto.c @@ -94,12 +94,16 @@ goto err; } - /* Remainder of IV consists of implicit part (unique per session) */ - ASSERT(buf_write(&iv_buffer, ctx->implicit_iv, ctx->implicit_iv_len)); - ASSERT(iv_buffer.len == iv_len); + /* Write packet id part of IV to work buffer */ + ASSERT(buf_write(&work, iv, packet_id_size(false))); - /* Write explicit part of IV to work buffer */ - ASSERT(buf_write(&work, iv, iv_len - ctx->implicit_iv_len)); + /* This generates the IV by XORing the implicit part of the IV + * with the packet id already written to the iv buffer */ + for (int i = 0; i < iv_len; i++) + { + iv[i] = iv[i] ^ ctx->implicit_iv[i]; + } + dmsg(D_PACKET_CONTENT, "ENCRYPT IV: %s", format_hex(iv, iv_len, 0, &gc)); /* Init cipher_ctx with IV. key & keylen are already initialized */ @@ -426,16 +430,21 @@ { uint8_t iv[OPENVPN_MAX_IV_LENGTH] = { 0 }; const int iv_len = cipher_ctx_iv_length(ctx->cipher); - const size_t packet_iv_len = iv_len - ctx->implicit_iv_len; + const size_t packet_iv_len = packet_id_size(false); - ASSERT(ctx->implicit_iv_len <= iv_len); - if (buf->len + ctx->implicit_iv_len < iv_len) + if (buf->len < packet_iv_len) { CRYPT_ERROR("missing IV info"); } memcpy(iv, BPTR(buf), packet_iv_len); - memcpy(iv + packet_iv_len, ctx->implicit_iv, ctx->implicit_iv_len); + + /* This generates the IV by XORing the implicit part of the IV + * with the packet id already written to the iv buffer */ + for (int i = 0; i < iv_len; i++) + { + iv[i] = iv[i] ^ ctx->implicit_iv[i]; + } dmsg(D_PACKET_CONTENT, "DECRYPT IV: %s", format_hex(iv, iv_len, 0, &gc)); @@ -962,7 +971,6 @@ hmac_ctx_free(ctx->hmac); ctx->hmac = NULL; } - ctx->implicit_iv_len = 0; } void @@ -1078,18 +1086,15 @@ cipher_ctx_t *cipher = co->key_ctx_bi.encrypt.cipher; if (cipher_ctx_mode_aead(cipher)) { - size_t impl_iv_len = cipher_ctx_iv_length(cipher) - sizeof(packet_id_type); ASSERT(cipher_ctx_iv_length(cipher) <= OPENVPN_MAX_IV_LENGTH); ASSERT(cipher_ctx_iv_length(cipher) >= OPENVPN_AEAD_MIN_IV_LEN); /* Generate dummy implicit IV */ ASSERT(rand_bytes(co->key_ctx_bi.encrypt.implicit_iv, OPENVPN_MAX_IV_LENGTH)); - co->key_ctx_bi.encrypt.implicit_iv_len = impl_iv_len; memcpy(co->key_ctx_bi.decrypt.implicit_iv, co->key_ctx_bi.encrypt.implicit_iv, OPENVPN_MAX_IV_LENGTH); - co->key_ctx_bi.decrypt.implicit_iv_len = impl_iv_len; } } diff --git a/src/openvpn/crypto.h b/src/openvpn/crypto.h index 439d003..4579b65 100644 --- a/src/openvpn/crypto.h +++ b/src/openvpn/crypto.h @@ -163,6 +163,17 @@ { cipher_ctx_t *cipher; /**< Generic cipher %context. */ hmac_ctx_t *hmac; /**< Generic HMAC %context. */ + /** + * This implicit IV will be always XORed with the packet id that is sent on + * the wire to get the IV. For the common AEAD ciphers of AES-GCM and + * Chacha20-Poly1305, the length of the IV is 12 bytes (96 bits). + * + * For non-epoch 32bit packet id AEAD format we set the first 32 + * bits of implicit_iv to 0. + * Xor with the packet id in this case works as concatenation: + * after xor the lower 32 bit of the IV are the packet id and + * the rest of the IV is from the implicit IV. + */ uint8_t implicit_iv[OPENVPN_MAX_IV_LENGTH]; /**< The implicit part of the IV */ size_t implicit_iv_len; /**< The length of implicit_iv */ diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index ef09e20..c77c4ed 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -1562,10 +1562,11 @@ size_t impl_iv_len = 0; ASSERT(cipher_ctx_iv_length(ctx->cipher) >= OPENVPN_AEAD_MIN_IV_LEN); impl_iv_len = cipher_ctx_iv_length(ctx->cipher) - sizeof(packet_id_type); - ASSERT(impl_iv_len <= OPENVPN_MAX_IV_LENGTH); + ASSERT(impl_iv_len + sizeof(packet_id_type) <= OPENVPN_MAX_IV_LENGTH); ASSERT(impl_iv_len <= key_len); - memcpy(ctx->implicit_iv, key, impl_iv_len); - ctx->implicit_iv_len = impl_iv_len; + CLEAR(ctx->implicit_iv); + /* The first bytes of the IV are filled with the packet id */ + memcpy(ctx->implicit_iv + sizeof(packet_id_type), key, impl_iv_len); } } diff --git a/tests/unit_tests/openvpn/test_ssl.c b/tests/unit_tests/openvpn/test_ssl.c index a1ca344..ae33cc6 100644 --- a/tests/unit_tests/openvpn/test_ssl.c +++ b/tests/unit_tests/openvpn/test_ssl.c @@ -284,18 +284,15 @@ if (cipher_ctx_mode_aead(cipher)) { - size_t impl_iv_len = cipher_ctx_iv_length(cipher) - sizeof(packet_id_type); ASSERT(cipher_ctx_iv_length(cipher) <= OPENVPN_MAX_IV_LENGTH); ASSERT(cipher_ctx_iv_length(cipher) >= OPENVPN_AEAD_MIN_IV_LEN); /* Generate dummy implicit IV */ ASSERT(rand_bytes(co->key_ctx_bi.encrypt.implicit_iv, OPENVPN_MAX_IV_LENGTH)); - co->key_ctx_bi.encrypt.implicit_iv_len = impl_iv_len; memcpy(co->key_ctx_bi.decrypt.implicit_iv, co->key_ctx_bi.encrypt.implicit_iv, OPENVPN_MAX_IV_LENGTH); - co->key_ctx_bi.decrypt.implicit_iv_len = impl_iv_len; } }