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. 24*a5a9a6bbSGordon 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; 64c8ec8eeaSjose borrego 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 7012b65585SGordon Ross smb_sign_find_seqnum( 7112b65585SGordon Ross smb_request_t *sr, 7212b65585SGordon Ross struct mbuf_chain *mbc, 7312b65585SGordon Ross unsigned char *mac_sig, 7412b65585SGordon Ross unsigned char *sr_sig) 7512b65585SGordon Ross { 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); 82c8ec8eeaSjose borrego if (memcmp(mac_sig, sr_sig, SMB_SIG_SIZE) == 0) { 8312b65585SGordon Ross goto found; 84c8ec8eeaSjose borrego } 8512b65585SGordon Ross t = sr->sr_seqnum - i; 8612b65585SGordon Ross (void) smb_sign_calc(sr, mbc, t, mac_sig); 8712b65585SGordon Ross if (memcmp(mac_sig, sr_sig, SMB_SIG_SIZE) == 0) { 8812b65585SGordon Ross goto found; 89c8ec8eeaSjose borrego } 9012b65585SGordon Ross } 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 1028622ec45SGordon Ross /* 103b819cea2SGordon Ross * Called during session destroy. 1048622ec45SGordon Ross */ 105b819cea2SGordon Ross static void 106b819cea2SGordon Ross smb_sign_fini(smb_session_t *s) 107b819cea2SGordon 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 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 132da6c28aaSamw /* 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 14112b65585SGordon Ross /* 142b819cea2SGordon Ross * Session-level initialization (once per session) 143da6c28aaSamw */ 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; 188faa1795aSjb150015 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 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 239da6c28aaSamw /* 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. 245da6c28aaSamw */ 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; 258da6c28aaSamw 25912b65585SGordon Ross if (s->sign_mech == NULL || sign->mackey == NULL) 260da6c28aaSamw return (-1); 261da6c28aaSamw 26212b65585SGordon Ross if ((rc = smb_md5_init(&ctx, s->sign_mech)) != 0) 263b819cea2SGordon Ross return (rc); 264b819cea2SGordon Ross 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); 269b819cea2SGordon Ross 270b819cea2SGordon Ross /* 271b819cea2SGordon Ross * Make an aligned copy of the SMB header, 272b819cea2SGordon Ross * fill in the sequence number, and digest. 273b819cea2SGordon Ross */ 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; 280b819cea2SGordon Ross 281b819cea2SGordon Ross rc = smb_md5_update(ctx, &smbhdr.r.raw, size); 282b819cea2SGordon Ross if (rc != 0) 283b819cea2SGordon Ross return (rc); 284b819cea2SGordon Ross 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)) { 291b819cea2SGordon Ross offset -= mbuf->m_len; 292b819cea2SGordon Ross mbuf = mbuf->m_next; 293b819cea2SGordon Ross } 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); 298b819cea2SGordon Ross offset = 0; 299b819cea2SGordon Ross mbuf = mbuf->m_next; 300b819cea2SGordon Ross } 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); 305b819cea2SGordon Ross mbuf = mbuf->m_next; 306b819cea2SGordon Ross } 307b819cea2SGordon Ross rc = smb_md5_final(ctx, digest); 308b819cea2SGordon Ross if (rc == 0) 309b819cea2SGordon Ross bcopy(digest, mac_sign, SMB_SIG_SIZE); 310b819cea2SGordon Ross 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 329faa1795aSjb150015 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 */ 338faa1795aSjb150015 if (sr->smb_com == SMB_COM_TRANSACTION_SECONDARY || 339faa1795aSjb150015 sr->smb_com == SMB_COM_TRANSACTION2_SECONDARY || 340faa1795aSjb150015 sr->smb_com == SMB_COM_NT_TRANSACT_SECONDARY) 341da6c28aaSamw return (0); 342da6c28aaSamw 343da6c28aaSamw /* Reset the offset to begining of header */ 34412b65585SGordon Ross mbc.chain_offset = sr->orig_request_hdr; 345da6c28aaSamw 346da6c28aaSamw /* calculate mac signature */ 34712b65585SGordon Ross if (smb_sign_calc(sr, &mbc, sr->sr_seqnum, mac_sig) != 0) 348da6c28aaSamw return (-1); 349da6c28aaSamw 350da6c28aaSamw /* 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*a5a9a6bbSGordon Ross DTRACE_PROBE2(smb__signature__mismatch, smb_request_t *, sr, 35712b65585SGordon Ross unsigned char *, mac_sig); 358148c5f43SAlan Wright cmn_err(CE_NOTE, "smb_sign_check_request: bad signature"); 35912b65585SGordon Ross 360c8ec8eeaSjose borrego /* 361c8ec8eeaSjose borrego * check nearby sequence numbers in debug mode 362c8ec8eeaSjose borrego */ 363b819cea2SGordon Ross #ifdef DEBUG 36412b65585SGordon Ross if (smb_sign_debug) { 36512b65585SGordon Ross return (smb_sign_find_seqnum(sr, &mbc, mac_sig, sr->smb_sig)); 366da6c28aaSamw } 36712b65585SGordon Ross #endif 36812b65585SGordon Ross return (-1); 369da6c28aaSamw } 370da6c28aaSamw 371da6c28aaSamw /* 372da6c28aaSamw * smb_sign_check_secondary 373da6c28aaSamw * 374da6c28aaSamw * Calculates MAC signature for the secondary transaction mbuf chain 375da6c28aaSamw * and compares it to the given signature. 376da6c28aaSamw * Return 0 if the signature verifies, otherwise, returns -1; 377da6c28aaSamw * 378da6c28aaSamw */ 379da6c28aaSamw int 380faa1795aSjb150015 smb_sign_check_secondary(smb_request_t *sr, unsigned int reply_seqnum) 381da6c28aaSamw { 38212b65585SGordon Ross struct mbuf_chain mbc = sr->command; 383da6c28aaSamw unsigned char mac_sig[SMB_SIG_SIZE]; 384da6c28aaSamw int rtn = 0; 385da6c28aaSamw 386da6c28aaSamw /* Reset the offset to begining of header */ 38712b65585SGordon Ross mbc.chain_offset = sr->orig_request_hdr; 388da6c28aaSamw 389da6c28aaSamw /* calculate mac signature */ 39012b65585SGordon Ross if (smb_sign_calc(sr, &mbc, reply_seqnum - 1, mac_sig) != 0) 391da6c28aaSamw return (-1); 392da6c28aaSamw 393da6c28aaSamw 394da6c28aaSamw /* compare the signatures */ 395faa1795aSjb150015 if (memcmp(mac_sig, sr->smb_sig, SMB_SIG_SIZE) != 0) { 396da6c28aaSamw cmn_err(CE_WARN, "SmbSignCheckSecond: bad signature"); 397da6c28aaSamw rtn = -1; 398da6c28aaSamw } 399da6c28aaSamw /* Save the reply sequence number */ 400faa1795aSjb150015 sr->reply_seqnum = reply_seqnum; 401da6c28aaSamw 402da6c28aaSamw return (rtn); 403da6c28aaSamw } 404da6c28aaSamw 405da6c28aaSamw /* 406da6c28aaSamw * smb_sign_reply 407da6c28aaSamw * 408da6c28aaSamw * Calculates MAC signature for the given mbuf chain, 409da6c28aaSamw * and write it to the signature field in the mbuf. 410da6c28aaSamw * 411da6c28aaSamw */ 412da6c28aaSamw void 413faa1795aSjb150015 smb_sign_reply(smb_request_t *sr, struct mbuf_chain *reply) 414da6c28aaSamw { 41512b65585SGordon Ross struct mbuf_chain mbc; 41612b65585SGordon Ross unsigned char mac[SMB_SIG_SIZE]; 417da6c28aaSamw 418da6c28aaSamw if (reply) 41912b65585SGordon Ross mbc = *reply; 420da6c28aaSamw else 42112b65585SGordon Ross mbc = sr->reply; 422da6c28aaSamw 423da6c28aaSamw /* Reset offset to start of reply */ 42412b65585SGordon Ross mbc.chain_offset = 0; 425da6c28aaSamw 426da6c28aaSamw /* 427da6c28aaSamw * Calculate MAC signature 428da6c28aaSamw */ 42912b65585SGordon Ross if (smb_sign_calc(sr, &mbc, sr->reply_seqnum, mac) != 0) { 430148c5f43SAlan Wright cmn_err(CE_WARN, "smb_sign_reply: error in smb_sign_calc"); 431da6c28aaSamw return; 432148c5f43SAlan Wright } 433da6c28aaSamw 434da6c28aaSamw /* 435da6c28aaSamw * Put signature in the response 436da6c28aaSamw */ 43712b65585SGordon Ross (void) smb_mbc_poke(&mbc, SMB_SIG_OFFS, "#c", 43812b65585SGordon Ross SMB_SIG_SIZE, mac); 439da6c28aaSamw } 440