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 static u_char 38 Get7Bits(input, startBit) 39 u_char *input; 40 int startBit; 41 { 42 unsigned int word; 43 44 word = (unsigned)input[startBit / 8] << 8; 45 word |= (unsigned)input[startBit / 8 + 1]; 46 47 word >>= 15 - (startBit % 8 + 7); 48 49 return word & 0xFE; 50 } 51 52 static void 53 MakeKey(key, des_key) 54 u_char *key; /* IN 56 bit DES key missing parity bits */ 55 u_char *des_key; /* OUT 64 bit DES key with parity bits added */ 56 { 57 des_key[0] = Get7Bits(key, 0); 58 des_key[1] = Get7Bits(key, 7); 59 des_key[2] = Get7Bits(key, 14); 60 des_key[3] = Get7Bits(key, 21); 61 des_key[4] = Get7Bits(key, 28); 62 des_key[5] = Get7Bits(key, 35); 63 des_key[6] = Get7Bits(key, 42); 64 des_key[7] = Get7Bits(key, 49); 65 66 #ifndef USE_CRYPT 67 des_set_odd_parity((des_cblock *)des_key); 68 #endif 69 } 70 71 #ifdef USE_CRYPT 72 /* 73 * in == 8-byte string (expanded version of the 56-bit key) 74 * out == 64-byte string where each byte is either 1 or 0 75 * Note that the low-order "bit" is always ignored by by setkey() 76 */ 77 static void 78 Expand(in, out) 79 u_char *in; 80 u_char *out; 81 { 82 int j, c; 83 int i; 84 85 for (i = 0; i < 64; in++){ 86 c = *in; 87 for (j = 7; j >= 0; j--) 88 *out++ = (c >> j) & 01; 89 i += 8; 90 } 91 } 92 93 /* The inverse of Expand 94 */ 95 static void 96 Collapse(in, out) 97 u_char *in; 98 u_char *out; 99 { 100 int j; 101 int i; 102 unsigned int c; 103 104 for (i = 0; i < 64; i += 8, out++) { 105 c = 0; 106 for (j = 7; j >= 0; j--, in++) 107 c |= *in << j; 108 *out = c & 0xff; 109 } 110 } 111 112 bool 113 DesSetkey(key) 114 u_char *key; 115 { 116 u_char des_key[8]; 117 u_char crypt_key[66]; 118 119 MakeKey(key, des_key); 120 Expand(des_key, crypt_key); 121 errno = 0; 122 setkey((const char *)crypt_key); 123 if (errno != 0) 124 return (0); 125 return (1); 126 } 127 128 bool 129 DesEncrypt(clear, cipher) 130 u_char *clear; /* IN 8 octets */ 131 u_char *cipher; /* OUT 8 octets */ 132 { 133 u_char des_input[66]; 134 135 Expand(clear, des_input); 136 errno = 0; 137 encrypt((char *)des_input, 0); 138 if (errno != 0) 139 return (0); 140 Collapse(des_input, cipher); 141 return (1); 142 } 143 144 bool 145 DesDecrypt(cipher, clear) 146 u_char *cipher; /* IN 8 octets */ 147 u_char *clear; /* OUT 8 octets */ 148 { 149 u_char des_input[66]; 150 151 Expand(cipher, des_input); 152 errno = 0; 153 encrypt((char *)des_input, 1); 154 if (errno != 0) 155 return (0); 156 Collapse(des_input, clear); 157 return (1); 158 } 159 160 #else /* USE_CRYPT */ 161 static des_key_schedule key_schedule; 162 163 bool 164 DesSetkey(key) 165 u_char *key; 166 { 167 des_cblock des_key; 168 MakeKey(key, des_key); 169 des_set_key(&des_key, key_schedule); 170 return (1); 171 } 172 173 bool 174 DesEncrypt(clear, cipher) 175 u_char *clear; /* IN 8 octets */ 176 u_char *cipher; /* OUT 8 octets */ 177 { 178 des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, 179 key_schedule, 1); 180 return (1); 181 } 182 183 bool 184 DesDecrypt(cipher, clear) 185 u_char *cipher; /* IN 8 octets */ 186 u_char *clear; /* OUT 8 octets */ 187 { 188 des_ecb_encrypt((des_cblock *)cipher, (des_cblock *)clear, 189 key_schedule, 0); 190 return (1); 191 } 192 193 #endif /* USE_CRYPT */ 194