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 2021-2025 RackTop Systems, Inc.
14 */
15
16 #include <sys/param.h>
17 #include <sys/random.h>
18 #include <sys/sunddi.h>
19 #include <sys/sysmacros.h>
20 #include <sys/sdt.h>
21
22 #include <netsmb/smb_osdep.h>
23
24 #include <netsmb/smb.h>
25 #include <netsmb/smb2.h>
26 #include <netsmb/smb_conn.h>
27 #include <netsmb/smb_subr.h>
28 #include <netsmb/mchain.h>
29
30 #include <netsmb/nsmb_kcrypt.h>
31
32 #define NEG_CTX_MAX_COUNT (16)
33 #define NEG_CTX_MAX_DATALEN (256)
34
35 enum smb2_neg_ctx_type {
36 SMB2_PREAUTH_INTEGRITY_CAPS = 1,
37 SMB2_ENCRYPTION_CAPS = 2,
38 SMB2_COMPRESSION_CAPS = 3, /* not implemented */
39 SMB2_NETNAME_NEGOTIATE_CONTEXT_ID = 5 /* not implemented */
40 };
41
42 typedef struct smb2_negotiate_ctx {
43 uint16_t type;
44 uint16_t datalen;
45 } smb2_neg_ctx_t;
46
47 /*
48 * SMB 3.1.1 specifies only one pre-auth hash algorithm: SHA-512
49 * and four encryption ones: AES128-CCM/GCM, AES256-CCM/GCM
50 */
51 #define MAX_HASHID_NUM (1)
52 #define MAX_CIPHER_NUM (4)
53
54 #define SMB31_PREAUTH_CTX_SALT_LEN 32
55
56 typedef struct smb2_preauth_integrity_caps {
57 uint16_t picap_hash_count;
58 uint16_t picap_salt_len;
59 uint16_t picap_hash_id;
60 uint8_t picap_salt[SMB31_PREAUTH_CTX_SALT_LEN];
61 } smb2_preauth_caps_t;
62
63 typedef struct smb2_encryption_caps {
64 uint16_t encap_cipher_count;
65 uint16_t encap_cipher_ids[MAX_CIPHER_NUM];
66 } smb2_encrypt_caps_t;
67
68 /*
69 * The contexts we support
70 */
71 typedef struct smb2_preauth_neg_ctx {
72 smb2_neg_ctx_t neg_ctx;
73 smb2_preauth_caps_t preauth_caps;
74 } smb2_preauth_neg_ctx_t;
75
76 typedef struct smb2_encrypt_neg_ctx {
77 smb2_neg_ctx_t neg_ctx;
78 smb2_encrypt_caps_t encrypt_caps;
79 } smb2_encrypt_neg_ctx_t;
80
81 typedef struct smb2_neg_ctxs {
82 uint32_t offset;
83 uint16_t count;
84 smb2_preauth_neg_ctx_t preauth_ctx;
85 smb2_encrypt_neg_ctx_t encrypt_ctx;
86 } smb2_neg_ctxs_t;
87
88
89 /*
90 * SMB 3.1.1 Negotiate Contexts
91 */
92
93 /*
94 * Bit mask used during testing to simulate not supporting certain
95 * encryption ciphers. Bit N-1 corresponds to SMB3_CIPHER_* value N,
96 * so the default 0xf advertises all four ciphers. Settable via mdb(1).
97 * Make sure at least one of these bits is set: 1, 2, 4, 8
98 */
99 int nsmb_ciphers_enabled = 0xf;
100
101 /*
102 * Put neg. contexts
103 */
104 int
smb3_negctxs_encode(struct smb_vc * vcp,struct mbchain * mbp,uint32_t * negctx_off_p,uint16_t * negctx_cnt_p)105 smb3_negctxs_encode(struct smb_vc *vcp, struct mbchain *mbp,
106 uint32_t *negctx_off_p, uint16_t *negctx_cnt_p)
107 {
108
109 uint8_t salt[SMB31_PREAUTH_CTX_SALT_LEN];
110 size_t saltlen = sizeof (salt);
111 int start;
112 uint16_t *ccnt_p;
113 uint16_t *len_p;
114 uint16_t len;
115 uint16_t ctx_cnt = 0;
116 uint16_t ccnt = 0;
117
118 (void) random_get_pseudo_bytes(salt, saltlen);
119
120 /*
121 * Put Contexts. Align 8 first.
122 */
123 mb_put_align8(mbp);
124 *negctx_off_p = htolel(mbp->mb_count);
125
126 /*
127 * 2.2.3.1.1 SMB2_PREAUTH_INTEGRITY_CAPABILITIES
128 * This one is _required_ for SMB 3.1.1
129 */
130 mb_put_uint16le(mbp, SMB2_PREAUTH_INTEGRITY_CAPS);
131 len_p = mb_reserve(mbp, 2);
132 mb_put_uint32le(mbp, 0); /* Reserved */
133 start = mbp->mb_count;
134
135 mb_put_uint16le(mbp, 1); /* HashAlgorithmCount */
136 mb_put_uint16le(mbp, saltlen); /* SaltLength */
137
138 /* The only supported hash algo - SHA-512 */
139 mb_put_uint16le(mbp, SMB3_HASH_SHA512);
140 /* Salt */
141 mb_put_mem(mbp, salt, saltlen, MB_MSYSTEM);
142
143 len = mbp->mb_count - start;
144 *len_p = htoles(len);
145 ctx_cnt++;
146
147 /*
148 * 2.2.3.1.2 SMB2_ENCRYPTION_CAPABILITIES
149 * List ciphers most preferred first.
150 * Todo: make these configurable
151 */
152 mb_put_align8(mbp);
153
154 mb_put_uint16le(mbp, SMB2_ENCRYPTION_CAPS);
155 len_p = mb_reserve(mbp, 2);
156 mb_put_uint32le(mbp, 0); /* Reserved */
157 start = mbp->mb_count;
158
159 ccnt_p = mb_reserve(mbp, 2); /* CipherCount */
160
161 /*
162 * Ciphers, in order of preference.
163 * Prefer 256-bit ciphers, and then GCM over CCM
164 * (because GCM is more efficient than CCM)
165 * With modern servers, always AES256_GCM
166 */
167 if (nsmb_ciphers_enabled & (1 << (SMB3_CIPHER_AES256_GCM - 1))) {
168 mb_put_uint16le(mbp, SMB3_CIPHER_AES256_GCM);
169 ccnt++;
170 }
171 if (nsmb_ciphers_enabled & (1 << (SMB3_CIPHER_AES256_CCM - 1))) {
172 mb_put_uint16le(mbp, SMB3_CIPHER_AES256_CCM);
173 ccnt++;
174 }
175 if (nsmb_ciphers_enabled & (1 << (SMB3_CIPHER_AES128_GCM - 1))) {
176 mb_put_uint16le(mbp, SMB3_CIPHER_AES128_GCM);
177 ccnt++;
178 }
179 if (nsmb_ciphers_enabled & (1 << (SMB3_CIPHER_AES128_CCM - 1))) {
180 mb_put_uint16le(mbp, SMB3_CIPHER_AES128_CCM);
181 ccnt++;
182 }
183
184 *ccnt_p = htoles(ccnt);
185
186 len = mbp->mb_count - start;
187 *len_p = htoles(len);
188 ctx_cnt++;
189
190 *negctx_cnt_p = htoles(ctx_cnt);
191
192 return (0);
193 }
194
195
196 /*
197 * Decode the SMB2 NEGOTIATE_CONTEXT section.
198 * [MS-SMB2] 2.2.4.1 SMB2 NEGOTIATE_CONTEXT Response Values
199 *
200 * This function should be called only for dialect >= 0x311
201 * Negotiate context list should contain exactly one
202 * SMB2_PREAUTH_INTEGRITY_CAPS context. Spec. ref:
203 * [MS-SMB2] 3.2.5.2 ... SMB2 NEGOTIATE Response
204 *
205 * The response contains the encryption cipher the server selected
206 * from among those we offered, or NONE if there was no overlap.
207 *
208 * This returns Unix-style error codes in cases where the response
209 * could not be decoded or otherwise faulty in ways that mean we
210 * cannot continue with it. Returning an error here means the
211 * caller will drop the connection and give up.
212 *
213 * SMB 3.1.1 specifies the only hashing algorithm - SHA-512.
214 * SMB 3.1.1 specifies four encryption algorithms:
215 * AES-128-CCM, AES-128-GCM, AES-256-CCM, AES-256-GCM
216 */
217 int
smb3_negctxs_decode(struct smb_vc * vcp,struct mdchain * mdp,uint16_t negctx_cnt)218 smb3_negctxs_decode(struct smb_vc *vcp, struct mdchain *mdp,
219 uint16_t negctx_cnt)
220 {
221 smb2_neg_ctxs_t negctxs_stor;
222 smb2_neg_ctxs_t *neg_ctxs = &negctxs_stor;
223 smb2_preauth_caps_t *picap = &neg_ctxs->preauth_ctx.preauth_caps;
224 smb2_encrypt_caps_t *encap = &neg_ctxs->encrypt_ctx.encrypt_caps;
225 uint16_t cipher = 0;
226 int found_preauth_ctx = 0;
227 int found_encrypt_ctx = 0;
228 int err = 0;
229 int rc;
230
231 bzero(neg_ctxs, sizeof (*neg_ctxs));
232 neg_ctxs->offset = md_tell(mdp);
233 neg_ctxs->count = negctx_cnt;
234
235 /*
236 * There should be exactly 1 SMB2_PREAUTH_INTEGRITY_CAPS negotiate ctx.
237 * SMB2_ENCRYPTION_CAPS is optional one.
238 * If there is no contexts or there are too many then stop parsing.
239 */
240 if (neg_ctxs->count < 1 || neg_ctxs->count > NEG_CTX_MAX_COUNT) {
241 err = EINVAL;
242 goto errout;
243 }
244
245 /*
246 * Parse negotiate contexts. Ignore non-decoding errors to fill
247 * as much as possible data for dtrace probe. Decode into the
248 * temporary neg_ctx, and then once we know which type it is
249 * (in the switch below) copy it to the specific member, eg
250 * neg_ctxs->preauth_ctx.neg_ctx (do this copying even if
251 * we detect errors so we have better data in neg_ctxs
252 * for the dtrace probe later in this function).
253 */
254 for (int i = 0; i < neg_ctxs->count; i++) {
255 smb2_neg_ctx_t neg_ctx;
256 uint32_t ctx_start;
257 uint32_t ctx_end_off;
258 uint32_t ctx_next_off;
259
260 /*
261 * Every context must be 8-byte aligned.
262 */
263 ctx_start = md_tell(mdp);
264 if ((ctx_start % 8) != 0) {
265 err = EINVAL;
266 goto errout;
267 }
268
269 /*
270 * Get Type, len, and "reserved"
271 */
272 if (md_get_uint16le(mdp, &neg_ctx.type) != 0 ||
273 md_get_uint16le(mdp, &neg_ctx.datalen) != 0 ||
274 md_get_uint32le(mdp, NULL) != 0) {
275 err = EINVAL;
276 goto errout;
277 }
278 DTRACE_PROBE1(neg_ctx, smb2_neg_ctx_t *, &neg_ctx);
279
280 /*
281 * We got something crazy?
282 */
283 if (neg_ctx.datalen > NEG_CTX_MAX_DATALEN) {
284 err = EINVAL;
285 goto errout;
286 }
287
288 /*
289 * Figure out where the next ctx should be.
290 * We're now at position: ctx_start + 8
291 */
292 ctx_end_off = ctx_start + 8 + neg_ctx.datalen;
293 ctx_next_off = P2ROUNDUP(ctx_end_off, 8);
294
295 switch (neg_ctx.type) {
296 case SMB2_PREAUTH_INTEGRITY_CAPS:
297 memcpy(&neg_ctxs->preauth_ctx.neg_ctx, &neg_ctx,
298 sizeof (neg_ctx));
299
300 /*
301 * There should be exactly one of these,
302 * per. [MS-SMB2] sec. 3.2.5.2
303 */
304 if (found_preauth_ctx++ != 0) {
305 err = EINVAL;
306 goto errout;
307 }
308
309 rc = md_get_uint16le(mdp, &picap->picap_hash_count);
310 if (rc != 0) {
311 err = EINVAL;
312 goto errout;
313 }
314
315 rc = md_get_uint16le(mdp, &picap->picap_salt_len);
316 if (rc != 0) {
317 err = EINVAL;
318 goto errout;
319 }
320
321 /*
322 * Get hash id. Must have exactly one
323 * here in the reply to the client.
324 */
325 if (picap->picap_hash_count != 1) {
326 err = EINVAL;
327 goto errout;
328 }
329 rc = md_get_uint16le(mdp, &picap->picap_hash_id);
330 if (rc != 0) {
331 err = EINVAL;
332 goto errout;
333 }
334
335 /*
336 * Skip salt from the server reply.
337 * We don't use it directly. It's there
338 * just to make the hash less predictable.
339 * Skip the space it occupies.
340 */
341 rc = md_get_mem(mdp, NULL,
342 picap->picap_salt_len, MB_MSYSTEM);
343 if (rc != 0) {
344 err = EINVAL;
345 goto errout;
346 }
347 break;
348
349 case SMB2_ENCRYPTION_CAPS:
350 memcpy(&neg_ctxs->encrypt_ctx.neg_ctx, &neg_ctx,
351 sizeof (neg_ctx));
352
353 if (found_encrypt_ctx++ != 0) {
354 err = EINVAL;
355 goto errout;
356 }
357
358 /*
359 * Get the cipher. Should be exactly one,
360 * per. [MS-SMB2] sec. 3.2.5.2
361 */
362 rc = md_get_uint16le(mdp, &encap->encap_cipher_count);
363 if (rc != 0 || encap->encap_cipher_count != 1) {
364 err = EINVAL;
365 goto errout;
366 }
367 rc = md_get_uint16le(mdp,
368 &encap->encap_cipher_ids[0]);
369 if (rc != 0) {
370 err = EINVAL;
371 goto errout;
372 }
373 cipher = encap->encap_cipher_ids[0];
374 break;
375
376 default:
377 /*
378 * Unknown context types are ignored.
379 * We should only get context types that
380 * correspond to what we sent, but there's
381 * not really any need to enforce that.
382 */
383 SMBSDEBUG("Unknown neg. ctx. type: 0x%x",
384 neg_ctx.type);
385 break;
386 }
387
388 /*
389 * If there's another context after this,
390 * skip any padding that might remain, or
391 * parts we didn't bother to decode.
392 */
393 if ((i + 1) < neg_ctxs->count) {
394 int skip = ctx_next_off - md_tell(mdp);
395 if (skip < 0) {
396 err = EINVAL;
397 goto errout;
398 }
399 if (skip > 0) {
400 (void) md_get_mem(mdp, NULL, skip, MB_MSYSTEM);
401 }
402 }
403
404 }
405
406 if (err != 0)
407 goto errout;
408
409 DTRACE_PROBE1(decoded, smb2_neg_ctxs_t *, neg_ctxs);
410
411 /*
412 * In SMB 0x311 there should be exactly 1 preauth
413 * negotiate context, and there should be exactly 1
414 * hash value in the list - SHA512.
415 */
416 if (found_preauth_ctx != 1 || picap->picap_hash_count != 1) {
417 err = EINVAL;
418 goto errout;
419 }
420 if (picap->picap_hash_id != SMB3_HASH_SHA512) {
421 /* STATUS_SMB_NO_PREAUTH_INEGRITY_HASH_OVERLAP */
422 err = EAUTH;
423 goto errout;
424 }
425 vcp->vc3_preauth_hashid = SMB3_HASH_SHA512;
426
427 /*
428 * Negotiation response for the encryption cipher we'll use.
429 *
430 * In our negotiate request we provided a list of ciphers
431 * we're willing to use. If the server has any in common
432 * with our list, it will have chosen one and put that
433 * cipher ID in the response now in the "cipher" variable.
434 * If there were no mutually acceptable ciphers. we'll have
435 * cipher = SMB3_CIPHER_NONE. If the server does not know
436 * about cipher negotiation, the SMB2_ENCRYPTION_CAPS neg.
437 * context might be absent, and we treat that the same as
438 * the "no overlap" case (cipher = SMB3_CIPHER_NONE).
439 *
440 * If the result of this cipher negotiaion gives us
441 * cipher = SMB3_CIPHER_NONE, that means we cannot use
442 * SMB2 encrypted messages. In general, that alone is
443 * not a problem so severe that we should give up on this
444 * connection. We can use SMB2/3 requests and responses
445 * without encryption if the server permits that.
446 *
447 * If encryption is mandatory based on server policy, eg
448 * when some share is marked as "encryption required",
449 * then our later SMB Tree Connect (smbfs mount) will fail.
450 * Similarly if the server requires encryption for all
451 * connections, we'll get an error from the server after
452 * sending a mesage that should have been encrypted.
453 */
454 if (found_encrypt_ctx == 0) {
455 vcp->vc3_enc_cipherid = SMB3_CIPHER_NONE;
456 } else {
457 /* Sanity check what we got. */
458 switch (cipher) {
459 case SMB3_CIPHER_AES256_GCM:
460 case SMB3_CIPHER_AES128_GCM:
461 vcp->vc3_enc_cipherid = cipher;
462 break;
463 case SMB3_CIPHER_AES256_CCM:
464 case SMB3_CIPHER_AES128_CCM:
465 vcp->vc3_enc_cipherid = cipher;
466 break;
467 default:
468 vcp->vc3_enc_cipherid = SMB3_CIPHER_NONE;
469 break;
470 }
471 }
472
473 errout:
474 return (err);
475 }
476