]> git.ozlabs.org Git - ppp.git/blob - pppd/pppcrypt.c
Added EAP support with MD5-Challenge and SRP-SHA1 methods. Tested
[ppp.git] / pppd / pppcrypt.c
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, Strata Software Limited.
7  * http://www.strataware.com/
8  *
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms are permitted
12  * provided that the above copyright notice and this paragraph are
13  * duplicated in all such forms and that any documentation,
14  * advertising materials, and other materials related to such
15  * distribution and use acknowledge that the software was developed
16  * by Eric Rosenquist.  The name of the author may not be used to
17  * endorse or promote products derived from this software without
18  * specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
22  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23  */
24
25 #include <errno.h>
26 #include "pppd.h"
27 #include "pppcrypt.h"
28
29 static u_char
30 Get7Bits(input, startBit)
31 u_char *input;
32 int startBit;
33 {
34         unsigned int word;
35
36         word  = (unsigned)input[startBit / 8] << 8;
37         word |= (unsigned)input[startBit / 8 + 1];
38
39         word >>= 15 - (startBit % 8 + 7);
40
41         return word & 0xFE;
42 }
43
44 static void
45 MakeKey(key, des_key)
46 u_char *key;            /* IN  56 bit DES key missing parity bits */
47 u_char *des_key;        /* OUT 64 bit DES key with parity bits added */
48 {
49         des_key[0] = Get7Bits(key,  0);
50         des_key[1] = Get7Bits(key,  7);
51         des_key[2] = Get7Bits(key, 14);
52         des_key[3] = Get7Bits(key, 21);
53         des_key[4] = Get7Bits(key, 28);
54         des_key[5] = Get7Bits(key, 35);
55         des_key[6] = Get7Bits(key, 42);
56         des_key[7] = Get7Bits(key, 49);
57
58 #ifndef USE_CRYPT
59         des_set_odd_parity((des_cblock *)des_key);
60 #endif
61 }
62
63 #ifdef USE_CRYPT
64 /*
65  * in == 8-byte string (expanded version of the 56-bit key)
66  * out == 64-byte string where each byte is either 1 or 0
67  * Note that the low-order "bit" is always ignored by by setkey()
68  */
69 static void
70 Expand(in, out)
71 u_char *in;
72 u_char *out;
73 {
74         int j, c;
75         int i;
76
77         for (i = 0; i < 64; in++){
78                 c = *in;
79                 for (j = 7; j >= 0; j--)
80                         *out++ = (c >> j) & 01;
81                 i += 8;
82         }
83 }
84
85 /* The inverse of Expand
86  */
87 static void
88 Collapse(in, out)
89 u_char *in;
90 u_char *out;
91 {
92         int j;
93         int i;
94         unsigned int c;
95
96         for (i = 0; i < 64; i += 8, out++) {
97             c = 0;
98             for (j = 7; j >= 0; j--, in++)
99                 c |= *in << j;
100             *out = c & 0xff;
101         }
102 }
103
104 bool
105 DesSetkey(key)
106 u_char *key;
107 {
108         u_char des_key[8];
109         u_char crypt_key[66];
110
111         MakeKey(key, des_key);
112         Expand(des_key, crypt_key);
113         errno = 0;
114         setkey((const char *)crypt_key);
115         if (errno != 0)
116                 return (0);
117         return (1);
118 }
119
120 bool
121 DesEncrypt(clear, cipher)
122 u_char *clear;  /* IN  8 octets */
123 u_char *cipher; /* OUT 8 octets */
124 {
125         u_char des_input[66];
126
127         Expand(clear, des_input);
128         errno = 0;
129         encrypt((char *)des_input, 0);
130         if (errno != 0)
131                 return (0);
132         Collapse(des_input, cipher);
133         return (1);
134 }
135
136 bool
137 DesDecrypt(cipher, clear)
138 u_char *cipher; /* IN  8 octets */
139 u_char *clear;  /* OUT 8 octets */
140 {
141         u_char des_input[66];
142
143         Expand(cipher, des_input);
144         errno = 0;
145         encrypt((char *)des_input, 1);
146         if (errno != 0)
147                 return (0);
148         Collapse(des_input, clear);
149         return (1);
150 }
151
152 #else /* USE_CRYPT */
153 static des_key_schedule key_schedule;
154
155 bool
156 DesSetkey(key)
157 u_char *key;
158 {
159         des_cblock des_key;
160         MakeKey(key, des_key);
161         des_set_key(&des_key, key_schedule);
162         return (1);
163 }
164
165 bool
166 DesEncrypt(clear, key, cipher)
167 u_char *clear;  /* IN  8 octets */
168 u_char *cipher; /* OUT 8 octets */
169 {
170         des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher,
171             key_schedule, 1);
172         return (1);
173 }
174
175 bool
176 DesDecrypt(cipher, clear)
177 u_char *cipher; /* IN  8 octets */
178 u_char *clear;  /* OUT 8 octets */
179 {
180         des_ecb_encrypt((des_cblock *)cipher, (des_cblock *)clear,
181             key_schedule, 0);
182         return (1);
183 }
184
185 #endif /* USE_CRYPT */