From patchwork Wed Feb 15 18:33:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitry Safonov X-Patchwork-Id: 13142037 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F3A56C636CC for ; Wed, 15 Feb 2023 18:34:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230196AbjBOSd6 (ORCPT ); Wed, 15 Feb 2023 13:33:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49016 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229874AbjBOSdx (ORCPT ); Wed, 15 Feb 2023 13:33:53 -0500 Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 74E4F392AC for ; Wed, 15 Feb 2023 10:33:45 -0800 (PST) Received: by mail-wm1-x32a.google.com with SMTP id bg5-20020a05600c3c8500b003e00c739ce4so2233418wmb.5 for ; Wed, 15 Feb 2023 10:33:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arista.com; s=google; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=KjelLWogeq3R9dVSd0htPVkEnfrgdkd4Opja0LLqdX8=; b=cFq+7YiNWbg237pdXKYw5bWxfLhRh4COzq+IdYTyBIG/Cyum8PPrDV4z7Fyj/Qk6ze q29W24kBjqRoPZ3CXZ8hcMaarWNWD2fk3VJOwnacX+G/KHwNFM8h1/MJPz4plqDlHex4 in16RJkU84lToXFBGSIGBkEWQATEzPPPdhAKug3h35nHUU9TQQdbA4MzE+L/8Rurg9+R GjEemEJvr4T2I8HM97FiqcoeQtqGSXuSTEFy7FuYBzm1k3QUM35ag+/AC4P5xLKiGwJq 9uVqNal5iXMMNbcx+3oSlKeC5wlUWdySrK8PGomIN2BshWCR/xqjwNh51F/AiSxP14Tb lpMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=KjelLWogeq3R9dVSd0htPVkEnfrgdkd4Opja0LLqdX8=; b=ReFYoOjuLkfH6dfSMSRJ+WeD/txfYSAX3OKeVJ7kKJ5MJFL+n9l6rCZh1Q8WJ4ngtJ NhE16sOz69IzxUulhoQwWoXKh9+zGPOrVY4v4mHN6C4mZ/Dj9GMqapo1T3hh6Dv7zNgP ffjkuIg+RY82QlGhK0OIhYvr8+59XKbGNJ+UE7fv74ekmT3YBUZ7hoNOIhV20WxnbHJW d8GUJewva3T6Ot0RWk1TvgYA08kBNVq3/ZelbmydmGgLxqWqtqtQM/98bDOU9jj89wpI Efem6SPZkYvmWWtqygkqKa0AJYjnJLv2/5dpon7aUErhiUo4SIjEdzuaB2Z3uhZSpi5P oTVA== X-Gm-Message-State: AO0yUKW3Cici4pdw7/XMIr/l1DwCpYM1Uqt3S1rc7l1KXrYHOGtSmH6H f/3KbEmQ0grNtY7iXKVrtsfwIw== X-Google-Smtp-Source: AK7set+VB63XJCIb+2rscQbm7OLnp+HG1w/BETq+j6XDDl+7L9wTzHt1xd+avPfIka6ItAbJVOWjqw== X-Received: by 2002:a05:600c:1604:b0:3dd:af7a:53ed with SMTP id m4-20020a05600c160400b003ddaf7a53edmr2777217wmn.11.1676486023818; Wed, 15 Feb 2023 10:33:43 -0800 (PST) Received: from Mindolluin.ire.aristanetworks.com ([217.173.96.166]) by smtp.gmail.com with ESMTPSA id s9-20020a05600c45c900b003e00c9888besm3196306wmo.30.2023.02.15.10.33.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 15 Feb 2023 10:33:42 -0800 (PST) From: Dmitry Safonov To: linux-kernel@vger.kernel.org, David Ahern , Eric Dumazet , Paolo Abeni , Jakub Kicinski , "David S. Miller" Cc: Dmitry Safonov , Andy Lutomirski , Ard Biesheuvel , Bob Gilligan , Dan Carpenter , David Laight , Dmitry Safonov <0x7f454c46@gmail.com>, Eric Biggers , "Eric W. Biederman" , Francesco Ruggeri , Herbert Xu , Hideaki YOSHIFUJI , Ivan Delalande , Leonard Crestez , Salam Noureddine , netdev@vger.kernel.org Subject: [PATCH v4 00/21] net/tcp: Add TCP-AO support Date: Wed, 15 Feb 2023 18:33:14 +0000 Message-Id: <20230215183335.800122-1-dima@arista.com> X-Mailer: git-send-email 2.39.1 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org In TODO (expect in next versions): - Documentation/ page about TCP-AO kernel design, UAPI - setsockopt(TCP_REPAIR) with TCP-AO - getsockopt() to return TCP-AO counters (per-MKT & per-ao_info) - tcp_{v4,v6}_send_reset() to support TCP-AO RST signing on request sockets - TCP-AO and TCP-MD5 interraction in non/default VRFs: more selftests - check getsockopt() with VRFs (currently untested) This is also available as a git branch for pulling: https://github.com/0x7f454c46/linux/tree/tcp-ao-v4 And another branch with selftests, that will be sent later separately: https://github.com/0x7f454c46/linux/tree/tcp-ao-v4-with-selftests Changes from v3: - TCP_MD5 dynamic static key enable/disable patches merged separately [4] - crypto_pool patches were nacked [5], so instead this patch set extends TCP-MD5-sigpool to be used for TCP-AO as well as for TCP-MD5 - Added missing `static' for tcp_v6_ao_calc_key() (kernel test robot ) - Removed CONFIG_TCP_AO default=y and added "If unsure, say N." - Don't leak ao_info and don't create an unsigned TCP socket if there was a TCP-AO key during handshake, but it was removed from listening socket while the connection was being established - Migrate to use static_key_fast_inc_not_disabled() and check return code of static_branch_inc() - Change some return codes to EAFNOSUPPORT for error-pathes where family is neither AF_INET nor AF_INET6 - setsockopt()s on a closed/listen socket might have created stray ao_info, remove it if connect() is called with a correct TCP-MD5 key, the same for the reverse situation: remove md5sig_info straight away from the socket if it's going to be TCP-AO connection - IPv4-mapped-IPv6 addresses + selftest in fcnal-test.sh (by Salam) - fix using uninitialized sisn/disn from stack - it would only make non-SYN packets fail verification on a listen socket, which are not expected anyway (kernel test robot ) - implicit padding in UAPI TCP-AO structures converted to explicit (spotted-by David Laight) - Some selftests missed zero-initializers for uapi structs on stack - Removed tcp_ao_do_lookup_rcvid() and tcp_ao_do_lookup_sndid() in favor of unified tcp_ao_matched_key() - Disallowed setting current/rnext keys on listen sockets - that wasn't supported and didn't affect anything, cleanup for the UAPI - VRFs support for TCP-AO Changes from v2: - Added more missing `static' declarations for local functions (kernel test robot ) - Building now with CONFIG_TCP_AO=n and CONFIG_TCP_MD5SIG=n (kernel test robot ) - Now setsockopt(TCP_AO) is allowed when it's TCP_LISTEN or TCP_CLOSE state OR the key added is not the first key on a socket (by Salam) - CONFIG_TCP_AO does not depend on CONFIG_TCP_MD5SIG anymore - Don't leak tcp_md5_needed static branch counter when TCP-MD5 key is modified/changed - TCP-AO lookups are dynamically enabled/disabled with static key when there is ao_info in the system (and when it is destroyed) - Wired SYN cookies up to TCP-AO (by Salam) - Fix verification for possible re-transmitted SYN packets (by Salam) - use sockopt_lock_sock() instead of lock_sock() (from v6.1 rebase, commit d51bbff2aba7) - use sockptr_t in getsockopt(TCP_AO_GET) (from v6.1 rebase, commit 34704ef024ae) - Fixed reallocating crypto_pool's scratch area by IPI while crypto_pool_get() was get by another CPU - selftests on older kernels (or with CONFIG_TCP_AO=n) should exit with SKIP, not FAIL (Shuah Khan ) - selftests that check interaction between TCP-AO and TCP-MD5 now SKIP when CONFIG_TCP_MD5SIG=n - Measured the performance of different hashing algorithms for TCP-AO and compare with TCP-MD5 performance. This is done with hacky patches to iperf (see [3]). At this moment I've done it in qemu/KVM with CPU affinities set on Intel(R) Core(TM) i7-7600U CPU @ 2.80GHz. No performance degradation was noticed before/after patches, but given the measures were done in a VM, without measuring it on a physical dut it only gives a hint of relative speed for different hash algorithms with TCP-AO. Here are results, averaging on 30 measures each: TCP: 3.51Gbits/sec TCP-MD5: 1.12Gbits/sec TCP-AO(HMAC(SHA1)): 1.53Gbits/sec TCP-AO(CMAC(AES128)): 621Mbits/sec TCP-AO(HMAC(SHA512)): 1.21Gbits/sec TCP-AO(HMAC(SHA384)): 1.20Gbits/sec TCP-AO(HMAC(SHA224)): 961Mbits/sec TCP-AO(HMAC(SHA3-512)): 157Mbits/sec TCP-AO(HMAC(RMD160)): 659Mbits/sec TCP-AO(HMAC(MD5): 1.12Gbits/sec (the last one is just for fun, but may make sense as it provides the same security as TCP-MD5, but allows multiple keys and a mechanism to change them from RFC5925) Changes from v1: - Building now with CONFIG_IPV6=n (kernel test robot ) - Added missing static declarations for local functions (kernel test robot ) - Addressed static analyzer and review comments by Dan Carpenter (thanks, they were very useful!) - Fix elif without defined() for !CONFIG_TCP_AO - Recursively build selftests/net/tcp_ao (Shuah Khan), patches in: https://lore.kernel.org/all/20220919201958.279545-1-dima@arista.com/T/#u - Don't leak crypto_pool reference when TCP-MD5 key is modified/changed - Add TCP-AO support for nettest.c and fcnal-test.sh (will be used for VRF testing in later versions) Comparison between Leonard proposal and this (overview): https://lore.kernel.org/all/3cf03d51-74db-675c-b392-e4647fa5b5a6@arista.com/T/#u Version 2: https://lore.kernel.org/all/20220923201319.493208-1-dima@arista.com/T/#u Version 1: https://lore.kernel.org/all/20220818170005.747015-1-dima@arista.com/T/#u This patchset implements the TCP-AO option as described in RFC5925. There is a request from industry to move away from TCP-MD5SIG and it seems the time is right to have a TCP-AO upstreamed. This TCP option is meant to replace the TCP MD5 option and address its shortcomings. Specifically, it provides more secure hashing, key rotation and support for long-lived connections (see the summary of TCP-AO advantages over TCP-MD5 in (1.3) of RFC5925). The patch series starts with six patches that are not specific to TCP-AO but implement a general crypto facility that we thought is useful to eliminate code duplication between TCP-MD5SIG and TCP-AO as well as other crypto users. These six patches are being submitted separately in a different patchset [1]. Including them here will show better the gain in code sharing. Next are 18 patches that implement the actual TCP-AO option, followed by patches implementing selftests. The patch set was written as a collaboration of three authors (in alphabetical order): Dmitry Safonov, Francesco Ruggeri and Salam Noureddine. Additional credits should be given to Prasad Koya, who was involved in early prototyping a few years back. There is also a separate submission done by Leonard Crestez whom we thank for his efforts getting an implementation of RFC5925 submitted for review upstream [2]. This is an independent implementation that makes different design decisions. For example, we chose a similar design to the TCP-MD5SIG implementation and used setsockopts to program per-socket keys, avoiding the extra complexity of managing a centralized key database in the kernel. A centralized database in the kernel has dubious benefits since it doesn’t eliminate per-socket setsockopts needed to specify which sockets need TCP-AO and what are the currently preferred keys. It also complicates traffic key caching and preventing deletion of in-use keys. In this implementation, a centralized database of keys can be thought of as living in user space and user applications would have to program those keys on matching sockets. On the server side, the user application programs keys (MKTS in TCP-AO nomenclature) on the listening socket for all peers that are expected to connect. Prefix matching on the peer address is supported. When a peer issues a successful connect, all the MKTs matching the IP address of the peer are copied to the newly created socket. On the active side, when a connect() is issued all MKTs that do not match the peer are deleted from the socket since they will never match the peer. This implementation uses three setsockopt()s for adding, deleting and modifying keys on a socket. All three setsockopt()s have extensive sanity checks that prevent inconsistencies in the keys on a given socket. A getsockopt() is provided to get key information from any given socket. Few things to note about this implementation: - Traffic keys are cached for established connections avoiding the cost of such calculation for each packet received or sent. - Great care has been taken to avoid deleting in-use MKTs as required by the RFC. - Any crypto algorithm supported by the Linux kernel can be used to calculate packet hashes. - Fastopen works with TCP-AO but hasn’t been tested extensively. - Tested for interop with other major networking vendors (on linux-4.19), including testing for key rotation and long lived connections. [1]: https://lore.kernel.org/all/20220726201600.1715505-1-dima@arista.com/ [2]: https://lore.kernel.org/all/cover.1658815925.git.cdleonard@gmail.com/ [3]: https://github.com/0x7f454c46/iperf/tree/tcp-md5-ao [4]: https://lore.kernel.org/all/166995421700.16716.17446147162780881407.git-patchwork-notify@kernel.org/T/#u [5]: https://lore.kernel.org/all/Y8kSkW4X4vQdFyOl@gondor.apana.org.au/T/#u Cc: Andy Lutomirski Cc: Ard Biesheuvel Cc: Bob Gilligan Cc: Dan Carpenter Cc: David Ahern Cc: David Laight Cc: "David S. Miller" Cc: Dmitry Safonov <0x7f454c46@gmail.com> Cc: Eric Biggers Cc: Eric Dumazet Cc: "Eric W. Biederman" Cc: Francesco Ruggeri Cc: Herbert Xu Cc: Hideaki YOSHIFUJI Cc: Ivan Delalande Cc: Jakub Kicinski Cc: Leonard Crestez Cc: Paolo Abeni Cc: Salam Noureddine Cc: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Dmitry Safonov (21): net/tcp: Prepare tcp_md5sig_pool for TCP-AO tcp: Add TCP-AO config and structures net/tcp: Introduce TCP_AO setsockopt()s net/tcp: Prevent TCP-MD5 with TCP-AO being set net/tcp: Calculate TCP-AO traffic keys net/tcp: Add TCP-AO sign to outgoing packets net/tcp: Add tcp_parse_auth_options() net/tcp: Add AO sign to RST packets net/tcp: Add TCP-AO sign to twsk net/tcp: Wire TCP-AO to request sockets net/tcp: Sign SYN-ACK segments with TCP-AO net/tcp: Verify inbound TCP-AO signed segments net/tcp: Add TCP-AO segments counters net/tcp: Add TCP-AO SNE support net/tcp: Add tcp_hash_fail() ratelimited logs net/tcp: Ignore specific ICMPs for TCP-AO connections net/tcp: Add option for TCP-AO to (not) hash header net/tcp: Add getsockopt(TCP_AO_GET) net/tcp: Allow asynchronous delete for TCP-AO keys (MKTs) net/tcp-ao: Add static_key for TCP-AO net/tcp-ao: Wire up l3index to TCP-AO include/linux/sockptr.h | 23 + include/linux/tcp.h | 30 +- include/net/dropreason.h | 25 + include/net/tcp.h | 207 +++- include/net/tcp_ao.h | 306 ++++++ include/uapi/linux/snmp.h | 5 + include/uapi/linux/tcp.h | 73 ++ net/ipv4/Kconfig | 17 + net/ipv4/Makefile | 2 + net/ipv4/proc.c | 5 + net/ipv4/syncookies.c | 4 + net/ipv4/tcp.c | 192 ++-- net/ipv4/tcp_ao.c | 2130 +++++++++++++++++++++++++++++++++++++ net/ipv4/tcp_input.c | 105 +- net/ipv4/tcp_ipv4.c | 354 ++++-- net/ipv4/tcp_minisocks.c | 35 +- net/ipv4/tcp_output.c | 211 +++- net/ipv4/tcp_sigpool.c | 333 ++++++ net/ipv6/Makefile | 1 + net/ipv6/syncookies.c | 5 + net/ipv6/tcp_ao.c | 149 +++ net/ipv6/tcp_ipv6.c | 372 +++++-- 22 files changed, 4251 insertions(+), 333 deletions(-) create mode 100644 include/net/tcp_ao.h create mode 100644 net/ipv4/tcp_ao.c create mode 100644 net/ipv4/tcp_sigpool.c create mode 100644 net/ipv6/tcp_ao.c base-commit: e1c04510f521e853019afeca2a5991a5ef8d6a5b