|
@@ -222,8 +222,8 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-int
|
|
|
-generate_smb3signingkey(struct cifs_ses *ses)
|
|
|
+static int generate_key(struct cifs_ses *ses, struct kvec label,
|
|
|
+ struct kvec context, __u8 *key, unsigned int key_size)
|
|
|
{
|
|
|
unsigned char zero = 0x0;
|
|
|
__u8 i[4] = {0, 0, 0, 1};
|
|
@@ -233,7 +233,7 @@ generate_smb3signingkey(struct cifs_ses *ses)
|
|
|
unsigned char *hashptr = prfhash;
|
|
|
|
|
|
memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
|
|
|
- memset(ses->smb3signingkey, 0x0, SMB3_SIGNKEY_SIZE);
|
|
|
+ memset(key, 0x0, key_size);
|
|
|
|
|
|
rc = smb3_crypto_shash_allocate(ses->server);
|
|
|
if (rc) {
|
|
@@ -262,7 +262,7 @@ generate_smb3signingkey(struct cifs_ses *ses)
|
|
|
}
|
|
|
|
|
|
rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
|
|
|
- "SMB2AESCMAC", 12);
|
|
|
+ label.iov_base, label.iov_len);
|
|
|
if (rc) {
|
|
|
cifs_dbg(VFS, "%s: Could not update with label\n", __func__);
|
|
|
goto smb3signkey_ret;
|
|
@@ -276,7 +276,7 @@ generate_smb3signingkey(struct cifs_ses *ses)
|
|
|
}
|
|
|
|
|
|
rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash,
|
|
|
- "SmbSign", 8);
|
|
|
+ context.iov_base, context.iov_len);
|
|
|
if (rc) {
|
|
|
cifs_dbg(VFS, "%s: Could not update with context\n", __func__);
|
|
|
goto smb3signkey_ret;
|
|
@@ -296,12 +296,102 @@ generate_smb3signingkey(struct cifs_ses *ses)
|
|
|
goto smb3signkey_ret;
|
|
|
}
|
|
|
|
|
|
- memcpy(ses->smb3signingkey, hashptr, SMB3_SIGNKEY_SIZE);
|
|
|
+ memcpy(key, hashptr, key_size);
|
|
|
|
|
|
smb3signkey_ret:
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+struct derivation {
|
|
|
+ struct kvec label;
|
|
|
+ struct kvec context;
|
|
|
+};
|
|
|
+
|
|
|
+struct derivation_triplet {
|
|
|
+ struct derivation signing;
|
|
|
+ struct derivation encryption;
|
|
|
+ struct derivation decryption;
|
|
|
+};
|
|
|
+
|
|
|
+static int
|
|
|
+generate_smb3signingkey(struct cifs_ses *ses,
|
|
|
+ const struct derivation_triplet *ptriplet)
|
|
|
+{
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ rc = generate_key(ses, ptriplet->signing.label,
|
|
|
+ ptriplet->signing.context, ses->smb3signingkey,
|
|
|
+ SMB3_SIGN_KEY_SIZE);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ rc = generate_key(ses, ptriplet->encryption.label,
|
|
|
+ ptriplet->encryption.context, ses->smb3encryptionkey,
|
|
|
+ SMB3_SIGN_KEY_SIZE);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ return generate_key(ses, ptriplet->decryption.label,
|
|
|
+ ptriplet->decryption.context,
|
|
|
+ ses->smb3decryptionkey, SMB3_SIGN_KEY_SIZE);
|
|
|
+}
|
|
|
+
|
|
|
+int
|
|
|
+generate_smb30signingkey(struct cifs_ses *ses)
|
|
|
+
|
|
|
+{
|
|
|
+ struct derivation_triplet triplet;
|
|
|
+ struct derivation *d;
|
|
|
+
|
|
|
+ d = &triplet.signing;
|
|
|
+ d->label.iov_base = "SMB2AESCMAC";
|
|
|
+ d->label.iov_len = 12;
|
|
|
+ d->context.iov_base = "SmbSign";
|
|
|
+ d->context.iov_len = 8;
|
|
|
+
|
|
|
+ d = &triplet.encryption;
|
|
|
+ d->label.iov_base = "SMB2AESCCM";
|
|
|
+ d->label.iov_len = 11;
|
|
|
+ d->context.iov_base = "ServerIn ";
|
|
|
+ d->context.iov_len = 10;
|
|
|
+
|
|
|
+ d = &triplet.decryption;
|
|
|
+ d->label.iov_base = "SMB2AESCCM";
|
|
|
+ d->label.iov_len = 11;
|
|
|
+ d->context.iov_base = "ServerOut";
|
|
|
+ d->context.iov_len = 10;
|
|
|
+
|
|
|
+ return generate_smb3signingkey(ses, &triplet);
|
|
|
+}
|
|
|
+
|
|
|
+int
|
|
|
+generate_smb311signingkey(struct cifs_ses *ses)
|
|
|
+
|
|
|
+{
|
|
|
+ struct derivation_triplet triplet;
|
|
|
+ struct derivation *d;
|
|
|
+
|
|
|
+ d = &triplet.signing;
|
|
|
+ d->label.iov_base = "SMB2AESCMAC";
|
|
|
+ d->label.iov_len = 12;
|
|
|
+ d->context.iov_base = "SmbSign";
|
|
|
+ d->context.iov_len = 8;
|
|
|
+
|
|
|
+ d = &triplet.encryption;
|
|
|
+ d->label.iov_base = "SMB2AESCCM";
|
|
|
+ d->label.iov_len = 11;
|
|
|
+ d->context.iov_base = "ServerIn ";
|
|
|
+ d->context.iov_len = 10;
|
|
|
+
|
|
|
+ d = &triplet.decryption;
|
|
|
+ d->label.iov_base = "SMB2AESCCM";
|
|
|
+ d->label.iov_len = 11;
|
|
|
+ d->context.iov_base = "ServerOut";
|
|
|
+ d->context.iov_len = 10;
|
|
|
+
|
|
|
+ return generate_smb3signingkey(ses, &triplet);
|
|
|
+}
|
|
|
+
|
|
|
int
|
|
|
smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
|
|
|
{
|