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. 23b819cea2SGordon Ross * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 24da6c28aaSamw */ 25da6c28aaSamw /* 26da6c28aaSamw * These routines provide the SMB MAC signing for the SMB server. 27da6c28aaSamw * The routines calculate the signature of a SMB message in an mbuf chain. 28da6c28aaSamw * 29c8ec8eeaSjose borrego * The following table describes the client server 30c8ec8eeaSjose borrego * signing registry relationship 31c8ec8eeaSjose borrego * 32c8ec8eeaSjose borrego * | Required | Enabled | Disabled 33c8ec8eeaSjose borrego * -------------+---------------+------------ +-------------- 34c8ec8eeaSjose borrego * Required | Signed | Signed | Fail 35c8ec8eeaSjose borrego * -------------+---------------+-------------+----------------- 36c8ec8eeaSjose borrego * Enabled | Signed | Signed | Not Signed 37c8ec8eeaSjose borrego * -------------+---------------+-------------+---------------- 38c8ec8eeaSjose borrego * Disabled | Fail | Not Signed | Not Signed 39da6c28aaSamw */ 40da6c28aaSamw 41da6c28aaSamw #include <sys/uio.h> 42bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h> 43b819cea2SGordon Ross #include <smbsrv/smb_signing.h> 44b819cea2SGordon Ross #include <sys/isa_defs.h> 45b819cea2SGordon Ross #include <sys/byteorder.h> 46da6c28aaSamw 47da6c28aaSamw #define SMB_SIG_SIZE 8 48da6c28aaSamw #define SMB_SIG_OFFS 14 49b819cea2SGordon Ross #define SMB_HDRLEN 32 50b819cea2SGordon Ross 51b819cea2SGordon Ross #ifdef _LITTLE_ENDIAN 52b819cea2SGordon Ross #define htolel(x) ((uint32_t)(x)) 53b819cea2SGordon Ross #else 54b819cea2SGordon Ross #define htolel(x) BSWAP_32(x) 55b819cea2SGordon Ross #endif 56da6c28aaSamw 57*12b65585SGordon Ross static int 58*12b65585SGordon Ross smb_sign_calc(smb_request_t *sr, struct mbuf_chain *mbc, 59*12b65585SGordon Ross uint32_t seqnum, unsigned char *sig); 60c8ec8eeaSjose borrego 61c8ec8eeaSjose borrego #ifdef DEBUG 62*12b65585SGordon Ross uint32_t smb_sign_debug_search = 10; 63c8ec8eeaSjose borrego 64*12b65585SGordon Ross /* 65*12b65585SGordon Ross * Debug code to search +/- for the correct sequence number. 66*12b65585SGordon Ross * If found, correct sign->seqnum and return 0, else return -1 67*12b65585SGordon Ross */ 68*12b65585SGordon Ross static int 69*12b65585SGordon Ross smb_sign_find_seqnum( 70*12b65585SGordon Ross smb_request_t *sr, 71*12b65585SGordon Ross struct mbuf_chain *mbc, 72*12b65585SGordon Ross unsigned char *mac_sig, 73*12b65585SGordon Ross unsigned char *sr_sig) 74*12b65585SGordon Ross { 75*12b65585SGordon Ross struct smb_sign *sign = &sr->session->signing; 76*12b65585SGordon Ross uint32_t i, t; 77*12b65585SGordon Ross 78*12b65585SGordon Ross for (i = 1; i < smb_sign_debug_search; i++) { 79*12b65585SGordon Ross t = sr->sr_seqnum + i; 80*12b65585SGordon Ross (void) smb_sign_calc(sr, mbc, t, mac_sig); 81c8ec8eeaSjose borrego if (memcmp(mac_sig, sr_sig, SMB_SIG_SIZE) == 0) { 82*12b65585SGordon Ross goto found; 83c8ec8eeaSjose borrego } 84*12b65585SGordon Ross t = sr->sr_seqnum - i; 85*12b65585SGordon Ross (void) smb_sign_calc(sr, mbc, t, mac_sig); 86*12b65585SGordon Ross if (memcmp(mac_sig, sr_sig, SMB_SIG_SIZE) == 0) { 87*12b65585SGordon Ross goto found; 88c8ec8eeaSjose borrego } 89*12b65585SGordon Ross } 90*12b65585SGordon Ross cmn_err(CE_WARN, "smb_sign_find_seqnum: failed after %d", i); 91*12b65585SGordon Ross return (-1); 92*12b65585SGordon Ross 93*12b65585SGordon Ross found: 94*12b65585SGordon Ross cmn_err(CE_WARN, "smb_sign_find_seqnum: found! %d <- %d", 95*12b65585SGordon Ross sign->seqnum, t); 96*12b65585SGordon Ross sign->seqnum = t; 97*12b65585SGordon Ross return (0); 98c8ec8eeaSjose borrego } 99c8ec8eeaSjose borrego #endif 100148c5f43SAlan Wright 1018622ec45SGordon Ross /* 102b819cea2SGordon Ross * Called during session destroy. 1038622ec45SGordon Ross */ 104b819cea2SGordon Ross static void 105b819cea2SGordon Ross smb_sign_fini(smb_session_t *s) 106b819cea2SGordon Ross { 107b819cea2SGordon Ross smb_sign_mech_t *mech; 108b819cea2SGordon Ross 109*12b65585SGordon Ross if ((mech = s->sign_mech) != NULL) { 110b819cea2SGordon Ross kmem_free(mech, sizeof (*mech)); 111*12b65585SGordon Ross s->sign_mech = NULL; 1128622ec45SGordon Ross } 1138622ec45SGordon Ross } 1148622ec45SGordon Ross 115da6c28aaSamw /* 116b819cea2SGordon Ross * smb_sign_begin 117da6c28aaSamw * 118da6c28aaSamw * Intializes MAC key based on the user session key and 119da6c28aaSamw * NTLM response and store it in the signing structure. 120b819cea2SGordon Ross * This is what begins SMB signing. 121da6c28aaSamw */ 122b819cea2SGordon Ross int 123b819cea2SGordon Ross smb_sign_begin(smb_request_t *sr, smb_token_t *token) 124da6c28aaSamw { 125b819cea2SGordon Ross smb_arg_sessionsetup_t *sinfo = sr->sr_ssetup; 126b819cea2SGordon Ross smb_session_t *session = sr->session; 127b819cea2SGordon Ross struct smb_sign *sign = &session->signing; 128b819cea2SGordon Ross smb_sign_mech_t *mech; 129b819cea2SGordon Ross int rc; 130da6c28aaSamw 131da6c28aaSamw /* 132*12b65585SGordon Ross * We should normally have a session key here because 133*12b65585SGordon Ross * our caller filters out Anonymous and Guest logons. 134*12b65585SGordon Ross * However, buggy clients could get us here without a 135*12b65585SGordon Ross * session key, in which case: just don't sign. 136*12b65585SGordon Ross */ 137*12b65585SGordon Ross if (token->tkn_ssnkey.val == NULL || token->tkn_ssnkey.len == 0) 138*12b65585SGordon Ross return (0); 139*12b65585SGordon Ross 140*12b65585SGordon Ross /* 141b819cea2SGordon Ross * Session-level initialization (once per session) 142da6c28aaSamw */ 143b819cea2SGordon Ross smb_rwx_rwenter(&session->s_lock, RW_WRITER); 144b819cea2SGordon Ross 145b819cea2SGordon Ross /* 146b819cea2SGordon Ross * Signing may already have been setup by a prior logon, 147b819cea2SGordon Ross * in which case we're done here. 148b819cea2SGordon Ross */ 149b819cea2SGordon Ross if (sign->mackey != NULL) { 150b819cea2SGordon Ross smb_rwx_rwexit(&session->s_lock); 151b819cea2SGordon Ross return (0); 152da6c28aaSamw } 153da6c28aaSamw 154b819cea2SGordon Ross /* 155b819cea2SGordon Ross * Get the mech handle 156b819cea2SGordon Ross */ 157*12b65585SGordon Ross if (session->sign_mech == NULL) { 158b819cea2SGordon Ross mech = kmem_zalloc(sizeof (*mech), KM_SLEEP); 159b819cea2SGordon Ross rc = smb_md5_getmech(mech); 160b819cea2SGordon Ross if (rc != 0) { 161b819cea2SGordon Ross kmem_free(mech, sizeof (*mech)); 162b819cea2SGordon Ross smb_rwx_rwexit(&session->s_lock); 163b819cea2SGordon Ross return (rc); 164b819cea2SGordon Ross } 165*12b65585SGordon Ross session->sign_mech = mech; 166b819cea2SGordon Ross session->sign_fini = smb_sign_fini; 167b819cea2SGordon Ross } 168da6c28aaSamw 169b819cea2SGordon Ross /* 170b819cea2SGordon Ross * Compute and store the signing (MAC) key. 171b819cea2SGordon Ross * 172b819cea2SGordon Ross * With extended security, the MAC key is the same as the 173*12b65585SGordon Ross * session key (and we'll have sinfo->ssi_ntpwlen == 0). 174b819cea2SGordon Ross * With non-extended security, it's the concatenation of 175b819cea2SGordon Ross * the session key and the "NT response" we received. 176b819cea2SGordon Ross */ 177*12b65585SGordon Ross sign->mackey_len = token->tkn_ssnkey.len + sinfo->ssi_ntpwlen; 178b819cea2SGordon Ross sign->mackey = kmem_alloc(sign->mackey_len, KM_SLEEP); 179*12b65585SGordon Ross bcopy(token->tkn_ssnkey.val, sign->mackey, token->tkn_ssnkey.len); 180*12b65585SGordon Ross if (sinfo->ssi_ntpwlen > 0) { 181*12b65585SGordon Ross bcopy(sinfo->ssi_ntpwd, sign->mackey + token->tkn_ssnkey.len, 182*12b65585SGordon Ross sinfo->ssi_ntpwlen); 183b819cea2SGordon Ross } 184da6c28aaSamw 185b819cea2SGordon Ross session->signing.seqnum = 0; 186148c5f43SAlan Wright sr->sr_seqnum = 2; 187faa1795aSjb150015 sr->reply_seqnum = 1; 188b819cea2SGordon Ross sign->flags = 0; 189b819cea2SGordon Ross 190b819cea2SGordon Ross if (session->secmode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) { 191b819cea2SGordon Ross sign->flags |= SMB_SIGNING_ENABLED; 192b819cea2SGordon Ross if (session->secmode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) 193b819cea2SGordon Ross sign->flags |= SMB_SIGNING_CHECK; 194b819cea2SGordon Ross } 195b819cea2SGordon Ross 196b819cea2SGordon Ross smb_rwx_rwexit(&session->s_lock); 197b819cea2SGordon Ross return (0); 198da6c28aaSamw } 199da6c28aaSamw 200da6c28aaSamw /* 201da6c28aaSamw * smb_sign_calc 202da6c28aaSamw * 203da6c28aaSamw * Calculates MAC signature for the given buffer and returns 204da6c28aaSamw * it in the mac_sign parameter. 205da6c28aaSamw * 206da6c28aaSamw * The sequence number is placed in the first four bytes of the signature 207da6c28aaSamw * field of the signature and the other 4 bytes are zeroed. 208da6c28aaSamw * The signature is the first 8 bytes of the MD5 result of the 209da6c28aaSamw * concatenated MAC key and the SMB message. 210da6c28aaSamw * 211da6c28aaSamw * MACsig = head(MD5(concat(MACKey, SMBMsg)), 8) 212da6c28aaSamw * 213da6c28aaSamw * where 214da6c28aaSamw * 215da6c28aaSamw * MACKey = concat( UserSessionKey, NTLMResp ) 216da6c28aaSamw * 217da6c28aaSamw * and 218da6c28aaSamw * 219da6c28aaSamw * SMBMsg is the SMB message containing the sequence number. 220da6c28aaSamw * 221b819cea2SGordon Ross * Return 0 if success 222da6c28aaSamw * 223da6c28aaSamw */ 224*12b65585SGordon Ross static int 225*12b65585SGordon Ross smb_sign_calc(smb_request_t *sr, struct mbuf_chain *mbc, 226*12b65585SGordon Ross uint32_t seqnum, unsigned char *mac_sign) 227da6c28aaSamw { 228*12b65585SGordon Ross smb_session_t *s = sr->session; 229*12b65585SGordon Ross struct smb_sign *sign = &s->signing; 230b819cea2SGordon Ross smb_sign_ctx_t ctx = 0; 231b819cea2SGordon Ross uchar_t digest[MD5_DIGEST_LENGTH]; 232b819cea2SGordon Ross uchar_t *hdrp; 233da6c28aaSamw struct mbuf *mbuf = mbc->chain; 234da6c28aaSamw int offset = mbc->chain_offset; 235da6c28aaSamw int size; 236b819cea2SGordon Ross int rc; 237da6c28aaSamw 238da6c28aaSamw /* 239b819cea2SGordon Ross * This union is a little bit of trickery to: 240b819cea2SGordon Ross * (1) get the sequence number int aligned, and 241b819cea2SGordon Ross * (2) reduce the number of digest calls, at the 242b819cea2SGordon Ross * cost of a copying 32 bytes instead of 8. 243b819cea2SGordon Ross * Both sides of this union are 2+32 bytes. 244da6c28aaSamw */ 245b819cea2SGordon Ross union { 246b819cea2SGordon Ross struct { 247b819cea2SGordon Ross uint8_t skip[2]; /* not used - just alignment */ 248b819cea2SGordon Ross uint8_t raw[SMB_HDRLEN]; /* header length (32) */ 249b819cea2SGordon Ross } r; 250b819cea2SGordon Ross struct { 251b819cea2SGordon Ross uint8_t skip[2]; /* not used - just alignment */ 252b819cea2SGordon Ross uint8_t hdr[SMB_SIG_OFFS]; /* sig. offset (14) */ 253b819cea2SGordon Ross uint32_t sig[2]; /* MAC signature, aligned! */ 254b819cea2SGordon Ross uint16_t ids[5]; /* pad, Tid, Pid, Uid, Mid */ 255b819cea2SGordon Ross } s; 256b819cea2SGordon Ross } smbhdr; 257da6c28aaSamw 258*12b65585SGordon Ross if (s->sign_mech == NULL || sign->mackey == NULL) 259da6c28aaSamw return (-1); 260da6c28aaSamw 261*12b65585SGordon Ross if ((rc = smb_md5_init(&ctx, s->sign_mech)) != 0) 262b819cea2SGordon Ross return (rc); 263b819cea2SGordon Ross 264b819cea2SGordon Ross /* Digest the MAC Key */ 265b819cea2SGordon Ross rc = smb_md5_update(ctx, sign->mackey, sign->mackey_len); 266b819cea2SGordon Ross if (rc != 0) 267b819cea2SGordon Ross return (rc); 268b819cea2SGordon Ross 269b819cea2SGordon Ross /* 270b819cea2SGordon Ross * Make an aligned copy of the SMB header, 271b819cea2SGordon Ross * fill in the sequence number, and digest. 272b819cea2SGordon Ross */ 273b819cea2SGordon Ross hdrp = (unsigned char *)&smbhdr.r.raw; 274b819cea2SGordon Ross size = SMB_HDRLEN; 275b819cea2SGordon Ross if (smb_mbc_peek(mbc, offset, "#c", size, hdrp) != 0) 276b819cea2SGordon Ross return (-1); 277b819cea2SGordon Ross smbhdr.s.sig[0] = htolel(seqnum); 278b819cea2SGordon Ross smbhdr.s.sig[1] = 0; 279b819cea2SGordon Ross 280b819cea2SGordon Ross rc = smb_md5_update(ctx, &smbhdr.r.raw, size); 281b819cea2SGordon Ross if (rc != 0) 282b819cea2SGordon Ross return (rc); 283b819cea2SGordon Ross 284b819cea2SGordon Ross /* 285b819cea2SGordon Ross * Digest the rest of the SMB packet, starting at the data 286b819cea2SGordon Ross * just after the SMB header. 287b819cea2SGordon Ross */ 288b819cea2SGordon Ross offset += size; 289b819cea2SGordon Ross while (mbuf != NULL && (offset >= mbuf->m_len)) { 290b819cea2SGordon Ross offset -= mbuf->m_len; 291b819cea2SGordon Ross mbuf = mbuf->m_next; 292b819cea2SGordon Ross } 293b819cea2SGordon Ross if (mbuf != NULL && (size = (mbuf->m_len - offset)) > 0) { 294b819cea2SGordon Ross rc = smb_md5_update(ctx, &mbuf->m_data[offset], size); 295b819cea2SGordon Ross if (rc != 0) 296b819cea2SGordon Ross return (rc); 297b819cea2SGordon Ross offset = 0; 298b819cea2SGordon Ross mbuf = mbuf->m_next; 299b819cea2SGordon Ross } 300b819cea2SGordon Ross while (mbuf != NULL) { 301b819cea2SGordon Ross rc = smb_md5_update(ctx, mbuf->m_data, mbuf->m_len); 302b819cea2SGordon Ross if (rc != 0) 303b819cea2SGordon Ross return (rc); 304b819cea2SGordon Ross mbuf = mbuf->m_next; 305b819cea2SGordon Ross } 306b819cea2SGordon Ross rc = smb_md5_final(ctx, digest); 307b819cea2SGordon Ross if (rc == 0) 308b819cea2SGordon Ross bcopy(digest, mac_sign, SMB_SIG_SIZE); 309b819cea2SGordon Ross 310b819cea2SGordon Ross return (rc); 311da6c28aaSamw } 312da6c28aaSamw 313da6c28aaSamw 314da6c28aaSamw /* 315da6c28aaSamw * smb_sign_check_request 316da6c28aaSamw * 317da6c28aaSamw * Calculates MAC signature for the request mbuf chain 318da6c28aaSamw * using the next expected sequence number and compares 319da6c28aaSamw * it to the given signature. 320da6c28aaSamw * 321da6c28aaSamw * Note it does not check the signature for secondary transactions 322da6c28aaSamw * as their sequence number is the same as the original request. 323da6c28aaSamw * 324da6c28aaSamw * Return 0 if the signature verifies, otherwise, returns -1; 325da6c28aaSamw * 326da6c28aaSamw */ 327da6c28aaSamw int 328faa1795aSjb150015 smb_sign_check_request(smb_request_t *sr) 329da6c28aaSamw { 330*12b65585SGordon Ross struct mbuf_chain mbc = sr->command; 331da6c28aaSamw unsigned char mac_sig[SMB_SIG_SIZE]; 332148c5f43SAlan Wright 333da6c28aaSamw /* 334da6c28aaSamw * Don't check secondary transactions - we dont know the sequence 335da6c28aaSamw * number. 336da6c28aaSamw */ 337faa1795aSjb150015 if (sr->smb_com == SMB_COM_TRANSACTION_SECONDARY || 338faa1795aSjb150015 sr->smb_com == SMB_COM_TRANSACTION2_SECONDARY || 339faa1795aSjb150015 sr->smb_com == SMB_COM_NT_TRANSACT_SECONDARY) 340da6c28aaSamw return (0); 341da6c28aaSamw 342da6c28aaSamw /* Reset the offset to begining of header */ 343*12b65585SGordon Ross mbc.chain_offset = sr->orig_request_hdr; 344da6c28aaSamw 345da6c28aaSamw /* calculate mac signature */ 346*12b65585SGordon Ross if (smb_sign_calc(sr, &mbc, sr->sr_seqnum, mac_sig) != 0) 347da6c28aaSamw return (-1); 348da6c28aaSamw 349da6c28aaSamw /* compare the signatures */ 350*12b65585SGordon Ross if (memcmp(mac_sig, sr->smb_sig, SMB_SIG_SIZE) == 0) { 351*12b65585SGordon Ross /* They match! OK, we're done. */ 352*12b65585SGordon Ross return (0); 353*12b65585SGordon Ross } 354*12b65585SGordon Ross 355*12b65585SGordon Ross DTRACE_PROBE2(smb__signature__mismatch, smb_request_t, sr, 356*12b65585SGordon Ross unsigned char *, mac_sig); 357148c5f43SAlan Wright cmn_err(CE_NOTE, "smb_sign_check_request: bad signature"); 358*12b65585SGordon Ross 359c8ec8eeaSjose borrego /* 360c8ec8eeaSjose borrego * check nearby sequence numbers in debug mode 361c8ec8eeaSjose borrego */ 362b819cea2SGordon Ross #ifdef DEBUG 363*12b65585SGordon Ross if (smb_sign_debug) { 364*12b65585SGordon Ross return (smb_sign_find_seqnum(sr, &mbc, mac_sig, sr->smb_sig)); 365da6c28aaSamw } 366*12b65585SGordon Ross #endif 367*12b65585SGordon 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 379faa1795aSjb150015 smb_sign_check_secondary(smb_request_t *sr, unsigned int reply_seqnum) 380da6c28aaSamw { 381*12b65585SGordon Ross struct mbuf_chain mbc = sr->command; 382da6c28aaSamw unsigned char mac_sig[SMB_SIG_SIZE]; 383da6c28aaSamw int rtn = 0; 384da6c28aaSamw 385da6c28aaSamw /* Reset the offset to begining of header */ 386*12b65585SGordon Ross mbc.chain_offset = sr->orig_request_hdr; 387da6c28aaSamw 388da6c28aaSamw /* calculate mac signature */ 389*12b65585SGordon Ross if (smb_sign_calc(sr, &mbc, reply_seqnum - 1, mac_sig) != 0) 390da6c28aaSamw return (-1); 391da6c28aaSamw 392da6c28aaSamw 393da6c28aaSamw /* compare the signatures */ 394faa1795aSjb150015 if (memcmp(mac_sig, sr->smb_sig, SMB_SIG_SIZE) != 0) { 395da6c28aaSamw cmn_err(CE_WARN, "SmbSignCheckSecond: bad signature"); 396da6c28aaSamw rtn = -1; 397da6c28aaSamw } 398da6c28aaSamw /* Save the reply sequence number */ 399faa1795aSjb150015 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 412faa1795aSjb150015 smb_sign_reply(smb_request_t *sr, struct mbuf_chain *reply) 413da6c28aaSamw { 414*12b65585SGordon Ross struct mbuf_chain mbc; 415*12b65585SGordon Ross unsigned char mac[SMB_SIG_SIZE]; 416da6c28aaSamw 417da6c28aaSamw if (reply) 418*12b65585SGordon Ross mbc = *reply; 419da6c28aaSamw else 420*12b65585SGordon Ross mbc = sr->reply; 421da6c28aaSamw 422da6c28aaSamw /* Reset offset to start of reply */ 423*12b65585SGordon Ross mbc.chain_offset = 0; 424da6c28aaSamw 425da6c28aaSamw /* 426da6c28aaSamw * Calculate MAC signature 427da6c28aaSamw */ 428*12b65585SGordon 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 */ 436*12b65585SGordon Ross (void) smb_mbc_poke(&mbc, SMB_SIG_OFFS, "#c", 437*12b65585SGordon Ross SMB_SIG_SIZE, mac); 438da6c28aaSamw } 439