cifs: consolidate signature generating code
We have two versions of signature generating code. A vectorized and non-vectorized version. Eliminate a large chunk of cut-and-paste code by turning the non-vectorized version into a wrapper around the vectorized one. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
This commit is contained in:
parent
376b43f41c
commit
826a95e4a3
@ -37,83 +37,8 @@
|
|||||||
* the sequence number before this function is called. Also, this function
|
* the sequence number before this function is called. Also, this function
|
||||||
* should be called with the server->srv_mutex held.
|
* should be called with the server->srv_mutex held.
|
||||||
*/
|
*/
|
||||||
static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
|
static int cifs_calc_signature(const struct kvec *iov, int n_vec,
|
||||||
struct TCP_Server_Info *server, char *signature)
|
struct TCP_Server_Info *server, char *signature)
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (cifs_pdu == NULL || signature == NULL || server == NULL)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (!server->secmech.sdescmd5) {
|
|
||||||
cERROR(1, "%s: Can't generate signature\n", __func__);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
|
|
||||||
if (rc) {
|
|
||||||
cERROR(1, "%s: Could not init md5\n", __func__);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = crypto_shash_update(&server->secmech.sdescmd5->shash,
|
|
||||||
server->session_key.response, server->session_key.len);
|
|
||||||
if (rc) {
|
|
||||||
cERROR(1, "%s: Could not update with response\n", __func__);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = crypto_shash_update(&server->secmech.sdescmd5->shash,
|
|
||||||
cifs_pdu->Protocol, be32_to_cpu(cifs_pdu->smb_buf_length));
|
|
||||||
if (rc) {
|
|
||||||
cERROR(1, "%s: Could not update with payload\n", __func__);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature);
|
|
||||||
if (rc)
|
|
||||||
cERROR(1, "%s: Could not generate md5 hash\n", __func__);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* must be called with server->srv_mutex held */
|
|
||||||
int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
|
|
||||||
__u32 *pexpected_response_sequence_number)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
char smb_signature[20];
|
|
||||||
|
|
||||||
if ((cifs_pdu == NULL) || (server == NULL))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (!(cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) ||
|
|
||||||
server->tcpStatus == CifsNeedNegotiate)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
if (!server->session_estab) {
|
|
||||||
memcpy(cifs_pdu->Signature.SecuritySignature, "BSRSPYL", 8);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
cifs_pdu->Signature.Sequence.SequenceNumber =
|
|
||||||
cpu_to_le32(server->sequence_number);
|
|
||||||
cifs_pdu->Signature.Sequence.Reserved = 0;
|
|
||||||
|
|
||||||
*pexpected_response_sequence_number = server->sequence_number++;
|
|
||||||
server->sequence_number++;
|
|
||||||
|
|
||||||
rc = cifs_calculate_signature(cifs_pdu, server, smb_signature);
|
|
||||||
if (rc)
|
|
||||||
memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
|
|
||||||
else
|
|
||||||
memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
|
|
||||||
struct TCP_Server_Info *server, char *signature)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int rc;
|
int rc;
|
||||||
@ -179,7 +104,7 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
|
|||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
char smb_signature[20];
|
char smb_signature[20];
|
||||||
struct smb_hdr *cifs_pdu = iov[0].iov_base;
|
struct smb_hdr *cifs_pdu = (struct smb_hdr *)iov[0].iov_base;
|
||||||
|
|
||||||
if ((cifs_pdu == NULL) || (server == NULL))
|
if ((cifs_pdu == NULL) || (server == NULL))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -200,7 +125,7 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
|
|||||||
*pexpected_response_sequence_number = server->sequence_number++;
|
*pexpected_response_sequence_number = server->sequence_number++;
|
||||||
server->sequence_number++;
|
server->sequence_number++;
|
||||||
|
|
||||||
rc = cifs_calc_signature2(iov, n_vec, server, smb_signature);
|
rc = cifs_calc_signature(iov, n_vec, server, smb_signature);
|
||||||
if (rc)
|
if (rc)
|
||||||
memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
|
memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
|
||||||
else
|
else
|
||||||
@ -209,13 +134,27 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cifs_verify_signature(struct smb_hdr *cifs_pdu,
|
/* must be called with server->srv_mutex held */
|
||||||
|
int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
|
||||||
|
__u32 *pexpected_response_sequence_number)
|
||||||
|
{
|
||||||
|
struct kvec iov;
|
||||||
|
|
||||||
|
iov.iov_base = cifs_pdu;
|
||||||
|
iov.iov_len = be32_to_cpu(cifs_pdu->smb_buf_length) + 4;
|
||||||
|
|
||||||
|
return cifs_sign_smb2(&iov, 1, server,
|
||||||
|
pexpected_response_sequence_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov,
|
||||||
struct TCP_Server_Info *server,
|
struct TCP_Server_Info *server,
|
||||||
__u32 expected_sequence_number)
|
__u32 expected_sequence_number)
|
||||||
{
|
{
|
||||||
unsigned int rc;
|
unsigned int rc;
|
||||||
char server_response_sig[8];
|
char server_response_sig[8];
|
||||||
char what_we_think_sig_should_be[20];
|
char what_we_think_sig_should_be[20];
|
||||||
|
struct smb_hdr *cifs_pdu = (struct smb_hdr *)iov[0].iov_base;
|
||||||
|
|
||||||
if (cifs_pdu == NULL || server == NULL)
|
if (cifs_pdu == NULL || server == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -247,8 +186,8 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
|
|||||||
cifs_pdu->Signature.Sequence.Reserved = 0;
|
cifs_pdu->Signature.Sequence.Reserved = 0;
|
||||||
|
|
||||||
mutex_lock(&server->srv_mutex);
|
mutex_lock(&server->srv_mutex);
|
||||||
rc = cifs_calculate_signature(cifs_pdu, server,
|
rc = cifs_calc_signature(iov, nr_iov, server,
|
||||||
what_we_think_sig_should_be);
|
what_we_think_sig_should_be);
|
||||||
mutex_unlock(&server->srv_mutex);
|
mutex_unlock(&server->srv_mutex);
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@ -380,7 +380,7 @@ extern void tconInfoFree(struct cifs_tcon *);
|
|||||||
extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
|
extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
|
||||||
extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
|
extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
|
||||||
__u32 *);
|
__u32 *);
|
||||||
extern int cifs_verify_signature(struct smb_hdr *,
|
extern int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov,
|
||||||
struct TCP_Server_Info *server,
|
struct TCP_Server_Info *server,
|
||||||
__u32 expected_sequence_number);
|
__u32 expected_sequence_number);
|
||||||
extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *);
|
extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *);
|
||||||
|
@ -496,13 +496,18 @@ int
|
|||||||
cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
|
cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
|
||||||
bool log_error)
|
bool log_error)
|
||||||
{
|
{
|
||||||
dump_smb(mid->resp_buf,
|
unsigned int len = be32_to_cpu(mid->resp_buf->smb_buf_length) + 4;
|
||||||
min_t(u32, 92, be32_to_cpu(mid->resp_buf->smb_buf_length)));
|
|
||||||
|
dump_smb(mid->resp_buf, min_t(u32, 92, len));
|
||||||
|
|
||||||
/* convert the length into a more usable form */
|
/* convert the length into a more usable form */
|
||||||
if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
|
if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
|
||||||
|
struct kvec iov;
|
||||||
|
|
||||||
|
iov.iov_base = mid->resp_buf;
|
||||||
|
iov.iov_len = len;
|
||||||
/* FIXME: add code to kill session */
|
/* FIXME: add code to kill session */
|
||||||
if (cifs_verify_signature(mid->resp_buf, server,
|
if (cifs_verify_signature(&iov, 1, server,
|
||||||
mid->sequence_number + 1) != 0)
|
mid->sequence_number + 1) != 0)
|
||||||
cERROR(1, "Unexpected SMB signature");
|
cERROR(1, "Unexpected SMB signature");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user