smb_crypt.c revision 116189
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 */
32116189Sobrien
33116189Sobrien#include <sys/cdefs.h>
34116189Sobrien__FBSDID("$FreeBSD: head/sys/netsmb/smb_crypt.c 116189 2003-06-11 05:37:42Z obrien $");
35116189Sobrien
3675374Sbp#include <sys/param.h>
3775374Sbp#include <sys/malloc.h>
3875374Sbp#include <sys/kernel.h>
3975374Sbp#include <sys/systm.h>
4075374Sbp#include <sys/conf.h>
4175374Sbp#include <sys/proc.h>
4275374Sbp#include <sys/fcntl.h>
4375374Sbp#include <sys/socket.h>
4475374Sbp#include <sys/socketvar.h>
4575374Sbp#include <sys/sysctl.h>
4675374Sbp
4775374Sbp#include <sys/md4.h>
4875374Sbp#include <sys/iconv.h>
4975374Sbp
5075374Sbp#include <netsmb/smb.h>
5175374Sbp#include <netsmb/smb_conn.h>
5275374Sbp#include <netsmb/smb_subr.h>
5375374Sbp#include <netsmb/smb_dev.h>
5475374Sbp
5575374Sbp#include "opt_netsmb.h"
5675374Sbp
5775374Sbp#ifdef NETSMBCRYPTO
5875374Sbp
5975374Sbp#include <crypto/des/des.h>
6075374Sbp
6175374Sbpstatic u_char N8[] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
6275374Sbp
6375374Sbp
6475374Sbpstatic void
6575374Sbpsmb_E(const u_char *key, u_char *data, u_char *dest)
6675374Sbp{
6775374Sbp	des_key_schedule *ksp;
6875374Sbp	u_char kk[8];
6975374Sbp
7075374Sbp	kk[0] = key[0] & 0xfe;
7175374Sbp	kk[1] = key[0] << 7 | (key[1] >> 1 & 0xfe);
7275374Sbp	kk[2] = key[1] << 6 | (key[2] >> 2 & 0xfe);
7375374Sbp	kk[3] = key[2] << 5 | (key[3] >> 3 & 0xfe);
7475374Sbp	kk[4] = key[3] << 4 | (key[4] >> 4 & 0xfe);
7575374Sbp	kk[5] = key[4] << 3 | (key[5] >> 5 & 0xfe);
7675374Sbp	kk[6] = key[5] << 2 | (key[6] >> 6 & 0xfe);
7775374Sbp	kk[7] = key[6] << 1;
78111119Simp	ksp = malloc(sizeof(des_key_schedule), M_SMBTEMP, M_WAITOK);
7978064Sume	des_set_key((des_cblock *)kk, *ksp);
8078064Sume	des_ecb_encrypt((des_cblock *)data, (des_cblock *)dest, *ksp, 1);
8175374Sbp	free(ksp, M_SMBTEMP);
8275374Sbp}
8375374Sbp#endif
8475374Sbp
8575374Sbp
8675374Sbpint
8775374Sbpsmb_encrypt(const u_char *apwd, u_char *C8, u_char *RN)
8875374Sbp{
8975374Sbp#ifdef NETSMBCRYPTO
9075374Sbp	u_char *p, *P14, *S21;
9175374Sbp
92111119Simp	p = malloc(14 + 21, M_SMBTEMP, M_WAITOK);
9375374Sbp	bzero(p, 14 + 21);
9475374Sbp	P14 = p;
9575374Sbp	S21 = p + 14;
9675374Sbp	bcopy(apwd, P14, min(14, strlen(apwd)));
9775374Sbp	/*
9875374Sbp	 * S21 = concat(Ex(P14, N8), zeros(5));
9975374Sbp	 */
10075374Sbp	smb_E(P14, N8, S21);
10175374Sbp	smb_E(P14 + 7, N8, S21 + 8);
10275374Sbp
10375374Sbp	smb_E(S21, C8, RN);
10475374Sbp	smb_E(S21 + 7, C8, RN + 8);
10575374Sbp	smb_E(S21 + 14, C8, RN + 16);
10675374Sbp	free(p, M_SMBTEMP);
10775374Sbp	return 0;
10875374Sbp#else
10975374Sbp	SMBERROR("password encryption is not available\n");
11075374Sbp	bzero(RN, 24);
11175374Sbp	return EAUTH;
11275374Sbp#endif
11375374Sbp}
11475374Sbp
11575374Sbpint
11675374Sbpsmb_ntencrypt(const u_char *apwd, u_char *C8, u_char *RN)
11775374Sbp{
11875374Sbp#ifdef NETSMBCRYPTO
11975374Sbp	u_char S21[21];
12075374Sbp	u_int16_t *unipwd;
12175374Sbp	MD4_CTX *ctxp;
12275374Sbp	int len;
12375374Sbp
12475374Sbp	len = strlen(apwd);
125111119Simp	unipwd = malloc((len + 1) * sizeof(u_int16_t), M_SMBTEMP, M_WAITOK);
12675374Sbp	/*
12775374Sbp	 * S21 = concat(MD4(U(apwd)), zeros(5));
12875374Sbp	 */
12975374Sbp	smb_strtouni(unipwd, apwd);
130111119Simp	ctxp = malloc(sizeof(MD4_CTX), M_SMBTEMP, M_WAITOK);
13175374Sbp	MD4Init(ctxp);
13275374Sbp	MD4Update(ctxp, (u_char*)unipwd, len * sizeof(u_int16_t));
13375374Sbp	free(unipwd, M_SMBTEMP);
13475374Sbp	bzero(S21, 21);
13575374Sbp	MD4Final(S21, ctxp);
13675374Sbp	free(ctxp, M_SMBTEMP);
13775374Sbp
13875374Sbp	smb_E(S21, C8, RN);
13975374Sbp	smb_E(S21 + 7, C8, RN + 8);
14075374Sbp	smb_E(S21 + 14, C8, RN + 16);
14175374Sbp	return 0;
14275374Sbp#else
14375374Sbp	SMBERROR("password encryption is not available\n");
14475374Sbp	bzero(RN, 24);
14575374Sbp	return EAUTH;
14675374Sbp#endif
14775374Sbp}
14875374Sbp
149