0ffd1095b6b8a49423e0698ba285de1bbc7a5365
[bbaumbach/samba-autobuild/.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 "../lib/crypto/crypto.h"
24 #include "smb_common.h"
25 #include "smb_signing.h"
26
27 #include <gnutls/gnutls.h>
28 #include <gnutls/crypto.h>
29
30 /* Used by the SMB signing functions. */
31
32 struct smb_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 smb_signing_reset_info(struct smb_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 smb_signing_state *smb_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 smb_signing_state *si;
80
81         if (alloc_fn) {
82                 void *p = alloc_fn(mem_ctx, sizeof(struct smb_signing_state));
83                 if (p == NULL) {
84                         return NULL;
85                 }
86                 memset(p, 0, sizeof(struct smb_signing_state));
87                 si = (struct smb_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 smb_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 smb_signing_state *smb_signing_init(TALLOC_CTX *mem_ctx,
114                                            bool allowed,
115                                            bool desired,
116                                            bool mandatory)
117 {
118         return smb_signing_init_ex(mem_ctx, allowed, desired, mandatory,
119                                    NULL, NULL);
120 }
121
122 static bool smb_signing_good(struct smb_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                 DEBUG(5, ("smb_signing_good: signing negotiated but not required and peer\n"
135                           "isn't sending correct signatures. Turning off.\n"));
136                 smb_signing_reset_info(si);
137                 return true;
138         }
139
140         /* Mandatory signing or bad packet after signing started - fail and disconnect. */
141         DEBUG(0, ("smb_signing_good: BAD SIG: seq %u\n", (unsigned int)seq));
142         return false;
143 }
144
145 static void smb_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         DEBUG(10,("smb_signing_md5: 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;
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;
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;
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;
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;
200         }
201
202         gnutls_hash_deinit(hash_hnd, calc_md5_mac);
203 }
204
205 uint32_t smb_signing_next_seqnum(struct smb_signing_state *si, bool oneway)
206 {
207         uint32_t seqnum;
208
209         if (si->mac_key.length == 0) {
210                 return 0;
211         }
212
213         seqnum = si->seqnum;
214         if (oneway) {
215                 si->seqnum += 1;
216         } else {
217                 si->seqnum += 2;
218         }
219
220         return seqnum;
221 }
222
223 void smb_signing_cancel_reply(struct smb_signing_state *si, bool oneway)
224 {
225         if (si->mac_key.length == 0) {
226                 return;
227         }
228
229         if (oneway) {
230                 si->seqnum -= 1;
231         } else {
232                 si->seqnum -= 2;
233         }
234 }
235
236 void smb_signing_sign_pdu(struct smb_signing_state *si,
237                           uint8_t *outhdr, size_t len,
238                           uint32_t seqnum)
239 {
240         uint8_t calc_md5_mac[16];
241         uint8_t com;
242         uint8_t flags;
243
244         if (si->mac_key.length == 0) {
245                 if (!si->negotiated) {
246                         return;
247                 }
248         }
249
250         /* JRA Paranioa test - we should be able to get rid of this... */
251         if (len < (HDR_SS_FIELD + 8)) {
252                 DEBUG(1,("smb_signing_sign_pdu: Logic error. "
253                          "Can't check signature on short packet! smb_len = %u\n",
254                          (unsigned)len));
255                 abort();
256         }
257
258         com = SVAL(outhdr, HDR_COM);
259         flags = SVAL(outhdr, HDR_FLG);
260
261         if (!(flags & FLAG_REPLY)) {
262                 uint16_t flags2 = SVAL(outhdr, HDR_FLG2);
263                 /*
264                  * If this is a request, specify what is
265                  * supported or required by the client
266                  */
267                 if (si->negotiated && si->desired) {
268                         flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
269                 }
270                 if (si->negotiated && si->mandatory) {
271                         flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
272                 }
273                 SSVAL(outhdr, HDR_FLG2, flags2);
274         }
275
276         if (si->mac_key.length == 0) {
277                 /* I wonder what BSRSPYL stands for - but this is what MS
278                    actually sends! */
279                 if (com == SMBsesssetupX) {
280                         memcpy(calc_md5_mac, "BSRSPYL ", 8);
281                 } else {
282                         memset(calc_md5_mac, 0, 8);
283                 }
284         } else {
285                 smb_signing_md5(&si->mac_key, outhdr, len,
286                                 seqnum, calc_md5_mac);
287         }
288
289         DEBUG(10, ("smb_signing_sign_pdu: sent SMB signature of\n"));
290         dump_data(10, calc_md5_mac, 8);
291
292         memcpy(&outhdr[HDR_SS_FIELD], calc_md5_mac, 8);
293
294 /*      outhdr[HDR_SS_FIELD+2]=0;
295         Uncomment this to test if the remote server actually verifies signatures...*/
296 }
297
298 bool smb_signing_check_pdu(struct smb_signing_state *si,
299                            const uint8_t *inhdr, size_t len,
300                            uint32_t seqnum)
301 {
302         bool good;
303         uint8_t calc_md5_mac[16];
304         const uint8_t *reply_sent_mac;
305
306         if (si->mac_key.length == 0) {
307                 return true;
308         }
309
310         if (len < (HDR_SS_FIELD + 8)) {
311                 DEBUG(1,("smb_signing_check_pdu: Can't check signature "
312                          "on short packet! smb_len = %u\n",
313                          (unsigned)len));
314                 return false;
315         }
316
317         smb_signing_md5(&si->mac_key, inhdr, len,
318                         seqnum, calc_md5_mac);
319
320         reply_sent_mac = &inhdr[HDR_SS_FIELD];
321         good = (memcmp(reply_sent_mac, calc_md5_mac, 8) == 0);
322
323         if (!good) {
324                 int i;
325                 const int sign_range = 5;
326
327                 DEBUG(5, ("smb_signing_check_pdu: BAD SIG: wanted SMB signature of\n"));
328                 dump_data(5, calc_md5_mac, 8);
329
330                 DEBUG(5, ("smb_signing_check_pdu: BAD SIG: got SMB signature of\n"));
331                 dump_data(5, reply_sent_mac, 8);
332
333                 for (i = -sign_range; i < sign_range; i++) {
334                         smb_signing_md5(&si->mac_key, inhdr, len,
335                                         seqnum+i, calc_md5_mac);
336                         if (memcmp(reply_sent_mac, calc_md5_mac, 8) == 0) {
337                                 DEBUG(0,("smb_signing_check_pdu: "
338                                          "out of seq. seq num %u matches. "
339                                          "We were expecting seq %u\n",
340                                          (unsigned int)seqnum+i,
341                                          (unsigned int)seqnum));
342                                 break;
343                         }
344                 }
345         } else {
346                 DEBUG(10, ("smb_signing_check_pdu: seq %u: "
347                            "got good SMB signature of\n",
348                            (unsigned int)seqnum));
349                 dump_data(10, reply_sent_mac, 8);
350         }
351
352         return smb_signing_good(si, good, seqnum);
353 }
354
355 bool smb_signing_activate(struct smb_signing_state *si,
356                           const DATA_BLOB user_session_key,
357                           const DATA_BLOB response)
358 {
359         size_t len;
360         off_t ofs;
361
362         if (!user_session_key.length) {
363                 return false;
364         }
365
366         if (!si->negotiated) {
367                 return false;
368         }
369
370         if (si->active) {
371                 return false;
372         }
373
374         if (si->mac_key.length > 0) {
375                 return false;
376         }
377
378         smb_signing_reset_info(si);
379
380         len = response.length + user_session_key.length;
381         if (si->alloc_fn) {
382                 si->mac_key.data = (uint8_t *)si->alloc_fn(si->mem_ctx, len);
383                 if (si->mac_key.data == NULL) {
384                         return false;
385                 }
386         } else {
387                 si->mac_key.data = (uint8_t *)talloc_size(si, len);
388                 if (si->mac_key.data == NULL) {
389                         return false;
390                 }
391         }
392         si->mac_key.length = len;
393
394         ofs = 0;
395         memcpy(&si->mac_key.data[ofs], user_session_key.data, user_session_key.length);
396
397         DEBUG(10, ("smb_signing_activate: user_session_key\n"));
398         dump_data(10, user_session_key.data, user_session_key.length);
399
400         if (response.length) {
401                 ofs = user_session_key.length;
402                 memcpy(&si->mac_key.data[ofs], response.data, response.length);
403                 DEBUG(10, ("smb_signing_activate: response_data\n"));
404                 dump_data(10, response.data, response.length);
405         } else {
406                 DEBUG(10, ("smb_signing_activate: NULL response_data\n"));
407         }
408
409         dump_data_pw("smb_signing_activate: mac key is:\n",
410                      si->mac_key.data, si->mac_key.length);
411
412         /* Initialise the sequence number */
413         si->seqnum = 2;
414
415         return true;
416 }
417
418 bool smb_signing_is_active(struct smb_signing_state *si)
419 {
420         return si->active;
421 }
422
423 bool smb_signing_is_allowed(struct smb_signing_state *si)
424 {
425         return si->allowed;
426 }
427
428 bool smb_signing_is_desired(struct smb_signing_state *si)
429 {
430         return si->desired;
431 }
432
433 bool smb_signing_is_mandatory(struct smb_signing_state *si)
434 {
435         return si->mandatory;
436 }
437
438 bool smb_signing_set_negotiated(struct smb_signing_state *si,
439                                 bool allowed, bool mandatory)
440 {
441         if (si->active) {
442                 return true;
443         }
444
445         if (mandatory) {
446                 allowed = true;
447         }
448
449         if (!si->allowed && mandatory) {
450                 return false;
451         }
452
453         if (si->mandatory && !allowed) {
454                 return false;
455         }
456
457         if (si->mandatory) {
458                 si->negotiated = true;
459                 return true;
460         }
461
462         if (mandatory) {
463                 si->negotiated = true;
464                 return true;
465         }
466
467         if (!si->desired) {
468                 si->negotiated = false;
469                 return true;
470         }
471
472         if (si->desired && allowed) {
473                 si->negotiated = true;
474                 return true;
475         }
476
477         si->negotiated = false;
478         return true;
479 }
480
481 bool smb_signing_is_negotiated(struct smb_signing_state *si)
482 {
483         return si->negotiated;
484 }
485
486 void smb_key_derivation(const uint8_t *KI, size_t KI_len,
487                         uint8_t KO[16])
488 {
489         static const uint8_t SSKeyHash[256] = {
490                 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
491                 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
492                 0x72, 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x55,
493                 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x07,
494                 0x6e, 0x28, 0x2e, 0x69, 0x88, 0x10, 0xb3, 0xdb,
495                 0x01, 0x55, 0x72, 0xfb, 0x74, 0x14, 0xfb, 0xc4,
496                 0xc5, 0xaf, 0x3b, 0x41, 0x65, 0x32, 0x17, 0xba,
497                 0xa3, 0x29, 0x08, 0xc1, 0xde, 0x16, 0x61, 0x7e,
498                 0x66, 0x98, 0xa4, 0x0b, 0xfe, 0x06, 0x83, 0x53,
499                 0x4d, 0x05, 0xdf, 0x6d, 0xa7, 0x51, 0x10, 0x73,
500                 0xc5, 0x50, 0xdc, 0x5e, 0xf8, 0x21, 0x46, 0xaa,
501                 0x96, 0x14, 0x33, 0xd7, 0x52, 0xeb, 0xaf, 0x1f,
502                 0xbf, 0x36, 0x6c, 0xfc, 0xb7, 0x1d, 0x21, 0x19,
503                 0x81, 0xd0, 0x6b, 0xfa, 0x77, 0xad, 0xbe, 0x18,
504                 0x78, 0xcf, 0x10, 0xbd, 0xd8, 0x78, 0xf7, 0xd3,
505                 0xc6, 0xdf, 0x43, 0x32, 0x19, 0xd3, 0x9b, 0xa8,
506                 0x4d, 0x9e, 0xaa, 0x41, 0xaf, 0xcb, 0xc6, 0xb9,
507                 0x34, 0xe7, 0x48, 0x25, 0xd4, 0x88, 0xc4, 0x51,
508                 0x60, 0x38, 0xd9, 0x62, 0xe8, 0x8d, 0x5b, 0x83,
509                 0x92, 0x7f, 0xb5, 0x0e, 0x1c, 0x2d, 0x06, 0x91,
510                 0xc3, 0x75, 0xb3, 0xcc, 0xf8, 0xf7, 0x92, 0x91,
511                 0x0b, 0x3d, 0xa1, 0x10, 0x5b, 0xd5, 0x0f, 0xa8,
512                 0x3f, 0x5d, 0x13, 0x83, 0x0a, 0x6b, 0x72, 0x93,
513                 0x14, 0x59, 0xd5, 0xab, 0xde, 0x26, 0x15, 0x6d,
514                 0x60, 0x67, 0x71, 0x06, 0x6e, 0x3d, 0x0d, 0xa7,
515                 0xcb, 0x70, 0xe9, 0x08, 0x5c, 0x99, 0xfa, 0x0a,
516                 0x5f, 0x3d, 0x44, 0xa3, 0x8b, 0xc0, 0x8d, 0xda,
517                 0xe2, 0x68, 0xd0, 0x0d, 0xcd, 0x7f, 0x3d, 0xf8,
518                 0x73, 0x7e, 0x35, 0x7f, 0x07, 0x02, 0x0a, 0xb5,
519                 0xe9, 0xb7, 0x87, 0xfb, 0xa1, 0xbf, 0xcb, 0x32,
520                 0x31, 0x66, 0x09, 0x48, 0x88, 0xcc, 0x18, 0xa3,
521                 0xb2, 0x1f, 0x1f, 0x1b, 0x90, 0x4e, 0xd7, 0xe1
522         };
523         HMACMD5Context ctx;
524
525         hmac_md5_init_limK_to_64(KI, KI_len, &ctx);
526         hmac_md5_update(SSKeyHash, sizeof(SSKeyHash), &ctx);
527         hmac_md5_final(KO, &ctx);
528
529         ZERO_STRUCT(ctx);
530 }