• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
73 static 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 
93 static 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 
113 static 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 
133 static 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 
153 static 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 
173 static 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 
193 static 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 
213 static 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  */
236 static 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 
244 static 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 
des_setkey(unsigned long SK[32],unsigned char key[8])300 static 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  */
des_setkey_enc(des_context * ctx,unsigned char key[8])372 void 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  */
des_setkey_dec(des_context * ctx,unsigned char key[8])380 void 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  */
des_crypt_ecb(des_context * ctx,const unsigned char input[8],unsigned char output[8])396 void 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