/*
 * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1
 *
 * Extracted from chap_ms.c by James Carlson.
 *
 * Copyright (c) 1995 Eric Rosenquist.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The name(s) of the authors of this software must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission.
 *
 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <errno.h>
#include "pppd.h"
#include "pppcrypt.h"

static u_char
Get7Bits(input, startBit)
u_char *input;
int startBit;
{
	unsigned int word;

	word  = (unsigned)input[startBit / 8] << 8;
	word |= (unsigned)input[startBit / 8 + 1];

	word >>= 15 - (startBit % 8 + 7);

	return word & 0xFE;
}

static void
MakeKey(key, des_key)
u_char *key;		/* IN  56 bit DES key missing parity bits */
u_char *des_key;	/* OUT 64 bit DES key with parity bits added */
{
	des_key[0] = Get7Bits(key,  0);
	des_key[1] = Get7Bits(key,  7);
	des_key[2] = Get7Bits(key, 14);
	des_key[3] = Get7Bits(key, 21);
	des_key[4] = Get7Bits(key, 28);
	des_key[5] = Get7Bits(key, 35);
	des_key[6] = Get7Bits(key, 42);
	des_key[7] = Get7Bits(key, 49);

#ifndef USE_CRYPT
	des_set_odd_parity((des_cblock *)des_key);
#endif
}

#ifdef USE_CRYPT
/*
 * in == 8-byte string (expanded version of the 56-bit key)
 * out == 64-byte string where each byte is either 1 or 0
 * Note that the low-order "bit" is always ignored by by setkey()
 */
static void
Expand(in, out)
u_char *in;
u_char *out;
{
        int j, c;
        int i;

        for (i = 0; i < 64; in++){
		c = *in;
                for (j = 7; j >= 0; j--)
                        *out++ = (c >> j) & 01;
                i += 8;
        }
}

/* The inverse of Expand
 */
static void
Collapse(in, out)
u_char *in;
u_char *out;
{
        int j;
        int i;
	unsigned int c;

	for (i = 0; i < 64; i += 8, out++) {
	    c = 0;
	    for (j = 7; j >= 0; j--, in++)
		c |= *in << j;
	    *out = c & 0xff;
	}
}

bool
DesSetkey(key)
u_char *key;
{
	u_char des_key[8];
	u_char crypt_key[66];

	MakeKey(key, des_key);
	Expand(des_key, crypt_key);
	errno = 0;
	setkey((const char *)crypt_key);
	if (errno != 0)
		return (0);
	return (1);
}

bool
DesEncrypt(clear, cipher)
u_char *clear;	/* IN  8 octets */
u_char *cipher;	/* OUT 8 octets */
{
	u_char des_input[66];

	Expand(clear, des_input);
	errno = 0;
	encrypt((char *)des_input, 0);
	if (errno != 0)
		return (0);
	Collapse(des_input, cipher);
	return (1);
}

bool
DesDecrypt(cipher, clear)
u_char *cipher;	/* IN  8 octets */
u_char *clear;	/* OUT 8 octets */
{
	u_char des_input[66];

	Expand(cipher, des_input);
	errno = 0;
	encrypt((char *)des_input, 1);
	if (errno != 0)
		return (0);
	Collapse(des_input, clear);
	return (1);
}

#else /* USE_CRYPT */
static des_key_schedule	key_schedule;

bool
DesSetkey(key)
u_char *key;
{
	des_cblock des_key;
	MakeKey(key, des_key);
	des_set_key(&des_key, key_schedule);
	return (1);
}

bool
DesEncrypt(clear, cipher)
u_char *clear;	/* IN  8 octets */
u_char *cipher;	/* OUT 8 octets */
{
	des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher,
	    key_schedule, 1);
	return (1);
}

bool
DesDecrypt(cipher, clear)
u_char *cipher;	/* IN  8 octets */
u_char *clear;	/* OUT 8 octets */
{
	des_ecb_encrypt((des_cblock *)cipher, (des_cblock *)clear,
	    key_schedule, 0);
	return (1);
}

#endif /* USE_CRYPT */
