smb3.1.1: set gcm256 when requested
authorSteve French <stfrench@microsoft.com>
Fri, 16 Oct 2020 04:41:40 +0000 (23:41 -0500)
committerSteve French <stfrench@microsoft.com>
Mon, 19 Oct 2020 20:11:11 +0000 (15:11 -0500)
update smb encryption code to set 32 byte key length and to
set gcm256 when requested on mount.

Signed-off-by: Steve French <stfrench@microsoft.com>
fs/cifs/smb2glob.h
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.h
fs/cifs/smb2transport.c

index cf20f0b5d8363dd0f2dfe9214db091fe3486268c..99a1951a01ec27e78a91f4f330bb14da0b7a2b9c 100644 (file)
@@ -58,6 +58,7 @@
 #define SMB2_HMACSHA256_SIZE (32)
 #define SMB2_CMACAES_SIZE (16)
 #define SMB3_SIGNKEY_SIZE (16)
+#define SMB3_GCM256_CRYPTKEY_SIZE (32)
 
 /* Maximum buffer size value we can send with 1 credit */
 #define SMB2_MAX_BUFFER_SIZE 65536
index dd1edabec328bd13377281d3678c2d5a2a5af412..48657ddbd75e689c20fc05034f2c13ea0870e11e 100644 (file)
@@ -3820,7 +3820,8 @@ fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int orig_len,
        tr_hdr->ProtocolId = SMB2_TRANSFORM_PROTO_NUM;
        tr_hdr->OriginalMessageSize = cpu_to_le32(orig_len);
        tr_hdr->Flags = cpu_to_le16(0x01);
-       if (cipher_type == SMB2_ENCRYPTION_AES128_GCM)
+       if ((cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
+           (cipher_type == SMB2_ENCRYPTION_AES256_GCM))
                get_random_bytes(&tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
        else
                get_random_bytes(&tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
@@ -3954,7 +3955,12 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
 
        tfm = enc ? server->secmech.ccmaesencrypt :
                                                server->secmech.ccmaesdecrypt;
-       rc = crypto_aead_setkey(tfm, key, SMB3_SIGN_KEY_SIZE);
+
+       if (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
+               rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
+       else
+               rc = crypto_aead_setkey(tfm, key, SMB3_SIGN_KEY_SIZE);
+
        if (rc) {
                cifs_server_dbg(VFS, "%s: Failed to set aead key %d\n", __func__, rc);
                return rc;
@@ -3992,7 +3998,8 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
                goto free_sg;
        }
 
-       if (server->cipher_type == SMB2_ENCRYPTION_AES128_GCM)
+       if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
+           (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
                memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
        else {
                iv[0] = 3;
index 05b010e5a06111f546d12b89381c9c451106376b..851c6cd4742ac4bcffd3d018c08ccf923aba830b 100644 (file)
@@ -352,6 +352,7 @@ struct smb2_preauth_neg_context {
 /* Encryption Algorithms Ciphers */
 #define SMB2_ENCRYPTION_AES128_CCM     cpu_to_le16(0x0001)
 #define SMB2_ENCRYPTION_AES128_GCM     cpu_to_le16(0x0002)
+/* we currently do not request AES256_CCM since presumably GCM faster */
 #define SMB2_ENCRYPTION_AES256_CCM      cpu_to_le16(0x0003)
 #define SMB2_ENCRYPTION_AES256_GCM      cpu_to_le16(0x0004)
 
index c0348e3b1695828f0178c55d52bd4024b0e8b474..ebccd71cc60a3887f398829897cfc4c1956bfa91 100644 (file)
@@ -849,12 +849,13 @@ smb3_crypto_aead_allocate(struct TCP_Server_Info *server)
        struct crypto_aead *tfm;
 
        if (!server->secmech.ccmaesencrypt) {
-               if (server->cipher_type == SMB2_ENCRYPTION_AES128_GCM)
+               if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
+                   (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
                        tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
                else
                        tfm = crypto_alloc_aead("ccm(aes)", 0, 0);
                if (IS_ERR(tfm)) {
-                       cifs_server_dbg(VFS, "%s: Failed to alloc encrypt aead\n",
+                       cifs_server_dbg(VFS, "%s: Failed alloc encrypt aead\n",
                                 __func__);
                        return PTR_ERR(tfm);
                }
@@ -862,7 +863,8 @@ smb3_crypto_aead_allocate(struct TCP_Server_Info *server)
        }
 
        if (!server->secmech.ccmaesdecrypt) {
-               if (server->cipher_type == SMB2_ENCRYPTION_AES128_GCM)
+               if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
+                   (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
                        tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
                else
                        tfm = crypto_alloc_aead("ccm(aes)", 0, 0);