Loading fs/cifsd/asn1.c +44 −57 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading fs/cifsd/asn1.h +5 −13 Original line number Diff line number Diff line Loading @@ -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__ */ fs/cifsd/auth.c +146 −135 Original line number Diff line number Diff line Loading @@ -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)); Loading @@ -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 */ Loading @@ -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)); Loading Loading @@ -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)); Loading Loading @@ -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, Loading @@ -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; } Loading @@ -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; Loading @@ -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), Loading @@ -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; Loading @@ -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); Loading Loading @@ -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); Loading @@ -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; } /** Loading @@ -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); Loading Loading @@ -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) { Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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 */ Loading @@ -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 */ Loading Loading @@ -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), Loading Loading @@ -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), Loading Loading @@ -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; Loading @@ -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), Loading Loading @@ -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) Loading Loading @@ -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) Loading Loading @@ -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)); Loading Loading @@ -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)); Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) Loading Loading @@ -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]; Loading @@ -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 || Loading @@ -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 || Loading Loading @@ -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); Loading fs/cifsd/auth.h +16 −41 Original line number Diff line number Diff line Loading @@ -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); Loading fs/cifsd/buffer_pool.c +2 −1 Original line number Diff line number Diff line Loading @@ -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 Loading
fs/cifsd/asn1.c +44 −57 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading
fs/cifsd/asn1.h +5 −13 Original line number Diff line number Diff line Loading @@ -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__ */
fs/cifsd/auth.c +146 −135 Original line number Diff line number Diff line Loading @@ -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)); Loading @@ -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 */ Loading @@ -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)); Loading Loading @@ -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)); Loading Loading @@ -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, Loading @@ -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; } Loading @@ -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; Loading @@ -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), Loading @@ -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; Loading @@ -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); Loading Loading @@ -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); Loading @@ -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; } /** Loading @@ -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); Loading Loading @@ -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) { Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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 */ Loading @@ -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 */ Loading Loading @@ -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), Loading Loading @@ -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), Loading Loading @@ -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; Loading @@ -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), Loading Loading @@ -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) Loading Loading @@ -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) Loading Loading @@ -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)); Loading Loading @@ -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)); Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) Loading Loading @@ -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]; Loading @@ -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 || Loading @@ -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 || Loading Loading @@ -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); Loading
fs/cifsd/auth.h +16 −41 Original line number Diff line number Diff line Loading @@ -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); Loading
fs/cifsd/buffer_pool.c +2 −1 Original line number Diff line number Diff line Loading @@ -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