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