smb_crypt.c revision 78064
175374Sbp/*
275374Sbp * Copyright (c) 2000-2001, Boris Popov
375374Sbp * All rights reserved.
475374Sbp *
575374Sbp * Redistribution and use in source and binary forms, with or without
675374Sbp * modification, are permitted provided that the following conditions
775374Sbp * are met:
875374Sbp * 1. Redistributions of source code must retain the above copyright
975374Sbp *    notice, this list of conditions and the following disclaimer.
1075374Sbp * 2. Redistributions in binary form must reproduce the above copyright
1175374Sbp *    notice, this list of conditions and the following disclaimer in the
1275374Sbp *    documentation and/or other materials provided with the distribution.
1375374Sbp * 3. All advertising materials mentioning features or use of this software
1475374Sbp *    must display the following acknowledgement:
1575374Sbp *    This product includes software developed by Boris Popov.
1675374Sbp * 4. Neither the name of the author nor the names of any co-contributors
1775374Sbp *    may be used to endorse or promote products derived from this software
1875374Sbp *    without specific prior written permission.
1975374Sbp *
2075374Sbp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2175374Sbp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2275374Sbp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2375374Sbp * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2475374Sbp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2575374Sbp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2675374Sbp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2775374Sbp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2875374Sbp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2975374Sbp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3075374Sbp * SUCH DAMAGE.
3175374Sbp *
3275374Sbp * $FreeBSD: head/sys/netsmb/smb_crypt.c 78064 2001-06-11 12:39:29Z ume $
3375374Sbp */
3475374Sbp#include <sys/param.h>
3575374Sbp#include <sys/malloc.h>
3675374Sbp#include <sys/kernel.h>
3775374Sbp#include <sys/systm.h>
3875374Sbp#include <sys/conf.h>
3975374Sbp#include <sys/proc.h>
4075374Sbp#include <sys/fcntl.h>
4175374Sbp#include <sys/socket.h>
4275374Sbp#include <sys/socketvar.h>
4375374Sbp#include <sys/sysctl.h>
4475374Sbp
4575374Sbp#include <sys/md4.h>
4675374Sbp#include <sys/iconv.h>
4775374Sbp
4875374Sbp#include <netsmb/smb.h>
4975374Sbp#include <netsmb/smb_conn.h>
5075374Sbp#include <netsmb/smb_subr.h>
5175374Sbp#include <netsmb/smb_dev.h>
5275374Sbp
5375374Sbp#include "opt_netsmb.h"
5475374Sbp
5575374Sbp#ifdef NETSMBCRYPTO
5675374Sbp
5775374Sbp#include <crypto/des/des.h>
5875374Sbp
5975374Sbpstatic u_char N8[] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
6075374Sbp
6175374Sbp
6275374Sbpstatic void
6375374Sbpsmb_E(const u_char *key, u_char *data, u_char *dest)
6475374Sbp{
6575374Sbp	des_key_schedule *ksp;
6675374Sbp	u_char kk[8];
6775374Sbp
6875374Sbp	kk[0] = key[0] & 0xfe;
6975374Sbp	kk[1] = key[0] << 7 | (key[1] >> 1 & 0xfe);
7075374Sbp	kk[2] = key[1] << 6 | (key[2] >> 2 & 0xfe);
7175374Sbp	kk[3] = key[2] << 5 | (key[3] >> 3 & 0xfe);
7275374Sbp	kk[4] = key[3] << 4 | (key[4] >> 4 & 0xfe);
7375374Sbp	kk[5] = key[4] << 3 | (key[5] >> 5 & 0xfe);
7475374Sbp	kk[6] = key[5] << 2 | (key[6] >> 6 & 0xfe);
7575374Sbp	kk[7] = key[6] << 1;
7675374Sbp	ksp = malloc(sizeof(des_key_schedule), M_SMBTEMP, M_WAITOK);
7778064Sume	des_set_key((des_cblock *)kk, *ksp);
7878064Sume	des_ecb_encrypt((des_cblock *)data, (des_cblock *)dest, *ksp, 1);
7975374Sbp	free(ksp, M_SMBTEMP);
8075374Sbp}
8175374Sbp#endif
8275374Sbp
8375374Sbp
8475374Sbpint
8575374Sbpsmb_encrypt(const u_char *apwd, u_char *C8, u_char *RN)
8675374Sbp{
8775374Sbp#ifdef NETSMBCRYPTO
8875374Sbp	u_char *p, *P14, *S21;
8975374Sbp
9075374Sbp	p = malloc(14 + 21, M_SMBTEMP, M_WAITOK);
9175374Sbp	bzero(p, 14 + 21);
9275374Sbp	P14 = p;
9375374Sbp	S21 = p + 14;
9475374Sbp	bcopy(apwd, P14, min(14, strlen(apwd)));
9575374Sbp	/*
9675374Sbp	 * S21 = concat(Ex(P14, N8), zeros(5));
9775374Sbp	 */
9875374Sbp	smb_E(P14, N8, S21);
9975374Sbp	smb_E(P14 + 7, N8, S21 + 8);
10075374Sbp
10175374Sbp	smb_E(S21, C8, RN);
10275374Sbp	smb_E(S21 + 7, C8, RN + 8);
10375374Sbp	smb_E(S21 + 14, C8, RN + 16);
10475374Sbp	free(p, M_SMBTEMP);
10575374Sbp	return 0;
10675374Sbp#else
10775374Sbp	SMBERROR("password encryption is not available\n");
10875374Sbp	bzero(RN, 24);
10975374Sbp	return EAUTH;
11075374Sbp#endif
11175374Sbp}
11275374Sbp
11375374Sbpint
11475374Sbpsmb_ntencrypt(const u_char *apwd, u_char *C8, u_char *RN)
11575374Sbp{
11675374Sbp#ifdef NETSMBCRYPTO
11775374Sbp	u_char S21[21];
11875374Sbp	u_int16_t *unipwd;
11975374Sbp	MD4_CTX *ctxp;
12075374Sbp	int len;
12175374Sbp
12275374Sbp	len = strlen(apwd);
12375374Sbp	unipwd = malloc(len * sizeof(u_int16_t), M_SMBTEMP, M_WAITOK);
12475374Sbp	/*
12575374Sbp	 * S21 = concat(MD4(U(apwd)), zeros(5));
12675374Sbp	 */
12775374Sbp	smb_strtouni(unipwd, apwd);
12875374Sbp	ctxp = malloc(sizeof(MD4_CTX), M_SMBTEMP, M_WAITOK);
12975374Sbp	MD4Init(ctxp);
13075374Sbp	MD4Update(ctxp, (u_char*)unipwd, len * sizeof(u_int16_t));
13175374Sbp	free(unipwd, M_SMBTEMP);
13275374Sbp	bzero(S21, 21);
13375374Sbp	MD4Final(S21, ctxp);
13475374Sbp	free(ctxp, M_SMBTEMP);
13575374Sbp
13675374Sbp	smb_E(S21, C8, RN);
13775374Sbp	smb_E(S21 + 7, C8, RN + 8);
13875374Sbp	smb_E(S21 + 14, C8, RN + 16);
13975374Sbp	return 0;
14075374Sbp#else
14175374Sbp	SMBERROR("password encryption is not available\n");
14275374Sbp	bzero(RN, 24);
14375374Sbp	return EAUTH;
14475374Sbp#endif
14575374Sbp}
14675374Sbp
147