smb_signing.c revision e8e4e80fe335862e1a369070e9acaa2060866c90
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "@(#)smb_signing.c 1.4 08/07/08 SMI"
/*
* These routines provide the SMB MAC signing for the SMB server.
* The routines calculate the signature of a SMB message in an mbuf chain.
*
* The following table describes the client server
* signing registry relationship
*
* | Required | Enabled | Disabled
* -------------+---------------+------------ +--------------
* Required | Signed | Signed | Fail
* -------------+---------------+-------------+-----------------
* Enabled | Signed | Signed | Not Signed
* -------------+---------------+-------------+----------------
* Disabled | Fail | Not Signed | Not Signed
*/
#include <smbsrv/smb_incl.h>
#define SMBAUTH_SESSION_KEY_SZ 16
#define SMB_SIG_SIZE 8
#define SMB_SIG_OFFS 14
int
unsigned char *mac_sign);
#ifdef DEBUG
void smb_sign_find_seqnum(
struct mbuf_chain *command,
unsigned char *mac_sig,
unsigned char *sr_sig,
{ \
if (smb_sign_debug) \
}
#else
{ }
#endif
#ifdef DEBUG
void
struct mbuf_chain *command,
unsigned char *mac_sig,
unsigned char *sr_sig,
{
int start_seqnum;
int i;
/* Debug code to hunt for the sequence number */
if (start_seqnum < 0)
start_seqnum = 0;
break;
}
}
}
#endif
/* This holds the MD5 mechanism */
/*
* smb_sign_init
*
* Intializes MAC key based on the user session key and
* NTLM response and store it in the signing structure.
*/
void
{
/*
* Initialise the crypto mechanism to MD5 if it not
* already initialised.
*/
/*
* There is no MD5 crypto mechanism
* so turn off signing
*/
"SmbSignInit: signing disabled (no MD5)");
return;
}
}
/* MAC key = concat (SessKey, NTLMResponse) */
resp_len);
}
/*
* smb_sign_calc
*
* Calculates MAC signature for the given buffer and returns
* it in the mac_sign parameter.
*
* The sequence number is placed in the first four bytes of the signature
* field of the signature and the other 4 bytes are zeroed.
* The signature is the first 8 bytes of the MD5 result of the
* concatenated MAC key and the SMB message.
*
* MACsig = head(MD5(concat(MACKey, SMBMsg)), 8)
*
* where
*
* MACKey = concat( UserSessionKey, NTLMResp )
*
* and
*
* SMBMsg is the SMB message containing the sequence number.
*
* Return 0 if success else -1
*
*/
int
unsigned char *mac_sign)
{
unsigned char mac[16];
int size;
int status;
data.cd_miscdata = 0;
digest.cd_miscdata = 0;
if (status != CRYPTO_SUCCESS)
goto error;
/*
* Put the sequence number into the first 4 bytes
* of the signature field in little endian format.
* We are using a buffer to represent the signature
* rather than modifying the SMB message.
*/
#ifdef __sparc
{
}
#else
#endif
/* Digest the MACKey */
if (status != CRYPTO_SUCCESS)
goto error;
/* Find start of data in chain */
}
/* Digest the SMB packet up to the signature field */
size = SMB_SIG_OFFS;
if (status != CRYPTO_SUCCESS)
goto error;
offset = 0;
}
if (size > 0) {
if (status != CRYPTO_SUCCESS)
goto error;
}
/*
* Digest in the seq_buf instead of the signature
* which has the sequence number
*/
if (status != CRYPTO_SUCCESS)
goto error;
/* Find the end of the signature field */
offset += SMB_SIG_SIZE;
}
/* Digest the rest of the SMB packet */
while (mbuf) {
if (status != CRYPTO_SUCCESS)
goto error;
offset = 0;
}
if (status != CRYPTO_SUCCESS)
goto error;
return (0);
return (-1);
}
/*
* smb_sign_check_request
*
* Calculates MAC signature for the request mbuf chain
* using the next expected sequence number and compares
* it to the given signature.
*
* Note it does not check the signature for secondary transactions
* as their sequence number is the same as the original request.
*
* Return 0 if the signature verifies, otherwise, returns -1;
*
*/
int
{
unsigned char mac_sig[SMB_SIG_SIZE];
int rtn = 0;
/*
* Don't check secondary transactions - we dont know the sequence
* number.
*/
return (0);
/* Reset the offset to begining of header */
/* calculate mac signature */
return (-1);
/* compare the signatures */
/*
* check nearby sequence numbers in debug mode
*/
rtn = -1;
}
/*
* Increment the sequence number for the reply, save the reply
* and set it for the next expect command.
* There is no reply for NT Cancel so just increment it for the
* next expected command.
*/
sr->reply_seqnum = 0;
else
return (rtn);
}
/*
* smb_sign_check_secondary
*
* Calculates MAC signature for the secondary transaction mbuf chain
* and compares it to the given signature.
* Return 0 if the signature verifies, otherwise, returns -1;
*
*/
int
{
unsigned char mac_sig[SMB_SIG_SIZE];
int rtn = 0;
/* Reset the offset to begining of header */
/* calculate mac signature */
mac_sig) != 0)
return (-1);
/* compare the signatures */
rtn = -1;
}
/* Save the reply sequence number */
return (rtn);
}
/*
* smb_sign_reply
*
* Calculates MAC signature for the given mbuf chain,
* and write it to the signature field in the mbuf.
*
*/
void
{
struct mbuf_chain resp;
unsigned char signature[SMB_SIG_SIZE];
int size = SMB_SIG_SIZE;
int offset = 0;
if (reply)
else
/* Reset offset to start of reply */
resp.chain_offset = 0;
/*
* Calculate MAC signature
*/
return;
/*
* Put signature in the response
*
* First find start of signature in chain (offset + signature offset)
*/
offset += SMB_SIG_OFFS;
}
offset = 0;
}
if (size > 0) {
}
}