From nobody Sun Apr 5 13:07:25 2026 Received: from mail-pj1-f42.google.com (mail-pj1-f42.google.com [209.85.216.42]) (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 B5CA837F8A1 for ; Wed, 4 Mar 2026 05:36:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772602613; cv=none; b=LdFtBkBmfl0HzCMw4z3DHMz/9s5r4MJf2BZdRBFdIkLm0xtqqr9K6Zx3FZOTfrFoaLQFWE5A6MgM8kmbMe2pvseUdm9dIDrhIFtuvWCDxiXM1raCIFDrr0V4Dq0CUvWn2kQFgHlByH3P/Feo8prHCR8Un4NiHFbp1CX8sfRQPCg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772602613; c=relaxed/simple; bh=X6tX6MsfjpCCm5XWJnWLuYwr3D2OjljkcPDWiXIpOAY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=U1piiqmOJaFIH9HI3N8iXvde98Wi+znyNN2htXzK0VaZwNxCd0PMwbX/n6NJAZAEli0WbXechCRiUw6QK08Sp6Mv7Xb0Rdv1rgS/VqITnjqo3gv3Z/VUURIZTKmcBY4dKYpcd+iuZsSAQrthicINGKVOXDo1eIp7jYpANT0PwS8= 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=h3YaSQoL; arc=none smtp.client-ip=209.85.216.42 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="h3YaSQoL" Received: by mail-pj1-f42.google.com with SMTP id 98e67ed59e1d1-3598c008455so1777309a91.3 for ; Tue, 03 Mar 2026 21:36:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772602611; x=1773207411; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=rNcMxZGmsNob2hi70jSfSua0A2NVCjnuBqG6KRIu95c=; b=h3YaSQoLLhnhiYDWEJdepXjDHNhTxpaKciEnl6O54BufaVNAP+MfeBNGp9mJ2IK5SF AzPtDHD2R5F8hpjYseFHu/ilBGvktPrsOIp1MQub88eQN+vWnXMYpT5OAlLZGu49U3bW d008yrwHFqGvtwknzrJrbRtYdtMRNVqa5SkCNDZldxNmUp1dub8YCITTzfFOPcYjRE5V PEdxZ5cCW4D0dPfXmH3eP4pCwzA1l++3Ho7ofMTEeWNECvCY7qsifQvbrCZzDhTBqCX1 8nTRTic/f91HvMr07VCOsOcPUea7SmgBsx4aa0D/Es1fllK5YX53ctY4Wfat8otBmvAw SGWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772602611; x=1773207411; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=rNcMxZGmsNob2hi70jSfSua0A2NVCjnuBqG6KRIu95c=; b=bYeu1f7QJ+5CDZNP8YRFl8xSECH5lch7ICCnwipijcKJOx/KAKwi2HoqFJgn9lWQHx +m21ogo9mhD1Zomo4RHgOfP1lWsRqE1/BhRff22PwqEVgennvuKX0IGJSWAD5OTF3l/B O+R0VGM3KGKJp5eguHPi75+FTm4Ci6Rd/WnzFSYbc2AGEFtOXV9KgRH8XeZHhpmJQnBZ kKWTb3tm9NT7u1rg56I2EQKZwxArhNPFnTj5dL968jHOBY/PfMOXKMnzo1cOS6uASlFF Xewfg2Af+P4D+Ki3nxTWTVC7KcVcmIgh17ZVOksAd9ZongGMqQ0a7ro0kH8IO3PhVEEQ ctXg== X-Forwarded-Encrypted: i=1; AJvYcCXSPWjs+CsVifEvo/lV1tBN5tdT4kVFUdb3XKQiysVo6ta/zACPbUL6xTbssGhe99dC6ucnNomKJPr8UMo=@vger.kernel.org X-Gm-Message-State: AOJu0YxVAlEgw2ynTNVS1pceARKfSod3EhRQxtWRLq6nsALvRf+xJlJu 1QkjePBbsl/rgDItfcm5dsZxRUHkGsDDXe2BaPFn9/Hf1AJuyXgOK0Lk X-Gm-Gg: ATEYQzxFg8yPdbo5ShTjnYoyTFd5L0ewlK/DUph1IeKRPAeXqcxMD6jAKSxDy7yVWBM xu7gjt/d84VjXi4hRxtdGE6jquhJwLVqLHlzFPgxExRmQuJn58lIwpm1Up9jUVeSiUfEb83SFMW WeEwjBVyOd0L2N5rTdYbIGjX7vDyO8QTCMhHPr0l+K1z4Qr2RK6MmB3gCQ5ODeAVrzVB9FBSrn0 AyXuiz9KWeBFwu1Hd0R+DvjjUpjg48At2Vu6M3yqeVv7+Ww5AG9181t4PnbsBi+X4Snwfb7NpeH n5FTLlYBWr0Da8SBlRdJ/f4wRFSD1k4eBbMEAtJc+N/HR7XWEy8mWueA744QDJ5nUQ+xGNgi9R5 4N9KxLAjMqpV86kW/0GoyY93TchP8c116GhdpElsB0pzOxEEcl+R2Kx7+TvIqIetNo1mPmfZbFH cXWEc//+vzrxtQ5PqZiGMCaucv+Bv3xYkcy6GcjhliCFk41LhKikGa X-Received: by 2002:a17:90b:3d83:b0:354:c629:efb2 with SMTP id 98e67ed59e1d1-359a6a563ddmr1057766a91.24.1772602611058; Tue, 03 Mar 2026 21:36:51 -0800 (PST) Received: from toolbx.alistair23.me ([2403:581e:fdf9:0:6209:4521:6813:45b7]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3599c090bfdsm4020057a91.8.2026.03.03.21.36.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Mar 2026 21:36:50 -0800 (PST) From: alistair23@gmail.com X-Google-Original-From: alistair.francis@wdc.com To: chuck.lever@oracle.com, hare@kernel.org, kernel-tls-handshake@lists.linux.dev, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-nvme@lists.infradead.org, linux-nfs@vger.kernel.org Cc: kbusch@kernel.org, axboe@kernel.dk, hch@lst.de, sagi@grimberg.me, kch@nvidia.com, hare@suse.de, alistair23@gmail.com, Alistair Francis Subject: [PATCH v7 4/5] nvme-tcp: Support KeyUpdate Date: Wed, 4 Mar 2026 15:34:59 +1000 Message-ID: <20260304053500.590630-5-alistair.francis@wdc.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260304053500.590630-1-alistair.francis@wdc.com> References: <20260304053500.590630-1-alistair.francis@wdc.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Alistair Francis If the nvme_tcp_try_send() or nvme_tcp_try_recv() functions return EKEYEXPIRED then the underlying TLS keys need to be updated. This occurs on an KeyUpdate event as described in RFC8446 https://datatracker.ietf.org/doc/html/rfc8446#section-4.6.3. If the NVMe Target (TLS server) initiates a KeyUpdate this patch will allow the NVMe layer to process the KeyUpdate request and forward the request to userspace. Userspace must then update the key to keep the connection alive. This patch allows us to handle the NVMe target sending a KeyUpdate request without aborting the connection. At this time we don't support initiating a KeyUpdate. Signed-off-by: Alistair Francis --- v7: - Use read_sock_cmsg instead of recvmsg() to handle KeyUpdate v6: - Don't use `struct nvme_tcp_hdr` to determine TLS_HANDSHAKE_KEYUPDATE, instead look at the cmsg fields. - Don't flush async_event_work v5: - Cleanup code flow - Check for MSG_CTRUNC in the msg_flags return from recvmsg and use that to determine if it's a control message v4: - Remove all support for initiating KeyUpdate - Don't call cancel_work() when updating keys v3: - Don't cancel existing handshake requests v2: - Don't change the state - Use a helper function for KeyUpdates - Continue sending in nvme_tcp_send_all() after a KeyUpdate - Remove command message using recvmsg drivers/nvme/host/tcp.c | 59 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 8b6172dd1c0f..ade11d2ac9ef 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -171,6 +171,7 @@ struct nvme_tcp_queue { bool tls_enabled; u32 rcv_crc; u32 snd_crc; + key_serial_t handshake_session_id; __le32 exp_ddgst; __le32 recv_ddgst; struct completion tls_complete; @@ -1361,6 +1362,59 @@ static int nvme_tcp_try_send(struct nvme_tcp_queue *= queue) return ret; } =20 +static void update_tls_keys(struct nvme_tcp_queue *queue) +{ + int qid =3D nvme_tcp_queue_id(queue); + int ret; + + dev_dbg(queue->ctrl->ctrl.device, + "updating key for queue %d\n", qid); + + ret =3D nvme_tcp_start_tls(&(queue->ctrl->ctrl), + queue, queue->ctrl->ctrl.tls_pskid, + HANDSHAKE_KEY_UPDATE_TYPE_RECEIVED); + + if (ret < 0) { + dev_err(queue->ctrl->ctrl.device, + "failed to update the keys %d\n", ret); + nvme_tcp_fail_request(queue->request); + } +} + +static int nvme_tcp_recv_cmsg(read_descriptor_t *desc, + struct sk_buff *skb, + unsigned int offset, size_t len, + u8 content_type) +{ + struct nvme_tcp_queue *queue =3D desc->arg.data; + struct socket *sock =3D queue->sock; + struct sock *sk =3D sock->sk; + + switch (content_type) { + case TLS_RECORD_TYPE_HANDSHAKE: + if (len =3D=3D 5) { + u8 header[5]; + + if (!skb_copy_bits(skb, offset, header, + sizeof(header))) { + if (header[0] =3D=3D TLS_HANDSHAKE_KEYUPDATE) { + dev_err(queue->ctrl->ctrl.device, "KeyUpdate message\n"); + release_sock(sk); + update_tls_keys(queue); + lock_sock(sk); + return 0; + } + } + } + + break; + default: + break; + } + + return -EAGAIN; +} + static int nvme_tcp_try_recv(struct nvme_tcp_queue *queue) { struct socket *sock =3D queue->sock; @@ -1372,7 +1426,8 @@ static int nvme_tcp_try_recv(struct nvme_tcp_queue *q= ueue) rd_desc.count =3D 1; lock_sock(sk); queue->nr_cqe =3D 0; - consumed =3D sock->ops->read_sock(sk, &rd_desc, nvme_tcp_recv_skb); + consumed =3D sock->ops->read_sock_cmsg(sk, &rd_desc, nvme_tcp_recv_skb, + nvme_tcp_recv_cmsg); release_sock(sk); return consumed =3D=3D -EAGAIN ? 0 : consumed; } @@ -1708,6 +1763,7 @@ static void nvme_tcp_tls_done(void *data, int status,= key_serial_t pskid, ctrl->ctrl.tls_pskid =3D key_serial(tls_key); key_put(tls_key); queue->tls_err =3D 0; + queue->handshake_session_id =3D handshake_session_id; } =20 out_complete: @@ -1737,6 +1793,7 @@ static int nvme_tcp_start_tls(struct nvme_ctrl *nctrl, keyring =3D key_serial(nctrl->opts->keyring); args.ta_keyring =3D keyring; args.ta_timeout_ms =3D tls_handshake_timeout * 1000; + args.ta_handshake_session_id =3D queue->handshake_session_id; queue->tls_err =3D -EOPNOTSUPP; init_completion(&queue->tls_complete); if (keyupdate =3D=3D HANDSHAKE_KEY_UPDATE_TYPE_UNSPEC) --=20 2.53.0