1da6c28aaSamw /*
2da6c28aaSamw  * CDDL HEADER START
3da6c28aaSamw  *
4da6c28aaSamw  * The contents of this file are subject to the terms of the
5da6c28aaSamw  * Common Development and Distribution License (the "License").
6da6c28aaSamw  * You may not use this file except in compliance with the License.
7da6c28aaSamw  *
8da6c28aaSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da6c28aaSamw  * or http://www.opensolaris.org/os/licensing.
10da6c28aaSamw  * See the License for the specific language governing permissions
11da6c28aaSamw  * and limitations under the License.
12da6c28aaSamw  *
13da6c28aaSamw  * When distributing Covered Code, include this CDDL HEADER in each
14da6c28aaSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15da6c28aaSamw  * If applicable, add the following below this CDDL HEADER, with the
16da6c28aaSamw  * fields enclosed by brackets "[]" replaced with your own identifying
17da6c28aaSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
18da6c28aaSamw  *
19da6c28aaSamw  * CDDL HEADER END
20da6c28aaSamw  */
21da6c28aaSamw /*
22148c5f43SAlan Wright  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23c51c88bdSMatt Barden  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
24a5a9a6bbSGordon Ross  * Copyright 2022 RackTop Systems, Inc.
25da6c28aaSamw  */
26da6c28aaSamw /*
27da6c28aaSamw  * These routines provide the SMB MAC signing for the SMB server.
28da6c28aaSamw  * The routines calculate the signature of a SMB message in an mbuf chain.
29da6c28aaSamw  *
30c8ec8eeaSjose borrego  * The following table describes the client server
31c8ec8eeaSjose borrego  * signing registry relationship
32c8ec8eeaSjose borrego  *
33c8ec8eeaSjose borrego  *		| Required	| Enabled     | Disabled
34c8ec8eeaSjose borrego  * -------------+---------------+------------ +--------------
35c8ec8eeaSjose borrego  * Required	| Signed	| Signed      | Fail
36c8ec8eeaSjose borrego  * -------------+---------------+-------------+-----------------
37c8ec8eeaSjose borrego  * Enabled	| Signed	| Signed      | Not Signed
38c8ec8eeaSjose borrego  * -------------+---------------+-------------+----------------
39c8ec8eeaSjose borrego  * Disabled	| Fail		| Not Signed  | Not Signed
40da6c28aaSamw  */
41da6c28aaSamw 
42da6c28aaSamw #include <sys/uio.h>
43bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h>
441160dcf7SMatt Barden #include <smbsrv/smb_kcrypt.h>
45b819cea2SGordon Ross #include <sys/isa_defs.h>
46b819cea2SGordon Ross #include <sys/byteorder.h>
47da6c28aaSamw 
48da6c28aaSamw #define	SMB_SIG_SIZE	8
49da6c28aaSamw #define	SMB_SIG_OFFS	14
50b819cea2SGordon Ross #define	SMB_HDRLEN	32
51b819cea2SGordon Ross 
52b819cea2SGordon Ross #ifdef _LITTLE_ENDIAN
53b819cea2SGordon Ross #define	htolel(x)	((uint32_t)(x))
54b819cea2SGordon Ross #else
55b819cea2SGordon Ross #define	htolel(x)	BSWAP_32(x)
56b819cea2SGordon Ross #endif
57da6c28aaSamw 
5812b65585SGordon Ross static int
5912b65585SGordon Ross smb_sign_calc(smb_request_t *sr, struct mbuf_chain *mbc,
6012b65585SGordon Ross     uint32_t seqnum, unsigned char *sig);
61c8ec8eeaSjose borrego 
62c8ec8eeaSjose borrego #ifdef DEBUG
6312b65585SGordon Ross uint32_t smb_sign_debug_search = 10;
6412b65585SGordon Ross 
6512b65585SGordon Ross /*
6612b65585SGordon Ross  * Debug code to search +/- for the correct sequence number.
6712b65585SGordon Ross  * If found, correct sign->seqnum and return 0, else return -1
6812b65585SGordon Ross  */
6912b65585SGordon Ross static int
smb_sign_find_seqnum(smb_request_t * sr,struct mbuf_chain * mbc,unsigned char * mac_sig,unsigned char * sr_sig)70c8ec8eeaSjose borrego smb_sign_find_seqnum(
7112b65585SGordon Ross     smb_request_t *sr,
7212b65585SGordon Ross     struct mbuf_chain *mbc,
73c8ec8eeaSjose borrego     unsigned char *mac_sig,
7412b65585SGordon Ross     unsigned char *sr_sig)
75c8ec8eeaSjose borrego {
7612b65585SGordon Ross 	struct smb_sign *sign = &sr->session->signing;
7712b65585SGordon Ross 	uint32_t i, t;
7812b65585SGordon Ross 
7912b65585SGordon Ross 	for (i = 1; i < smb_sign_debug_search; i++) {
8012b65585SGordon Ross 		t = sr->sr_seqnum + i;
8112b65585SGordon Ross 		(void) smb_sign_calc(sr, mbc, t, mac_sig);
8212b65585SGordon Ross 		if (memcmp(mac_sig, sr_sig, SMB_SIG_SIZE) == 0) {
8312b65585SGordon Ross 			goto found;
8412b65585SGordon Ross 		}
8512b65585SGordon Ross 		t = sr->sr_seqnum - i;
8612b65585SGordon Ross 		(void) smb_sign_calc(sr, mbc, t, mac_sig);
87c8ec8eeaSjose borrego 		if (memcmp(mac_sig, sr_sig, SMB_SIG_SIZE) == 0) {
8812b65585SGordon Ross 			goto found;
89c8ec8eeaSjose borrego 		}
90c8ec8eeaSjose borrego 	}
9112b65585SGordon Ross 	cmn_err(CE_WARN, "smb_sign_find_seqnum: failed after %d", i);
9212b65585SGordon Ross 	return (-1);
9312b65585SGordon Ross 
9412b65585SGordon Ross found:
9512b65585SGordon Ross 	cmn_err(CE_WARN, "smb_sign_find_seqnum: found! %d <- %d",
9612b65585SGordon Ross 	    sign->seqnum, t);
9712b65585SGordon Ross 	sign->seqnum = t;
9812b65585SGordon Ross 	return (0);
99c8ec8eeaSjose borrego }
100c8ec8eeaSjose borrego #endif
101148c5f43SAlan Wright 
102b819cea2SGordon Ross /*
103b819cea2SGordon Ross  * Called during session destroy.
104b819cea2SGordon Ross  */
105b819cea2SGordon Ross static void
smb_sign_fini(smb_session_t * s)106b819cea2SGordon Ross smb_sign_fini(smb_session_t *s)
1078622ec45SGordon Ross {
1081160dcf7SMatt Barden 	smb_crypto_mech_t *mech;
109b819cea2SGordon Ross 
11012b65585SGordon Ross 	if ((mech = s->sign_mech) != NULL) {
111b819cea2SGordon Ross 		kmem_free(mech, sizeof (*mech));
11212b65585SGordon Ross 		s->sign_mech = NULL;
1138622ec45SGordon Ross 	}
1148622ec45SGordon Ross }
1158622ec45SGordon Ross 
116da6c28aaSamw /*
117b819cea2SGordon Ross  * smb_sign_begin
118da6c28aaSamw  *
119da6c28aaSamw  * Intializes MAC key based on the user session key and
120da6c28aaSamw  * NTLM response and store it in the signing structure.
121b819cea2SGordon Ross  * This is what begins SMB signing.
122da6c28aaSamw  */
123c51c88bdSMatt Barden void
smb_sign_begin(smb_request_t * sr,smb_token_t * token)124b819cea2SGordon Ross smb_sign_begin(smb_request_t *sr, smb_token_t *token)
125da6c28aaSamw {
126b819cea2SGordon Ross 	smb_arg_sessionsetup_t *sinfo = sr->sr_ssetup;
127b819cea2SGordon Ross 	smb_session_t *session = sr->session;
128b819cea2SGordon Ross 	struct smb_sign *sign = &session->signing;
1291160dcf7SMatt Barden 	smb_crypto_mech_t *mech;
130b819cea2SGordon Ross 	int rc;
131da6c28aaSamw 
13212b65585SGordon Ross 	/*
13312b65585SGordon Ross 	 * We should normally have a session key here because
13412b65585SGordon Ross 	 * our caller filters out Anonymous and Guest logons.
13512b65585SGordon Ross 	 * However, buggy clients could get us here without a
13612b65585SGordon Ross 	 * session key, in which case: just don't sign.
13712b65585SGordon Ross 	 */
13812b65585SGordon Ross 	if (token->tkn_ssnkey.val == NULL || token->tkn_ssnkey.len == 0)
139c51c88bdSMatt Barden 		return;
14012b65585SGordon Ross 
141b819cea2SGordon Ross 	/*
142b819cea2SGordon Ross 	 * Session-level initialization (once per session)
143b819cea2SGordon Ross 	 */
144b819cea2SGordon Ross 	smb_rwx_rwenter(&session->s_lock, RW_WRITER);
145b819cea2SGordon Ross 
146b819cea2SGordon Ross 	/*
147b819cea2SGordon Ross 	 * Signing may already have been setup by a prior logon,
148b819cea2SGordon Ross 	 * in which case we're done here.
149b819cea2SGordon Ross 	 */
150b819cea2SGordon Ross 	if (sign->mackey != NULL) {
151b819cea2SGordon Ross 		smb_rwx_rwexit(&session->s_lock);
152c51c88bdSMatt Barden 		return;
153da6c28aaSamw 	}
154da6c28aaSamw 
155b819cea2SGordon Ross 	/*
156b819cea2SGordon Ross 	 * Get the mech handle
157b819cea2SGordon Ross 	 */
15812b65585SGordon Ross 	if (session->sign_mech == NULL) {
159b819cea2SGordon Ross 		mech = kmem_zalloc(sizeof (*mech), KM_SLEEP);
160b819cea2SGordon Ross 		rc = smb_md5_getmech(mech);
161b819cea2SGordon Ross 		if (rc != 0) {
162b819cea2SGordon Ross 			kmem_free(mech, sizeof (*mech));
163b819cea2SGordon Ross 			smb_rwx_rwexit(&session->s_lock);
164c51c88bdSMatt Barden 			return;
165b819cea2SGordon Ross 		}
16612b65585SGordon Ross 		session->sign_mech = mech;
167b819cea2SGordon Ross 		session->sign_fini = smb_sign_fini;
168b819cea2SGordon Ross 	}
169da6c28aaSamw 
170b819cea2SGordon Ross 	/*
171b819cea2SGordon Ross 	 * Compute and store the signing (MAC) key.
172b819cea2SGordon Ross 	 *
173b819cea2SGordon Ross 	 * With extended security, the MAC key is the same as the
17412b65585SGordon Ross 	 * session key (and we'll have sinfo->ssi_ntpwlen == 0).
175b819cea2SGordon Ross 	 * With non-extended security, it's the concatenation of
176b819cea2SGordon Ross 	 * the session key and the "NT response" we received.
177b819cea2SGordon Ross 	 */
17812b65585SGordon Ross 	sign->mackey_len = token->tkn_ssnkey.len + sinfo->ssi_ntpwlen;
179b819cea2SGordon Ross 	sign->mackey = kmem_alloc(sign->mackey_len, KM_SLEEP);
18012b65585SGordon Ross 	bcopy(token->tkn_ssnkey.val, sign->mackey, token->tkn_ssnkey.len);
18112b65585SGordon Ross 	if (sinfo->ssi_ntpwlen > 0) {
18212b65585SGordon Ross 		bcopy(sinfo->ssi_ntpwd, sign->mackey + token->tkn_ssnkey.len,
18312b65585SGordon Ross 		    sinfo->ssi_ntpwlen);
184b819cea2SGordon Ross 	}
185da6c28aaSamw 
186b819cea2SGordon Ross 	session->signing.seqnum = 0;
187148c5f43SAlan Wright 	sr->sr_seqnum = 2;
188faa1795aSjb 	sr->reply_seqnum = 1;
189b819cea2SGordon Ross 	sign->flags = 0;
190b819cea2SGordon Ross 
1911160dcf7SMatt Barden 	if (session->srv_secmode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
192b819cea2SGordon Ross 		sign->flags |= SMB_SIGNING_ENABLED;
1931160dcf7SMatt Barden 		if (session->srv_secmode &
1941160dcf7SMatt Barden 		    NEGOTIATE_SECURITY_SIGNATURES_REQUIRED)
195b819cea2SGordon Ross 			sign->flags |= SMB_SIGNING_CHECK;
196b819cea2SGordon Ross 	}
197b819cea2SGordon Ross 
198b819cea2SGordon Ross 	smb_rwx_rwexit(&session->s_lock);
199da6c28aaSamw }
200da6c28aaSamw 
201da6c28aaSamw /*
202da6c28aaSamw  * smb_sign_calc
203da6c28aaSamw  *
204da6c28aaSamw  * Calculates MAC signature for the given buffer and returns
205da6c28aaSamw  * it in the mac_sign parameter.
206da6c28aaSamw  *
207da6c28aaSamw  * The sequence number is placed in the first four bytes of the signature
208da6c28aaSamw  * field of the signature and the other 4 bytes are zeroed.
209da6c28aaSamw  * The signature is the first 8 bytes of the MD5 result of the
210da6c28aaSamw  * concatenated MAC key and the SMB message.
211da6c28aaSamw  *
212da6c28aaSamw  * MACsig = head(MD5(concat(MACKey, SMBMsg)), 8)
213da6c28aaSamw  *
214da6c28aaSamw  * where
215da6c28aaSamw  *
216da6c28aaSamw  *	MACKey = concat( UserSessionKey, NTLMResp )
217da6c28aaSamw  *
218da6c28aaSamw  * and
219da6c28aaSamw  *
220da6c28aaSamw  *	SMBMsg is the SMB message containing the sequence number.
221da6c28aaSamw  *
222b819cea2SGordon Ross  * Return 0 if success
223da6c28aaSamw  *
224da6c28aaSamw  */
22512b65585SGordon Ross static int
smb_sign_calc(smb_request_t * sr,struct mbuf_chain * mbc,uint32_t seqnum,unsigned char * mac_sign)22612b65585SGordon Ross smb_sign_calc(smb_request_t *sr, struct mbuf_chain *mbc,
22712b65585SGordon Ross     uint32_t seqnum, unsigned char *mac_sign)
228da6c28aaSamw {
22912b65585SGordon Ross 	smb_session_t *s = sr->session;
23012b65585SGordon Ross 	struct smb_sign *sign = &s->signing;
231b819cea2SGordon Ross 	smb_sign_ctx_t ctx = 0;
232b819cea2SGordon Ross 	uchar_t digest[MD5_DIGEST_LENGTH];
233b819cea2SGordon Ross 	uchar_t *hdrp;
234da6c28aaSamw 	struct mbuf *mbuf = mbc->chain;
235da6c28aaSamw 	int offset = mbc->chain_offset;
236da6c28aaSamw 	int size;
237b819cea2SGordon Ross 	int rc;
238da6c28aaSamw 
239b819cea2SGordon Ross 	/*
240b819cea2SGordon Ross 	 * This union is a little bit of trickery to:
241b819cea2SGordon Ross 	 * (1) get the sequence number int aligned, and
242b819cea2SGordon Ross 	 * (2) reduce the number of digest calls, at the
243b819cea2SGordon Ross 	 * cost of a copying 32 bytes instead of 8.
244b819cea2SGordon Ross 	 * Both sides of this union are 2+32 bytes.
245b819cea2SGordon Ross 	 */
246b819cea2SGordon Ross 	union {
247b819cea2SGordon Ross 		struct {
248b819cea2SGordon Ross 			uint8_t skip[2]; /* not used - just alignment */
249b819cea2SGordon Ross 			uint8_t raw[SMB_HDRLEN];  /* header length (32) */
250b819cea2SGordon Ross 		} r;
251b819cea2SGordon Ross 		struct {
252b819cea2SGordon Ross 			uint8_t skip[2]; /* not used - just alignment */
253b819cea2SGordon Ross 			uint8_t hdr[SMB_SIG_OFFS]; /* sig. offset (14) */
254b819cea2SGordon Ross 			uint32_t sig[2]; /* MAC signature, aligned! */
255b819cea2SGordon Ross 			uint16_t ids[5]; /* pad, Tid, Pid, Uid, Mid */
256b819cea2SGordon Ross 		} s;
257b819cea2SGordon Ross 	} smbhdr;
258b819cea2SGordon Ross 
25912b65585SGordon Ross 	if (s->sign_mech == NULL || sign->mackey == NULL)
260b819cea2SGordon Ross 		return (-1);
261da6c28aaSamw 
26212b65585SGordon Ross 	if ((rc = smb_md5_init(&ctx, s->sign_mech)) != 0)
263b819cea2SGordon Ross 		return (rc);
264da6c28aaSamw 
265b819cea2SGordon Ross 	/* Digest the MAC Key */
266b819cea2SGordon Ross 	rc = smb_md5_update(ctx, sign->mackey, sign->mackey_len);
267b819cea2SGordon Ross 	if (rc != 0)
268b819cea2SGordon Ross 		return (rc);
269da6c28aaSamw 
270da6c28aaSamw 	/*
271b819cea2SGordon Ross 	 * Make an aligned copy of the SMB header,
272b819cea2SGordon Ross 	 * fill in the sequence number, and digest.
273da6c28aaSamw 	 */
274b819cea2SGordon Ross 	hdrp = (unsigned char *)&smbhdr.r.raw;
275b819cea2SGordon Ross 	size = SMB_HDRLEN;
276b819cea2SGordon Ross 	if (smb_mbc_peek(mbc, offset, "#c", size, hdrp) != 0)
277b819cea2SGordon Ross 		return (-1);
278b819cea2SGordon Ross 	smbhdr.s.sig[0] = htolel(seqnum);
279b819cea2SGordon Ross 	smbhdr.s.sig[1] = 0;
280da6c28aaSamw 
281b819cea2SGordon Ross 	rc = smb_md5_update(ctx, &smbhdr.r.raw, size);
282b819cea2SGordon Ross 	if (rc != 0)
283b819cea2SGordon Ross 		return (rc);
284da6c28aaSamw 
285b819cea2SGordon Ross 	/*
286b819cea2SGordon Ross 	 * Digest the rest of the SMB packet, starting at the data
287b819cea2SGordon Ross 	 * just after the SMB header.
288b819cea2SGordon Ross 	 */
289b819cea2SGordon Ross 	offset += size;
290b819cea2SGordon Ross 	while (mbuf != NULL && (offset >= mbuf->m_len)) {
291da6c28aaSamw 		offset -= mbuf->m_len;
292da6c28aaSamw 		mbuf = mbuf->m_next;
293da6c28aaSamw 	}
294b819cea2SGordon Ross 	if (mbuf != NULL && (size = (mbuf->m_len - offset)) > 0) {
295b819cea2SGordon Ross 		rc = smb_md5_update(ctx, &mbuf->m_data[offset], size);
296b819cea2SGordon Ross 		if (rc != 0)
297b819cea2SGordon Ross 			return (rc);
298da6c28aaSamw 		offset = 0;
299da6c28aaSamw 		mbuf = mbuf->m_next;
300da6c28aaSamw 	}
301b819cea2SGordon Ross 	while (mbuf != NULL) {
302b819cea2SGordon Ross 		rc = smb_md5_update(ctx, mbuf->m_data, mbuf->m_len);
303b819cea2SGordon Ross 		if (rc != 0)
304b819cea2SGordon Ross 			return (rc);
305da6c28aaSamw 		mbuf = mbuf->m_next;
306da6c28aaSamw 	}
307b819cea2SGordon Ross 	rc = smb_md5_final(ctx, digest);
308b819cea2SGordon Ross 	if (rc == 0)
309b819cea2SGordon Ross 		bcopy(digest, mac_sign, SMB_SIG_SIZE);
310da6c28aaSamw 
311b819cea2SGordon Ross 	return (rc);
312da6c28aaSamw }
313da6c28aaSamw 
314da6c28aaSamw 
315da6c28aaSamw /*
316da6c28aaSamw  * smb_sign_check_request
317da6c28aaSamw  *
318da6c28aaSamw  * Calculates MAC signature for the request mbuf chain
319da6c28aaSamw  * using the next expected sequence number and compares
320da6c28aaSamw  * it to the given signature.
321da6c28aaSamw  *
322da6c28aaSamw  * Note it does not check the signature for secondary transactions
323da6c28aaSamw  * as their sequence number is the same as the original request.
324da6c28aaSamw  *
325da6c28aaSamw  * Return 0 if the signature verifies, otherwise, returns -1;
326da6c28aaSamw  *
327da6c28aaSamw  */
328da6c28aaSamw int
smb_sign_check_request(smb_request_t * sr)329faa1795aSjb smb_sign_check_request(smb_request_t *sr)
330da6c28aaSamw {
33112b65585SGordon Ross 	struct mbuf_chain mbc = sr->command;
332da6c28aaSamw 	unsigned char mac_sig[SMB_SIG_SIZE];
333148c5f43SAlan Wright 
334da6c28aaSamw 	/*
335da6c28aaSamw 	 * Don't check secondary transactions - we dont know the sequence
336da6c28aaSamw 	 * number.
337da6c28aaSamw 	 */
338faa1795aSjb 	if (sr->smb_com == SMB_COM_TRANSACTION_SECONDARY ||
339faa1795aSjb 	    sr->smb_com == SMB_COM_TRANSACTION2_SECONDARY ||
340faa1795aSjb 	    sr->smb_com == SMB_COM_NT_TRANSACT_SECONDARY)
341da6c28aaSamw 		return (0);
342da6c28aaSamw 
343c8ec8eeaSjose borrego 	/* Reset the offset to begining of header */
34412b65585SGordon Ross 	mbc.chain_offset = sr->orig_request_hdr;
345c8ec8eeaSjose borrego 
346c8ec8eeaSjose borrego 	/* calculate mac signature */
34712b65585SGordon Ross 	if (smb_sign_calc(sr, &mbc, sr->sr_seqnum, mac_sig) != 0)
348c8ec8eeaSjose borrego 		return (-1);
349c8ec8eeaSjose borrego 
350c8ec8eeaSjose borrego 	/* compare the signatures */
35112b65585SGordon Ross 	if (memcmp(mac_sig, sr->smb_sig, SMB_SIG_SIZE) == 0) {
35212b65585SGordon Ross 		/* They match! OK, we're done. */
35312b65585SGordon Ross 		return (0);
35412b65585SGordon Ross 	}
35512b65585SGordon Ross 
356*45f8fdd1SGordon Ross 	DTRACE_PROBE2(signature__mismatch, smb_request_t *, sr,
35712b65585SGordon Ross 	    unsigned char *, mac_sig);
358b819cea2SGordon Ross 
35912b65585SGordon Ross 	/*
36012b65585SGordon Ross 	 * check nearby sequence numbers in debug mode
36112b65585SGordon Ross 	 */
36212b65585SGordon Ross #ifdef	DEBUG
36312b65585SGordon Ross 	if (smb_sign_debug) {
36412b65585SGordon Ross 		return (smb_sign_find_seqnum(sr, &mbc, mac_sig, sr->smb_sig));
365da6c28aaSamw 	}
36612b65585SGordon Ross #endif
36712b65585SGordon Ross 	return (-1);
368da6c28aaSamw }
369da6c28aaSamw 
370da6c28aaSamw /*
371da6c28aaSamw  * smb_sign_check_secondary
372da6c28aaSamw  *
373da6c28aaSamw  * Calculates MAC signature for the secondary transaction mbuf chain
374da6c28aaSamw  * and compares it to the given signature.
375da6c28aaSamw  * Return 0 if the signature verifies, otherwise, returns -1;
376da6c28aaSamw  *
377da6c28aaSamw  */
378da6c28aaSamw int
smb_sign_check_secondary(smb_request_t * sr,unsigned int reply_seqnum)379faa1795aSjb smb_sign_check_secondary(smb_request_t *sr, unsigned int reply_seqnum)
380da6c28aaSamw {
38112b65585SGordon Ross 	struct mbuf_chain mbc = sr->command;
382da6c28aaSamw 	unsigned char mac_sig[SMB_SIG_SIZE];
383da6c28aaSamw 	int rtn = 0;
384da6c28aaSamw 
385c8ec8eeaSjose borrego 	/* Reset the offset to begining of header */
38612b65585SGordon Ross 	mbc.chain_offset = sr->orig_request_hdr;
387da6c28aaSamw 
388c8ec8eeaSjose borrego 	/* calculate mac signature */
38912b65585SGordon Ross 	if (smb_sign_calc(sr, &mbc, reply_seqnum - 1, mac_sig) != 0)
390c8ec8eeaSjose borrego 		return (-1);
391da6c28aaSamw 
392da6c28aaSamw 
393c8ec8eeaSjose borrego 	/* compare the signatures */
394c8ec8eeaSjose borrego 	if (memcmp(mac_sig, sr->smb_sig, SMB_SIG_SIZE) != 0) {
395c8ec8eeaSjose borrego 		cmn_err(CE_WARN, "SmbSignCheckSecond: bad signature");
396c8ec8eeaSjose borrego 		rtn = -1;
397da6c28aaSamw 	}
398da6c28aaSamw 	/* Save the reply sequence number */
399faa1795aSjb 	sr->reply_seqnum = reply_seqnum;
400da6c28aaSamw 
401da6c28aaSamw 	return (rtn);
402da6c28aaSamw }
403da6c28aaSamw 
404da6c28aaSamw /*
405da6c28aaSamw  * smb_sign_reply
406da6c28aaSamw  *
407da6c28aaSamw  * Calculates MAC signature for the given mbuf chain,
408da6c28aaSamw  * and write it to the signature field in the mbuf.
409da6c28aaSamw  *
410da6c28aaSamw  */
411da6c28aaSamw void
smb_sign_reply(smb_request_t * sr,struct mbuf_chain * reply)412faa1795aSjb smb_sign_reply(smb_request_t *sr, struct mbuf_chain *reply)
413da6c28aaSamw {
41412b65585SGordon Ross 	struct mbuf_chain mbc;
41512b65585SGordon Ross 	unsigned char mac[SMB_SIG_SIZE];
416da6c28aaSamw 
417da6c28aaSamw 	if (reply)
41812b65585SGordon Ross 		mbc = *reply;
419da6c28aaSamw 	else
42012b65585SGordon Ross 		mbc = sr->reply;
421da6c28aaSamw 
422da6c28aaSamw 	/* Reset offset to start of reply */
42312b65585SGordon Ross 	mbc.chain_offset = 0;
424da6c28aaSamw 
425da6c28aaSamw 	/*
426da6c28aaSamw 	 * Calculate MAC signature
427da6c28aaSamw 	 */
42812b65585SGordon Ross 	if (smb_sign_calc(sr, &mbc, sr->reply_seqnum, mac) != 0) {
429148c5f43SAlan Wright 		cmn_err(CE_WARN, "smb_sign_reply: error in smb_sign_calc");
430da6c28aaSamw 		return;
431148c5f43SAlan Wright 	}
432da6c28aaSamw 
433da6c28aaSamw 	/*
434da6c28aaSamw 	 * Put signature in the response
435da6c28aaSamw 	 */
43612b65585SGordon Ross 	(void) smb_mbc_poke(&mbc, SMB_SIG_OFFS, "#c",
43712b65585SGordon Ross 	    SMB_SIG_SIZE, mac);
438da6c28aaSamw }
439