xref: /onnv-gate/usr/src/uts/common/fs/smbsrv/smb_signing.c (revision 12508:edb7861a1533)
15331Samw /*
25331Samw  * CDDL HEADER START
35331Samw  *
45331Samw  * The contents of this file are subject to the terms of the
55331Samw  * Common Development and Distribution License (the "License").
65331Samw  * You may not use this file except in compliance with the License.
75331Samw  *
85331Samw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95331Samw  * or http://www.opensolaris.org/os/licensing.
105331Samw  * See the License for the specific language governing permissions
115331Samw  * and limitations under the License.
125331Samw  *
135331Samw  * When distributing Covered Code, include this CDDL HEADER in each
145331Samw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155331Samw  * If applicable, add the following below this CDDL HEADER, with the
165331Samw  * fields enclosed by brackets "[]" replaced with your own identifying
175331Samw  * information: Portions Copyright [yyyy] [name of copyright owner]
185331Samw  *
195331Samw  * CDDL HEADER END
205331Samw  */
215331Samw /*
22*12508Samw@Sun.COM  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
235331Samw  */
245331Samw /*
255331Samw  * These routines provide the SMB MAC signing for the SMB server.
265331Samw  * The routines calculate the signature of a SMB message in an mbuf chain.
275331Samw  *
287348SJose.Borrego@Sun.COM  * The following table describes the client server
297348SJose.Borrego@Sun.COM  * signing registry relationship
307348SJose.Borrego@Sun.COM  *
317348SJose.Borrego@Sun.COM  *		| Required	| Enabled     | Disabled
327348SJose.Borrego@Sun.COM  * -------------+---------------+------------ +--------------
337348SJose.Borrego@Sun.COM  * Required	| Signed	| Signed      | Fail
347348SJose.Borrego@Sun.COM  * -------------+---------------+-------------+-----------------
357348SJose.Borrego@Sun.COM  * Enabled	| Signed	| Signed      | Not Signed
367348SJose.Borrego@Sun.COM  * -------------+---------------+-------------+----------------
377348SJose.Borrego@Sun.COM  * Disabled	| Fail		| Not Signed  | Not Signed
385331Samw  */
395331Samw 
405331Samw #include <sys/uio.h>
4110966SJordan.Brown@Sun.COM #include <smbsrv/smb_kproto.h>
425331Samw #include <smbsrv/msgbuf.h>
435331Samw #include <sys/crypto/api.h>
445331Samw 
456600Sas200622 #define	SMBAUTH_SESSION_KEY_SZ 16
465331Samw #define	SMB_SIG_SIZE	8
475331Samw #define	SMB_SIG_OFFS	14
485331Samw 
497348SJose.Borrego@Sun.COM int
507348SJose.Borrego@Sun.COM smb_sign_calc(struct mbuf_chain *mbc,
517348SJose.Borrego@Sun.COM     struct smb_sign *sign,
527348SJose.Borrego@Sun.COM     uint32_t seqnum,
537348SJose.Borrego@Sun.COM     unsigned char *mac_sign);
547348SJose.Borrego@Sun.COM 
557348SJose.Borrego@Sun.COM #ifdef DEBUG
567348SJose.Borrego@Sun.COM void smb_sign_find_seqnum(
57*12508Samw@Sun.COM     uint32_t seqnum,
587348SJose.Borrego@Sun.COM     struct smb_sign *sign,
597348SJose.Borrego@Sun.COM     struct mbuf_chain *command,
607348SJose.Borrego@Sun.COM     unsigned char *mac_sig,
617348SJose.Borrego@Sun.COM     unsigned char *sr_sig,
627348SJose.Borrego@Sun.COM     boolean_t *found);
63*12508Samw@Sun.COM #define	SMB_CHECK_SEQNUM(seqnum, sign, command, mac_sig, sr_sig, found) \
647348SJose.Borrego@Sun.COM { \
657348SJose.Borrego@Sun.COM 	if (smb_sign_debug) \
66*12508Samw@Sun.COM 		smb_sign_find_seqnum(seqnum, sign, \
67*12508Samw@Sun.COM 		    command, mac_sig, sr_sig, found); \
687348SJose.Borrego@Sun.COM }
697348SJose.Borrego@Sun.COM #else
70*12508Samw@Sun.COM #define	SMB_CHECK_SEQNUM(seqnum, sign, command, mac_sig, sr_sig, found) \
71*12508Samw@Sun.COM 	{ \
72*12508Samw@Sun.COM 		*found = 0; \
73*12508Samw@Sun.COM 	}
747348SJose.Borrego@Sun.COM #endif
757348SJose.Borrego@Sun.COM 
767348SJose.Borrego@Sun.COM #ifdef DEBUG
777348SJose.Borrego@Sun.COM void
smb_sign_find_seqnum(uint32_t seqnum,struct smb_sign * sign,struct mbuf_chain * command,unsigned char * mac_sig,unsigned char * sr_sig,boolean_t * found)787348SJose.Borrego@Sun.COM smb_sign_find_seqnum(
79*12508Samw@Sun.COM     uint32_t seqnum,
807348SJose.Borrego@Sun.COM     struct smb_sign *sign,
817348SJose.Borrego@Sun.COM     struct mbuf_chain *command,
827348SJose.Borrego@Sun.COM     unsigned char *mac_sig,
837348SJose.Borrego@Sun.COM     unsigned char *sr_sig,
847348SJose.Borrego@Sun.COM     boolean_t *found)
857348SJose.Borrego@Sun.COM {
867348SJose.Borrego@Sun.COM int start_seqnum;
877348SJose.Borrego@Sun.COM int i;
887348SJose.Borrego@Sun.COM 
897348SJose.Borrego@Sun.COM 	/* Debug code to hunt for the sequence number */
907348SJose.Borrego@Sun.COM 	*found = B_FALSE;
91*12508Samw@Sun.COM 	start_seqnum = seqnum - 10;
927348SJose.Borrego@Sun.COM 	if (start_seqnum < 0)
937348SJose.Borrego@Sun.COM 		start_seqnum = 0;
94*12508Samw@Sun.COM 	for (i = start_seqnum; i <= start_seqnum + 20; i++) {
957639SNick.Todd@Sun.COM 		(void) smb_sign_calc(command, sign, i, mac_sig);
967348SJose.Borrego@Sun.COM 		if (memcmp(mac_sig, sr_sig, SMB_SIG_SIZE) == 0) {
977348SJose.Borrego@Sun.COM 			sign->seqnum = i;
987348SJose.Borrego@Sun.COM 			*found = B_TRUE;
997348SJose.Borrego@Sun.COM 			break;
1007348SJose.Borrego@Sun.COM 		}
101*12508Samw@Sun.COM 		cmn_err(CE_WARN, "smb_sign_find_seqnum: seqnum:%d mismatch", i);
1027348SJose.Borrego@Sun.COM 	}
1037348SJose.Borrego@Sun.COM 	cmn_err(CE_WARN, "smb_sign_find_seqnum: found=%d", *found);
1047348SJose.Borrego@Sun.COM }
1057348SJose.Borrego@Sun.COM #endif
106*12508Samw@Sun.COM 
1075331Samw /* This holds the MD5 mechanism */
1085331Samw static	crypto_mechanism_t crypto_mech = {CRYPTO_MECHANISM_INVALID, 0, 0};
1095331Samw 
1105331Samw /*
1115331Samw  * smb_sign_init
1125331Samw  *
1135331Samw  * Intializes MAC key based on the user session key and
1145331Samw  * NTLM response and store it in the signing structure.
1155331Samw  */
1165331Samw void
smb_sign_init(smb_request_t * sr,smb_session_key_t * session_key,char * resp,int resp_len)1176139Sjb150015 smb_sign_init(smb_request_t *sr, smb_session_key_t *session_key,
1185331Samw 	char *resp, int resp_len)
1195331Samw {
1206139Sjb150015 	struct smb_sign *sign = &sr->session->signing;
1215331Samw 
1225331Samw 	/*
1235331Samw 	 * Initialise the crypto mechanism to MD5 if it not
1245331Samw 	 * already initialised.
1255331Samw 	 */
1265331Samw 	if (crypto_mech.cm_type ==  CRYPTO_MECHANISM_INVALID) {
1275331Samw 		crypto_mech.cm_type = crypto_mech2id(SUN_CKM_MD5);
1285331Samw 		if (crypto_mech.cm_type == CRYPTO_MECHANISM_INVALID) {
1295331Samw 			/*
1305331Samw 			 * There is no MD5 crypto mechanism
1315331Samw 			 * so turn off signing
1325331Samw 			 */
1336139Sjb150015 			sr->sr_cfg->skc_signing_enable = 0;
1346139Sjb150015 			sr->session->secmode &=
1355331Samw 			    (~NEGOTIATE_SECURITY_SIGNATURES_ENABLED);
1365331Samw 			cmn_err(CE_WARN,
1375331Samw 			    "SmbSignInit: signing disabled (no MD5)");
1385331Samw 			return;
1395331Samw 		}
1405331Samw 	}
1415331Samw 
1425331Samw 	/* MAC key = concat (SessKey, NTLMResponse) */
1435331Samw 
1445331Samw 	bcopy(session_key, sign->mackey, sizeof (smb_session_key_t));
1455331Samw 	bcopy(resp, &(sign->mackey[sizeof (smb_session_key_t)]),
1465331Samw 	    resp_len);
1475331Samw 	sign->mackey_len = sizeof (smb_session_key_t) + resp_len;
1485331Samw 
149*12508Samw@Sun.COM 	sr->session->signing.seqnum = 0;
150*12508Samw@Sun.COM 	sr->sr_seqnum = 2;
1516139Sjb150015 	sr->reply_seqnum = 1;
1525331Samw 	sign->flags = SMB_SIGNING_ENABLED;
1535331Samw 
1545331Samw }
1555331Samw 
1565331Samw /*
1575331Samw  * smb_sign_calc
1585331Samw  *
1595331Samw  * Calculates MAC signature for the given buffer and returns
1605331Samw  * it in the mac_sign parameter.
1615331Samw  *
1625331Samw  * The sequence number is placed in the first four bytes of the signature
1635331Samw  * field of the signature and the other 4 bytes are zeroed.
1645331Samw  * The signature is the first 8 bytes of the MD5 result of the
1655331Samw  * concatenated MAC key and the SMB message.
1665331Samw  *
1675331Samw  * MACsig = head(MD5(concat(MACKey, SMBMsg)), 8)
1685331Samw  *
1695331Samw  * where
1705331Samw  *
1715331Samw  *	MACKey = concat( UserSessionKey, NTLMResp )
1725331Samw  *
1735331Samw  * and
1745331Samw  *
1755331Samw  *	SMBMsg is the SMB message containing the sequence number.
1765331Samw  *
1775331Samw  * Return 0 if  success else -1
1785331Samw  *
1795331Samw  */
1807348SJose.Borrego@Sun.COM int
smb_sign_calc(struct mbuf_chain * mbc,struct smb_sign * sign,uint32_t seqnum,unsigned char * mac_sign)1815331Samw smb_sign_calc(struct mbuf_chain *mbc,
1825331Samw     struct smb_sign *sign,
1835331Samw     uint32_t seqnum,
1845331Samw     unsigned char *mac_sign)
1855331Samw {
1865331Samw 	uint32_t seq_buf[2] = {0, 0};
1875331Samw 	unsigned char mac[16];
1885331Samw 	struct mbuf *mbuf = mbc->chain;
1895331Samw 	int offset = mbc->chain_offset;
1905331Samw 	int size;
1915331Samw 	int status;
1925331Samw 
1935331Samw 	crypto_data_t data;
1945331Samw 	crypto_data_t digest;
1955331Samw 	crypto_context_t crypto_ctx;
1965331Samw 
1975331Samw 	data.cd_format = CRYPTO_DATA_RAW;
1985331Samw 	data.cd_offset = 0;
1995331Samw 	data.cd_length = (size_t)-1;
2005331Samw 	data.cd_miscdata = 0;
2015331Samw 
2025331Samw 	digest.cd_format = CRYPTO_DATA_RAW;
2035331Samw 	digest.cd_offset = 0;
2045331Samw 	digest.cd_length = (size_t)-1;
2055331Samw 	digest.cd_miscdata = 0;
2065331Samw 	digest.cd_raw.iov_base = (char *)mac;
2075331Samw 	digest.cd_raw.iov_len = sizeof (mac);
2085331Samw 
2095331Samw 	status = crypto_digest_init(&crypto_mech, &crypto_ctx, 0);
2106600Sas200622 	if (status != CRYPTO_SUCCESS)
2116600Sas200622 		goto error;
2125331Samw 
2135331Samw 	/*
2145331Samw 	 * Put the sequence number into the first 4 bytes
2155331Samw 	 * of the signature field in little endian format.
2165331Samw 	 * We are using a buffer to represent the signature
2175331Samw 	 * rather than modifying the SMB message.
2185331Samw 	 */
2195331Samw #ifdef __sparc
2205331Samw 	{
2215331Samw 		uint32_t temp;
2225331Samw 		((uint8_t *)&temp)[0] = ((uint8_t *)&seqnum)[3];
2235331Samw 		((uint8_t *)&temp)[1] = ((uint8_t *)&seqnum)[2];
2245331Samw 		((uint8_t *)&temp)[2] = ((uint8_t *)&seqnum)[1];
2255331Samw 		((uint8_t *)&temp)[3] = ((uint8_t *)&seqnum)[0];
2265331Samw 
2275331Samw 		seq_buf[0] = temp;
2285331Samw 	}
2295331Samw #else
2305331Samw 	seq_buf[0] = seqnum;
2315331Samw #endif
2325331Samw 
2335331Samw 	/* Digest the MACKey */
2345331Samw 	data.cd_raw.iov_base = (char *)sign->mackey;
2355331Samw 	data.cd_raw.iov_len = sign->mackey_len;
2366600Sas200622 	data.cd_length = sign->mackey_len;
2376600Sas200622 	status = crypto_digest_update(crypto_ctx, &data, 0);
2386600Sas200622 	if (status != CRYPTO_SUCCESS)
2396600Sas200622 		goto error;
2405331Samw 
2415331Samw 	/* Find start of data in chain */
2425331Samw 	while (offset >= mbuf->m_len) {
2435331Samw 		offset -= mbuf->m_len;
2445331Samw 		mbuf = mbuf->m_next;
2455331Samw 	}
2465331Samw 
2475331Samw 	/* Digest the SMB packet up to the signature field */
2485331Samw 	size = SMB_SIG_OFFS;
2495331Samw 	while (size >= mbuf->m_len - offset) {
2505331Samw 		data.cd_raw.iov_base = &mbuf->m_data[offset];
2515331Samw 		data.cd_raw.iov_len = mbuf->m_len - offset;
2526600Sas200622 		data.cd_length = mbuf->m_len - offset;
2536600Sas200622 		status = crypto_digest_update(crypto_ctx, &data, 0);
2546600Sas200622 		if (status != CRYPTO_SUCCESS)
2556600Sas200622 			goto error;
2565331Samw 
2575331Samw 		size -= mbuf->m_len - offset;
2585331Samw 		mbuf = mbuf->m_next;
2595331Samw 		offset = 0;
2605331Samw 	}
2615331Samw 	if (size > 0) {
2625331Samw 		data.cd_raw.iov_base = &mbuf->m_data[offset];
2635331Samw 		data.cd_raw.iov_len = size;
2646600Sas200622 		data.cd_length = size;
2656600Sas200622 		status = crypto_digest_update(crypto_ctx, &data, 0);
2666600Sas200622 		if (status != CRYPTO_SUCCESS)
2676600Sas200622 			goto error;
2685331Samw 		offset += size;
2695331Samw 	}
2705331Samw 
2715331Samw 	/*
2725331Samw 	 * Digest in the seq_buf instead of the signature
2735331Samw 	 * which has the sequence number
2745331Samw 	 */
2755331Samw 
2765331Samw 	data.cd_raw.iov_base = (char *)seq_buf;
2775331Samw 	data.cd_raw.iov_len = SMB_SIG_SIZE;
2786600Sas200622 	data.cd_length = SMB_SIG_SIZE;
2796600Sas200622 	status = crypto_digest_update(crypto_ctx, &data, 0);
2806600Sas200622 	if (status != CRYPTO_SUCCESS)
2816600Sas200622 		goto error;
2825331Samw 
2835331Samw 	/* Find the end of the signature field  */
2845331Samw 	offset += SMB_SIG_SIZE;
2855331Samw 	while (offset >= mbuf->m_len) {
2865331Samw 		offset -= mbuf->m_len;
2875331Samw 		mbuf = mbuf->m_next;
2885331Samw 	}
2895331Samw 	/* Digest the rest of the SMB packet */
2905331Samw 	while (mbuf) {
2915331Samw 		data.cd_raw.iov_base = &mbuf->m_data[offset];
2925331Samw 		data.cd_raw.iov_len = mbuf->m_len - offset;
2936600Sas200622 		data.cd_length = mbuf->m_len - offset;
2946600Sas200622 		status = crypto_digest_update(crypto_ctx, &data, 0);
2956600Sas200622 		if (status != CRYPTO_SUCCESS)
2966600Sas200622 			goto error;
2975331Samw 		mbuf = mbuf->m_next;
2985331Samw 		offset = 0;
2995331Samw 	}
3006600Sas200622 	digest.cd_length = SMBAUTH_SESSION_KEY_SZ;
3016600Sas200622 	status = crypto_digest_final(crypto_ctx, &digest, 0);
3026600Sas200622 	if (status != CRYPTO_SUCCESS)
3036600Sas200622 		goto error;
3045331Samw 	bcopy(mac, mac_sign, SMB_SIG_SIZE);
3055331Samw 	return (0);
3065331Samw error:
3075331Samw 	cmn_err(CE_WARN, "SmbSignCalc: crypto error %d", status);
3085331Samw 	return (-1);
3095331Samw 
3105331Samw }
3115331Samw 
3125331Samw 
3135331Samw /*
3145331Samw  * smb_sign_check_request
3155331Samw  *
3165331Samw  * Calculates MAC signature for the request mbuf chain
3175331Samw  * using the next expected sequence number and compares
3185331Samw  * it to the given signature.
3195331Samw  *
3205331Samw  * Note it does not check the signature for secondary transactions
3215331Samw  * as their sequence number is the same as the original request.
3225331Samw  *
3235331Samw  * Return 0 if the signature verifies, otherwise, returns -1;
3245331Samw  *
3255331Samw  */
3265331Samw int
smb_sign_check_request(smb_request_t * sr)3276139Sjb150015 smb_sign_check_request(smb_request_t *sr)
3285331Samw {
3296139Sjb150015 	struct mbuf_chain command = sr->command;
3305331Samw 	unsigned char mac_sig[SMB_SIG_SIZE];
3316139Sjb150015 	struct smb_sign *sign = &sr->session->signing;
3325331Samw 	int rtn = 0;
3337348SJose.Borrego@Sun.COM 	boolean_t found = B_TRUE;
334*12508Samw@Sun.COM 
3355331Samw 	/*
3365331Samw 	 * Don't check secondary transactions - we dont know the sequence
3375331Samw 	 * number.
3385331Samw 	 */
3396139Sjb150015 	if (sr->smb_com == SMB_COM_TRANSACTION_SECONDARY ||
3406139Sjb150015 	    sr->smb_com == SMB_COM_TRANSACTION2_SECONDARY ||
3416139Sjb150015 	    sr->smb_com == SMB_COM_NT_TRANSACT_SECONDARY)
3425331Samw 		return (0);
3435331Samw 
3447348SJose.Borrego@Sun.COM 	/* Reset the offset to begining of header */
3457348SJose.Borrego@Sun.COM 	command.chain_offset = sr->orig_request_hdr;
3465331Samw 
3477348SJose.Borrego@Sun.COM 	/* calculate mac signature */
348*12508Samw@Sun.COM 	if (smb_sign_calc(&command, sign, sr->sr_seqnum, mac_sig) != 0)
3497348SJose.Borrego@Sun.COM 		return (-1);
3505331Samw 
3517348SJose.Borrego@Sun.COM 	/* compare the signatures */
3527348SJose.Borrego@Sun.COM 	if (memcmp(mac_sig, sr->smb_sig, SMB_SIG_SIZE) != 0) {
3537348SJose.Borrego@Sun.COM 		DTRACE_PROBE2(smb__signing__req, smb_request_t, sr,
3547348SJose.Borrego@Sun.COM 		    smb_sign_t *, sr->smb_sig);
355*12508Samw@Sun.COM 		cmn_err(CE_NOTE, "smb_sign_check_request: bad signature");
3567348SJose.Borrego@Sun.COM 		/*
3577348SJose.Borrego@Sun.COM 		 * check nearby sequence numbers in debug mode
3587348SJose.Borrego@Sun.COM 		 */
359*12508Samw@Sun.COM 		SMB_CHECK_SEQNUM(sr->sr_seqnum, sign, &command,
360*12508Samw@Sun.COM 		    mac_sig, sr->smb_sig, &found);
3617348SJose.Borrego@Sun.COM 		if (found == B_FALSE)
3625331Samw 			rtn = -1;
3635331Samw 	}
3645331Samw 	return (rtn);
3655331Samw }
3665331Samw 
3675331Samw /*
3685331Samw  * smb_sign_check_secondary
3695331Samw  *
3705331Samw  * Calculates MAC signature for the secondary transaction mbuf chain
3715331Samw  * and compares it to the given signature.
3725331Samw  * Return 0 if the signature verifies, otherwise, returns -1;
3735331Samw  *
3745331Samw  */
3755331Samw int
smb_sign_check_secondary(smb_request_t * sr,unsigned int reply_seqnum)3766139Sjb150015 smb_sign_check_secondary(smb_request_t *sr, unsigned int reply_seqnum)
3775331Samw {
3786139Sjb150015 	struct mbuf_chain command = sr->command;
3795331Samw 	unsigned char mac_sig[SMB_SIG_SIZE];
3806139Sjb150015 	struct smb_sign *sign = &sr->session->signing;
3815331Samw 	int rtn = 0;
3825331Samw 
3837348SJose.Borrego@Sun.COM 	/* Reset the offset to begining of header */
3847348SJose.Borrego@Sun.COM 	command.chain_offset = sr->orig_request_hdr;
3855331Samw 
3867348SJose.Borrego@Sun.COM 	/* calculate mac signature */
3877348SJose.Borrego@Sun.COM 	if (smb_sign_calc(&command, sign, reply_seqnum - 1,
3887348SJose.Borrego@Sun.COM 	    mac_sig) != 0)
3897348SJose.Borrego@Sun.COM 		return (-1);
3905331Samw 
3915331Samw 
3927348SJose.Borrego@Sun.COM 	/* compare the signatures */
3937348SJose.Borrego@Sun.COM 	if (memcmp(mac_sig, sr->smb_sig, SMB_SIG_SIZE) != 0) {
3947348SJose.Borrego@Sun.COM 		cmn_err(CE_WARN, "SmbSignCheckSecond: bad signature");
3957348SJose.Borrego@Sun.COM 		rtn = -1;
3965331Samw 	}
3975331Samw 	/* Save the reply sequence number */
3986139Sjb150015 	sr->reply_seqnum = reply_seqnum;
3995331Samw 
4005331Samw 	return (rtn);
4015331Samw }
4025331Samw 
4035331Samw /*
4045331Samw  * smb_sign_reply
4055331Samw  *
4065331Samw  * Calculates MAC signature for the given mbuf chain,
4075331Samw  * and write it to the signature field in the mbuf.
4085331Samw  *
4095331Samw  */
4105331Samw void
smb_sign_reply(smb_request_t * sr,struct mbuf_chain * reply)4116139Sjb150015 smb_sign_reply(smb_request_t *sr, struct mbuf_chain *reply)
4125331Samw {
4135331Samw 	struct mbuf_chain resp;
4146139Sjb150015 	struct smb_sign *sign = &sr->session->signing;
4155331Samw 	unsigned char signature[SMB_SIG_SIZE];
4165331Samw 	struct mbuf *mbuf;
4175331Samw 	int size = SMB_SIG_SIZE;
4185331Samw 	unsigned char *sig_ptr = signature;
4195331Samw 	int offset = 0;
4205331Samw 
4215331Samw 	if (reply)
4225331Samw 		resp = *reply;
4235331Samw 	else
4246139Sjb150015 		resp = sr->reply;
4255331Samw 
4265331Samw 	/* Reset offset to start of reply */
4275331Samw 	resp.chain_offset = 0;
4285331Samw 	mbuf = resp.chain;
4295331Samw 
4305331Samw 	/*
4315331Samw 	 * Calculate MAC signature
4325331Samw 	 */
433*12508Samw@Sun.COM 	if (smb_sign_calc(&resp, sign, sr->reply_seqnum, signature) != 0) {
434*12508Samw@Sun.COM 		cmn_err(CE_WARN, "smb_sign_reply: error in smb_sign_calc");
4355331Samw 		return;
436*12508Samw@Sun.COM 	}
4375331Samw 
4385331Samw 	/*
4395331Samw 	 * Put signature in the response
4405331Samw 	 *
4415331Samw 	 * First find start of signature in chain (offset + signature offset)
4425331Samw 	 */
4435331Samw 	offset += SMB_SIG_OFFS;
4445331Samw 	while (offset >= mbuf->m_len) {
4455331Samw 		offset -= mbuf->m_len;
4465331Samw 		mbuf = mbuf->m_next;
4475331Samw 	}
4485331Samw 
4495331Samw 	while (size >= mbuf->m_len - offset) {
4505331Samw 		(void) memcpy(&mbuf->m_data[offset],
4515331Samw 		    sig_ptr, mbuf->m_len - offset);
4525331Samw 		offset = 0;
4535331Samw 		sig_ptr += mbuf->m_len - offset;
4545331Samw 		size -= mbuf->m_len - offset;
4555331Samw 		mbuf = mbuf->m_next;
4565331Samw 	}
4575331Samw 	if (size > 0) {
4585331Samw 		(void) memcpy(&mbuf->m_data[offset], sig_ptr, size);
4595331Samw 	}
4605331Samw }
461