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