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 }
|