From patchwork Mon Dec 9 21:09:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 3981 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:1d8b:b0:5dc:2311:f747 with SMTP id hp11csp2897185mab; Mon, 9 Dec 2024 13:10:20 -0800 (PST) X-Forwarded-Encrypted: i=2; AJvYcCXa9+922TnbtKeDYEyqxRTCMPJgEhHZA0xewqV4ZmHDVDio8eSd9KmDSaQVRU7DG1LCgJNfVB6u8Xw=@openvpn.net X-Google-Smtp-Source: AGHT+IGduWaSVRIoi79wAc2iwzvdLhxa5Xb5sQcsNsfGIsvYIvT6LkuXW/u2McmXTVaAJb8Wzids X-Received: by 2002:a05:6602:6418:b0:843:ea96:f707 with SMTP id ca18e2360f4ac-844b51bdcadmr218295939f.8.1733778620414; Mon, 09 Dec 2024 13:10:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1733778620; cv=none; d=google.com; s=arc-20240605; b=dd8TKE4mfmtIi3zvd6UknaXhwRJHxqyTWjO0YIzTqYR+kWFrX0zTvIYSvgNsvJDTI5 39Zz41Ukj4OYTs7g4QefDyJUy/+Anl61n/y0Kq7FHFJ1PIPDdpOzq74KN+l9r5n9oKdu pUkiknWAB8NuBIcxiP1Yp8CaWHFE+UON1w9vtC9EzbaUdnMJmo3F0TYfi9X+oX69sGGq FxHrQus7SR9LKxfy459fvGC238tMr0Njzl2rQZ6sqvPlHeACT4L+gOG9LDR8WlHNrZcY 4b8M4P5uATtxgpmvDxt+5rM76vtHtkiaGf5Mfy7N7N4bK3JlK0+IvJBxkBkDnkk16zFF i5+g== 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=QEC9bfymkkvj4ImpM91nyqylBQDV8cJZk08xIKT0vLE=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=hi2bxXemPRtmfDbp0YnNLJXCh37Vv+Uvisn0LAHb7mf8Dan2y15D+7krZP1DNlj+Qp rVJ0k6q9QZMaFJn/ZvVtJFCwD8oGvZX5XCovEtvpMO4IiLj/KsxdycMCb8AmdMxiQz5z YaYvFhvAhFsBxZkY+XdOuuuR3jDwuLtA58d6+ZlcWkfmg9Jq7j7ntw1JcR5Fhd9IziYu GaoMkqTk5dE1j2IWopRyQBfL7y0d4CJEsfYkq5DoHxZEmEUHDdtYT0IvzgFW60pp1+Bh wf5lZq1QxgDoDamTRVv7nmk/zhwWlYiXYozsa9k1YTLcMLTpNQIMxGvsW6HCoOrXdk5Y eSCA==; 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=lfNdedEO; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=ArpoZZwq; 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 ca18e2360f4ac-84473a8487bsi336902539f.117.2024.12.09.13.10.20 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 09 Dec 2024 13:10:20 -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=lfNdedEO; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=ArpoZZwq; 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-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1tKl1A-0001yD-9l; Mon, 09 Dec 2024 21:10:13 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1tKl18-0001y7-Gx for openvpn-devel@lists.sourceforge.net; Mon, 09 Dec 2024 21:10:11 +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=aGcUt+be/tn5yrMi7GoVdiFDHuTl6ZxyY7peVRa8pC8=; b=lfNdedEOpoln5Hb4N83276kq1l JydWOfKX6pcxaqDXHfwUwBSVprEGZ4IA0OxWA3ty1L33E8Eg2u4GOIs8yZ7+T/DTFM1z76C96ia8y 23ATpVLVSlRmgnS+REHmgH1uFxfT85SxpTRZaBrRXhwpsNkgbBdVZv+IWT9e/Cql16i4=; 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=aGcUt+be/tn5yrMi7GoVdiFDHuTl6ZxyY7peVRa8pC8=; b=ArpoZZwqGB+u1oP1Tmc8pcGtng 3srwBvXD6zsWmXqM1jdwoQG/Uzg/v6klUr+T9erJOV+by20H67QCxDlnt1Ld0J8KN9AVgVYOypHsW HbBpWV/Y8ozaLH/ZzdCYM4MnnYVgx+zhGPL1O9ODNe8YhgOEaPTursnMKTcvaC46GtSc=; 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 1tKl17-00051L-6I for openvpn-devel@lists.sourceforge.net; Mon, 09 Dec 2024 21:10:11 +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 4B9L9vt8013580 for ; Mon, 9 Dec 2024 22:09:57 +0100 Received: (from gert@localhost) by blue.greenie.muc.de (8.17.1.9/8.17.1.9/Submit) id 4B9L9vMF013545 for openvpn-devel@lists.sourceforge.net; Mon, 9 Dec 2024 22:09:57 +0100 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Mon, 9 Dec 2024 22:09:56 +0100 Message-ID: <20241209210956.13536-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-trusted.bondedsender.org] 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: 1tKl17-00051L-6I Subject: [Openvpn-devel] [PATCH v8] 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?1817998650369908943?= 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 --- 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 8 of this Change. Acked-by according to Gerrit (reflected above): MaxF diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c index 67c5b04..d6cd256 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 7d32353..531664d 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 2acf985..05079cc 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -1562,8 +1562,9 @@ 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 <= 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; } }