xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb3_encrypt.c (revision 45ede40b2394db7967e59f19288fae9b62efd4aa)
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
50 smb3_encrypt_init_nonce(smb_user_t *user)
51 {
52 	user->u_nonce_cnt = 0;
53 	(void) random_get_pseudo_bytes(user->u_nonce_fixed,
54 	    sizeof (user->u_nonce_fixed));
55 	(void) random_get_pseudo_bytes((uint8_t *)&user->u_salt,
56 	    sizeof (user->u_salt));
57 }
58 
59 int
60 smb3_encrypt_gen_nonce(smb_user_t *user, uint8_t *buf, size_t len)
61 {
62 	uint64_t cnt = atomic_inc_64_nv(&user->u_nonce_cnt);
63 
64 	/*
65 	 * Nonces must be unique per-key for the life of the key.
66 	 * Bail before we roll over to avoid breaking the crypto.
67 	 */
68 
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 		rc = -1;
103 		break;
104 	}
105 
106 	if (rc != 0) {
107 		kmem_free(mech, sizeof (*mech));
108 		return (rc);
109 	}
110 	s->enc_mech = mech;
111 
112 	return (0);
113 }
114 
115 /*
116  * Initializes keys/state required for SMB3 Encryption.
117  * Note: If a failure occurs here, don't fail the request.
118  * Instead, return an error when we attempt to encrypt/decrypt.
119  */
120 void
121 smb3_encrypt_begin(smb_request_t *sr, smb_token_t *token)
122 {
123 	smb_session_t *s = sr->session;
124 	smb_user_t *u = sr->uid_user;
125 	struct smb_key *enc_key = &u->u_enc_key;
126 	struct smb_key *dec_key = &u->u_dec_key;
127 
128 	/*
129 	 * In order to enforce encryption, all users need to
130 	 * have Session.EncryptData properly set, even anon/guest.
131 	 */
132 	u->u_encrypt = s->s_server->sv_cfg.skc_encrypt;
133 	enc_key->len = 0;
134 	dec_key->len = 0;
135 
136 	/*
137 	 * If we don't have a session key, we'll fail later when a
138 	 * request that requires (en/de)cryption can't be (en/de)crypted.
139 	 * Also don't bother initializing if we don't have a mechanism.
140 	 */
141 	if (token->tkn_ssnkey.val == NULL || token->tkn_ssnkey.len == 0 ||
142 	    s->enc_mech == NULL)
143 		return;
144 
145 	/*
146 	 * Compute and store the encryption keys, which live in
147 	 * the user structure.
148 	 */
149 
150 	/*
151 	 * For SMB3, the encrypt/decrypt keys are derived from
152 	 * the session key using KDF in counter mode.
153 	 */
154 	if (s->dialect >= SMB_VERS_3_11) {
155 		if (smb3_kdf(enc_key->key,
156 		    token->tkn_ssnkey.val, token->tkn_ssnkey.len,
157 		    (uint8_t *)"SMBS2CCipherKey", 16,
158 		    u->u_preauth_hashval, SHA512_DIGEST_LENGTH) != 0)
159 			return;
160 
161 		if (smb3_kdf(dec_key->key,
162 		    token->tkn_ssnkey.val, token->tkn_ssnkey.len,
163 		    (uint8_t *)"SMBC2SCipherKey", 16,
164 		    u->u_preauth_hashval, SHA512_DIGEST_LENGTH) != 0)
165 			return;
166 	} else {
167 		if (smb3_kdf(enc_key->key,
168 		    token->tkn_ssnkey.val, token->tkn_ssnkey.len,
169 		    (uint8_t *)"SMB2AESCCM", 11,
170 		    (uint8_t *)"ServerOut", 10) != 0)
171 			return;
172 
173 		if (smb3_kdf(dec_key->key,
174 		    token->tkn_ssnkey.val, token->tkn_ssnkey.len,
175 		    (uint8_t *)"SMB2AESCCM", 11,
176 		    (uint8_t *)"ServerIn ", 10) != 0)
177 			return;
178 	}
179 
180 	smb3_encrypt_init_nonce(u);
181 
182 	enc_key->len = SMB3_KEYLEN;
183 	dec_key->len = SMB3_KEYLEN;
184 }
185 
186 /*
187  * Decrypt the request in sr->command.
188  * This decrypts "in place", though due to CCM's design,
189  * it processes all input before doing any output.
190  */
191 int
192 smb3_decrypt_sr(smb_request_t *sr)
193 {
194 	struct mbuf_chain *mbc = &sr->command;
195 	smb_session_t *s = sr->session;
196 	smb_user_t *u = sr->tform_ssn;
197 	uint8_t tmp_hdr[SMB2_HDR_SIZE];
198 	smb3_enc_ctx_t ctx;
199 	struct smb_key *dec_key = &u->u_dec_key;
200 	struct mbuf *mbuf;
201 	int offset, resid, tlen, rc;
202 	smb3_crypto_param_t param;
203 	smb_crypto_mech_t mech;
204 	boolean_t gcm = sr->session->smb31_enc_cipherid ==
205 	    SMB3_CIPHER_AES128_GCM;
206 	size_t nonce_size = (gcm ? SMB3_AES128_GCM_NONCE_SIZE :
207 	    SMB3_AES128_CCM_NONCE_SIZE);
208 
209 	ASSERT(u != NULL);
210 	if (s->enc_mech == NULL || dec_key->len != 16) {
211 		return (-1);
212 	}
213 
214 	tlen = SMB3_TFORM_HDR_SIZE - SMB3_NONCE_OFFS;
215 	offset = mbc->chain_offset + SMB3_NONCE_OFFS;
216 	resid = mbc->max_bytes - offset;
217 
218 	if (resid < (sr->msgsize + tlen)) {
219 		cmn_err(CE_WARN, "too little data to decrypt");
220 		return (-1);
221 	}
222 
223 	if (smb_mbc_peek(mbc, offset, "#c", tlen, tmp_hdr) != 0) {
224 		return (-1);
225 	}
226 
227 	offset += tlen;
228 	resid -= tlen;
229 
230 	/*
231 	 * The transform header, minus the PROTOCOL_ID and the
232 	 * SIGNATURE, is authenticated but not encrypted.
233 	 */
234 	if (gcm)
235 		smb3_crypto_init_gcm_param(&param, sr->nonce, nonce_size,
236 		    tmp_hdr, tlen);
237 	else
238 		smb3_crypto_init_ccm_param(&param, sr->nonce, nonce_size,
239 		    tmp_hdr, tlen, sr->msgsize + SMB2_SIG_SIZE);
240 
241 	/*
242 	 * Unlike signing, which uses one global mech struct,
243 	 * encryption requires modifying the mech to add a
244 	 * per-use param struct. Thus, we need to make a copy.
245 	 */
246 	mech = *(smb_crypto_mech_t *)s->enc_mech;
247 	rc = smb3_decrypt_init(&ctx, &mech, &param,
248 	    dec_key->key, dec_key->len);
249 	if (rc != 0) {
250 		return (rc);
251 	}
252 
253 	/*
254 	 * Digest the rest of the SMB packet, starting at the data
255 	 * just after the SMB header.
256 	 *
257 	 * Advance to the src mbuf where we start digesting.
258 	 */
259 	mbuf = mbc->chain;
260 	while (mbuf != NULL && (offset >= mbuf->m_len)) {
261 		offset -= mbuf->m_len;
262 		mbuf = mbuf->m_next;
263 	}
264 
265 	if (mbuf == NULL)
266 		return (-1);
267 
268 	/*
269 	 * Digest the remainder of this mbuf, limited to the
270 	 * residual count, and starting at the current offset.
271 	 */
272 	tlen = mbuf->m_len - offset;
273 	if (tlen > resid)
274 		tlen = resid;
275 
276 	rc = smb3_decrypt_update(&ctx, (uint8_t *)mbuf->m_data + offset, tlen);
277 	if (rc != 0) {
278 		return (rc);
279 	}
280 	resid -= tlen;
281 
282 	/*
283 	 * Digest any more mbufs in the chain.
284 	 */
285 	while (resid > 0) {
286 		mbuf = mbuf->m_next;
287 		if (mbuf == NULL) {
288 			smb3_encrypt_cancel(&ctx);
289 			return (-1);
290 		}
291 		tlen = mbuf->m_len;
292 		if (tlen > resid)
293 			tlen = resid;
294 		rc = smb3_decrypt_update(&ctx, (uint8_t *)mbuf->m_data, tlen);
295 		if (rc != 0) {
296 			return (rc);
297 		}
298 		resid -= tlen;
299 	}
300 
301 	/*
302 	 * AES_CCM processes the signature like normal data.
303 	 */
304 	rc = smb3_decrypt_update(&ctx, sr->smb2_sig, SMB2_SIG_SIZE);
305 
306 	if (rc != 0) {
307 		cmn_err(CE_WARN, "failed to process signature");
308 		return (rc);
309 	}
310 	/*
311 	 * smb3_decrypt_final will return an error
312 	 * if the signatures don't match.
313 	 */
314 	rc = smb3_decrypt_final(&ctx, sr->sr_request_buf, sr->sr_req_length);
315 
316 	/*
317 	 * We had to decode TFORM_HDR_SIZE bytes before we got here,
318 	 * and we just peeked the first TFORM_HDR_SIZE bytes at the
319 	 * beginning of this function, so this can't underflow.
320 	 */
321 	ASSERT(sr->command.max_bytes > SMB3_TFORM_HDR_SIZE);
322 	sr->command.max_bytes -= SMB3_TFORM_HDR_SIZE;
323 	return (rc);
324 }
325 
326 /*
327  * Encrypt the response in in_mbc, and output
328  * an encrypted response in out_mbc.
329  * The data in in_mbc is preserved.
330  */
331 int
332 smb3_encrypt_sr(smb_request_t *sr, struct mbuf_chain *in_mbc,
333     struct mbuf_chain *out_mbc)
334 {
335 	smb_session_t *s = sr->session;
336 	smb_user_t *u = sr->tform_ssn;
337 	uint8_t *buf = (uint8_t *)out_mbc->chain->m_data;
338 	size_t buflen = out_mbc->max_bytes;
339 	smb3_enc_ctx_t ctx;
340 	struct smb_key *enc_key = &u->u_enc_key;
341 	struct mbuf *mbuf;
342 	int resid, tlen, rc;
343 	smb3_crypto_param_t param;
344 	smb_crypto_mech_t mech;
345 	boolean_t gcm = sr->session->smb31_enc_cipherid ==
346 	    SMB3_CIPHER_AES128_GCM;
347 	size_t nonce_size = (gcm ? SMB3_AES128_GCM_NONCE_SIZE :
348 	    SMB3_AES128_CCM_NONCE_SIZE);
349 
350 	ASSERT(u != NULL);
351 	if (s->enc_mech == NULL || enc_key->len != 16) {
352 		return (-1);
353 	}
354 
355 	rc = smb3_encrypt_gen_nonce(u, sr->nonce, nonce_size);
356 
357 	if (rc != 0) {
358 		cmn_err(CE_WARN, "ran out of nonces");
359 		return (-1);
360 	}
361 
362 	(void) smb_mbc_poke(out_mbc, SMB3_NONCE_OFFS, "#c",
363 	    nonce_size, sr->nonce);
364 
365 	resid = in_mbc->max_bytes;
366 
367 	/*
368 	 * The transform header, minus the PROTOCOL_ID and the
369 	 * SIGNATURE, is authenticated but not encrypted.
370 	 */
371 	if (gcm)
372 		smb3_crypto_init_gcm_param(&param, sr->nonce, nonce_size,
373 		    buf + SMB3_NONCE_OFFS,
374 		    SMB3_TFORM_HDR_SIZE - SMB3_NONCE_OFFS);
375 	else
376 		smb3_crypto_init_ccm_param(&param, sr->nonce, nonce_size,
377 		    buf + SMB3_NONCE_OFFS,
378 		    SMB3_TFORM_HDR_SIZE - SMB3_NONCE_OFFS, resid);
379 
380 	/*
381 	 * Unlike signing, which uses one global mech struct,
382 	 * encryption requires modifying the mech to add a
383 	 * per-use param struct. Thus, we need to make a copy.
384 	 */
385 	mech = *(smb_crypto_mech_t *)s->enc_mech;
386 	rc = smb3_encrypt_init(&ctx, &mech, &param,
387 	    enc_key->key, enc_key->len, buf + SMB3_TFORM_HDR_SIZE,
388 	    buflen - SMB3_TFORM_HDR_SIZE);
389 	if (rc != 0) {
390 		return (rc);
391 	}
392 
393 	/*
394 	 * Unlike signing and decryption, we're processing the entirety of the
395 	 * message here, so we don't skip anything.
396 	 */
397 	mbuf = in_mbc->chain;
398 	while (resid > 0 && mbuf != NULL) {
399 		tlen = mbuf->m_len;
400 		if (tlen > resid)
401 			tlen = resid;
402 		rc = smb3_encrypt_update(&ctx, (uint8_t *)mbuf->m_data, tlen);
403 		if (rc != 0) {
404 			return (rc);
405 		}
406 		resid -= tlen;
407 		mbuf = mbuf->m_next;
408 	}
409 
410 	if (mbuf == NULL && resid > 0) {
411 		cmn_err(CE_WARN, "not enough data to encrypt");
412 		smb3_encrypt_cancel(&ctx);
413 		return (-1);
414 	}
415 
416 	rc = smb3_encrypt_final(&ctx, buf + SMB3_SIG_OFFS);
417 
418 	return (rc);
419 }
420 
421 void
422 smb3_encrypt_fini(smb_session_t *s)
423 {
424 	smb_crypto_mech_t *mech;
425 
426 	if ((mech = s->enc_mech) != NULL) {
427 		kmem_free(mech, sizeof (*mech));
428 		s->enc_mech = NULL;
429 	}
430 }
431