1d768ef39d0b71f4d0229399197db72af7dbf335
[samba.git] / libcli / smb / smb_signing.c
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 localy allowed */
34         bool allowed;
35
36         /* is signing localy desired */
37         bool desired;
38
39         /* is signing localy 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 static void smb1_signing_reset_info(struct smb1_signing_state *si)
59 {
60         si->active = false;
61         si->seqnum = 0;
62
63         if (si->free_fn) {
64                 si->free_fn(si->mem_ctx, si->mac_key.data);
65         } else {
66                 talloc_free(si->mac_key.data);
67         }
68         si->mac_key.data = NULL;
69         si->mac_key.length = 0;
70 }
71
72 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         struct smb1_signing_state *si;
80
81         if (alloc_fn) {
82                 void *p = alloc_fn(mem_ctx, sizeof(struct smb1_signing_state));
83                 if (p == NULL) {
84                         return NULL;
85                 }
86                 memset(p, 0, sizeof(struct smb1_signing_state));
87                 si = (struct smb1_signing_state *)p;
88                 si->mem_ctx = mem_ctx;
89                 si->alloc_fn = alloc_fn;
90                 si->free_fn = free_fn;
91         } else {
92                 si = talloc_zero(mem_ctx, struct smb1_signing_state);
93                 if (si == NULL) {
94                         return NULL;
95                 }
96         }
97
98         if (mandatory) {
99                 desired = true;
100         }
101
102         if (desired) {
103                 allowed = true;
104         }
105
106         si->allowed = allowed;
107         si->desired = desired;
108         si->mandatory = mandatory;
109
110         return si;
111 }
112
113 struct smb1_signing_state *smb1_signing_init(TALLOC_CTX *mem_ctx,
114                                            bool allowed,
115                                            bool desired,
116                                            bool mandatory)
117 {
118         return smb1_signing_init_ex(mem_ctx, allowed, desired, mandatory,
119                                    NULL, NULL);
120 }
121
122 static bool smb1_signing_good(struct smb1_signing_state *si,
123                              bool good, uint32_t seq)
124 {
125         if (good) {
126                 if (!si->active) {
127                         si->active = true;
128                 }
129                 return true;
130         }
131
132         if (!si->mandatory && !si->active) {
133                 /* Non-mandatory signing - just turn off if this is the first bad packet.. */
134                 DBG_INFO("signing negotiated but not required and peer\n"
135                           "isn't sending correct signatures. Turning off.\n");
136                 smb1_signing_reset_info(si);
137                 return true;
138         }
139
140         /* Mandatory signing or bad packet after signing started - fail and disconnect. */
141         DBG_ERR("BAD SIG: seq %u\n", (unsigned int)seq);
142         return false;
143 }
144
145 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         const size_t offset_end_of_sig = (HDR_SS_FIELD + 8);
151         uint8_t sequence_buf[8];
152         gnutls_hash_hd_t hash_hnd = NULL;
153         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         DBG_DEBUG("sequence number %u\n", seq_number );
163
164         SIVAL(sequence_buf, 0, seq_number);
165         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         rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5);
174         if (rc < 0) {
175                 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
176         }
177         /* Initialise with the key. */
178         rc = gnutls_hash(hash_hnd, mac_key->data, mac_key->length);
179         if (rc < 0) {
180                 gnutls_hash_deinit(hash_hnd, NULL);
181                 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
182         }
183         /* Copy in the first bit of the SMB header. */
184         rc = gnutls_hash(hash_hnd, hdr, HDR_SS_FIELD);
185         if (rc < 0) {
186                 gnutls_hash_deinit(hash_hnd, NULL);
187                 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
188         }
189         /* Copy in the sequence number, instead of the signature. */
190         rc = gnutls_hash(hash_hnd, sequence_buf, sizeof(sequence_buf));
191         if (rc < 0) {
192                 gnutls_hash_deinit(hash_hnd, NULL);
193                 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         rc = gnutls_hash(hash_hnd, hdr + offset_end_of_sig, len - offset_end_of_sig);
197         if (rc < 0) {
198                 gnutls_hash_deinit(hash_hnd, NULL);
199                 return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
200         }
201
202         gnutls_hash_deinit(hash_hnd, calc_md5_mac);
203
204         return NT_STATUS_OK;
205 }
206
207 uint32_t smb1_signing_next_seqnum(struct smb1_signing_state *si, bool oneway)
208 {
209         uint32_t seqnum;
210
211         if (si->mac_key.length == 0) {
212                 return 0;
213         }
214
215         seqnum = si->seqnum;
216         if (oneway) {
217                 si->seqnum += 1;
218         } else {
219                 si->seqnum += 2;
220         }
221
222         return seqnum;
223 }
224
225 void smb1_signing_cancel_reply(struct smb1_signing_state *si, bool oneway)
226 {
227         if (si->mac_key.length == 0) {
228                 return;
229         }
230
231         if (oneway) {
232                 si->seqnum -= 1;
233         } else {
234                 si->seqnum -= 2;
235         }
236 }
237
238 NTSTATUS smb1_signing_sign_pdu(struct smb1_signing_state *si,
239                               uint8_t *outhdr, size_t len,
240                               uint32_t seqnum)
241 {
242         uint8_t calc_md5_mac[16];
243         uint8_t com;
244         uint8_t flags;
245
246         if (si->mac_key.length == 0) {
247                 if (!si->negotiated) {
248                         return NT_STATUS_OK;
249                 }
250         }
251
252         /* JRA Paranioa test - we should be able to get rid of this... */
253         if (len < (HDR_SS_FIELD + 8)) {
254                 DBG_WARNING("Logic error. "
255                          "Can't check signature on short packet! smb_len = %u\n",
256                          (unsigned)len);
257                 abort();
258         }
259
260         com = SVAL(outhdr, HDR_COM);
261         flags = SVAL(outhdr, HDR_FLG);
262
263         if (!(flags & FLAG_REPLY)) {
264                 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                 if (si->negotiated && si->desired) {
270                         flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
271                 }
272                 if (si->negotiated && si->mandatory) {
273                         flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
274                 }
275                 SSVAL(outhdr, HDR_FLG2, flags2);
276         }
277
278         if (si->mac_key.length == 0) {
279                 /* I wonder what BSRSPYL stands for - but this is what MS
280                    actually sends! */
281                 if (com == SMBsesssetupX) {
282                         memcpy(calc_md5_mac, "BSRSPYL ", 8);
283                 } else {
284                         memset(calc_md5_mac, 0, 8);
285                 }
286         } else {
287                 NTSTATUS status;
288
289                 status = smb1_signing_md5(&si->mac_key,
290                                          outhdr,
291                                          len,
292                                          seqnum,
293                                          calc_md5_mac);
294                 if (!NT_STATUS_IS_OK(status)) {
295                         return status;
296                 }
297         }
298
299         DBG_DEBUG("sent SMB signature of\n");
300         dump_data(10, calc_md5_mac, 8);
301
302         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         return NT_STATUS_OK;
308 }
309
310 bool smb1_signing_check_pdu(struct smb1_signing_state *si,
311                            const uint8_t *inhdr, size_t len,
312                            uint32_t seqnum)
313 {
314         bool good;
315         uint8_t calc_md5_mac[16];
316         const uint8_t *reply_sent_mac;
317         NTSTATUS status;
318
319         if (si->mac_key.length == 0) {
320                 return true;
321         }
322
323         if (len < (HDR_SS_FIELD + 8)) {
324                 DBG_WARNING("Can't check signature "
325                          "on short packet! smb_len = %u\n",
326                          (unsigned)len);
327                 return false;
328         }
329
330         status = smb1_signing_md5(&si->mac_key,
331                                  inhdr,
332                                  len,
333                                  seqnum,
334                                  calc_md5_mac);
335         if (!NT_STATUS_IS_OK(status)) {
336                 DBG_ERR("Failed to calculate signing mac: %s\n",
337                         nt_errstr(status));
338                 return false;
339         }
340
341         reply_sent_mac = &inhdr[HDR_SS_FIELD];
342         good = mem_equal_const_time(reply_sent_mac, calc_md5_mac, 8);
343
344         if (!good) {
345                 int i;
346                 const int sign_range = 5;
347
348                 DBG_INFO("BAD SIG: wanted SMB signature of\n");
349                 dump_data(5, calc_md5_mac, 8);
350
351                 DBG_INFO("BAD SIG: got SMB signature of\n");
352                 dump_data(5, reply_sent_mac, 8);
353
354                 for (i = -sign_range; i < sign_range; i++) {
355                         smb1_signing_md5(&si->mac_key, inhdr, len,
356                                         seqnum+i, calc_md5_mac);
357                         if (mem_equal_const_time(reply_sent_mac, calc_md5_mac, 8)) {
358                                 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                                 break;
363                         }
364                 }
365         } else {
366                 DBG_DEBUG("seq %u: got good SMB signature of\n",
367                            (unsigned int)seqnum);
368                 dump_data(10, reply_sent_mac, 8);
369         }
370
371         return smb1_signing_good(si, good, seqnum);
372 }
373
374 bool smb1_signing_activate(struct smb1_signing_state *si,
375                           const DATA_BLOB user_session_key,
376                           const DATA_BLOB response)
377 {
378         size_t len;
379         off_t ofs;
380
381         if (!user_session_key.length) {
382                 return false;
383         }
384
385         if (!si->negotiated) {
386                 return false;
387         }
388
389         if (si->active) {
390                 return false;
391         }
392
393         if (si->mac_key.length > 0) {
394                 return false;
395         }
396
397         smb1_signing_reset_info(si);
398
399         len = response.length + user_session_key.length;
400         if (si->alloc_fn) {
401                 si->mac_key.data = (uint8_t *)si->alloc_fn(si->mem_ctx, len);
402                 if (si->mac_key.data == NULL) {
403                         return false;
404                 }
405         } else {
406                 si->mac_key.data = (uint8_t *)talloc_size(si, len);
407                 if (si->mac_key.data == NULL) {
408                         return false;
409                 }
410         }
411         si->mac_key.length = len;
412
413         ofs = 0;
414         memcpy(&si->mac_key.data[ofs], user_session_key.data, user_session_key.length);
415
416         DBG_DEBUG("user_session_key\n");
417         dump_data(10, user_session_key.data, user_session_key.length);
418
419         if (response.length) {
420                 ofs = user_session_key.length;
421                 memcpy(&si->mac_key.data[ofs], response.data, response.length);
422                 DBG_DEBUG("response_data\n");
423                 dump_data(10, response.data, response.length);
424         } else {
425                 DBG_DEBUG("NULL response_data\n");
426         }
427
428         dump_data_pw("smb1_signing_activate: mac key is:\n",
429                      si->mac_key.data, si->mac_key.length);
430
431         /* Initialise the sequence number */
432         si->seqnum = 2;
433
434         return true;
435 }
436
437 bool smb1_signing_is_active(struct smb1_signing_state *si)
438 {
439         return si->active;
440 }
441
442 bool smb1_signing_is_desired(struct smb1_signing_state *si)
443 {
444         return si->desired;
445 }
446
447 bool smb1_signing_is_mandatory(struct smb1_signing_state *si)
448 {
449         return si->mandatory;
450 }
451
452 bool smb1_signing_set_negotiated(struct smb1_signing_state *si,
453                                 bool allowed, bool mandatory)
454 {
455         if (si->active) {
456                 return true;
457         }
458
459         if (mandatory) {
460                 allowed = true;
461         }
462
463         if (!si->allowed && mandatory) {
464                 return false;
465         }
466
467         if (si->mandatory && !allowed) {
468                 return false;
469         }
470
471         if (si->mandatory) {
472                 si->negotiated = true;
473                 return true;
474         }
475
476         if (mandatory) {
477                 si->negotiated = true;
478                 return true;
479         }
480
481         if (!si->desired) {
482                 si->negotiated = false;
483                 return true;
484         }
485
486         if (si->desired && allowed) {
487                 si->negotiated = true;
488                 return true;
489         }
490
491         si->negotiated = false;
492         return true;
493 }
494
495 bool smb1_signing_is_negotiated(struct smb1_signing_state *si)
496 {
497         return si->negotiated;
498 }
499
500 NTSTATUS smb1_key_derivation(const uint8_t *KI,
501                             size_t KI_len,
502                             uint8_t KO[16])
503 {
504         int rc;
505         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         rc = gnutls_hmac_fast(GNUTLS_MAC_MD5,
542                               KI,
543                               KI_len,
544                               SSKeyHash,
545                               sizeof(SSKeyHash),
546                               KO);
547         if (rc < 0) {
548                 return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED);
549         }
550
551         return NT_STATUS_OK;
552 }