1/*
2 *  FIPS-46-3 compliant Triple-DES implementation
3 *
4 *  Based on XySSL: Copyright (C) 2006-2008  Christophe Devine
5 *
6 *  Copyright (C) 2009  Paul Bakker <polarssl_maintainer at polarssl dot org>
7 *
8 *  All rights reserved.
9 *
10 *  Redistribution and use in source and binary forms, with or without
11 *  modification, are permitted provided that the following conditions
12 *  are met:
13 *
14 *    * Redistributions of source code must retain the above copyright
15 *      notice, this list of conditions and the following disclaimer.
16 *    * Redistributions in binary form must reproduce the above copyright
17 *      notice, this list of conditions and the following disclaimer in the
18 *      documentation and/or other materials provided with the distribution.
19 *    * Neither the names of PolarSSL or XySSL nor the names of its contributors
20 *      may be used to endorse or promote products derived from this software
21 *      without specific prior written permission.
22 *
23 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35/*
36 *  DES, on which TDES is based, was originally designed by Horst Feistel
37 *  at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
38 *
39 *  http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
40 */
41
42#include "netif/ppp/ppp_opts.h"
43#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_DES
44
45#include "netif/ppp/polarssl/des.h"
46
47/*
48 * 32-bit integer manipulation macros (big endian)
49 */
50#ifndef GET_ULONG_BE
51#define GET_ULONG_BE(n,b,i)                             \
52{                                                       \
53    (n) = ( (unsigned long) (b)[(i)    ] << 24 )        \
54        | ( (unsigned long) (b)[(i) + 1] << 16 )        \
55        | ( (unsigned long) (b)[(i) + 2] <<  8 )        \
56        | ( (unsigned long) (b)[(i) + 3]       );       \
57}
58#endif
59
60#ifndef PUT_ULONG_BE
61#define PUT_ULONG_BE(n,b,i)                             \
62{                                                       \
63    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
64    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
65    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
66    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
67}
68#endif
69
70/*
71 * Expanded DES S-boxes
72 */
73static const unsigned long SB1[64] =
74{
75    0x01010400, 0x00000000, 0x00010000, 0x01010404,
76    0x01010004, 0x00010404, 0x00000004, 0x00010000,
77    0x00000400, 0x01010400, 0x01010404, 0x00000400,
78    0x01000404, 0x01010004, 0x01000000, 0x00000004,
79    0x00000404, 0x01000400, 0x01000400, 0x00010400,
80    0x00010400, 0x01010000, 0x01010000, 0x01000404,
81    0x00010004, 0x01000004, 0x01000004, 0x00010004,
82    0x00000000, 0x00000404, 0x00010404, 0x01000000,
83    0x00010000, 0x01010404, 0x00000004, 0x01010000,
84    0x01010400, 0x01000000, 0x01000000, 0x00000400,
85    0x01010004, 0x00010000, 0x00010400, 0x01000004,
86    0x00000400, 0x00000004, 0x01000404, 0x00010404,
87    0x01010404, 0x00010004, 0x01010000, 0x01000404,
88    0x01000004, 0x00000404, 0x00010404, 0x01010400,
89    0x00000404, 0x01000400, 0x01000400, 0x00000000,
90    0x00010004, 0x00010400, 0x00000000, 0x01010004
91};
92
93static const unsigned long SB2[64] =
94{
95    0x80108020, 0x80008000, 0x00008000, 0x00108020,
96    0x00100000, 0x00000020, 0x80100020, 0x80008020,
97    0x80000020, 0x80108020, 0x80108000, 0x80000000,
98    0x80008000, 0x00100000, 0x00000020, 0x80100020,
99    0x00108000, 0x00100020, 0x80008020, 0x00000000,
100    0x80000000, 0x00008000, 0x00108020, 0x80100000,
101    0x00100020, 0x80000020, 0x00000000, 0x00108000,
102    0x00008020, 0x80108000, 0x80100000, 0x00008020,
103    0x00000000, 0x00108020, 0x80100020, 0x00100000,
104    0x80008020, 0x80100000, 0x80108000, 0x00008000,
105    0x80100000, 0x80008000, 0x00000020, 0x80108020,
106    0x00108020, 0x00000020, 0x00008000, 0x80000000,
107    0x00008020, 0x80108000, 0x00100000, 0x80000020,
108    0x00100020, 0x80008020, 0x80000020, 0x00100020,
109    0x00108000, 0x00000000, 0x80008000, 0x00008020,
110    0x80000000, 0x80100020, 0x80108020, 0x00108000
111};
112
113static const unsigned long SB3[64] =
114{
115    0x00000208, 0x08020200, 0x00000000, 0x08020008,
116    0x08000200, 0x00000000, 0x00020208, 0x08000200,
117    0x00020008, 0x08000008, 0x08000008, 0x00020000,
118    0x08020208, 0x00020008, 0x08020000, 0x00000208,
119    0x08000000, 0x00000008, 0x08020200, 0x00000200,
120    0x00020200, 0x08020000, 0x08020008, 0x00020208,
121    0x08000208, 0x00020200, 0x00020000, 0x08000208,
122    0x00000008, 0x08020208, 0x00000200, 0x08000000,
123    0x08020200, 0x08000000, 0x00020008, 0x00000208,
124    0x00020000, 0x08020200, 0x08000200, 0x00000000,
125    0x00000200, 0x00020008, 0x08020208, 0x08000200,
126    0x08000008, 0x00000200, 0x00000000, 0x08020008,
127    0x08000208, 0x00020000, 0x08000000, 0x08020208,
128    0x00000008, 0x00020208, 0x00020200, 0x08000008,
129    0x08020000, 0x08000208, 0x00000208, 0x08020000,
130    0x00020208, 0x00000008, 0x08020008, 0x00020200
131};
132
133static const unsigned long SB4[64] =
134{
135    0x00802001, 0x00002081, 0x00002081, 0x00000080,
136    0x00802080, 0x00800081, 0x00800001, 0x00002001,
137    0x00000000, 0x00802000, 0x00802000, 0x00802081,
138    0x00000081, 0x00000000, 0x00800080, 0x00800001,
139    0x00000001, 0x00002000, 0x00800000, 0x00802001,
140    0x00000080, 0x00800000, 0x00002001, 0x00002080,
141    0x00800081, 0x00000001, 0x00002080, 0x00800080,
142    0x00002000, 0x00802080, 0x00802081, 0x00000081,
143    0x00800080, 0x00800001, 0x00802000, 0x00802081,
144    0x00000081, 0x00000000, 0x00000000, 0x00802000,
145    0x00002080, 0x00800080, 0x00800081, 0x00000001,
146    0x00802001, 0x00002081, 0x00002081, 0x00000080,
147    0x00802081, 0x00000081, 0x00000001, 0x00002000,
148    0x00800001, 0x00002001, 0x00802080, 0x00800081,
149    0x00002001, 0x00002080, 0x00800000, 0x00802001,
150    0x00000080, 0x00800000, 0x00002000, 0x00802080
151};
152
153static const unsigned long SB5[64] =
154{
155    0x00000100, 0x02080100, 0x02080000, 0x42000100,
156    0x00080000, 0x00000100, 0x40000000, 0x02080000,
157    0x40080100, 0x00080000, 0x02000100, 0x40080100,
158    0x42000100, 0x42080000, 0x00080100, 0x40000000,
159    0x02000000, 0x40080000, 0x40080000, 0x00000000,
160    0x40000100, 0x42080100, 0x42080100, 0x02000100,
161    0x42080000, 0x40000100, 0x00000000, 0x42000000,
162    0x02080100, 0x02000000, 0x42000000, 0x00080100,
163    0x00080000, 0x42000100, 0x00000100, 0x02000000,
164    0x40000000, 0x02080000, 0x42000100, 0x40080100,
165    0x02000100, 0x40000000, 0x42080000, 0x02080100,
166    0x40080100, 0x00000100, 0x02000000, 0x42080000,
167    0x42080100, 0x00080100, 0x42000000, 0x42080100,
168    0x02080000, 0x00000000, 0x40080000, 0x42000000,
169    0x00080100, 0x02000100, 0x40000100, 0x00080000,
170    0x00000000, 0x40080000, 0x02080100, 0x40000100
171};
172
173static const unsigned long SB6[64] =
174{
175    0x20000010, 0x20400000, 0x00004000, 0x20404010,
176    0x20400000, 0x00000010, 0x20404010, 0x00400000,
177    0x20004000, 0x00404010, 0x00400000, 0x20000010,
178    0x00400010, 0x20004000, 0x20000000, 0x00004010,
179    0x00000000, 0x00400010, 0x20004010, 0x00004000,
180    0x00404000, 0x20004010, 0x00000010, 0x20400010,
181    0x20400010, 0x00000000, 0x00404010, 0x20404000,
182    0x00004010, 0x00404000, 0x20404000, 0x20000000,
183    0x20004000, 0x00000010, 0x20400010, 0x00404000,
184    0x20404010, 0x00400000, 0x00004010, 0x20000010,
185    0x00400000, 0x20004000, 0x20000000, 0x00004010,
186    0x20000010, 0x20404010, 0x00404000, 0x20400000,
187    0x00404010, 0x20404000, 0x00000000, 0x20400010,
188    0x00000010, 0x00004000, 0x20400000, 0x00404010,
189    0x00004000, 0x00400010, 0x20004010, 0x00000000,
190    0x20404000, 0x20000000, 0x00400010, 0x20004010
191};
192
193static const unsigned long SB7[64] =
194{
195    0x00200000, 0x04200002, 0x04000802, 0x00000000,
196    0x00000800, 0x04000802, 0x00200802, 0x04200800,
197    0x04200802, 0x00200000, 0x00000000, 0x04000002,
198    0x00000002, 0x04000000, 0x04200002, 0x00000802,
199    0x04000800, 0x00200802, 0x00200002, 0x04000800,
200    0x04000002, 0x04200000, 0x04200800, 0x00200002,
201    0x04200000, 0x00000800, 0x00000802, 0x04200802,
202    0x00200800, 0x00000002, 0x04000000, 0x00200800,
203    0x04000000, 0x00200800, 0x00200000, 0x04000802,
204    0x04000802, 0x04200002, 0x04200002, 0x00000002,
205    0x00200002, 0x04000000, 0x04000800, 0x00200000,
206    0x04200800, 0x00000802, 0x00200802, 0x04200800,
207    0x00000802, 0x04000002, 0x04200802, 0x04200000,
208    0x00200800, 0x00000000, 0x00000002, 0x04200802,
209    0x00000000, 0x00200802, 0x04200000, 0x00000800,
210    0x04000002, 0x04000800, 0x00000800, 0x00200002
211};
212
213static const unsigned long SB8[64] =
214{
215    0x10001040, 0x00001000, 0x00040000, 0x10041040,
216    0x10000000, 0x10001040, 0x00000040, 0x10000000,
217    0x00040040, 0x10040000, 0x10041040, 0x00041000,
218    0x10041000, 0x00041040, 0x00001000, 0x00000040,
219    0x10040000, 0x10000040, 0x10001000, 0x00001040,
220    0x00041000, 0x00040040, 0x10040040, 0x10041000,
221    0x00001040, 0x00000000, 0x00000000, 0x10040040,
222    0x10000040, 0x10001000, 0x00041040, 0x00040000,
223    0x00041040, 0x00040000, 0x10041000, 0x00001000,
224    0x00000040, 0x10040040, 0x00001000, 0x00041040,
225    0x10001000, 0x00000040, 0x10000040, 0x10040000,
226    0x10040040, 0x10000000, 0x00040000, 0x10001040,
227    0x00000000, 0x10041040, 0x00040040, 0x10000040,
228    0x10040000, 0x10001000, 0x10001040, 0x00000000,
229    0x10041040, 0x00041000, 0x00041000, 0x00001040,
230    0x00001040, 0x00040040, 0x10000000, 0x10041000
231};
232
233/*
234 * PC1: left and right halves bit-swap
235 */
236static const unsigned long LHs[16] =
237{
238    0x00000000, 0x00000001, 0x00000100, 0x00000101,
239    0x00010000, 0x00010001, 0x00010100, 0x00010101,
240    0x01000000, 0x01000001, 0x01000100, 0x01000101,
241    0x01010000, 0x01010001, 0x01010100, 0x01010101
242};
243
244static const unsigned long RHs[16] =
245{
246    0x00000000, 0x01000000, 0x00010000, 0x01010000,
247    0x00000100, 0x01000100, 0x00010100, 0x01010100,
248    0x00000001, 0x01000001, 0x00010001, 0x01010001,
249    0x00000101, 0x01000101, 0x00010101, 0x01010101,
250};
251
252/*
253 * Initial Permutation macro
254 */
255#define DES_IP(X,Y)                                             \
256{                                                               \
257    T = ((X >>  4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T <<  4);   \
258    T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16);   \
259    T = ((Y >>  2) ^ X) & 0x33333333; X ^= T; Y ^= (T <<  2);   \
260    T = ((Y >>  8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T <<  8);   \
261    Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF;                    \
262    T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T;                   \
263    X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF;                    \
264}
265
266/*
267 * Final Permutation macro
268 */
269#define DES_FP(X,Y)                                             \
270{                                                               \
271    X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF;                    \
272    T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T;                   \
273    Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF;                    \
274    T = ((Y >>  8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T <<  8);   \
275    T = ((Y >>  2) ^ X) & 0x33333333; X ^= T; Y ^= (T <<  2);   \
276    T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16);   \
277    T = ((X >>  4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T <<  4);   \
278}
279
280/*
281 * DES round macro
282 */
283#define DES_ROUND(X,Y)                          \
284{                                               \
285    T = *SK++ ^ X;                              \
286    Y ^= SB8[ (T      ) & 0x3F ] ^              \
287         SB6[ (T >>  8) & 0x3F ] ^              \
288         SB4[ (T >> 16) & 0x3F ] ^              \
289         SB2[ (T >> 24) & 0x3F ];               \
290                                                \
291    T = *SK++ ^ ((X << 28) | (X >> 4));         \
292    Y ^= SB7[ (T      ) & 0x3F ] ^              \
293         SB5[ (T >>  8) & 0x3F ] ^              \
294         SB3[ (T >> 16) & 0x3F ] ^              \
295         SB1[ (T >> 24) & 0x3F ];               \
296}
297
298#define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; }
299
300static void des_setkey( unsigned long SK[32], unsigned char key[8] )
301{
302    int i;
303    unsigned long X, Y, T;
304
305    GET_ULONG_BE( X, key, 0 );
306    GET_ULONG_BE( Y, key, 4 );
307
308    /*
309     * Permuted Choice 1
310     */
311    T =  ((Y >>  4) ^ X) & 0x0F0F0F0F;  X ^= T; Y ^= (T <<  4);
312    T =  ((Y      ) ^ X) & 0x10101010;  X ^= T; Y ^= (T      );
313
314    X =   (LHs[ (X      ) & 0xF] << 3) | (LHs[ (X >>  8) & 0xF ] << 2)
315        | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ]     )
316        | (LHs[ (X >>  5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
317        | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
318
319    Y =   (RHs[ (Y >>  1) & 0xF] << 3) | (RHs[ (Y >>  9) & 0xF ] << 2)
320        | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ]     )
321        | (RHs[ (Y >>  4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
322        | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
323
324    X &= 0x0FFFFFFF;
325    Y &= 0x0FFFFFFF;
326
327    /*
328     * calculate subkeys
329     */
330    for( i = 0; i < 16; i++ )
331    {
332        if( i < 2 || i == 8 || i == 15 )
333        {
334            X = ((X <<  1) | (X >> 27)) & 0x0FFFFFFF;
335            Y = ((Y <<  1) | (Y >> 27)) & 0x0FFFFFFF;
336        }
337        else
338        {
339            X = ((X <<  2) | (X >> 26)) & 0x0FFFFFFF;
340            Y = ((Y <<  2) | (Y >> 26)) & 0x0FFFFFFF;
341        }
342
343        *SK++ =   ((X <<  4) & 0x24000000) | ((X << 28) & 0x10000000)
344                | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
345                | ((X <<  6) & 0x01000000) | ((X <<  9) & 0x00200000)
346                | ((X >>  1) & 0x00100000) | ((X << 10) & 0x00040000)
347                | ((X <<  2) & 0x00020000) | ((X >> 10) & 0x00010000)
348                | ((Y >> 13) & 0x00002000) | ((Y >>  4) & 0x00001000)
349                | ((Y <<  6) & 0x00000800) | ((Y >>  1) & 0x00000400)
350                | ((Y >> 14) & 0x00000200) | ((Y      ) & 0x00000100)
351                | ((Y >>  5) & 0x00000020) | ((Y >> 10) & 0x00000010)
352                | ((Y >>  3) & 0x00000008) | ((Y >> 18) & 0x00000004)
353                | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
354
355        *SK++ =   ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
356                | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
357                | ((X >>  2) & 0x02000000) | ((X <<  1) & 0x01000000)
358                | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
359                | ((X <<  3) & 0x00080000) | ((X >>  6) & 0x00040000)
360                | ((X << 15) & 0x00020000) | ((X >>  4) & 0x00010000)
361                | ((Y >>  2) & 0x00002000) | ((Y <<  8) & 0x00001000)
362                | ((Y >> 14) & 0x00000808) | ((Y >>  9) & 0x00000400)
363                | ((Y      ) & 0x00000200) | ((Y <<  7) & 0x00000100)
364                | ((Y >>  7) & 0x00000020) | ((Y >>  3) & 0x00000011)
365                | ((Y <<  2) & 0x00000004) | ((Y >> 21) & 0x00000002);
366    }
367}
368
369/*
370 * DES key schedule (56-bit, encryption)
371 */
372void des_setkey_enc( des_context *ctx, unsigned char key[8] )
373{
374    des_setkey( ctx->sk, key );
375}
376
377/*
378 * DES key schedule (56-bit, decryption)
379 */
380void des_setkey_dec( des_context *ctx, unsigned char key[8] )
381{
382    int i;
383
384    des_setkey( ctx->sk, key );
385
386    for( i = 0; i < 16; i += 2 )
387    {
388        SWAP( ctx->sk[i    ], ctx->sk[30 - i] );
389        SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
390    }
391}
392
393/*
394 * DES-ECB block encryption/decryption
395 */
396void des_crypt_ecb( des_context *ctx,
397                    const unsigned char input[8],
398                    unsigned char output[8] )
399{
400    int i;
401    unsigned long X, Y, T, *SK;
402
403    SK = ctx->sk;
404
405    GET_ULONG_BE( X, input, 0 );
406    GET_ULONG_BE( Y, input, 4 );
407
408    DES_IP( X, Y );
409
410    for( i = 0; i < 8; i++ )
411    {
412        DES_ROUND( Y, X );
413        DES_ROUND( X, Y );
414    }
415
416    DES_FP( Y, X );
417
418    PUT_ULONG_BE( Y, output, 0 );
419    PUT_ULONG_BE( X, output, 4 );
420}
421
422#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_DES */
423