cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

auth.c (30337B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *   Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>
      4 *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
      5 */
      6
      7#include <linux/kernel.h>
      8#include <linux/fs.h>
      9#include <linux/uaccess.h>
     10#include <linux/backing-dev.h>
     11#include <linux/writeback.h>
     12#include <linux/uio.h>
     13#include <linux/xattr.h>
     14#include <crypto/hash.h>
     15#include <crypto/aead.h>
     16#include <linux/random.h>
     17#include <linux/scatterlist.h>
     18
     19#include "auth.h"
     20#include "glob.h"
     21
     22#include <linux/fips.h>
     23#include <crypto/des.h>
     24
     25#include "server.h"
     26#include "smb_common.h"
     27#include "connection.h"
     28#include "mgmt/user_session.h"
     29#include "mgmt/user_config.h"
     30#include "crypto_ctx.h"
     31#include "transport_ipc.h"
     32#include "../smbfs_common/arc4.h"
     33
     34/*
     35 * Fixed format data defining GSS header and fixed string
     36 * "not_defined_in_RFC4178@please_ignore".
     37 * So sec blob data in neg phase could be generated statically.
     38 */
     39static char NEGOTIATE_GSS_HEADER[AUTH_GSS_LENGTH] = {
     40#ifdef CONFIG_SMB_SERVER_KERBEROS5
     41	0x60, 0x5e, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05,
     42	0x05, 0x02, 0xa0, 0x54, 0x30, 0x52, 0xa0, 0x24,
     43	0x30, 0x22, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
     44	0xf7, 0x12, 0x01, 0x02, 0x02, 0x06, 0x09, 0x2a,
     45	0x86, 0x48, 0x82, 0xf7, 0x12, 0x01, 0x02, 0x02,
     46	0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
     47	0x37, 0x02, 0x02, 0x0a, 0xa3, 0x2a, 0x30, 0x28,
     48	0xa0, 0x26, 0x1b, 0x24, 0x6e, 0x6f, 0x74, 0x5f,
     49	0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x5f,
     50	0x69, 0x6e, 0x5f, 0x52, 0x46, 0x43, 0x34, 0x31,
     51	0x37, 0x38, 0x40, 0x70, 0x6c, 0x65, 0x61, 0x73,
     52	0x65, 0x5f, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65
     53#else
     54	0x60, 0x48, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05,
     55	0x05, 0x02, 0xa0, 0x3e, 0x30, 0x3c, 0xa0, 0x0e,
     56	0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
     57	0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa3, 0x2a,
     58	0x30, 0x28, 0xa0, 0x26, 0x1b, 0x24, 0x6e, 0x6f,
     59	0x74, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65,
     60	0x64, 0x5f, 0x69, 0x6e, 0x5f, 0x52, 0x46, 0x43,
     61	0x34, 0x31, 0x37, 0x38, 0x40, 0x70, 0x6c, 0x65,
     62	0x61, 0x73, 0x65, 0x5f, 0x69, 0x67, 0x6e, 0x6f,
     63	0x72, 0x65
     64#endif
     65};
     66
     67void ksmbd_copy_gss_neg_header(void *buf)
     68{
     69	memcpy(buf, NEGOTIATE_GSS_HEADER, AUTH_GSS_LENGTH);
     70}
     71
     72/**
     73 * ksmbd_gen_sess_key() - function to generate session key
     74 * @sess:	session of connection
     75 * @hash:	source hash value to be used for find session key
     76 * @hmac:	source hmac value to be used for finding session key
     77 *
     78 */
     79static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash,
     80			      char *hmac)
     81{
     82	struct ksmbd_crypto_ctx *ctx;
     83	int rc;
     84
     85	ctx = ksmbd_crypto_ctx_find_hmacmd5();
     86	if (!ctx) {
     87		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
     88		return -ENOMEM;
     89	}
     90
     91	rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
     92				 hash,
     93				 CIFS_HMAC_MD5_HASH_SIZE);
     94	if (rc) {
     95		ksmbd_debug(AUTH, "hmacmd5 set key fail error %d\n", rc);
     96		goto out;
     97	}
     98
     99	rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
    100	if (rc) {
    101		ksmbd_debug(AUTH, "could not init hmacmd5 error %d\n", rc);
    102		goto out;
    103	}
    104
    105	rc = crypto_shash_update(CRYPTO_HMACMD5(ctx),
    106				 hmac,
    107				 SMB2_NTLMV2_SESSKEY_SIZE);
    108	if (rc) {
    109		ksmbd_debug(AUTH, "Could not update with response error %d\n", rc);
    110		goto out;
    111	}
    112
    113	rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), sess->sess_key);
    114	if (rc) {
    115		ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n", rc);
    116		goto out;
    117	}
    118
    119out:
    120	ksmbd_release_crypto_ctx(ctx);
    121	return rc;
    122}
    123
    124static int calc_ntlmv2_hash(struct ksmbd_session *sess, char *ntlmv2_hash,
    125			    char *dname)
    126{
    127	int ret, len, conv_len;
    128	wchar_t *domain = NULL;
    129	__le16 *uniname = NULL;
    130	struct ksmbd_crypto_ctx *ctx;
    131
    132	ctx = ksmbd_crypto_ctx_find_hmacmd5();
    133	if (!ctx) {
    134		ksmbd_debug(AUTH, "can't generate ntlmv2 hash\n");
    135		return -ENOMEM;
    136	}
    137
    138	ret = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
    139				  user_passkey(sess->user),
    140				  CIFS_ENCPWD_SIZE);
    141	if (ret) {
    142		ksmbd_debug(AUTH, "Could not set NT Hash as a key\n");
    143		goto out;
    144	}
    145
    146	ret = crypto_shash_init(CRYPTO_HMACMD5(ctx));
    147	if (ret) {
    148		ksmbd_debug(AUTH, "could not init hmacmd5\n");
    149		goto out;
    150	}
    151
    152	/* convert user_name to unicode */
    153	len = strlen(user_name(sess->user));
    154	uniname = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
    155	if (!uniname) {
    156		ret = -ENOMEM;
    157		goto out;
    158	}
    159
    160	conv_len = smb_strtoUTF16(uniname, user_name(sess->user), len,
    161				  sess->conn->local_nls);
    162	if (conv_len < 0 || conv_len > len) {
    163		ret = -EINVAL;
    164		goto out;
    165	}
    166	UniStrupr(uniname);
    167
    168	ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
    169				  (char *)uniname,
    170				  UNICODE_LEN(conv_len));
    171	if (ret) {
    172		ksmbd_debug(AUTH, "Could not update with user\n");
    173		goto out;
    174	}
    175
    176	/* Convert domain name or conn name to unicode and uppercase */
    177	len = strlen(dname);
    178	domain = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
    179	if (!domain) {
    180		ret = -ENOMEM;
    181		goto out;
    182	}
    183
    184	conv_len = smb_strtoUTF16((__le16 *)domain, dname, len,
    185				  sess->conn->local_nls);
    186	if (conv_len < 0 || conv_len > len) {
    187		ret = -EINVAL;
    188		goto out;
    189	}
    190
    191	ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
    192				  (char *)domain,
    193				  UNICODE_LEN(conv_len));
    194	if (ret) {
    195		ksmbd_debug(AUTH, "Could not update with domain\n");
    196		goto out;
    197	}
    198
    199	ret = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_hash);
    200	if (ret)
    201		ksmbd_debug(AUTH, "Could not generate md5 hash\n");
    202out:
    203	kfree(uniname);
    204	kfree(domain);
    205	ksmbd_release_crypto_ctx(ctx);
    206	return ret;
    207}
    208
    209/**
    210 * ksmbd_auth_ntlmv2() - NTLMv2 authentication handler
    211 * @sess:	session of connection
    212 * @ntlmv2:		NTLMv2 challenge response
    213 * @blen:		NTLMv2 blob length
    214 * @domain_name:	domain name
    215 *
    216 * Return:	0 on success, error number on error
    217 */
    218int ksmbd_auth_ntlmv2(struct ksmbd_session *sess, struct ntlmv2_resp *ntlmv2,
    219		      int blen, char *domain_name, char *cryptkey)
    220{
    221	char ntlmv2_hash[CIFS_ENCPWD_SIZE];
    222	char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
    223	struct ksmbd_crypto_ctx *ctx;
    224	char *construct = NULL;
    225	int rc, len;
    226
    227	ctx = ksmbd_crypto_ctx_find_hmacmd5();
    228	if (!ctx) {
    229		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
    230		return -ENOMEM;
    231	}
    232
    233	rc = calc_ntlmv2_hash(sess, ntlmv2_hash, domain_name);
    234	if (rc) {
    235		ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
    236		goto out;
    237	}
    238
    239	rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
    240				 ntlmv2_hash,
    241				 CIFS_HMAC_MD5_HASH_SIZE);
    242	if (rc) {
    243		ksmbd_debug(AUTH, "Could not set NTLMV2 Hash as a key\n");
    244		goto out;
    245	}
    246
    247	rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
    248	if (rc) {
    249		ksmbd_debug(AUTH, "Could not init hmacmd5\n");
    250		goto out;
    251	}
    252
    253	len = CIFS_CRYPTO_KEY_SIZE + blen;
    254	construct = kzalloc(len, GFP_KERNEL);
    255	if (!construct) {
    256		rc = -ENOMEM;
    257		goto out;
    258	}
    259
    260	memcpy(construct, cryptkey, CIFS_CRYPTO_KEY_SIZE);
    261	memcpy(construct + CIFS_CRYPTO_KEY_SIZE, &ntlmv2->blob_signature, blen);
    262
    263	rc = crypto_shash_update(CRYPTO_HMACMD5(ctx), construct, len);
    264	if (rc) {
    265		ksmbd_debug(AUTH, "Could not update with response\n");
    266		goto out;
    267	}
    268
    269	rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_rsp);
    270	if (rc) {
    271		ksmbd_debug(AUTH, "Could not generate md5 hash\n");
    272		goto out;
    273	}
    274
    275	rc = ksmbd_gen_sess_key(sess, ntlmv2_hash, ntlmv2_rsp);
    276	if (rc) {
    277		ksmbd_debug(AUTH, "Could not generate sess key\n");
    278		goto out;
    279	}
    280
    281	if (memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE) != 0)
    282		rc = -EINVAL;
    283out:
    284	ksmbd_release_crypto_ctx(ctx);
    285	kfree(construct);
    286	return rc;
    287}
    288
    289/**
    290 * ksmbd_decode_ntlmssp_auth_blob() - helper function to construct
    291 * authenticate blob
    292 * @authblob:	authenticate blob source pointer
    293 * @usr:	user details
    294 * @sess:	session of connection
    295 *
    296 * Return:	0 on success, error number on error
    297 */
    298int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
    299				   int blob_len, struct ksmbd_conn *conn,
    300				   struct ksmbd_session *sess)
    301{
    302	char *domain_name;
    303	unsigned int nt_off, dn_off;
    304	unsigned short nt_len, dn_len;
    305	int ret;
    306
    307	if (blob_len < sizeof(struct authenticate_message)) {
    308		ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
    309			    blob_len);
    310		return -EINVAL;
    311	}
    312
    313	if (memcmp(authblob->Signature, "NTLMSSP", 8)) {
    314		ksmbd_debug(AUTH, "blob signature incorrect %s\n",
    315			    authblob->Signature);
    316		return -EINVAL;
    317	}
    318
    319	nt_off = le32_to_cpu(authblob->NtChallengeResponse.BufferOffset);
    320	nt_len = le16_to_cpu(authblob->NtChallengeResponse.Length);
    321	dn_off = le32_to_cpu(authblob->DomainName.BufferOffset);
    322	dn_len = le16_to_cpu(authblob->DomainName.Length);
    323
    324	if (blob_len < (u64)dn_off + dn_len || blob_len < (u64)nt_off + nt_len)
    325		return -EINVAL;
    326
    327	/* TODO : use domain name that imported from configuration file */
    328	domain_name = smb_strndup_from_utf16((const char *)authblob + dn_off,
    329					     dn_len, true, conn->local_nls);
    330	if (IS_ERR(domain_name))
    331		return PTR_ERR(domain_name);
    332
    333	/* process NTLMv2 authentication */
    334	ksmbd_debug(AUTH, "decode_ntlmssp_authenticate_blob dname%s\n",
    335		    domain_name);
    336	ret = ksmbd_auth_ntlmv2(sess, (struct ntlmv2_resp *)((char *)authblob + nt_off),
    337				nt_len - CIFS_ENCPWD_SIZE,
    338				domain_name, conn->ntlmssp.cryptkey);
    339	kfree(domain_name);
    340
    341	/* The recovered secondary session key */
    342	if (conn->ntlmssp.client_flags & NTLMSSP_NEGOTIATE_KEY_XCH) {
    343		struct arc4_ctx *ctx_arc4;
    344		unsigned int sess_key_off, sess_key_len;
    345
    346		sess_key_off = le32_to_cpu(authblob->SessionKey.BufferOffset);
    347		sess_key_len = le16_to_cpu(authblob->SessionKey.Length);
    348
    349		if (blob_len < (u64)sess_key_off + sess_key_len)
    350			return -EINVAL;
    351
    352		ctx_arc4 = kmalloc(sizeof(*ctx_arc4), GFP_KERNEL);
    353		if (!ctx_arc4)
    354			return -ENOMEM;
    355
    356		cifs_arc4_setkey(ctx_arc4, sess->sess_key,
    357				 SMB2_NTLMV2_SESSKEY_SIZE);
    358		cifs_arc4_crypt(ctx_arc4, sess->sess_key,
    359				(char *)authblob + sess_key_off, sess_key_len);
    360		kfree_sensitive(ctx_arc4);
    361	}
    362
    363	return ret;
    364}
    365
    366/**
    367 * ksmbd_decode_ntlmssp_neg_blob() - helper function to construct
    368 * negotiate blob
    369 * @negblob: negotiate blob source pointer
    370 * @rsp:     response header pointer to be updated
    371 * @sess:    session of connection
    372 *
    373 */
    374int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
    375				  int blob_len, struct ksmbd_conn *conn)
    376{
    377	if (blob_len < sizeof(struct negotiate_message)) {
    378		ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
    379			    blob_len);
    380		return -EINVAL;
    381	}
    382
    383	if (memcmp(negblob->Signature, "NTLMSSP", 8)) {
    384		ksmbd_debug(AUTH, "blob signature incorrect %s\n",
    385			    negblob->Signature);
    386		return -EINVAL;
    387	}
    388
    389	conn->ntlmssp.client_flags = le32_to_cpu(negblob->NegotiateFlags);
    390	return 0;
    391}
    392
    393/**
    394 * ksmbd_build_ntlmssp_challenge_blob() - helper function to construct
    395 * challenge blob
    396 * @chgblob: challenge blob source pointer to initialize
    397 * @rsp:     response header pointer to be updated
    398 * @sess:    session of connection
    399 *
    400 */
    401unsigned int
    402ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
    403				   struct ksmbd_conn *conn)
    404{
    405	struct target_info *tinfo;
    406	wchar_t *name;
    407	__u8 *target_name;
    408	unsigned int flags, blob_off, blob_len, type, target_info_len = 0;
    409	int len, uni_len, conv_len;
    410	int cflags = conn->ntlmssp.client_flags;
    411
    412	memcpy(chgblob->Signature, NTLMSSP_SIGNATURE, 8);
    413	chgblob->MessageType = NtLmChallenge;
    414
    415	flags = NTLMSSP_NEGOTIATE_UNICODE |
    416		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_TARGET_TYPE_SERVER |
    417		NTLMSSP_NEGOTIATE_TARGET_INFO;
    418
    419	if (cflags & NTLMSSP_NEGOTIATE_SIGN) {
    420		flags |= NTLMSSP_NEGOTIATE_SIGN;
    421		flags |= cflags & (NTLMSSP_NEGOTIATE_128 |
    422				   NTLMSSP_NEGOTIATE_56);
    423	}
    424
    425	if (cflags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
    426		flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
    427
    428	if (cflags & NTLMSSP_REQUEST_TARGET)
    429		flags |= NTLMSSP_REQUEST_TARGET;
    430
    431	if (conn->use_spnego &&
    432	    (cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
    433		flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
    434
    435	if (cflags & NTLMSSP_NEGOTIATE_KEY_XCH)
    436		flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
    437
    438	chgblob->NegotiateFlags = cpu_to_le32(flags);
    439	len = strlen(ksmbd_netbios_name());
    440	name = kmalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
    441	if (!name)
    442		return -ENOMEM;
    443
    444	conv_len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len,
    445				  conn->local_nls);
    446	if (conv_len < 0 || conv_len > len) {
    447		kfree(name);
    448		return -EINVAL;
    449	}
    450
    451	uni_len = UNICODE_LEN(conv_len);
    452
    453	blob_off = sizeof(struct challenge_message);
    454	blob_len = blob_off + uni_len;
    455
    456	chgblob->TargetName.Length = cpu_to_le16(uni_len);
    457	chgblob->TargetName.MaximumLength = cpu_to_le16(uni_len);
    458	chgblob->TargetName.BufferOffset = cpu_to_le32(blob_off);
    459
    460	/* Initialize random conn challenge */
    461	get_random_bytes(conn->ntlmssp.cryptkey, sizeof(__u64));
    462	memcpy(chgblob->Challenge, conn->ntlmssp.cryptkey,
    463	       CIFS_CRYPTO_KEY_SIZE);
    464
    465	/* Add Target Information to security buffer */
    466	chgblob->TargetInfoArray.BufferOffset = cpu_to_le32(blob_len);
    467
    468	target_name = (__u8 *)chgblob + blob_off;
    469	memcpy(target_name, name, uni_len);
    470	tinfo = (struct target_info *)(target_name + uni_len);
    471
    472	chgblob->TargetInfoArray.Length = 0;
    473	/* Add target info list for NetBIOS/DNS settings */
    474	for (type = NTLMSSP_AV_NB_COMPUTER_NAME;
    475	     type <= NTLMSSP_AV_DNS_DOMAIN_NAME; type++) {
    476		tinfo->Type = cpu_to_le16(type);
    477		tinfo->Length = cpu_to_le16(uni_len);
    478		memcpy(tinfo->Content, name, uni_len);
    479		tinfo = (struct target_info *)((char *)tinfo + 4 + uni_len);
    480		target_info_len += 4 + uni_len;
    481	}
    482
    483	/* Add terminator subblock */
    484	tinfo->Type = 0;
    485	tinfo->Length = 0;
    486	target_info_len += 4;
    487
    488	chgblob->TargetInfoArray.Length = cpu_to_le16(target_info_len);
    489	chgblob->TargetInfoArray.MaximumLength = cpu_to_le16(target_info_len);
    490	blob_len += target_info_len;
    491	kfree(name);
    492	ksmbd_debug(AUTH, "NTLMSSP SecurityBufferLength %d\n", blob_len);
    493	return blob_len;
    494}
    495
    496#ifdef CONFIG_SMB_SERVER_KERBEROS5
    497int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
    498			    int in_len, char *out_blob, int *out_len)
    499{
    500	struct ksmbd_spnego_authen_response *resp;
    501	struct ksmbd_user *user = NULL;
    502	int retval;
    503
    504	resp = ksmbd_ipc_spnego_authen_request(in_blob, in_len);
    505	if (!resp) {
    506		ksmbd_debug(AUTH, "SPNEGO_AUTHEN_REQUEST failure\n");
    507		return -EINVAL;
    508	}
    509
    510	if (!(resp->login_response.status & KSMBD_USER_FLAG_OK)) {
    511		ksmbd_debug(AUTH, "krb5 authentication failure\n");
    512		retval = -EPERM;
    513		goto out;
    514	}
    515
    516	if (*out_len <= resp->spnego_blob_len) {
    517		ksmbd_debug(AUTH, "buf len %d, but blob len %d\n",
    518			    *out_len, resp->spnego_blob_len);
    519		retval = -EINVAL;
    520		goto out;
    521	}
    522
    523	if (resp->session_key_len > sizeof(sess->sess_key)) {
    524		ksmbd_debug(AUTH, "session key is too long\n");
    525		retval = -EINVAL;
    526		goto out;
    527	}
    528
    529	user = ksmbd_alloc_user(&resp->login_response);
    530	if (!user) {
    531		ksmbd_debug(AUTH, "login failure\n");
    532		retval = -ENOMEM;
    533		goto out;
    534	}
    535	sess->user = user;
    536
    537	memcpy(sess->sess_key, resp->payload, resp->session_key_len);
    538	memcpy(out_blob, resp->payload + resp->session_key_len,
    539	       resp->spnego_blob_len);
    540	*out_len = resp->spnego_blob_len;
    541	retval = 0;
    542out:
    543	kvfree(resp);
    544	return retval;
    545}
    546#else
    547int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
    548			    int in_len, char *out_blob, int *out_len)
    549{
    550	return -EOPNOTSUPP;
    551}
    552#endif
    553
    554/**
    555 * ksmbd_sign_smb2_pdu() - function to generate packet signing
    556 * @conn:	connection
    557 * @key:	signing key
    558 * @iov:        buffer iov array
    559 * @n_vec:	number of iovecs
    560 * @sig:	signature value generated for client request packet
    561 *
    562 */
    563int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
    564			int n_vec, char *sig)
    565{
    566	struct ksmbd_crypto_ctx *ctx;
    567	int rc, i;
    568
    569	ctx = ksmbd_crypto_ctx_find_hmacsha256();
    570	if (!ctx) {
    571		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
    572		return -ENOMEM;
    573	}
    574
    575	rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
    576				 key,
    577				 SMB2_NTLMV2_SESSKEY_SIZE);
    578	if (rc)
    579		goto out;
    580
    581	rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
    582	if (rc) {
    583		ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
    584		goto out;
    585	}
    586
    587	for (i = 0; i < n_vec; i++) {
    588		rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
    589					 iov[i].iov_base,
    590					 iov[i].iov_len);
    591		if (rc) {
    592			ksmbd_debug(AUTH, "hmacsha256 update error %d\n", rc);
    593			goto out;
    594		}
    595	}
    596
    597	rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), sig);
    598	if (rc)
    599		ksmbd_debug(AUTH, "hmacsha256 generation error %d\n", rc);
    600out:
    601	ksmbd_release_crypto_ctx(ctx);
    602	return rc;
    603}
    604
    605/**
    606 * ksmbd_sign_smb3_pdu() - function to generate packet signing
    607 * @conn:	connection
    608 * @key:	signing key
    609 * @iov:        buffer iov array
    610 * @n_vec:	number of iovecs
    611 * @sig:	signature value generated for client request packet
    612 *
    613 */
    614int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
    615			int n_vec, char *sig)
    616{
    617	struct ksmbd_crypto_ctx *ctx;
    618	int rc, i;
    619
    620	ctx = ksmbd_crypto_ctx_find_cmacaes();
    621	if (!ctx) {
    622		ksmbd_debug(AUTH, "could not crypto alloc cmac\n");
    623		return -ENOMEM;
    624	}
    625
    626	rc = crypto_shash_setkey(CRYPTO_CMACAES_TFM(ctx),
    627				 key,
    628				 SMB2_CMACAES_SIZE);
    629	if (rc)
    630		goto out;
    631
    632	rc = crypto_shash_init(CRYPTO_CMACAES(ctx));
    633	if (rc) {
    634		ksmbd_debug(AUTH, "cmaces init error %d\n", rc);
    635		goto out;
    636	}
    637
    638	for (i = 0; i < n_vec; i++) {
    639		rc = crypto_shash_update(CRYPTO_CMACAES(ctx),
    640					 iov[i].iov_base,
    641					 iov[i].iov_len);
    642		if (rc) {
    643			ksmbd_debug(AUTH, "cmaces update error %d\n", rc);
    644			goto out;
    645		}
    646	}
    647
    648	rc = crypto_shash_final(CRYPTO_CMACAES(ctx), sig);
    649	if (rc)
    650		ksmbd_debug(AUTH, "cmaces generation error %d\n", rc);
    651out:
    652	ksmbd_release_crypto_ctx(ctx);
    653	return rc;
    654}
    655
    656struct derivation {
    657	struct kvec label;
    658	struct kvec context;
    659	bool binding;
    660};
    661
    662static int generate_key(struct ksmbd_session *sess, struct kvec label,
    663			struct kvec context, __u8 *key, unsigned int key_size)
    664{
    665	unsigned char zero = 0x0;
    666	__u8 i[4] = {0, 0, 0, 1};
    667	__u8 L128[4] = {0, 0, 0, 128};
    668	__u8 L256[4] = {0, 0, 1, 0};
    669	int rc;
    670	unsigned char prfhash[SMB2_HMACSHA256_SIZE];
    671	unsigned char *hashptr = prfhash;
    672	struct ksmbd_crypto_ctx *ctx;
    673
    674	memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
    675	memset(key, 0x0, key_size);
    676
    677	ctx = ksmbd_crypto_ctx_find_hmacsha256();
    678	if (!ctx) {
    679		ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
    680		return -ENOMEM;
    681	}
    682
    683	rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
    684				 sess->sess_key,
    685				 SMB2_NTLMV2_SESSKEY_SIZE);
    686	if (rc)
    687		goto smb3signkey_ret;
    688
    689	rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
    690	if (rc) {
    691		ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
    692		goto smb3signkey_ret;
    693	}
    694
    695	rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), i, 4);
    696	if (rc) {
    697		ksmbd_debug(AUTH, "could not update with n\n");
    698		goto smb3signkey_ret;
    699	}
    700
    701	rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
    702				 label.iov_base,
    703				 label.iov_len);
    704	if (rc) {
    705		ksmbd_debug(AUTH, "could not update with label\n");
    706		goto smb3signkey_ret;
    707	}
    708
    709	rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), &zero, 1);
    710	if (rc) {
    711		ksmbd_debug(AUTH, "could not update with zero\n");
    712		goto smb3signkey_ret;
    713	}
    714
    715	rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
    716				 context.iov_base,
    717				 context.iov_len);
    718	if (rc) {
    719		ksmbd_debug(AUTH, "could not update with context\n");
    720		goto smb3signkey_ret;
    721	}
    722
    723	if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
    724	    sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
    725		rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, 4);
    726	else
    727		rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, 4);
    728	if (rc) {
    729		ksmbd_debug(AUTH, "could not update with L\n");
    730		goto smb3signkey_ret;
    731	}
    732
    733	rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), hashptr);
    734	if (rc) {
    735		ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n",
    736			    rc);
    737		goto smb3signkey_ret;
    738	}
    739
    740	memcpy(key, hashptr, key_size);
    741
    742smb3signkey_ret:
    743	ksmbd_release_crypto_ctx(ctx);
    744	return rc;
    745}
    746
    747static int generate_smb3signingkey(struct ksmbd_session *sess,
    748				   struct ksmbd_conn *conn,
    749				   const struct derivation *signing)
    750{
    751	int rc;
    752	struct channel *chann;
    753	char *key;
    754
    755	chann = lookup_chann_list(sess, conn);
    756	if (!chann)
    757		return 0;
    758
    759	if (sess->conn->dialect >= SMB30_PROT_ID && signing->binding)
    760		key = chann->smb3signingkey;
    761	else
    762		key = sess->smb3signingkey;
    763
    764	rc = generate_key(sess, signing->label, signing->context, key,
    765			  SMB3_SIGN_KEY_SIZE);
    766	if (rc)
    767		return rc;
    768
    769	if (!(sess->conn->dialect >= SMB30_PROT_ID && signing->binding))
    770		memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE);
    771
    772	ksmbd_debug(AUTH, "dumping generated AES signing keys\n");
    773	ksmbd_debug(AUTH, "Session Id    %llu\n", sess->id);
    774	ksmbd_debug(AUTH, "Session Key   %*ph\n",
    775		    SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
    776	ksmbd_debug(AUTH, "Signing Key   %*ph\n",
    777		    SMB3_SIGN_KEY_SIZE, key);
    778	return 0;
    779}
    780
    781int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess,
    782			       struct ksmbd_conn *conn)
    783{
    784	struct derivation d;
    785
    786	d.label.iov_base = "SMB2AESCMAC";
    787	d.label.iov_len = 12;
    788	d.context.iov_base = "SmbSign";
    789	d.context.iov_len = 8;
    790	d.binding = conn->binding;
    791
    792	return generate_smb3signingkey(sess, conn, &d);
    793}
    794
    795int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess,
    796				struct ksmbd_conn *conn)
    797{
    798	struct derivation d;
    799
    800	d.label.iov_base = "SMBSigningKey";
    801	d.label.iov_len = 14;
    802	if (conn->binding) {
    803		struct preauth_session *preauth_sess;
    804
    805		preauth_sess = ksmbd_preauth_session_lookup(conn, sess->id);
    806		if (!preauth_sess)
    807			return -ENOENT;
    808		d.context.iov_base = preauth_sess->Preauth_HashValue;
    809	} else {
    810		d.context.iov_base = sess->Preauth_HashValue;
    811	}
    812	d.context.iov_len = 64;
    813	d.binding = conn->binding;
    814
    815	return generate_smb3signingkey(sess, conn, &d);
    816}
    817
    818struct derivation_twin {
    819	struct derivation encryption;
    820	struct derivation decryption;
    821};
    822
    823static int generate_smb3encryptionkey(struct ksmbd_session *sess,
    824				      const struct derivation_twin *ptwin)
    825{
    826	int rc;
    827
    828	rc = generate_key(sess, ptwin->encryption.label,
    829			  ptwin->encryption.context, sess->smb3encryptionkey,
    830			  SMB3_ENC_DEC_KEY_SIZE);
    831	if (rc)
    832		return rc;
    833
    834	rc = generate_key(sess, ptwin->decryption.label,
    835			  ptwin->decryption.context,
    836			  sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
    837	if (rc)
    838		return rc;
    839
    840	ksmbd_debug(AUTH, "dumping generated AES encryption keys\n");
    841	ksmbd_debug(AUTH, "Cipher type   %d\n", sess->conn->cipher_type);
    842	ksmbd_debug(AUTH, "Session Id    %llu\n", sess->id);
    843	ksmbd_debug(AUTH, "Session Key   %*ph\n",
    844		    SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
    845	if (sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
    846	    sess->conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
    847		ksmbd_debug(AUTH, "ServerIn Key  %*ph\n",
    848			    SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3encryptionkey);
    849		ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
    850			    SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3decryptionkey);
    851	} else {
    852		ksmbd_debug(AUTH, "ServerIn Key  %*ph\n",
    853			    SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3encryptionkey);
    854		ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
    855			    SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3decryptionkey);
    856	}
    857	return 0;
    858}
    859
    860int ksmbd_gen_smb30_encryptionkey(struct ksmbd_session *sess)
    861{
    862	struct derivation_twin twin;
    863	struct derivation *d;
    864
    865	d = &twin.encryption;
    866	d->label.iov_base = "SMB2AESCCM";
    867	d->label.iov_len = 11;
    868	d->context.iov_base = "ServerOut";
    869	d->context.iov_len = 10;
    870
    871	d = &twin.decryption;
    872	d->label.iov_base = "SMB2AESCCM";
    873	d->label.iov_len = 11;
    874	d->context.iov_base = "ServerIn ";
    875	d->context.iov_len = 10;
    876
    877	return generate_smb3encryptionkey(sess, &twin);
    878}
    879
    880int ksmbd_gen_smb311_encryptionkey(struct ksmbd_session *sess)
    881{
    882	struct derivation_twin twin;
    883	struct derivation *d;
    884
    885	d = &twin.encryption;
    886	d->label.iov_base = "SMBS2CCipherKey";
    887	d->label.iov_len = 16;
    888	d->context.iov_base = sess->Preauth_HashValue;
    889	d->context.iov_len = 64;
    890
    891	d = &twin.decryption;
    892	d->label.iov_base = "SMBC2SCipherKey";
    893	d->label.iov_len = 16;
    894	d->context.iov_base = sess->Preauth_HashValue;
    895	d->context.iov_len = 64;
    896
    897	return generate_smb3encryptionkey(sess, &twin);
    898}
    899
    900int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
    901				     __u8 *pi_hash)
    902{
    903	int rc;
    904	struct smb2_hdr *rcv_hdr = smb2_get_msg(buf);
    905	char *all_bytes_msg = (char *)&rcv_hdr->ProtocolId;
    906	int msg_size = get_rfc1002_len(buf);
    907	struct ksmbd_crypto_ctx *ctx = NULL;
    908
    909	if (conn->preauth_info->Preauth_HashId !=
    910	    SMB2_PREAUTH_INTEGRITY_SHA512)
    911		return -EINVAL;
    912
    913	ctx = ksmbd_crypto_ctx_find_sha512();
    914	if (!ctx) {
    915		ksmbd_debug(AUTH, "could not alloc sha512\n");
    916		return -ENOMEM;
    917	}
    918
    919	rc = crypto_shash_init(CRYPTO_SHA512(ctx));
    920	if (rc) {
    921		ksmbd_debug(AUTH, "could not init shashn");
    922		goto out;
    923	}
    924
    925	rc = crypto_shash_update(CRYPTO_SHA512(ctx), pi_hash, 64);
    926	if (rc) {
    927		ksmbd_debug(AUTH, "could not update with n\n");
    928		goto out;
    929	}
    930
    931	rc = crypto_shash_update(CRYPTO_SHA512(ctx), all_bytes_msg, msg_size);
    932	if (rc) {
    933		ksmbd_debug(AUTH, "could not update with n\n");
    934		goto out;
    935	}
    936
    937	rc = crypto_shash_final(CRYPTO_SHA512(ctx), pi_hash);
    938	if (rc) {
    939		ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
    940		goto out;
    941	}
    942out:
    943	ksmbd_release_crypto_ctx(ctx);
    944	return rc;
    945}
    946
    947int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
    948		      __u8 *pi_hash)
    949{
    950	int rc;
    951	struct ksmbd_crypto_ctx *ctx = NULL;
    952
    953	ctx = ksmbd_crypto_ctx_find_sha256();
    954	if (!ctx) {
    955		ksmbd_debug(AUTH, "could not alloc sha256\n");
    956		return -ENOMEM;
    957	}
    958
    959	rc = crypto_shash_init(CRYPTO_SHA256(ctx));
    960	if (rc) {
    961		ksmbd_debug(AUTH, "could not init shashn");
    962		goto out;
    963	}
    964
    965	rc = crypto_shash_update(CRYPTO_SHA256(ctx), sd_buf, len);
    966	if (rc) {
    967		ksmbd_debug(AUTH, "could not update with n\n");
    968		goto out;
    969	}
    970
    971	rc = crypto_shash_final(CRYPTO_SHA256(ctx), pi_hash);
    972	if (rc) {
    973		ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
    974		goto out;
    975	}
    976out:
    977	ksmbd_release_crypto_ctx(ctx);
    978	return rc;
    979}
    980
    981static int ksmbd_get_encryption_key(struct ksmbd_conn *conn, __u64 ses_id,
    982				    int enc, u8 *key)
    983{
    984	struct ksmbd_session *sess;
    985	u8 *ses_enc_key;
    986
    987	sess = ksmbd_session_lookup_all(conn, ses_id);
    988	if (!sess)
    989		return -EINVAL;
    990
    991	ses_enc_key = enc ? sess->smb3encryptionkey :
    992		sess->smb3decryptionkey;
    993	memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
    994
    995	return 0;
    996}
    997
    998static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
    999				   unsigned int buflen)
   1000{
   1001	void *addr;
   1002
   1003	if (is_vmalloc_addr(buf))
   1004		addr = vmalloc_to_page(buf);
   1005	else
   1006		addr = virt_to_page(buf);
   1007	sg_set_page(sg, addr, buflen, offset_in_page(buf));
   1008}
   1009
   1010static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
   1011					 u8 *sign)
   1012{
   1013	struct scatterlist *sg;
   1014	unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
   1015	int i, nr_entries[3] = {0}, total_entries = 0, sg_idx = 0;
   1016
   1017	if (!nvec)
   1018		return NULL;
   1019
   1020	for (i = 0; i < nvec - 1; i++) {
   1021		unsigned long kaddr = (unsigned long)iov[i + 1].iov_base;
   1022
   1023		if (is_vmalloc_addr(iov[i + 1].iov_base)) {
   1024			nr_entries[i] = ((kaddr + iov[i + 1].iov_len +
   1025					PAGE_SIZE - 1) >> PAGE_SHIFT) -
   1026				(kaddr >> PAGE_SHIFT);
   1027		} else {
   1028			nr_entries[i]++;
   1029		}
   1030		total_entries += nr_entries[i];
   1031	}
   1032
   1033	/* Add two entries for transform header and signature */
   1034	total_entries += 2;
   1035
   1036	sg = kmalloc_array(total_entries, sizeof(struct scatterlist), GFP_KERNEL);
   1037	if (!sg)
   1038		return NULL;
   1039
   1040	sg_init_table(sg, total_entries);
   1041	smb2_sg_set_buf(&sg[sg_idx++], iov[0].iov_base + 24, assoc_data_len);
   1042	for (i = 0; i < nvec - 1; i++) {
   1043		void *data = iov[i + 1].iov_base;
   1044		int len = iov[i + 1].iov_len;
   1045
   1046		if (is_vmalloc_addr(data)) {
   1047			int j, offset = offset_in_page(data);
   1048
   1049			for (j = 0; j < nr_entries[i]; j++) {
   1050				unsigned int bytes = PAGE_SIZE - offset;
   1051
   1052				if (!len)
   1053					break;
   1054
   1055				if (bytes > len)
   1056					bytes = len;
   1057
   1058				sg_set_page(&sg[sg_idx++],
   1059					    vmalloc_to_page(data), bytes,
   1060					    offset_in_page(data));
   1061
   1062				data += bytes;
   1063				len -= bytes;
   1064				offset = 0;
   1065			}
   1066		} else {
   1067			sg_set_page(&sg[sg_idx++], virt_to_page(data), len,
   1068				    offset_in_page(data));
   1069		}
   1070	}
   1071	smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE);
   1072	return sg;
   1073}
   1074
   1075int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
   1076			unsigned int nvec, int enc)
   1077{
   1078	struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base);
   1079	unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
   1080	int rc;
   1081	struct scatterlist *sg;
   1082	u8 sign[SMB2_SIGNATURE_SIZE] = {};
   1083	u8 key[SMB3_ENC_DEC_KEY_SIZE];
   1084	struct aead_request *req;
   1085	char *iv;
   1086	unsigned int iv_len;
   1087	struct crypto_aead *tfm;
   1088	unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
   1089	struct ksmbd_crypto_ctx *ctx;
   1090
   1091	rc = ksmbd_get_encryption_key(conn,
   1092				      le64_to_cpu(tr_hdr->SessionId),
   1093				      enc,
   1094				      key);
   1095	if (rc) {
   1096		pr_err("Could not get %scryption key\n", enc ? "en" : "de");
   1097		return rc;
   1098	}
   1099
   1100	if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
   1101	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
   1102		ctx = ksmbd_crypto_ctx_find_gcm();
   1103	else
   1104		ctx = ksmbd_crypto_ctx_find_ccm();
   1105	if (!ctx) {
   1106		pr_err("crypto alloc failed\n");
   1107		return -ENOMEM;
   1108	}
   1109
   1110	if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
   1111	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
   1112		tfm = CRYPTO_GCM(ctx);
   1113	else
   1114		tfm = CRYPTO_CCM(ctx);
   1115
   1116	if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
   1117	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
   1118		rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
   1119	else
   1120		rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
   1121	if (rc) {
   1122		pr_err("Failed to set aead key %d\n", rc);
   1123		goto free_ctx;
   1124	}
   1125
   1126	rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE);
   1127	if (rc) {
   1128		pr_err("Failed to set authsize %d\n", rc);
   1129		goto free_ctx;
   1130	}
   1131
   1132	req = aead_request_alloc(tfm, GFP_KERNEL);
   1133	if (!req) {
   1134		rc = -ENOMEM;
   1135		goto free_ctx;
   1136	}
   1137
   1138	if (!enc) {
   1139		memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
   1140		crypt_len += SMB2_SIGNATURE_SIZE;
   1141	}
   1142
   1143	sg = ksmbd_init_sg(iov, nvec, sign);
   1144	if (!sg) {
   1145		pr_err("Failed to init sg\n");
   1146		rc = -ENOMEM;
   1147		goto free_req;
   1148	}
   1149
   1150	iv_len = crypto_aead_ivsize(tfm);
   1151	iv = kzalloc(iv_len, GFP_KERNEL);
   1152	if (!iv) {
   1153		rc = -ENOMEM;
   1154		goto free_sg;
   1155	}
   1156
   1157	if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
   1158	    conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
   1159		memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
   1160	} else {
   1161		iv[0] = 3;
   1162		memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
   1163	}
   1164
   1165	aead_request_set_crypt(req, sg, sg, crypt_len, iv);
   1166	aead_request_set_ad(req, assoc_data_len);
   1167	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
   1168
   1169	if (enc)
   1170		rc = crypto_aead_encrypt(req);
   1171	else
   1172		rc = crypto_aead_decrypt(req);
   1173	if (rc)
   1174		goto free_iv;
   1175
   1176	if (enc)
   1177		memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
   1178
   1179free_iv:
   1180	kfree(iv);
   1181free_sg:
   1182	kfree(sg);
   1183free_req:
   1184	kfree(req);
   1185free_ctx:
   1186	ksmbd_release_crypto_ctx(ctx);
   1187	return rc;
   1188}