smb: client: More crypto library conversions
Subsystems (3)
cover smb: client: More crypto library conversions
This series converts fs/smb/client/ to access SHA-512, HMAC-SHA256, MD5, and HMAC-MD5 using the library APIs instead of crypto_shash.
This simplifies the code significantly. It also slightly improves performance, as it eliminates unnecessary overhead.
Tested with Samba with all SMB versions, with mfsymlinks in the mount options, 'server min protocol = NT1' and 'server signing = required' in smb.conf, and doing a simple file data and symlink verification test. That seems to cover all the modified code paths.
However, with SMB 1.0 I get "CIFS: VFS: SMB signature verification returned error = -13", regardless of whether this series is applied or not. Presumably, testing that case requires some other setting I couldn't find.
Regardless, these are straightforward conversions and all the actual crypto is exactly the same as before, as far as I can tell.
Eric Biggers (8):
smb: client: Use SHA-512 library for SMB3.1.1 preauth hash
smb: client: Use HMAC-SHA256 library for key generation
smb: client: Use HMAC-SHA256 library for SMB2 signature calculation
smb: client: Use MD5 library for M-F symlink hashing
smb: client: Use MD5 library for SMB1 signature calculation
smb: client: Use HMAC-MD5 library for NTLMv2
smb: client: Remove obsolete crypto_shash allocations
smb: client: Consolidate cmac(aes) shash allocation
fs/smb/client/Kconfig | 7 +- fs/smb/client/cifsencrypt.c | 201 +++++++++++++--------------------- fs/smb/client/cifsfs.c | 4 - fs/smb/client/cifsglob.h | 3 - fs/smb/client/cifsproto.h | 10 +- fs/smb/client/link.c | 31 +----- fs/smb/client/sess.c | 2 +- fs/smb/client/smb2misc.c | 53 ++------- fs/smb/client/smb2proto.h | 8 +- fs/smb/client/smb2transport.c | 164 +++++---------------------- 10 files changed, 131 insertions(+), 352 deletions(-)
base-commit: 67029a49db6c1f21106a1b5fcdd0ea234a6e0711
Signature · 1 line
2.51.0
PATCH 1/8 smb: client: Use SHA-512 library for SMB3.1.1 preauth hash
Convert smb311_update_preauth_hash() to use the SHA-512 library instead of a "sha512" crypto_shash. This is simpler and faster. With the library there's no need to allocate memory, no need to handle errors, and the SHA-512 code is accessed directly without inefficient indirect calls and other unnecessary API overhead.
Remove the call to smb311_crypto_shash_allocate() from smb311_update_preauth_hash(), since it appears to have been needed only to allocate the "sha512" crypto_shash. (It also had the side effect of allocating the "cmac(aes)" crypto_shash, but that's also done in generate_key() which is where the AES-CMAC key is initialized.)
For now the "sha512" crypto_shash is still being allocated elsewhere. It will be removed in a later commit.
--- fs/smb/client/Kconfig | 1 + fs/smb/client/smb2misc.c | 53 +++++++++------------------------------ fs/smb/client/smb2proto.h | 6 ++--- 3 files changed, 16 insertions(+), 44 deletions(-)
fs/smb/client/Kconfig +1 -0
@@ -14,10 +14,11 @@ config CIFS select CRYPTO_CCM select CRYPTO_GCM select CRYPTO_ECB select CRYPTO_AES select CRYPTO_LIB_ARC4 + select CRYPTO_LIB_SHA512 select KEYS select DNS_RESOLVER select ASN1 select OID_REGISTRY select NETFS_SUPPORT
fs/smb/client/smb2misc.c +12 -41
93 lines not on this page · raw message
fs/smb/client/smb2proto.h +3 -3
@@ -294,13 +294,13 @@ extern int smb2_validate_and_copy_iov(unsigned int offset, unsigned int minbufsize, char *data);extern void smb2_copy_fs_info_to_kstatfs (struct smb2_fs_full_size_info *pfs_inf,struct kstatfs *kst);extern int smb311_crypto_shash_allocate (struct TCP_Server_Info *server); -extern int smb311_update_preauth_hash (struct cifs_ses *ses, -struct TCP_Server_Info *server, -struct kvec *iov,int nvec); +extern void smb311_update_preauth_hash (struct cifs_ses *ses, +struct TCP_Server_Info *server, +struct kvec *iov,int nvec); extern int smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, const char *path, u32 desired_access, u32 class, u32 type, u32 output_len, struct kvec *rsp, int *buftype,
Signature · 1 line
2.51.0
PATCH 2/8 smb: client: Use HMAC-SHA256 library for key generation
In reply to Eric BiggersConvert generate_key() to use the HMAC-SHA256 library instead of a "hmac(sha256)" crypto_shash. This is simpler and faster. With the library there's no need to allocate memory, no need to handle errors, and the HMAC-SHA256 code is accessed directly without inefficient indirect calls and other unnecessary API overhead.
Also remove the unnecessary 'hashptr' variable.
For now smb3_crypto_shash_allocate() still allocates a "hmac(sha256)" crypto_shash. It will be removed in a later commit.
--- fs/smb/client/Kconfig | 1 + fs/smb/client/smb2transport.c | 68 ++++++++--------------------------- 2 files changed, 15 insertions(+), 54 deletions(-)
fs/smb/client/Kconfig +1 -0
@@ -14,10 +14,11 @@ config CIFS select CRYPTO_CCM select CRYPTO_GCM select CRYPTO_ECB select CRYPTO_AES select CRYPTO_LIB_ARC4 + select CRYPTO_LIB_SHA256 select CRYPTO_LIB_SHA512 select KEYS select DNS_RESOLVER select ASN1 select OID_REGISTRY
fs/smb/client/smb2transport.c +14 -54
104 lines not on this page · raw message
Signature · 1 line
2.51.0
PATCH 3/8 smb: client: Use HMAC-SHA256 library for SMB2 signature calculation
In reply to Eric BiggersConvert smb2_calc_signature() to use the HMAC-SHA256 library instead of a "hmac(sha256)" crypto_shash. This is simpler and faster. With the library there's no need to allocate memory, no need to handle errors, and the HMAC-SHA256 code is accessed directly without inefficient indirect calls and other unnecessary API overhead.
To make this possible, make __cifs_calc_signature() support both the HMAC-SHA256 library and crypto_shash. (crypto_shash is still needed for HMAC-MD5 and AES-CMAC. A later commit will switch HMAC-MD5 from shash to the library. I'd like to eventually do the same for AES-CMAC, but it doesn't have a library API yet. So for now, shash is still needed.)
Also remove the unnecessary 'sigptr' variable.
For now smb3_crypto_shash_allocate() still allocates a "hmac(sha256)" crypto_shash. It will be removed in a later commit.
--- fs/smb/client/cifsencrypt.c | 52 +++++++++++++++++++++++----------- fs/smb/client/cifsproto.h | 9 ++++-- fs/smb/client/smb2transport.c | 53 ++++++++--------------------------- 3 files changed, 53 insertions(+), 61 deletions(-)
fs/smb/client/cifsencrypt.c +36 -16
@@ -22,43 +22,62 @@#include <linux/highmem.h> #include <linux/fips.h> #include <linux/iov_iter.h> #include <crypto/aead.h> #include <crypto/arc4.h> +#include <crypto/sha2.h> -static size_t cifs_shash_step (void *iter_base,size_t progress,size_t len, -void *priv,void *priv2) +static int cifs_sig_update (struct cifs_calc_sig_ctx *ctx, +const u8 *data,size_t len) { -struct shash_desc *shash = priv; +if (ctx->hmac) { +hmac_sha256_update (ctx->hmac, data, len); +return 0 ; + } +return crypto_shash_update (ctx->shash, data, len); +} + +static int cifs_sig_final (struct cifs_calc_sig_ctx *ctx,u8 *out) +{ +if (ctx->hmac) { +hmac_sha256_final (ctx->hmac, out); +return 0 ; + } +return crypto_shash_final (ctx->shash, out); +} + +static size_t cifs_sig_step (void *iter_base,size_t progress,size_t len, +void *priv,void *priv2) +{ +struct cifs_calc_sig_ctx *ctx = priv;int ret, *pret = priv2; - ret =crypto_shash_update (shash, iter_base, len); + ret =cifs_sig_update (ctx, iter_base, len);if (ret <0 ) { *pret = ret;return len; }return 0 ; }/* * Pass the data from an iterator into a hash. */ -static int cifs_shash_iter (const struct iov_iter *iter,size_t maxsize, -struct shash_desc *shash) +static int cifs_sig_iter (const struct iov_iter *iter,size_t maxsize, +struct cifs_calc_sig_ctx *ctx) {struct iov_iter tmp_iter = *iter;int err = -EIO ; -if (iterate_and_advance_kernel (&tmp_iter, maxsize, shash, &err, - cifs_shash_step) != maxsize) +if (iterate_and_advance_kernel (&tmp_iter, maxsize, ctx, &err, + cifs_sig_step) != maxsize)return err;return 0 ; } -int __cifs_calc_signature (struct smb_rqst *rqst, -struct TCP_Server_Info *server,char *signature, -struct shash_desc *shash) +int __cifs_calc_signature (struct smb_rqst *rqst,struct TCP_Server_Info *server, +char *signature,struct cifs_calc_sig_ctx *ctx) {int i;ssize_t rc;struct kvec *iov = rqst->rq_iov;int n_vec = rqst->rq_nvec;
@@ -80,24 +99,23 @@ int __cifs_calc_signature(struct smb_rqst *rqst,if (iov[i].iov_base ==NULL ) {cifs_dbg (VFS ,"null iovec entry\n" );return -EIO ; } - rc =crypto_shash_update (shash, - iov[i].iov_base, iov[i].iov_len); + rc =cifs_sig_update (ctx, iov[i].iov_base, iov[i].iov_len);if (rc) {cifs_dbg (VFS ,"%s: Could not update with payload\n" , __func__);return rc; } } - rc =cifs_shash_iter (&rqst->rq_iter,iov_iter_count (&rqst->rq_iter), shash); + rc =cifs_sig_iter (&rqst->rq_iter,iov_iter_count (&rqst->rq_iter), ctx);if (rc <0 )return rc; - rc =crypto_shash_final (shash, signature); + rc =cifs_sig_final (ctx, signature);if (rc)cifs_dbg (VFS ,"%s: Could not generate hash\n" , __func__);return rc; }
@@ -132,11 +150,13 @@ static int cifs_calc_signature(struct smb_rqst *rqst,if (rc) {cifs_dbg (VFS ,"%s: Could not update with response\n" , __func__);return rc; } -return __cifs_calc_signature (rqst, server, signature, server->secmech.md5); +return __cifs_calc_signature ( + rqst, server, signature, + &(struct cifs_calc_sig_ctx ){ .shash = server->secmech.md5 }); }/* must be called with server->srv_mutex held */ int cifs_sign_rqst (struct smb_rqst *rqst,struct TCP_Server_Info *server,__u32 *pexpected_response_sequence_number)
fs/smb/client/cifsproto.h +6 -3
@@ -630,13 +630,16 @@ int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, unsigned int *pbytes_read);int cifs_create_mf_symlink (unsigned int xid,struct cifs_tcon *tcon,struct cifs_sb_info *cifs_sb,const unsigned char *path,char *pbuf,unsigned int *pbytes_written); -int __cifs_calc_signature (struct smb_rqst *rqst, -struct TCP_Server_Info *server,char *signature, -struct shash_desc *shash); +struct cifs_calc_sig_ctx { +struct hmac_sha256_ctx *hmac; +struct shash_desc *shash; +}; +int __cifs_calc_signature (struct smb_rqst *rqst,struct TCP_Server_Info *server, +char *signature,struct cifs_calc_sig_ctx *ctx);enum securityEnum cifs_select_sectype (struct TCP_Server_Info *,enum securityEnum );int cifs_alloc_hash (const char *name,struct shash_desc **sdesc);void cifs_free_hash (struct shash_desc **sdesc);
fs/smb/client/smb2transport.c +11 -42
112 lines not on this page · raw message
Signature · 1 line
2.51.0
PATCH 4/8 smb: client: Use MD5 library for M-F symlink hashing
In reply to Eric BiggersConvert parse_mf_symlink() and format_mf_symlink() to use the MD5 library instead of a "md5" crypto_shash. This is simpler and faster. With the library there's no need to allocate memory, no need to handle errors, and the MD5 code is accessed directly without inefficient indirect calls and other unnecessary API overhead.
This also fixes an issue where these functions did not work on kernels booted in FIPS mode. The use of MD5 here is for data integrity rather than a security purpose, so it can use a non-FIPS-approved algorithm.
--- fs/smb/client/Kconfig | 1 + fs/smb/client/link.c | 31 +++---------------------------- 2 files changed, 4 insertions(+), 28 deletions(-)
fs/smb/client/Kconfig +1 -0
@@ -14,10 +14,11 @@ config CIFS select CRYPTO_CCM select CRYPTO_GCM select CRYPTO_ECB select CRYPTO_AES select CRYPTO_LIB_ARC4 + select CRYPTO_LIB_MD5 select CRYPTO_LIB_SHA256 select CRYPTO_LIB_SHA512 select KEYS select DNS_RESOLVER select ASN1
fs/smb/client/link.c +3 -28
@@ -3,10 +3,11 @@* * Copyright (C) International Business Machines Corp., 2002,2008 * Author(s): Steve French ([email protected]) * */ +#include <crypto/md5.h> #include <linux/fs.h> #include <linux/stat.h> #include <linux/slab.h> #include <linux/namei.h> #include "cifsfs.h"
@@ -34,27 +35,10 @@#define CIFS_MF_SYMLINK_LEN_FORMAT "XSym\n%04u\n"#define CIFS_MF_SYMLINK_MD5_FORMAT "%16phN\n"#define CIFS_MF_SYMLINK_MD5_ARGS (md5_hash) md5_hash -static int -symlink_hash (unsigned int link_len,const char *link_str,u8 *md5_hash) -{ -int rc; -struct shash_desc *md5 =NULL ; - - rc =cifs_alloc_hash ("md5" , &md5); -if (rc) -return rc; - - rc =crypto_shash_digest (md5, link_str, link_len, md5_hash); -if (rc) -cifs_dbg (VFS ,"%s: Could not generate md5 hash\n" , __func__); -cifs_free_hash (&md5); -return rc; -} -static int parse_mf_symlink (const u8 *buf,unsigned int buf_len,unsigned int *_link_len,char **_link_str) {int rc;
@@ -75,15 +59,11 @@ parse_mf_symlink(const u8 *buf, unsigned int buf_len, unsigned int *_link_len,return -EINVAL ;if (link_len >CIFS_MF_SYMLINK_LINK_MAXLEN )return -EINVAL ; - rc =symlink_hash (link_len, link_str, md5_hash); -if (rc) { -cifs_dbg (FYI ,"%s: MD5 hash failure: %d\n" , __func__, rc); -return rc; - } +md5 (link_str, link_len, md5_hash);scnprintf (md5_str2,sizeof (md5_str2),CIFS_MF_SYMLINK_MD5_FORMAT ,CIFS_MF_SYMLINK_MD5_ARGS (md5_hash));
@@ -101,11 +81,10 @@ parse_mf_symlink(const u8 *buf, unsigned int buf_len, unsigned int *_link_len, }static int format_mf_symlink (u8 *buf,unsigned int buf_len,const char *link_str) { -int rc;unsigned int link_len;unsigned int ofs;u8 md5_hash[16 ];if (buf_len !=CIFS_MF_SYMLINK_FILE_SIZE )
@@ -114,15 +93,11 @@ format_mf_symlink(u8 *buf, unsigned int buf_len, const char *link_str) link_len =strlen (link_str);if (link_len >CIFS_MF_SYMLINK_LINK_MAXLEN )return -ENAMETOOLONG ; - rc =symlink_hash (link_len, link_str, md5_hash); -if (rc) { -cifs_dbg (FYI ,"%s: MD5 hash failure: %d\n" , __func__, rc); -return rc; - } +md5 (link_str, link_len, md5_hash);scnprintf (buf, buf_len, CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT, link_len,CIFS_MF_SYMLINK_MD5_ARGS (md5_hash));
Signature · 1 line
2.51.0
PATCH 5/8 smb: client: Use MD5 library for SMB1 signature calculation
In reply to Eric BiggersConvert cifs_calc_signature() to use the MD5 library instead of a "md5" crypto_shash. This is simpler and faster. With the library there's no need to allocate memory, no need to handle errors, and the MD5 code is accessed directly without inefficient indirect calls and other unnecessary API overhead.
To preserve the existing behavior of MD5 signature support being disabled when the kernel is booted with "fips=1", make cifs_calc_signature() check fips_enabled itself. Previously it relied on the error from cifs_alloc_hash("md5", &server->secmech.md5).
--- fs/smb/client/cifsencrypt.c | 34 +++++++++++++++++----------------- fs/smb/client/cifsproto.h | 1 + 2 files changed, 18 insertions(+), 17 deletions(-)
fs/smb/client/cifsencrypt.c +17 -17
@@ -22,24 +22,33 @@#include <linux/highmem.h> #include <linux/fips.h> #include <linux/iov_iter.h> #include <crypto/aead.h> #include <crypto/arc4.h> +#include <crypto/md5.h> #include <crypto/sha2.h> static int cifs_sig_update (struct cifs_calc_sig_ctx *ctx,const u8 *data,size_t len) { +if (ctx->md5) { +md5_update (ctx->md5, data, len); +return 0 ; + }if (ctx->hmac) {hmac_sha256_update (ctx->hmac, data, len);return 0 ; }return crypto_shash_update (ctx->shash, data, len); }static int cifs_sig_final (struct cifs_calc_sig_ctx *ctx,u8 *out) { +if (ctx->md5) { +md5_final (ctx->md5, out); +return 0 ; + }if (ctx->hmac) {hmac_sha256_final (ctx->hmac, out);return 0 ; }return crypto_shash_final (ctx->shash, out);
@@ -128,35 +137,26 @@ int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,* should be called with the server->srv_mutex held. */ static int cifs_calc_signature (struct smb_rqst *rqst,struct TCP_Server_Info *server,char *signature) { -int rc; +struct md5_ctx ctx;if (!rqst->rq_iov || !signature || !server)return -EINVAL ; - - rc =cifs_alloc_hash ("md5" , &server->secmech.md5); -if (rc) -return -1 ; - - rc =crypto_shash_init (server->secmech.md5); -if (rc) { -cifs_dbg (VFS ,"%s: Could not init md5\n" , __func__); -return rc; +if (fips_enabled) { +cifs_dbg (VFS , +"MD5 signature support is disabled due to FIPS\n" ); +return -EOPNOTSUPP ; } - rc =crypto_shash_update (server->secmech.md5, - server->session_key.response, server->session_key.len); -if (rc) { -cifs_dbg (VFS ,"%s: Could not update with response\n" , __func__); -return rc; - } +md5_init (&ctx); +md5_update (&ctx, server->session_key.response, server->session_key.len);return __cifs_calc_signature ( rqst, server, signature, - &(struct cifs_calc_sig_ctx ){ .shash = server->secmech.md5 }); + &(struct cifs_calc_sig_ctx ){ .md5 = &ctx }); }/* must be called with server->srv_mutex held */ int cifs_sign_rqst (struct smb_rqst *rqst,struct TCP_Server_Info *server,__u32 *pexpected_response_sequence_number)
fs/smb/client/cifsproto.h +1 -0
@@ -631,10 +631,11 @@ int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,int cifs_create_mf_symlink (unsigned int xid,struct cifs_tcon *tcon,struct cifs_sb_info *cifs_sb,const unsigned char *path,char *pbuf,unsigned int *pbytes_written);struct cifs_calc_sig_ctx { +struct md5_ctx *md5;struct hmac_sha256_ctx *hmac;struct shash_desc *shash; };int __cifs_calc_signature (struct smb_rqst *rqst,struct TCP_Server_Info *server,char *signature,struct cifs_calc_sig_ctx *ctx);
Signature · 1 line
2.51.0
PATCH 6/8 smb: client: Use HMAC-MD5 library for NTLMv2
In reply to Eric BiggersFor the HMAC-MD5 computations in NTLMv2, use the HMAC-MD5 library instead of a "hmac(md5)" crypto_shash. This is simpler and faster. With the library there's no need to allocate memory, no need to handle errors, and the HMAC-MD5 code is accessed directly without inefficient indirect calls and other unnecessary API overhead.
To preserve the existing behavior of NTLMv2 support being disabled when the kernel is booted with "fips=1", make setup_ntlmv2_rsp() check fips_enabled itself. Previously it relied on the error from cifs_alloc_hash("hmac(md5)", &hmacmd5).
--- fs/smb/client/cifsencrypt.c | 114 +++++++----------------------------- 1 file changed, 22 insertions(+), 92 deletions(-)
fs/smb/client/cifsencrypt.c +22 -92
@@ -423,33 +423,23 @@ static __le64 find_timestamp(struct cifs_ses *ses)ktime_get_real_ts64 (&ts);return cpu_to_le64 (cifs_UnixTimeToNT (ts)); }static int calc_ntlmv2_hash (struct cifs_ses *ses,char *ntlmv2_hash, -const struct nls_table *nls_cp,struct shash_desc *hmacmd5) +const struct nls_table *nls_cp) { -int rc =0 ;int len;char nt_hash[CIFS_NTHASH_SIZE ]; +struct hmac_md5_ctx hmac_ctx;__le16 *user;wchar_t *domain;wchar_t *server;/* calculate md4 hash of password */ E_md4hash (ses->password, nt_hash, nls_cp); - rc =crypto_shash_setkey (hmacmd5->tfm, nt_hash,CIFS_NTHASH_SIZE ); -if (rc) { -cifs_dbg (VFS ,"%s: Could not set NT hash as a key, rc=%d\n" , __func__, rc); -return rc; - } - - rc =crypto_shash_init (hmacmd5); -if (rc) { -cifs_dbg (VFS ,"%s: Could not init HMAC-MD5, rc=%d\n" , __func__, rc); -return rc; - } +hmac_md5_init_usingrawkey (&hmac_ctx, nt_hash,CIFS_NTHASH_SIZE );/* convert ses->user_name to unicode */ len = ses->user_name ?strlen (ses->user_name) :0 ; user =kmalloc (2 + (len *2 ),GFP_KERNEL );if (user ==NULL )
@@ -460,16 +450,12 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,UniStrupr (user); }else { *(u16 *)user =0 ; } - rc =crypto_shash_update (hmacmd5, (char *)user,2 * len); +hmac_md5_update (&hmac_ctx, (const u8 *)user,2 * len);kfree (user); -if (rc) { -cifs_dbg (VFS ,"%s: Could not update with user, rc=%d\n" , __func__, rc); -return rc; - }/* convert ses->domainName to unicode and uppercase */ if (ses->domainName) { len =strlen (ses->domainName);
@@ -477,81 +463,48 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,if (domain ==NULL )return -ENOMEM ; len =cifs_strtoUTF16 ((__le16 *)domain, ses->domainName, len, nls_cp); - rc =crypto_shash_update (hmacmd5, (char *)domain,2 * len); +hmac_md5_update (&hmac_ctx, (const u8 *)domain,2 * len);kfree (domain); -if (rc) { -cifs_dbg (VFS ,"%s: Could not update with domain, rc=%d\n" , __func__, rc); -return rc; - } }else {/* We use ses->ip_addr if no domain name available */ len =strlen (ses->ip_addr); server =kmalloc (2 + (len *2 ),GFP_KERNEL );if (server ==NULL )return -ENOMEM ; len =cifs_strtoUTF16 ((__le16 *)server, ses->ip_addr, len, nls_cp); - rc =crypto_shash_update (hmacmd5, (char *)server,2 * len); +hmac_md5_update (&hmac_ctx, (const u8 *)server,2 * len);kfree (server); -if (rc) { -cifs_dbg (VFS ,"%s: Could not update with server, rc=%d\n" , __func__, rc); -return rc; - } } - rc =crypto_shash_final (hmacmd5, ntlmv2_hash); -if (rc) -cifs_dbg (VFS ,"%s: Could not generate MD5 hash, rc=%d\n" , __func__, rc); - -return rc; +hmac_md5_final (&hmac_ctx, ntlmv2_hash); +return 0 ; } -static int -CalcNTLMv2_response (const struct cifs_ses *ses,char *ntlmv2_hash,struct shash_desc *hmacmd5) +static void CalcNTLMv2_response (const struct cifs_ses *ses,char *ntlmv2_hash) { -int rc;struct ntlmv2_resp *ntlmv2 = (struct ntlmv2_resp *) (ses->auth_key.response +CIFS_SESS_KEY_SIZE );unsigned int hash_len;/* The MD5 hash starts at challenge_key.key */ hash_len = ses->auth_key.len - (CIFS_SESS_KEY_SIZE + offsetof(struct ntlmv2_resp, challenge.key[0])); - rc =crypto_shash_setkey (hmacmd5->tfm, ntlmv2_hash,CIFS_HMAC_MD5_HASH_SIZE ); -if (rc) { -cifs_dbg (VFS ,"%s: Could not set NTLMv2 hash as a key, rc=%d\n" , __func__, rc); -return rc; - } - - rc =crypto_shash_init (hmacmd5); -if (rc) { -cifs_dbg (VFS ,"%s: Could not init HMAC-MD5, rc=%d\n" , __func__, rc); -return rc; - } -if (ses->server->negflavor ==CIFS_NEGFLAVOR_EXTENDED )memcpy (ntlmv2->challenge.key, ses->ntlmssp->cryptkey,CIFS_SERVER_CHALLENGE_SIZE );else memcpy (ntlmv2->challenge.key, ses->server->cryptkey,CIFS_SERVER_CHALLENGE_SIZE ); - rc =crypto_shash_update (hmacmd5, ntlmv2->challenge.key, hash_len); -if (rc) { -cifs_dbg (VFS ,"%s: Could not update with response, rc=%d\n" , __func__, rc); -return rc; - } - -/* Note that the MD5 digest over writes anon.challenge_key.key */ - rc =crypto_shash_final (hmacmd5, ntlmv2->ntlmv2_hash); -if (rc) -cifs_dbg (VFS ,"%s: Could not generate MD5 hash, rc=%d\n" , __func__, rc); - -return rc; +/* Note that the HMAC-MD5 value overwrites ntlmv2->challenge.key */ +hmac_md5_usingrawkey (ntlmv2_hash,CIFS_HMAC_MD5_HASH_SIZE , + ntlmv2->challenge.key, hash_len, + ntlmv2->ntlmv2_hash); }/* * Set up NTLMv2 response blob with SPN (cifs/<hostname>) appended to the * existing list of AV pairs.
@@ -604,11 +557,10 @@ static int set_auth_key_response(struct cifs_ses *ses) }int setup_ntlmv2_rsp (struct cifs_ses *ses,const struct nls_table *nls_cp) { -struct shash_desc *hmacmd5 =NULL ;unsigned char *tiblob =NULL ;/* target info blob */ struct ntlmv2_resp *ntlmv2;char ntlmv2_hash[16 ];__le64 rsp_timestamp;__u64 cc;
@@ -675,55 +627,33 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) ntlmv2->reserved =0 ; ntlmv2->time = rsp_timestamp; ntlmv2->client_chal = cc; ntlmv2->reserved2 =0 ; - rc =cifs_alloc_hash ("hmac(md5)" , &hmacmd5); -if (rc) { -cifs_dbg (VFS ,"Could not allocate HMAC-MD5, rc=%d\n" , rc); +if (fips_enabled) { +cifs_dbg (VFS ,"NTLMv2 support is disabled due to FIPS\n" ); + rc = -EOPNOTSUPP ; goto unlock; }/* calculate ntlmv2_hash */ - rc =calc_ntlmv2_hash (ses, ntlmv2_hash, nls_cp, hmacmd5); + rc =calc_ntlmv2_hash (ses, ntlmv2_hash, nls_cp);if (rc) {cifs_dbg (VFS ,"Could not get NTLMv2 hash, rc=%d\n" , rc); goto unlock; }/* calculate first part of the client response (CR1) */ - rc =CalcNTLMv2_response (ses, ntlmv2_hash, hmacmd5); -if (rc) { -cifs_dbg (VFS ,"Could not calculate CR1, rc=%d\n" , rc); - goto unlock; - } +CalcNTLMv2_response (ses, ntlmv2_hash);/* now calculate the session key for NTLMv2 */ - rc =crypto_shash_setkey (hmacmd5->tfm, ntlmv2_hash,CIFS_HMAC_MD5_HASH_SIZE ); -if (rc) { -cifs_dbg (VFS ,"%s: Could not set NTLMv2 hash as a key, rc=%d\n" , __func__, rc); - goto unlock; - } - - rc =crypto_shash_init (hmacmd5); -if (rc) { -cifs_dbg (VFS ,"%s: Could not init HMAC-MD5, rc=%d\n" , __func__, rc); - goto unlock; - } - - rc =crypto_shash_update (hmacmd5, ntlmv2->ntlmv2_hash,CIFS_HMAC_MD5_HASH_SIZE ); -if (rc) { -cifs_dbg (VFS ,"%s: Could not update with response, rc=%d\n" , __func__, rc); - goto unlock; - } - - rc =crypto_shash_final (hmacmd5, ses->auth_key.response); -if (rc) -cifs_dbg (VFS ,"%s: Could not generate MD5 hash, rc=%d\n" , __func__, rc); +hmac_md5_usingrawkey (ntlmv2_hash,CIFS_HMAC_MD5_HASH_SIZE , + ntlmv2->ntlmv2_hash,CIFS_HMAC_MD5_HASH_SIZE , + ses->auth_key.response); + rc =0 ; unlock:cifs_server_unlock (ses->server); -cifs_free_hash (&hmacmd5); setup_ntlmv2_rsp_ret:kfree_sensitive (tiblob);return rc; }
Signature · 1 line
2.51.0
PATCH 7/8 smb: client: Remove obsolete crypto_shash allocations
In reply to Eric BiggersNow that the SMB client accesses MD5, HMAC-MD5, HMAC-SHA256, and SHA-512 only via the library API and not via crypto_shash, allocating crypto_shash objects for these algorithms is no longer necessary. Remove all these allocations, their corresponding kconfig selections, and their corresponding module soft dependencies.
--- fs/smb/client/Kconfig | 4 ---- fs/smb/client/cifsencrypt.c | 3 --- fs/smb/client/cifsfs.c | 4 ---- fs/smb/client/cifsglob.h | 3 --- fs/smb/client/smb2transport.c | 35 ++--------------------------------- 5 files changed, 2 insertions(+), 47 deletions(-)
fs/smb/client/Kconfig +0 -4
@@ -3,15 +3,11 @@ config CIFS tristate "SMB3 and CIFS support (advanced network filesystem)" depends on INET select NLS select NLS_UCS2_UTILS select CRYPTO - select CRYPTO_MD5 - select CRYPTO_SHA256 - select CRYPTO_SHA512 select CRYPTO_CMAC - select CRYPTO_HMAC select CRYPTO_AEAD2 select CRYPTO_CCM select CRYPTO_GCM select CRYPTO_ECB select CRYPTO_AES
fs/smb/client/cifsencrypt.c +0 -3
@@ -691,13 +691,10 @@ calc_seckey(struct cifs_ses *ses)void cifs_crypto_secmech_release (struct TCP_Server_Info *server) {cifs_free_hash (&server->secmech.aes_cmac); -cifs_free_hash (&server->secmech.hmacsha256); -cifs_free_hash (&server->secmech.md5); -cifs_free_hash (&server->secmech.sha512);if (server->secmech.enc) {crypto_free_aead (server->secmech.enc); server->secmech.enc =NULL ; }
fs/smb/client/cifsfs.c +0 -4
@@ -2137,17 +2137,13 @@ MODULE_LICENSE("GPL"); /* combination of LGPL + GPL source behaves as GPL */MODULE_DESCRIPTION ("VFS to access SMB3 servers e.g. Samba, Macs, Azure and Windows (and " "also older servers complying with the SNIA CIFS Specification)" );MODULE_VERSION (CIFS_VERSION );MODULE_SOFTDEP ("ecb" ); -MODULE_SOFTDEP ("hmac" ); -MODULE_SOFTDEP ("md5" );MODULE_SOFTDEP ("nls" );MODULE_SOFTDEP ("aes" );MODULE_SOFTDEP ("cmac" ); -MODULE_SOFTDEP ("sha256" ); -MODULE_SOFTDEP ("sha512" );MODULE_SOFTDEP ("aead2" );MODULE_SOFTDEP ("ccm" );MODULE_SOFTDEP ("gcm" );module_init (init_cifs)module_exit (exit_cifs)
fs/smb/client/cifsglob.h +0 -3
@@ -219,13 +219,10 @@ struct session_key {char *response; };/* crypto hashing related structure/fields, not specific to a sec mech */ struct cifs_secmech { -struct shash_desc *md5;/* md5 hash function, for CIFS/SMB1 signatures */ -struct shash_desc *hmacsha256;/* hmac-sha256 hash function, for SMB2 signatures */ -struct shash_desc *sha512;/* sha512 hash function, for SMB3.1.1 preauth hash */ struct shash_desc *aes_cmac;/* block-cipher based MAC function, for SMB3 signatures */ struct crypto_aead *enc;/* smb3 encryption AEAD TFM (AES-CCM and AES-GCM) */ struct crypto_aead *dec;/* smb3 decryption AEAD TFM (AES-CCM and AES-GCM) */ };
fs/smb/client/smb2transport.c +2 -33
@@ -29,53 +29,22 @@static int smb3_crypto_shash_allocate (struct TCP_Server_Info *server) {struct cifs_secmech *p = &server->secmech; -int rc; - - rc =cifs_alloc_hash ("hmac(sha256)" , &p->hmacsha256); -if (rc) - goto err; - - rc =cifs_alloc_hash ("cmac(aes)" , &p->aes_cmac); -if (rc) - goto err; -return 0 ; -err: -cifs_free_hash (&p->hmacsha256); -return rc; +return cifs_alloc_hash ("cmac(aes)" , &p->aes_cmac); }int smb311_crypto_shash_allocate (struct TCP_Server_Info *server) {struct cifs_secmech *p = &server->secmech; -int rc =0 ; - rc =cifs_alloc_hash ("hmac(sha256)" , &p->hmacsha256); -if (rc) -return rc; - - rc =cifs_alloc_hash ("cmac(aes)" , &p->aes_cmac); -if (rc) - goto err; - - rc =cifs_alloc_hash ("sha512" , &p->sha512); -if (rc) - goto err; - -return 0 ; - -err: -cifs_free_hash (&p->aes_cmac); -cifs_free_hash (&p->hmacsha256); -return rc; +return cifs_alloc_hash ("cmac(aes)" , &p->aes_cmac); } -static int smb3_get_sign_key (__u64 ses_id,struct TCP_Server_Info *server,u8 *key) {struct cifs_chan *chan;struct TCP_Server_Info *pserver;
Signature · 1 line
2.51.0
PATCH 8/8 smb: client: Consolidate cmac(aes) shash allocation
In reply to Eric BiggersNow that smb3_crypto_shash_allocate() and smb311_crypto_shash_allocate() are identical and only allocate "cmac(aes)", delete the latter and replace the call to it with the former.
--- fs/smb/client/sess.c | 2 +- fs/smb/client/smb2proto.h | 2 +- fs/smb/client/smb2transport.c | 10 +--------- 3 files changed, 3 insertions(+), 11 deletions(-)
fs/smb/client/sess.c +1 -1
@@ -582,11 +582,11 @@ cifs_ses_add_channel(struct cifs_ses *ses,/* * We need to allocate the server crypto now as we will need * to sign packets before we generate the channel signing key * (we sign with the session key) */ - rc =smb311_crypto_shash_allocate (chan->server); + rc =smb3_crypto_shash_allocate (chan->server);if (rc) {cifs_dbg (VFS ,"%s: crypto alloc failed\n" , __func__);mutex_unlock (&ses->session_mutex); goto out; }
fs/smb/client/smb2proto.h +1 -1
@@ -293,11 +293,11 @@ extern int smb2_validate_and_copy_iov(unsigned int offset,struct kvec *iov, unsigned int minbufsize, char *data);extern void smb2_copy_fs_info_to_kstatfs (struct smb2_fs_full_size_info *pfs_inf,struct kstatfs *kst); -extern int smb311_crypto_shash_allocate (struct TCP_Server_Info *server); +extern int smb3_crypto_shash_allocate (struct TCP_Server_Info *server);extern void smb311_update_preauth_hash (struct cifs_ses *ses,struct TCP_Server_Info *server,struct kvec *iov,int nvec); extern int smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
fs/smb/client/smb2transport.c +1 -9
@@ -25,20 +25,12 @@#include "smb2proto.h" #include "cifs_debug.h" #include "../common/smb2status.h" #include "smb2glob.h" -static int -smb3_crypto_shash_allocate (struct TCP_Server_Info *server) -{ -struct cifs_secmech *p = &server->secmech; - -return cifs_alloc_hash ("cmac(aes)" , &p->aes_cmac); -} -int -smb311_crypto_shash_allocate (struct TCP_Server_Info *server) +smb3_crypto_shash_allocate (struct TCP_Server_Info *server) {struct cifs_secmech *p = &server->secmech;return cifs_alloc_hash ("cmac(aes)" , &p->aes_cmac); }
Signature · 1 line
2.51.0
Hi Eric,
Quoted 11 lines · Eric Biggers
This series converts
fs/smb/client/to access SHA-512, HMAC-SHA256, MD5, and HMAC-MD5 using the library APIs instead ofcrypto_shash.This simplifies the code significantly. It also slightly improves performance, as it eliminates unnecessary overhead.
Tested with Samba with all SMB versions, with mfsymlinks in the mount options, 'server min protocol = NT1' and 'server signing = required' in smb.conf, and doing a simple file data and symlink verification test. That seems to cover all the modified code paths.
Quoted 7 lines
However, with SMB 1.0 I get "CIFS: VFS: SMB signature verification returned error = -13", regardless of whether this series is applied or not. Presumably, testing that case requires some other setting I couldn't find.
Regardless, these are straightforward conversions and all the actual crypto is exactly the same as before, as far as I can tell.
I think the overall series looks good and do a great cleanup.
Just a minor nit about fips_enabled: since it's now being handled explicitly (rather than an error on cifs_alloc_hash() currently), I think it makes sense to move the check to mount code path when 'sectype == NTLMv2' (I don't particularly care about SMB1, but something similar can be done for 'smb1 && sign' cases I guess).
Quoted 23 lines
Eric Biggers (8):
smb: client: Use SHA-512 library for SMB3.1.1 preauth hash
smb: client: Use HMAC-SHA256 library for key generation
smb: client: Use HMAC-SHA256 library for SMB2 signature calculation
smb: client: Use MD5 library for M-F symlink hashing
smb: client: Use MD5 library for SMB1 signature calculation
smb: client: Use HMAC-MD5 library for NTLMv2
smb: client: Remove obsoletecrypto_shashallocations
smb: client: Consolidate cmac(aes) shash allocationfs/smb/client/Kconfig | 7 +- fs/smb/client/cifsencrypt.c | 201 +++++++++++++--------------------- fs/smb/client/cifsfs.c | 4 - fs/smb/client/cifsglob.h | 3 - fs/smb/client/cifsproto.h | 10 +- fs/smb/client/link.c | 31 +----- fs/smb/client/sess.c | 2 +- fs/smb/client/smb2misc.c | 53 ++------- fs/smb/client/smb2proto.h | 8 +- fs/smb/client/smb2transport.c | 164 +++++---------------------- 10 files changed, 131 insertions(+), 352 deletions(-)
Quoted 3 lines
base-commit:
67029a49db6c1f21106a1b5fcdd0ea234a6e0711Signature · 1 line
2.51.0
Cheers,
Enzo
Quoted 22 lines · Enzo Matsumiya
Hi Eric,
Quoted 11 lines · Eric Biggers
This series converts
fs/smb/client/to access SHA-512, HMAC-SHA256, MD5, and HMAC-MD5 using the library APIs instead ofcrypto_shash.This simplifies the code significantly. It also slightly improves performance, as it eliminates unnecessary overhead.
Tested with Samba with all SMB versions, with mfsymlinks in the mount options, 'server min protocol = NT1' and 'server signing = required' in smb.conf, and doing a simple file data and symlink verification test. That seems to cover all the modified code paths.
Quoted 7 lines
However, with SMB 1.0 I get "CIFS: VFS: SMB signature verification returned error = -13", regardless of whether this series is applied or not. Presumably, testing that case requires some other setting I couldn't find.
Regardless, these are straightforward conversions and all the actual crypto is exactly the same as before, as far as I can tell.
Quoted 7 lines
I think the overall series looks good and do a great cleanup.
Just a minor nit about
fips_enabled: since it's now being handled explicitly (rather than an error oncifs_alloc_hash()currently), I think it makes sense to move the check to mount code path when 'sectype == NTLMv2' (I don't particularly care about SMB1, but something similar can be done for 'smb1 && sign' cases I guess).
For MD5 message signing and NTLMv2, this series keeps the fips_enabled checks where they were before. That is, they're inserted where the calls to cifs_alloc_hash() were before. I think moving them to earlier locations is best done in later patches, as it's not obvious (at least to me) exactly how to do that.
I spent a while reading the code again, and this is what I came up with:
- For MD5 message signing: cifs_enable_signing() is probably the right place to disallow it. However, it's called regardless of the signing algorithm. So it needs a parameter passed in that tells it that the signing algorithm will be MD5 (or equivalently the dialect is SMB1).
- For NTLMv2: select_sec() and SMB2_select_sec() are where the authentication protocol is selected and are probably the right places to disallow NTLMv2 and RawNTLMSSP. However, those are two places, not one. We'd have to remember to put the fips_enabled check in both.
The nice thing about keeping the fips_enabled checks next to the actual uses of the algorithms is that it ensures they stay in sync. So maybe we should just stay with that here.
- Eric
Quoted 19 lines · Eric Biggers
This series converts
fs/smb/client/to access SHA-512, HMAC-SHA256, MD5, and HMAC-MD5 using the library APIs instead ofcrypto_shash.This simplifies the code significantly. It also slightly improves performance, as it eliminates unnecessary overhead.
Tested with Samba with all SMB versions, with mfsymlinks in the mount options, 'server min protocol = NT1' and 'server signing = required' in smb.conf, and doing a simple file data and symlink verification test. That seems to cover all the modified code paths.
However, with SMB 1.0 I get "CIFS: VFS: SMB signature verification returned error = -13", regardless of whether this series is applied or not. Presumably, testing that case requires some other setting I couldn't find.
Regardless, these are straightforward conversions and all the actual crypto is exactly the same as before, as far as I can tell.
Quoted 9 lines
Eric Biggers (8):
smb: client: Use SHA-512 library for SMB3.1.1 preauth hash
smb: client: Use HMAC-SHA256 library for key generation
smb: client: Use HMAC-SHA256 library for SMB2 signature calculation
smb: client: Use MD5 library for M-F symlink hashing
smb: client: Use MD5 library for SMB1 signature calculation
smb: client: Use HMAC-MD5 library for NTLMv2
smb: client: Remove obsoletecrypto_shashallocations
smb: client: Consolidate cmac(aes) shash allocation
As requested off-list, here are some (micro)benchmark results for this series. The CPU was AMD Ryzen 9 9950X. The server was Samba running on localhost. Message signing was enabled. A valid username and password were given in the mount options. The "Improvement" column is the percent change in throughput (reciprocal cycles):
Microbenchmark Before After Improvement
============== ====== ===== =========== 1. Total cycles spent in 44548 20081 122%
smb311_update_preauth_hash()
during SMB 3.1.1 mount
(4 calls total)
2. setup_ntlmv2_rsp() cycles 31777 22231 43%
3. Total cycles spent in 17802 22876 -22%
generate_key()
during SMB 3.1.1 mount
(3 calls total)
4. Total cycles spent in 205110 87204 135%
smb2_calc_signature()
during SMB 2.0 mount
(26 calls & 3316 bytes total)
5. Total cycles spent in 22689767 21043125 8%
smb2_calc_signature()
reading 10MB file using SMB 2.0
(316 calls & 10031077 bytes total)
6. Total cycles spent in 56803 37840 50%
cifs_calc_signature()
during SMB 1.0 mount
(18 calls & 1551 bytes total)
7. Total cycles spent in 52669066 51974573 1%
cifs_calc_signature()
reading 10MB file using SMB 1.0
(336 calls & 10021426 bytes total)
8. parse_mf_symlink() cycles 7654 4902 56%
Note: case 3 regressed because the "cmac(aes)" allocation moved from smb311_update_preauth_hash (case 1) to generate_key (case 3). Excluding that allocation, generate_key got faster. Likewise, the sum of cases 1, 2, and 3 (which all occurred at mount time) got faster.
There was a greater speedup in signature calculation than I expected. It's probably because many SMB messages are short (especially the ones exchanged at mount time), and also because the old code allocated new crypto_shash objects more frequently than I had thought. The SMB 2.0 code allocated a new "hmac(sha256)" crypto_shash for every other message signed. That overhead is all gone after switching to the library.
TLDR: all SMB crypto calculations (SHA-512, HMAC-SHA256, MD5, HMAC-MD5) affected by this series are faster now. The library APIs fix the unnecessary overhead that the traditional crypto API has. Of course, it's also a lot easier to use as well.
- Eric
Quoted 2 lines
with SMB 1.0 I get "CIFS: VFS: SMB signature verification returned error = -13",
If testing SMB1 to Samba the server disabled signing unless I set
"server signing = mandatory"
in smb.conf. But with that, signing with your patches worked fine even to SMB1
Were you testing to Samba with SMB1?
Quoted 93 lines · Eric Biggers
Quoted 19 lines · Eric Biggers
This series converts
fs/smb/client/to access SHA-512, HMAC-SHA256, MD5, and HMAC-MD5 using the library APIs instead ofcrypto_shash.This simplifies the code significantly. It also slightly improves performance, as it eliminates unnecessary overhead.
Tested with Samba with all SMB versions, with mfsymlinks in the mount options, 'server min protocol = NT1' and 'server signing = required' in smb.conf, and doing a simple file data and symlink verification test. That seems to cover all the modified code paths.
However, with SMB 1.0 I get "CIFS: VFS: SMB signature verification returned error = -13", regardless of whether this series is applied or not. Presumably, testing that case requires some other setting I couldn't find.
Regardless, these are straightforward conversions and all the actual crypto is exactly the same as before, as far as I can tell.
Quoted 9 lines
Eric Biggers (8):
smb: client: Use SHA-512 library for SMB3.1.1 preauth hash
smb: client: Use HMAC-SHA256 library for key generation
smb: client: Use HMAC-SHA256 library for SMB2 signature calculation
smb: client: Use MD5 library for M-F symlink hashing
smb: client: Use MD5 library for SMB1 signature calculation
smb: client: Use HMAC-MD5 library for NTLMv2
smb: client: Remove obsoletecrypto_shashallocations
smb: client: Consolidate cmac(aes) shash allocationAs requested off-list, here are some (micro)benchmark results for this series. The CPU was AMD Ryzen 9 9950X. The server was Samba running on localhost. Message signing was enabled. A valid username and password were given in the mount options. The "Improvement" column is the percent change in throughput (reciprocal cycles):
Microbenchmark Before After Improvement ============== ====== ===== ===========1. Total cycles spent in 44548 20081 122%
smb311_update_preauth_hash()
during SMB 3.1.1 mount
(4 calls total)2.
setup_ntlmv2_rsp()cycles 31777 22231 43%3. Total cycles spent in 17802 22876 -22%
generate_key()
during SMB 3.1.1 mount
(3 calls total)4. Total cycles spent in 205110 87204 135%
smb2_calc_signature()
during SMB 2.0 mount
(26 calls & 3316 bytes total)5. Total cycles spent in 22689767 21043125 8%
smb2_calc_signature()
reading 10MB file using SMB 2.0
(316 calls & 10031077 bytes total)6. Total cycles spent in 56803 37840 50%
cifs_calc_signature()
during SMB 1.0 mount
(18 calls & 1551 bytes total)7. Total cycles spent in 52669066 51974573 1%
cifs_calc_signature()
reading 10MB file using SMB 1.0
(336 calls & 10021426 bytes total)8.
parse_mf_symlink()cycles 7654 4902 56%Note: case 3 regressed because the "cmac(aes)" allocation moved from
smb311_update_preauth_hash(case 1) togenerate_key(case 3). Excluding that allocation,generate_keygot faster. Likewise, the sum of cases 1, 2, and 3 (which all occurred at mount time) got faster.There was a greater speedup in signature calculation than I expected. It's probably because many SMB messages are short (especially the ones exchanged at mount time), and also because the old code allocated new
crypto_shashobjects more frequently than I had thought. The SMB 2.0 code allocated a new "hmac(sha256)"crypto_shashfor every other message signed. That overhead is all gone after switching to the library.TLDR: all SMB crypto calculations (SHA-512, HMAC-SHA256, MD5, HMAC-MD5) affected by this series are faster now. The library APIs fix the unnecessary overhead that the traditional crypto API has. Of course, it's also a lot easier to use as well.
- Eric
Signature · 3 lines
Thanks, Steve
Quoted 8 lines · Steve French
Quoted 2 lines
with SMB 1.0 I get "CIFS: VFS: SMB signature verification returned error = -13",
If testing SMB1 to Samba the server disabled signing unless I set
"server signing = mandatory"
in smb.conf. But with that, signing with your patches worked fine even to SMB1Were you testing to Samba with SMB1?
As per my cover letter, these are the settings I used:
Tested with Samba with all SMB versions, with mfsymlinks in the mount options, 'server min protocol = NT1' and 'server signing = required' in smb.conf, and doing a simple file data and symlink verification test. That seems to cover all the modified code paths.
This was with Samba 4.23.1.
I just tried 'server signing = mandatory' too (just in case that's different from "required"), and I still get the error.
Anyway, it's not related to my patchset, as it happens regardless of it. I also tried some much older kernels, and it still happens there too.
- Eric
Quoted 20 lines · Eric Biggers
This series converts
fs/smb/client/to access SHA-512, HMAC-SHA256, MD5, and HMAC-MD5 using the library APIs instead ofcrypto_shash.This simplifies the code significantly. It also slightly improves performance, as it eliminates unnecessary overhead.
Tested with Samba with all SMB versions, with mfsymlinks in the mount options, 'server min protocol = NT1' and 'server signing = required' in smb.conf, and doing a simple file data and symlink verification test. That seems to cover all the modified code paths.
However, with SMB 1.0 I get "CIFS: VFS: SMB signature verification returned error = -13", regardless of whether this series is applied or not. Presumably, testing that case requires some other setting I couldn't find.
Regardless, these are straightforward conversions and all the actual crypto is exactly the same as before, as far as I can tell.
Quoted 10 lines
Eric Biggers (8):
smb: client: Use SHA-512 library for SMB3.1.1 preauth hash
smb: client: Use HMAC-SHA256 library for key generation
smb: client: Use HMAC-SHA256 library for SMB2 signature calculation
smb: client: Use MD5 library for M-F symlink hashing
smb: client: Use MD5 library for SMB1 signature calculation
smb: client: Use HMAC-MD5 library for NTLMv2
smb: client: Remove obsoletecrypto_shashallocations
smb: client: Consolidate cmac(aes) shash allocation