/*
* 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
*/
/*
*/
/*
* Support for SMB "signing" (message integrity)
*/
#include <netsmb/smb_osdep.h>
#include <netsmb/smb_conn.h>
#include <netsmb/smb_subr.h>
#ifdef DEBUG
/*
* Set this to a small number to debug sequence numbers
* that seem to get out of step.
*/
int nsmb_signing_fudge = 0;
#endif
/* Mechanism definitions */
void
smb_crypto_mech_init(void)
{
}
/*
* Compute HMAC-MD5 of packet data, using the stored MAC key.
*
* See similar code for the server side:
* uts/common/fs/smbsrv/smb_signing.c : smb_sign_calc
*/
static int
{
int status;
/*
* This union is a little bit of trickery to:
* (1) get the sequence number int aligned, and
* (2) reduce the number of digest calls, at the
* cost of a copying 32 bytes instead of 8.
* Both sides of this union are 2+32 bytes.
*/
union {
struct {
} r;
struct {
} s;
} smbhdr;
/*
* Make an aligned copy of the SMB header
* and fill in the sequence number.
*/
/*
* Compute the MAC: MD5(concat(Key, message))
*/
SMBSDEBUG("crypto_mech_md5 invalid\n");
return (CRYPTO_MECHANISM_INVALID);
}
if (status != CRYPTO_SUCCESS)
return (status);
/* Digest the MAC Key */
key.cd_miscdata = 0;
if (status != CRYPTO_SUCCESS)
return (status);
/* Digest the (copied) SMB header */
data.cd_miscdata = 0;
if (status != CRYPTO_SUCCESS)
return (status);
/* Digest rest of the SMB message. */
data.cd_miscdata = 0;
if (status != CRYPTO_SUCCESS)
return (status);
/* Final */
digest.cd_miscdata = 0;
if (status != CRYPTO_SUCCESS)
return (status);
/*
* Finally, store the signature.
* (first 8 bytes of the mac)
*/
if (signature)
return (0);
}
/*
* Sign a request with HMAC-MD5.
*/
void
{
int status;
/*
* Our mblk allocation ensures this,
* but just in case...
*/
return;
}
/*
* Signing is required, but we have no key yet
* fill in with the magic fake signing value.
* This happens with SPNEGO, NTLMSSP, ...
*/
return;
}
/*
* This will compute the MAC and store it
* directly into the message at sigloc.
*/
if (status != CRYPTO_SUCCESS) {
}
}
/*
* Verify reply signature.
*/
int
{
/*
* Note vc_mackey and vc_mackeylen gets filled in by
* smb_usr_iod_work as the connection comes in.
*/
SMBSDEBUG("no mac key\n");
return (0);
}
/*
* Let caller deal with empty reply or short messages by
* returning zero. Caller will fail later, in parsing.
*/
SMBSDEBUG("empty reply\n");
return (0);
}
return (0);
}
/*
* Compute the expected signature in sigbuf.
*/
if (status != CRYPTO_SUCCESS) {
/*
* If we can't compute a MAC, then there's
* no point trying other seqno values.
*/
return (EBADRPC);
}
/*
* Compare the computed signature with the
* one found in the message (at sigloc)
*/
return (0);
SMBERROR("BAD signature, Server=%s MID=0x%x Seq=%d\n",
#ifdef DEBUG
/*
* of the sequence # has gotten a bit out of sync.
*/
break;
break;
}
}
if (fudge <= nsmb_signing_fudge) {
SMBERROR("MID=0x%x, Seq=%d, but %d would have worked\n",
}
#endif
return (EBADRPC);
}