Unverified Commit bfe6cb0c authored by Steve French's avatar Steve French Committed by GitHub
Browse files

Merge pull request #50 from namjaejeon/cifsd-for-next

Cifsd for next
parents 4ead0568 a6a5fa77
Loading
Loading
Loading
Loading
+44 −57
Original line number Diff line number Diff line
@@ -74,11 +74,8 @@ static bool asn1_oid_decode(const unsigned char *value, size_t vlen,

	optr = *oid;

	if (!asn1_subid_decode(&iptr, end, &subid)) {
		kfree(*oid);
		*oid = NULL;
		return false;
	}
	if (!asn1_subid_decode(&iptr, end, &subid))
		goto fail;

	if (subid < 40) {
		optr[0] = 0;
@@ -95,35 +92,27 @@ static bool asn1_oid_decode(const unsigned char *value, size_t vlen,
	optr += 2;

	while (iptr < end) {
		if (++(*oidlen) > vlen) {
			kfree(*oid);
			*oid = NULL;
			return false;
		if (++(*oidlen) > vlen)
			goto fail;

		if (!asn1_subid_decode(&iptr, end, optr++))
			goto fail;
	}
	return true;

		if (!asn1_subid_decode(&iptr, end, optr++)) {
fail:
	kfree(*oid);
	*oid = NULL;
	return false;
}
	}
	return true;
}

static bool
oid_eq(unsigned long *oid1, unsigned int oid1len,
static bool oid_eq(unsigned long *oid1, unsigned int oid1len,
		   unsigned long *oid2, unsigned int oid2len)
{
	unsigned int i;

	if (oid1len != oid2len)
		return false;

	for (i = 0; i < oid1len; i++) {
		if (oid1[i] != oid2[i])
			return false;
	}
	return true;
	return memcmp(oid1, oid2, oid1len) == 0;
}

int
@@ -156,10 +145,7 @@ static int compute_asn_hdr_len_bytes(int len)
		return 0;
}

static void encode_asn_tag(char *buf,
			   unsigned int *ofs,
			   char tag,
			   char seq,
static void encode_asn_tag(char *buf, unsigned int *ofs, char tag, char seq,
			   int length)
{
	int i;
@@ -170,9 +156,9 @@ static void encode_asn_tag(char *buf,
	/* insert tag */
	buf[index++] = tag;

	if (!hdr_len)
	if (!hdr_len) {
		buf[index++] = len;
	else {
	} else {
		buf[index++] = 0x80 | hdr_len;
		for (i = hdr_len - 1; i >= 0; i--)
			buf[index++] = (len >> (i * 8)) & 0xFF;
@@ -182,9 +168,9 @@ static void encode_asn_tag(char *buf,
	len = len - (index - *ofs);
	buf[index++] = seq;

	if (!hdr_len)
	if (!hdr_len) {
		buf[index++] = len;
	else {
	} else {
		buf[index++] = 0x80 | hdr_len;
		for (i = hdr_len - 1; i >= 0; i--)
			buf[index++] = (len >> (i * 8)) & 0xFF;
@@ -262,8 +248,8 @@ int build_spnego_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen,
	return 0;
}

int gssapi_this_mech(void *context, size_t hdrlen,
		unsigned char tag, const void *value, size_t vlen)
int gssapi_this_mech(void *context, size_t hdrlen, unsigned char tag,
		     const void *value, size_t vlen)
{
	unsigned long *oid;
	size_t oidlen;
@@ -287,21 +273,17 @@ int gssapi_this_mech(void *context, size_t hdrlen,
	return err;
}

int neg_token_init_mech_type(void *context, size_t hdrlen,
		unsigned char tag, const void *value, size_t vlen)
int neg_token_init_mech_type(void *context, size_t hdrlen, unsigned char tag,
			     const void *value, size_t vlen)
{
	struct ksmbd_conn *conn = context;
	unsigned long *oid;
	size_t oidlen;
	int mech_type;

	if (!asn1_oid_decode(value, vlen, &oid, &oidlen)) {
	char buf[50];

		sprint_oid(value, vlen, buf, sizeof(buf));
		ksmbd_debug(AUTH, "Unexpected OID: %s\n", buf);
		return -EBADMSG;
	}
	if (!asn1_oid_decode(value, vlen, &oid, &oidlen))
		goto fail;

	if (oid_eq(oid, oidlen, NTLMSSP_OID, NTLMSSP_OID_LEN))
		mech_type = KSMBD_AUTH_NTLMSSP;
@@ -312,19 +294,24 @@ int neg_token_init_mech_type(void *context, size_t hdrlen,
	else if (oid_eq(oid, oidlen, KRB5U2U_OID, KRB5U2U_OID_LEN))
		mech_type = KSMBD_AUTH_KRB5U2U;
	else
		goto out;
		goto fail;

	conn->auth_mechs |= mech_type;
	if (conn->preferred_auth_mech == 0)
		conn->preferred_auth_mech = mech_type;

out:
	kfree(oid);
	return 0;

fail:
	kfree(oid);
	sprint_oid(value, vlen, buf, sizeof(buf));
	ksmbd_debug(AUTH, "Unexpected OID: %s\n", buf);
	return -EBADMSG;
}

int neg_token_init_mech_token(void *context, size_t hdrlen,
		unsigned char tag, const void *value, size_t vlen)
int neg_token_init_mech_token(void *context, size_t hdrlen, unsigned char tag,
			      const void *value, size_t vlen)
{
	struct ksmbd_conn *conn = context;

@@ -337,8 +324,8 @@ int neg_token_init_mech_token(void *context, size_t hdrlen,
	return 0;
}

int neg_token_targ_resp_token(void *context, size_t hdrlen,
		unsigned char tag, const void *value, size_t vlen)
int neg_token_targ_resp_token(void *context, size_t hdrlen, unsigned char tag,
			      const void *value, size_t vlen)
{
	struct ksmbd_conn *conn = context;

+5 −13
Original line number Diff line number Diff line
@@ -10,20 +10,12 @@
#ifndef __ASN1_H__
#define __ASN1_H__

int ksmbd_decode_negTokenInit(unsigned char *security_blob,
			      int length,
int ksmbd_decode_negTokenInit(unsigned char *security_blob, int length,
			      struct ksmbd_conn *conn);

int ksmbd_decode_negTokenTarg(unsigned char *security_blob,
			      int length,
int ksmbd_decode_negTokenTarg(unsigned char *security_blob, int length,
			      struct ksmbd_conn *conn);

int build_spnego_ntlmssp_neg_blob(unsigned char **pbuffer,
				  u16 *buflen,
				  char *ntlm_blob,
				  int ntlm_blob_len);

int build_spnego_ntlmssp_auth_blob(unsigned char **pbuffer,
				   u16 *buflen,
int build_spnego_ntlmssp_neg_blob(unsigned char **pbuffer, u16 *buflen,
				  char *ntlm_blob, int ntlm_blob_len);
int build_spnego_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen,
				   int neg_result);
#endif /* __ASN1_H__ */
+146 −135
Original line number Diff line number Diff line
@@ -92,14 +92,12 @@ smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
	unsigned char key2[8];
	struct des_ctx ctx;

	str_to_key(key, key2);

	if (fips_enabled) {
		ksmbd_debug(AUTH,
			"FIPS compliance enabled: DES not permitted\n");
		ksmbd_debug(AUTH, "FIPS compliance enabled: DES not permitted\n");
		return -ENOENT;
	}

	str_to_key(key, key2);
	des_expand_key(&ctx, key2, DES_KEY_SIZE);
	des_encrypt(&ctx, out, in);
	memzero_explicit(&ctx, sizeof(ctx));
@@ -116,8 +114,7 @@ static int ksmbd_enc_p24(unsigned char *p21, const unsigned char *c8, unsigned c
	rc = smbhash(p24 + 8, c8, p21 + 7);
	if (rc)
		return rc;
	rc = smbhash(p24 + 16, c8, p21 + 14);
	return rc;
	return smbhash(p24 + 16, c8, p21 + 14);
}

/* produce a md4 message digest from data of length n bytes */
@@ -130,7 +127,7 @@ static int ksmbd_enc_md4(unsigned char *md4_hash, unsigned char *link_str,
	ctx = ksmbd_crypto_ctx_find_md4();
	if (!ctx) {
		ksmbd_debug(AUTH, "Crypto md4 allocation error\n");
		return -EINVAL;
		return -ENOMEM;
	}

	rc = crypto_shash_init(CRYPTO_MD4(ctx));
@@ -162,7 +159,7 @@ static int ksmbd_enc_update_sess_key(unsigned char *md5_hash, char *nonce,
	ctx = ksmbd_crypto_ctx_find_md5();
	if (!ctx) {
		ksmbd_debug(AUTH, "Crypto md5 allocation error\n");
		return -EINVAL;
		return -ENOMEM;
	}

	rc = crypto_shash_init(CRYPTO_MD5(ctx));
@@ -202,11 +199,13 @@ static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash,
			      char *hmac)
{
	struct ksmbd_crypto_ctx *ctx;
	int rc = -EINVAL;
	int rc;

	ctx = ksmbd_crypto_ctx_find_hmacmd5();
	if (!ctx)
		goto out;
	if (!ctx) {
		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
		return -ENOMEM;
	}

	rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
				 hash,
@@ -226,15 +225,13 @@ static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash,
				 hmac,
				 SMB2_NTLMV2_SESSKEY_SIZE);
	if (rc) {
		ksmbd_debug(AUTH, "Could not update with response error %d\n",
			rc);
		ksmbd_debug(AUTH, "Could not update with response error %d\n", rc);
		goto out;
	}

	rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), sess->sess_key);
	if (rc) {
		ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n",
			rc);
		ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n", rc);
		goto out;
	}

@@ -246,7 +243,7 @@ static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash,
static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
			    char *dname)
{
	int ret = -EINVAL, len;
	int ret, len, conv_len;
	wchar_t *domain = NULL;
	__le16 *uniname = NULL;
	struct ksmbd_crypto_ctx *ctx;
@@ -254,7 +251,7 @@ static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
	ctx = ksmbd_crypto_ctx_find_hmacmd5();
	if (!ctx) {
		ksmbd_debug(AUTH, "can't generate ntlmv2 hash\n");
		goto out;
		return -ENOMEM;
	}

	ret = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
@@ -279,15 +276,17 @@ static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
		goto out;
	}

	if (len) {
		len = smb_strtoUTF16(uniname, user_name(sess->user), len,
	conv_len = smb_strtoUTF16(uniname, user_name(sess->user), len,
				  sess->conn->local_nls);
		UniStrupr(uniname);
	if (conv_len < 0 || conv_len > len) {
		ret = -EINVAL;
		goto out;
	}
	UniStrupr(uniname);

	ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
				  (char *)uniname,
				  UNICODE_LEN(len));
				  UNICODE_LEN(conv_len));
	if (ret) {
		ksmbd_debug(AUTH, "Could not update with user\n");
		goto out;
@@ -301,21 +300,25 @@ static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
		goto out;
	}

	len = smb_strtoUTF16((__le16 *)domain, dname, len,
	conv_len = smb_strtoUTF16((__le16 *)domain, dname, len,
				  sess->conn->local_nls);
	if (conv_len < 0 || conv_len > len) {
		ret = -EINVAL;
		goto out;
	}

	ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
				  (char *)domain,
				  UNICODE_LEN(len));
				  UNICODE_LEN(conv_len));
	if (ret) {
		ksmbd_debug(AUTH, "Could not update with domain\n");
		goto out;
	}

	ret = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_hash);
out:
	if (ret)
		ksmbd_debug(AUTH, "Could not generate md5 hash\n");
out:
	kfree(uniname);
	kfree(domain);
	ksmbd_release_crypto_ctx(ctx);
@@ -344,8 +347,7 @@ int ksmbd_auth_ntlm(struct ksmbd_session *sess, char *pw_buf)
		return rc;
	}

	ksmbd_enc_md4(sess->sess_key,
			user_passkey(sess->user),
	ksmbd_enc_md4(sess->sess_key, user_passkey(sess->user),
		      CIFS_SMB1_SESSKEY_SIZE);
	memcpy(sess->sess_key + CIFS_SMB1_SESSKEY_SIZE, key,
	       CIFS_AUTH_RESP_SIZE);
@@ -353,12 +355,11 @@ int ksmbd_auth_ntlm(struct ksmbd_session *sess, char *pw_buf)

	if (strncmp(pw_buf, key, CIFS_AUTH_RESP_SIZE) != 0) {
		ksmbd_debug(AUTH, "ntlmv1 authentication failed\n");
		rc = -EINVAL;
	} else {
		ksmbd_debug(AUTH, "ntlmv1 authentication pass\n");
		return -EINVAL;
	}

	return rc;
	ksmbd_debug(AUTH, "ntlmv1 authentication pass\n");
	return 0;
}

/**
@@ -377,12 +378,12 @@ int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
	char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
	struct ksmbd_crypto_ctx *ctx;
	char *construct = NULL;
	int rc = -EINVAL, len;
	int rc, len;

	ctx = ksmbd_crypto_ctx_find_hmacmd5();
	if (!ctx) {
		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5 rc %d\n", rc);
		goto out;
		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
		return -ENOMEM;
	}

	rc = calc_ntlmv2_hash(sess, ntlmv2_hash, domain_name);
@@ -413,8 +414,7 @@ int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
	}

	memcpy(construct, sess->ntlmssp.cryptkey, CIFS_CRYPTO_KEY_SIZE);
	memcpy(construct + CIFS_CRYPTO_KEY_SIZE,
		(char *)(&ntlmv2->blob_signature), blen);
	memcpy(construct + CIFS_CRYPTO_KEY_SIZE, &ntlmv2->blob_signature, blen);

	rc = crypto_shash_update(CRYPTO_HMACMD5(ctx), construct, len);
	if (rc) {
@@ -434,7 +434,8 @@ int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
		goto out;
	}

	rc = memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE);
	if (memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE) != 0)
		rc = -EINVAL;
out:
	ksmbd_release_crypto_ctx(ctx);
	kfree(construct);
@@ -473,7 +474,8 @@ static int __ksmbd_auth_ntlmv2(struct ksmbd_session *sess, char *client_nonce,
		goto out;
	}

	rc = memcmp(ntlm_resp, key, CIFS_AUTH_RESP_SIZE);
	if (memcmp(ntlm_resp, key, CIFS_AUTH_RESP_SIZE) != 0)
		rc = -EINVAL;
out:
	return rc;
}
@@ -533,8 +535,7 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
	/* process NTLMv2 authentication */
	ksmbd_debug(AUTH, "decode_ntlmssp_authenticate_blob dname%s\n",
		    domain_name);
	ret = ksmbd_auth_ntlmv2(sess,
			(struct ntlmv2_resp *)((char *)authblob + nt_off),
	ret = ksmbd_auth_ntlmv2(sess, (struct ntlmv2_resp *)((char *)authblob + nt_off),
				nt_len - CIFS_ENCPWD_SIZE,
				domain_name);
	kfree(domain_name);
@@ -584,6 +585,7 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
	wchar_t *name;
	__u8 *target_name;
	unsigned int len, flags, blob_off, blob_len, type, target_info_len = 0;
	unsigned int uni_len, conv_len;
	int cflags = sess->ntlmssp.client_flags;

	memcpy(chgblob->Signature, NTLMSSP_SIGNATURE, 8);
@@ -611,19 +613,24 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,

	chgblob->NegotiateFlags = cpu_to_le32(flags);
	len = strlen(ksmbd_netbios_name());
	name = kmalloc(2 + (len * 2), GFP_KERNEL);
	name = kmalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
	if (!name)
		return -ENOMEM;

	len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len,
	conv_len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len,
				  sess->conn->local_nls);
	len = UNICODE_LEN(len);
	if (conv_len < 0 || conv_len > len) {
		kfree(name);
		return -EINVAL;
	}

	uni_len = UNICODE_LEN(conv_len);

	blob_off = sizeof(struct challenge_message);
	blob_len = blob_off + len;
	blob_len = blob_off + uni_len;

	chgblob->TargetName.Length = cpu_to_le16(len);
	chgblob->TargetName.MaximumLength = cpu_to_le16(len);
	chgblob->TargetName.Length = cpu_to_le16(uni_len);
	chgblob->TargetName.MaximumLength = cpu_to_le16(uni_len);
	chgblob->TargetName.BufferOffset = cpu_to_le32(blob_off);

	/* Initialize random conn challenge */
@@ -635,18 +642,18 @@ ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
	chgblob->TargetInfoArray.BufferOffset = cpu_to_le32(blob_len);

	target_name = (__u8 *)chgblob + blob_off;
	memcpy(target_name, name, len);
	tinfo = (struct target_info *)(target_name + len);
	memcpy(target_name, name, uni_len);
	tinfo = (struct target_info *)(target_name + uni_len);

	chgblob->TargetInfoArray.Length = 0;
	/* Add target info list for NetBIOS/DNS settings */
	for (type = NTLMSSP_AV_NB_COMPUTER_NAME;
	     type <= NTLMSSP_AV_DNS_DOMAIN_NAME; type++) {
		tinfo->Type = cpu_to_le16(type);
		tinfo->Length = cpu_to_le16(len);
		memcpy(tinfo->Content, name, len);
		tinfo = (struct target_info *)((char *)tinfo + 4 + len);
		target_info_len += 4 + len;
		tinfo->Length = cpu_to_le16(uni_len);
		memcpy(tinfo->Content, name, uni_len);
		tinfo = (struct target_info *)((char *)tinfo + 4 + uni_len);
		target_info_len += 4 + uni_len;
	}

	/* Add terminator subblock */
@@ -733,13 +740,12 @@ int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
			int n_vec, char *sig)
{
	struct ksmbd_crypto_ctx *ctx;
	int rc = -EINVAL;
	int i;
	int rc, i;

	ctx = ksmbd_crypto_ctx_find_hmacsha256();
	if (!ctx) {
		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5 rc %d\n", rc);
		goto out;
		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
		return -ENOMEM;
	}

	rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
@@ -785,13 +791,12 @@ int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
			int n_vec, char *sig)
{
	struct ksmbd_crypto_ctx *ctx;
	int rc = -EINVAL;
	int i;
	int rc, i;

	ctx = ksmbd_crypto_ctx_find_cmacaes();
	if (!ctx) {
		ksmbd_debug(AUTH, "could not crypto alloc cmac rc %d\n", rc);
		goto out;
		ksmbd_debug(AUTH, "could not crypto alloc cmac\n");
		return -ENOMEM;
	}

	rc = crypto_shash_setkey(CRYPTO_CMACAES_TFM(ctx),
@@ -837,7 +842,7 @@ static int generate_key(struct ksmbd_session *sess, struct kvec label,
	__u8 i[4] = {0, 0, 0, 1};
	__u8 L128[4] = {0, 0, 0, 128};
	__u8 L256[4] = {0, 0, 1, 0};
	int rc = -EINVAL;
	int rc;
	unsigned char prfhash[SMB2_HMACSHA256_SIZE];
	unsigned char *hashptr = prfhash;
	struct ksmbd_crypto_ctx *ctx;
@@ -847,8 +852,8 @@ static int generate_key(struct ksmbd_session *sess, struct kvec label,

	ctx = ksmbd_crypto_ctx_find_hmacsha256();
	if (!ctx) {
		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5 rc %d\n", rc);
		goto smb3signkey_ret;
		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
		return -ENOMEM;
	}

	rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
@@ -945,7 +950,7 @@ static int generate_smb3signingkey(struct ksmbd_session *sess,
		    SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
	ksmbd_debug(AUTH, "Signing Key   %*ph\n",
		    SMB3_SIGN_KEY_SIZE, key);
	return rc;
	return 0;
}

int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess)
@@ -1013,7 +1018,7 @@ static int generate_smb3encryptionkey(struct ksmbd_session *sess,
		ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
			    SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3decryptionkey);
	}
	return rc;
	return 0;
}

int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess)
@@ -1059,21 +1064,20 @@ int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess)
int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
				     __u8 *pi_hash)
{
	int rc = -1;
	int rc;
	struct smb2_hdr *rcv_hdr = (struct smb2_hdr *)buf;
	char *all_bytes_msg = (char *)&rcv_hdr->ProtocolId;
	int msg_size = be32_to_cpu(rcv_hdr->smb2_buf_length);
	struct ksmbd_crypto_ctx *ctx = NULL;

	if (conn->preauth_info->Preauth_HashId ==
	    SMB2_PREAUTH_INTEGRITY_SHA512) {
	if (conn->preauth_info->Preauth_HashId !=
	    SMB2_PREAUTH_INTEGRITY_SHA512)
		return -EINVAL;

	ctx = ksmbd_crypto_ctx_find_sha512();
	if (!ctx) {
			ksmbd_debug(AUTH, "could not alloc sha512 rc %d\n", rc);
			goto out;
		}
	} else {
		goto out;
		ksmbd_debug(AUTH, "could not alloc sha512\n");
		return -ENOMEM;
	}

	rc = crypto_shash_init(CRYPTO_SHA512(ctx));
@@ -1107,13 +1111,13 @@ int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
		      __u8 *pi_hash)
{
	int rc = -1;
	int rc;
	struct ksmbd_crypto_ctx *ctx = NULL;

	ctx = ksmbd_crypto_ctx_find_sha256();
	if (!ctx) {
		ksmbd_debug(AUTH, "could not alloc sha256 rc %d\n", rc);
		goto out;
		ksmbd_debug(AUTH, "could not alloc sha256\n");
		return -ENOMEM;
	}

	rc = crypto_shash_init(CRYPTO_SHA256(ctx));
@@ -1146,7 +1150,7 @@ static int ksmbd_get_encryption_key(struct ksmbd_conn *conn, __u64 ses_id,

	sess = ksmbd_session_lookup(conn, ses_id);
	if (!sess)
		return 1;
		return -EINVAL;

	ses_enc_key = enc ? sess->smb3encryptionkey :
		sess->smb3decryptionkey;
@@ -1174,6 +1178,9 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
	unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24;
	int i, nr_entries[3] = {0}, total_entries = 0, sg_idx = 0;

	if (!nvec)
		return NULL;

	for (i = 0; i < nvec - 1; i++) {
		unsigned long kaddr = (unsigned long)iov[i + 1].iov_base;

@@ -1206,7 +1213,7 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
			for (j = 0; j < nr_entries[i]; j++) {
				unsigned int bytes = PAGE_SIZE - offset;

				if (len <= 0)
				if (!len)
					break;

				if (bytes > len)
@@ -1235,7 +1242,7 @@ int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
	struct smb2_transform_hdr *tr_hdr =
		(struct smb2_transform_hdr *)iov[0].iov_base;
	unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24;
	int rc = 0;
	int rc;
	struct scatterlist *sg;
	u8 sign[SMB2_SIGNATURE_SIZE] = {};
	u8 key[SMB3_ENC_DEC_KEY_SIZE];
@@ -1252,7 +1259,7 @@ int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
				      key);
	if (rc) {
		ksmbd_err("Could not get %scryption key\n", enc ? "en" : "de");
		return 0;
		return rc;
	}

	if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
@@ -1262,7 +1269,7 @@ int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
		ctx = ksmbd_crypto_ctx_find_ccm();
	if (!ctx) {
		ksmbd_err("crypto alloc failed\n");
		return -EINVAL;
		return -ENOMEM;
	}

	if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
@@ -1330,9 +1337,13 @@ int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
		rc = crypto_aead_encrypt(req);
	else
		rc = crypto_aead_decrypt(req);
	if (!rc && enc)
	if (rc)
		goto free_iv;

	if (enc)
		memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);

free_iv:
	kfree(iv);
free_sg:
	kfree(sg);
+16 −41
Original line number Diff line number Diff line
@@ -35,55 +35,30 @@ struct ksmbd_session;
struct ksmbd_conn;
struct kvec;

int ksmbd_crypt_message(struct ksmbd_conn *conn,
			struct kvec *iov,
			unsigned int nvec,
			int enc);

int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
			unsigned int nvec, int enc);
void ksmbd_copy_gss_neg_header(void *buf);

int ksmbd_auth_ntlm(struct ksmbd_session *sess,
		    char *pw_buf);

int ksmbd_auth_ntlmv2(struct ksmbd_session *sess,
		      struct ntlmv2_resp *ntlmv2,
		      int blen,
		      char *domain_name);

int ksmbd_auth_ntlm(struct ksmbd_session *sess, char *pw_buf);
int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
		      int blen, char *domain_name);
int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
				   int blob_len,
				   struct ksmbd_session *sess);

				   int blob_len, struct ksmbd_session *sess);
int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
				  int blob_len,
				  struct ksmbd_session *sess);

				  int blob_len, struct ksmbd_session *sess);
unsigned int
ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
				   struct ksmbd_session *sess);

int ksmbd_krb5_authenticate(struct ksmbd_session *sess,
			char *in_blob, int in_len,
			char *out_blob, int *out_len);

int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn,
			char *key,
			struct kvec *iov,
			int n_vec,
			char *sig);
int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn,
			char *key,
			struct kvec *iov,
			int n_vec,
			char *sig);

int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
			    int in_len,	char *out_blob, int *out_len);
int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
			int n_vec, char *sig);
int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
			int n_vec, char *sig);
int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess);
int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess);
int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess);
int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess);

int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn,
				     char *buf,
int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
				     __u8 *pi_hash);
int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
		      __u8 *pi_hash);
+2 −1
Original line number Diff line number Diff line
@@ -251,7 +251,8 @@ int ksmbd_init_buffer_pools(void)
		goto out;

	filp_cache = kmem_cache_create("ksmbd_file_cache",
			sizeof(struct ksmbd_file), 0, SLAB_HWCACHE_ALIGN, NULL);
				       sizeof(struct ksmbd_file), 0,
				       SLAB_HWCACHE_ALIGN, NULL);
	if (!filp_cache)
		goto out;

Loading