0001
0002
0003
0004
0005
0006
0007 #include <linux/kernel.h>
0008 #include <linux/fs.h>
0009 #include <linux/uaccess.h>
0010 #include <linux/backing-dev.h>
0011 #include <linux/writeback.h>
0012 #include <linux/uio.h>
0013 #include <linux/xattr.h>
0014 #include <crypto/hash.h>
0015 #include <crypto/aead.h>
0016 #include <linux/random.h>
0017 #include <linux/scatterlist.h>
0018
0019 #include "auth.h"
0020 #include "glob.h"
0021
0022 #include <linux/fips.h>
0023 #include <crypto/des.h>
0024
0025 #include "server.h"
0026 #include "smb_common.h"
0027 #include "connection.h"
0028 #include "mgmt/user_session.h"
0029 #include "mgmt/user_config.h"
0030 #include "crypto_ctx.h"
0031 #include "transport_ipc.h"
0032 #include "../smbfs_common/arc4.h"
0033
0034
0035
0036
0037
0038
0039 static char NEGOTIATE_GSS_HEADER[AUTH_GSS_LENGTH] = {
0040 #ifdef CONFIG_SMB_SERVER_KERBEROS5
0041 0x60, 0x5e, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05,
0042 0x05, 0x02, 0xa0, 0x54, 0x30, 0x52, 0xa0, 0x24,
0043 0x30, 0x22, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0044 0xf7, 0x12, 0x01, 0x02, 0x02, 0x06, 0x09, 0x2a,
0045 0x86, 0x48, 0x82, 0xf7, 0x12, 0x01, 0x02, 0x02,
0046 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
0047 0x37, 0x02, 0x02, 0x0a, 0xa3, 0x2a, 0x30, 0x28,
0048 0xa0, 0x26, 0x1b, 0x24, 0x6e, 0x6f, 0x74, 0x5f,
0049 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x5f,
0050 0x69, 0x6e, 0x5f, 0x52, 0x46, 0x43, 0x34, 0x31,
0051 0x37, 0x38, 0x40, 0x70, 0x6c, 0x65, 0x61, 0x73,
0052 0x65, 0x5f, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65
0053 #else
0054 0x60, 0x48, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05,
0055 0x05, 0x02, 0xa0, 0x3e, 0x30, 0x3c, 0xa0, 0x0e,
0056 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
0057 0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa3, 0x2a,
0058 0x30, 0x28, 0xa0, 0x26, 0x1b, 0x24, 0x6e, 0x6f,
0059 0x74, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65,
0060 0x64, 0x5f, 0x69, 0x6e, 0x5f, 0x52, 0x46, 0x43,
0061 0x34, 0x31, 0x37, 0x38, 0x40, 0x70, 0x6c, 0x65,
0062 0x61, 0x73, 0x65, 0x5f, 0x69, 0x67, 0x6e, 0x6f,
0063 0x72, 0x65
0064 #endif
0065 };
0066
0067 void ksmbd_copy_gss_neg_header(void *buf)
0068 {
0069 memcpy(buf, NEGOTIATE_GSS_HEADER, AUTH_GSS_LENGTH);
0070 }
0071
0072
0073
0074
0075
0076
0077
0078
0079 static int ksmbd_gen_sess_key(struct ksmbd_session *sess, char *hash,
0080 char *hmac)
0081 {
0082 struct ksmbd_crypto_ctx *ctx;
0083 int rc;
0084
0085 ctx = ksmbd_crypto_ctx_find_hmacmd5();
0086 if (!ctx) {
0087 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
0088 return -ENOMEM;
0089 }
0090
0091 rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
0092 hash,
0093 CIFS_HMAC_MD5_HASH_SIZE);
0094 if (rc) {
0095 ksmbd_debug(AUTH, "hmacmd5 set key fail error %d\n", rc);
0096 goto out;
0097 }
0098
0099 rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
0100 if (rc) {
0101 ksmbd_debug(AUTH, "could not init hmacmd5 error %d\n", rc);
0102 goto out;
0103 }
0104
0105 rc = crypto_shash_update(CRYPTO_HMACMD5(ctx),
0106 hmac,
0107 SMB2_NTLMV2_SESSKEY_SIZE);
0108 if (rc) {
0109 ksmbd_debug(AUTH, "Could not update with response error %d\n", rc);
0110 goto out;
0111 }
0112
0113 rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), sess->sess_key);
0114 if (rc) {
0115 ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n", rc);
0116 goto out;
0117 }
0118
0119 out:
0120 ksmbd_release_crypto_ctx(ctx);
0121 return rc;
0122 }
0123
0124 static int calc_ntlmv2_hash(struct ksmbd_conn *conn, struct ksmbd_session *sess,
0125 char *ntlmv2_hash, char *dname)
0126 {
0127 int ret, len, conv_len;
0128 wchar_t *domain = NULL;
0129 __le16 *uniname = NULL;
0130 struct ksmbd_crypto_ctx *ctx;
0131
0132 ctx = ksmbd_crypto_ctx_find_hmacmd5();
0133 if (!ctx) {
0134 ksmbd_debug(AUTH, "can't generate ntlmv2 hash\n");
0135 return -ENOMEM;
0136 }
0137
0138 ret = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
0139 user_passkey(sess->user),
0140 CIFS_ENCPWD_SIZE);
0141 if (ret) {
0142 ksmbd_debug(AUTH, "Could not set NT Hash as a key\n");
0143 goto out;
0144 }
0145
0146 ret = crypto_shash_init(CRYPTO_HMACMD5(ctx));
0147 if (ret) {
0148 ksmbd_debug(AUTH, "could not init hmacmd5\n");
0149 goto out;
0150 }
0151
0152
0153 len = strlen(user_name(sess->user));
0154 uniname = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
0155 if (!uniname) {
0156 ret = -ENOMEM;
0157 goto out;
0158 }
0159
0160 conv_len = smb_strtoUTF16(uniname, user_name(sess->user), len,
0161 conn->local_nls);
0162 if (conv_len < 0 || conv_len > len) {
0163 ret = -EINVAL;
0164 goto out;
0165 }
0166 UniStrupr(uniname);
0167
0168 ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
0169 (char *)uniname,
0170 UNICODE_LEN(conv_len));
0171 if (ret) {
0172 ksmbd_debug(AUTH, "Could not update with user\n");
0173 goto out;
0174 }
0175
0176
0177 len = strlen(dname);
0178 domain = kzalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
0179 if (!domain) {
0180 ret = -ENOMEM;
0181 goto out;
0182 }
0183
0184 conv_len = smb_strtoUTF16((__le16 *)domain, dname, len,
0185 conn->local_nls);
0186 if (conv_len < 0 || conv_len > len) {
0187 ret = -EINVAL;
0188 goto out;
0189 }
0190
0191 ret = crypto_shash_update(CRYPTO_HMACMD5(ctx),
0192 (char *)domain,
0193 UNICODE_LEN(conv_len));
0194 if (ret) {
0195 ksmbd_debug(AUTH, "Could not update with domain\n");
0196 goto out;
0197 }
0198
0199 ret = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_hash);
0200 if (ret)
0201 ksmbd_debug(AUTH, "Could not generate md5 hash\n");
0202 out:
0203 kfree(uniname);
0204 kfree(domain);
0205 ksmbd_release_crypto_ctx(ctx);
0206 return ret;
0207 }
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess,
0219 struct ntlmv2_resp *ntlmv2, int blen, char *domain_name,
0220 char *cryptkey)
0221 {
0222 char ntlmv2_hash[CIFS_ENCPWD_SIZE];
0223 char ntlmv2_rsp[CIFS_HMAC_MD5_HASH_SIZE];
0224 struct ksmbd_crypto_ctx *ctx;
0225 char *construct = NULL;
0226 int rc, len;
0227
0228 ctx = ksmbd_crypto_ctx_find_hmacmd5();
0229 if (!ctx) {
0230 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
0231 return -ENOMEM;
0232 }
0233
0234 rc = calc_ntlmv2_hash(conn, sess, ntlmv2_hash, domain_name);
0235 if (rc) {
0236 ksmbd_debug(AUTH, "could not get v2 hash rc %d\n", rc);
0237 goto out;
0238 }
0239
0240 rc = crypto_shash_setkey(CRYPTO_HMACMD5_TFM(ctx),
0241 ntlmv2_hash,
0242 CIFS_HMAC_MD5_HASH_SIZE);
0243 if (rc) {
0244 ksmbd_debug(AUTH, "Could not set NTLMV2 Hash as a key\n");
0245 goto out;
0246 }
0247
0248 rc = crypto_shash_init(CRYPTO_HMACMD5(ctx));
0249 if (rc) {
0250 ksmbd_debug(AUTH, "Could not init hmacmd5\n");
0251 goto out;
0252 }
0253
0254 len = CIFS_CRYPTO_KEY_SIZE + blen;
0255 construct = kzalloc(len, GFP_KERNEL);
0256 if (!construct) {
0257 rc = -ENOMEM;
0258 goto out;
0259 }
0260
0261 memcpy(construct, cryptkey, CIFS_CRYPTO_KEY_SIZE);
0262 memcpy(construct + CIFS_CRYPTO_KEY_SIZE, &ntlmv2->blob_signature, blen);
0263
0264 rc = crypto_shash_update(CRYPTO_HMACMD5(ctx), construct, len);
0265 if (rc) {
0266 ksmbd_debug(AUTH, "Could not update with response\n");
0267 goto out;
0268 }
0269
0270 rc = crypto_shash_final(CRYPTO_HMACMD5(ctx), ntlmv2_rsp);
0271 if (rc) {
0272 ksmbd_debug(AUTH, "Could not generate md5 hash\n");
0273 goto out;
0274 }
0275
0276 rc = ksmbd_gen_sess_key(sess, ntlmv2_hash, ntlmv2_rsp);
0277 if (rc) {
0278 ksmbd_debug(AUTH, "Could not generate sess key\n");
0279 goto out;
0280 }
0281
0282 if (memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE) != 0)
0283 rc = -EINVAL;
0284 out:
0285 ksmbd_release_crypto_ctx(ctx);
0286 kfree(construct);
0287 return rc;
0288 }
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299 int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
0300 int blob_len, struct ksmbd_conn *conn,
0301 struct ksmbd_session *sess)
0302 {
0303 char *domain_name;
0304 unsigned int nt_off, dn_off;
0305 unsigned short nt_len, dn_len;
0306 int ret;
0307
0308 if (blob_len < sizeof(struct authenticate_message)) {
0309 ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
0310 blob_len);
0311 return -EINVAL;
0312 }
0313
0314 if (memcmp(authblob->Signature, "NTLMSSP", 8)) {
0315 ksmbd_debug(AUTH, "blob signature incorrect %s\n",
0316 authblob->Signature);
0317 return -EINVAL;
0318 }
0319
0320 nt_off = le32_to_cpu(authblob->NtChallengeResponse.BufferOffset);
0321 nt_len = le16_to_cpu(authblob->NtChallengeResponse.Length);
0322 dn_off = le32_to_cpu(authblob->DomainName.BufferOffset);
0323 dn_len = le16_to_cpu(authblob->DomainName.Length);
0324
0325 if (blob_len < (u64)dn_off + dn_len || blob_len < (u64)nt_off + nt_len)
0326 return -EINVAL;
0327
0328
0329 domain_name = smb_strndup_from_utf16((const char *)authblob + dn_off,
0330 dn_len, true, conn->local_nls);
0331 if (IS_ERR(domain_name))
0332 return PTR_ERR(domain_name);
0333
0334
0335 ksmbd_debug(AUTH, "decode_ntlmssp_authenticate_blob dname%s\n",
0336 domain_name);
0337 ret = ksmbd_auth_ntlmv2(conn, sess,
0338 (struct ntlmv2_resp *)((char *)authblob + nt_off),
0339 nt_len - CIFS_ENCPWD_SIZE,
0340 domain_name, conn->ntlmssp.cryptkey);
0341 kfree(domain_name);
0342
0343
0344 if (conn->ntlmssp.client_flags & NTLMSSP_NEGOTIATE_KEY_XCH) {
0345 struct arc4_ctx *ctx_arc4;
0346 unsigned int sess_key_off, sess_key_len;
0347
0348 sess_key_off = le32_to_cpu(authblob->SessionKey.BufferOffset);
0349 sess_key_len = le16_to_cpu(authblob->SessionKey.Length);
0350
0351 if (blob_len < (u64)sess_key_off + sess_key_len)
0352 return -EINVAL;
0353
0354 ctx_arc4 = kmalloc(sizeof(*ctx_arc4), GFP_KERNEL);
0355 if (!ctx_arc4)
0356 return -ENOMEM;
0357
0358 cifs_arc4_setkey(ctx_arc4, sess->sess_key,
0359 SMB2_NTLMV2_SESSKEY_SIZE);
0360 cifs_arc4_crypt(ctx_arc4, sess->sess_key,
0361 (char *)authblob + sess_key_off, sess_key_len);
0362 kfree_sensitive(ctx_arc4);
0363 }
0364
0365 return ret;
0366 }
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376 int ksmbd_decode_ntlmssp_neg_blob(struct negotiate_message *negblob,
0377 int blob_len, struct ksmbd_conn *conn)
0378 {
0379 if (blob_len < sizeof(struct negotiate_message)) {
0380 ksmbd_debug(AUTH, "negotiate blob len %d too small\n",
0381 blob_len);
0382 return -EINVAL;
0383 }
0384
0385 if (memcmp(negblob->Signature, "NTLMSSP", 8)) {
0386 ksmbd_debug(AUTH, "blob signature incorrect %s\n",
0387 negblob->Signature);
0388 return -EINVAL;
0389 }
0390
0391 conn->ntlmssp.client_flags = le32_to_cpu(negblob->NegotiateFlags);
0392 return 0;
0393 }
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403 unsigned int
0404 ksmbd_build_ntlmssp_challenge_blob(struct challenge_message *chgblob,
0405 struct ksmbd_conn *conn)
0406 {
0407 struct target_info *tinfo;
0408 wchar_t *name;
0409 __u8 *target_name;
0410 unsigned int flags, blob_off, blob_len, type, target_info_len = 0;
0411 int len, uni_len, conv_len;
0412 int cflags = conn->ntlmssp.client_flags;
0413
0414 memcpy(chgblob->Signature, NTLMSSP_SIGNATURE, 8);
0415 chgblob->MessageType = NtLmChallenge;
0416
0417 flags = NTLMSSP_NEGOTIATE_UNICODE |
0418 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_TARGET_TYPE_SERVER |
0419 NTLMSSP_NEGOTIATE_TARGET_INFO;
0420
0421 if (cflags & NTLMSSP_NEGOTIATE_SIGN) {
0422 flags |= NTLMSSP_NEGOTIATE_SIGN;
0423 flags |= cflags & (NTLMSSP_NEGOTIATE_128 |
0424 NTLMSSP_NEGOTIATE_56);
0425 }
0426
0427 if (cflags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
0428 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
0429
0430 if (cflags & NTLMSSP_REQUEST_TARGET)
0431 flags |= NTLMSSP_REQUEST_TARGET;
0432
0433 if (conn->use_spnego &&
0434 (cflags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
0435 flags |= NTLMSSP_NEGOTIATE_EXTENDED_SEC;
0436
0437 if (cflags & NTLMSSP_NEGOTIATE_KEY_XCH)
0438 flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
0439
0440 chgblob->NegotiateFlags = cpu_to_le32(flags);
0441 len = strlen(ksmbd_netbios_name());
0442 name = kmalloc(2 + UNICODE_LEN(len), GFP_KERNEL);
0443 if (!name)
0444 return -ENOMEM;
0445
0446 conv_len = smb_strtoUTF16((__le16 *)name, ksmbd_netbios_name(), len,
0447 conn->local_nls);
0448 if (conv_len < 0 || conv_len > len) {
0449 kfree(name);
0450 return -EINVAL;
0451 }
0452
0453 uni_len = UNICODE_LEN(conv_len);
0454
0455 blob_off = sizeof(struct challenge_message);
0456 blob_len = blob_off + uni_len;
0457
0458 chgblob->TargetName.Length = cpu_to_le16(uni_len);
0459 chgblob->TargetName.MaximumLength = cpu_to_le16(uni_len);
0460 chgblob->TargetName.BufferOffset = cpu_to_le32(blob_off);
0461
0462
0463 get_random_bytes(conn->ntlmssp.cryptkey, sizeof(__u64));
0464 memcpy(chgblob->Challenge, conn->ntlmssp.cryptkey,
0465 CIFS_CRYPTO_KEY_SIZE);
0466
0467
0468 chgblob->TargetInfoArray.BufferOffset = cpu_to_le32(blob_len);
0469
0470 target_name = (__u8 *)chgblob + blob_off;
0471 memcpy(target_name, name, uni_len);
0472 tinfo = (struct target_info *)(target_name + uni_len);
0473
0474 chgblob->TargetInfoArray.Length = 0;
0475
0476 for (type = NTLMSSP_AV_NB_COMPUTER_NAME;
0477 type <= NTLMSSP_AV_DNS_DOMAIN_NAME; type++) {
0478 tinfo->Type = cpu_to_le16(type);
0479 tinfo->Length = cpu_to_le16(uni_len);
0480 memcpy(tinfo->Content, name, uni_len);
0481 tinfo = (struct target_info *)((char *)tinfo + 4 + uni_len);
0482 target_info_len += 4 + uni_len;
0483 }
0484
0485
0486 tinfo->Type = 0;
0487 tinfo->Length = 0;
0488 target_info_len += 4;
0489
0490 chgblob->TargetInfoArray.Length = cpu_to_le16(target_info_len);
0491 chgblob->TargetInfoArray.MaximumLength = cpu_to_le16(target_info_len);
0492 blob_len += target_info_len;
0493 kfree(name);
0494 ksmbd_debug(AUTH, "NTLMSSP SecurityBufferLength %d\n", blob_len);
0495 return blob_len;
0496 }
0497
0498 #ifdef CONFIG_SMB_SERVER_KERBEROS5
0499 int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
0500 int in_len, char *out_blob, int *out_len)
0501 {
0502 struct ksmbd_spnego_authen_response *resp;
0503 struct ksmbd_user *user = NULL;
0504 int retval;
0505
0506 resp = ksmbd_ipc_spnego_authen_request(in_blob, in_len);
0507 if (!resp) {
0508 ksmbd_debug(AUTH, "SPNEGO_AUTHEN_REQUEST failure\n");
0509 return -EINVAL;
0510 }
0511
0512 if (!(resp->login_response.status & KSMBD_USER_FLAG_OK)) {
0513 ksmbd_debug(AUTH, "krb5 authentication failure\n");
0514 retval = -EPERM;
0515 goto out;
0516 }
0517
0518 if (*out_len <= resp->spnego_blob_len) {
0519 ksmbd_debug(AUTH, "buf len %d, but blob len %d\n",
0520 *out_len, resp->spnego_blob_len);
0521 retval = -EINVAL;
0522 goto out;
0523 }
0524
0525 if (resp->session_key_len > sizeof(sess->sess_key)) {
0526 ksmbd_debug(AUTH, "session key is too long\n");
0527 retval = -EINVAL;
0528 goto out;
0529 }
0530
0531 user = ksmbd_alloc_user(&resp->login_response);
0532 if (!user) {
0533 ksmbd_debug(AUTH, "login failure\n");
0534 retval = -ENOMEM;
0535 goto out;
0536 }
0537 sess->user = user;
0538
0539 memcpy(sess->sess_key, resp->payload, resp->session_key_len);
0540 memcpy(out_blob, resp->payload + resp->session_key_len,
0541 resp->spnego_blob_len);
0542 *out_len = resp->spnego_blob_len;
0543 retval = 0;
0544 out:
0545 kvfree(resp);
0546 return retval;
0547 }
0548 #else
0549 int ksmbd_krb5_authenticate(struct ksmbd_session *sess, char *in_blob,
0550 int in_len, char *out_blob, int *out_len)
0551 {
0552 return -EOPNOTSUPP;
0553 }
0554 #endif
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565 int ksmbd_sign_smb2_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
0566 int n_vec, char *sig)
0567 {
0568 struct ksmbd_crypto_ctx *ctx;
0569 int rc, i;
0570
0571 ctx = ksmbd_crypto_ctx_find_hmacsha256();
0572 if (!ctx) {
0573 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
0574 return -ENOMEM;
0575 }
0576
0577 rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
0578 key,
0579 SMB2_NTLMV2_SESSKEY_SIZE);
0580 if (rc)
0581 goto out;
0582
0583 rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
0584 if (rc) {
0585 ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
0586 goto out;
0587 }
0588
0589 for (i = 0; i < n_vec; i++) {
0590 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
0591 iov[i].iov_base,
0592 iov[i].iov_len);
0593 if (rc) {
0594 ksmbd_debug(AUTH, "hmacsha256 update error %d\n", rc);
0595 goto out;
0596 }
0597 }
0598
0599 rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), sig);
0600 if (rc)
0601 ksmbd_debug(AUTH, "hmacsha256 generation error %d\n", rc);
0602 out:
0603 ksmbd_release_crypto_ctx(ctx);
0604 return rc;
0605 }
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616 int ksmbd_sign_smb3_pdu(struct ksmbd_conn *conn, char *key, struct kvec *iov,
0617 int n_vec, char *sig)
0618 {
0619 struct ksmbd_crypto_ctx *ctx;
0620 int rc, i;
0621
0622 ctx = ksmbd_crypto_ctx_find_cmacaes();
0623 if (!ctx) {
0624 ksmbd_debug(AUTH, "could not crypto alloc cmac\n");
0625 return -ENOMEM;
0626 }
0627
0628 rc = crypto_shash_setkey(CRYPTO_CMACAES_TFM(ctx),
0629 key,
0630 SMB2_CMACAES_SIZE);
0631 if (rc)
0632 goto out;
0633
0634 rc = crypto_shash_init(CRYPTO_CMACAES(ctx));
0635 if (rc) {
0636 ksmbd_debug(AUTH, "cmaces init error %d\n", rc);
0637 goto out;
0638 }
0639
0640 for (i = 0; i < n_vec; i++) {
0641 rc = crypto_shash_update(CRYPTO_CMACAES(ctx),
0642 iov[i].iov_base,
0643 iov[i].iov_len);
0644 if (rc) {
0645 ksmbd_debug(AUTH, "cmaces update error %d\n", rc);
0646 goto out;
0647 }
0648 }
0649
0650 rc = crypto_shash_final(CRYPTO_CMACAES(ctx), sig);
0651 if (rc)
0652 ksmbd_debug(AUTH, "cmaces generation error %d\n", rc);
0653 out:
0654 ksmbd_release_crypto_ctx(ctx);
0655 return rc;
0656 }
0657
0658 struct derivation {
0659 struct kvec label;
0660 struct kvec context;
0661 bool binding;
0662 };
0663
0664 static int generate_key(struct ksmbd_conn *conn, struct ksmbd_session *sess,
0665 struct kvec label, struct kvec context, __u8 *key,
0666 unsigned int key_size)
0667 {
0668 unsigned char zero = 0x0;
0669 __u8 i[4] = {0, 0, 0, 1};
0670 __u8 L128[4] = {0, 0, 0, 128};
0671 __u8 L256[4] = {0, 0, 1, 0};
0672 int rc;
0673 unsigned char prfhash[SMB2_HMACSHA256_SIZE];
0674 unsigned char *hashptr = prfhash;
0675 struct ksmbd_crypto_ctx *ctx;
0676
0677 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE);
0678 memset(key, 0x0, key_size);
0679
0680 ctx = ksmbd_crypto_ctx_find_hmacsha256();
0681 if (!ctx) {
0682 ksmbd_debug(AUTH, "could not crypto alloc hmacmd5\n");
0683 return -ENOMEM;
0684 }
0685
0686 rc = crypto_shash_setkey(CRYPTO_HMACSHA256_TFM(ctx),
0687 sess->sess_key,
0688 SMB2_NTLMV2_SESSKEY_SIZE);
0689 if (rc)
0690 goto smb3signkey_ret;
0691
0692 rc = crypto_shash_init(CRYPTO_HMACSHA256(ctx));
0693 if (rc) {
0694 ksmbd_debug(AUTH, "hmacsha256 init error %d\n", rc);
0695 goto smb3signkey_ret;
0696 }
0697
0698 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), i, 4);
0699 if (rc) {
0700 ksmbd_debug(AUTH, "could not update with n\n");
0701 goto smb3signkey_ret;
0702 }
0703
0704 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
0705 label.iov_base,
0706 label.iov_len);
0707 if (rc) {
0708 ksmbd_debug(AUTH, "could not update with label\n");
0709 goto smb3signkey_ret;
0710 }
0711
0712 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), &zero, 1);
0713 if (rc) {
0714 ksmbd_debug(AUTH, "could not update with zero\n");
0715 goto smb3signkey_ret;
0716 }
0717
0718 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx),
0719 context.iov_base,
0720 context.iov_len);
0721 if (rc) {
0722 ksmbd_debug(AUTH, "could not update with context\n");
0723 goto smb3signkey_ret;
0724 }
0725
0726 if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
0727 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
0728 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L256, 4);
0729 else
0730 rc = crypto_shash_update(CRYPTO_HMACSHA256(ctx), L128, 4);
0731 if (rc) {
0732 ksmbd_debug(AUTH, "could not update with L\n");
0733 goto smb3signkey_ret;
0734 }
0735
0736 rc = crypto_shash_final(CRYPTO_HMACSHA256(ctx), hashptr);
0737 if (rc) {
0738 ksmbd_debug(AUTH, "Could not generate hmacmd5 hash error %d\n",
0739 rc);
0740 goto smb3signkey_ret;
0741 }
0742
0743 memcpy(key, hashptr, key_size);
0744
0745 smb3signkey_ret:
0746 ksmbd_release_crypto_ctx(ctx);
0747 return rc;
0748 }
0749
0750 static int generate_smb3signingkey(struct ksmbd_session *sess,
0751 struct ksmbd_conn *conn,
0752 const struct derivation *signing)
0753 {
0754 int rc;
0755 struct channel *chann;
0756 char *key;
0757
0758 chann = lookup_chann_list(sess, conn);
0759 if (!chann)
0760 return 0;
0761
0762 if (conn->dialect >= SMB30_PROT_ID && signing->binding)
0763 key = chann->smb3signingkey;
0764 else
0765 key = sess->smb3signingkey;
0766
0767 rc = generate_key(conn, sess, signing->label, signing->context, key,
0768 SMB3_SIGN_KEY_SIZE);
0769 if (rc)
0770 return rc;
0771
0772 if (!(conn->dialect >= SMB30_PROT_ID && signing->binding))
0773 memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE);
0774
0775 ksmbd_debug(AUTH, "dumping generated AES signing keys\n");
0776 ksmbd_debug(AUTH, "Session Id %llu\n", sess->id);
0777 ksmbd_debug(AUTH, "Session Key %*ph\n",
0778 SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
0779 ksmbd_debug(AUTH, "Signing Key %*ph\n",
0780 SMB3_SIGN_KEY_SIZE, key);
0781 return 0;
0782 }
0783
0784 int ksmbd_gen_smb30_signingkey(struct ksmbd_session *sess,
0785 struct ksmbd_conn *conn)
0786 {
0787 struct derivation d;
0788
0789 d.label.iov_base = "SMB2AESCMAC";
0790 d.label.iov_len = 12;
0791 d.context.iov_base = "SmbSign";
0792 d.context.iov_len = 8;
0793 d.binding = conn->binding;
0794
0795 return generate_smb3signingkey(sess, conn, &d);
0796 }
0797
0798 int ksmbd_gen_smb311_signingkey(struct ksmbd_session *sess,
0799 struct ksmbd_conn *conn)
0800 {
0801 struct derivation d;
0802
0803 d.label.iov_base = "SMBSigningKey";
0804 d.label.iov_len = 14;
0805 if (conn->binding) {
0806 struct preauth_session *preauth_sess;
0807
0808 preauth_sess = ksmbd_preauth_session_lookup(conn, sess->id);
0809 if (!preauth_sess)
0810 return -ENOENT;
0811 d.context.iov_base = preauth_sess->Preauth_HashValue;
0812 } else {
0813 d.context.iov_base = sess->Preauth_HashValue;
0814 }
0815 d.context.iov_len = 64;
0816 d.binding = conn->binding;
0817
0818 return generate_smb3signingkey(sess, conn, &d);
0819 }
0820
0821 struct derivation_twin {
0822 struct derivation encryption;
0823 struct derivation decryption;
0824 };
0825
0826 static int generate_smb3encryptionkey(struct ksmbd_conn *conn,
0827 struct ksmbd_session *sess,
0828 const struct derivation_twin *ptwin)
0829 {
0830 int rc;
0831
0832 rc = generate_key(conn, sess, ptwin->encryption.label,
0833 ptwin->encryption.context, sess->smb3encryptionkey,
0834 SMB3_ENC_DEC_KEY_SIZE);
0835 if (rc)
0836 return rc;
0837
0838 rc = generate_key(conn, sess, ptwin->decryption.label,
0839 ptwin->decryption.context,
0840 sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE);
0841 if (rc)
0842 return rc;
0843
0844 ksmbd_debug(AUTH, "dumping generated AES encryption keys\n");
0845 ksmbd_debug(AUTH, "Cipher type %d\n", conn->cipher_type);
0846 ksmbd_debug(AUTH, "Session Id %llu\n", sess->id);
0847 ksmbd_debug(AUTH, "Session Key %*ph\n",
0848 SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key);
0849 if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
0850 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
0851 ksmbd_debug(AUTH, "ServerIn Key %*ph\n",
0852 SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3encryptionkey);
0853 ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
0854 SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3decryptionkey);
0855 } else {
0856 ksmbd_debug(AUTH, "ServerIn Key %*ph\n",
0857 SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3encryptionkey);
0858 ksmbd_debug(AUTH, "ServerOut Key %*ph\n",
0859 SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3decryptionkey);
0860 }
0861 return 0;
0862 }
0863
0864 int ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn,
0865 struct ksmbd_session *sess)
0866 {
0867 struct derivation_twin twin;
0868 struct derivation *d;
0869
0870 d = &twin.encryption;
0871 d->label.iov_base = "SMB2AESCCM";
0872 d->label.iov_len = 11;
0873 d->context.iov_base = "ServerOut";
0874 d->context.iov_len = 10;
0875
0876 d = &twin.decryption;
0877 d->label.iov_base = "SMB2AESCCM";
0878 d->label.iov_len = 11;
0879 d->context.iov_base = "ServerIn ";
0880 d->context.iov_len = 10;
0881
0882 return generate_smb3encryptionkey(conn, sess, &twin);
0883 }
0884
0885 int ksmbd_gen_smb311_encryptionkey(struct ksmbd_conn *conn,
0886 struct ksmbd_session *sess)
0887 {
0888 struct derivation_twin twin;
0889 struct derivation *d;
0890
0891 d = &twin.encryption;
0892 d->label.iov_base = "SMBS2CCipherKey";
0893 d->label.iov_len = 16;
0894 d->context.iov_base = sess->Preauth_HashValue;
0895 d->context.iov_len = 64;
0896
0897 d = &twin.decryption;
0898 d->label.iov_base = "SMBC2SCipherKey";
0899 d->label.iov_len = 16;
0900 d->context.iov_base = sess->Preauth_HashValue;
0901 d->context.iov_len = 64;
0902
0903 return generate_smb3encryptionkey(conn, sess, &twin);
0904 }
0905
0906 int ksmbd_gen_preauth_integrity_hash(struct ksmbd_conn *conn, char *buf,
0907 __u8 *pi_hash)
0908 {
0909 int rc;
0910 struct smb2_hdr *rcv_hdr = smb2_get_msg(buf);
0911 char *all_bytes_msg = (char *)&rcv_hdr->ProtocolId;
0912 int msg_size = get_rfc1002_len(buf);
0913 struct ksmbd_crypto_ctx *ctx = NULL;
0914
0915 if (conn->preauth_info->Preauth_HashId !=
0916 SMB2_PREAUTH_INTEGRITY_SHA512)
0917 return -EINVAL;
0918
0919 ctx = ksmbd_crypto_ctx_find_sha512();
0920 if (!ctx) {
0921 ksmbd_debug(AUTH, "could not alloc sha512\n");
0922 return -ENOMEM;
0923 }
0924
0925 rc = crypto_shash_init(CRYPTO_SHA512(ctx));
0926 if (rc) {
0927 ksmbd_debug(AUTH, "could not init shashn");
0928 goto out;
0929 }
0930
0931 rc = crypto_shash_update(CRYPTO_SHA512(ctx), pi_hash, 64);
0932 if (rc) {
0933 ksmbd_debug(AUTH, "could not update with n\n");
0934 goto out;
0935 }
0936
0937 rc = crypto_shash_update(CRYPTO_SHA512(ctx), all_bytes_msg, msg_size);
0938 if (rc) {
0939 ksmbd_debug(AUTH, "could not update with n\n");
0940 goto out;
0941 }
0942
0943 rc = crypto_shash_final(CRYPTO_SHA512(ctx), pi_hash);
0944 if (rc) {
0945 ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
0946 goto out;
0947 }
0948 out:
0949 ksmbd_release_crypto_ctx(ctx);
0950 return rc;
0951 }
0952
0953 int ksmbd_gen_sd_hash(struct ksmbd_conn *conn, char *sd_buf, int len,
0954 __u8 *pi_hash)
0955 {
0956 int rc;
0957 struct ksmbd_crypto_ctx *ctx = NULL;
0958
0959 ctx = ksmbd_crypto_ctx_find_sha256();
0960 if (!ctx) {
0961 ksmbd_debug(AUTH, "could not alloc sha256\n");
0962 return -ENOMEM;
0963 }
0964
0965 rc = crypto_shash_init(CRYPTO_SHA256(ctx));
0966 if (rc) {
0967 ksmbd_debug(AUTH, "could not init shashn");
0968 goto out;
0969 }
0970
0971 rc = crypto_shash_update(CRYPTO_SHA256(ctx), sd_buf, len);
0972 if (rc) {
0973 ksmbd_debug(AUTH, "could not update with n\n");
0974 goto out;
0975 }
0976
0977 rc = crypto_shash_final(CRYPTO_SHA256(ctx), pi_hash);
0978 if (rc) {
0979 ksmbd_debug(AUTH, "Could not generate hash err : %d\n", rc);
0980 goto out;
0981 }
0982 out:
0983 ksmbd_release_crypto_ctx(ctx);
0984 return rc;
0985 }
0986
0987 static int ksmbd_get_encryption_key(struct ksmbd_conn *conn, __u64 ses_id,
0988 int enc, u8 *key)
0989 {
0990 struct ksmbd_session *sess;
0991 u8 *ses_enc_key;
0992
0993 sess = ksmbd_session_lookup_all(conn, ses_id);
0994 if (!sess)
0995 return -EINVAL;
0996
0997 ses_enc_key = enc ? sess->smb3encryptionkey :
0998 sess->smb3decryptionkey;
0999 memcpy(key, ses_enc_key, SMB3_ENC_DEC_KEY_SIZE);
1000
1001 return 0;
1002 }
1003
1004 static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
1005 unsigned int buflen)
1006 {
1007 void *addr;
1008
1009 if (is_vmalloc_addr(buf))
1010 addr = vmalloc_to_page(buf);
1011 else
1012 addr = virt_to_page(buf);
1013 sg_set_page(sg, addr, buflen, offset_in_page(buf));
1014 }
1015
1016 static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec,
1017 u8 *sign)
1018 {
1019 struct scatterlist *sg;
1020 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
1021 int i, nr_entries[3] = {0}, total_entries = 0, sg_idx = 0;
1022
1023 if (!nvec)
1024 return NULL;
1025
1026 for (i = 0; i < nvec - 1; i++) {
1027 unsigned long kaddr = (unsigned long)iov[i + 1].iov_base;
1028
1029 if (is_vmalloc_addr(iov[i + 1].iov_base)) {
1030 nr_entries[i] = ((kaddr + iov[i + 1].iov_len +
1031 PAGE_SIZE - 1) >> PAGE_SHIFT) -
1032 (kaddr >> PAGE_SHIFT);
1033 } else {
1034 nr_entries[i]++;
1035 }
1036 total_entries += nr_entries[i];
1037 }
1038
1039
1040 total_entries += 2;
1041
1042 sg = kmalloc_array(total_entries, sizeof(struct scatterlist), GFP_KERNEL);
1043 if (!sg)
1044 return NULL;
1045
1046 sg_init_table(sg, total_entries);
1047 smb2_sg_set_buf(&sg[sg_idx++], iov[0].iov_base + 24, assoc_data_len);
1048 for (i = 0; i < nvec - 1; i++) {
1049 void *data = iov[i + 1].iov_base;
1050 int len = iov[i + 1].iov_len;
1051
1052 if (is_vmalloc_addr(data)) {
1053 int j, offset = offset_in_page(data);
1054
1055 for (j = 0; j < nr_entries[i]; j++) {
1056 unsigned int bytes = PAGE_SIZE - offset;
1057
1058 if (!len)
1059 break;
1060
1061 if (bytes > len)
1062 bytes = len;
1063
1064 sg_set_page(&sg[sg_idx++],
1065 vmalloc_to_page(data), bytes,
1066 offset_in_page(data));
1067
1068 data += bytes;
1069 len -= bytes;
1070 offset = 0;
1071 }
1072 } else {
1073 sg_set_page(&sg[sg_idx++], virt_to_page(data), len,
1074 offset_in_page(data));
1075 }
1076 }
1077 smb2_sg_set_buf(&sg[sg_idx], sign, SMB2_SIGNATURE_SIZE);
1078 return sg;
1079 }
1080
1081 int ksmbd_crypt_message(struct ksmbd_conn *conn, struct kvec *iov,
1082 unsigned int nvec, int enc)
1083 {
1084 struct smb2_transform_hdr *tr_hdr = smb2_get_msg(iov[0].iov_base);
1085 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
1086 int rc;
1087 struct scatterlist *sg;
1088 u8 sign[SMB2_SIGNATURE_SIZE] = {};
1089 u8 key[SMB3_ENC_DEC_KEY_SIZE];
1090 struct aead_request *req;
1091 char *iv;
1092 unsigned int iv_len;
1093 struct crypto_aead *tfm;
1094 unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
1095 struct ksmbd_crypto_ctx *ctx;
1096
1097 rc = ksmbd_get_encryption_key(conn,
1098 le64_to_cpu(tr_hdr->SessionId),
1099 enc,
1100 key);
1101 if (rc) {
1102 pr_err("Could not get %scryption key\n", enc ? "en" : "de");
1103 return rc;
1104 }
1105
1106 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1107 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1108 ctx = ksmbd_crypto_ctx_find_gcm();
1109 else
1110 ctx = ksmbd_crypto_ctx_find_ccm();
1111 if (!ctx) {
1112 pr_err("crypto alloc failed\n");
1113 return -ENOMEM;
1114 }
1115
1116 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1117 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1118 tfm = CRYPTO_GCM(ctx);
1119 else
1120 tfm = CRYPTO_CCM(ctx);
1121
1122 if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
1123 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM)
1124 rc = crypto_aead_setkey(tfm, key, SMB3_GCM256_CRYPTKEY_SIZE);
1125 else
1126 rc = crypto_aead_setkey(tfm, key, SMB3_GCM128_CRYPTKEY_SIZE);
1127 if (rc) {
1128 pr_err("Failed to set aead key %d\n", rc);
1129 goto free_ctx;
1130 }
1131
1132 rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE);
1133 if (rc) {
1134 pr_err("Failed to set authsize %d\n", rc);
1135 goto free_ctx;
1136 }
1137
1138 req = aead_request_alloc(tfm, GFP_KERNEL);
1139 if (!req) {
1140 rc = -ENOMEM;
1141 goto free_ctx;
1142 }
1143
1144 if (!enc) {
1145 memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
1146 crypt_len += SMB2_SIGNATURE_SIZE;
1147 }
1148
1149 sg = ksmbd_init_sg(iov, nvec, sign);
1150 if (!sg) {
1151 pr_err("Failed to init sg\n");
1152 rc = -ENOMEM;
1153 goto free_req;
1154 }
1155
1156 iv_len = crypto_aead_ivsize(tfm);
1157 iv = kzalloc(iv_len, GFP_KERNEL);
1158 if (!iv) {
1159 rc = -ENOMEM;
1160 goto free_sg;
1161 }
1162
1163 if (conn->cipher_type == SMB2_ENCRYPTION_AES128_GCM ||
1164 conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) {
1165 memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
1166 } else {
1167 iv[0] = 3;
1168 memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
1169 }
1170
1171 aead_request_set_crypt(req, sg, sg, crypt_len, iv);
1172 aead_request_set_ad(req, assoc_data_len);
1173 aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
1174
1175 if (enc)
1176 rc = crypto_aead_encrypt(req);
1177 else
1178 rc = crypto_aead_decrypt(req);
1179 if (rc)
1180 goto free_iv;
1181
1182 if (enc)
1183 memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
1184
1185 free_iv:
1186 kfree(iv);
1187 free_sg:
1188 kfree(sg);
1189 free_req:
1190 kfree(req);
1191 free_ctx:
1192 ksmbd_release_crypto_ctx(ctx);
1193 return rc;
1194 }