From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oo1-f50.google.com (mail-oo1-f50.google.com [209.85.161.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3B4833FB7E7 for ; Fri, 8 May 2026 14:54:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.50 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778252046; cv=none; b=ZLqSQz3ftaTKkaguoULhBiEhjy7HWx2YRYxWsAW9TC5tHcjcEf14197VTyMgl8ejW4bhgYpMw2Hjph6XVYgfBsnptD9eHF9erPTYS0cYGF6EynHAupu5IjZMkCpYnP2tN7swce3GTE1h7kpGAsvKw5EvVQBkNV1RYmzw5NGm2Ac= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778252046; c=relaxed/simple; bh=Jie18w538Ct7x3CbVmimV1bnCHwry8E9OuWrmJ6cumQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UlZqp6/oD+O4Ik50CNv57mN8mKyjEd5J4tSWNX+GnYeeQncTKVtoPD38d9QPKgVpBPNJywZEU6xgHEvtzucnU8LT3RjRPs/6caepPevsrcCLG6/x3Kr1akYAG3k0clNjIvRb2YRJMb+14v2frZ7E5Qdu4L2TIjMBbqmmMjk2CDg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Y66C6sfo; arc=none smtp.client-ip=209.85.161.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Y66C6sfo" Received: by mail-oo1-f50.google.com with SMTP id 006d021491bc7-6948fb494a0so1133629eaf.2 for ; Fri, 08 May 2026 07:54:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778252044; x=1778856844; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=/pc5hm9zFh0GvB9s3uy8ydQwYAOR2n93oEpCRRyHbDs=; b=Y66C6sfoXs7fYH05OJUcRJvV1jKRTahMqbmBEEFc6pEwM+vnFILwFzy7oiJXwAHzJq 6McZilUcNdRmcBLdk8wUWGTDGi8xFdx5+vN5U8dMJzPWm7+J7IRSBj9Dj5DcL14iF9RV datUsrsz1sGfWsFhp8DI/u1SQCPSNebZsTKQgiRM0LA2VJciSkEzIq73hEsG7dSejPog 2qPxIpJaS6kJkpUxi7irYcXACruv6ugox/eDmjy1ulmESnQ6wJ+zAgzy63hMz67syz8q 2+V7KFNL9U/7MaTHkDQ9g8MAAp9iQJIrWgBmGBa/48n7HyUNPaBXGWui2NgQv936MSt+ cRmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778252044; x=1778856844; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=/pc5hm9zFh0GvB9s3uy8ydQwYAOR2n93oEpCRRyHbDs=; b=shrNqW/krqXLtEc0nsV5bQ7ItIzDqRrGyV3oGV411E8hoG7PAUOjMBAB8bjtVczulH c5rM9oXnCVxq8hfwoIHR1tKxhxsqS1o6wpGhGglEp0Y1PA+BDnq/N2FPNZU264dlSAws Gsrj2VknMlhJgC5CXN6lvn7zBwge9uQVoxDOvB0cxYQQ6zdxheN0TMijNE4OmcK+t496 gSwc5ehZynYDv6eq6OXzFcOMAOJMdyUG/eeyjGh+blAN8KccqeKb/QzKIXrsBRDCZ8/C How7MpeqbyVazJ2UQM8Kog4Ebe6j/Gv9kNf3miBZARum+piyPWe628aruvqWtRNFIdIx MrEg== X-Forwarded-Encrypted: i=1; AFNElJ8n2juLM6Orltkvbnh+BDRNJIBiDbklMX7oLcmO7r6irSStwuFBfY9LHZ6YAehL6DZ9ZSMuu/MsKH0C6FQ=@vger.kernel.org X-Gm-Message-State: AOJu0YzelFfHTXH9Vy1Mam3iaLjcQ9Q4YjMymrKMM/TWsJVb1GnYlU6j 8JmUmQgXNkiW5eulpdbdn5+ItIfQMLokCyGzo+9kNmomQP6kT3uXiMmC X-Gm-Gg: AeBDiev5Fcj1UxlPkkT8I4uwTn+URhPyB99ymaUwalZ7HxyFEC2M0PXCQS85/GFcG9L 7O073RAkGPuekLcDd3/k4bfJm7160tdFw3oHj36Xtny8als83u0cPLTKRTwB/Y7WitcB2QG3yJY CzhzOb64AV6bgij66GaKKq8QB32O4IpeVJLSX86JQaJf8aBN1lwfn7UPXfyCmEaMopGYRutqMR9 +pLgMhgp36Zuz6PhgR3VXvchfSYN4RP9L7+Cz6MVuPv1dFZzNZwR0OaFILi4225s3v26Ir/CGYj NUaCL3TIGdjnNxEPyWkSGyvxL/t90+tJj19ZogPxzHhGp6nmwJjSaV6565oU64MHou8qlVytcIg WtSE2sxh5Q+6na3IJ4EGZ0jOV/c7SF5yJndgO4vl5ibrW0qDZIfU/5kDsMhmUrg2Jm47cjq0wSL dGIJTAWVgKd7fSZavJtx8S9OzSqm6kv2RfKaon9s8FP0vwxdpZ5VL+wvOCPyQ3q9WC0xgwfA558 A== X-Received: by 2002:a05:6820:1c92:b0:694:a17f:759d with SMTP id 006d021491bc7-69998d1d6damr7091353eaf.28.1778252044172; Fri, 08 May 2026 07:54:04 -0700 (PDT) Received: from localhost ([2a03:2880:10ff:4f::]) by smtp.gmail.com with ESMTPSA id 006d021491bc7-69b25e0dbb5sm1108003eaf.13.2026.05.08.07.54.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 08 May 2026 07:54:03 -0700 (PDT) From: Daniel Zahka Date: Fri, 08 May 2026 07:53:48 -0700 Subject: [PATCH net-next 5/6] netdevsim: psp: add real aes-gcm encryption and decryption Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260508-nsim-psp-crypto-v1-5-4b50ed09b794@gmail.com> References: <20260508-nsim-psp-crypto-v1-0-4b50ed09b794@gmail.com> In-Reply-To: <20260508-nsim-psp-crypto-v1-0-4b50ed09b794@gmail.com> To: Jakub Kicinski , Andrew Lunn , "David S. Miller" , Eric Dumazet , Paolo Abeni , Willem de Bruijn Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org X-Mailer: b4 0.13.0 Implement real AES-GCM-128/256 encryption and decryption for PSP packets in the netdevsim driver, and remove gmac from supported versions. We now have to add and remove the PSP ICV trailer from packets. We linearize skb's because the aesgcm crypto library does not work on non-linear buffers. Assisted-by: Claude:claude-opus-4.6 Signed-off-by: Daniel Zahka --- drivers/net/Kconfig | 1 + drivers/net/netdevsim/psp.c | 98 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 93 insertions(+), 6 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 44a220c05536..2d21ba13de15 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -611,6 +611,7 @@ config NETDEVSIM select PAGE_POOL select NET_SHAPER select CRYPTO_LIB_AES_CBC_MACS if INET_PSP + select CRYPTO_LIB_AESGCM if INET_PSP help This driver is a developer testing tool and software model that can be used to test various control path networking APIs, especially diff --git a/drivers/net/netdevsim/psp.c b/drivers/net/netdevsim/psp.c index 8cdb88b1e232..4945973d523d 100644 --- a/drivers/net/netdevsim/psp.c +++ b/drivers/net/netdevsim/psp.c @@ -1,8 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include +#include #include #include +#include #include #include #include @@ -44,9 +47,17 @@ enum skb_drop_reason nsim_psp_handle_tx(struct sk_buff *skb, struct netdevsim *ns) { enum skb_drop_reason rc = 0; + u8 iv[GCM_AES_IV_SIZE]; + struct aesgcm_ctx ctx; struct psp_assoc *pas; + unsigned int key_size; + struct psphdr *psph; + int payload_len; struct net *net; + u8 *authtag; + int psp_off; void **ptr; + int err; rcu_read_lock(); pas = psp_skb_get_assoc_rcu(skb); @@ -72,12 +83,52 @@ nsim_psp_handle_tx(struct sk_buff *skb, struct netdevsim *ns) goto out_unlock; } + key_size = psp_key_size(pas->version); + err = aesgcm_expandkey(&ctx, pas->tx.key, key_size, PSP_TRL_SIZE); + if (err) { + rc = SKB_DROP_REASON_PSP_OUTPUT; + goto out_unlock; + } + + if (skb_linearize_cow(skb) || + (skb_tailroom(skb) < PSP_TRL_SIZE && + pskb_expand_head(skb, 0, PSP_TRL_SIZE, GFP_ATOMIC))) { + rc = SKB_DROP_REASON_PSP_OUTPUT; + goto out_unlock; + } + skb_put(skb, PSP_TRL_SIZE); + + if (skb->protocol == htons(ETH_P_IP)) { + be16_add_cpu(&ip_hdr(skb)->tot_len, PSP_TRL_SIZE); + ip_send_check(ip_hdr(skb)); + } else if (skb->protocol == htons(ETH_P_IPV6)) { + be16_add_cpu(&ipv6_hdr(skb)->payload_len, PSP_TRL_SIZE); + } + be16_add_cpu(&udp_hdr(skb)->len, PSP_TRL_SIZE); + + psph = (struct psphdr *)(skb_transport_header(skb) + + sizeof(struct udphdr)); + + /* Real impl needs to guarantee IV isn't reused on the same key */ + psph->iv = cpu_to_be64(ktime_get_mono_fast_ns()); + memcpy(iv, &psph->spi, sizeof(psph->spi)); + memcpy(iv + sizeof(psph->spi), &psph->iv, sizeof(psph->iv)); + psp_off = skb_transport_offset(skb) + sizeof(struct udphdr); + payload_len = skb->len - psp_off - PSP_HDR_SIZE - PSP_TRL_SIZE; + authtag = skb->data + skb->len - PSP_TRL_SIZE; + + aesgcm_encrypt(&ctx, + skb->data + psp_off + PSP_HDR_SIZE, + skb->data + psp_off + PSP_HDR_SIZE, + payload_len, (u8 *)psph, PSP_HDR_SIZE, + iv, authtag); + memzero_explicit(&ctx, sizeof(ctx)); + skb->decrypted = 0; u64_stats_update_begin(&ns->psp.syncp); u64_stats_inc(&ns->psp.tx_packets); - u64_stats_add(&ns->psp.tx_bytes, - skb->len - skb_inner_transport_offset(skb)); + u64_stats_add(&ns->psp.tx_bytes, payload_len); u64_stats_update_end(&ns->psp.syncp); out_unlock: rcu_read_unlock(); @@ -87,12 +138,17 @@ nsim_psp_handle_tx(struct sk_buff *skb, struct netdevsim *ns) /* Returns true if skb was consumed, false otherwise. */ bool nsim_psp_handle_rx(struct netdevsim *ns, struct sk_buff *skb) { + u8 iv[GCM_AES_IV_SIZE]; + struct aesgcm_ctx ctx; struct psp_dev *psd; + u8 key[PSP_MAX_KEY]; struct psphdr *psph; + unsigned int phase; struct udphdr *uh; int payload_len; u32 versions; int psp_off; + u8 *authtag; bool is_udp; int l3_hlen; u8 version; @@ -154,9 +210,41 @@ bool nsim_psp_handle_rx(struct netdevsim *ns, struct sk_buff *skb) if (payload_len < 0) goto drop; + if (FIELD_GET(PSPHDR_CRYPT_OFFSET, psph->crypt_offset)) + goto drop; + + if (skb_linearize_cow(skb)) + goto drop; + + psph = (struct psphdr *)(skb->data + psp_off); + phase = !!(ntohl(psph->spi) & PSP_SPI_KEY_PHASE); + + spin_lock_bh(&ns->psp.dev_keys_lock); + nsim_psp_derive_key(ns->psp.dev_keys[phase], psph->spi, version, key); + spin_unlock_bh(&ns->psp.dev_keys_lock); + + err = aesgcm_expandkey(&ctx, key, psp_key_size(version), PSP_TRL_SIZE); + memzero_explicit(key, sizeof(key)); + if (err) + goto drop; + + memcpy(iv, &psph->spi, sizeof(psph->spi)); + memcpy(iv + sizeof(psph->spi), &psph->iv, sizeof(psph->iv)); + authtag = skb->data + skb->len - PSP_TRL_SIZE; + + if (!aesgcm_decrypt(&ctx, + skb->data + psp_off + PSP_HDR_SIZE, + skb->data + psp_off + PSP_HDR_SIZE, + payload_len, (u8 *)psph, PSP_HDR_SIZE, + iv, authtag)) { + memzero_explicit(&ctx, sizeof(ctx)); + goto drop; + } + memzero_explicit(&ctx, sizeof(ctx)); + skb_push(skb, ETH_HLEN); skb->mac_len = ETH_HLEN; - err = psp_dev_rcv(skb, psd_id, 0, false); + err = psp_dev_rcv(skb, psd_id, 0, true); if (err) goto drop; @@ -274,9 +362,7 @@ static struct psp_dev_ops nsim_psp_ops = { static struct psp_dev_caps nsim_psp_caps = { .versions = 1 << PSP_VERSION_HDR0_AES_GCM_128 | - 1 << PSP_VERSION_HDR0_AES_GMAC_128 | - 1 << PSP_VERSION_HDR0_AES_GCM_256 | - 1 << PSP_VERSION_HDR0_AES_GMAC_256, + 1 << PSP_VERSION_HDR0_AES_GCM_256, .assoc_drv_spc = sizeof(void *), }; -- 2.52.0