/*
 * 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"

#if defined(__ANDROID__)
/* This code can use one of three DES libraries. The first, if USE_LIBDES is
 * defined, are the libdes functions. This interface is still supported by
 * OpenSSL as backwards compatibility. If USE_CRYPT is defined then the
 * libcrypt functions are used. Lastly, if USE_OPENSSL is defined the "modern"
 * OpenSSL interface is used. */

#if defined(USE_CRYPT)
#include <crypt.h>
#elif defined(USE_OPENSSL)
#include <openssl/des.h>
#elif defined(USE_LIBDES)
#include <des.h>
#else
#error "Must define one of USE_CRYPT, USE_LIBDES or USE_OPENSSL"
#endif

#endif

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);

#if defined(USE_LIBDES)
	des_set_odd_parity((des_cblock *)des_key);
#endif
}

#if defined(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);
}

#elif defined(USE_OPENSSL)
static DES_key_schedule key_schedule;

bool
DesSetkey(key)
u_char *key;
{
	DES_cblock des_key;
	MakeKey(key, (u_char*) &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 /* encrypt */);
	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 /* decrypt */);
	return (1);
}

#elif defined(USE_LIBDES)
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
#if defined(__ANDROID__)
DesEncrypt(clear, cipher)
#else
DesEncrypt(clear, key, cipher)
#endif
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);
}

#else

#error "Must define one of USE_CRYPT, USE_LIBDES or USE_OPENSSL"

#endif /* USE_CRYPT */
