• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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