]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/CyaSSL/ctaocrypt/src/des3.c
Commit 3 RX100 low power demos.
[freertos] / FreeRTOS-Plus / CyaSSL / ctaocrypt / src / des3.c
1 /* des3.c
2  *
3  * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
4  *
5  * This file is part of CyaSSL.
6  *
7  * CyaSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * CyaSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24 #endif
25
26 #ifndef NO_DES3
27
28 #include <cyassl/ctaocrypt/des3.h>
29
30 #ifdef NO_INLINE
31     #include <cyassl/ctaocrypt/misc.h>
32 #else
33     #include <ctaocrypt/src/misc.c>
34 #endif
35
36
37 /* permuted choice table (key) */
38 static const byte pc1[] = {
39        57, 49, 41, 33, 25, 17,  9,
40         1, 58, 50, 42, 34, 26, 18,
41        10,  2, 59, 51, 43, 35, 27,
42        19, 11,  3, 60, 52, 44, 36,
43
44        63, 55, 47, 39, 31, 23, 15,
45         7, 62, 54, 46, 38, 30, 22,
46        14,  6, 61, 53, 45, 37, 29,
47        21, 13,  5, 28, 20, 12,  4
48 };
49
50 /* number left rotations of pc1 */
51 static const byte totrot[] = {
52        1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
53 };
54
55 /* permuted choice key (table) */
56 static const byte pc2[] = {
57        14, 17, 11, 24,  1,  5,
58         3, 28, 15,  6, 21, 10,
59        23, 19, 12,  4, 26,  8,
60        16,  7, 27, 20, 13,  2,
61        41, 52, 31, 37, 47, 55,
62        30, 40, 51, 45, 33, 48,
63        44, 49, 39, 56, 34, 53,
64        46, 42, 50, 36, 29, 32
65 };
66
67 /* End of DES-defined tables */
68
69 /* bit 0 is left-most in byte */
70 static const int bytebit[] = {
71        0200,0100,040,020,010,04,02,01
72 };
73
74 const word32 Spbox[8][64] = {
75 {
76 0x01010400,0x00000000,0x00010000,0x01010404,
77 0x01010004,0x00010404,0x00000004,0x00010000,
78 0x00000400,0x01010400,0x01010404,0x00000400,
79 0x01000404,0x01010004,0x01000000,0x00000004,
80 0x00000404,0x01000400,0x01000400,0x00010400,
81 0x00010400,0x01010000,0x01010000,0x01000404,
82 0x00010004,0x01000004,0x01000004,0x00010004,
83 0x00000000,0x00000404,0x00010404,0x01000000,
84 0x00010000,0x01010404,0x00000004,0x01010000,
85 0x01010400,0x01000000,0x01000000,0x00000400,
86 0x01010004,0x00010000,0x00010400,0x01000004,
87 0x00000400,0x00000004,0x01000404,0x00010404,
88 0x01010404,0x00010004,0x01010000,0x01000404,
89 0x01000004,0x00000404,0x00010404,0x01010400,
90 0x00000404,0x01000400,0x01000400,0x00000000,
91 0x00010004,0x00010400,0x00000000,0x01010004},
92 {
93 0x80108020,0x80008000,0x00008000,0x00108020,
94 0x00100000,0x00000020,0x80100020,0x80008020,
95 0x80000020,0x80108020,0x80108000,0x80000000,
96 0x80008000,0x00100000,0x00000020,0x80100020,
97 0x00108000,0x00100020,0x80008020,0x00000000,
98 0x80000000,0x00008000,0x00108020,0x80100000,
99 0x00100020,0x80000020,0x00000000,0x00108000,
100 0x00008020,0x80108000,0x80100000,0x00008020,
101 0x00000000,0x00108020,0x80100020,0x00100000,
102 0x80008020,0x80100000,0x80108000,0x00008000,
103 0x80100000,0x80008000,0x00000020,0x80108020,
104 0x00108020,0x00000020,0x00008000,0x80000000,
105 0x00008020,0x80108000,0x00100000,0x80000020,
106 0x00100020,0x80008020,0x80000020,0x00100020,
107 0x00108000,0x00000000,0x80008000,0x00008020,
108 0x80000000,0x80100020,0x80108020,0x00108000},
109 {
110 0x00000208,0x08020200,0x00000000,0x08020008,
111 0x08000200,0x00000000,0x00020208,0x08000200,
112 0x00020008,0x08000008,0x08000008,0x00020000,
113 0x08020208,0x00020008,0x08020000,0x00000208,
114 0x08000000,0x00000008,0x08020200,0x00000200,
115 0x00020200,0x08020000,0x08020008,0x00020208,
116 0x08000208,0x00020200,0x00020000,0x08000208,
117 0x00000008,0x08020208,0x00000200,0x08000000,
118 0x08020200,0x08000000,0x00020008,0x00000208,
119 0x00020000,0x08020200,0x08000200,0x00000000,
120 0x00000200,0x00020008,0x08020208,0x08000200,
121 0x08000008,0x00000200,0x00000000,0x08020008,
122 0x08000208,0x00020000,0x08000000,0x08020208,
123 0x00000008,0x00020208,0x00020200,0x08000008,
124 0x08020000,0x08000208,0x00000208,0x08020000,
125 0x00020208,0x00000008,0x08020008,0x00020200},
126 {
127 0x00802001,0x00002081,0x00002081,0x00000080,
128 0x00802080,0x00800081,0x00800001,0x00002001,
129 0x00000000,0x00802000,0x00802000,0x00802081,
130 0x00000081,0x00000000,0x00800080,0x00800001,
131 0x00000001,0x00002000,0x00800000,0x00802001,
132 0x00000080,0x00800000,0x00002001,0x00002080,
133 0x00800081,0x00000001,0x00002080,0x00800080,
134 0x00002000,0x00802080,0x00802081,0x00000081,
135 0x00800080,0x00800001,0x00802000,0x00802081,
136 0x00000081,0x00000000,0x00000000,0x00802000,
137 0x00002080,0x00800080,0x00800081,0x00000001,
138 0x00802001,0x00002081,0x00002081,0x00000080,
139 0x00802081,0x00000081,0x00000001,0x00002000,
140 0x00800001,0x00002001,0x00802080,0x00800081,
141 0x00002001,0x00002080,0x00800000,0x00802001,
142 0x00000080,0x00800000,0x00002000,0x00802080},
143 {
144 0x00000100,0x02080100,0x02080000,0x42000100,
145 0x00080000,0x00000100,0x40000000,0x02080000,
146 0x40080100,0x00080000,0x02000100,0x40080100,
147 0x42000100,0x42080000,0x00080100,0x40000000,
148 0x02000000,0x40080000,0x40080000,0x00000000,
149 0x40000100,0x42080100,0x42080100,0x02000100,
150 0x42080000,0x40000100,0x00000000,0x42000000,
151 0x02080100,0x02000000,0x42000000,0x00080100,
152 0x00080000,0x42000100,0x00000100,0x02000000,
153 0x40000000,0x02080000,0x42000100,0x40080100,
154 0x02000100,0x40000000,0x42080000,0x02080100,
155 0x40080100,0x00000100,0x02000000,0x42080000,
156 0x42080100,0x00080100,0x42000000,0x42080100,
157 0x02080000,0x00000000,0x40080000,0x42000000,
158 0x00080100,0x02000100,0x40000100,0x00080000,
159 0x00000000,0x40080000,0x02080100,0x40000100},
160 {
161 0x20000010,0x20400000,0x00004000,0x20404010,
162 0x20400000,0x00000010,0x20404010,0x00400000,
163 0x20004000,0x00404010,0x00400000,0x20000010,
164 0x00400010,0x20004000,0x20000000,0x00004010,
165 0x00000000,0x00400010,0x20004010,0x00004000,
166 0x00404000,0x20004010,0x00000010,0x20400010,
167 0x20400010,0x00000000,0x00404010,0x20404000,
168 0x00004010,0x00404000,0x20404000,0x20000000,
169 0x20004000,0x00000010,0x20400010,0x00404000,
170 0x20404010,0x00400000,0x00004010,0x20000010,
171 0x00400000,0x20004000,0x20000000,0x00004010,
172 0x20000010,0x20404010,0x00404000,0x20400000,
173 0x00404010,0x20404000,0x00000000,0x20400010,
174 0x00000010,0x00004000,0x20400000,0x00404010,
175 0x00004000,0x00400010,0x20004010,0x00000000,
176 0x20404000,0x20000000,0x00400010,0x20004010},
177 {
178 0x00200000,0x04200002,0x04000802,0x00000000,
179 0x00000800,0x04000802,0x00200802,0x04200800,
180 0x04200802,0x00200000,0x00000000,0x04000002,
181 0x00000002,0x04000000,0x04200002,0x00000802,
182 0x04000800,0x00200802,0x00200002,0x04000800,
183 0x04000002,0x04200000,0x04200800,0x00200002,
184 0x04200000,0x00000800,0x00000802,0x04200802,
185 0x00200800,0x00000002,0x04000000,0x00200800,
186 0x04000000,0x00200800,0x00200000,0x04000802,
187 0x04000802,0x04200002,0x04200002,0x00000002,
188 0x00200002,0x04000000,0x04000800,0x00200000,
189 0x04200800,0x00000802,0x00200802,0x04200800,
190 0x00000802,0x04000002,0x04200802,0x04200000,
191 0x00200800,0x00000000,0x00000002,0x04200802,
192 0x00000000,0x00200802,0x04200000,0x00000800,
193 0x04000002,0x04000800,0x00000800,0x00200002},
194 {
195 0x10001040,0x00001000,0x00040000,0x10041040,
196 0x10000000,0x10001040,0x00000040,0x10000000,
197 0x00040040,0x10040000,0x10041040,0x00041000,
198 0x10041000,0x00041040,0x00001000,0x00000040,
199 0x10040000,0x10000040,0x10001000,0x00001040,
200 0x00041000,0x00040040,0x10040040,0x10041000,
201 0x00001040,0x00000000,0x00000000,0x10040040,
202 0x10000040,0x10001000,0x00041040,0x00040000,
203 0x00041040,0x00040000,0x10041000,0x00001000,
204 0x00000040,0x10040040,0x00001000,0x00041040,
205 0x10001000,0x00000040,0x10000040,0x10040000,
206 0x10040040,0x10000000,0x00040000,0x10001040,
207 0x00000000,0x10041040,0x00040040,0x10000040,
208 0x10040000,0x10001000,0x10001040,0x00000000,
209 0x10041040,0x00041000,0x00041000,0x00001040,
210 0x00001040,0x00040040,0x10000000,0x10041000}
211 };
212
213
214 static INLINE void IPERM(word32* left, word32* right)
215 {
216     word32 work;
217
218     *right = rotlFixed(*right, 4U);
219     work = (*left ^ *right) & 0xf0f0f0f0;
220     *left ^= work;
221
222     *right = rotrFixed(*right^work, 20U);
223     work = (*left ^ *right) & 0xffff0000;
224     *left ^= work;
225
226     *right = rotrFixed(*right^work, 18U);
227     work = (*left ^ *right) & 0x33333333;
228     *left ^= work;
229
230     *right = rotrFixed(*right^work, 6U);
231     work = (*left ^ *right) & 0x00ff00ff;
232     *left ^= work;
233
234     *right = rotlFixed(*right^work, 9U);
235     work = (*left ^ *right) & 0xaaaaaaaa;
236     *left = rotlFixed(*left^work, 1U);
237     *right ^= work;
238 }
239
240
241 static INLINE void FPERM(word32* left, word32* right)
242 {
243     word32 work;
244
245     *right = rotrFixed(*right, 1U);
246     work = (*left ^ *right) & 0xaaaaaaaa;
247     *right ^= work;
248
249     *left = rotrFixed(*left^work, 9U);
250     work = (*left ^ *right) & 0x00ff00ff;
251     *right ^= work;
252
253     *left = rotlFixed(*left^work, 6U);
254     work = (*left ^ *right) & 0x33333333;
255     *right ^= work;
256
257     *left = rotlFixed(*left^work, 18U);
258     work = (*left ^ *right) & 0xffff0000;
259     *right ^= work;
260
261     *left = rotlFixed(*left^work, 20U);
262     work = (*left ^ *right) & 0xf0f0f0f0;
263     *right ^= work;
264
265     *left = rotrFixed(*left^work, 4U);
266 }
267
268
269 static void DesSetKey(const byte* key, int dir, word32* out)
270 {
271     byte buffer[56+56+8];
272     byte *const pc1m = buffer;                 /* place to modify pc1 into */
273     byte *const pcr = pc1m + 56;               /* place to rotate pc1 into */
274     byte *const ks = pcr + 56;
275     register int i,j,l;
276     int m;
277
278     for (j = 0; j < 56; j++) {          /* convert pc1 to bits of key */
279         l = pc1[j] - 1;                 /* integer bit location  */
280         m = l & 07;                     /* find bit              */
281         pc1m[j] = (key[l >> 3] &        /* find which key byte l is in */
282             bytebit[m])                 /* and which bit of that byte */
283             ? 1 : 0;                    /* and store 1-bit result */
284     }
285     for (i = 0; i < 16; i++) {          /* key chunk for each iteration */
286         XMEMSET(ks, 0, 8);               /* Clear key schedule */
287         for (j = 0; j < 56; j++)        /* rotate pc1 the right amount */
288             pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l: l-28];
289         /* rotate left and right halves independently */
290         for (j = 0; j < 48; j++){   /* select bits individually */
291             /* check bit that goes to ks[j] */
292             if (pcr[pc2[j] - 1]){
293                 /* mask it in if it's there */
294                 l= j % 6;
295                 ks[j/6] |= bytebit[l] >> 2;
296             }
297         }
298         /* Now convert to odd/even interleaved form for use in F */
299         out[2*i] = ((word32)ks[0] << 24)
300             | ((word32)ks[2] << 16)
301             | ((word32)ks[4] << 8)
302             | ((word32)ks[6]);
303         out[2*i + 1] = ((word32)ks[1] << 24)
304             | ((word32)ks[3] << 16)
305             | ((word32)ks[5] << 8)
306             | ((word32)ks[7]);
307     }
308     
309     /* reverse key schedule order */
310     if (dir == DES_DECRYPTION)
311         for (i = 0; i < 16; i += 2) {
312             word32 swap = out[i];
313             out[i] = out[DES_KS_SIZE - 2 - i];
314             out[DES_KS_SIZE - 2 - i] = swap;
315
316             swap = out[i + 1];
317             out[i + 1] = out[DES_KS_SIZE - 1 - i];
318             out[DES_KS_SIZE - 1 - i] = swap;
319         }
320    
321 }
322
323
324 static INLINE int Reverse(int dir)
325 {
326     return !dir;
327 }
328
329
330 void Des_SetIV(Des* des, const byte* iv)
331 {
332     if (des && iv)
333         XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
334 }
335
336
337 void Des3_SetIV(Des3* des, const byte* iv)
338 {
339     if (des && iv)
340         XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
341 }
342
343
344 void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
345 {
346     DesSetKey(key, dir, des->key);
347
348     Des_SetIV(des, iv);
349 }
350
351
352 void Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
353 {
354     DesSetKey(key + (dir == DES_ENCRYPTION ? 0 : 16), dir, des->key[0]);
355     DesSetKey(key + 8, Reverse(dir), des->key[1]);
356     DesSetKey(key + (dir == DES_DECRYPTION ? 0 : 16), dir, des->key[2]);
357
358     Des3_SetIV(des, iv);  
359 }
360
361
362 static void DesRawProcessBlock(word32* lIn, word32* rIn, const word32* kptr)
363 {
364     word32 l = *lIn, r = *rIn, i;
365
366     for (i=0; i<8; i++)
367     {
368         word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0];
369         l ^= Spbox[6][(work) & 0x3f]
370           ^  Spbox[4][(work >> 8) & 0x3f]
371           ^  Spbox[2][(work >> 16) & 0x3f]
372           ^  Spbox[0][(work >> 24) & 0x3f];
373         work = r ^ kptr[4*i+1];
374         l ^= Spbox[7][(work) & 0x3f]
375           ^  Spbox[5][(work >> 8) & 0x3f]
376           ^  Spbox[3][(work >> 16) & 0x3f]
377           ^  Spbox[1][(work >> 24) & 0x3f];
378
379         work = rotrFixed(l, 4U) ^ kptr[4*i+2];
380         r ^= Spbox[6][(work) & 0x3f]
381           ^  Spbox[4][(work >> 8) & 0x3f]
382           ^  Spbox[2][(work >> 16) & 0x3f]
383           ^  Spbox[0][(work >> 24) & 0x3f];
384         work = l ^ kptr[4*i+3];
385         r ^= Spbox[7][(work) & 0x3f]
386           ^  Spbox[5][(work >> 8) & 0x3f]
387           ^  Spbox[3][(work >> 16) & 0x3f]
388           ^  Spbox[1][(work >> 24) & 0x3f];
389     }
390
391     *lIn = l; *rIn = r;
392 }
393
394
395 static void DesProcessBlock(Des* des, const byte* in, byte* out)
396 {
397     word32 l, r;
398
399     XMEMCPY(&l, in, sizeof(l));
400     XMEMCPY(&r, in + sizeof(l), sizeof(r));
401     #ifdef LITTLE_ENDIAN_ORDER
402         l = ByteReverseWord32(l);
403         r = ByteReverseWord32(r);
404     #endif
405     IPERM(&l,&r);
406     
407     DesRawProcessBlock(&l, &r, des->key);   
408
409     FPERM(&l,&r);
410     #ifdef LITTLE_ENDIAN_ORDER
411         l = ByteReverseWord32(l);
412         r = ByteReverseWord32(r);
413     #endif
414     XMEMCPY(out, &r, sizeof(r));
415     XMEMCPY(out + sizeof(r), &l, sizeof(l));
416 }
417
418
419 static void Des3ProcessBlock(Des3* des, const byte* in, byte* out)
420 {
421     word32 l, r;
422
423     XMEMCPY(&l, in, sizeof(l));
424     XMEMCPY(&r, in + sizeof(l), sizeof(r));
425     #ifdef LITTLE_ENDIAN_ORDER
426         l = ByteReverseWord32(l);
427         r = ByteReverseWord32(r);
428     #endif
429     IPERM(&l,&r);
430     
431     DesRawProcessBlock(&l, &r, des->key[0]);   
432     DesRawProcessBlock(&r, &l, des->key[1]);   
433     DesRawProcessBlock(&l, &r, des->key[2]);   
434
435     FPERM(&l,&r);
436     #ifdef LITTLE_ENDIAN_ORDER
437         l = ByteReverseWord32(l);
438         r = ByteReverseWord32(r);
439     #endif
440     XMEMCPY(out, &r, sizeof(r));
441     XMEMCPY(out + sizeof(r), &l, sizeof(l));
442 }
443
444
445 void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
446 {
447     word32 blocks = sz / DES_BLOCK_SIZE;
448
449     while (blocks--) {
450         xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
451         DesProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
452         XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
453
454         out += DES_BLOCK_SIZE;
455         in  += DES_BLOCK_SIZE; 
456     }
457 }
458
459
460 void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
461 {
462     word32 blocks = sz / DES_BLOCK_SIZE;
463     byte   hold[16];
464
465     while (blocks--) {
466         XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
467         DesProcessBlock(des, (byte*)des->tmp, out);
468         xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
469
470         XMEMCPY(hold, des->reg, DES_BLOCK_SIZE);
471         XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
472         XMEMCPY(des->tmp, hold, DES_BLOCK_SIZE);
473
474         out += DES_BLOCK_SIZE;
475         in  += DES_BLOCK_SIZE; 
476     }
477 }
478
479
480 void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
481 {
482     word32 blocks = sz / DES_BLOCK_SIZE;
483
484     while (blocks--) {
485         xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
486         Des3ProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
487         XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
488
489         out += DES_BLOCK_SIZE;
490         in  += DES_BLOCK_SIZE; 
491     }
492 }
493
494
495 void Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
496 {
497     word32 blocks = sz / DES_BLOCK_SIZE;
498
499     while (blocks--) {
500         XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
501         Des3ProcessBlock(des, (byte*)des->tmp, out);
502         xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
503         XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
504
505         out += DES_BLOCK_SIZE;
506         in  += DES_BLOCK_SIZE; 
507     }
508 }
509
510 #ifdef CYASSL_DES_ECB
511
512 /* One block, compatibility only */
513 void Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
514 {
515     word32 blocks = sz / DES_BLOCK_SIZE;
516
517     while (blocks--) {
518         DesProcessBlock(des, in, out);
519
520         out += DES_BLOCK_SIZE;
521         in  += DES_BLOCK_SIZE; 
522     }
523 }
524
525 #endif /* CYASSL_DES_ECB */
526
527
528 #endif /* NO_DES3 */