Skip to content

Commit 45a4546

Browse files
sprasad-microsoftsmfrench
authored andcommitted
cifs: Adjust key sizes and key generation routines for AES256 encryption
For AES256 encryption (GCM and CCM), we need to adjust the size of a few fields to 32 bytes instead of 16 to accommodate the larger keys. Also, the L value supplied to the key generator needs to be changed from to 256 when these algorithms are used. Keeping the ioctl struct for dumping keys of the same size for now. Will send out a different patch for that one. Signed-off-by: Shyam Prasad N <[email protected]> Reviewed-by: Ronnie Sahlberg <[email protected]> CC: <[email protected]> # v5.10+ Signed-off-by: Steve French <[email protected]>
1 parent 0d02ec6 commit 45a4546

File tree

5 files changed

+41
-15
lines changed

5 files changed

+41
-15
lines changed

fs/cifs/cifsglob.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -919,8 +919,8 @@ struct cifs_ses {
919919
bool binding:1; /* are we binding the session? */
920920
__u16 session_flags;
921921
__u8 smb3signingkey[SMB3_SIGN_KEY_SIZE];
922-
__u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE];
923-
__u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE];
922+
__u8 smb3encryptionkey[SMB3_ENC_DEC_KEY_SIZE];
923+
__u8 smb3decryptionkey[SMB3_ENC_DEC_KEY_SIZE];
924924
__u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE];
925925

926926
__u8 binding_preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE];

fs/cifs/cifspdu.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@
147147
*/
148148
#define SMB3_SIGN_KEY_SIZE (16)
149149

150+
/*
151+
* Size of the smb3 encryption/decryption keys
152+
*/
153+
#define SMB3_ENC_DEC_KEY_SIZE (32)
154+
150155
#define CIFS_CLIENT_CHALLENGE_SIZE (8)
151156
#define CIFS_SERVER_CHALLENGE_SIZE (8)
152157
#define CIFS_HMAC_MD5_HASH_SIZE (16)

fs/cifs/smb2glob.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
#define SMB2_HMACSHA256_SIZE (32)
5959
#define SMB2_CMACAES_SIZE (16)
6060
#define SMB3_SIGNKEY_SIZE (16)
61+
#define SMB3_GCM128_CRYPTKEY_SIZE (16)
6162
#define SMB3_GCM256_CRYPTKEY_SIZE (32)
6263

6364
/* Maximum buffer size value we can send with 1 credit */

fs/cifs/smb2ops.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4158,7 +4158,7 @@ smb2_get_enc_key(struct TCP_Server_Info *server, __u64 ses_id, int enc, u8 *key)
41584158
if (ses->Suid == ses_id) {
41594159
ses_enc_key = enc ? ses->smb3encryptionkey :
41604160
ses->smb3decryptionkey;
4161-
memcpy(key, ses_enc_key, SMB3_SIGN_KEY_SIZE);
4161+
memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
41624162
spin_unlock(&cifs_tcp_ses_lock);
41634163
return 0;
41644164
}
@@ -4185,7 +4185,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
41854185
int rc = 0;
41864186
struct scatterlist *sg;
41874187
u8 sign[SMB2_SIGNATURE_SIZE] = {};
4188-
u8 key[SMB3_SIGN_KEY_SIZE];
4188+
u8 key[SMB3_ENC_DEC_KEY_SIZE];
41894189
struct aead_request *req;
41904190
char *iv;
41914191
unsigned int iv_len;
@@ -4209,10 +4209,11 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
42094209
tfm = enc ? server->secmech.ccmaesencrypt :
42104210
server->secmech.ccmaesdecrypt;
42114211

4212-
if (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
4212+
if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
4213+
(server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
42134214
rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
42144215
else
4215-
rc = crypto_aead_setkey(tfm, key, SMB3_SIGN_KEY_SIZE);
4216+
rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
42164217

42174218
if (rc) {
42184219
cifs_server_dbg(VFS, "%s: Failed to set aead key %d\n", __func__, rc);

fs/cifs/smb2transport.c

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,8 @@ static int generate_key(struct cifs_ses *ses, struct kvec label,
298298
{
299299
unsigned char zero = 0x0;
300300
__u8 i[4] = {0, 0, 0, 1};
301-
__u8 L[4] = {0, 0, 0, 128};
301+
__u8 L128[4] = {0, 0, 0, 128};
302+
__u8 L256[4] = {0, 0, 1, 0};
302303
int rc = 0;
303304
unsigned char prfhash[SMB2_HMACSHA256_SIZE];
304305
unsigned char *hashptr = prfhash;
@@ -354,8 +355,14 @@ static int generate_key(struct cifs_ses *ses, struct kvec label,
354355
goto smb3signkey_ret;
355356
}
356357

357-
rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
358-
L, 4);
358+
if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
359+
(server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) {
360+
rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
361+
L256, 4);
362+
} else {
363+
rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash,
364+
L128, 4);
365+
}
359366
if (rc) {
360367
cifs_server_dbg(VFS, "%s: Could not update with L\n", __func__);
361368
goto smb3signkey_ret;
@@ -390,6 +397,9 @@ generate_smb3signingkey(struct cifs_ses *ses,
390397
const struct derivation_triplet *ptriplet)
391398
{
392399
int rc;
400+
#ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
401+
struct TCP_Server_Info *server = ses->server;
402+
#endif
393403

394404
/*
395405
* All channels use the same encryption/decryption keys but
@@ -422,11 +432,11 @@ generate_smb3signingkey(struct cifs_ses *ses,
422432
rc = generate_key(ses, ptriplet->encryption.label,
423433
ptriplet->encryption.context,
424434
ses->smb3encryptionkey,
425-
SMB3_SIGN_KEY_SIZE);
435+
SMB3_ENC_DEC_KEY_SIZE);
426436
rc = generate_key(ses, ptriplet->decryption.label,
427437
ptriplet->decryption.context,
428438
ses->smb3decryptionkey,
429-
SMB3_SIGN_KEY_SIZE);
439+
SMB3_ENC_DEC_KEY_SIZE);
430440
if (rc)
431441
return rc;
432442
}
@@ -442,14 +452,23 @@ generate_smb3signingkey(struct cifs_ses *ses,
442452
*/
443453
cifs_dbg(VFS, "Session Id %*ph\n", (int)sizeof(ses->Suid),
444454
&ses->Suid);
455+
cifs_dbg(VFS, "Cipher type %d\n", server->cipher_type);
445456
cifs_dbg(VFS, "Session Key %*ph\n",
446457
SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
447458
cifs_dbg(VFS, "Signing Key %*ph\n",
448459
SMB3_SIGN_KEY_SIZE, ses->smb3signingkey);
449-
cifs_dbg(VFS, "ServerIn Key %*ph\n",
450-
SMB3_SIGN_KEY_SIZE, ses->smb3encryptionkey);
451-
cifs_dbg(VFS, "ServerOut Key %*ph\n",
452-
SMB3_SIGN_KEY_SIZE, ses->smb3decryptionkey);
460+
if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
461+
(server->cipher_type == SMB2_ENCRYPTION_AES256_GCM)) {
462+
cifs_dbg(VFS, "ServerIn Key %*ph\n",
463+
SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3encryptionkey);
464+
cifs_dbg(VFS, "ServerOut Key %*ph\n",
465+
SMB3_GCM256_CRYPTKEY_SIZE, ses->smb3decryptionkey);
466+
} else {
467+
cifs_dbg(VFS, "ServerIn Key %*ph\n",
468+
SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3encryptionkey);
469+
cifs_dbg(VFS, "ServerOut Key %*ph\n",
470+
SMB3_GCM128_CRYPTKEY_SIZE, ses->smb3decryptionkey);
471+
}
453472
#endif
454473
return rc;
455474
}

0 commit comments

Comments
 (0)