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
Get7Bits(input,startBit)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
MakeKey(key,des_key)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
Expand(in,out)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
Collapse(in,out)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
DesSetkey(key)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
DesEncrypt(clear,cipher)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
DesDecrypt(cipher,clear)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
DesSetkey(key)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
DesEncrypt(clear,cipher)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
DesDecrypt(cipher,clear)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
DesSetkey(key)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__)
DesEncrypt(clear,cipher)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
DesDecrypt(cipher,clear)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