1 /* 2 * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1 3 * 4 * Extracted from chap_ms.c by James Carlson. 5 * 6 * Copyright (c) 1995 Eric Rosenquist. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. The name(s) of the authors of this software must not be used to 21 * endorse or promote products derived from this software without 22 * prior written permission. 23 * 24 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 25 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 26 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 27 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 28 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 29 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 30 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 31 */ 32 33 #include <errno.h> 34 #include "pppd.h" 35 #include "pppcrypt.h" 36 37 #if defined(__ANDROID__) 38 /* This code can use one of three DES libraries. The first, if USE_LIBDES is 39 * defined, are the libdes functions. This interface is still supported by 40 * OpenSSL as backwards compatibility. If USE_CRYPT is defined then the 41 * libcrypt functions are used. Lastly, if USE_OPENSSL is defined the "modern" 42 * OpenSSL interface is used. */ 43 44 #if defined(USE_CRYPT) 45 #include <crypt.h> 46 #elif defined(USE_OPENSSL) 47 #include <openssl/des.h> 48 #elif defined(USE_LIBDES) 49 #include <des.h> 50 #else 51 #error "Must define one of USE_CRYPT, USE_LIBDES or USE_OPENSSL" 52 #endif 53 54 #endif 55 56 static u_char 57 Get7Bits(input, startBit) 58 u_char *input; 59 int startBit; 60 { 61 unsigned int word; 62 63 word = (unsigned)input[startBit / 8] << 8; 64 word |= (unsigned)input[startBit / 8 + 1]; 65 66 word >>= 15 - (startBit % 8 + 7); 67 68 return word & 0xFE; 69 } 70 71 static void 72 MakeKey(key, des_key) 73 u_char *key; /* IN 56 bit DES key missing parity bits */ 74 u_char *des_key; /* OUT 64 bit DES key with parity bits added */ 75 { 76 des_key[0] = Get7Bits(key, 0); 77 des_key[1] = Get7Bits(key, 7); 78 des_key[2] = Get7Bits(key, 14); 79 des_key[3] = Get7Bits(key, 21); 80 des_key[4] = Get7Bits(key, 28); 81 des_key[5] = Get7Bits(key, 35); 82 des_key[6] = Get7Bits(key, 42); 83 des_key[7] = Get7Bits(key, 49); 84 85 #if defined(USE_LIBDES) 86 des_set_odd_parity((des_cblock *)des_key); 87 #endif 88 } 89 90 #if defined(USE_CRYPT) 91 /* 92 * in == 8-byte string (expanded version of the 56-bit key) 93 * out == 64-byte string where each byte is either 1 or 0 94 * Note that the low-order "bit" is always ignored by by setkey() 95 */ 96 static void 97 Expand(in, out) 98 u_char *in; 99 u_char *out; 100 { 101 int j, c; 102 int i; 103 104 for (i = 0; i < 64; in++){ 105 c = *in; 106 for (j = 7; j >= 0; j--) 107 *out++ = (c >> j) & 01; 108 i += 8; 109 } 110 } 111 112 /* The inverse of Expand 113 */ 114 static void 115 Collapse(in, out) 116 u_char *in; 117 u_char *out; 118 { 119 int j; 120 int i; 121 unsigned int c; 122 123 for (i = 0; i < 64; i += 8, out++) { 124 c = 0; 125 for (j = 7; j >= 0; j--, in++) 126 c |= *in << j; 127 *out = c & 0xff; 128 } 129 } 130 131 bool 132 DesSetkey(key) 133 u_char *key; 134 { 135 u_char des_key[8]; 136 u_char crypt_key[66]; 137 138 MakeKey(key, des_key); 139 Expand(des_key, crypt_key); 140 errno = 0; 141 setkey((const char *)crypt_key); 142 if (errno != 0) 143 return (0); 144 return (1); 145 } 146 147 bool 148 DesEncrypt(clear, cipher) 149 u_char *clear; /* IN 8 octets */ 150 u_char *cipher; /* OUT 8 octets */ 151 { 152 u_char des_input[66]; 153 154 Expand(clear, des_input); 155 errno = 0; 156 encrypt((char *)des_input, 0); 157 if (errno != 0) 158 return (0); 159 Collapse(des_input, cipher); 160 return (1); 161 } 162 163 bool 164 DesDecrypt(cipher, clear) 165 u_char *cipher; /* IN 8 octets */ 166 u_char *clear; /* OUT 8 octets */ 167 { 168 u_char des_input[66]; 169 170 Expand(cipher, des_input); 171 errno = 0; 172 encrypt((char *)des_input, 1); 173 if (errno != 0) 174 return (0); 175 Collapse(des_input, clear); 176 return (1); 177 } 178 179 #elif defined(USE_OPENSSL) 180 static DES_key_schedule key_schedule; 181 182 bool 183 DesSetkey(key) 184 u_char *key; 185 { 186 DES_cblock des_key; 187 MakeKey(key, (u_char*) &des_key); 188 DES_set_key(&des_key, &key_schedule); 189 return (1); 190 } 191 192 bool 193 DesEncrypt(clear, cipher) 194 u_char *clear; /* IN 8 octets */ 195 u_char *cipher; /* OUT 8 octets */ 196 { 197 DES_ecb_encrypt((DES_cblock *)clear, (DES_cblock *)cipher, 198 &key_schedule, 1 /* encrypt */); 199 return (1); 200 } 201 202 bool 203 DesDecrypt(cipher, clear) 204 u_char *cipher; /* IN 8 octets */ 205 u_char *clear; /* OUT 8 octets */ 206 { 207 DES_ecb_encrypt((DES_cblock *)cipher, (DES_cblock *)clear, 208 &key_schedule, 0 /* decrypt */); 209 return (1); 210 } 211 212 #elif defined(USE_LIBDES) 213 static des_key_schedule key_schedule; 214 215 bool 216 DesSetkey(key) 217 u_char *key; 218 { 219 des_cblock des_key; 220 MakeKey(key, des_key); 221 des_set_key(&des_key, key_schedule); 222 return (1); 223 } 224 225 bool 226 #if defined(__ANDROID__) 227 DesEncrypt(clear, cipher) 228 #else 229 DesEncrypt(clear, key, cipher) 230 #endif 231 u_char *clear; /* IN 8 octets */ 232 u_char *cipher; /* OUT 8 octets */ 233 { 234 des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, 235 key_schedule, 1); 236 return (1); 237 } 238 239 bool 240 DesDecrypt(cipher, clear) 241 u_char *cipher; /* IN 8 octets */ 242 u_char *clear; /* OUT 8 octets */ 243 { 244 des_ecb_encrypt((des_cblock *)cipher, (des_cblock *)clear, 245 key_schedule, 0); 246 return (1); 247 } 248 249 #else 250 251 #error "Must define one of USE_CRYPT, USE_LIBDES or USE_OPENSSL" 252 253 #endif /* USE_CRYPT */ 254