613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * CDDL HEADER START
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * The contents of this file are subject to the terms of the
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Common Development and Distribution License (the "License").
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * You may not use this file except in compliance with the License.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * or http://www.opensolaris.org/os/licensing.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * See the License for the specific language governing permissions
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * and limitations under the License.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * When distributing Covered Code, include this CDDL HEADER in each
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * If applicable, add the following below this CDDL HEADER, with the
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * fields enclosed by brackets "[]" replaced with your own identifying
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * information: Portions Copyright [yyyy] [name of copyright owner]
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * CDDL HEADER END
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross/*
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Support for SMB "signing" (message integrity)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/param.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/systm.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/conf.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/proc.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/fcntl.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/socket.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/md4.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/md5.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/des.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/kmem.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/crypto/api.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/crypto/common.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/cmn_err.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/stream.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/strsun.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/sdt.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <netsmb/smb_osdep.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <netsmb/smb.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <netsmb/smb_conn.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <netsmb/smb_subr.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <netsmb/smb_dev.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <netsmb/smb_rq.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#ifdef DEBUG
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Set this to a small number to debug sequence numbers
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * that seem to get out of step.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossint nsmb_signing_fudge = 0;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#endif
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross/* Mechanism definitions */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossstatic crypto_mechanism_t crypto_mech_md5 = { CRYPTO_MECH_INVALID };
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossvoid
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_crypto_mech_init(void)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross crypto_mech_md5.cm_type = crypto_mech2id(SUN_CKM_MD5);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross}
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#define SMBSIGLEN 8 /* SMB signature length */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#define SMBSIGOFF 14 /* SMB signature offset */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Compute HMAC-MD5 of packet data, using the stored MAC key.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * See similar code for the server side:
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * uts/common/fs/smbsrv/smb_signing.c : smb_sign_calc
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossstatic int
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_compute_MAC(struct smb_vc *vcp, mblk_t *mp,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross uint32_t seqno, uchar_t *signature)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross crypto_context_t crypto_ctx;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross crypto_data_t key;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross crypto_data_t data;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross crypto_data_t digest;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross uchar_t mac[16];
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross int status;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * This union is a little bit of trickery to:
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * (1) get the sequence number int aligned, and
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * (2) reduce the number of digest calls, at the
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * cost of a copying 32 bytes instead of 8.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Both sides of this union are 2+32 bytes.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross union {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross uint8_t skip[2]; /* not used - just alignment */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross uint8_t raw[SMB_HDRLEN]; /* header length (32) */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross } r;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross uint8_t skip[2]; /* not used - just alignment */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross uint8_t hdr[SMBSIGOFF]; /* sig. offset (14) */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross uint32_t sig[2]; /* MAC signature, aligned! */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross uint16_t ids[5]; /* pad, Tid, Pid, Uid, Mid */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross } s;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross } smbhdr;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross ASSERT(mp != NULL);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross ASSERT(MBLKL(mp) >= SMB_HDRLEN);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross ASSERT(vcp->vc_mackey != NULL);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Make an aligned copy of the SMB header
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * and fill in the sequence number.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross bcopy(mp->b_rptr, smbhdr.r.raw, SMB_HDRLEN);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smbhdr.s.sig[0] = htolel(seqno);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smbhdr.s.sig[1] = 0;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Compute the MAC: MD5(concat(Key, message))
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (crypto_mech_md5.cm_type == CRYPTO_MECH_INVALID) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMBSDEBUG("crypto_mech_md5 invalid\n");
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (CRYPTO_MECHANISM_INVALID);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross status = crypto_digest_init(&crypto_mech_md5, &crypto_ctx, 0);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (status != CRYPTO_SUCCESS)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (status);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* Digest the MAC Key */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross key.cd_format = CRYPTO_DATA_RAW;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross key.cd_offset = 0;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross key.cd_length = vcp->vc_mackeylen;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross key.cd_miscdata = 0;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross key.cd_raw.iov_base = (char *)vcp->vc_mackey;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross key.cd_raw.iov_len = vcp->vc_mackeylen;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross status = crypto_digest_update(crypto_ctx, &key, 0);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (status != CRYPTO_SUCCESS)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (status);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* Digest the (copied) SMB header */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross data.cd_format = CRYPTO_DATA_RAW;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross data.cd_offset = 0;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross data.cd_length = SMB_HDRLEN;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross data.cd_miscdata = 0;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross data.cd_raw.iov_base = (char *)smbhdr.r.raw;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross data.cd_raw.iov_len = SMB_HDRLEN;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross status = crypto_digest_update(crypto_ctx, &data, 0);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (status != CRYPTO_SUCCESS)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (status);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* Digest rest of the SMB message. */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross data.cd_format = CRYPTO_DATA_MBLK;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross data.cd_offset = SMB_HDRLEN;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross data.cd_length = msgdsize(mp) - SMB_HDRLEN;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross data.cd_miscdata = 0;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross data.cd_mp = mp;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross status = crypto_digest_update(crypto_ctx, &data, 0);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (status != CRYPTO_SUCCESS)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (status);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* Final */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross digest.cd_format = CRYPTO_DATA_RAW;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross digest.cd_offset = 0;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross digest.cd_length = sizeof (mac);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross digest.cd_miscdata = 0;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross digest.cd_raw.iov_base = (char *)mac;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross digest.cd_raw.iov_len = sizeof (mac);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross status = crypto_digest_final(crypto_ctx, &digest, 0);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (status != CRYPTO_SUCCESS)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (status);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Finally, store the signature.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * (first 8 bytes of the mac)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (signature)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross bcopy(mac, signature, SMBSIGLEN);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (0);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross}
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Sign a request with HMAC-MD5.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Rossvoid
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_rq_sign(struct smb_rq *rqp)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct smb_vc *vcp = rqp->sr_vc;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross mblk_t *mp = rqp->sr_rq.mb_top;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross uint8_t *sigloc;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross int status;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Our mblk allocation ensures this,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * but just in case...
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (MBLKL(mp) < SMB_HDRLEN) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (!pullupmsg(mp, SMB_HDRLEN))
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross return;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross sigloc = mp->b_rptr + SMBSIGOFF;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (vcp->vc_mackey == NULL) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Signing is required, but we have no key yet
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * fill in with the magic fake signing value.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * This happens with SPNEGO, NTLMSSP, ...
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross bcopy("BSRSPLY", sigloc, 8);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross return;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * This will compute the MAC and store it
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * directly into the message at sigloc.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross status = smb_compute_MAC(vcp, mp, rqp->sr_seqno, sigloc);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (status != CRYPTO_SUCCESS) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMBSDEBUG("Crypto error %d", status);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross bzero(sigloc, SMBSIGLEN);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross}
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Verify reply signature.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossint
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_rq_verify(struct smb_rq *rqp)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct smb_vc *vcp = rqp->sr_vc;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross mblk_t *mp = rqp->sr_rp.md_top;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross uint8_t sigbuf[SMBSIGLEN];
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross uint8_t *sigloc;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross int fudge, rsn, status;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Note vc_mackey and vc_mackeylen gets filled in by
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * smb_usr_iod_work as the connection comes in.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (vcp->vc_mackey == NULL) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMBSDEBUG("no mac key\n");
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (0);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Let caller deal with empty reply or short messages by
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * returning zero. Caller will fail later, in parsing.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (mp == NULL) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMBSDEBUG("empty reply\n");
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (0);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (MBLKL(mp) < SMB_HDRLEN) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (!pullupmsg(mp, SMB_HDRLEN))
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (0);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross sigloc = mp->b_rptr + SMBSIGOFF;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross /*
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross * Compute the expected signature in sigbuf.
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross rsn = rqp->sr_rseqno;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross status = smb_compute_MAC(vcp, mp, rsn, sigbuf);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (status != CRYPTO_SUCCESS) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMBSDEBUG("Crypto error %d", status);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * If we can't compute a MAC, then there's
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * no point trying other seqno values.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (EBADRPC);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Compare the computed signature with the
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * one found in the message (at sigloc)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (bcmp(sigbuf, sigloc, SMBSIGLEN) == 0)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (0);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross SMBERROR("BAD signature, Server=%s MID=0x%x Seq=%d\n",
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross vcp->vc_srvname, rqp->sr_mid, rsn);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#ifdef DEBUG
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * For diag purposes, we check whether the client/server idea
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * of the sequence # has gotten a bit out of sync.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross for (fudge = 1; fudge <= nsmb_signing_fudge; fudge++) {
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross (void) smb_compute_MAC(vcp, mp, rsn + fudge, sigbuf);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (bcmp(sigbuf, sigloc, SMBSIGLEN) == 0)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross break;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross (void) smb_compute_MAC(vcp, mp, rsn - fudge, sigbuf);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (bcmp(sigbuf, sigloc, SMBSIGLEN) == 0) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross fudge = -fudge;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross break;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (fudge <= nsmb_signing_fudge) {
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross SMBERROR("MID=0x%x, Seq=%d, but %d would have worked\n",
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross rqp->sr_mid, rsn, rsn + fudge);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#endif
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (EBADRPC);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross}