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