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