Print this page
12513 SMB 3.1.1 support for server
   1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.

  14  */
  15 
  16 /*
  17  * Routines for smb3 encryption.
  18  */
  19 
  20 #include <smbsrv/smb2_kproto.h>
  21 #include <smbsrv/smb_kcrypt.h>
  22 #include <sys/random.h>
  23 #include <sys/cmn_err.h>
  24 
  25 #define SMB3_NONCE_OFFS         20
  26 #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 };
  44 
  45 /*
  46  * Arbitrary value used to prevent nonce reuse via overflow. Currently
  47  * 2^64 - 2^32 - 1. Assumes we can't have (or are unlikely to have)
  48  * 2^32 concurrent messages when we hit this number.
  49  */
  50 static uint64_t smb3_max_nonce = 0xffffffff00000000ULL;
  51 
  52 /*
  53  * Nonce generation based on draft-mcgrew-iv-gen-01
  54  * "Generation of Deterministic Initialization Vectors (IVs) and Nonces"
  55  *
  56  * Generate an 8-byte random salt and a 3-byte random 'fixed' value.
  57  * then, nonce = (++counter ^ salt) || fixed
  58  *
  59  * This protects against nonce-reuse (8-byte counter), as well as known
  60  * attacks on reusing nonces with different keys
  61  */
  62 
  63 void


  83         if (cnt > smb3_max_nonce)
  84                 return (-1);
  85 
  86         cnt ^= user->u_salt;
  87         bcopy((uint8_t *)&cnt, buf, sizeof (cnt));
  88 
  89         ASSERT(len > sizeof (cnt));
  90         bcopy(user->u_nonce_fixed, buf + sizeof (cnt), len - sizeof (cnt));
  91         return (0);
  92 }
  93 
  94 int
  95 smb3_encrypt_init_mech(smb_session_t *s)
  96 {
  97         smb_crypto_mech_t *mech;
  98         int rc;
  99 
 100         if (s->enc_mech != NULL)
 101                 return (0);
 102 



 103         mech = kmem_zalloc(sizeof (*mech), KM_SLEEP);
 104         rc = smb3_encrypt_getmech(mech);











 105         if (rc != 0) {
 106                 kmem_free(mech, sizeof (*mech));
 107                 return (rc);
 108         }
 109         s->enc_mech = mech;
 110 
 111         return (0);
 112 }
 113 
 114 /*
 115  * Initializes keys/state required for SMB3 Encryption.
 116  * Note: If a failure occurs here, don't fail the request.
 117  * Instead, return an error when we attempt to encrypt/decrypt.
 118  */
 119 void
 120 smb3_encrypt_begin(smb_request_t *sr, smb_token_t *token)
 121 {
 122         smb_session_t *s = sr->session;
 123         smb_user_t *u = sr->uid_user;
 124         struct smb_key *enc_key = &u->u_enc_key;


 133         dec_key->len = 0;
 134 
 135         /*
 136          * If we don't have a session key, we'll fail later when a
 137          * request that requires (en/de)cryption can't be (en/de)crypted.
 138          * Also don't bother initializing if we don't have a mechanism.
 139          */
 140         if (token->tkn_ssnkey.val == NULL || token->tkn_ssnkey.len == 0 ||
 141             s->enc_mech == NULL)
 142                 return;
 143 
 144         /*
 145          * Compute and store the encryption keys, which live in
 146          * the user structure.
 147          */
 148 
 149         /*
 150          * For SMB3, the encrypt/decrypt keys are derived from
 151          * the session key using KDF in counter mode.
 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;

 162 
 163         smb3_encrypt_init_nonce(u);
 164 
 165         enc_key->len = SMB3_KEYLEN;
 166         dec_key->len = SMB3_KEYLEN;
 167 }
 168 
 169 /*
 170  * Decrypt the request in sr->command.
 171  * This decrypts "in place", though due to CCM's design,
 172  * it processes all input before doing any output.
 173  */
 174 int
 175 smb3_decrypt_sr(smb_request_t *sr)
 176 {
 177         struct mbuf_chain *mbc = &sr->command;
 178         smb_session_t *s = sr->session;
 179         smb_user_t *u = sr->tform_ssn;
 180         uint8_t tmp_hdr[SMB2_HDR_SIZE];
 181         smb3_enc_ctx_t ctx;
 182         struct smb_key *dec_key = &u->u_dec_key;
 183         struct mbuf *mbuf;
 184         int offset, resid, tlen, rc;
 185         smb3_crypto_param_t param;
 186         smb_crypto_mech_t mech;




 187 
 188         ASSERT(u != NULL);
 189         if (s->enc_mech == NULL || dec_key->len != 16) {
 190                 return (-1);
 191         }
 192 
 193         tlen = SMB3_TFORM_HDR_SIZE - SMB3_NONCE_OFFS;
 194         offset = mbc->chain_offset + SMB3_NONCE_OFFS;
 195         resid = mbc->max_bytes - offset;
 196 
 197         if (resid < (sr->msgsize + tlen)) {
 198                 cmn_err(CE_WARN, "too little data to decrypt");
 199                 return (-1);
 200         }
 201 
 202         if (smb_mbc_peek(mbc, offset, "#c", tlen, tmp_hdr) != 0) {
 203                 return (-1);
 204         }
 205 
 206         offset += tlen;
 207         resid -= tlen;
 208 
 209         /*
 210          * The transform header, minus the PROTOCOL_ID and the
 211          * SIGNATURE, is authenticated but not encrypted.
 212          */
 213         smb3_crypto_init_param(&param, sr->nonce, SMB3_NONCE_SIZE,




 214             tmp_hdr, tlen, sr->msgsize + SMB2_SIG_SIZE);
 215 
 216         /*
 217          * Unlike signing, which uses one global mech struct,
 218          * encryption requires modifying the mech to add a
 219          * per-use param struct. Thus, we need to make a copy.
 220          */
 221         mech = *(smb_crypto_mech_t *)s->enc_mech;
 222         rc = smb3_decrypt_init(&ctx, &mech, &param,
 223             dec_key->key, dec_key->len);
 224         if (rc != 0) {
 225                 return (rc);
 226         }
 227 
 228         /*
 229          * Digest the rest of the SMB packet, starting at the data
 230          * just after the SMB header.
 231          *
 232          * Advance to the src mbuf where we start digesting.
 233          */


 300 
 301 /*
 302  * Encrypt the response in in_mbc, and output
 303  * an encrypted response in out_mbc.
 304  * The data in in_mbc is preserved.
 305  */
 306 int
 307 smb3_encrypt_sr(smb_request_t *sr, struct mbuf_chain *in_mbc,
 308     struct mbuf_chain *out_mbc)
 309 {
 310         smb_session_t *s = sr->session;
 311         smb_user_t *u = sr->tform_ssn;
 312         uint8_t *buf = (uint8_t *)out_mbc->chain->m_data;
 313         size_t buflen = out_mbc->max_bytes;
 314         smb3_enc_ctx_t ctx;
 315         struct smb_key *enc_key = &u->u_enc_key;
 316         struct mbuf *mbuf;
 317         int resid, tlen, rc;
 318         smb3_crypto_param_t param;
 319         smb_crypto_mech_t mech;




 320 
 321         ASSERT(u != NULL);
 322         if (s->enc_mech == NULL || enc_key->len != 16) {
 323                 return (-1);
 324         }
 325 
 326         rc = smb3_encrypt_gen_nonce(u, sr->nonce, SMB3_NONCE_SIZE);
 327 
 328         if (rc != 0) {
 329                 cmn_err(CE_WARN, "ran out of nonces");
 330                 return (-1);
 331         }
 332 
 333         (void) smb_mbc_poke(out_mbc, SMB3_NONCE_OFFS, "#c",
 334             SMB3_NONCE_SIZE, sr->nonce);
 335 
 336         resid = in_mbc->max_bytes;
 337 
 338         /*
 339          * The transform header, minus the PROTOCOL_ID and the
 340          * SIGNATURE, is authenticated but not encrypted.
 341          */
 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);




 346 
 347         /*
 348          * Unlike signing, which uses one global mech struct,
 349          * encryption requires modifying the mech to add a
 350          * per-use param struct. Thus, we need to make a copy.
 351          */
 352         mech = *(smb_crypto_mech_t *)s->enc_mech;
 353         rc = smb3_encrypt_init(&ctx, &mech, &param,
 354             enc_key->key, enc_key->len, buf + SMB3_TFORM_HDR_SIZE,
 355             buflen - SMB3_TFORM_HDR_SIZE);
 356         if (rc != 0) {
 357                 return (rc);
 358         }
 359 
 360         /*
 361          * Unlike signing and decryption, we're processing the entirety of the
 362          * message here, so we don't skip anything.
 363          */
 364         mbuf = in_mbc->chain;
 365         while (resid > 0 && mbuf != NULL) {


   1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  14  * Copyright 2020 RackTop Systems, Inc.
  15  */
  16 
  17 /*
  18  * Routines for smb3 encryption.
  19  */
  20 
  21 #include <smbsrv/smb2_kproto.h>
  22 #include <smbsrv/smb_kcrypt.h>
  23 #include <sys/random.h>
  24 #include <sys/cmn_err.h>
  25 
  26 #define SMB3_NONCE_OFFS         20
  27 #define SMB3_SIG_OFFS           4
  28 #define SMB3_AES128_CCM_NONCE_SIZE      11
  29 #define SMB3_AES128_GCM_NONCE_SIZE      12















  30 
  31 /*
  32  * Arbitrary value used to prevent nonce reuse via overflow. Currently
  33  * 2^64 - 2^32 - 1. Assumes we can't have (or are unlikely to have)
  34  * 2^32 concurrent messages when we hit this number.
  35  */
  36 static uint64_t smb3_max_nonce = 0xffffffff00000000ULL;
  37 
  38 /*
  39  * Nonce generation based on draft-mcgrew-iv-gen-01
  40  * "Generation of Deterministic Initialization Vectors (IVs) and Nonces"
  41  *
  42  * Generate an 8-byte random salt and a 3-byte random 'fixed' value.
  43  * then, nonce = (++counter ^ salt) || fixed
  44  *
  45  * This protects against nonce-reuse (8-byte counter), as well as known
  46  * attacks on reusing nonces with different keys
  47  */
  48 
  49 void


  69         if (cnt > smb3_max_nonce)
  70                 return (-1);
  71 
  72         cnt ^= user->u_salt;
  73         bcopy((uint8_t *)&cnt, buf, sizeof (cnt));
  74 
  75         ASSERT(len > sizeof (cnt));
  76         bcopy(user->u_nonce_fixed, buf + sizeof (cnt), len - sizeof (cnt));
  77         return (0);
  78 }
  79 
  80 int
  81 smb3_encrypt_init_mech(smb_session_t *s)
  82 {
  83         smb_crypto_mech_t *mech;
  84         int rc;
  85 
  86         if (s->enc_mech != NULL)
  87                 return (0);
  88 
  89         if (s->dialect < SMB_VERS_3_11)
  90                 s->smb31_enc_cipherid = SMB3_CIPHER_AES128_CCM;
  91 
  92         mech = kmem_zalloc(sizeof (*mech), KM_SLEEP);
  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         if (rc != 0) {
 106                 kmem_free(mech, sizeof (*mech));
 107                 return (rc);
 108         }
 109         s->enc_mech = mech;
 110 
 111         return (0);
 112 }
 113 
 114 /*
 115  * Initializes keys/state required for SMB3 Encryption.
 116  * Note: If a failure occurs here, don't fail the request.
 117  * Instead, return an error when we attempt to encrypt/decrypt.
 118  */
 119 void
 120 smb3_encrypt_begin(smb_request_t *sr, smb_token_t *token)
 121 {
 122         smb_session_t *s = sr->session;
 123         smb_user_t *u = sr->uid_user;
 124         struct smb_key *enc_key = &u->u_enc_key;


 133         dec_key->len = 0;
 134 
 135         /*
 136          * If we don't have a session key, we'll fail later when a
 137          * request that requires (en/de)cryption can't be (en/de)crypted.
 138          * Also don't bother initializing if we don't have a mechanism.
 139          */
 140         if (token->tkn_ssnkey.val == NULL || token->tkn_ssnkey.len == 0 ||
 141             s->enc_mech == NULL)
 142                 return;
 143 
 144         /*
 145          * Compute and store the encryption keys, which live in
 146          * the user structure.
 147          */
 148 
 149         /*
 150          * For SMB3, the encrypt/decrypt keys are derived from
 151          * the session key using KDF in counter mode.
 152          */
 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         }
 178 
 179         smb3_encrypt_init_nonce(u);
 180 
 181         enc_key->len = SMB3_KEYLEN;
 182         dec_key->len = SMB3_KEYLEN;
 183 }
 184 
 185 /*
 186  * Decrypt the request in sr->command.
 187  * This decrypts "in place", though due to CCM's design,
 188  * it processes all input before doing any output.
 189  */
 190 int
 191 smb3_decrypt_sr(smb_request_t *sr)
 192 {
 193         struct mbuf_chain *mbc = &sr->command;
 194         smb_session_t *s = sr->session;
 195         smb_user_t *u = sr->tform_ssn;
 196         uint8_t tmp_hdr[SMB2_HDR_SIZE];
 197         smb3_enc_ctx_t ctx;
 198         struct smb_key *dec_key = &u->u_dec_key;
 199         struct mbuf *mbuf;
 200         int offset, resid, tlen, rc;
 201         smb3_crypto_param_t param;
 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);
 207 
 208         ASSERT(u != NULL);
 209         if (s->enc_mech == NULL || dec_key->len != 16) {
 210                 return (-1);
 211         }
 212 
 213         tlen = SMB3_TFORM_HDR_SIZE - SMB3_NONCE_OFFS;
 214         offset = mbc->chain_offset + SMB3_NONCE_OFFS;
 215         resid = mbc->max_bytes - offset;
 216 
 217         if (resid < (sr->msgsize + tlen)) {
 218                 cmn_err(CE_WARN, "too little data to decrypt");
 219                 return (-1);
 220         }
 221 
 222         if (smb_mbc_peek(mbc, offset, "#c", tlen, tmp_hdr) != 0) {
 223                 return (-1);
 224         }
 225 
 226         offset += tlen;
 227         resid -= tlen;
 228 
 229         /*
 230          * The transform header, minus the PROTOCOL_ID and the
 231          * SIGNATURE, is authenticated but not encrypted.
 232          */
 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);
 239 
 240         /*
 241          * Unlike signing, which uses one global mech struct,
 242          * encryption requires modifying the mech to add a
 243          * per-use param struct. Thus, we need to make a copy.
 244          */
 245         mech = *(smb_crypto_mech_t *)s->enc_mech;
 246         rc = smb3_decrypt_init(&ctx, &mech, &param,
 247             dec_key->key, dec_key->len);
 248         if (rc != 0) {
 249                 return (rc);
 250         }
 251 
 252         /*
 253          * Digest the rest of the SMB packet, starting at the data
 254          * just after the SMB header.
 255          *
 256          * Advance to the src mbuf where we start digesting.
 257          */


 324 
 325 /*
 326  * Encrypt the response in in_mbc, and output
 327  * an encrypted response in out_mbc.
 328  * The data in in_mbc is preserved.
 329  */
 330 int
 331 smb3_encrypt_sr(smb_request_t *sr, struct mbuf_chain *in_mbc,
 332     struct mbuf_chain *out_mbc)
 333 {
 334         smb_session_t *s = sr->session;
 335         smb_user_t *u = sr->tform_ssn;
 336         uint8_t *buf = (uint8_t *)out_mbc->chain->m_data;
 337         size_t buflen = out_mbc->max_bytes;
 338         smb3_enc_ctx_t ctx;
 339         struct smb_key *enc_key = &u->u_enc_key;
 340         struct mbuf *mbuf;
 341         int resid, tlen, rc;
 342         smb3_crypto_param_t param;
 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);
 348 
 349         ASSERT(u != NULL);
 350         if (s->enc_mech == NULL || enc_key->len != 16) {
 351                 return (-1);
 352         }
 353 
 354         rc = smb3_encrypt_gen_nonce(u, sr->nonce, nonce_size);
 355 
 356         if (rc != 0) {
 357                 cmn_err(CE_WARN, "ran out of nonces");
 358                 return (-1);
 359         }
 360 
 361         (void) smb_mbc_poke(out_mbc, SMB3_NONCE_OFFS, "#c",
 362             nonce_size, sr->nonce);
 363 
 364         resid = in_mbc->max_bytes;
 365 
 366         /*
 367          * The transform header, minus the PROTOCOL_ID and the
 368          * SIGNATURE, is authenticated but not encrypted.
 369          */
 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);
 378 
 379         /*
 380          * Unlike signing, which uses one global mech struct,
 381          * encryption requires modifying the mech to add a
 382          * per-use param struct. Thus, we need to make a copy.
 383          */
 384         mech = *(smb_crypto_mech_t *)s->enc_mech;
 385         rc = smb3_encrypt_init(&ctx, &mech, &param,
 386             enc_key->key, enc_key->len, buf + SMB3_TFORM_HDR_SIZE,
 387             buflen - SMB3_TFORM_HDR_SIZE);
 388         if (rc != 0) {
 389                 return (rc);
 390         }
 391 
 392         /*
 393          * Unlike signing and decryption, we're processing the entirety of the
 394          * message here, so we don't skip anything.
 395          */
 396         mbuf = in_mbc->chain;
 397         while (resid > 0 && mbuf != NULL) {