xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb3_encrypt.c (revision 4e5ef1cee66fbfbbd2b3e56b81e2bb5700f4a59e)
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
64 smb3_encrypt_init_nonce(smb_user_t *user)
65 {
66 	user->u_nonce_cnt = 0;
67 	(void) random_get_pseudo_bytes(user->u_nonce_fixed,
68 	    sizeof (user->u_nonce_fixed));
69 	(void) random_get_pseudo_bytes((uint8_t *)&user->u_salt,
70 	    sizeof (user->u_salt));
71 }
72 
73 int
74 smb3_encrypt_gen_nonce(smb_user_t *user, uint8_t *buf, size_t len)
75 {
76 	uint64_t cnt = atomic_inc_64_nv(&user->u_nonce_cnt);
77 
78 	/*
79 	 * Nonces must be unique per-key for the life of the key.
80 	 * Bail before we roll over to avoid breaking the crypto.
81 	 */
82 
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;
125 	struct smb_key *dec_key = &u->u_dec_key;
126 
127 	/*
128 	 * In order to enforce encryption, all users need to
129 	 * have Session.EncryptData properly set, even anon/guest.
130 	 */
131 	u->u_encrypt = s->s_server->sv_cfg.skc_encrypt;
132 	enc_key->len = 0;
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 	 */
234 	mbuf = mbc->chain;
235 	while (mbuf != NULL && (offset >= mbuf->m_len)) {
236 		offset -= mbuf->m_len;
237 		mbuf = mbuf->m_next;
238 	}
239 
240 	if (mbuf == NULL)
241 		return (-1);
242 
243 	/*
244 	 * Digest the remainder of this mbuf, limited to the
245 	 * residual count, and starting at the current offset.
246 	 */
247 	tlen = mbuf->m_len - offset;
248 	if (tlen > resid)
249 		tlen = resid;
250 
251 	rc = smb3_decrypt_update(&ctx, (uint8_t *)mbuf->m_data + offset, tlen);
252 	if (rc != 0) {
253 		return (rc);
254 	}
255 	resid -= tlen;
256 
257 	/*
258 	 * Digest any more mbufs in the chain.
259 	 */
260 	while (resid > 0) {
261 		mbuf = mbuf->m_next;
262 		if (mbuf == NULL) {
263 			smb3_encrypt_cancel(&ctx);
264 			return (-1);
265 		}
266 		tlen = mbuf->m_len;
267 		if (tlen > resid)
268 			tlen = resid;
269 		rc = smb3_decrypt_update(&ctx, (uint8_t *)mbuf->m_data, tlen);
270 		if (rc != 0) {
271 			return (rc);
272 		}
273 		resid -= tlen;
274 	}
275 
276 	/*
277 	 * AES_CCM processes the signature like normal data.
278 	 */
279 	rc = smb3_decrypt_update(&ctx, sr->smb2_sig, SMB2_SIG_SIZE);
280 
281 	if (rc != 0) {
282 		cmn_err(CE_WARN, "failed to process signature");
283 		return (rc);
284 	}
285 	/*
286 	 * smb3_decrypt_final will return an error
287 	 * if the signatures don't match.
288 	 */
289 	rc = smb3_decrypt_final(&ctx, sr->sr_request_buf, sr->sr_req_length);
290 
291 	/*
292 	 * We had to decode TFORM_HDR_SIZE bytes before we got here,
293 	 * and we just peeked the first TFORM_HDR_SIZE bytes at the
294 	 * beginning of this function, so this can't underflow.
295 	 */
296 	ASSERT(sr->command.max_bytes > SMB3_TFORM_HDR_SIZE);
297 	sr->command.max_bytes -= SMB3_TFORM_HDR_SIZE;
298 	return (rc);
299 }
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) {
366 		tlen = mbuf->m_len;
367 		if (tlen > resid)
368 			tlen = resid;
369 		rc = smb3_encrypt_update(&ctx, (uint8_t *)mbuf->m_data, tlen);
370 		if (rc != 0) {
371 			return (rc);
372 		}
373 		resid -= tlen;
374 		mbuf = mbuf->m_next;
375 	}
376 
377 	if (mbuf == NULL && resid > 0) {
378 		cmn_err(CE_WARN, "not enough data to encrypt");
379 		smb3_encrypt_cancel(&ctx);
380 		return (-1);
381 	}
382 
383 	rc = smb3_encrypt_final(&ctx, buf + SMB3_SIG_OFFS);
384 
385 	return (rc);
386 }
387 
388 void
389 smb3_encrypt_fini(smb_session_t *s)
390 {
391 	smb_crypto_mech_t *mech;
392 
393 	if ((mech = s->enc_mech) != NULL) {
394 		kmem_free(mech, sizeof (*mech));
395 		s->enc_mech = NULL;
396 	}
397 }
398