Print this page
12513 SMB 3.1.1 support for server

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/smbsrv/smb3_encrypt.c
          +++ new/usr/src/uts/common/fs/smbsrv/smb3_encrypt.c
↓ open down ↓ 3 lines elided ↑ open up ↑
   4    4   * You may only use this file in accordance with the terms of version
   5    5   * 1.0 of the CDDL.
   6    6   *
   7    7   * A full copy of the text of the CDDL should have accompanied this
   8    8   * source.  A copy of the CDDL is also available via the Internet at
   9    9   * http://www.illumos.org/license/CDDL.
  10   10   */
  11   11  
  12   12  /*
  13   13   * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
       14 + * Copyright 2020 RackTop Systems, Inc.
  14   15   */
  15   16  
  16   17  /*
  17   18   * Routines for smb3 encryption.
  18   19   */
  19   20  
  20   21  #include <smbsrv/smb2_kproto.h>
  21   22  #include <smbsrv/smb_kcrypt.h>
  22   23  #include <sys/random.h>
  23   24  #include <sys/cmn_err.h>
  24   25  
  25   26  #define SMB3_NONCE_OFFS         20
  26   27  #define SMB3_SIG_OFFS           4
  27      -#define SMB3_NONCE_SIZE         11 /* 12 for gcm later */
  28      -
  29      -/*
  30      - * Inputs to KDF for EncryptionKey and DecryptionKey.
  31      - * See comment for smb3_do_kdf for content.
  32      - */
  33      -static uint8_t encrypt_kdf_input[30] = {
  34      -        0, 0, 0, 1, 'S', 'M', 'B', '2',
  35      -        'A', 'E', 'S', 'C', 'C', 'M', 0, 0,
  36      -        'S', 'e', 'r', 'v', 'e', 'r', 'O',
  37      -        'u', 't', 0, 0, 0, 0, 0x80 };
  38      -
  39      -static uint8_t decrypt_kdf_input[30] = {
  40      -        0, 0, 0, 1, 'S', 'M', 'B', '2',
  41      -        'A', 'E', 'S', 'C', 'C', 'M', 0, 0,
  42      -        'S', 'e', 'r', 'v', 'e', 'r', 'I',
  43      -        'n', ' ', 0, 0, 0, 0, 0x80 };
       28 +#define SMB3_AES128_CCM_NONCE_SIZE      11
       29 +#define SMB3_AES128_GCM_NONCE_SIZE      12
  44   30  
  45   31  /*
  46   32   * Arbitrary value used to prevent nonce reuse via overflow. Currently
  47   33   * 2^64 - 2^32 - 1. Assumes we can't have (or are unlikely to have)
  48   34   * 2^32 concurrent messages when we hit this number.
  49   35   */
  50   36  static uint64_t smb3_max_nonce = 0xffffffff00000000ULL;
  51   37  
  52   38  /*
  53   39   * Nonce generation based on draft-mcgrew-iv-gen-01
↓ open down ↓ 39 lines elided ↑ open up ↑
  93   79  
  94   80  int
  95   81  smb3_encrypt_init_mech(smb_session_t *s)
  96   82  {
  97   83          smb_crypto_mech_t *mech;
  98   84          int rc;
  99   85  
 100   86          if (s->enc_mech != NULL)
 101   87                  return (0);
 102   88  
       89 +        if (s->dialect < SMB_VERS_3_11)
       90 +                s->smb31_enc_cipherid = SMB3_CIPHER_AES128_CCM;
       91 +
 103   92          mech = kmem_zalloc(sizeof (*mech), KM_SLEEP);
 104      -        rc = smb3_encrypt_getmech(mech);
       93 +
       94 +        switch (s->smb31_enc_cipherid) {
       95 +        case SMB3_CIPHER_AES128_GCM:
       96 +                rc = smb3_aes_gcm_getmech(mech);
       97 +                break;
       98 +        case SMB3_CIPHER_AES128_CCM:
       99 +                rc = smb3_aes_ccm_getmech(mech);
      100 +                break;
      101 +        default:
      102 +                return (-1);
      103 +        }
      104 +
 105  105          if (rc != 0) {
 106  106                  kmem_free(mech, sizeof (*mech));
 107  107                  return (rc);
 108  108          }
 109  109          s->enc_mech = mech;
 110  110  
 111  111          return (0);
 112  112  }
 113  113  
 114  114  /*
↓ open down ↓ 28 lines elided ↑ open up ↑
 143  143  
 144  144          /*
 145  145           * Compute and store the encryption keys, which live in
 146  146           * the user structure.
 147  147           */
 148  148  
 149  149          /*
 150  150           * For SMB3, the encrypt/decrypt keys are derived from
 151  151           * the session key using KDF in counter mode.
 152  152           */
 153      -        if (smb3_do_kdf(enc_key->key, encrypt_kdf_input,
 154      -            sizeof (encrypt_kdf_input), token->tkn_ssnkey.val,
 155      -            token->tkn_ssnkey.len) != 0)
 156      -                return;
 157      -
 158      -        if (smb3_do_kdf(dec_key->key, decrypt_kdf_input,
 159      -            sizeof (decrypt_kdf_input), token->tkn_ssnkey.val,
 160      -            token->tkn_ssnkey.len) != 0)
 161      -                return;
      153 +        if (s->dialect >= SMB_VERS_3_11) {
      154 +                if (smb3_kdf(enc_key->key,
      155 +                    token->tkn_ssnkey.val, token->tkn_ssnkey.len,
      156 +                    (uint8_t *)"SMBS2CCipherKey", 16,
      157 +                    s->smb31_preauth_hashval, SHA512_DIGEST_LENGTH) != 0)
      158 +                        return;
      159 +
      160 +                if (smb3_kdf(dec_key->key,
      161 +                    token->tkn_ssnkey.val, token->tkn_ssnkey.len,
      162 +                    (uint8_t *)"SMBC2SCipherKey", 16,
      163 +                    s->smb31_preauth_hashval, SHA512_DIGEST_LENGTH) != 0)
      164 +                        return;
      165 +        } else {
      166 +                if (smb3_kdf(enc_key->key,
      167 +                    token->tkn_ssnkey.val, token->tkn_ssnkey.len,
      168 +                    (uint8_t *)"SMB2AESCCM", 11,
      169 +                    (uint8_t *)"ServerOut", 10) != 0)
      170 +                        return;
      171 +
      172 +                if (smb3_kdf(dec_key->key,
      173 +                    token->tkn_ssnkey.val, token->tkn_ssnkey.len,
      174 +                    (uint8_t *)"SMB2AESCCM", 11,
      175 +                    (uint8_t *)"ServerIn ", 10) != 0)
      176 +                        return;
      177 +        }
 162  178  
 163  179          smb3_encrypt_init_nonce(u);
 164  180  
 165  181          enc_key->len = SMB3_KEYLEN;
 166  182          dec_key->len = SMB3_KEYLEN;
 167  183  }
 168  184  
 169  185  /*
 170  186   * Decrypt the request in sr->command.
 171  187   * This decrypts "in place", though due to CCM's design,
↓ open down ↓ 5 lines elided ↑ open up ↑
 177  193          struct mbuf_chain *mbc = &sr->command;
 178  194          smb_session_t *s = sr->session;
 179  195          smb_user_t *u = sr->tform_ssn;
 180  196          uint8_t tmp_hdr[SMB2_HDR_SIZE];
 181  197          smb3_enc_ctx_t ctx;
 182  198          struct smb_key *dec_key = &u->u_dec_key;
 183  199          struct mbuf *mbuf;
 184  200          int offset, resid, tlen, rc;
 185  201          smb3_crypto_param_t param;
 186  202          smb_crypto_mech_t mech;
      203 +        boolean_t gcm = sr->session->smb31_enc_cipherid ==
      204 +            SMB3_CIPHER_AES128_GCM;
      205 +        size_t nonce_size = (gcm ? SMB3_AES128_GCM_NONCE_SIZE :
      206 +            SMB3_AES128_CCM_NONCE_SIZE);
 187  207  
 188  208          ASSERT(u != NULL);
 189  209          if (s->enc_mech == NULL || dec_key->len != 16) {
 190  210                  return (-1);
 191  211          }
 192  212  
 193  213          tlen = SMB3_TFORM_HDR_SIZE - SMB3_NONCE_OFFS;
 194  214          offset = mbc->chain_offset + SMB3_NONCE_OFFS;
 195  215          resid = mbc->max_bytes - offset;
 196  216  
↓ open down ↓ 6 lines elided ↑ open up ↑
 203  223                  return (-1);
 204  224          }
 205  225  
 206  226          offset += tlen;
 207  227          resid -= tlen;
 208  228  
 209  229          /*
 210  230           * The transform header, minus the PROTOCOL_ID and the
 211  231           * SIGNATURE, is authenticated but not encrypted.
 212  232           */
 213      -        smb3_crypto_init_param(&param, sr->nonce, SMB3_NONCE_SIZE,
 214      -            tmp_hdr, tlen, sr->msgsize + SMB2_SIG_SIZE);
      233 +        if (gcm)
      234 +                smb3_crypto_init_gcm_param(&param, sr->nonce, nonce_size,
      235 +                    tmp_hdr, tlen);
      236 +        else
      237 +                smb3_crypto_init_ccm_param(&param, sr->nonce, nonce_size,
      238 +                    tmp_hdr, tlen, sr->msgsize + SMB2_SIG_SIZE);
 215  239  
 216  240          /*
 217  241           * Unlike signing, which uses one global mech struct,
 218  242           * encryption requires modifying the mech to add a
 219  243           * per-use param struct. Thus, we need to make a copy.
 220  244           */
 221  245          mech = *(smb_crypto_mech_t *)s->enc_mech;
 222  246          rc = smb3_decrypt_init(&ctx, &mech, &param,
 223  247              dec_key->key, dec_key->len);
 224  248          if (rc != 0) {
↓ open down ↓ 85 lines elided ↑ open up ↑
 310  334          smb_session_t *s = sr->session;
 311  335          smb_user_t *u = sr->tform_ssn;
 312  336          uint8_t *buf = (uint8_t *)out_mbc->chain->m_data;
 313  337          size_t buflen = out_mbc->max_bytes;
 314  338          smb3_enc_ctx_t ctx;
 315  339          struct smb_key *enc_key = &u->u_enc_key;
 316  340          struct mbuf *mbuf;
 317  341          int resid, tlen, rc;
 318  342          smb3_crypto_param_t param;
 319  343          smb_crypto_mech_t mech;
      344 +        boolean_t gcm = sr->session->smb31_enc_cipherid ==
      345 +            SMB3_CIPHER_AES128_GCM;
      346 +        size_t nonce_size = (gcm ? SMB3_AES128_GCM_NONCE_SIZE :
      347 +            SMB3_AES128_CCM_NONCE_SIZE);
 320  348  
 321  349          ASSERT(u != NULL);
 322  350          if (s->enc_mech == NULL || enc_key->len != 16) {
 323  351                  return (-1);
 324  352          }
 325  353  
 326      -        rc = smb3_encrypt_gen_nonce(u, sr->nonce, SMB3_NONCE_SIZE);
      354 +        rc = smb3_encrypt_gen_nonce(u, sr->nonce, nonce_size);
 327  355  
 328  356          if (rc != 0) {
 329  357                  cmn_err(CE_WARN, "ran out of nonces");
 330  358                  return (-1);
 331  359          }
 332  360  
 333  361          (void) smb_mbc_poke(out_mbc, SMB3_NONCE_OFFS, "#c",
 334      -            SMB3_NONCE_SIZE, sr->nonce);
      362 +            nonce_size, sr->nonce);
 335  363  
 336  364          resid = in_mbc->max_bytes;
 337  365  
 338  366          /*
 339  367           * The transform header, minus the PROTOCOL_ID and the
 340  368           * SIGNATURE, is authenticated but not encrypted.
 341  369           */
 342      -        smb3_crypto_init_param(&param,
 343      -            sr->nonce, SMB3_NONCE_SIZE,
 344      -            buf + SMB3_NONCE_OFFS, SMB3_TFORM_HDR_SIZE - SMB3_NONCE_OFFS,
 345      -            resid);
      370 +        if (gcm)
      371 +                smb3_crypto_init_gcm_param(&param, sr->nonce, nonce_size,
      372 +                    buf + SMB3_NONCE_OFFS,
      373 +                    SMB3_TFORM_HDR_SIZE - SMB3_NONCE_OFFS);
      374 +        else
      375 +                smb3_crypto_init_ccm_param(&param, sr->nonce, nonce_size,
      376 +                    buf + SMB3_NONCE_OFFS,
      377 +                    SMB3_TFORM_HDR_SIZE - SMB3_NONCE_OFFS, resid);
 346  378  
 347  379          /*
 348  380           * Unlike signing, which uses one global mech struct,
 349  381           * encryption requires modifying the mech to add a
 350  382           * per-use param struct. Thus, we need to make a copy.
 351  383           */
 352  384          mech = *(smb_crypto_mech_t *)s->enc_mech;
 353  385          rc = smb3_encrypt_init(&ctx, &mech, &param,
 354  386              enc_key->key, enc_key->len, buf + SMB3_TFORM_HDR_SIZE,
 355  387              buflen - SMB3_TFORM_HDR_SIZE);
↓ open down ↓ 42 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX