1/*
2 * Copyright (c) 2000-2001, Boris Popov
3 * All rights reserved.
4 *
5 * Portions Copyright (C) 2001 - 2014 Apple Inc. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *    This product includes software developed by Boris Popov.
18 * 4. Neither the name of the author nor the names of any co-contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 */
35#include <sys/param.h>
36#include <sys/malloc.h>
37#include <sys/kernel.h>
38#include <sys/systm.h>
39#include <sys/conf.h>
40#include <sys/proc.h>
41#include <sys/fcntl.h>
42#include <sys/socket.h>
43#include <sys/sysctl.h>
44#include <libkern/crypto/md5.h>
45
46#include <sys/smb_apple.h>
47
48#include <netsmb/smb.h>
49#include <netsmb/smb_2.h>
50#include <netsmb/smb_conn.h>
51#include <netsmb/smb_subr.h>
52#include <netsmb/smb_rq.h>
53#include <netsmb/smb_dev.h>
54#include <netsmb/md4.h>
55#include <netsmb/smb_packets_2.h>
56
57#include <smbfs/smbfs_subr.h>
58#include <netsmb/smb_converter.h>
59
60#include <crypto/des.h>
61#include <corecrypto/cchmac.h>
62#include <corecrypto/ccsha2.h>
63#include <corecrypto/cccmac.h>
64#include <corecrypto/ccnistkdf.h>
65
66
67#define SMBSIGLEN (8)
68#define SMBSIGOFF (14)
69#define SMBPASTSIG (SMBSIGOFF + SMBSIGLEN)
70#define SMBFUDGESIGN 4
71
72/* SMB 2/3 Signing defines */
73#define SMB2SIGLEN (16)
74#define SMB2SIGOFF (48)
75
76#ifdef SMB_DEBUG
77/* Need to build with SMB_DEBUG if you what to turn this on */
78#define SSNDEBUG 0
79#endif // SMB_DEBUG
80
81static int smb3_verify(struct smb_rq *rqp, struct mdchain *mdp,
82                       uint32_t nextCmdOffset, uint8_t *signature);
83static void smb3_sign(struct smb_rq *rqp);
84
85static u_char N8[] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
86
87
88static void
89smb_E(const u_char *key, u_char *data, u_char *dest)
90{
91	des_key_schedule *ksp;
92	u_char kk[8];
93
94	kk[0] = key[0] & 0xfe;
95	kk[1] = key[0] << 7 | (key[1] >> 1 & 0xfe);
96	kk[2] = key[1] << 6 | (key[2] >> 2 & 0xfe);
97	kk[3] = key[2] << 5 | (key[3] >> 3 & 0xfe);
98	kk[4] = key[3] << 4 | (key[4] >> 4 & 0xfe);
99	kk[5] = key[4] << 3 | (key[5] >> 5 & 0xfe);
100	kk[6] = key[5] << 2 | (key[6] >> 6 & 0xfe);
101	kk[7] = key[6] << 1;
102    SMB_MALLOC(ksp, des_key_schedule *, sizeof(des_key_schedule), M_SMBTEMP, M_WAITOK);
103	des_set_key((des_cblock*)kk, *ksp);
104	des_ecb_encrypt((des_cblock*)data, (des_cblock*)dest, *ksp, 1);
105
106    if (ksp) {
107        SMB_FREE(ksp, M_SMBTEMP);
108    }
109}
110
111/*
112 * mbuf_get_nbytes
113 *
114 * Utility routine to fetch 'nBytes' bytes from an mbuf chain
115 * into buffer 'buf' at offset 'offset'.  Returns number of
116 * bytes copied into buffer, always 'nBytes' unless mbuf chain
117 * was exhausted.
118 */
119static size_t
120mbuf_get_nbytes(size_t nBytes, unsigned char *buf, size_t offset, mbuf_t *mb, size_t *mb_len, size_t *mb_off)
121{
122    size_t remain, cnt, need, off;
123
124    remain = nBytes;
125    off = offset;
126    cnt = 0;
127
128    if (!nBytes) {
129        SMBERROR("Called with nBytes == 0\n");
130        return 0;
131    }
132
133    if (*mb == NULL) {
134     SMBERROR("Called with NULL mb\n");
135        return 0;
136    }
137
138    while (remain) {
139        if (!(*mb_len)) {
140            /* Advance to next mbuf */
141            *mb = mbuf_next(*mb);
142            if (*mb == NULL) {
143                break;
144            }
145            *mb_len = mbuf_len(*mb);
146            *mb_off = 0;
147        }
148
149        need = remain;
150        if (need >= *mb_len) {
151            need = *mb_len;
152        }
153
154        memcpy(buf + off, (uint8_t *)(mbuf_data(*mb)) + *mb_off, need);
155
156        remain -= need;
157        cnt += need;
158        off += need;
159        *mb_off += need;
160        *mb_len -= need;
161    }
162
163    return (cnt);
164}
165
166/*
167 * Compute an LM response given the ASCII password and a challenge.
168 */
169int smb_lmresponse(const u_char *apwd, u_char *C8, u_char *RN)
170{
171	u_char *p, *P14, *S21;
172
173    SMB_MALLOC(p, u_char *, 14+21, M_SMBTEMP, M_WAITOK);
174	bzero(p, 14 + 21);
175	P14 = p;
176	S21 = p + 14;
177	bcopy(apwd, P14, MIN(14, strnlen((char *)apwd, SMB_MAXPASSWORDLEN + 1)));
178	/*
179	 * S21 = concat(Ex(P14, N8), zeros(5));
180	 */
181	smb_E(P14, N8, S21);
182	smb_E(P14 + 7, N8, S21 + 8);
183
184	smb_E(S21, C8, RN);
185	smb_E(S21 + 7, C8, RN + 8);
186	smb_E(S21 + 14, C8, RN + 16);
187
188    if (p) {
189        SMB_FREE(p, M_SMBTEMP);
190    }
191
192	return 24; /* return the len */
193}
194
195/*
196 * smb_ntlmhash
197 *
198 * Compute the NTLM hash of the given password, which is used in the calculation of
199 * the NTLM Response. Used for both the NTLMv2 and LMv2 hashes.
200 *
201 */
202static void smb_ntlmhash(const uint8_t *passwd, uint8_t *ntlmHash, size_t ntlmHash_len)
203{
204	uint16_t *unicode_passwd = NULL;
205	MD4_CTX md4;
206	size_t len;
207
208	bzero(ntlmHash, ntlmHash_len);
209	len = strnlen((char *)passwd, SMB_MAXPASSWORDLEN + 1);
210
211    if (len == 0) {
212        /* Empty password, but we still need to allocate a buffer to */
213        /* encrypt two NULL bytes so we can compute the NTLM hash correctly. */
214        len = 1;
215    }
216
217    SMB_MALLOC(unicode_passwd, uint16_t *, len * sizeof(uint16_t), M_SMBTEMP, M_WAITOK);
218	if (unicode_passwd == NULL)	/* Should never happen, but better safe than sorry */
219		return;
220
221	len = smb_strtouni(unicode_passwd, (char *)passwd, len, UTF_PRECOMPOSED);
222	bzero(&md4, sizeof(md4));
223	MD4Init(&md4);
224	MD4Update(&md4, (uint8_t *)unicode_passwd, (unsigned int)len);
225	MD4Final(ntlmHash, &md4);
226
227    if (unicode_passwd) {
228        SMB_FREE(unicode_passwd, M_SMBTEMP);
229    }
230
231#ifdef SSNDEBUG
232	smb_hexdump(__FUNCTION__, "ntlmHash = ", ntlmHash, 16);
233#endif // SSNDEBUG
234}
235
236/*
237 * Compute an NTLM response given the Unicode password (as an ASCII string,
238 * not a Unicode string!) and a challenge.
239 */
240void smb_ntlmresponse(const u_char *apwd, u_char *C8, u_char *RN)
241{
242	u_char S21[SMB_NTLM_LEN];
243
244	smb_ntlmhash(apwd, S21, sizeof(S21));
245
246	smb_E(S21, C8, RN);
247	smb_E(S21 + 7, C8, RN + 8);
248	smb_E(S21 + 14, C8, RN + 16);
249}
250
251#define SSNDEBUG 0
252#if SSNDEBUG
253void
254prblob(u_char *b, size_t len)
255{
256    while (len--)
257        SMBDEBUG("%02x", *b++);
258    SMBDEBUG("\n");
259}
260#endif
261
262static void
263HMACT64(const u_char *key, size_t key_len, const u_char *data,
264        size_t data_len, u_char *digest)
265{
266    MD5_CTX context;
267    u_char k_ipad[64];	/* inner padding - key XORd with ipad */
268    u_char k_opad[64];	/* outer padding - key XORd with opad */
269    int i;
270
271    /* if key is longer than 64 bytes use only the first 64 bytes */
272    if (key_len > 64)
273        key_len = 64;
274
275    /*
276     * The HMAC-MD5 (and HMACT64) transform looks like:
277     *
278     * MD5(K XOR opad, MD5(K XOR ipad, data))
279     *
280     * where K is an n byte key
281     * ipad is the byte 0x36 repeated 64 times
282     * opad is the byte 0x5c repeated 64 times
283     * and data is the data being protected.
284     */
285
286    /* start out by storing key in pads */
287    bzero(k_ipad, sizeof k_ipad);
288    bzero(k_opad, sizeof k_opad);
289    bcopy(key, k_ipad, key_len);
290    bcopy(key, k_opad, key_len);
291
292    /* XOR key with ipad and opad values */
293    for (i = 0; i < 64; i++) {
294        k_ipad[i] ^= 0x36;
295        k_opad[i] ^= 0x5c;
296    }
297
298    /*
299     * perform inner MD5
300     */
301    MD5Init(&context);			/* init context for 1st pass */
302    MD5Update(&context, k_ipad, 64);	/* start with inner pad */
303    MD5Update(&context, data, (unsigned int) data_len);	/* then data of datagram */
304    MD5Final(digest, &context);		/* finish up 1st pass */
305
306    /*
307     * perform outer MD5
308     */
309    MD5Init(&context);			/* init context for 2nd pass */
310    MD5Update(&context, k_opad, 64);	/* start with outer pad */
311    MD5Update(&context, digest, 16);	/* then results of 1st hash */
312    MD5Final(digest, &context);		/* finish up 2nd pass */
313}
314
315/*
316 * Compute an NTLMv2 hash given the Unicode password (as an ASCII string,
317 * not a Unicode string!), the user name, the destination workgroup/domain
318 * name, and a challenge.
319 */
320int
321smb_ntlmv2hash(const u_char *apwd, const u_char *user,
322               const u_char *destination, u_char *v2hash)
323{
324    u_char v1hash[SMB_NTLM_LEN];
325    u_int16_t *uniuser = NULL, *unidest = NULL;
326    size_t uniuserlen, unidestlen;
327    size_t len;
328    size_t datalen;
329    u_char *data;
330
331    smb_ntlmhash(apwd, v1hash, sizeof(v1hash));
332
333#if SSNDEBUG
334    SMBDEBUG("v1hash = ");
335    prblob(v1hash, 21);
336#endif
337
338    /*
339     * v2hash = HMACT64(v1hash, 16, concat(upcase(user), upcase(dest))
340     * We assume that user and destination are supplied to us as
341     * upper-case UTF-8.
342    */
343    len = strlen((char *)user);
344    SMB_MALLOC(uniuser, u_int16_t *, len * sizeof(u_int16_t), M_SMBTEMP, M_WAITOK);
345    uniuserlen = smb_strtouni(uniuser, (char *)user, len,
346                              UTF_PRECOMPOSED|UTF_NO_NULL_TERM);
347
348    len = strlen((char *)destination);
349    SMB_MALLOC(unidest, u_int16_t *, len * sizeof(u_int16_t), M_SMBTEMP, M_WAITOK);
350    unidestlen = smb_strtouni(unidest, (char *)destination, len,
351                              UTF_PRECOMPOSED|UTF_NO_NULL_TERM);
352
353    datalen = uniuserlen + unidestlen;
354    SMB_MALLOC(data, u_char *, datalen, M_SMBTEMP, M_WAITOK);
355    bcopy(uniuser, data, uniuserlen);
356    bcopy(unidest, data + uniuserlen, unidestlen);
357
358    if (uniuser) {
359        SMB_FREE(uniuser, M_SMBTEMP);
360    }
361
362    if (unidest) {
363        SMB_FREE(unidest, M_SMBTEMP);
364    }
365
366    HMACT64(v1hash, 16, data, datalen, v2hash);
367
368    if (data) {
369        SMB_FREE(data, M_SMBTEMP);
370    }
371
372#if SSNDEBUG
373    SMBDEBUG("v2hash = ");
374    prblob(v2hash, 16);
375#endif
376    return (0);
377}
378
379/*
380 * Compute an NTLMv2 response given the Unicode password (as an ASCII string,
381 * not a Unicode string!), the user name, the destination workgroup/domain
382 * name, a challenge, and the blob.
383 */
384int
385smb_ntlmv2response(u_char *v2hash, u_char *C8, const u_char *blob,
386                   size_t bloblen, u_char **RN, size_t *RNlen)
387{
388    size_t datalen;
389    u_char *data;
390    size_t v2resplen;
391    u_char *v2resp;
392
393    datalen = 8 + bloblen;
394    SMB_MALLOC(data, u_char *, datalen, M_SMBTEMP, M_WAITOK);
395    bcopy(C8, data, 8);
396    bcopy(blob, data + 8, bloblen);
397
398    v2resplen = 16 + bloblen;
399    SMB_MALLOC(v2resp, u_char *, v2resplen, M_SMBTEMP, M_WAITOK);
400    HMACT64(v2hash, 16, data, datalen, v2resp);
401
402    if (data) {
403        SMB_FREE(data, M_SMBTEMP);
404    }
405
406    bcopy(blob, v2resp + 16, bloblen);
407    *RN = v2resp;
408    *RNlen = v2resplen;
409
410#if SSNDEBUG
411    SMBDEBUG("v2resp = ");
412    prblob(v2resp, v2resplen);
413#endif
414    return (0);
415}
416
417/*
418 * Initialize the signing data, free the key and
419 * set everything else to zero.
420 */
421void smb_reset_sig(struct smb_vc *vcp)
422{
423    if (vcp->vc_mackey != NULL) {
424        SMB_FREE(vcp->vc_mackey, M_SMBTEMP);
425    }
426
427    vcp->vc_mackey = NULL;
428    vcp->vc_mackeylen = 0;
429    vcp->vc_smb3_signing_key_len = 0;
430    vcp->vc_seqno = 0;
431}
432
433/*
434 * Sign request with MAC.
435 */
436int
437smb_rq_sign(struct smb_rq *rqp)
438{
439	struct smb_vc *vcp = rqp->sr_vc;
440	struct mbchain *mbp;
441	mbuf_t mb;
442	MD5_CTX md5;
443	u_char digest[16];
444
445	KASSERT(vcp->vc_hflags2 & SMB_FLAGS2_SECURITY_SIGNATURE,
446	    ("signatures not enabled"));
447
448	/*
449	 * Durring the authentication process we send a magic fake signing string,
450	 * because signing really doesn't start until the authentication process is
451	 * complete. The sequence number counter starts once we send our authentication
452	 * message and must be reset if authentication fails.
453	 */
454	if ((vcp->vc_mackey == NULL) || (rqp->sr_cmd == SMB_COM_SESSION_SETUP_ANDX)) {
455		/* Should never be null, but just to be safe */
456		if (rqp->sr_rqsig)
457			bcopy("BSRSPLY ", rqp->sr_rqsig, 8);
458		return (0);
459	}
460	/*
461	 * This is a bit of a kludge. If the request is non-TRANSACTION,
462	 * or it is the first request of a transaction, give it the next
463	 * sequence number, and expect the reply to have the sequence number
464	 * following that one. Otherwise, it is a secondary request in
465	 * a transaction, and it gets the same sequence numbers as the
466	 * primary request.
467	 */
468	if (rqp->sr_t2 == NULL ||
469	    (rqp->sr_t2->t2_flags & SMBT2_SECONDARY) == 0) {
470		rqp->sr_seqno = vcp->vc_seqno++;
471		rqp->sr_rseqno = vcp->vc_seqno++;
472	} else {
473		/*
474		 * Sequence numbers are already in the struct because
475		 * smb_t2_request_int() uses the same one for all the
476		 * requests in the transaction.
477		 * (At least we hope so.)
478		 */
479		KASSERT(rqp->sr_t2 == NULL ||
480		    (rqp->sr_t2->t2_flags & SMBT2_SECONDARY) == 0 ||
481		    rqp->sr_t2->t2_rq == rqp,
482		    ("sec t2 rq not using same smb_rq"));
483	}
484
485	/* Initialize sec. signature field to sequence number + zeros. */
486	if (rqp->sr_rqsig) {
487		*(uint32_t *)rqp->sr_rqsig = htolel(rqp->sr_seqno);
488		*(uint32_t *)(rqp->sr_rqsig + 4) = 0;
489	}
490
491	/*
492	 * Compute HMAC-MD5 of packet data, keyed by MAC key.
493	 * Store the first 8 bytes in the sec. signature field.
494	 */
495	smb_rq_getrequest(rqp, &mbp);
496	MD5Init(&md5);
497	MD5Update(&md5, vcp->vc_mackey, vcp->vc_mackeylen);
498	for (mb = mbp->mb_top; mb != NULL; mb = mbuf_next(mb))
499		MD5Update(&md5, mbuf_data(mb), (unsigned int)mbuf_len(mb));
500	MD5Final(digest, &md5);
501	if (rqp->sr_rqsig)
502		bcopy(digest, rqp->sr_rqsig, 8);
503
504	return (0);
505}
506
507static int
508smb_verify(struct smb_rq *rqp, uint32_t seqno)
509{
510	struct smb_vc *vcp = rqp->sr_vc;
511	struct mdchain *mdp;
512	mbuf_t mb;
513	u_char sigbuf[SMBSIGLEN];
514	MD5_CTX md5;
515	u_char digest[16];
516
517	/*
518	 * Compute HMAC-MD5 of packet data, keyed by MAC key.
519	 * We play games to pretend the security signature field
520	 * contains their sequence number, to avoid modifying
521	 * the packet itself.
522	 */
523	smb_rq_getreply(rqp, &mdp);
524	mb = mdp->md_top;
525	KASSERT(mbuf_len(mb) >= SMB_HDRLEN, ("forgot to mbuf_pullup"));
526	MD5Init(&md5);
527	MD5Update(&md5, vcp->vc_mackey, vcp->vc_mackeylen);
528	MD5Update(&md5, mbuf_data(mb), SMBSIGOFF);
529	*(uint32_t *)sigbuf = htolel(seqno);
530	*(uint32_t *)(sigbuf + 4) = 0;
531	MD5Update(&md5, sigbuf, SMBSIGLEN);
532	MD5Update(&md5, (uint8_t *)mbuf_data(mb) + SMBPASTSIG,
533			  (unsigned int)(mbuf_len(mb) - SMBPASTSIG));
534	for (mb = mbuf_next(mb); mb != NULL; mb = mbuf_next(mb))
535		if (mbuf_len(mb))
536			MD5Update(&md5, mbuf_data(mb), (unsigned int)mbuf_len(mb));
537	MD5Final(digest, &md5);
538	/*
539	 * Finally, verify the signature.
540	 */
541	return (bcmp((uint8_t *)mbuf_data(mdp->md_top) + SMBSIGOFF, digest, SMBSIGLEN));
542}
543
544/*
545 * Verify reply signature.
546 */
547int
548smb_rq_verify(struct smb_rq *rqp)
549{
550	struct smb_vc *vcp = rqp->sr_vc;
551	int32_t fudge;
552
553	if (!(vcp->vc_hflags2 & SMB_FLAGS2_SECURITY_SIGNATURE)) {
554		SMBWARNING("signatures not enabled!\n");
555		return (0);
556	}
557
558	/*
559	 * Durring the authentication process we send a dummy signature, because
560	 * signing really doesn't start until the authentication process is
561	 * complete. The last authentication message return by the server can be
562	 * signed, but only if the authentication succeed. If an error is return
563	 * then the signing process will fail and if we tested for signing the wrong
564	 * error would be return. So durring the authentication process we no longer
565	 * verify the signature. From my testing it looks like Windows and Samba
566	 * clients do the same thing.
567	 */
568	if ((vcp->vc_mackey == NULL) || (rqp->sr_cmd == SMB_COM_SESSION_SETUP_ANDX))
569		return (0);
570
571	/* Its an anonymous logins, signing is not supported */
572	if ((vcp->vc_flags & SMBV_ANONYMOUS_ACCESS) == SMBV_ANONYMOUS_ACCESS)
573		return (0);
574
575	if (smb_verify(rqp, rqp->sr_rseqno) == 0)
576		return (0);
577
578	/*
579	 * Now for diag purposes we check whether the client/server idea
580	 * of the sequence # has gotten a bit out of sync. This only gets
581	 * excute if debugging has been turned on.
582	 */
583	if (smbfs_loglevel) {
584		for (fudge = -SMBFUDGESIGN; fudge <= SMBFUDGESIGN; fudge++)
585			if (fudge == 0)
586				continue;
587			else if (smb_verify(rqp, rqp->sr_rseqno + fudge) == 0)
588				break;
589
590		if (fudge <= SMBFUDGESIGN)
591			SMBERROR("sr_rseqno=%d, but %d would have worked\n",
592						rqp->sr_rseqno, rqp->sr_rseqno + fudge);
593		else
594			SMBERROR("sr_rseqno=%d\n", rqp->sr_rseqno);
595	}
596
597	return (EAUTH);
598}
599
600/*
601 * SMB 2/3 Sign a single request with HMAC-SHA256
602 */
603static void smb2_sign(struct smb_rq *rqp)
604{
605    struct smb_vc *vcp = rqp->sr_vc;
606    struct mbchain *mbp;
607    mbuf_t mb;
608    const struct ccdigest_info *di = ccsha256_di();
609    u_char *mac;
610
611    if (rqp->sr_rqsig == NULL) {
612        SMBDEBUG("sr_rqsig was never allocated.\n");
613        return;
614    }
615
616    if (di == NULL) {
617        SMBERROR("ccsha256_di returned NULL digest_info\n");
618        return;
619    }
620
621    /* make sure ccdigest_info size is reasonable (sha256 output len is 32 bytes) */
622    if (di->output_size > 64) {
623        SMBERROR("Unreasonable output size %lu\n", di->output_size);
624        return;
625    }
626
627    SMB_MALLOC(mac, u_char *, di->output_size, M_SMBTEMP, M_WAITOK);
628    if (mac == NULL) {
629        SMBERROR("Out of memory\n");
630        return;
631    }
632
633    bzero(mac, di->output_size);
634
635    /* Initialize 16-byte security signature field to all zeros. */
636    bzero(rqp->sr_rqsig, SMB2SIGLEN);
637
638    /* Set flag to indicate this PDU is signed */
639    *rqp->sr_flagsp |= htolel(SMB2_FLAGS_SIGNED);
640
641    smb_rq_getrequest(rqp, &mbp);
642    cchmac_di_decl(di, hc);
643    cchmac_init(di, hc, vcp->vc_mackeylen, vcp->vc_mackey);
644
645    for (mb = mbp->mb_top; mb != NULL; mb = mbuf_next(mb))
646        cchmac_update(di, hc, mbuf_len(mb), mbuf_data(mb));
647    cchmac_final(di, hc, mac);
648
649    // Copy first 16 bytes of the HMAC hash into the signature field
650    bcopy(mac, rqp->sr_rqsig, SMB2SIGLEN);
651
652    if (mac) {
653        SMB_FREE(mac, M_SMBTEMP);
654    }
655}
656
657/*
658 * SMB 2/3 Sign request or compound chain with HMAC-SHA256
659 */
660int
661smb2_rq_sign(struct smb_rq *rqp)
662{
663	struct smb_vc *vcp;
664    struct smb_rq *this_rqp;
665    uint32_t      do_smb3_sign = 0;
666
667    if (rqp == NULL) {
668        SMBDEBUG("Called with NULL rqp\n");
669        return (EINVAL);
670    }
671
672    vcp = rqp->sr_vc;
673
674    if (vcp == NULL) {
675        SMBERROR("vcp is NULL\n");
676        return  (EINVAL);
677    }
678
679    /* Is signing required for the command? */
680    if ((rqp->sr_command == SMB2_SESSION_SETUP) ||
681        (rqp->sr_command == SMB2_OPLOCK_BREAK) ||
682         (rqp->sr_command == SMB2_NEGOTIATE)) {
683        return (0);
684    }
685
686    /*
687     * If we are supposed to sign, then fail if we do not have a
688     * session key.
689     */
690    if (vcp->vc_mackey == NULL) {
691        SMBERROR("No session key for signing.\n");
692        return (EINVAL);
693    }
694
695    /* Check for SMB 3 signing */
696    if (vcp->vc_flags & (SMBV_SMB30 | SMBV_SMB302)) {
697        do_smb3_sign = 1;
698    }
699
700    this_rqp = rqp;
701    while (this_rqp != NULL) {
702        if (do_smb3_sign) {
703            smb3_sign(this_rqp);
704        } else {
705            smb2_sign(this_rqp);
706        }
707        this_rqp = this_rqp->sr_next_rqp;
708    }
709
710    return (0);
711}
712
713/*
714 * SMB 2/3 Verify a reply with HMAC-SHA256
715 */
716static int smb2_verify(struct smb_rq *rqp, struct mdchain *mdp, uint32_t nextCmdOffset, uint8_t *signature)
717{
718    struct smb_vc *vcp = rqp->sr_vc;
719    mbuf_t mb, mb_temp;
720    size_t mb_off, remaining, mb_len, sign_len, mb_total_len;
721    u_char zero_buf[SMB2SIGLEN];
722    int result;
723    const struct ccdigest_info *di = ccsha256_di();
724    u_char *mac;
725
726    if (vcp == NULL) {
727        SMBERROR("vcp is NULL\n");
728        return  (EINVAL);
729    }
730
731    if (di == NULL) {
732        SMBERROR("NULL digest from sha256_di\n");
733        return (EINVAL);
734    }
735
736    /* make sure ccdigest_info size is reasonable (sha256 output len is 32 bytes) */
737    if (di->output_size > 64) {
738        SMBERROR("Unreasonable output size %lu\n", di->output_size);
739        return (EINVAL);
740    }
741
742    SMB_MALLOC(mac, u_char *, di->output_size, M_SMBTEMP, M_WAITOK);
743    if (mac == NULL) {
744        SMBERROR("Out of memory\n");
745        return (ENOMEM);
746    }
747
748    mb = mdp->md_cur;
749    mb_len = (size_t)mbuf_data(mb) + mbuf_len(mb) - (size_t)mdp->md_pos;
750    mb_total_len = mbuf_len(mb);
751    mb_off = mbuf_len(mb) - mb_len;
752
753    /* sanity checks */
754    if (mb_len < SMB2_HDRLEN) {
755        SMBDEBUG("mbuf not pulled up for SMB 2/3 header, mbuf_len: %lu\n", mbuf_len(mb));
756        if (mac) {
757            SMB_FREE(mac, M_SMBTEMP);
758        }
759        return (EBADRPC);
760    }
761    if (mb_off > mb_total_len) {
762        SMBDEBUG("mb_off: %lu past end of mbuf, mbuf_len: %lu\n", mb_off, mb_total_len);
763        if (mac) {
764            SMB_FREE(mac, M_SMBTEMP);
765        }
766        return (EBADRPC);
767    }
768
769    remaining = nextCmdOffset;
770    if (!remaining) {
771        /*
772         * We don't know the length of the reply because it's
773         * not a compound reply, or the end of a compound reply.
774         * So calculate total length of this reply.
775         */
776        remaining = mb_len; /* length in first mbuf */
777        mb_temp = mbuf_next(mb);
778        while (mb_temp) {
779            remaining += mbuf_len(mb_temp);
780            mb_temp = mbuf_next(mb_temp);
781        }
782    }
783
784    /* sanity check */
785    if (remaining < SMB2_HDRLEN) {
786        /* should never happen, but we have to be very careful */
787        SMBDEBUG("reply length: %lu too short\n", remaining);
788        if (mac) {
789            SMB_FREE(mac, M_SMBTEMP);
790        }
791        return (EBADRPC);
792    }
793
794    bzero(zero_buf, SMB2SIGLEN);
795    bzero(mac, di->output_size);
796    cchmac_di_decl(di, hc);
797    cchmac_init(di, hc, vcp->vc_mackeylen, vcp->vc_mackey);
798
799    /* sanity check */
800    if (mb_len < SMB2SIGOFF) {
801        /* mb_len would go negative when decremented below */
802        SMBDEBUG("mb_len exhausted: mb_len: %lu SMB2SIGOFF: %u\n", mb_len, (uint32_t)SMB2SIGOFF);
803        if (mac) {
804            SMB_FREE(mac, M_SMBTEMP);
805        }
806        return (EBADRPC);
807    }
808
809    /* Sign the first 48 bytes of the reply (up to the signature field) */
810    cchmac_update(di, hc, SMB2SIGOFF, (uint8_t *)mbuf_data(mb) + mb_off);
811    mb_off += SMB2SIGOFF;
812    mb_len -= SMB2SIGOFF;
813    remaining -= SMB2SIGOFF;
814
815    /* sanity check */
816    if (mb_off > mb_total_len) {
817        // mb_offset would go past the end of current mbuf, when incremented below */
818        SMBDEBUG("mb_off past end, mb_off: %lu mbub_len: %lu\n", mb_off, mb_total_len);
819        if (mac) {
820            SMB_FREE(mac, M_SMBTEMP);
821        }
822        return (EBADRPC);
823    }
824    /* sanity check */
825    if (mb_len < SMB2SIGLEN) {
826        /* mb_len would go negative when decremented below */
827        SMBDEBUG("mb_len exhausted: mb_len: %lu SMB2SIGLEN: %u\n", mb_len, (uint32_t)SMB2SIGLEN);
828        if (mac) {
829            SMB_FREE(mac, M_SMBTEMP);
830        }
831        return (EBADRPC);
832    }
833
834    // Sign 16 zeros
835    cchmac_update(di, hc, SMB2SIGLEN, zero_buf);
836    mb_off += SMB2SIGLEN;
837    mb_len -= SMB2SIGLEN;
838    remaining -= SMB2SIGLEN;
839
840    /* Sign remainder of this reply */
841    while (remaining) {
842        if (!mb_len) {
843            mb = mbuf_next(mb);
844            if (!mb) {
845                SMBDEBUG("mbuf_next didn't return an mbuf\n");
846                if (mac) {
847                    SMB_FREE(mac, M_SMBTEMP);
848                }
849                return EBADRPC;
850            }
851            mb_len = mbuf_len(mb);
852            mb_off = 0;
853        }
854
855        /* Calculate length to sign for this pass */
856        sign_len = remaining;
857        if (sign_len > mb_len) {
858            sign_len = mb_len;
859        }
860
861        /* Sign it */
862        cchmac_update(di, hc, sign_len, (uint8_t *)mbuf_data(mb) + mb_off);
863
864        mb_off += sign_len;
865        mb_len -= sign_len;
866        remaining -= sign_len;
867    }
868
869    cchmac_final(di, hc, mac);
870
871	/*
872	 * Finally, verify the signature.
873	 */
874    result = bcmp(signature, mac, SMB2SIGLEN);
875    if (mac) {
876        SMB_FREE(mac, M_SMBTEMP);
877    }
878	return (result);
879}
880
881/*
882 * SMB 2/3 Verify reply signature with HMAC-SHA256
883 */
884int
885smb2_rq_verify(struct smb_rq *rqp, struct mdchain *mdp, uint8_t *signature)
886{
887    struct smb_vc *vcp;
888    uint32_t nextCmdOffset;
889    int err;
890
891    if (rqp == NULL) {
892        SMBDEBUG("Called with NULL rqp\n");
893        return (EINVAL);
894    }
895
896    vcp = rqp->sr_vc;
897
898    if (vcp == NULL) {
899        SMBERROR("NULL vcp\n");
900        return  (0);
901    }
902    nextCmdOffset = rqp->sr_rspnextcmd;
903
904    if (!(vcp->vc_hflags2 & SMB_FLAGS2_SECURITY_SIGNATURE) &&
905        !(rqp->sr_flags & SMBR_SIGNED)) {
906		SMBWARNING("signatures not enabled!\n");
907		return (0);
908	}
909
910    if ((vcp->vc_mackey == NULL) ||
911        (rqp->sr_command == SMB2_OPLOCK_BREAK) ||
912        ((rqp->sr_command == SMB2_SESSION_SETUP) && !(rqp->sr_rspflags & SMB2_FLAGS_SIGNED))) {
913        /*
914         * Don't verify signature if we don't have a session key from gssd yet.
915         * Don't verify signature if a SessionSetup reply that hasn't
916         * been signed yet (server only signs the final SessionSetup reply).
917         */
918		return (0);
919    }
920
921    /* Its an anonymous login, signing is not supported */
922	if ((vcp->vc_flags & SMBV_ANONYMOUS_ACCESS) == SMBV_ANONYMOUS_ACCESS) {
923		return (0);
924    }
925
926    if (vcp->vc_flags & (SMBV_SMB30 | SMBV_SMB302)) {
927        err = smb3_verify(rqp, mdp, nextCmdOffset, signature);
928    } else {
929        err = smb2_verify(rqp, mdp, nextCmdOffset, signature);
930    }
931
932    if (err) {
933        SMBDEBUG("Could not verify signature for sr_command %x, msgid: %llu\n", rqp->sr_command, rqp->sr_messageid);
934        err = EAUTH;
935    }
936
937    return (err);
938}
939
940/*
941 * SMB 3 Routines
942 */
943
944
945/*
946 * SMB 3 Verify a reply with AES-CMAC-128
947 */
948static int
949smb3_verify(struct smb_rq *rqp, struct mdchain *mdp,
950            uint32_t nextCmdOffset, uint8_t *signature)
951{
952    struct smb_vc *vcp = rqp->sr_vc;
953    mbuf_t mb, mb_temp;
954    size_t mb_off, remaining, mb_len, mb_total_len;
955    u_char block[CMAC_BLOCKSIZE];
956    size_t n, i, nBlocks, nPartial;
957    const struct ccmode_cbc *ccmode = ccaes_cbc_encrypt_mode();
958    int result;
959    u_char *mac;
960
961    if (vcp == NULL) {
962        SMBERROR("vcp is NULL\n");
963        return  (EINVAL);
964    }
965
966    if (vcp->vc_smb3_signing_key_len < SMB3_KEY_LEN) {
967        SMBERROR("SMB3 signing key len too small: %u\n", vcp->vc_smb3_signing_key_len);
968        return (EAUTH);
969    }
970
971    /* Init the cipher */
972    cccmac_mode_decl(ccmode, cmac);
973    cccmac_init(ccmode, cmac, vcp->vc_smb3_signing_key);
974
975    SMB_MALLOC(mac, u_char *, CMAC_BLOCKSIZE, M_SMBTEMP, M_WAITOK);
976    if (mac == NULL) {
977        SMBERROR("Out of memory\n");
978        return (ENOMEM);
979    }
980
981    mb = mdp->md_cur;
982    mb_len = (size_t)mbuf_data(mb) + mbuf_len(mb) - (size_t)mdp->md_pos;
983    mb_total_len = mbuf_len(mb);
984    mb_off = mbuf_len(mb) - mb_len;
985
986    /* sanity checks */
987    if (mb_len < SMB2_HDRLEN) {
988        SMBDEBUG("mbuf not pulled up for SMB 3 header, mbuf_len: %lu\n", mbuf_len(mb));
989        if (mac) {
990            SMB_FREE(mac, M_SMBTEMP);
991        }
992        return (EBADRPC);
993    }
994    if (mb_off > mb_total_len) {
995        SMBDEBUG("mb_off: %lu past end of mbuf, mbuf_len: %lu\n", mb_off, mb_total_len);
996        if (mac) {
997            SMB_FREE(mac, M_SMBTEMP);
998        }
999        return (EBADRPC);
1000    }
1001
1002    remaining = nextCmdOffset;
1003    if (!remaining) {
1004        /*
1005         * We don't know the length of the reply because it's
1006         * not a compound reply, or the end of a compound reply.
1007         * So calculate total length of this reply.
1008         */
1009        remaining = mb_len; /* length in first mbuf */
1010        mb_temp = mbuf_next(mb);
1011        while (mb_temp) {
1012            remaining += mbuf_len(mb_temp);
1013            mb_temp = mbuf_next(mb_temp);
1014        }
1015    }
1016
1017    /* sanity check */
1018    if (remaining < SMB2_HDRLEN) {
1019        /* should never happen, but we have to be very careful */
1020        SMBDEBUG("reply length: %lu too short\n", remaining);
1021        if (mac) {
1022            SMB_FREE(mac, M_SMBTEMP);
1023        }
1024        return (EBADRPC);
1025    }
1026
1027    /* sanity check */
1028    if (mb_len < SMB2SIGOFF) {
1029        /* mb_len would go negative when decremented below */
1030        SMBDEBUG("mb_len exhausted: mb_len: %lu SMB2SIGOFF: %u\n", mb_len, (uint32_t)SMB2SIGOFF);
1031        if (mac) {
1032            SMB_FREE(mac, M_SMBTEMP);
1033        }
1034        return (EBADRPC);
1035    }
1036
1037    /* Sign the first 48 bytes (3 CMAC blocks) of the reply (up to the signature field) */
1038    cccmac_block_update(ccmode, cmac, 3, (uint8_t *)mbuf_data(mb) + mb_off);
1039    mb_off += SMB2SIGOFF;
1040    mb_len -= SMB2SIGOFF;
1041    remaining -= SMB2SIGOFF;
1042
1043    /* sanity check */
1044    if (mb_off > mb_total_len) {
1045        // mb_offset would go past the end of current mbuf, when incremented below */
1046        SMBDEBUG("mb_off past end, mb_off: %lu mbub_len: %lu\n", mb_off, mb_total_len);
1047        if (mac) {
1048            SMB_FREE(mac, M_SMBTEMP);
1049        }
1050        return (EBADRPC);
1051    }
1052    /* sanity check */
1053    if (mb_len < SMB2SIGLEN) {
1054        /* mb_len would go negative when decremented below */
1055        SMBDEBUG("mb_len exhausted: mb_len: %lu SMB2SIGLEN: %u\n", mb_len, (uint32_t)SMB2SIGLEN);
1056        if (mac) {
1057            SMB_FREE(mac, M_SMBTEMP);
1058        }
1059        return (EBADRPC);
1060    }
1061
1062    /*
1063     * The AES-CMAC-128 corecrypto SPI is a bit inconvenient,
1064     * and differs from the SPIs we use for SMB1 and SMB2:
1065     *
1066     * We have to pass 16-byte blocks on each ccmac_update() call.
1067     * We have to pass *some* data in the cccmac_final() call.
1068     *
1069     * These two requirements complicates things a bit on
1070     * our side :(
1071     */
1072
1073    if (remaining == SMB2SIGLEN) {
1074        /* Finalize now, signing 16 zeros */
1075        memset(block, 0, SMB2SIGLEN);
1076        cccmac_final(ccmode, cmac, SMB2SIGLEN, block, mac);
1077        goto final;
1078    }
1079
1080    /* Sign 16 zeros */
1081    memset(block, 0, SMB2SIGLEN);
1082    cccmac_block_update(ccmode, cmac, 1, block);
1083    mb_off += SMB2SIGLEN;
1084    mb_len -= SMB2SIGLEN;
1085    remaining -= SMB2SIGLEN;
1086
1087    /* Sign remaining blocks */
1088    nBlocks = remaining / CMAC_BLOCKSIZE;
1089    nPartial = remaining % CMAC_BLOCKSIZE;
1090
1091    if (!nPartial) {
1092        /* Have to save *some* data for cccmac_final() */
1093        if (!nBlocks) {
1094            /* Shouldn't ever see this */
1095            SMBDEBUG("short msg, remaining: %lu\n", remaining);
1096            if (mac) {
1097                SMB_FREE(mac, M_SMBTEMP);
1098            }
1099            return (EBADRPC);
1100        }
1101
1102        nBlocks--;
1103        nPartial = CMAC_BLOCKSIZE;
1104    }
1105
1106    for (i = 0; i < nBlocks; i++) {
1107        n = mbuf_get_nbytes(CMAC_BLOCKSIZE, block, 0, &mb, &mb_len, &mb_off);
1108        if (n != CMAC_BLOCKSIZE) {
1109            SMBDEBUG("mbuf chain exhausted at block %lu, exp: 16, got: %lu\n", i, n);
1110            if (mac) {
1111                SMB_FREE(mac, M_SMBTEMP);
1112            }
1113            return (EBADRPC);
1114        }
1115
1116        /* Sign a block */
1117        cccmac_block_update(ccmode, cmac, 1, block);
1118    }
1119
1120    /* Sign remainder (nPartial) */
1121    n = mbuf_get_nbytes(nPartial, block, 0, &mb, &mb_len, &mb_off);
1122    if (n != nPartial) {
1123        SMBDEBUG("mbuf chain exhausted, nPartial: %lu, got: %lu\n", nPartial, n);
1124        if (mac) {
1125            SMB_FREE(mac, M_SMBTEMP);
1126        }
1127        return (EBADRPC);
1128    }
1129
1130    cccmac_final(ccmode, cmac, nPartial, block, mac);
1131
1132final:
1133	/*
1134	 * Finally, verify the signature.
1135	 */
1136    result = bcmp(signature, mac, SMB2SIGLEN);
1137
1138    if (result) {
1139        SMBDEBUG("SMB3 signature mismatch:\n");
1140
1141        SMBDEBUG("SigCalc: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
1142                 mac[0], mac[1], mac[2], mac[3],
1143                 mac[4], mac[5], mac[6], mac[7],
1144                 mac[8], mac[9], mac[10], mac[11],
1145                 mac[12], mac[13], mac[14], mac[15]);
1146
1147        SMBDEBUG("SigExpected: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
1148                 signature[0], signature[1], signature[2],signature[3],
1149                 signature[4], signature[5], signature[6], signature[7],
1150                 signature[8], signature[9], signature[10], signature[11],
1151                 signature[12], signature[13], signature[14], signature[15]);
1152    }
1153
1154    if (mac) {
1155        SMB_FREE(mac, M_SMBTEMP);
1156    }
1157
1158	return (result);
1159}
1160
1161/*
1162 * SMB 3 Sign a single request with AES-CMAC-128
1163 */
1164static void
1165smb3_sign(struct smb_rq *rqp)
1166{
1167    struct smb_vc *vcp = rqp->sr_vc;
1168    struct mbchain *mbp;
1169    mbuf_t mb;
1170    size_t mb_off, remaining, mb_len;
1171    size_t nBlocks, nPartial, i, n;
1172    u_char block[CMAC_BLOCKSIZE];
1173    u_char *mac;
1174    const struct ccmode_cbc *ccmode = ccaes_cbc_encrypt_mode();
1175
1176    if (rqp->sr_rqsig == NULL) {
1177        SMBDEBUG("sr_rqsig was never allocated.\n");
1178        return;
1179    }
1180
1181    if (vcp->vc_smb3_signing_key_len < SMB3_KEY_LEN) {
1182        SMBERROR("smb3 keylen %u\n", vcp->vc_smb3_signing_key_len);
1183        return;
1184    }
1185
1186    /* Init the cipher */
1187    cccmac_mode_decl(ccmode, cmac);
1188    cccmac_init(ccmode, cmac, vcp->vc_smb3_signing_key);
1189
1190    SMB_MALLOC(mac, u_char *, CMAC_BLOCKSIZE, M_SMBTEMP, M_WAITOK);
1191    if (mac == NULL) {
1192        SMBERROR("Out of memory\n");
1193        return;
1194    }
1195
1196    /* Initialize 16-byte security signature field to all zeros. */
1197    bzero(rqp->sr_rqsig, SMB2SIGLEN);
1198
1199    /* Set flag to indicate this PDU is signed */
1200    *rqp->sr_flagsp |= htolel(SMB2_FLAGS_SIGNED);
1201
1202    smb_rq_getrequest(rqp, &mbp);
1203
1204    /* First determine the total length  to sign */
1205    remaining = 0;
1206    for (mb = mbp->mb_top; mb != NULL; mb = mbuf_next(mb)) {
1207        remaining += mbuf_len(mb);
1208    }
1209
1210    nBlocks = remaining / CMAC_BLOCKSIZE;
1211    nPartial = remaining % CMAC_BLOCKSIZE;
1212
1213    if (!nPartial) {
1214        /* Have to save *some* data for cccmac_final() */
1215        if (!nBlocks) {
1216            /* Shouldn't ever see this */
1217            SMBDEBUG("short msg, remaining: %lu\n", remaining);
1218            goto out;
1219        }
1220
1221        nBlocks--;
1222        nPartial = CMAC_BLOCKSIZE;
1223    }
1224
1225    mb = mbp->mb_top;
1226    mb_len = mbuf_len(mb);
1227    mb_off = 0;
1228
1229    for (i = 0; i < nBlocks; i++) {
1230        n = mbuf_get_nbytes(CMAC_BLOCKSIZE, block, 0, &mb, &mb_len, &mb_off);
1231        if (n != CMAC_BLOCKSIZE) {
1232            SMBDEBUG("mbuf chain exhausted at block %lu, exp: 16, got: %lu\n", i, n);
1233            goto out;
1234        }
1235
1236        /* Sign a block */
1237        cccmac_block_update(ccmode, cmac, 1, block);
1238    }
1239
1240    /* Sign remainder (nPartial) */
1241    n = mbuf_get_nbytes(nPartial, block, 0, &mb, &mb_len, &mb_off);
1242    if (n != nPartial) {
1243        SMBDEBUG("mbuf chain exhausted, nPartial: %lu, got: %lu\n", nPartial, n);
1244        goto out;
1245    }
1246
1247    cccmac_final(ccmode, cmac, nPartial, block, mac);
1248
1249    // Copy first 16 bytes of the HMAC hash into the signature field
1250    bcopy(mac, rqp->sr_rqsig, SMB2SIGLEN);
1251
1252out:
1253    if (mac) {
1254        SMB_FREE(mac, M_SMBTEMP);
1255    }
1256}
1257
1258/*
1259 * Encrypts an SMB msg or msg chain given in 'mb'.
1260 * Note: On any error the mbuf chain is freed.
1261 */
1262int smb3_rq_encrypt(struct smb_rq *rqp, mbuf_t *mb)
1263{
1264    mbuf_t                  mb_hdr, mb_tmp;
1265    struct smb_vc           *vcp = rqp->sr_vc;
1266    size_t                  len;
1267    unsigned char           nonce[16];
1268    unsigned char           dig[CCAES_BLOCK_SIZE];
1269    uint64_t                i64;
1270    uint32_t                msglen, i32;
1271    uint16_t                i16;
1272    int                     error;
1273    unsigned char           *msgp;
1274    const struct ccmode_ccm *ccmode = ccaes_ccm_encrypt_mode();
1275
1276    mb_hdr = NULL;
1277
1278    if (!vcp->vc_smb3_encrypt_key_len) {
1279        /* Cannot encrypt without a key */
1280        SMBDEBUG("smb3 encr, no key\n");
1281        return EINVAL;
1282    }
1283
1284    /* Declare/Init cypher context */
1285    ccccm_ctx_decl(ccmode->size, ctx);
1286    ccccm_nonce_decl(ccmode->nonce_size, nonce_ctx);
1287
1288    /* Need an mbuf for the Transform header */
1289    error = mbuf_gethdr(MBUF_WAITOK, MBUF_TYPE_DATA, &mb_hdr);
1290    if (error) {
1291        SMBERROR("No mbuf for transform hdr, error: %d\n", error);
1292        error = ENOBUFS;
1293        goto out;
1294    }
1295
1296    /* Build the Transform header */
1297    msgp = mbuf_data(mb_hdr);
1298    memset(msgp, 0, SMB3_AES_TF_HDR_LEN);
1299
1300    /* Set protocol field (0xFD 'S' 'M' 'B') */
1301    memcpy(msgp + SMB3_AES_TF_PROTO_OFF, SMB3_AES_TF_PROTO_STR,
1302           SMB3_AES_TF_PROTO_LEN);
1303
1304    /* Update session nonce */
1305    SMBC_ST_LOCK(vcp);
1306    vcp->vc_smb3_nonce_low++;
1307    if (!vcp->vc_smb3_nonce_low) {
1308        vcp->vc_smb3_nonce_low++;
1309        vcp->vc_smb3_nonce_high++;
1310    }
1311    SMBC_ST_UNLOCK(vcp);
1312
1313    /* Setup nonce field */
1314    memset(nonce, 0, 16);
1315    memcpy(nonce, &vcp->vc_smb3_nonce_high, 8);
1316    memcpy(&nonce[8], &vcp->vc_smb3_nonce_low, 8);
1317
1318    // Zero last 5 bytes per spec
1319    memset(&nonce[11], 0, 5);
1320
1321    memcpy(msgp + SMB3_AES_TF_NONCE_OFF, nonce, SMB3_AES_TF_NONCE_LEN);
1322
1323    // Set length of original message
1324    len = mbuf_pkthdr_len(*mb);
1325
1326    if (len > 0xffffffff) {
1327        /* The transform header field "original_message_size" holds the
1328         * total length of the unencrypted msg(s) going out, and the field
1329         * is a uint32_t (only 4 bytes).  So we can only encrypt a 4 GB
1330         * message (chained or not chained).
1331         */
1332        SMBERROR("mb msglen too big for transform: %lu\n", len);
1333        error = EAUTH;
1334        goto out;
1335    }
1336
1337    // Set message length (okay to cast, we already checked above */
1338    msglen = (uint32_t)len;
1339    i32 = htolel(msglen);
1340    memcpy(msgp + SMB3_AES_TF_MSGLEN_OFF, &i32,
1341           SMB3_AES_TF_MSGLEN_LEN);
1342
1343    /* Set Encryption Algorithm */
1344    i16 = htoles(SMB2_ENCRYPTION_AES128_CCM);
1345    memcpy(msgp + SMB3_AES_TF_ENCR_ALG_OFF, &i16,
1346           SMB3_AES_TF_ENCR_ALG_LEN);
1347
1348    /* Session ID */
1349    i64 = htoleq(rqp->sr_rqsessionid);
1350    memcpy(msgp + SMB3_AES_TF_SESSID_OFF, &i64,
1351           SMB3_AES_TF_SESSID_LEN);
1352
1353    // Set data length of mb_hdr
1354    mbuf_setlen(mb_hdr, SMB3_AES_TF_HDR_LEN);
1355
1356    /* Init the cipher */
1357    ccccm_init(ccmode, ctx, vcp->vc_smb3_encrypt_key_len, vcp->vc_smb3_encrypt_key);
1358
1359    ccccm_set_iv(ccmode, ctx, nonce_ctx, SMB3_CCM_NONCE_LEN, msgp + SMB3_AES_TF_NONCE_OFF,
1360                           SMB3_AES_TF_SIG_LEN, SMB3_AES_AUTHDATA_LEN, msglen);
1361
1362    // Sign authenticated data
1363    ccccm_cbcmac(ccmode, ctx, nonce_ctx, SMB3_AES_AUTHDATA_LEN, msgp + SMB3_AES_AUTHDATA_OFF);
1364
1365    // Encrypt msg data in place
1366    for (mb_tmp = *mb; mb_tmp != NULL; mb_tmp = mbuf_next(mb_tmp)) {
1367        ccccm_update(ccmode, ctx, nonce_ctx, mbuf_len(mb_tmp), mbuf_data(mb_tmp), mbuf_data(mb_tmp));
1368    }
1369
1370    // Set transform header signature
1371    ccccm_finalize(ccmode, ctx, nonce_ctx, dig);
1372    memcpy(msgp + SMB3_AES_TF_SIG_OFF, dig, CCAES_BLOCK_SIZE);
1373
1374    // Ideally, should turn off these flags from original mb:
1375    // (*mb)->m_flags &= ~(M_PKTHDR | M_EOR);
1376
1377    // Return the new mbuf chain
1378    mb_hdr = mbuf_concatenate(mb_hdr, *mb);
1379    m_fixhdr(mb_hdr);
1380    *mb = mb_hdr;
1381
1382out:
1383    if (error) {
1384        mbuf_freem(*mb);
1385
1386        if (mb_hdr != NULL) {
1387            mbuf_freem(mb_hdr);
1388        }
1389    }
1390
1391    ccccm_ctx_clear(ccmode->size, ctx);
1392    ccccm_nonce_clear(ccmode->size, nonce_ctx);
1393
1394    return (error);
1395}
1396
1397/*
1398 * Decrypts an SMB msg or msg chain given in 'mb'.
1399 * Note: On any error the mbuf chain is freed.
1400 */
1401int smb3_msg_decrypt(struct smb_vc *vcp, mbuf_t *mb)
1402{
1403    SMB3_AES_TF_HEADER      *tf_hdr;
1404    mbuf_t                  mb_hdr, mb_tmp, mbuf_payload;
1405    uint16_t                i16;
1406    uint64_t                i64;
1407    uint32_t                msglen;
1408    int                     error;
1409    unsigned char           *msgp;
1410    unsigned char          sig[SMB3_AES_TF_SIG_LEN];
1411    const struct ccmode_ccm *ccmode = ccaes_ccm_decrypt_mode();
1412
1413    mbuf_payload = NULL;
1414    mb_hdr = NULL;
1415    error = 0;
1416
1417    /* Declare/Init cypher context */
1418    ccccm_ctx_decl(ccmode->size, ctx);
1419    ccccm_nonce_decl(ccmode->nonce_size, nonce_ctx);
1420
1421    if (!vcp->vc_smb3_decrypt_key_len) {
1422        /* Cannot decrypt without a key */
1423        SMBDEBUG("smb3 decr, no key\n");
1424        error = EAUTH;
1425        goto out;
1426    }
1427
1428    mb_hdr = *mb;
1429
1430    // Split TF header from payload
1431    if (mbuf_split(mb_hdr, SMB3_AES_TF_HDR_LEN, MBUF_WAITOK, &mbuf_payload)) {
1432        /* Split failed, avoid freeing mb twice during cleanup */
1433        mb_hdr = NULL;
1434        error = EBADRPC;
1435        goto out;
1436    }
1437
1438    // Pullup Transform header (52 bytes)
1439    if (mbuf_pullup(&mb_hdr, SMB3_AES_TF_HDR_LEN)) {
1440        error = EBADRPC;
1441        goto out;
1442    }
1443
1444    msgp = mbuf_data(mb_hdr);
1445    tf_hdr = (SMB3_AES_TF_HEADER *)msgp;
1446
1447    // Verify the protocol signature
1448    if (bcmp(msgp, SMB3_AES_TF_PROTO_STR, SMB3_AES_TF_PROTO_LEN) != 0) {
1449        SMBDEBUG("TF HDR protocol incorrect: %02x %02x %02x %02x\n",
1450                 msgp[0], msgp[1], msgp[2], msgp[3]);
1451        error = EBADRPC;
1452        goto out;
1453    }
1454
1455    // Verify the encryption algorithm
1456    i16 = letohs(tf_hdr->encrypt_algorithm);
1457    if (i16 != SMB2_ENCRYPTION_AES128_CCM) {
1458        SMBDEBUG("Unsupported ENCR alg: %u\n", (uint32_t)i16);
1459        error = EAUTH;
1460        goto out;
1461    }
1462
1463    // Verify Session Id
1464    i64 = letohq(tf_hdr->sess_id);
1465    if (i64 != vcp->vc_session_id) {
1466        SMBDEBUG("TF sess_id mismatch: expect: %llu got: %llu\n",
1467                 vcp->vc_session_id, i64);
1468        error = EAUTH;
1469        goto out;
1470    }
1471
1472    // Need msglen from tf header for cypher init
1473    msglen = letohl(tf_hdr->orig_msg_size);
1474
1475    // Init the cipher
1476    ccccm_init(ccmode, ctx, vcp->vc_smb3_decrypt_key_len, vcp->vc_smb3_decrypt_key);
1477
1478    ccccm_set_iv(ccmode, ctx, nonce_ctx, SMB3_CCM_NONCE_LEN, msgp + SMB3_AES_TF_NONCE_OFF,
1479                 SMB3_AES_TF_SIG_LEN, SMB3_AES_AUTHDATA_LEN, msglen);
1480
1481    /* Calculate Signature of Authenticated Data + Payload */
1482    ccccm_cbcmac(ccmode, ctx, nonce_ctx, SMB3_AES_AUTHDATA_LEN, msgp + SMB3_AES_AUTHDATA_OFF);
1483
1484    // Decrypt msg data in place
1485    for (mb_tmp = mbuf_payload; mb_tmp != NULL; mb_tmp = mbuf_next(mb_tmp)) {
1486        ccccm_update(ccmode, ctx, nonce_ctx, mbuf_len(mb_tmp), mbuf_data(mb_tmp), mbuf_data(mb_tmp));
1487    }
1488
1489    /* Final signature -> sig */
1490    ccccm_finalize(ccmode, ctx, nonce_ctx, sig);
1491
1492    // Check signature
1493    if (bcmp(sig, tf_hdr->signature, SMB3_AES_TF_SIG_LEN)) {
1494        SMBDEBUG("Transform signature mismatch\n");
1495
1496        SMBDEBUG("TF Sig: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
1497                 tf_hdr->signature[0], tf_hdr->signature[1], tf_hdr->signature[2], tf_hdr->signature[3],
1498                 tf_hdr->signature[4], tf_hdr->signature[5], tf_hdr->signature[6], tf_hdr->signature[7],
1499                 tf_hdr->signature[8], tf_hdr->signature[9], tf_hdr->signature[10], tf_hdr->signature[11],
1500                 tf_hdr->signature[12], tf_hdr->signature[13], tf_hdr->signature[14], tf_hdr->signature[15]);
1501
1502        SMBDEBUG("CalcSig: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
1503                 sig[0], sig[1], sig[2],sig[3], sig[4], sig[5], sig[6], sig[7],
1504                 sig[8], sig[9], sig[10],sig[11], sig[12], sig[13], sig[14], sig[15]);
1505        error = EAUTH;
1506        goto out;
1507    }
1508
1509    /* And we're done, return plain text */
1510    m_fixhdr(mbuf_payload);
1511    *mb = mbuf_payload;
1512
1513out:
1514    if (error) {
1515        if (mbuf_payload) {
1516            mbuf_freem(mbuf_payload);
1517        }
1518    }
1519
1520    if (mb_hdr != NULL) {
1521        mbuf_freem(mb_hdr);
1522    }
1523
1524    ccccm_ctx_clear(ccmode->size, ctx);
1525    ccccm_nonce_clear(ccmode->size, nonce_ctx);
1526
1527    return (error);
1528}
1529
1530static void smb3_init_nonce(struct smb_vc *vcp)
1531{
1532    MD5_CTX md5;
1533    struct timespec tnow;
1534    uint64_t nsec;
1535    unsigned char digest[16];
1536
1537    /*
1538     * We will whip up a nonce by generating a simple
1539     * HMAC-MD5 digest of system time and the session_id,
1540     * keyed by the session key. Nothing fancy.
1541     */
1542
1543    MD5Init(&md5);
1544
1545    nanouptime(&tnow);
1546    nsec = tnow.tv_sec;
1547
1548    MD5Update(&md5, vcp->vc_mackey, vcp->vc_mackeylen);
1549    MD5Update(&md5, (uint8_t *)&nsec, sizeof(uint64_t));
1550    MD5Update(&md5, &vcp->vc_session_id, sizeof(uint64_t));
1551    MD5Final(digest, &md5);
1552
1553    memcpy(&vcp->vc_smb3_nonce_high, digest, 8);
1554    memcpy(&vcp->vc_smb3_nonce_low, &digest[8], 8);
1555}
1556
1557static int
1558smb_kdf_hmac_sha256(uint8_t *input_key, uint32_t input_keylen,
1559                    uint8_t *label, uint32_t label_len,
1560                    uint8_t *context, uint32_t context_len,
1561                    uint8_t *output_key, uint32_t output_key_len)
1562{
1563    int err;
1564    const struct ccdigest_info *di = ccsha256_di();
1565
1566    err = ccnistkdf_ctr_hmac(di,
1567                             input_keylen, input_key,
1568                             label_len, label,
1569                             context_len, context,
1570                             output_key_len, output_key);
1571    return (err);
1572}
1573
1574/*
1575 * int smb3_derive_keys(struct smb_vc *vcp)
1576 *
1577 * Derives all necessary keys for SMB 3
1578 * signing and encryption, which are all
1579 * stored in the smb_vc struct.
1580 *
1581 * Keys are derived using KDF in Counter Mode
1582 * from as specified by sp800-108.
1583 *
1584 * Keys generated:
1585 *
1586 * vc_smb3_signing_key
1587 * vc_smb3_signing_key_len
1588 *
1589 */
1590int smb3_derive_keys(struct smb_vc *vcp)
1591{
1592    uint8_t label[16];
1593    uint8_t context[16];
1594    int     err;
1595
1596    vcp->vc_smb3_signing_key_len = 0;
1597    vcp->vc_smb3_encrypt_key_len = 0;
1598    vcp->vc_smb3_decrypt_key_len = 0;
1599
1600    // Setup session nonce
1601    smb3_init_nonce(vcp);
1602
1603    // Check Session.SessionKey
1604    if (vcp->vc_mackey == NULL) {
1605        SMBDEBUG("Keys not generated, missing session key\n");
1606        err = EINVAL;
1607        goto out;
1608    }
1609    if (vcp->vc_mackeylen < SMB3_KEY_LEN) {
1610        SMBDEBUG("Warning: Session.SessionKey too small, len: %u\n",
1611                 vcp->vc_mackeylen);
1612    }
1613
1614    // Derive Session.SigningKey (vc_smb3_signing_key)
1615    memset(label, 0, 16);
1616    memset(context, 0, 16);
1617
1618    strncpy((char *)label, "SMB2AESCMAC", 11);
1619    strncpy((char *)context, "SmbSign", 7);
1620
1621    err = smb_kdf_hmac_sha256(vcp->vc_mackey, vcp->vc_mackeylen,
1622                              label, 12,  // includes NULL Terminator
1623                              context, 8, // includes NULL Terminator
1624                              vcp->vc_smb3_signing_key,
1625                              SMB3_KEY_LEN);
1626    if (!err) {
1627        vcp->vc_smb3_signing_key_len = SMB3_KEY_LEN;
1628    } else {
1629        SMBDEBUG("Could not generate smb3 signing key, error: %d\n", err);
1630    }
1631
1632    // Derive Session.EncryptionKey (vc_smb3_encrypt_key)
1633    memset(label, 0, 16);
1634    memset(context, 0, 16);
1635
1636    memcpy(label, "SMB2AESCCM", 10);
1637    memcpy(context, "ServerIn ", 9);
1638
1639    err = smb_kdf_hmac_sha256(vcp->vc_mackey, vcp->vc_mackeylen,
1640                              label, 11,  // includes NULL Terminator
1641                              context, 10, // includes NULL Terminator
1642                              vcp->vc_smb3_encrypt_key,
1643                              SMB3_KEY_LEN);
1644    if (!err) {
1645        vcp->vc_smb3_encrypt_key_len = SMB3_KEY_LEN;
1646    } else {
1647        SMBDEBUG("Could not generate smb3 encrypt key, error: %d\n", err);
1648    }
1649
1650    // Derive Session.DecryptionKey (vc_smb3_decrypt_key)
1651    memset(label, 0, 16);
1652    memset(context, 0, 16);
1653
1654    memcpy(label, "SMB2AESCCM", 10);
1655    memcpy(context, "ServerOut", 9);
1656
1657    err = smb_kdf_hmac_sha256(vcp->vc_mackey, vcp->vc_mackeylen,
1658                              label, 11,  // includes NULL Terminator
1659                              context, 10, // includes NULL Terminator
1660                              vcp->vc_smb3_decrypt_key,
1661                              SMB3_KEY_LEN);
1662    if (!err) {
1663        vcp->vc_smb3_decrypt_key_len = SMB3_KEY_LEN;
1664    } else {
1665        SMBDEBUG("Could not generate smb3 decrypt key, error: %d\n", err);
1666    }
1667
1668out:
1669    return (err);
1670}
1671