|
Packit |
13e0ca |
/*-
|
|
Packit |
13e0ca |
* Copyright (c) 2003 Michael Bretterklieber
|
|
Packit |
13e0ca |
* All rights reserved.
|
|
Packit |
13e0ca |
*
|
|
Packit |
13e0ca |
* Redistribution and use in source and binary forms, with or without
|
|
Packit |
13e0ca |
* modification, are permitted provided that the following conditions
|
|
Packit |
13e0ca |
* are met:
|
|
Packit |
13e0ca |
* 1. Redistributions of source code must retain the above copyright
|
|
Packit |
13e0ca |
* notice, this list of conditions and the following disclaimer.
|
|
Packit |
13e0ca |
* 2. Redistributions in binary form must reproduce the above copyright
|
|
Packit |
13e0ca |
* notice, this list of conditions and the following disclaimer in the
|
|
Packit |
13e0ca |
* documentation and/or other materials provided with the distribution.
|
|
Packit |
13e0ca |
*
|
|
Packit |
13e0ca |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
Packit |
13e0ca |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit |
13e0ca |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
Packit |
13e0ca |
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
Packit |
13e0ca |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
Packit |
13e0ca |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
Packit |
13e0ca |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
Packit |
13e0ca |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
Packit |
13e0ca |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
Packit |
13e0ca |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
Packit |
13e0ca |
* SUCH DAMAGE.
|
|
Packit |
13e0ca |
*
|
|
Packit |
13e0ca |
* The bogus 'gensalt_nthash_rn' function and all modifications to the other
|
|
Packit |
13e0ca |
* parts of this file are
|
|
Packit |
13e0ca |
*
|
|
Packit |
13e0ca |
* Copyright (c) 2017 Björn Esser <besser82@fedoraproject.org>
|
|
Packit |
13e0ca |
* All rights reserved.
|
|
Packit |
13e0ca |
*
|
|
Packit |
13e0ca |
* and is provided under the same licensing terms and conditions as the
|
|
Packit |
13e0ca |
* other parts of this file.
|
|
Packit |
13e0ca |
*/
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#include "crypt-port.h"
|
|
Packit |
13e0ca |
#include "alg-md4.h"
|
|
Packit |
13e0ca |
#include "crypt-private.h"
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#include <errno.h>
|
|
Packit |
13e0ca |
#include <stdio.h>
|
|
Packit |
13e0ca |
#include <stdlib.h>
|
|
Packit |
13e0ca |
#include <netinet/in.h>
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#if INCLUDE_nthash
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/*
|
|
Packit |
13e0ca |
* NT HASH = md4(str2unicode(phrase))
|
|
Packit |
13e0ca |
*/
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
void
|
|
Packit |
13e0ca |
crypt_nthash_rn (const char *phrase, size_t ARG_UNUSED (phr_size),
|
|
Packit |
13e0ca |
const char *setting, size_t ARG_UNUSED (set_size),
|
|
Packit |
13e0ca |
uint8_t *output, size_t out_size,
|
|
Packit |
13e0ca |
void *scratch, size_t scr_size)
|
|
Packit |
13e0ca |
{
|
|
Packit |
13e0ca |
size_t unipwLen;
|
|
Packit |
13e0ca |
int i;
|
|
Packit |
13e0ca |
static const char hexconvtab[] = "0123456789abcdef";
|
|
Packit |
13e0ca |
static const char *magic = "$3$";
|
|
Packit |
13e0ca |
uint16_t unipw[128];
|
|
Packit |
13e0ca |
unsigned char hash[16];
|
|
Packit |
13e0ca |
const char *s;
|
|
Packit |
13e0ca |
struct md4_ctx *ctx = scratch;
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
if ((out_size < 4 + 32) ||
|
|
Packit |
13e0ca |
(scr_size < sizeof (struct md4_ctx)))
|
|
Packit |
13e0ca |
{
|
|
Packit |
13e0ca |
errno = ERANGE;
|
|
Packit |
13e0ca |
return;
|
|
Packit |
13e0ca |
}
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
if (strncmp (setting, magic, strlen (magic)))
|
|
Packit |
13e0ca |
{
|
|
Packit |
13e0ca |
errno = EINVAL;
|
|
Packit |
13e0ca |
return;
|
|
Packit |
13e0ca |
}
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
XCRYPT_SECURE_MEMSET (unipw, sizeof unipw);
|
|
Packit |
13e0ca |
/* convert to unicode (thanx Archie) */
|
|
Packit |
13e0ca |
unipwLen = 0;
|
|
Packit |
13e0ca |
for (s = phrase; unipwLen < sizeof(unipw) / 2 && *s; s++)
|
|
Packit |
13e0ca |
unipw[unipwLen++] = htons((uint16_t)(*s << 8));
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* Compute MD4 of Unicode password */
|
|
Packit |
13e0ca |
md4_init_ctx (ctx);
|
|
Packit |
13e0ca |
md4_process_bytes ((unsigned char *)unipw, ctx, unipwLen*sizeof(uint16_t));
|
|
Packit |
13e0ca |
md4_finish_ctx (ctx, hash);
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
output = (uint8_t *)stpcpy ((char *)output, magic);
|
|
Packit |
13e0ca |
*output++ = '$';
|
|
Packit |
13e0ca |
for (i = 0; i < 16; i++)
|
|
Packit |
13e0ca |
{
|
|
Packit |
13e0ca |
*output++ = (uint8_t)hexconvtab[hash[i] >> 4];
|
|
Packit |
13e0ca |
*output++ = (uint8_t)hexconvtab[hash[i] & 0xf];
|
|
Packit |
13e0ca |
}
|
|
Packit |
13e0ca |
*output = '\0';
|
|
Packit |
13e0ca |
}
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* This function does not return any valid salt,
|
|
Packit |
13e0ca |
since the NTHASH crypt function simply ignores
|
|
Packit |
13e0ca |
any setting passed to it. Anyways, the string
|
|
Packit |
13e0ca |
returned in OUTPUT will start with the correct
|
|
Packit |
13e0ca |
magic string '$3$', so it can be used as
|
|
Packit |
13e0ca |
SETTING for the crypt function. */
|
|
Packit |
13e0ca |
void
|
|
Packit |
13e0ca |
gensalt_nthash_rn (unsigned long count,
|
|
Packit |
13e0ca |
const uint8_t *rbytes,
|
|
Packit |
13e0ca |
size_t nrbytes,
|
|
Packit |
13e0ca |
uint8_t *output,
|
|
Packit |
13e0ca |
size_t o_size)
|
|
Packit |
13e0ca |
{
|
|
Packit |
13e0ca |
static const char *salt = "$3$__not_used__";
|
|
Packit |
13e0ca |
struct md4_ctx ctx;
|
|
Packit |
13e0ca |
unsigned char hashbuf[16];
|
|
Packit |
13e0ca |
char hashstr[14 + 1];
|
|
Packit |
13e0ca |
unsigned long i;
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
/* Minimal O_SIZE to store the fake salt.
|
|
Packit |
13e0ca |
At least 1 byte of RBYTES is needed
|
|
Packit |
13e0ca |
to calculate the MD4 hash used in the
|
|
Packit |
13e0ca |
fake salt. */
|
|
Packit |
13e0ca |
if ((o_size < 29) || (nrbytes < 1))
|
|
Packit |
13e0ca |
{
|
|
Packit |
13e0ca |
errno = ERANGE;
|
|
Packit |
13e0ca |
return;
|
|
Packit |
13e0ca |
}
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
if (count < 20)
|
|
Packit |
13e0ca |
count = 20;
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
md4_init_ctx (&ctx;;
|
|
Packit |
13e0ca |
for (i = 0; i < count; i++)
|
|
Packit |
13e0ca |
{
|
|
Packit |
13e0ca |
md4_process_bytes (salt, &ctx, (i % 15) + 1);
|
|
Packit |
13e0ca |
md4_process_bytes (rbytes, &ctx, nrbytes);
|
|
Packit |
13e0ca |
md4_process_bytes (salt, &ctx, 15);
|
|
Packit |
13e0ca |
md4_process_bytes (salt, &ctx, 15 - (i % 15));
|
|
Packit |
13e0ca |
}
|
|
Packit |
13e0ca |
md4_finish_ctx (&ctx, &hashbuf);
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
for (i = 0; i < 7; i++)
|
|
Packit |
13e0ca |
sprintf (&(hashstr[i * 2]), "%02x", hashbuf[i]);
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
memcpy (output, salt, 15);
|
|
Packit |
13e0ca |
memcpy (output + 15, hashstr, 14);
|
|
Packit |
13e0ca |
}
|
|
Packit |
13e0ca |
|
|
Packit |
13e0ca |
#endif
|