1115720Smarkm/*-
2115720Smarkm * Copyright (c) 2003 Michael Bretterklieber
3115720Smarkm * All rights reserved.
4115720Smarkm *
5115720Smarkm * Redistribution and use in source and binary forms, with or without
6115720Smarkm * modification, are permitted provided that the following conditions
7115720Smarkm * are met:
8115720Smarkm * 1. Redistributions of source code must retain the above copyright
9115720Smarkm *    notice, this list of conditions and the following disclaimer.
10115720Smarkm * 2. Redistributions in binary form must reproduce the above copyright
11115720Smarkm *    notice, this list of conditions and the following disclaimer in the
12115720Smarkm *    documentation and/or other materials provided with the distribution.
13115720Smarkm *
14115720Smarkm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15115720Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16115720Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17115720Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18115720Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19115720Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20115720Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21115720Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22115720Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23115720Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24115720Smarkm * SUCH DAMAGE.
25115720Smarkm */
26115720Smarkm
27115720Smarkm#include <sys/cdefs.h>
28115720Smarkm__FBSDID("$FreeBSD$");
29115720Smarkm
30115720Smarkm#include <sys/types.h>
31115720Smarkm
32115720Smarkm#include <netinet/in.h>
33115720Smarkm
34115720Smarkm#include <ctype.h>
35115720Smarkm#include <err.h>
36115720Smarkm#include <md4.h>
37115720Smarkm#include <stdarg.h>
38115720Smarkm#include <stdio.h>
39115720Smarkm#include <string.h>
40115720Smarkm#include <unistd.h>
41115720Smarkm
42115720Smarkm#include "crypt.h"
43115720Smarkm
44115720Smarkm/*
45115720Smarkm * NT HASH = md4(str2unicode(pw))
46115720Smarkm */
47115720Smarkm
48115720Smarkm/* ARGSUSED */
49115720Smarkmchar *
50115720Smarkmcrypt_nthash(const char *pw, const char *salt __unused)
51115720Smarkm{
52115720Smarkm	size_t unipwLen;
53115720Smarkm	int i, j;
54115720Smarkm	static char hexconvtab[] = "0123456789abcdef";
55115720Smarkm	static const char *magic = "$3$";
56115720Smarkm	static char passwd[120];
57115720Smarkm	u_int16_t unipw[128];
58115720Smarkm	char final[MD4_SIZE*2 + 1];
59115720Smarkm	u_char hash[MD4_SIZE];
60115720Smarkm	const char *s;
61115720Smarkm	MD4_CTX	ctx;
62115720Smarkm
63115720Smarkm	bzero(unipw, sizeof(unipw));
64115720Smarkm	/* convert to unicode (thanx Archie) */
65115720Smarkm	unipwLen = 0;
66115720Smarkm	for (s = pw; unipwLen < sizeof(unipw) / 2 && *s; s++)
67115720Smarkm		unipw[unipwLen++] = htons(*s << 8);
68115720Smarkm
69115720Smarkm	/* Compute MD4 of Unicode password */
70115720Smarkm 	MD4Init(&ctx);
71115720Smarkm	MD4Update(&ctx, (u_char *)unipw, unipwLen*sizeof(u_int16_t));
72115720Smarkm	MD4Final(hash, &ctx);
73115720Smarkm
74115720Smarkm	for (i = j = 0; i < MD4_SIZE; i++) {
75115720Smarkm		final[j++] = hexconvtab[hash[i] >> 4];
76115720Smarkm		final[j++] = hexconvtab[hash[i] & 15];
77115720Smarkm	}
78115720Smarkm	final[j] = '\0';
79115720Smarkm
80115720Smarkm	strcpy(passwd, magic);
81115720Smarkm	strcat(passwd, "$");
82115720Smarkm	strncat(passwd, final, MD4_SIZE*2);
83115720Smarkm
84115720Smarkm	/* Don't leave anything around in vm they could use. */
85115720Smarkm	memset(final, 0, sizeof(final));
86115720Smarkm
87115720Smarkm	return (passwd);
88115720Smarkm}
89