Commit 220d83b5 authored by Enzo Matsumiya's avatar Enzo Matsumiya Committed by Steve French

smb: client: make SHA-512 TFM ephemeral

The SHA-512 shash TFM is used only briefly during Session Setup stage,
when computing SMB 3.1.1 preauth hash.

There's no need to keep it allocated in servers' secmech the whole time,
so keep its lifetime inside smb311_update_preauth_hash().

This also makes smb311_crypto_shash_allocate() redundant, so expose
smb3_crypto_shash_allocate() and use that.
Signed-off-by: default avatarEnzo Matsumiya <ematsumiya@suse.de>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent db44ca9f
...@@ -700,7 +700,6 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server) ...@@ -700,7 +700,6 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server)
cifs_free_hash(&server->secmech.aes_cmac); cifs_free_hash(&server->secmech.aes_cmac);
cifs_free_hash(&server->secmech.hmacsha256); cifs_free_hash(&server->secmech.hmacsha256);
cifs_free_hash(&server->secmech.md5); cifs_free_hash(&server->secmech.md5);
cifs_free_hash(&server->secmech.sha512);
if (!SERVER_IS_CHAN(server)) { if (!SERVER_IS_CHAN(server)) {
if (server->secmech.enc) { if (server->secmech.enc) {
......
...@@ -180,7 +180,6 @@ struct session_key { ...@@ -180,7 +180,6 @@ struct session_key {
struct cifs_secmech { struct cifs_secmech {
struct shash_desc *md5; /* md5 hash function, for CIFS/SMB1 signatures */ 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 *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 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 *enc; /* smb3 encryption AEAD TFM (AES-CCM and AES-GCM) */
......
...@@ -624,7 +624,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, ...@@ -624,7 +624,7 @@ cifs_ses_add_channel(struct cifs_ses *ses,
* to sign packets before we generate the channel signing key * to sign packets before we generate the channel signing key
* (we sign with the session key) * (we sign with the session key)
*/ */
rc = smb311_crypto_shash_allocate(chan->server); rc = smb3_crypto_shash_allocate(chan->server);
if (rc) { if (rc) {
cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__); cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
mutex_unlock(&ses->session_mutex); mutex_unlock(&ses->session_mutex);
......
...@@ -906,41 +906,41 @@ smb311_update_preauth_hash(struct cifs_ses *ses, struct TCP_Server_Info *server, ...@@ -906,41 +906,41 @@ smb311_update_preauth_hash(struct cifs_ses *ses, struct TCP_Server_Info *server,
|| (hdr->Status != || (hdr->Status !=
cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED)))) cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))))
return 0; return 0;
ok: ok:
rc = smb311_crypto_shash_allocate(server); rc = cifs_alloc_hash("sha512", &sha512);
if (rc) if (rc) {
cifs_dbg(VFS, "%s: Could not allocate SHA512 shash, rc=%d\n", __func__, rc);
return rc; return rc;
}
sha512 = server->secmech.sha512;
rc = crypto_shash_init(sha512); rc = crypto_shash_init(sha512);
if (rc) { if (rc) {
cifs_dbg(VFS, "%s: Could not init sha512 shash\n", __func__); cifs_dbg(VFS, "%s: Could not init SHA512 shash, rc=%d\n", __func__, rc);
return rc; goto err_free;
} }
rc = crypto_shash_update(sha512, ses->preauth_sha_hash, rc = crypto_shash_update(sha512, ses->preauth_sha_hash,
SMB2_PREAUTH_HASH_SIZE); SMB2_PREAUTH_HASH_SIZE);
if (rc) { if (rc) {
cifs_dbg(VFS, "%s: Could not update sha512 shash\n", __func__); cifs_dbg(VFS, "%s: Could not update SHA512 shash, rc=%d\n", __func__, rc);
return rc; goto err_free;
} }
for (i = 0; i < nvec; i++) { for (i = 0; i < nvec; i++) {
rc = crypto_shash_update(sha512, iov[i].iov_base, iov[i].iov_len); rc = crypto_shash_update(sha512, iov[i].iov_base, iov[i].iov_len);
if (rc) { if (rc) {
cifs_dbg(VFS, "%s: Could not update sha512 shash\n", cifs_dbg(VFS, "%s: Could not update SHA512 shash, rc=%d\n", __func__, rc);
__func__); goto err_free;
return rc;
} }
} }
rc = crypto_shash_final(sha512, ses->preauth_sha_hash); rc = crypto_shash_final(sha512, ses->preauth_sha_hash);
if (rc) { if (rc) {
cifs_dbg(VFS, "%s: Could not finalize sha512 shash\n", cifs_dbg(VFS, "%s: Could not finalize SHA12 shash, rc=%d\n", __func__, rc);
__func__); goto err_free;
return rc;
} }
err_free:
cifs_free_hash(&sha512);
return 0; return 0;
} }
...@@ -291,7 +291,7 @@ extern int smb2_validate_and_copy_iov(unsigned int offset, ...@@ -291,7 +291,7 @@ extern int smb2_validate_and_copy_iov(unsigned int offset,
extern void smb2_copy_fs_info_to_kstatfs( extern void smb2_copy_fs_info_to_kstatfs(
struct smb2_fs_full_size_info *pfs_inf, struct smb2_fs_full_size_info *pfs_inf,
struct kstatfs *kst); 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 int smb311_update_preauth_hash(struct cifs_ses *ses, extern int smb311_update_preauth_hash(struct cifs_ses *ses,
struct TCP_Server_Info *server, struct TCP_Server_Info *server,
struct kvec *iov, int nvec); struct kvec *iov, int nvec);
......
...@@ -26,8 +26,7 @@ ...@@ -26,8 +26,7 @@
#include "../common/smb2status.h" #include "../common/smb2status.h"
#include "smb2glob.h" #include "smb2glob.h"
static int int smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
{ {
struct cifs_secmech *p = &server->secmech; struct cifs_secmech *p = &server->secmech;
int rc; int rc;
...@@ -46,33 +45,6 @@ smb3_crypto_shash_allocate(struct TCP_Server_Info *server) ...@@ -46,33 +45,6 @@ smb3_crypto_shash_allocate(struct TCP_Server_Info *server)
return rc; return rc;
} }
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;
}
static static
int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key) int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment