From patchwork Thu Jan 9 17:55:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 4043 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:1539:b0:5e7:b9eb:58e8 with SMTP id a25csp1497185mar; Thu, 9 Jan 2025 09:55:52 -0800 (PST) X-Forwarded-Encrypted: i=2; AJvYcCV4lv1jXQx+4xiHrwtluDoUa2Vyuc0c/unSJaMm0RZzQaxtIWFmN99/iJ2tMJZflGdCWNwomfXGmWU=@openvpn.net X-Google-Smtp-Source: AGHT+IH4BZ5SyRBhOc6t2jBTLRVXMBZlmBnmU4n2tMYqGAge5x4B7lxO+EseKPYnXlYyn0FnBL18 X-Received: by 2002:a05:6808:1a17:b0:3eb:7675:3495 with SMTP id 5614622812f47-3ef2ebcb1demr4195293b6e.1.1736445352256; Thu, 09 Jan 2025 09:55:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1736445352; cv=none; d=google.com; s=arc-20240605; b=SzLX45s+6bviDTKOV7LTcgawIXPMfK6LtqociO5q3kkt7VwK9hTv6Dfz1ln+w7FMzo E5p9mOxKG6sWyYD5GSzOz6xKeurCajaoDWaY2hWXxnopO8UBcfz6U1lYSvrhpaz30W9k ec28hjALgwlr6Y1GgR9ksa3nDxhss0P8gajTz3iVi4FnjpPsEYdljlBWcKxB3NurNbhO f7jy80zNzK4Jk0MIuVDHYxbHu4Ka8F8kd7Gao2Wp9RCIKRnva30VT8jDXVXIEBRt45n7 gay0M3NiiJJQcN/D/uW5iOccVPqieERaL4n66Zo0YX7ukiyRtpgjoC7EuvQqaqemFtI3 c0gg== 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=mVQsY9Bl6rTVAKej0uQ2A7k/nAHA7Gvik6MrN7IuqtM=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=KBSg16nZyMA6JH+h/EI82feSuhhHIkIc7U7GWR5iZQccNv7fY64C0SY55FkjpC0uMi EOe/4EKF17E6UuZOnGE5lmrx9DJnjk0A6WbdNva9nUwlMplznQj3vGi4ssMQ/IB/2iXP YiDTUnqEl0XoxOpE0MGw/fFOSlpUwNFdRndQnGVdlid7KoSer3fpwBiwnxnxzGy8nwYB RgOhFW2aKfPsI/ieItL123JrHSS70O0GRe6THhzBIvdclDjiyGly+3YLS7D0blO87Rje yjVuR8fhQzN6G5ULuRZxHINpynZWn1i5P6QZ9FGJWpK7nQX5J9T3F2XLN2mSWrVrLO78 evVw==; 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=H8gW2mto; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b="gI/zJOM3"; 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 006d021491bc7-5f88260a080si1232688eaf.26.2025.01.09.09.55.51 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Jan 2025 09:55:52 -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=H8gW2mto; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b="gI/zJOM3"; 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 1tVwl1-00044e-74; Thu, 09 Jan 2025 17:55:47 +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 1tVwkv-00044U-9s for openvpn-devel@lists.sourceforge.net; Thu, 09 Jan 2025 17:55:42 +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=ClK0GBQGYnY3wEsB7qOdqrho6dNrkMCTVBPXWKgiZsc=; b=H8gW2mtoe5I8ibmMnPYLVMuMGV 3qEpw3l+pQjUpFXQb2fdN9cGFWInFDymuOENDkw7kVxr1FTiHg1eXvZBpAaIjZO40IChJGcJZk5gu sv7oL8gmpyHasXPmkVx3oe1fukSYXCmNEBf4vYlkt2xKkEY1gzlIVyE54VMk59xQPKz8=; 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=ClK0GBQGYnY3wEsB7qOdqrho6dNrkMCTVBPXWKgiZsc=; b=gI/zJOM3x0zKBS6SGzbyr5SmS2 75T/yMhlqPPb06qErj/gUMDyk2mtANNSpTpnvZwkaHRs4xHPh2sNBNBvuXsWP/I5OGc2whSPDVDwh vhHFUrBAHGtirm5wdn0oqEt3fuUW8fOYyQkbdU4MD6hL1UQDBhFmfoyF4f43qWmMe3ug=; 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 1tVwku-0004Z2-S5 for openvpn-devel@lists.sourceforge.net; Thu, 09 Jan 2025 17:55:41 +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 509HtTiW022043 for ; Thu, 9 Jan 2025 18:55:29 +0100 Received: (from gert@localhost) by blue.greenie.muc.de (8.17.1.9/8.17.1.9/Submit) id 509HtTJw022042 for openvpn-devel@lists.sourceforge.net; Thu, 9 Jan 2025 18:55:29 +0100 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Thu, 9 Jan 2025 18:55:28 +0100 Message-ID: <20250109175528.22033-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 Change-Id: I2a104decdb1e77a460f7a6976bcd0560b67a07b5 Signed-off-by: Arne Schwabe Acked-by: MaxF --- This change was reviewed on Gerrit and approved by at least one developer. I request to merge it to master. Content analysis details: (0.0 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 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 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 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record X-Headers-End: 1tVwku-0004Z2-S5 Subject: [Openvpn-devel] [PATCH v12] Add methods to read/write packet ids for epoch data 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?1820794921843067073?= X-GMAIL-MSGID: =?utf-8?q?1820794921843067073?= From: Arne Schwabe Change-Id: I2a104decdb1e77a460f7a6976bcd0560b67a07b5 Signed-off-by: Arne Schwabe Acked-by: MaxF --- 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/+/803 This mail reflects revision 12 of this Change. Acked-by according to Gerrit (reflected above): MaxF diff --git a/src/openvpn/packet_id.c b/src/openvpn/packet_id.c index 117c95f..0806e99 100644 --- a/src/openvpn/packet_id.c +++ b/src/openvpn/packet_id.c @@ -120,7 +120,8 @@ int64_t diff; /* - * If time value increases, start a new sequence number sequence. + * If time value increases, start a new sequence list of number + * sequence for the new time point. */ if (!CIRC_LIST_SIZE(p->seq_list) || pin->time > p->time @@ -343,6 +344,21 @@ return true; } +static bool +packet_id_send_update_epoch(struct packet_id_send *p) +{ + if (!p->time) + { + p->time = now; + } + if (p->id == PACKET_ID_EPOCH_MAX) + { + return false; + } + p->id++; + return true; +} + bool packet_id_write(struct packet_id_send *p, struct buffer *buf, bool long_form, bool prepend) @@ -634,4 +650,44 @@ gc_free(&gc); } +uint16_t +packet_id_read_epoch(struct packet_id_net *pin, struct buffer *buf) +{ + uint64_t packet_id; + + + if (!buf_read(buf, &packet_id, sizeof(packet_id))) + { + return 0; + } + + uint64_t id = ntohll(packet_id); + /* top most 16 bits */ + uint16_t epoch = id >> 48; + + pin->id = id & PACKET_ID_MASK; + return epoch; +} + +bool +packet_id_write_epoch(struct packet_id_send *p, uint16_t epoch, struct buffer *buf) +{ + if (!packet_id_send_update_epoch(p)) + { + return false; + } + + /* Highest 16 bits of packet id is the epoch. + * + * The lower 48 bits are the per-epoch packet id counter. */ + uint64_t net_id = ((uint64_t) epoch) << 48 | p->id; + + /* convert to network order. This ensures that the highest bytes + * also become the first ones on the wire*/ + net_id = htonll(net_id); + + return buf_write(buf, &net_id, sizeof(net_id)); +} + + #endif /* ifdef ENABLE_DEBUG */ diff --git a/src/openvpn/packet_id.h b/src/openvpn/packet_id.h index d8a3e1a..c05ac9a 100644 --- a/src/openvpn/packet_id.h +++ b/src/openvpn/packet_id.h @@ -44,7 +44,11 @@ * These are ephemeral and are never saved to a file. */ typedef uint32_t packet_id_type; -#define PACKET_ID_MAX UINT32_MAX +#define PACKET_ID_MAX UINT32_MAX +#define PACKET_ID_EPOCH_MAX 0x0000ffffffffffffull +/** Mask of the bits that contain the 48-bit of the per-epoch packet + * counter in the packet id*/ +#define PACKET_ID_MASK 0x0000ffffffffffffull typedef uint32_t net_time_t; /* @@ -158,7 +162,8 @@ * includes a timestamp as well. * * An epoch packet-id is a 16 bit epoch - * counter plus a 48 per-epoch packet-id + * counter plus a 48 per-epoch packet-id. + * * * Long packet-ids are used as IVs for * CFB/OFB ciphers and for control channel @@ -321,4 +326,25 @@ } } +/** + * Writes the packet ID containing both the epoch and the packet id to the + * buffer specified by buf. + * @param p packet id send structure to use for the packet id + * @param epoch epoch to write to the packet + * @param buf buffer to write the packet id/epoch to + * @return false if the packet id space is exhausted and cannot be written + */ +bool +packet_id_write_epoch(struct packet_id_send *p, uint16_t epoch, struct buffer *buf); + +/** + * Reads the packet ID containing both the epoch and the per-epoch counter + * from the buf. Will return 0 as epoch id if there is any error. + * @param p packet_id struct to populate with the on-wire counter + * @param buf buffer to read the packet id from. + * @return 0 for an error/invalid id, epoch otherwise + */ +uint16_t +packet_id_read_epoch(struct packet_id_net *p, struct buffer *buf); + #endif /* PACKET_ID_H */ diff --git a/tests/unit_tests/openvpn/test_packet_id.c b/tests/unit_tests/openvpn/test_packet_id.c index d918985..312a6b3d 100644 --- a/tests/unit_tests/openvpn/test_packet_id.c +++ b/tests/unit_tests/openvpn/test_packet_id.c @@ -44,6 +44,7 @@ } test_buf_data; struct buffer test_buf; struct packet_id_send pis; + struct gc_arena gc; }; static int @@ -59,6 +60,7 @@ data->test_buf.data = (void *) &data->test_buf_data; data->test_buf.capacity = sizeof(data->test_buf_data); + data->gc = gc_new(); *state = data; return 0; @@ -67,6 +69,8 @@ static int test_packet_id_write_teardown(void **state) { + struct test_packet_id_write_data *data = *state; + gc_free(&data->gc); free(*state); return 0; } @@ -209,6 +213,54 @@ reliable_free(rel); } +static void +test_packet_id_write_epoch(void **state) +{ + struct test_packet_id_write_data *data = *state; + + struct buffer buf = alloc_buf_gc(128, &data->gc); + + /* test normal writing of packet id to the buffer */ + assert_true(packet_id_write_epoch(&data->pis, 0x23, &buf)); + + assert_int_equal(buf.len, 8); + uint8_t expected_header[8] = { 0x00, 0x23, 0, 0, 0, 0, 0, 1}; + assert_memory_equal(BPTR(&buf), expected_header, 8); + + /* too small buffer should error out */ + struct buffer buf_short = alloc_buf_gc(5, &data->gc); + assert_false(packet_id_write_epoch(&data->pis, 0xabde, &buf_short)); + + /* test a true 48 bit packet id */ + data->pis.id = 0xfa079ab9d2e8; + struct buffer buf_48 = alloc_buf_gc(128, &data->gc); + assert_true(packet_id_write_epoch(&data->pis, 0xfffe, &buf_48)); + uint8_t expected_header_48[8] = { 0xff, 0xfe, 0xfa, 0x07, 0x9a, 0xb9, 0xd2, 0xe9}; + assert_memory_equal(BPTR(&buf_48), expected_header_48, 8); + + /* test writing/checking the 48 bit per epoch packet counter + * overflow */ + data->pis.id = 0xfffffffffffe; + struct buffer buf_of = alloc_buf_gc(128, &data->gc); + assert_true(packet_id_write_epoch(&data->pis, 0xf00f, &buf_of)); + uint8_t expected_header_of[8] = { 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + assert_memory_equal(BPTR(&buf_of), expected_header_of, 8); + + /* This is go over 2^48 - 1 and should error out. */ + assert_false(packet_id_write_epoch(&data->pis, 0xf00f, &buf_of)); + + /* Now read back the packet ids and check if they are the same as what we + * have written */ + struct packet_id_net pin; + assert_int_equal(packet_id_read_epoch(&pin, &buf), 0x23); + assert_int_equal(pin.id, 1); + + assert_int_equal(packet_id_read_epoch(&pin, &buf_48), 0xfffe); + assert_int_equal(pin.id, 0xfa079ab9d2e9); + + assert_int_equal(packet_id_read_epoch(&pin, &buf_of), 0xf00f); + assert_int_equal(pin.id, 0xffffffffffff); +} static void test_copy_acks_to_lru(void **state) @@ -296,6 +348,10 @@ cmocka_unit_test_setup_teardown(test_packet_id_write_long_wrap, test_packet_id_write_setup, test_packet_id_write_teardown), + cmocka_unit_test_setup_teardown(test_packet_id_write_epoch, + test_packet_id_write_setup, + test_packet_id_write_teardown), + cmocka_unit_test(test_get_num_output_sequenced_available), cmocka_unit_test(test_copy_acks_to_lru)