From patchwork Thu Feb 8 08:57:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 3606 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:e8a8:b0:554:adf7:68e6 with SMTP id oz40csp96954mab; Thu, 8 Feb 2024 00:58:39 -0800 (PST) X-Forwarded-Encrypted: i=2; AJvYcCU2EducG9WUZ/cM4tz/U46zKBel8do6I/RE40/qCnJObRIOezm7aUbsRFRlW49dDt18tt4BHW4lnUPGd8NwMpj4+u5PqZQ= X-Google-Smtp-Source: AGHT+IFr6GPXkswPzr6/TMOE3YpJBLgG7AmK7s6gBxn7zU5dEepoREGyc4n7H4MPrPJe+ULOkfTN X-Received: by 2002:a05:6358:8a1:b0:178:f482:6e59 with SMTP id m33-20020a05635808a100b00178f4826e59mr10649005rwj.3.1707382719583; Thu, 08 Feb 2024 00:58:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1707382719; cv=none; d=google.com; s=arc-20160816; b=wjiq4E9x1ULzN6836DgxuyyTXC7lew7e1nBxr85yiCpIT7S8fb3guRg9BA4uwFlyjC c6fJlKfaHtrgvzM2cZLci2y6bVCYIwpsaJ7+r7+GSwfp2L6IY0qH5JfGvxiF0Wa+mgx9 HNPCCqiKzthb9nqkKB4jKIARy1+fLRfmYRex9LUbPk/rNvpo874yQlAo70KC2NmA++ph TKUR0O0kyuRxulyXUQIjHYscqxh7TKspjtfmCeTSUtQCRReZNkeCaems1EhityHzvtBn EUmGM6htir4EDOcYnEOxymNRVzQquuA3MQGn25sqK7LOX9SxKDXqrcLI/iDWTuHiPKVx Ve9g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; 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=YLeRPRzHX/YP7qYHCmJUNWrQSAkT3jm2m5RiVvakev4=; fh=XUlaB/rSFNDV4iyiz0IiRhpcI3+NTuEZrBZFfJuGUJ8=; b=AZ/IyHg3zqnIM/hIRH0v2i5rO1XSgOcWcFpFUhs0lxYuRX9WfnadcrG3LwsulipZ+0 yLc0eZWOIX2JFFiFqWcHIiDjSowk48ZsNMv6QD+GCKlOQBolSyMkFS7HJY2YrFe+QSuy n0Y8/AifIJlNGFxdW4crkNXng4sNdYqjUW8o8S8sMoXtZml68xgu4+52aPzB8hZFBj5F GQ3+gQFxknlVQXSvpPcmA24B4ab5Yp1Z+CZxOpUdVxddTxD8jt0lKAXzI4oN3usXPg8j 63FDMNKulB9kKbLy1SqipTvbBQXgsY9rwC//3MIT92e7ZUBLZZtyKTqMJN9FYQJhpnae MOcA==; darn=openvpn.net ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=iAvynpCX; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=kjgdvZCA; 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 X-Forwarded-Encrypted: i=1; AJvYcCUmDmKN+lH8PIWK7x+43VcX3GlqoN7Wwes81E77NJIDjtiboXFC8BFJ2ePED8fZqARPw2TZ2m7Q/hwjdbHzGhV/QiDzvlnXvxRUOC0h32x7vLfXZZZmOeDk6vK33EJzGRY3aeGzcN3i7xxUdhMOaF9W9tAcwgI= Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id k29-20020a63ba1d000000b005d61412ca90si3237860pgf.453.2024.02.08.00.58.39 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Feb 2024 00:58:39 -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=iAvynpCX; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=kjgdvZCA; 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-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1rY0EQ-0006Py-Vh; Thu, 08 Feb 2024 08:58:06 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1rY0EO-0006Ps-Uw for openvpn-devel@lists.sourceforge.net; Thu, 08 Feb 2024 08:58:05 +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=rfuoFfT3AYTSIHb7xdwIkfxAinqonIrT2cnwgw5xJps=; b=iAvynpCXqb3AgU8Du6lKGzi9pj FFMj4X+reNRUQA78AIVyrYliuFr03KQS5h6o2wYoWzRoPlg98Q3zoemwqZ2sQuLIqULsxJLTEglW4 P4rMbarbhWIC1SkQmt2qOV/+aUvohjEgoxcb8Qfe/1M85mpIPpnD5o2gRu7ijLJwTWUg=; 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=rfuoFfT3AYTSIHb7xdwIkfxAinqonIrT2cnwgw5xJps=; b=kjgdvZCAX++NIKIjHEAN/ifQSt V4y0b6afOBtFzm96Cf5RqHwDdMiQXSOyKoPEiUVjfmMo3HUHbr1FvB6KVetjweCux+NIOLdAPUsoD yIxLxdLfObTRhxOh4k1B+kwSRhU0+ZxIL8OC13Sf4a+SR3B/oZIX6svqxvOfftSBf34A=; 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 1rY0EL-0000UT-Pa for openvpn-devel@lists.sourceforge.net; Thu, 08 Feb 2024 08:58:04 +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 4188voBq000879 for ; Thu, 8 Feb 2024 09:57:50 +0100 Received: (from gert@localhost) by blue.greenie.muc.de (8.17.1.9/8.17.1.9/Submit) id 4188vo7J000878 for openvpn-devel@lists.sourceforge.net; Thu, 8 Feb 2024 09:57:50 +0100 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Thu, 8 Feb 2024 09:57:49 +0100 Message-ID: <20240208085749.869-1-gert@greenie.muc.de> X-Mailer: git-send-email 2.43.0 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 test is reusing code from --test-crypto but is modified to not rely on the static key functionality and also only tests the most common algorithm. So it does not yet completely replace --test-cry [...] Content analysis details: (-0.0 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record -0.0 T_SCC_BODY_TEXT_LINE No description available. X-Headers-End: 1rY0EL-0000UT-Pa Subject: [Openvpn-devel] [PATCH v3] Add unit test for encrypting/decrypting data channel 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?1790320542992584778?= X-GMAIL-MSGID: =?utf-8?q?1790320542992584778?= From: Arne Schwabe This test is reusing code from --test-crypto but is modified to not rely on the static key functionality and also only tests the most common algorithm. So it does not yet completely replace --test-crypto Change-Id: Ifa5ae96165d17b3cae4afc53e844bb34d1610e58 Acked-by: Frank Lichtenheld --- 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/+/505 This mail reflects revision 3 of this Change. Acked-by according to Gerrit (reflected above): Frank Lichtenheld diff --git a/tests/unit_tests/openvpn/test_ssl.c b/tests/unit_tests/openvpn/test_ssl.c index 18b9ec8..8c1fb5b 100644 --- a/tests/unit_tests/openvpn/test_ssl.c +++ b/tests/unit_tests/openvpn/test_ssl.c @@ -44,6 +44,9 @@ #include "ssl_verify_backend.h" #include "win32.h" #include "test_common.h" +#include "ssl.h" +#include "buffer.h" +#include "packet_id.h" /* Mock function to be allowed to include win32.c which is required for * getting the temp directory */ @@ -120,20 +123,238 @@ gc_free(&gc); } +static void +init_implicit_iv(struct crypto_options *co) +{ + 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; + } +} + +static void +init_frame_parameters(struct frame *frame) +{ + int overhead = 0; + + /* tls-auth and tls-crypt */ + overhead += 128; + + /* TCP length field and opcode */ + overhead += 3; + + /* ACK array and remote SESSION ID (part of the ACK array) */ + overhead += ACK_SIZE(RELIABLE_ACK_SIZE); + + /* Previous OpenVPN version calculated the maximum size and buffer of a + * control frame depending on the overhead of the data channel frame + * overhead and limited its maximum size to 1250. Since control frames + * also need to fit into data channel buffer we have the same + * default of 1500 + 100 as data channel buffers have. Increasing + * control channel mtu beyond this limit also increases the data channel + * buffers */ + int tls_mtu = 1500; + frame->buf.payload_size = tls_mtu + 100; + + frame->buf.headroom = overhead; + frame->buf.tailroom = overhead; + + frame->tun_mtu = tls_mtu; + +} + +static void +do_data_channel_round_trip(struct crypto_options *co) +{ + struct gc_arena gc = gc_new(); + + /* initialise frame for the test */ + struct frame frame; + init_frame_parameters(&frame); + + struct buffer src = alloc_buf_gc(frame.buf.payload_size, &gc); + struct buffer work = alloc_buf_gc(BUF_SIZE(&frame), &gc); + struct buffer encrypt_workspace = alloc_buf_gc(BUF_SIZE(&frame), &gc); + struct buffer decrypt_workspace = alloc_buf_gc(BUF_SIZE(&frame), &gc); + struct buffer buf = clear_buf(); + void *buf_p; + + /* init work */ + ASSERT(buf_init(&work, frame.buf.headroom)); + + init_implicit_iv(co); + update_time(); + + /* Test encryption, decryption for all packet sizes */ + for (int i = 1; i <= frame.buf.payload_size; ++i) + { + + /* msg(M_INFO, "TESTING ENCRYPT/DECRYPT of packet length=%d", i); */ + + /* + * Load src with random data. + */ + ASSERT(buf_init(&src, 0)); + ASSERT(i <= src.capacity); + src.len = i; + ASSERT(rand_bytes(BPTR(&src), BLEN(&src))); + + /* copy source to input buf */ + buf = work; + buf_p = buf_write_alloc(&buf, BLEN(&src)); + ASSERT(buf_p); + memcpy(buf_p, BPTR(&src), BLEN(&src)); + + /* initialize work buffer with buf.headroom bytes of prepend capacity */ + ASSERT(buf_init(&encrypt_workspace, frame.buf.headroom)); + + /* encrypt */ + openvpn_encrypt(&buf, encrypt_workspace, co); + + /* decrypt */ + openvpn_decrypt(&buf, decrypt_workspace, co, &frame, BPTR(&buf)); + + /* compare */ + assert_int_equal(buf.len, src.len); + assert_memory_equal(BPTR(&src), BPTR(&buf), i); + + } + gc_free(&gc); +} + + + +struct crypto_options +init_crypto_options(const char *cipher, const char *auth) +{ + struct key2 key2 = { .n = 2}; + + ASSERT(rand_bytes(key2.keys[0].cipher, sizeof(key2.keys[0].cipher))); + ASSERT(rand_bytes(key2.keys[0].hmac, sizeof(key2.keys[0].hmac))); + ASSERT(rand_bytes(key2.keys[1].cipher, sizeof(key2.keys[1].cipher))); + ASSERT(rand_bytes(key2.keys[1].hmac, sizeof(key2.keys)[1].hmac)); + + struct crypto_options co = { 0 }; + + struct key_type kt = create_kt(cipher, auth, "ssl-test"); + + init_key_ctx_bi(&co.key_ctx_bi, &key2, 0, &kt, "unit-test-ssl"); + packet_id_init(&co.packet_id, 5, 5, "UNITTEST", 0); + + return co; +} + +static void +uninit_crypto_options(struct crypto_options *co) +{ + packet_id_free(&co->packet_id); + free_key_ctx_bi(&co->key_ctx_bi); + +} + + +static void +run_data_channel_with_cipher(const char *cipher, const char *auth) +{ + struct crypto_options co = init_crypto_options(cipher, auth); + do_data_channel_round_trip(&co); + uninit_crypto_options(&co); +} + +static void +test_data_channel_roundtrip_aes_128_gcm(void **state) +{ + run_data_channel_with_cipher("AES-128-GCM", "none"); +} + +static void +test_data_channel_roundtrip_aes_192_gcm(void **state) +{ + run_data_channel_with_cipher("AES-192-GCM", "none"); +} + +static void +test_data_channel_roundtrip_aes_256_gcm(void **state) +{ + run_data_channel_with_cipher("AES-256-GCM", "none"); +} + +static void +test_data_channel_roundtrip_aes_128_cbc(void **state) +{ + run_data_channel_with_cipher("AES-128-CBC", "SHA256"); +} + +static void +test_data_channel_roundtrip_aes_192_cbc(void **state) +{ + run_data_channel_with_cipher("AES-192-CBC", "SHA256"); +} + +static void +test_data_channel_roundtrip_aes_256_cbc(void **state) +{ + run_data_channel_with_cipher("AES-256-CBC", "SHA256"); +} + +static void +test_data_channel_roundtrip_chacha20_poly1305(void **state) +{ + if (!cipher_valid("ChaCha20-Poly1305")) + { + skip(); + return; + } + run_data_channel_with_cipher("ChaCha20-Poly1305", "none"); +} + +static void +test_data_channel_roundtrip_bf_cbc(void **state) +{ + if (!cipher_valid("BF-CBC")) + { + skip(); + return; + } + run_data_channel_with_cipher("BF-CBC", "SHA1"); +} + + int main(void) { openvpn_unit_test_setup(); const struct CMUnitTest tests[] = { - cmocka_unit_test(crypto_pem_encode_certificate) + cmocka_unit_test(crypto_pem_encode_certificate), + cmocka_unit_test(test_data_channel_roundtrip_aes_128_gcm), + cmocka_unit_test(test_data_channel_roundtrip_aes_192_gcm), + cmocka_unit_test(test_data_channel_roundtrip_aes_256_gcm), + cmocka_unit_test(test_data_channel_roundtrip_chacha20_poly1305), + cmocka_unit_test(test_data_channel_roundtrip_aes_128_cbc), + cmocka_unit_test(test_data_channel_roundtrip_aes_192_cbc), + cmocka_unit_test(test_data_channel_roundtrip_aes_256_cbc), + cmocka_unit_test(test_data_channel_roundtrip_bf_cbc), }; #if defined(ENABLE_CRYPTO_OPENSSL) tls_init_lib(); #endif - int ret = cmocka_run_group_tests_name("crypto tests", tests, NULL, NULL); + int ret = cmocka_run_group_tests_name("ssl tests", tests, NULL, NULL); #if defined(ENABLE_CRYPTO_OPENSSL) tls_free_lib();