From patchwork Sun Jun 27 21:03:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 12347015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 51EADC48BC2 for ; Sun, 27 Jun 2021 21:03:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 223EB61C17 for ; Sun, 27 Jun 2021 21:03:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231472AbhF0VFr (ORCPT ); Sun, 27 Jun 2021 17:05:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60098 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231468AbhF0VFr (ORCPT ); Sun, 27 Jun 2021 17:05:47 -0400 Received: from mail-lf1-x12a.google.com (mail-lf1-x12a.google.com [IPv6:2a00:1450:4864:20::12a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E2CC8C061574 for ; Sun, 27 Jun 2021 14:03:22 -0700 (PDT) Received: by mail-lf1-x12a.google.com with SMTP id a18so5886133lfs.10 for ; Sun, 27 Jun 2021 14:03:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=LbfDY+YAUNfBcHJepYASk83ZPdwamwLRex2Oj/NcptM=; b=hEUW1hHAXrf/k8TM1o0xv/ede2skwev+woXiq9881UbLyT16AG/1tmYd6h6y9LfV6a NrfvX8S1Uu6mv2P3Hibo2hPO4mj8gDIcuw9HuAFzUZI4IsnHtq33C1wdDnEgtDfBjD4l enuLh5Qkp538J0+7WThYUqcAIFbHbrHxqH7ouEEs8Ta1YNN7jzSY1Lt2utjvnk62Cwot d8+h8QNf+/KOx7n6LnK2iMqBi/TRZtl0HSs0WLj9QKo3VNQr0UGzXuvEZDMSl+yAy9HO n82OajIDyh3R9WrBncj8zh2ZGJgqEqHqI/WzWHRmOJtInLhWPLYzbEdtI6+vwnCCIsqg uTdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=LbfDY+YAUNfBcHJepYASk83ZPdwamwLRex2Oj/NcptM=; b=DXOXvcu7hVM451O6dDzrDvOTtFwV09nalwLiZ6WnlUlUp0LT1q6utg+dq4DpUV+Ok6 yUBuTVv7KdqXIGpi3ssz7R78Ve2Az5OGPhiOtiMHNisCbSLOCiUOyXy7VykmxJmpSmoo PF4ckihBRLSjvAw5/lnqoc8NgV899a6/ZWxt1S0tJiZjQxQ5znKtolcTGhDk6IUyusnT fhZ4RhHehOIq0G7nnikkmFJj2p9QiYklFUAAMxlLo9EzE0YboxVkOSpKXjLHZcJQ8qvs SF/FiG+0G2/80zI3O8Bgtp8LWHqc3w1PW+UeiMdINEzuJ4+Hfj4/Tdu8QbtxlgBt1zWI R21Q== X-Gm-Message-State: AOAM530xlfrOw0OT2YwjkVN74bL5MJ3lqThJIHRGsO3CMEovwjrXW1Ey uogcbHBlVqjzM8PJ9hUNwY6TY0gwkQEHhcqpNmsA/kio4SuOXw== X-Google-Smtp-Source: ABdhPJzV3iZx2oCNwDKJe22Fu27Isi4WMbbskXtt5z32kfiaLdvs8eLyixU2JpX8rIECftBbGVSqI8ZR/A5zV99H+NY= X-Received: by 2002:a19:6a19:: with SMTP id u25mr16636910lfu.313.1624827800892; Sun, 27 Jun 2021 14:03:20 -0700 (PDT) MIME-Version: 1.0 From: Steve French Date: Sun, 27 Jun 2021 16:03:10 -0500 Message-ID: Subject: [PATCH][SMB3.1.1] client support for signing negotiate context To: CIFS , samba-technical , COMMON INTERNET FILE SYSTEM SERVER Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Here is a WIP patch for negotiating optional signing negotiate context (which will allow negotiating faster GMAC packet signing if server supports it). This patch handles enabling requesting it during negotiate protocol (set module parm "enable_GMAC_signing" to 1) and parsing the negotiate protocol response. See MS-SMB2 section 2.2.3.17. From 4c27f85b79e853bf28e774638b4225dbc1defc4c Mon Sep 17 00:00:00 2001 From: Steve French Date: Sun, 27 Jun 2021 15:30:24 -0500 Subject: [PATCH] SMB3.1.1: Add support for negotiating signing algorithm Support for faster packet signing (using GMAC instead of CMAC) can now be negotiated to some newer servers, including Windows. See MS-SMB2 section 2.2.3.17. This patch adds support for sending the new negotiate context and decoding the response. A followon patch will add support for changing the signing algorithm used based on what was negotiated. To allow the client to request GMAC signing set module parameter "enable_GMAC_signing" to 1. Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 4 +++ fs/cifs/cifsglob.h | 2 ++ fs/cifs/smb2pdu.c | 77 ++++++++++++++++++++++++++++++++++++++++------ fs/cifs/smb2pdu.h | 5 ++- 4 files changed, 77 insertions(+), 11 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 9fb874dd8d24..280d0952f912 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -65,6 +65,7 @@ bool lookupCacheEnabled = true; bool disable_legacy_dialects; /* false by default */ bool enable_gcm_256 = true; bool require_gcm_256; /* false by default */ +bool enable_GMAC_signing; /* false by default */ unsigned int global_secflags = CIFSSEC_DEF; /* unsigned int ntlmv2_support = 0; */ unsigned int sign_CIFS_PDUs = 1; @@ -104,6 +105,9 @@ MODULE_PARM_DESC(enable_gcm_256, "Enable requesting strongest (256 bit) GCM encr module_param(require_gcm_256, bool, 0644); MODULE_PARM_DESC(require_gcm_256, "Require strongest (256 bit) GCM encryption. Default: n/N/0"); +module_param(enable_GMAC_signing, bool, 0644); +MODULE_PARM_DESC(enable_GMAC_signing, "Enable requesting faster (GMAC) packet signing. Default: n/N/0"); + module_param(disable_legacy_dialects, bool, 0644); MODULE_PARM_DESC(disable_legacy_dialects, "To improve security it may be " "helpful to restrict the ability to " diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 3100f8b66e60..ac2e98e1ba60 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -666,6 +666,7 @@ struct TCP_Server_Info { unsigned int max_write; unsigned int min_offload; __le16 compress_algorithm; + __le16 signing_algorithm; __le16 cipher_type; /* save initital negprot hash */ __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; @@ -1868,6 +1869,7 @@ extern unsigned int global_secflags; /* if on, session setup sent extern unsigned int sign_CIFS_PDUs; /* enable smb packet signing */ extern bool enable_gcm_256; /* allow optional negotiate of strongest signing (aes-gcm-256) */ extern bool require_gcm_256; /* require use of strongest signing (aes-gcm-256) */ +extern bool enable_GMAC_signing; /* request use of faster (GMAC) signing if available */ extern bool linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/ extern unsigned int CIFSMaxBufSize; /* max size not including hdr */ extern unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */ diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 962826dc3316..e8359b9f72d2 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -433,6 +433,18 @@ build_compression_ctxt(struct smb2_compression_capabilities_context *pneg_ctxt) pneg_ctxt->CompressionAlgorithms[2] = SMB3_COMPRESS_LZNT1; } +static void +build_signing_ctxt(struct smb2_signing_capabilities *pneg_ctxt) +{ + pneg_ctxt->ContextType = SMB2_SIGNING_CAPABILITIES; + pneg_ctxt->DataLength = + cpu_to_le16(sizeof(struct smb2_signing_capabilities) + - sizeof(struct smb2_neg_context)); + pneg_ctxt->SigningAlgorithmCount = cpu_to_le16(2); + pneg_ctxt->SigningAlgorithms[0] = cpu_to_le16(SIGNING_ALG_AES_CMAC); + pneg_ctxt->SigningAlgorithms[1] = cpu_to_le16(SIGNING_ALG_AES_GMAC); +} + static void build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt) { @@ -498,7 +510,7 @@ assemble_neg_contexts(struct smb2_negotiate_req *req, struct TCP_Server_Info *server, unsigned int *total_len) { char *pneg_ctxt; - unsigned int ctxt_len; + unsigned int ctxt_len, neg_context_count; if (*total_len > 200) { /* In case length corrupted don't want to overrun smb buffer */ @@ -525,6 +537,17 @@ assemble_neg_contexts(struct smb2_negotiate_req *req, *total_len += ctxt_len; pneg_ctxt += ctxt_len; + ctxt_len = build_netname_ctxt((struct smb2_netname_neg_context *)pneg_ctxt, + server->hostname); + *total_len += ctxt_len; + pneg_ctxt += ctxt_len; + + build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); + *total_len += sizeof(struct smb2_posix_neg_context); + pneg_ctxt += sizeof(struct smb2_posix_neg_context); + + neg_context_count = 4; + if (server->compress_algorithm) { build_compression_ctxt((struct smb2_compression_capabilities_context *) pneg_ctxt); @@ -533,17 +556,24 @@ assemble_neg_contexts(struct smb2_negotiate_req *req, 8) * 8; *total_len += ctxt_len; pneg_ctxt += ctxt_len; - req->NegotiateContextCount = cpu_to_le16(5); - } else - req->NegotiateContextCount = cpu_to_le16(4); + neg_context_count++; + } - ctxt_len = build_netname_ctxt((struct smb2_netname_neg_context *)pneg_ctxt, - server->hostname); - *total_len += ctxt_len; - pneg_ctxt += ctxt_len; + if (enable_GMAC_signing) { + pr_warn_once("requesting GMAC signing is experimental\n"); + build_signing_ctxt((struct smb2_signing_capabilities *) + pneg_ctxt); + ctxt_len = DIV_ROUND_UP( + sizeof(struct smb2_signing_capabilities), + 8) * 8; + *total_len += ctxt_len; + pneg_ctxt += ctxt_len; + neg_context_count++; + } + + /* check for and add transport_capabilities and signing capabilities */ + req->NegotiateContextCount = cpu_to_le16(neg_context_count); - build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); - *total_len += sizeof(struct smb2_posix_neg_context); } static void decode_preauth_context(struct smb2_preauth_neg_context *ctxt) @@ -632,6 +662,30 @@ static int decode_encrypt_ctx(struct TCP_Server_Info *server, return 0; } +static void decode_signing_ctx(struct TCP_Server_Info *server, + struct smb2_signing_capabilities *pctxt) +{ + unsigned int len = le16_to_cpu(pctxt->DataLength); + + if ((len < 4) || (len > 16)) { + pr_warn_once("server sent bad signing negcontext\n"); + return; + } + if (le16_to_cpu(pctxt->SigningAlgorithmCount) != 1) { + pr_warn_once("Invalid signing algorithm count\n"); + return; + } + if (le16_to_cpu(pctxt->SigningAlgorithms[0]) > 2) { + pr_warn_once("unknown signing algorithm\n"); + return; + } + server->signing_algorithm = pctxt->SigningAlgorithms[0]; + + cifs_dbg(VFS, "GMAC signing is experimental. Algorithm %d chosen\n", + le16_to_cpu(server->signing_algorithm)); +} + + static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp, struct TCP_Server_Info *server, unsigned int len_of_smb) @@ -675,6 +729,9 @@ static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp, (struct smb2_compression_capabilities_context *)pctx); else if (pctx->ContextType == SMB2_POSIX_EXTENSIONS_AVAILABLE) server->posix_ext_supported = true; + else if (pctx->ContextType == SMB2_SIGNING_CAPABILITIES) + decode_signing_ctx(server, + (struct smb2_signing_capabilities *)pctx); else cifs_server_dbg(VFS, "unknown negcontext of type %d ignored\n", le16_to_cpu(pctx->ContextType)); diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index a5c48b85549a..67d701783182 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h @@ -394,6 +394,7 @@ struct smb2_compression_capabilities_context { __u16 Padding; __u32 Flags; __le16 CompressionAlgorithms[3]; + /* Check if pad needed */ } __packed; /* @@ -420,6 +421,7 @@ struct smb2_transport_capabilities_context { __le16 DataLength; __u32 Reserved; __le32 Flags; + __u32 Pad; } __packed; /* @@ -457,7 +459,8 @@ struct smb2_signing_capabilities { __le16 DataLength; __u32 Reserved; __le16 SigningAlgorithmCount; - __le16 SigningAlgorithms[]; + __le16 SigningAlgorithms[2]; /* CMAC and GMAC */ + __u16 Pad; /* Pad to 8 byte rounding */ } __packed; #define POSIX_CTXT_DATA_LEN 16 -- 2.30.2