From nobody Thu Dec 18 12:31:48 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5F5B92BDC27 for ; Wed, 6 Aug 2025 20:38:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754512711; cv=none; b=j75cXLRlnncJnqn0FQxjBT223ktXUUhtrRSk9aL5chd7zlzDvNkYKtLCZtDrqa+kzI2ZJbWUQVSGTDRUUl2eK2KOwEs60bvHT2zPUqi49EkRFDZ8ZFH+9JuLQTAoLkLsXZuvVBUIDOEVYMjA2qbdpLgwkOYDavpR8YRXYOWlS+Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754512711; c=relaxed/simple; bh=RADfIKwPhj+DkAPatNQkX2gb7fWflAIEqUTVTjDwFZs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cxmIF8nw6z/HQn/38liiJzCUTL3Lp1BE6xqCpgu2KqY8v1sEtRwPlHq1vFS0PpQW/QPnQYOz0ecnOg6fT5vz8QW4cD2tzWiQrkGUAv8VnxJxz9cGJ1wDI8lp8dtPsvzPsYXGv2uUbgSbgsS4ibg454NDdREn2Wz/usqyxru5U6Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=EWpuGyPi; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="EWpuGyPi" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1754512708; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=V53J5dLsJ8va+hHlO5XgVswqLQWMnx9lx0yK9P6Bodw=; b=EWpuGyPiwtPbOgouHE0851awW6fNPZvWULjROaDkTogdHGwb1AEMwLd0rMzHmDWxj5gBlk oVVVCu91NrJfWapXmAEROA2DWv0RM00SKXTVTCiJuCPWnJVx0nnUDQ+6h7InDSzKpDRHJa N5uxwfmpXGS7kadmtgLF4SZ0InmkCoY= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-685-bKiLt4O8MsOY2Yur167_xg-1; Wed, 06 Aug 2025 16:38:25 -0400 X-MC-Unique: bKiLt4O8MsOY2Yur167_xg-1 X-Mimecast-MFC-AGG-ID: bKiLt4O8MsOY2Yur167_xg_1754512703 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 8E0EA1800342; Wed, 6 Aug 2025 20:38:23 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.17]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 714FE180035C; Wed, 6 Aug 2025 20:38:20 +0000 (UTC) From: David Howells To: Steve French Cc: David Howells , Paulo Alcantara , Shyam Prasad N , Tom Talpey , Wang Zhaolong , Stefan Metzmacher , Mina Almasry , linux-cifs@vger.kernel.org, linux-kernel@vger.kernel.org, netfs@lists.linux.dev, linux-fsdevel@vger.kernel.org Subject: [RFC PATCH 14/31] cifs: Split crypt_message() into encrypt and decrypt variants Date: Wed, 6 Aug 2025 21:36:35 +0100 Message-ID: <20250806203705.2560493-15-dhowells@redhat.com> In-Reply-To: <20250806203705.2560493-1-dhowells@redhat.com> References: <20250806203705.2560493-1-dhowells@redhat.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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" Split crypt_message() into encrypt and decrypt variants so that the encrypt variant can be substantially changed. Signed-off-by: David Howells cc: Steve French cc: Paulo Alcantara cc: Shyam Prasad N cc: Tom Talpey cc: linux-cifs@vger.kernel.org cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org --- fs/smb/client/smb2ops.c | 100 ++++++++++++++++++++++++++++++++++------ 1 file changed, 85 insertions(+), 15 deletions(-) diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 7b714e50f681..0ad4a2a012a0 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -4297,16 +4297,17 @@ smb2_get_enc_key(struct TCP_Server_Info *server, __= u64 ses_id, int enc, u8 *key) =20 return -EAGAIN; } + /* - * Encrypt or decrypt @rqst message. @rqst[0] has the following format: + * Encrypt @rqst message. @rqst[0] has the following format: * iov[0] - transform header (associate data), * iov[1-N] - SMB2 header and pages - data to encrypt. * On success return encrypted data in iov[1-N] and pages, leave iov[0] * untouched. */ static int -crypt_message(struct TCP_Server_Info *server, int num_rqst, - struct smb_rqst *rqst, int enc, struct crypto_aead *tfm) +encrypt_message(struct TCP_Server_Info *server, int num_rqst, + struct smb_rqst *rqst, struct crypto_aead *tfm) { struct smb2_transform_hdr *tr_hdr =3D (struct smb2_transform_hdr *)rqst[0].rq_iov[0].iov_base; @@ -4321,10 +4322,10 @@ crypt_message(struct TCP_Server_Info *server, int n= um_rqst, void *creq; size_t sensitive_size; =20 - rc =3D smb2_get_enc_key(server, le64_to_cpu(tr_hdr->SessionId), enc, key); + rc =3D smb2_get_enc_key(server, le64_to_cpu(tr_hdr->SessionId), 1, key); if (rc) { - cifs_server_dbg(FYI, "%s: Could not get %scryption key. sid: 0x%llx\n", = __func__, - enc ? "en" : "de", le64_to_cpu(tr_hdr->SessionId)); + cifs_server_dbg(FYI, "%s: Could not get encryption key. sid: 0x%llx\n", + __func__, le64_to_cpu(tr_hdr->SessionId)); return rc; } =20 @@ -4350,11 +4351,6 @@ crypt_message(struct TCP_Server_Info *server, int nu= m_rqst, if (IS_ERR(creq)) return PTR_ERR(creq); =20 - if (!enc) { - memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE); - crypt_len +=3D SMB2_SIGNATURE_SIZE; - } - if ((server->cipher_type =3D=3D SMB2_ENCRYPTION_AES128_GCM) || (server->cipher_type =3D=3D SMB2_ENCRYPTION_AES256_GCM)) memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE); @@ -4367,15 +4363,89 @@ crypt_message(struct TCP_Server_Info *server, int n= um_rqst, aead_request_set_crypt(req, sg, sg, crypt_len, iv); aead_request_set_ad(req, assoc_data_len); =20 - rc =3D enc ? crypto_aead_encrypt(req) : crypto_aead_decrypt(req); + rc =3D crypto_aead_encrypt(req); =20 - if (!rc && enc) + if (!rc) memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE); =20 kvfree_sensitive(creq, sensitive_size); return rc; } =20 +/* + * Decrypt @rqst message. @rqst[0] has the following format: + * iov[0] - transform header (associate data), + * iov[1-N] - SMB2 header and pages - data to decrypt. + * On success return encrypted data in iov[1-N] and pages, leave iov[0] + * untouched. + */ +static int +decrypt_message(struct TCP_Server_Info *server, int num_rqst, + struct smb_rqst *rqst, struct crypto_aead *tfm) +{ + struct smb2_transform_hdr *tr_hdr =3D + (struct smb2_transform_hdr *)rqst[0].rq_iov[0].iov_base; + unsigned int assoc_data_len =3D sizeof(struct smb2_transform_hdr) - 20; + int rc =3D 0; + struct scatterlist *sg; + u8 sign[SMB2_SIGNATURE_SIZE] =3D {}; + u8 key[SMB3_ENC_DEC_KEY_SIZE]; + struct aead_request *req; + u8 *iv; + unsigned int crypt_len =3D le32_to_cpu(tr_hdr->OriginalMessageSize); + void *creq; + size_t sensitive_size; + + rc =3D smb2_get_enc_key(server, le64_to_cpu(tr_hdr->SessionId), 0, key); + if (rc) { + cifs_server_dbg(FYI, "%s: Could not get decryption key. sid: 0x%llx\n", + __func__, le64_to_cpu(tr_hdr->SessionId)); + return rc; + } + + if ((server->cipher_type =3D=3D SMB2_ENCRYPTION_AES256_CCM) || + (server->cipher_type =3D=3D SMB2_ENCRYPTION_AES256_GCM)) + rc =3D crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE); + else + rc =3D crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE); + + if (rc) { + cifs_server_dbg(VFS, "%s: Failed to set aead key %d\n", __func__, rc); + return rc; + } + + rc =3D crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE); + if (rc) { + cifs_server_dbg(VFS, "%s: Failed to set authsize %d\n", __func__, rc); + return rc; + } + + creq =3D smb2_get_aead_req(tfm, rqst, num_rqst, sign, &iv, &req, &sg, + &sensitive_size); + if (IS_ERR(creq)) + return PTR_ERR(creq); + + memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE); + crypt_len +=3D SMB2_SIGNATURE_SIZE; + + if ((server->cipher_type =3D=3D SMB2_ENCRYPTION_AES128_GCM) || + (server->cipher_type =3D=3D SMB2_ENCRYPTION_AES256_GCM)) + memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE); + else { + iv[0] =3D 3; + memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE); + } + + aead_request_set_tfm(req, tfm); + aead_request_set_crypt(req, sg, sg, crypt_len, iv); + aead_request_set_ad(req, assoc_data_len); + + rc =3D crypto_aead_decrypt(req); + + kvfree_sensitive(creq, sensitive_size); + return rc; +} + /* * Clear a read buffer, discarding the folios which have the 1st mark set. */ @@ -4509,7 +4579,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server= , int num_rqst, /* fill the 1st iov with a transform header */ fill_transform_hdr(tr_hdr, orig_len, old_rq, server->cipher_type); =20 - rc =3D crypt_message(server, num_rqst, new_rq, 1, server->secmech.enc); + rc =3D encrypt_message(server, num_rqst, new_rq, server->secmech.enc); cifs_dbg(FYI, "Encrypt message returned %d\n", rc); if (rc) goto err_free; @@ -4571,7 +4641,7 @@ decrypt_raw_data(struct TCP_Server_Info *server, char= *buf, tfm =3D server->secmech.dec; } =20 - rc =3D crypt_message(server, 1, &rqst, 0, tfm); + rc =3D decrypt_message(server, 1, &rqst, tfm); cifs_dbg(FYI, "Decrypt message returned %d\n", rc); =20 if (is_offloaded)