]> git.ozlabs.org Git - ppp.git/blob - pppd/ppp-des.c
Reduce the clutter by defining the MD4/MD5/SHA digest lengths in one place. Avoid...
[ppp.git] / pppd / ppp-des.c
1 /*
2  * ppp-des.c - PPP/DES implementation for MS-CHAP and EAP SRP-SHA1
3  *
4  * Extracted from chap_ms.c by James Carlson.
5  * Added abstraction via PPP_Digest* callbacks by Eivind Næss
6  *
7  * Copyright (c) 1995 Eric Rosenquist. All rights reserved.
8  * Copyright (c) 2022 Eivind Næss. All rights reserved.
9  * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in
20  *    the documentation and/or other materials provided with the
21  *    distribution.
22  *
23  * 3. The name(s) of the authors of this software must not be used to
24  *    endorse or promote products derived from this software without
25  *    prior written permission.
26  *
27  * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
28  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
29  * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
30  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
31  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
32  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
33  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
34  *
35  * Sections of this code holds different copyright information.
36  */
37
38 #ifdef HAVE_CONFIG_H
39 #include "config.h"
40 #endif
41
42 #include <stddef.h>
43 #include <stdlib.h>
44
45 #include "ppp-crypto-priv.h"
46
47 /*
48  * DES related functions are imported from openssl 3.0 project with the 
49  * follwoing license:
50  *
51  * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
52  *
53  * Licensed under the Apache License 2.0 (the "License").  You may not use
54  * this file except in compliance with the License.  You can obtain a copy
55  * in the file LICENSE in the source distribution or at
56  * https://www.openssl.org/source/license.html
57  */
58 typedef unsigned char DES_cblock[8];
59 #define DES_KEY_SZ      (sizeof(DES_cblock))
60
61 static const unsigned char odd_parity[256] = {
62     1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
63     16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
64     32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
65     49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
66     64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
67     81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
68     97, 97, 98, 98, 100, 100, 103, 103, 104, 104, 107, 107, 109, 109, 110,
69     110,
70     112, 112, 115, 115, 117, 117, 118, 118, 121, 121, 122, 122, 124, 124, 127,
71     127,
72     128, 128, 131, 131, 133, 133, 134, 134, 137, 137, 138, 138, 140, 140, 143,
73     143,
74     145, 145, 146, 146, 148, 148, 151, 151, 152, 152, 155, 155, 157, 157, 158,
75     158,
76     161, 161, 162, 162, 164, 164, 167, 167, 168, 168, 171, 171, 173, 173, 174,
77     174,
78     176, 176, 179, 179, 181, 181, 182, 182, 185, 185, 186, 186, 188, 188, 191,
79     191,
80     193, 193, 194, 194, 196, 196, 199, 199, 200, 200, 203, 203, 205, 205, 206,
81     206,
82     208, 208, 211, 211, 213, 213, 214, 214, 217, 217, 218, 218, 220, 220, 223,
83     223,
84     224, 224, 227, 227, 229, 229, 230, 230, 233, 233, 234, 234, 236, 236, 239,
85     239,
86     241, 241, 242, 242, 244, 244, 247, 247, 248, 248, 251, 251, 253, 253, 254,
87     254
88 };
89
90 static void DES_set_odd_parity(DES_cblock *key)
91 {
92     unsigned int i;
93     for (i = 0; i < DES_KEY_SZ; i++)
94         (*key)[i] = odd_parity[(*key)[i]];
95 }
96
97 static unsigned char
98 Get7Bits(const unsigned char *input, int startBit)
99 {
100         unsigned int word;
101
102         word  = (unsigned)input[startBit / 8] << 8;
103         word |= (unsigned)input[startBit / 8 + 1];
104
105         word >>= 15 - (startBit % 8 + 7);
106
107         return word & 0xFE;
108 }
109
110 static void
111 MakeKey(const unsigned char *key, unsigned char *des_key)
112 {
113         /* key     IN  56 bit DES key missing parity bits */
114         /* des_key OUT 64 bit DES key with parity bits added */
115         des_key[0] = Get7Bits(key,  0);
116         des_key[1] = Get7Bits(key,  7);
117         des_key[2] = Get7Bits(key, 14);
118         des_key[3] = Get7Bits(key, 21);
119         des_key[4] = Get7Bits(key, 28);
120         des_key[5] = Get7Bits(key, 35);
121         des_key[6] = Get7Bits(key, 42);
122         des_key[7] = Get7Bits(key, 49);
123
124         DES_set_odd_parity((DES_cblock *)des_key);
125 }
126
127
128 #ifdef OPENSSL_HAVE_DES
129
130 #include <openssl/evp.h>
131
132 #if OPENSSL_VERSION_NUMBER < 0x10100000L
133 #define EVP_CIPHER_CTX_reset EVP_CIPHER_CTX_cleanup
134 #endif
135
136 static int des_init(PPP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv)
137 {
138     if (ctx) {
139         EVP_CIPHER_CTX *cc = EVP_CIPHER_CTX_new();
140         if (cc) {
141             if (key) {
142                 MakeKey(key, ctx->key);
143             }
144             if (EVP_CipherInit(cc, EVP_des_ecb(), ctx->key, ctx->iv, ctx->is_encr)) {
145
146                 if (EVP_CIPHER_CTX_set_padding(cc, 0)) {
147                     ctx->priv = cc;
148                     return 1;
149                 }
150             }
151             EVP_CIPHER_CTX_free(cc);
152         }
153     }
154     return 0;
155 }
156
157 static int des_update(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl)
158 {
159     if (ctx) {
160         return EVP_CipherUpdate((EVP_CIPHER_CTX*) ctx->priv, out, outl, in, inl);
161     }
162     return 0;
163 }
164
165 static int des_final(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
166 {
167     if (ctx) {
168         return EVP_CipherFinal((EVP_CIPHER_CTX*) ctx->priv, out, outl);
169     }
170     return 0;
171 }
172
173 static void des_clean(PPP_CIPHER_CTX *ctx)
174 {
175     if (ctx->priv) {
176         EVP_CIPHER_CTX_free((EVP_CIPHER_CTX*) ctx->priv);
177         ctx->priv = NULL;
178     }
179 }
180
181 /**
182  * Using the EVP_ interface with openssl, there is no replacement for the
183  * DES_set_key() function, and each iteration of DesEncrypt(Clear,Key,Cipher)
184  * per RFC2759 is another iteration of the EVP_CipherInit, EVP_CipherUpdate,
185  * EVP_CipherFinal functions.
186  *
187  * As a work-around, we reset the EVP_CIPHER_CTX object, and re-initializes
188  * the context by calling EVP_CipherInit() with the new key.
189  */
190 static void des_set_key(PPP_CIPHER_CTX *ctx, const unsigned char *key)
191 {
192     EVP_CIPHER_CTX_reset((EVP_CIPHER_CTX*) ctx->priv);
193     MakeKey(key, ctx->key);
194     EVP_CipherInit((EVP_CIPHER_CTX*) ctx->priv, EVP_des_ecb(), ctx->key, ctx->iv, ctx->is_encr);
195 }
196
197 #else
198
199 /*
200  * DES related functions are imported from openssl 3.0 project with the 
201  * follwoing license:
202  *
203  * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
204  *
205  * Licensed under the Apache License 2.0 (the "License").  You may not use
206  * this file except in compliance with the License.  You can obtain a copy
207  * in the file LICENSE in the source distribution or at
208  * https://www.openssl.org/source/license.html
209  */
210
211 typedef unsigned int DES_LONG;
212 typedef unsigned char DES_cblock[8];
213 typedef struct DES_ks {
214     union {
215         DES_cblock cblock;
216         /*
217          * make sure things are correct size on machines with 8 byte longs
218          */
219         DES_LONG deslong[2];
220     } ks[16];
221 } DES_key_schedule;
222
223
224 #define c2l(c,l)        (l =((DES_LONG)(*((c)++)))    , \
225                          l|=((DES_LONG)(*((c)++)))<< 8L, \
226                          l|=((DES_LONG)(*((c)++)))<<16L, \
227                          l|=((DES_LONG)(*((c)++)))<<24L)
228
229 # define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
230                          *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
231                          *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
232                          *((c)++)=(unsigned char)(((l)>>24L)&0xff))
233
234 #define ITERATIONS 16
235
236 #define ROTATE(a,n)     (((a)>>(n))+((a)<<(32-(n))))
237
238 # define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
239         (b)^=(t),\
240         (a)^=((t)<<(n)))
241
242 #define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
243         (a)=(a)^(t)^(t>>(16-(n))))
244
245 # define IP(l,r) \
246         { \
247         register DES_LONG tt; \
248         PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
249         PERM_OP(l,r,tt,16,0x0000ffffL); \
250         PERM_OP(r,l,tt, 2,0x33333333L); \
251         PERM_OP(l,r,tt, 8,0x00ff00ffL); \
252         PERM_OP(r,l,tt, 1,0x55555555L); \
253         }
254
255 # define FP(l,r) \
256         { \
257         register DES_LONG tt; \
258         PERM_OP(l,r,tt, 1,0x55555555L); \
259         PERM_OP(r,l,tt, 8,0x00ff00ffL); \
260         PERM_OP(l,r,tt, 2,0x33333333L); \
261         PERM_OP(r,l,tt,16,0x0000ffffL); \
262         PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
263         }
264
265 #define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
266 #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
267         u=R^s[S  ]; \
268         t=R^s[S+1]
269
270 #define D_ENCRYPT(LL,R,S) { \
271         LOAD_DATA_tmp(R,S,u,t,E0,E1); \
272         t=ROTATE(t,4); \
273         LL^= \
274             DES_SPtrans[0][(u>> 2L)&0x3f]^ \
275             DES_SPtrans[2][(u>>10L)&0x3f]^ \
276             DES_SPtrans[4][(u>>18L)&0x3f]^ \
277             DES_SPtrans[6][(u>>26L)&0x3f]^ \
278             DES_SPtrans[1][(t>> 2L)&0x3f]^ \
279             DES_SPtrans[3][(t>>10L)&0x3f]^ \
280             DES_SPtrans[5][(t>>18L)&0x3f]^ \
281             DES_SPtrans[7][(t>>26L)&0x3f]; }
282
283
284 static const DES_LONG DES_SPtrans[8][64] = {
285     {
286         /* nibble 0 */
287         0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
288         0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
289         0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
290         0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
291         0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
292         0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
293         0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
294         0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
295         0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
296         0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
297         0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
298         0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
299         0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
300         0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
301         0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
302         0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
303     },
304     {
305         /* nibble 1 */
306         0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
307         0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
308         0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
309         0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
310         0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
311         0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
312         0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
313         0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
314         0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
315         0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
316         0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
317         0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
318         0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
319         0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
320         0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
321         0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
322     },
323     {
324         /* nibble 2 */
325         0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
326         0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
327         0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
328         0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
329         0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
330         0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
331         0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
332         0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
333         0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
334         0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
335         0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
336         0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
337         0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
338         0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
339         0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
340         0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
341     },
342     {
343         /* nibble 3 */
344         0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
345         0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
346         0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
347         0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
348         0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
349         0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
350         0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
351         0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
352         0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
353         0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
354         0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
355         0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
356         0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
357         0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
358         0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
359         0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
360     },
361     {
362         /* nibble 4 */
363         0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
364         0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
365         0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
366         0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
367         0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
368         0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
369         0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
370         0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
371         0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
372         0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
373         0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
374         0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
375         0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
376         0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
377         0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
378         0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
379     },
380     {
381         /* nibble 5 */
382         0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
383         0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
384         0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
385         0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
386         0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
387         0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
388         0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
389         0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
390         0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
391         0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
392         0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
393         0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
394         0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
395         0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
396         0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
397         0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
398     },
399     {
400         /* nibble 6 */
401         0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
402         0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
403         0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
404         0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
405         0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
406         0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
407         0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
408         0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
409         0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
410         0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
411         0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
412         0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
413         0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
414         0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
415         0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
416         0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
417     },
418     {
419         /* nibble 7 */
420         0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
421         0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
422         0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
423         0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
424         0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
425         0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
426         0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
427         0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
428         0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
429         0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
430         0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
431         0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
432         0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
433         0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
434         0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
435         0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
436     }
437 };
438
439 static const DES_LONG des_skb[8][64] = {
440     {
441      /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
442      0x00000000L, 0x00000010L, 0x20000000L, 0x20000010L,
443      0x00010000L, 0x00010010L, 0x20010000L, 0x20010010L,
444      0x00000800L, 0x00000810L, 0x20000800L, 0x20000810L,
445      0x00010800L, 0x00010810L, 0x20010800L, 0x20010810L,
446      0x00000020L, 0x00000030L, 0x20000020L, 0x20000030L,
447      0x00010020L, 0x00010030L, 0x20010020L, 0x20010030L,
448      0x00000820L, 0x00000830L, 0x20000820L, 0x20000830L,
449      0x00010820L, 0x00010830L, 0x20010820L, 0x20010830L,
450      0x00080000L, 0x00080010L, 0x20080000L, 0x20080010L,
451      0x00090000L, 0x00090010L, 0x20090000L, 0x20090010L,
452      0x00080800L, 0x00080810L, 0x20080800L, 0x20080810L,
453      0x00090800L, 0x00090810L, 0x20090800L, 0x20090810L,
454      0x00080020L, 0x00080030L, 0x20080020L, 0x20080030L,
455      0x00090020L, 0x00090030L, 0x20090020L, 0x20090030L,
456      0x00080820L, 0x00080830L, 0x20080820L, 0x20080830L,
457      0x00090820L, 0x00090830L, 0x20090820L, 0x20090830L,
458      },
459     {
460      /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
461      0x00000000L, 0x02000000L, 0x00002000L, 0x02002000L,
462      0x00200000L, 0x02200000L, 0x00202000L, 0x02202000L,
463      0x00000004L, 0x02000004L, 0x00002004L, 0x02002004L,
464      0x00200004L, 0x02200004L, 0x00202004L, 0x02202004L,
465      0x00000400L, 0x02000400L, 0x00002400L, 0x02002400L,
466      0x00200400L, 0x02200400L, 0x00202400L, 0x02202400L,
467      0x00000404L, 0x02000404L, 0x00002404L, 0x02002404L,
468      0x00200404L, 0x02200404L, 0x00202404L, 0x02202404L,
469      0x10000000L, 0x12000000L, 0x10002000L, 0x12002000L,
470      0x10200000L, 0x12200000L, 0x10202000L, 0x12202000L,
471      0x10000004L, 0x12000004L, 0x10002004L, 0x12002004L,
472      0x10200004L, 0x12200004L, 0x10202004L, 0x12202004L,
473      0x10000400L, 0x12000400L, 0x10002400L, 0x12002400L,
474      0x10200400L, 0x12200400L, 0x10202400L, 0x12202400L,
475      0x10000404L, 0x12000404L, 0x10002404L, 0x12002404L,
476      0x10200404L, 0x12200404L, 0x10202404L, 0x12202404L,
477      },
478     {
479      /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
480      0x00000000L, 0x00000001L, 0x00040000L, 0x00040001L,
481      0x01000000L, 0x01000001L, 0x01040000L, 0x01040001L,
482      0x00000002L, 0x00000003L, 0x00040002L, 0x00040003L,
483      0x01000002L, 0x01000003L, 0x01040002L, 0x01040003L,
484      0x00000200L, 0x00000201L, 0x00040200L, 0x00040201L,
485      0x01000200L, 0x01000201L, 0x01040200L, 0x01040201L,
486      0x00000202L, 0x00000203L, 0x00040202L, 0x00040203L,
487      0x01000202L, 0x01000203L, 0x01040202L, 0x01040203L,
488      0x08000000L, 0x08000001L, 0x08040000L, 0x08040001L,
489      0x09000000L, 0x09000001L, 0x09040000L, 0x09040001L,
490      0x08000002L, 0x08000003L, 0x08040002L, 0x08040003L,
491      0x09000002L, 0x09000003L, 0x09040002L, 0x09040003L,
492      0x08000200L, 0x08000201L, 0x08040200L, 0x08040201L,
493      0x09000200L, 0x09000201L, 0x09040200L, 0x09040201L,
494      0x08000202L, 0x08000203L, 0x08040202L, 0x08040203L,
495      0x09000202L, 0x09000203L, 0x09040202L, 0x09040203L,
496      },
497     {
498      /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
499      0x00000000L, 0x00100000L, 0x00000100L, 0x00100100L,
500      0x00000008L, 0x00100008L, 0x00000108L, 0x00100108L,
501      0x00001000L, 0x00101000L, 0x00001100L, 0x00101100L,
502      0x00001008L, 0x00101008L, 0x00001108L, 0x00101108L,
503      0x04000000L, 0x04100000L, 0x04000100L, 0x04100100L,
504      0x04000008L, 0x04100008L, 0x04000108L, 0x04100108L,
505      0x04001000L, 0x04101000L, 0x04001100L, 0x04101100L,
506      0x04001008L, 0x04101008L, 0x04001108L, 0x04101108L,
507      0x00020000L, 0x00120000L, 0x00020100L, 0x00120100L,
508      0x00020008L, 0x00120008L, 0x00020108L, 0x00120108L,
509      0x00021000L, 0x00121000L, 0x00021100L, 0x00121100L,
510      0x00021008L, 0x00121008L, 0x00021108L, 0x00121108L,
511      0x04020000L, 0x04120000L, 0x04020100L, 0x04120100L,
512      0x04020008L, 0x04120008L, 0x04020108L, 0x04120108L,
513      0x04021000L, 0x04121000L, 0x04021100L, 0x04121100L,
514      0x04021008L, 0x04121008L, 0x04021108L, 0x04121108L,
515      },
516     {
517      /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
518      0x00000000L, 0x10000000L, 0x00010000L, 0x10010000L,
519      0x00000004L, 0x10000004L, 0x00010004L, 0x10010004L,
520      0x20000000L, 0x30000000L, 0x20010000L, 0x30010000L,
521      0x20000004L, 0x30000004L, 0x20010004L, 0x30010004L,
522      0x00100000L, 0x10100000L, 0x00110000L, 0x10110000L,
523      0x00100004L, 0x10100004L, 0x00110004L, 0x10110004L,
524      0x20100000L, 0x30100000L, 0x20110000L, 0x30110000L,
525      0x20100004L, 0x30100004L, 0x20110004L, 0x30110004L,
526      0x00001000L, 0x10001000L, 0x00011000L, 0x10011000L,
527      0x00001004L, 0x10001004L, 0x00011004L, 0x10011004L,
528      0x20001000L, 0x30001000L, 0x20011000L, 0x30011000L,
529      0x20001004L, 0x30001004L, 0x20011004L, 0x30011004L,
530      0x00101000L, 0x10101000L, 0x00111000L, 0x10111000L,
531      0x00101004L, 0x10101004L, 0x00111004L, 0x10111004L,
532      0x20101000L, 0x30101000L, 0x20111000L, 0x30111000L,
533      0x20101004L, 0x30101004L, 0x20111004L, 0x30111004L,
534      },
535     {   
536      /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
537      0x00000000L, 0x08000000L, 0x00000008L, 0x08000008L,
538      0x00000400L, 0x08000400L, 0x00000408L, 0x08000408L,
539      0x00020000L, 0x08020000L, 0x00020008L, 0x08020008L,
540      0x00020400L, 0x08020400L, 0x00020408L, 0x08020408L,
541      0x00000001L, 0x08000001L, 0x00000009L, 0x08000009L,
542      0x00000401L, 0x08000401L, 0x00000409L, 0x08000409L,
543      0x00020001L, 0x08020001L, 0x00020009L, 0x08020009L,
544      0x00020401L, 0x08020401L, 0x00020409L, 0x08020409L,
545      0x02000000L, 0x0A000000L, 0x02000008L, 0x0A000008L,
546      0x02000400L, 0x0A000400L, 0x02000408L, 0x0A000408L,
547      0x02020000L, 0x0A020000L, 0x02020008L, 0x0A020008L,
548      0x02020400L, 0x0A020400L, 0x02020408L, 0x0A020408L,
549      0x02000001L, 0x0A000001L, 0x02000009L, 0x0A000009L,
550      0x02000401L, 0x0A000401L, 0x02000409L, 0x0A000409L,
551      0x02020001L, 0x0A020001L, 0x02020009L, 0x0A020009L,
552      0x02020401L, 0x0A020401L, 0x02020409L, 0x0A020409L,
553      },
554     {
555      /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
556      0x00000000L, 0x00000100L, 0x00080000L, 0x00080100L,
557      0x01000000L, 0x01000100L, 0x01080000L, 0x01080100L,
558      0x00000010L, 0x00000110L, 0x00080010L, 0x00080110L,
559      0x01000010L, 0x01000110L, 0x01080010L, 0x01080110L,
560      0x00200000L, 0x00200100L, 0x00280000L, 0x00280100L,
561      0x01200000L, 0x01200100L, 0x01280000L, 0x01280100L,
562      0x00200010L, 0x00200110L, 0x00280010L, 0x00280110L,
563      0x01200010L, 0x01200110L, 0x01280010L, 0x01280110L,
564      0x00000200L, 0x00000300L, 0x00080200L, 0x00080300L,
565      0x01000200L, 0x01000300L, 0x01080200L, 0x01080300L,
566      0x00000210L, 0x00000310L, 0x00080210L, 0x00080310L,
567      0x01000210L, 0x01000310L, 0x01080210L, 0x01080310L,
568      0x00200200L, 0x00200300L, 0x00280200L, 0x00280300L,
569      0x01200200L, 0x01200300L, 0x01280200L, 0x01280300L,
570      0x00200210L, 0x00200310L, 0x00280210L, 0x00280310L,
571      0x01200210L, 0x01200310L, 0x01280210L, 0x01280310L,
572      },
573     {
574      /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
575      0x00000000L, 0x04000000L, 0x00040000L, 0x04040000L,
576      0x00000002L, 0x04000002L, 0x00040002L, 0x04040002L,
577      0x00002000L, 0x04002000L, 0x00042000L, 0x04042000L,
578      0x00002002L, 0x04002002L, 0x00042002L, 0x04042002L,
579      0x00000020L, 0x04000020L, 0x00040020L, 0x04040020L,
580      0x00000022L, 0x04000022L, 0x00040022L, 0x04040022L,
581      0x00002020L, 0x04002020L, 0x00042020L, 0x04042020L,
582      0x00002022L, 0x04002022L, 0x00042022L, 0x04042022L,
583      0x00000800L, 0x04000800L, 0x00040800L, 0x04040800L,
584      0x00000802L, 0x04000802L, 0x00040802L, 0x04040802L,
585      0x00002800L, 0x04002800L, 0x00042800L, 0x04042800L,
586      0x00002802L, 0x04002802L, 0x00042802L, 0x04042802L,
587      0x00000820L, 0x04000820L, 0x00040820L, 0x04040820L,
588      0x00000822L, 0x04000822L, 0x00040822L, 0x04040822L,
589      0x00002820L, 0x04002820L, 0x00042820L, 0x04042820L,
590      0x00002822L, 0x04002822L, 0x00042822L, 0x04042822L,
591      }
592 };
593
594
595 static void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
596 {
597     register DES_LONG l, r, t, u;
598     register DES_LONG *s; 
599
600     r = data[0];
601     l = data[1];
602
603     IP(r, l); 
604     /*  
605      * Things have been modified so that the initial rotate is done outside
606      * the loop.  This required the DES_SPtrans values in sp.h to be rotated
607      * 1 bit to the right. One perl script later and things have a 5% speed
608      * up on a sparc2. Thanks to Richard Outerbridge for pointing this out.
609      */
610     /* clear the top bits on machines with 8byte longs */
611     /* shift left by 2 */
612     r = ROTATE(r, 29) & 0xffffffffL;
613     l = ROTATE(l, 29) & 0xffffffffL;
614
615     s = ks->ks->deslong;
616     /*  
617      * I don't know if it is worth the effort of loop unrolling the inner
618      * loop
619      */
620     if (enc) {
621         D_ENCRYPT(l, r, 0);     /* 1 */
622         D_ENCRYPT(r, l, 2);     /* 2 */
623         D_ENCRYPT(l, r, 4);     /* 3 */
624         D_ENCRYPT(r, l, 6);     /* 4 */
625         D_ENCRYPT(l, r, 8);     /* 5 */
626         D_ENCRYPT(r, l, 10);    /* 6 */
627         D_ENCRYPT(l, r, 12);    /* 7 */
628         D_ENCRYPT(r, l, 14);    /* 8 */
629         D_ENCRYPT(l, r, 16);    /* 9 */
630         D_ENCRYPT(r, l, 18);    /* 10 */
631         D_ENCRYPT(l, r, 20);    /* 11 */
632         D_ENCRYPT(r, l, 22);    /* 12 */
633         D_ENCRYPT(l, r, 24);    /* 13 */
634         D_ENCRYPT(r, l, 26);    /* 14 */
635         D_ENCRYPT(l, r, 28);    /* 15 */
636         D_ENCRYPT(r, l, 30);    /* 16 */
637     } else {
638         D_ENCRYPT(l, r, 30);    /* 16 */
639         D_ENCRYPT(r, l, 28);    /* 15 */
640         D_ENCRYPT(l, r, 26);    /* 14 */
641         D_ENCRYPT(r, l, 24);    /* 13 */
642         D_ENCRYPT(l, r, 22);    /* 12 */
643         D_ENCRYPT(r, l, 20);    /* 11 */
644         D_ENCRYPT(l, r, 18);    /* 10 */
645         D_ENCRYPT(r, l, 16);    /* 9 */
646         D_ENCRYPT(l, r, 14);    /* 8 */
647         D_ENCRYPT(r, l, 12);    /* 7 */
648         D_ENCRYPT(l, r, 10);    /* 6 */
649         D_ENCRYPT(r, l, 8);     /* 5 */
650         D_ENCRYPT(l, r, 6);     /* 4 */
651         D_ENCRYPT(r, l, 4);     /* 3 */
652         D_ENCRYPT(l, r, 2);     /* 2 */
653         D_ENCRYPT(r, l, 0);     /* 1 */
654     }   
655
656     /* rotate and clear the top bits on machines with 8byte longs */
657     l = ROTATE(l, 3) & 0xffffffffL;
658     r = ROTATE(r, 3) & 0xffffffffL;
659
660     FP(r, l); 
661     data[0] = l;
662     data[1] = r;
663     l = r = t = u = 0;
664 }
665
666
667 static void DES_ecb_encrypt(const DES_cblock *input, DES_cblock *output,
668                      DES_key_schedule *ks, int enc)
669 {
670     register DES_LONG l;
671     DES_LONG ll[2];
672     const unsigned char *in = &(*input)[0];
673     unsigned char *out = &(*output)[0];
674
675     c2l(in, l); 
676     ll[0] = l;
677     c2l(in, l); 
678     ll[1] = l;
679     DES_encrypt1(ll, ks, enc);
680     l = ll[0];
681     l2c(l, out);
682     l = ll[1];
683     l2c(l, out);
684     l = ll[0] = ll[1] = 0;
685 }
686
687
688 static void DES_set_key(const DES_cblock *key, DES_key_schedule *schedule)
689 {
690     static const int shifts2[16] =
691         { 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 };
692     register DES_LONG c, d, t, s, t2;
693     register const unsigned char *in;
694     register DES_LONG *k;
695     register int i;
696
697 #ifdef OPENBSD_DEV_CRYPTO
698     memcpy(schedule->key, key, sizeof(schedule->key));
699     schedule->session = NULL;
700 #endif
701     k = &schedule->ks->deslong[0];
702     in = &(*key)[0];
703
704     c2l(in, c);
705     c2l(in, d);
706
707     /*
708      * do PC1 in 47 simple operations. Thanks to John Fletcher
709      * for the inspiration.
710      */
711     PERM_OP(d, c, t, 4, 0x0f0f0f0fL);
712     HPERM_OP(c, t, -2, 0xcccc0000L);
713     HPERM_OP(d, t, -2, 0xcccc0000L);
714     PERM_OP(d, c, t, 1, 0x55555555L);
715     PERM_OP(c, d, t, 8, 0x00ff00ffL);
716     PERM_OP(d, c, t, 1, 0x55555555L);
717     d = (((d & 0x000000ffL) << 16L) | (d & 0x0000ff00L) |
718          ((d & 0x00ff0000L) >> 16L) | ((c & 0xf0000000L) >> 4L));
719     c &= 0x0fffffffL;
720
721     for (i = 0; i < ITERATIONS; i++) {
722         if (shifts2[i]) {
723             c = ((c >> 2L) | (c << 26L));
724             d = ((d >> 2L) | (d << 26L));
725         } else {
726             c = ((c >> 1L) | (c << 27L));
727             d = ((d >> 1L) | (d << 27L));
728         }
729         c &= 0x0fffffffL;
730         d &= 0x0fffffffL;
731         /*
732          * could be a few less shifts but I am to lazy at this point in time
733          * to investigate
734          */
735         s = des_skb[0][(c) & 0x3f] |
736             des_skb[1][((c >> 6L) & 0x03) | ((c >> 7L) & 0x3c)] |
737             des_skb[2][((c >> 13L) & 0x0f) | ((c >> 14L) & 0x30)] |
738             des_skb[3][((c >> 20L) & 0x01) | ((c >> 21L) & 0x06) |
739                        ((c >> 22L) & 0x38)];
740         t = des_skb[4][(d) & 0x3f] |
741             des_skb[5][((d >> 7L) & 0x03) | ((d >> 8L) & 0x3c)] |
742             des_skb[6][(d >> 15L) & 0x3f] |
743             des_skb[7][((d >> 21L) & 0x0f) | ((d >> 22L) & 0x30)];
744
745         /* table contained 0213 4657 */
746         t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL;
747         *(k++) = ROTATE(t2, 30) & 0xffffffffL;
748
749         t2 = ((s >> 16L) | (t & 0xffff0000L));
750         *(k++) = ROTATE(t2, 26) & 0xffffffffL;
751     }
752 }
753
754 /* End of import of OpenSSL DES encryption functions */
755
756 static int des_init(PPP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv)
757 {
758     DES_key_schedule *ks = calloc(1, sizeof(DES_key_schedule));
759     if (ks) {
760
761         if (key) {
762             MakeKey(key, ctx->key);
763             DES_set_key((DES_cblock*) &ctx->key, ks);
764         }
765
766         ctx->priv = ks;
767         return 1;
768     }
769
770     return 0;
771 }
772
773 static int des_update(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl)
774 {
775     int offset = 0;
776     inl = inl / 8;
777     while (offset < inl) {
778         DES_ecb_encrypt((DES_cblock *)in + offset, (DES_cblock *)out + offset,
779             (DES_key_schedule*) ctx->priv, ctx->is_encr);
780         offset ++;
781     }
782
783     *outl = offset * 8;
784     return 1;
785 }
786
787 static int des_final(PPP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
788 {
789     return 1;
790 }
791
792 static void des_clean(PPP_CIPHER_CTX *ctx)
793 {
794     if (ctx->priv) {
795         free(ctx->priv);
796         ctx->priv = NULL;
797     }
798 }
799
800 static void des_set_key(PPP_CIPHER_CTX *ctx, const unsigned char *key)
801 {
802     MakeKey(key, ctx->key);
803     DES_set_key((DES_cblock*) &ctx->key, (DES_key_schedule*) ctx->priv);
804 }
805
806 #endif
807
808 static PPP_CIPHER ppp_des = {
809     .init_fn = des_init,
810     .update_fn = des_update,
811     .final_fn = des_final,
812     .set_key_fn = des_set_key,
813     .clean_fn = des_clean,
814 };
815
816 const PPP_CIPHER *PPP_des_ecb(void)
817 {
818     return &ppp_des;
819 }
820