You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
253 lines
5.5 KiB
253 lines
5.5 KiB
/* |
|
* 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 */
|
|
|