Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : SMB Signing Code
4 : Copyright (C) Jeremy Allison 2003.
5 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
6 : Copyright (C) Stefan Metzmacher 2009
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "smb_common.h"
24 : #include "smb_signing.h"
25 :
26 : #include "lib/crypto/gnutls_helpers.h"
27 : #include <gnutls/gnutls.h>
28 : #include <gnutls/crypto.h>
29 :
30 : /* Used by the SMB1 signing functions. */
31 :
32 : struct smb1_signing_state {
33 : /* is signing locally allowed */
34 : bool allowed;
35 :
36 : /* is signing locally desired */
37 : bool desired;
38 :
39 : /* is signing locally mandatory */
40 : bool mandatory;
41 :
42 : /* is signing negotiated by the peer */
43 : bool negotiated;
44 :
45 : bool active; /* Have I ever seen a validly signed packet? */
46 :
47 : /* mac_key.length > 0 means signing is started */
48 : DATA_BLOB mac_key;
49 :
50 : /* the next expected seqnum */
51 : uint32_t seqnum;
52 :
53 : TALLOC_CTX *mem_ctx;
54 : void *(*alloc_fn)(TALLOC_CTX *mem_ctx, size_t len);
55 : void (*free_fn)(TALLOC_CTX *mem_ctx, void *ptr);
56 : };
57 :
58 2931 : static void smb1_signing_reset_info(struct smb1_signing_state *si)
59 : {
60 2931 : si->active = false;
61 2931 : si->seqnum = 0;
62 :
63 2931 : if (si->free_fn) {
64 0 : si->free_fn(si->mem_ctx, si->mac_key.data);
65 : } else {
66 2931 : talloc_free(si->mac_key.data);
67 : }
68 2931 : si->mac_key.data = NULL;
69 2931 : si->mac_key.length = 0;
70 2931 : }
71 :
72 66409 : struct smb1_signing_state *smb1_signing_init_ex(TALLOC_CTX *mem_ctx,
73 : bool allowed,
74 : bool desired,
75 : bool mandatory,
76 : void *(*alloc_fn)(TALLOC_CTX *, size_t),
77 : void (*free_fn)(TALLOC_CTX *, void *))
78 : {
79 1736 : struct smb1_signing_state *si;
80 :
81 66409 : if (alloc_fn) {
82 0 : void *p = alloc_fn(mem_ctx, sizeof(struct smb1_signing_state));
83 0 : if (p == NULL) {
84 0 : return NULL;
85 : }
86 0 : memset(p, 0, sizeof(struct smb1_signing_state));
87 0 : si = (struct smb1_signing_state *)p;
88 0 : si->mem_ctx = mem_ctx;
89 0 : si->alloc_fn = alloc_fn;
90 0 : si->free_fn = free_fn;
91 : } else {
92 66409 : si = talloc_zero(mem_ctx, struct smb1_signing_state);
93 66409 : if (si == NULL) {
94 0 : return NULL;
95 : }
96 : }
97 :
98 66409 : if (mandatory) {
99 20590 : desired = true;
100 : }
101 :
102 64976 : if (desired) {
103 22029 : allowed = true;
104 : }
105 :
106 66409 : si->allowed = allowed;
107 66409 : si->desired = desired;
108 66409 : si->mandatory = mandatory;
109 :
110 66409 : return si;
111 : }
112 :
113 66409 : struct smb1_signing_state *smb1_signing_init(TALLOC_CTX *mem_ctx,
114 : bool allowed,
115 : bool desired,
116 : bool mandatory)
117 : {
118 66409 : return smb1_signing_init_ex(mem_ctx, allowed, desired, mandatory,
119 : NULL, NULL);
120 : }
121 :
122 554585 : static bool smb1_signing_good(struct smb1_signing_state *si,
123 : bool good, uint32_t seq)
124 : {
125 554585 : if (good) {
126 554582 : if (!si->active) {
127 2928 : si->active = true;
128 : }
129 554582 : return true;
130 : }
131 :
132 3 : if (!si->mandatory && !si->active) {
133 : /* Non-mandatory signing - just turn off if this is the first bad packet.. */
134 0 : DBG_INFO("signing negotiated but not required and peer\n"
135 : "isn't sending correct signatures. Turning off.\n");
136 0 : smb1_signing_reset_info(si);
137 0 : return true;
138 : }
139 :
140 : /* Mandatory signing or bad packet after signing started - fail and disconnect. */
141 3 : DBG_ERR("BAD SIG: seq %u\n", (unsigned int)seq);
142 3 : return false;
143 : }
144 :
145 1109096 : static NTSTATUS smb1_signing_md5(const DATA_BLOB *mac_key,
146 : const uint8_t *hdr, size_t len,
147 : uint32_t seq_number,
148 : uint8_t calc_md5_mac[16])
149 : {
150 1109096 : const size_t offset_end_of_sig = (HDR_SS_FIELD + 8);
151 30606 : uint8_t sequence_buf[8];
152 1109096 : gnutls_hash_hd_t hash_hnd = NULL;
153 30606 : int rc;
154 :
155 : /*
156 : * Firstly put the sequence number into the first 4 bytes.
157 : * and zero out the next 4 bytes.
158 : *
159 : * We do this here, to avoid modifying the packet.
160 : */
161 :
162 1109096 : DBG_DEBUG("sequence number %u\n", seq_number );
163 :
164 1109096 : SIVAL(sequence_buf, 0, seq_number);
165 1109096 : SIVAL(sequence_buf, 4, 0);
166 :
167 : /*
168 : * Calculate the 16 byte MAC - but don't alter the data in the
169 : * incoming packet.
170 : *
171 : * This makes for a bit of fussing about, but it's not too bad.
172 : */
173 1109096 : rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5);
174 1109096 : if (rc < 0) {
175 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
176 : }
177 : /* Initialise with the key. */
178 1109096 : rc = gnutls_hash(hash_hnd, mac_key->data, mac_key->length);
179 1109096 : if (rc < 0) {
180 0 : gnutls_hash_deinit(hash_hnd, NULL);
181 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
182 : }
183 : /* Copy in the first bit of the SMB header. */
184 1109096 : rc = gnutls_hash(hash_hnd, hdr, HDR_SS_FIELD);
185 1109096 : if (rc < 0) {
186 0 : gnutls_hash_deinit(hash_hnd, NULL);
187 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
188 : }
189 : /* Copy in the sequence number, instead of the signature. */
190 1109096 : rc = gnutls_hash(hash_hnd, sequence_buf, sizeof(sequence_buf));
191 1109096 : if (rc < 0) {
192 0 : gnutls_hash_deinit(hash_hnd, NULL);
193 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
194 : }
195 : /* Copy in the rest of the packet in, skipping the signature. */
196 1109096 : rc = gnutls_hash(hash_hnd, hdr + offset_end_of_sig, len - offset_end_of_sig);
197 1109096 : if (rc < 0) {
198 0 : gnutls_hash_deinit(hash_hnd, NULL);
199 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
200 : }
201 :
202 1109096 : gnutls_hash_deinit(hash_hnd, calc_md5_mac);
203 :
204 1109096 : return NT_STATUS_OK;
205 : }
206 :
207 1606548 : uint32_t smb1_signing_next_seqnum(struct smb1_signing_state *si, bool oneway)
208 : {
209 16108 : uint32_t seqnum;
210 :
211 1606548 : if (si->mac_key.length == 0) {
212 1052138 : return 0;
213 : }
214 :
215 553472 : seqnum = si->seqnum;
216 553472 : if (oneway) {
217 529 : si->seqnum += 1;
218 : } else {
219 552943 : si->seqnum += 2;
220 : }
221 :
222 538302 : return seqnum;
223 : }
224 :
225 989 : void smb1_signing_cancel_reply(struct smb1_signing_state *si, bool oneway)
226 : {
227 989 : if (si->mac_key.length == 0) {
228 989 : return;
229 : }
230 :
231 0 : if (oneway) {
232 0 : si->seqnum -= 1;
233 : } else {
234 0 : si->seqnum -= 2;
235 : }
236 : }
237 :
238 1604910 : NTSTATUS smb1_signing_sign_pdu(struct smb1_signing_state *si,
239 : uint8_t *outhdr, size_t len,
240 : uint32_t seqnum)
241 : {
242 16100 : uint8_t calc_md5_mac[16];
243 16100 : uint8_t com;
244 16100 : uint8_t flags;
245 :
246 1604910 : if (si->mac_key.length == 0) {
247 1050429 : if (!si->negotiated) {
248 1047629 : return NT_STATUS_OK;
249 : }
250 : }
251 :
252 : /* JRA Paranioa test - we should be able to get rid of this... */
253 557281 : if (len < (HDR_SS_FIELD + 8)) {
254 0 : DBG_WARNING("Logic error. "
255 : "Can't check signature on short packet! smb_len = %u\n",
256 : (unsigned)len);
257 0 : abort();
258 : }
259 :
260 557281 : com = SVAL(outhdr, HDR_COM);
261 557281 : flags = SVAL(outhdr, HDR_FLG);
262 :
263 557281 : if (!(flags & FLAG_REPLY)) {
264 479511 : uint16_t flags2 = SVAL(outhdr, HDR_FLG2);
265 : /*
266 : * If this is a request, specify what is
267 : * supported or required by the client
268 : */
269 479511 : if (si->negotiated && si->desired) {
270 9799 : flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
271 : }
272 479511 : if (si->negotiated && si->mandatory) {
273 9772 : flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
274 : }
275 479511 : SSVAL(outhdr, HDR_FLG2, flags2);
276 : }
277 :
278 557281 : if (si->mac_key.length == 0) {
279 : /* I wonder what BSRSPYL stands for - but this is what MS
280 : actually sends! */
281 2800 : if (com == SMBsesssetupX) {
282 2719 : memcpy(calc_md5_mac, "BSRSPYL ", 8);
283 : } else {
284 81 : memset(calc_md5_mac, 0, 8);
285 : }
286 : } else {
287 15303 : NTSTATUS status;
288 :
289 554481 : status = smb1_signing_md5(&si->mac_key,
290 : outhdr,
291 : len,
292 : seqnum,
293 : calc_md5_mac);
294 554481 : if (!NT_STATUS_IS_OK(status)) {
295 0 : return status;
296 : }
297 : }
298 :
299 557281 : DBG_DEBUG("sent SMB signature of\n");
300 557281 : dump_data(10, calc_md5_mac, 8);
301 :
302 557281 : memcpy(&outhdr[HDR_SS_FIELD], calc_md5_mac, 8);
303 :
304 : /* outhdr[HDR_SS_FIELD+2]=0;
305 : Uncomment this to test if the remote server actually verifies signatures...*/
306 :
307 557281 : return NT_STATUS_OK;
308 : }
309 :
310 1589195 : bool smb1_signing_check_pdu(struct smb1_signing_state *si,
311 : const uint8_t *inhdr, size_t len,
312 : uint32_t seqnum)
313 : {
314 15851 : bool good;
315 15851 : uint8_t calc_md5_mac[16];
316 15851 : const uint8_t *reply_sent_mac;
317 15851 : NTSTATUS status;
318 :
319 1589195 : if (si->mac_key.length == 0) {
320 1034062 : return true;
321 : }
322 :
323 554585 : if (len < (HDR_SS_FIELD + 8)) {
324 0 : DBG_WARNING("Can't check signature "
325 : "on short packet! smb_len = %u\n",
326 : (unsigned)len);
327 0 : return false;
328 : }
329 :
330 554585 : status = smb1_signing_md5(&si->mac_key,
331 : inhdr,
332 : len,
333 : seqnum,
334 : calc_md5_mac);
335 554585 : if (!NT_STATUS_IS_OK(status)) {
336 0 : DBG_ERR("Failed to calculate signing mac: %s\n",
337 : nt_errstr(status));
338 0 : return false;
339 : }
340 :
341 554585 : reply_sent_mac = &inhdr[HDR_SS_FIELD];
342 554585 : good = mem_equal_const_time(reply_sent_mac, calc_md5_mac, 8);
343 :
344 554585 : if (!good) {
345 0 : int i;
346 3 : const int sign_range = 5;
347 :
348 3 : DBG_INFO("BAD SIG: wanted SMB signature of\n");
349 3 : dump_data(5, calc_md5_mac, 8);
350 :
351 3 : DBG_INFO("BAD SIG: got SMB signature of\n");
352 3 : dump_data(5, reply_sent_mac, 8);
353 :
354 33 : for (i = -sign_range; i < sign_range; i++) {
355 30 : smb1_signing_md5(&si->mac_key, inhdr, len,
356 : seqnum+i, calc_md5_mac);
357 30 : if (mem_equal_const_time(reply_sent_mac, calc_md5_mac, 8)) {
358 0 : DBG_ERR("out of seq. seq num %u matches. "
359 : "We were expecting seq %u\n",
360 : (unsigned int)seqnum+i,
361 : (unsigned int)seqnum);
362 0 : break;
363 : }
364 : }
365 : } else {
366 554582 : DBG_DEBUG("seq %u: got good SMB signature of\n",
367 : (unsigned int)seqnum);
368 554582 : dump_data(10, reply_sent_mac, 8);
369 : }
370 :
371 554585 : return smb1_signing_good(si, good, seqnum);
372 : }
373 :
374 7638 : bool smb1_signing_activate(struct smb1_signing_state *si,
375 : const DATA_BLOB user_session_key,
376 : const DATA_BLOB response)
377 : {
378 266 : size_t len;
379 266 : off_t ofs;
380 :
381 7638 : if (!user_session_key.length) {
382 23 : return false;
383 : }
384 :
385 7615 : if (!si->negotiated) {
386 4644 : return false;
387 : }
388 :
389 2971 : if (si->active) {
390 40 : return false;
391 : }
392 :
393 2931 : if (si->mac_key.length > 0) {
394 0 : return false;
395 : }
396 :
397 2931 : smb1_signing_reset_info(si);
398 :
399 2931 : len = response.length + user_session_key.length;
400 2931 : if (si->alloc_fn) {
401 0 : si->mac_key.data = (uint8_t *)si->alloc_fn(si->mem_ctx, len);
402 0 : if (si->mac_key.data == NULL) {
403 0 : return false;
404 : }
405 : } else {
406 2931 : si->mac_key.data = (uint8_t *)talloc_size(si, len);
407 2931 : if (si->mac_key.data == NULL) {
408 0 : return false;
409 : }
410 : }
411 2931 : si->mac_key.length = len;
412 :
413 2931 : ofs = 0;
414 2931 : memcpy(&si->mac_key.data[ofs], user_session_key.data, user_session_key.length);
415 :
416 2931 : DBG_DEBUG("user_session_key\n");
417 2931 : dump_data(10, user_session_key.data, user_session_key.length);
418 :
419 2931 : if (response.length) {
420 24 : ofs = user_session_key.length;
421 24 : memcpy(&si->mac_key.data[ofs], response.data, response.length);
422 24 : DBG_DEBUG("response_data\n");
423 24 : dump_data(10, response.data, response.length);
424 : } else {
425 2907 : DBG_DEBUG("NULL response_data\n");
426 : }
427 :
428 2931 : dump_data_pw("smb1_signing_activate: mac key is:\n",
429 2931 : si->mac_key.data, si->mac_key.length);
430 :
431 : /* Initialise the sequence number */
432 2931 : si->seqnum = 2;
433 :
434 2931 : return true;
435 : }
436 :
437 674742 : bool smb1_signing_is_active(struct smb1_signing_state *si)
438 : {
439 674742 : return si->active;
440 : }
441 :
442 5753 : bool smb1_signing_is_desired(struct smb1_signing_state *si)
443 : {
444 5753 : return si->desired;
445 : }
446 :
447 26253 : bool smb1_signing_is_mandatory(struct smb1_signing_state *si)
448 : {
449 26253 : return si->mandatory;
450 : }
451 :
452 19958 : bool smb1_signing_set_negotiated(struct smb1_signing_state *si,
453 : bool allowed, bool mandatory)
454 : {
455 19958 : if (si->active) {
456 838 : return true;
457 : }
458 :
459 19120 : if (mandatory) {
460 3070 : allowed = true;
461 : }
462 :
463 19120 : if (!si->allowed && mandatory) {
464 0 : return false;
465 : }
466 :
467 19120 : if (si->mandatory && !allowed) {
468 0 : return false;
469 : }
470 :
471 19120 : if (si->mandatory) {
472 1168 : si->negotiated = true;
473 1168 : return true;
474 : }
475 :
476 17952 : if (mandatory) {
477 2191 : si->negotiated = true;
478 2191 : return true;
479 : }
480 :
481 15761 : if (!si->desired) {
482 15761 : si->negotiated = false;
483 15761 : return true;
484 : }
485 :
486 0 : if (si->desired && allowed) {
487 0 : si->negotiated = true;
488 0 : return true;
489 : }
490 :
491 0 : si->negotiated = false;
492 0 : return true;
493 : }
494 :
495 6808 : bool smb1_signing_is_negotiated(struct smb1_signing_state *si)
496 : {
497 6808 : return si->negotiated;
498 : }
499 :
500 11182 : NTSTATUS smb1_key_derivation(const uint8_t *KI,
501 : size_t KI_len,
502 : uint8_t KO[16])
503 : {
504 266 : int rc;
505 266 : static const uint8_t SSKeyHash[256] = {
506 : 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
507 : 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
508 : 0x72, 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x55,
509 : 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x07,
510 : 0x6e, 0x28, 0x2e, 0x69, 0x88, 0x10, 0xb3, 0xdb,
511 : 0x01, 0x55, 0x72, 0xfb, 0x74, 0x14, 0xfb, 0xc4,
512 : 0xc5, 0xaf, 0x3b, 0x41, 0x65, 0x32, 0x17, 0xba,
513 : 0xa3, 0x29, 0x08, 0xc1, 0xde, 0x16, 0x61, 0x7e,
514 : 0x66, 0x98, 0xa4, 0x0b, 0xfe, 0x06, 0x83, 0x53,
515 : 0x4d, 0x05, 0xdf, 0x6d, 0xa7, 0x51, 0x10, 0x73,
516 : 0xc5, 0x50, 0xdc, 0x5e, 0xf8, 0x21, 0x46, 0xaa,
517 : 0x96, 0x14, 0x33, 0xd7, 0x52, 0xeb, 0xaf, 0x1f,
518 : 0xbf, 0x36, 0x6c, 0xfc, 0xb7, 0x1d, 0x21, 0x19,
519 : 0x81, 0xd0, 0x6b, 0xfa, 0x77, 0xad, 0xbe, 0x18,
520 : 0x78, 0xcf, 0x10, 0xbd, 0xd8, 0x78, 0xf7, 0xd3,
521 : 0xc6, 0xdf, 0x43, 0x32, 0x19, 0xd3, 0x9b, 0xa8,
522 : 0x4d, 0x9e, 0xaa, 0x41, 0xaf, 0xcb, 0xc6, 0xb9,
523 : 0x34, 0xe7, 0x48, 0x25, 0xd4, 0x88, 0xc4, 0x51,
524 : 0x60, 0x38, 0xd9, 0x62, 0xe8, 0x8d, 0x5b, 0x83,
525 : 0x92, 0x7f, 0xb5, 0x0e, 0x1c, 0x2d, 0x06, 0x91,
526 : 0xc3, 0x75, 0xb3, 0xcc, 0xf8, 0xf7, 0x92, 0x91,
527 : 0x0b, 0x3d, 0xa1, 0x10, 0x5b, 0xd5, 0x0f, 0xa8,
528 : 0x3f, 0x5d, 0x13, 0x83, 0x0a, 0x6b, 0x72, 0x93,
529 : 0x14, 0x59, 0xd5, 0xab, 0xde, 0x26, 0x15, 0x6d,
530 : 0x60, 0x67, 0x71, 0x06, 0x6e, 0x3d, 0x0d, 0xa7,
531 : 0xcb, 0x70, 0xe9, 0x08, 0x5c, 0x99, 0xfa, 0x0a,
532 : 0x5f, 0x3d, 0x44, 0xa3, 0x8b, 0xc0, 0x8d, 0xda,
533 : 0xe2, 0x68, 0xd0, 0x0d, 0xcd, 0x7f, 0x3d, 0xf8,
534 : 0x73, 0x7e, 0x35, 0x7f, 0x07, 0x02, 0x0a, 0xb5,
535 : 0xe9, 0xb7, 0x87, 0xfb, 0xa1, 0xbf, 0xcb, 0x32,
536 : 0x31, 0x66, 0x09, 0x48, 0x88, 0xcc, 0x18, 0xa3,
537 : 0xb2, 0x1f, 0x1f, 0x1b, 0x90, 0x4e, 0xd7, 0xe1
538 : };
539 :
540 : /* The callers passing down KI_len of 16 so no need to limit to 64 */
541 11182 : rc = gnutls_hmac_fast(GNUTLS_MAC_MD5,
542 : KI,
543 : KI_len,
544 : SSKeyHash,
545 : sizeof(SSKeyHash),
546 : KO);
547 11182 : if (rc < 0) {
548 0 : return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED);
549 : }
550 :
551 11182 : return NT_STATUS_OK;
552 : }
|