Print this page
12513 SMB 3.1.1 support for server


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.

  24  */
  25 /*
  26  * These routines provide the SMB MAC signing for the SMB2 server.
  27  * The routines calculate the signature of a SMB message in an mbuf chain.
  28  *
  29  * The following table describes the client server
  30  * signing registry relationship
  31  *
  32  *              | Required      | Enabled     | Disabled
  33  * -------------+---------------+------------ +--------------
  34  * Required     | Signed        | Signed      | Fail
  35  * -------------+---------------+-------------+-----------------
  36  * Enabled      | Signed        | Signed      | Not Signed
  37  * -------------+---------------+-------------+----------------
  38  * Disabled     | Fail          | Not Signed  | Not Signed
  39  */
  40 
  41 #include <sys/uio.h>
  42 #include <smbsrv/smb2_kproto.h>
  43 #include <smbsrv/smb_kcrypt.h>


 101 
 102 static struct mac_ops
 103 smb3_sign_ops = {
 104         smb3_cmac_init,
 105         smb3_cmac_update,
 106         smb3_cmac_final
 107 };
 108 
 109 static int
 110 smb3_sign_calc(smb_request_t *sr,
 111     struct mbuf_chain *mbc,
 112     uint8_t *digest16)
 113 {
 114         int rv;
 115 
 116         rv = smb2_sign_calc_common(sr, mbc, digest16, &smb3_sign_ops);
 117 
 118         return (rv);
 119 }
 120 
 121 /*
 122  * Input to KDF for SigningKey.
 123  * See comment for smb3_do_kdf for content.
 124  */
 125 static uint8_t sign_kdf_input[29] = {
 126         0, 0, 0, 1, 'S', 'M', 'B', '2',
 127         'A', 'E', 'S', 'C', 'M', 'A', 'C', 0,
 128         0, 'S', 'm', 'b', 'S', 'i', 'g', 'n',
 129         0, 0, 0, 0, 0x80 };
 130 
 131 void
 132 smb2_sign_init_mech(smb_session_t *s)
 133 {
 134         smb_crypto_mech_t *mech;
 135         int (*get_mech)(smb_crypto_mech_t *);
 136         int (*sign_calc)(smb_request_t *, struct mbuf_chain *, uint8_t *);
 137         int rc;
 138 
 139         if (s->sign_mech != NULL)
 140                 return;
 141 
 142         if (s->dialect >= SMB_VERS_3_0) {
 143                 get_mech = smb3_cmac_getmech;
 144                 sign_calc = smb3_sign_calc;
 145         } else {
 146                 get_mech = smb2_hmac_getmech;
 147                 sign_calc = smb2_sign_calc;
 148         }
 149 
 150         mech = kmem_zalloc(sizeof (*mech), KM_SLEEP);


 179          * We should normally have a session key here because
 180          * our caller filters out Anonymous and Guest logons.
 181          * However, buggy clients could get us here without a
 182          * session key, in which case we'll fail later when a
 183          * request that requires signing can't be checked.
 184          * Also, don't bother initializing if we don't have a mechanism.
 185          */
 186         if (token->tkn_ssnkey.val == NULL || token->tkn_ssnkey.len == 0 ||
 187             s->sign_mech == NULL)
 188                 return;
 189 
 190         /*
 191          * Compute and store the signing key, which lives in
 192          * the user structure.
 193          */
 194         if (s->dialect >= SMB_VERS_3_0) {
 195                 /*
 196                  * For SMB3, the signing key is a "KDF" hash of the
 197                  * session key.
 198                  */
 199                 if (smb3_do_kdf(sign_key->key, sign_kdf_input,
 200                     sizeof (sign_kdf_input), token->tkn_ssnkey.val,
 201                     token->tkn_ssnkey.len) != 0)



 202                         return;








 203                 sign_key->len = SMB3_KEYLEN;
 204         } else {
 205                 /*
 206                  * For SMB2, the signing key is just the first 16 bytes
 207                  * of the session key (truncated or padded with zeros).
 208                  * [MS-SMB2] 3.2.5.3.1
 209                  */
 210                 sign_key->len = SMB2_KEYLEN;
 211                 bcopy(token->tkn_ssnkey.val, sign_key->key,
 212                     MIN(token->tkn_ssnkey.len, sign_key->len));
 213         }
 214 
 215         mutex_enter(&u->u_mutex);
 216         if ((s->srv_secmode & SMB2_NEGOTIATE_SIGNING_ENABLED) != 0)
 217                 u->u_sign_flags |= SMB_SIGNING_ENABLED;
 218         if ((s->srv_secmode & SMB2_NEGOTIATE_SIGNING_REQUIRED) != 0 ||
 219             (s->cli_secmode & SMB2_NEGOTIATE_SIGNING_REQUIRED) != 0)
 220                 u->u_sign_flags |=
 221                     SMB_SIGNING_ENABLED | SMB_SIGNING_CHECK;
 222         mutex_exit(&u->u_mutex);


 412         if (s->sign_calc == NULL)
 413                 return;
 414 
 415         msg_len = sr->reply.chain_offset - sr->smb2_reply_hdr;
 416         (void) MBC_SHADOW_CHAIN(&tmp_mbc, &sr->reply,
 417             sr->smb2_reply_hdr, msg_len);
 418 
 419         /*
 420          * Calculate the MAC signature for this reply.
 421          * smb2_sign_calc() or smb3_sign_calc()
 422          */
 423         if (s->sign_calc(sr, &tmp_mbc, reply_sig) != 0)
 424                 return;
 425 
 426         /*
 427          * Poke the signature into the response.
 428          */
 429         hdr_off = sr->smb2_reply_hdr + SMB2_SIG_OFFS;
 430         (void) smb_mbc_poke(&sr->reply, hdr_off, "#c",
 431             SMB2_SIG_SIZE, reply_sig);
 432 }
 433 
 434 /*
 435  * Derive SMB3 key as described in [MS-SMB2] 3.1.4.2
 436  * and [NIST SP800-108]
 437  *
 438  * r = 32, L = 128, PRF = HMAC-SHA256, key = (session key)
 439  *
 440  * Note that these describe pre-3.1.1 inputs.
 441  *
 442  * Session.SigningKey for binding a session:
 443  * - Session.SessionKey as K1
 444  * - label = SMB2AESCMAC (size 12)
 445  * - context = SmbSign (size 8)
 446  * Channel.SigningKey for for all other requests
 447  * - if SMB2_SESSION_FLAG_BINDING, GSS key (in Session.SessionKey?) as K1;
 448  * - otherwise, Session.SessionKey as K1
 449  * - label = SMB2AESCMAC (size 12)
 450  * - context = SmbSign (size 8)
 451  * Session.ApplicationKey for ... (not sure what yet)
 452  * - Session.SessionKey as K1
 453  * - label = SMB2APP (size 8)
 454  * - context = SmbRpc (size 7)
 455  * Session.EncryptionKey for encrypting server messages
 456  * - Session.SessionKey as K1
 457  * - label = "SMB2AESCCM" (size 11)
 458  * - context = "ServerOut" (size 10)
 459  * Session.DecryptionKey for decrypting client requests
 460  * - Session.SessionKey as K1
 461  * - label = "SMB2AESCCM" (size 11)
 462  * - context = "ServerIn " (size 10) (Note the space)
 463  */
 464 
 465 int
 466 smb3_do_kdf(void *outbuf, void *input, size_t input_len,
 467     uint8_t *key, uint32_t key_len)
 468 {
 469         uint8_t digest32[SHA256_DIGEST_LENGTH];
 470         smb_crypto_mech_t mech;
 471         smb_sign_ctx_t hctx = 0;
 472         int rc;
 473 
 474         bzero(&mech, sizeof (mech));
 475         if ((rc = smb2_hmac_getmech(&mech)) != 0)
 476                 return (rc);
 477 
 478         /* Limit the SessionKey input to its maximum size (16 bytes) */
 479         rc = smb2_hmac_init(&hctx, &mech, key, MIN(key_len, SMB2_KEYLEN));
 480         if (rc != 0)
 481                 return (rc);
 482 
 483         if ((rc = smb2_hmac_update(hctx, input, input_len)) != 0)
 484                 return (rc);
 485 
 486         if ((rc = smb2_hmac_final(hctx, digest32)) != 0)
 487                 return (rc);
 488 
 489         /* Output is first 16 bytes of digest. */
 490         bcopy(digest32, outbuf, SMB3_KEYLEN);
 491         return (0);
 492 }


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  24  * Copyright 2020 RackTop Systems, Inc.
  25  */
  26 /*
  27  * These routines provide the SMB MAC signing for the SMB2 server.
  28  * The routines calculate the signature of a SMB message in an mbuf chain.
  29  *
  30  * The following table describes the client server
  31  * signing registry relationship
  32  *
  33  *              | Required      | Enabled     | Disabled
  34  * -------------+---------------+------------ +--------------
  35  * Required     | Signed        | Signed      | Fail
  36  * -------------+---------------+-------------+-----------------
  37  * Enabled      | Signed        | Signed      | Not Signed
  38  * -------------+---------------+-------------+----------------
  39  * Disabled     | Fail          | Not Signed  | Not Signed
  40  */
  41 
  42 #include <sys/uio.h>
  43 #include <smbsrv/smb2_kproto.h>
  44 #include <smbsrv/smb_kcrypt.h>


 102 
 103 static struct mac_ops
 104 smb3_sign_ops = {
 105         smb3_cmac_init,
 106         smb3_cmac_update,
 107         smb3_cmac_final
 108 };
 109 
 110 static int
 111 smb3_sign_calc(smb_request_t *sr,
 112     struct mbuf_chain *mbc,
 113     uint8_t *digest16)
 114 {
 115         int rv;
 116 
 117         rv = smb2_sign_calc_common(sr, mbc, digest16, &smb3_sign_ops);
 118 
 119         return (rv);
 120 }
 121 










 122 void
 123 smb2_sign_init_mech(smb_session_t *s)
 124 {
 125         smb_crypto_mech_t *mech;
 126         int (*get_mech)(smb_crypto_mech_t *);
 127         int (*sign_calc)(smb_request_t *, struct mbuf_chain *, uint8_t *);
 128         int rc;
 129 
 130         if (s->sign_mech != NULL)
 131                 return;
 132 
 133         if (s->dialect >= SMB_VERS_3_0) {
 134                 get_mech = smb3_cmac_getmech;
 135                 sign_calc = smb3_sign_calc;
 136         } else {
 137                 get_mech = smb2_hmac_getmech;
 138                 sign_calc = smb2_sign_calc;
 139         }
 140 
 141         mech = kmem_zalloc(sizeof (*mech), KM_SLEEP);


 170          * We should normally have a session key here because
 171          * our caller filters out Anonymous and Guest logons.
 172          * However, buggy clients could get us here without a
 173          * session key, in which case we'll fail later when a
 174          * request that requires signing can't be checked.
 175          * Also, don't bother initializing if we don't have a mechanism.
 176          */
 177         if (token->tkn_ssnkey.val == NULL || token->tkn_ssnkey.len == 0 ||
 178             s->sign_mech == NULL)
 179                 return;
 180 
 181         /*
 182          * Compute and store the signing key, which lives in
 183          * the user structure.
 184          */
 185         if (s->dialect >= SMB_VERS_3_0) {
 186                 /*
 187                  * For SMB3, the signing key is a "KDF" hash of the
 188                  * session key.
 189                  */
 190                 if (s->dialect >= SMB_VERS_3_11) {
 191                         if (smb3_kdf(sign_key->key,
 192                             token->tkn_ssnkey.val, token->tkn_ssnkey.len,
 193                             (uint8_t *)"SMBSigningKey", 14,
 194                             s->smb31_preauth_hashval, SHA512_DIGEST_LENGTH)
 195                             != 0)
 196                                 return;
 197                 } else {
 198                         if (smb3_kdf(sign_key->key,
 199                             token->tkn_ssnkey.val, token->tkn_ssnkey.len,
 200                             (uint8_t *)"SMB2AESCMAC", 12,
 201                             (uint8_t *)"SmbSign", 8)
 202                             != 0)
 203                                 return;
 204                 }
 205                 sign_key->len = SMB3_KEYLEN;
 206         } else {
 207                 /*
 208                  * For SMB2, the signing key is just the first 16 bytes
 209                  * of the session key (truncated or padded with zeros).
 210                  * [MS-SMB2] 3.2.5.3.1
 211                  */
 212                 sign_key->len = SMB2_KEYLEN;
 213                 bcopy(token->tkn_ssnkey.val, sign_key->key,
 214                     MIN(token->tkn_ssnkey.len, sign_key->len));
 215         }
 216 
 217         mutex_enter(&u->u_mutex);
 218         if ((s->srv_secmode & SMB2_NEGOTIATE_SIGNING_ENABLED) != 0)
 219                 u->u_sign_flags |= SMB_SIGNING_ENABLED;
 220         if ((s->srv_secmode & SMB2_NEGOTIATE_SIGNING_REQUIRED) != 0 ||
 221             (s->cli_secmode & SMB2_NEGOTIATE_SIGNING_REQUIRED) != 0)
 222                 u->u_sign_flags |=
 223                     SMB_SIGNING_ENABLED | SMB_SIGNING_CHECK;
 224         mutex_exit(&u->u_mutex);


 414         if (s->sign_calc == NULL)
 415                 return;
 416 
 417         msg_len = sr->reply.chain_offset - sr->smb2_reply_hdr;
 418         (void) MBC_SHADOW_CHAIN(&tmp_mbc, &sr->reply,
 419             sr->smb2_reply_hdr, msg_len);
 420 
 421         /*
 422          * Calculate the MAC signature for this reply.
 423          * smb2_sign_calc() or smb3_sign_calc()
 424          */
 425         if (s->sign_calc(sr, &tmp_mbc, reply_sig) != 0)
 426                 return;
 427 
 428         /*
 429          * Poke the signature into the response.
 430          */
 431         hdr_off = sr->smb2_reply_hdr + SMB2_SIG_OFFS;
 432         (void) smb_mbc_poke(&sr->reply, hdr_off, "#c",
 433             SMB2_SIG_SIZE, reply_sig);




























































 434 }