5 * \brief DES and EDE-DES implementation
14 #include <util/delay.h>
15 #include <avr/pgmspace.h>
17 prog_uint8_t sbox[256] = {
19 0xE4, 0xD1, 0x2F, 0xB8, 0x3A, 0x6C, 0x59, 0x07,
20 0x0F, 0x74, 0xE2, 0xD1, 0xA6, 0xCB, 0x95, 0x38,
21 0x41, 0xE8, 0xD6, 0x2B, 0xFC, 0x97, 0x3A, 0x50,
22 0xFC, 0x82, 0x49, 0x17, 0x5B, 0x3E, 0xA0, 0x6D,
24 0xF1, 0x8E, 0x6B, 0x34, 0x97, 0x2D, 0xC0, 0x5A,
25 0x3D, 0x47, 0xF2, 0x8E, 0xC0, 0x1A, 0x69, 0xB5,
26 0x0E, 0x7B, 0xA4, 0xD1, 0x58, 0xC6, 0x93, 0x2F,
27 0xD8, 0xA1, 0x3F, 0x42, 0xB6, 0x7C, 0x05, 0xE9,
29 0xA0, 0x9E, 0x63, 0xF5, 0x1D, 0xC7, 0xB4, 0x28,
30 0xD7, 0x09, 0x34, 0x6A, 0x28, 0x5E, 0xCB, 0xF1,
31 0xD6, 0x49, 0x8F, 0x30, 0xB1, 0x2C, 0x5A, 0xE7,
32 0x1A, 0xD0, 0x69, 0x87, 0x4F, 0xE3, 0xB5, 0x2C,
34 0x7D, 0xE3, 0x06, 0x9A, 0x12, 0x85, 0xBC, 0x4F,
35 0xD8, 0xB5, 0x6F, 0x03, 0x47, 0x2C, 0x1A, 0xE9,
36 0xA6, 0x90, 0xCB, 0x7D, 0xF1, 0x3E, 0x52, 0x84,
37 0x3F, 0x06, 0xA1, 0xD8, 0x94, 0x5B, 0xC7, 0x2E,
39 0x2C, 0x41, 0x7A, 0xB6, 0x85, 0x3F, 0xD0, 0xE9,
40 0xEB, 0x2C, 0x47, 0xD1, 0x50, 0xFA, 0x39, 0x86,
41 0x42, 0x1B, 0xAD, 0x78, 0xF9, 0xC5, 0x63, 0x0E,
42 0xB8, 0xC7, 0x1E, 0x2D, 0x6F, 0x09, 0xA4, 0x53,
44 0xC1, 0xAF, 0x92, 0x68, 0x0D, 0x34, 0xE7, 0x5B,
45 0xAF, 0x42, 0x7C, 0x95, 0x61, 0xDE, 0x0B, 0x38,
46 0x9E, 0xF5, 0x28, 0xC3, 0x70, 0x4A, 0x1D, 0xB6,
47 0x43, 0x2C, 0x95, 0xFA, 0xBE, 0x17, 0x60, 0x8D,
49 0x4B, 0x2E, 0xF0, 0x8D, 0x3C, 0x97, 0x5A, 0x61,
50 0xD0, 0xB7, 0x49, 0x1A, 0xE3, 0x5C, 0x2F, 0x86,
51 0x14, 0xBD, 0xC3, 0x7E, 0xAF, 0x68, 0x05, 0x92,
52 0x6B, 0xD8, 0x14, 0xA7, 0x95, 0x0F, 0xE2, 0x3C,
54 0xD2, 0x84, 0x6F, 0xB1, 0xA9, 0x3E, 0x50, 0xC7,
55 0x1F, 0xD8, 0xA3, 0x74, 0xC5, 0x6B, 0x0E, 0x92,
56 0x7B, 0x41, 0x9C, 0xE2, 0x06, 0xAD, 0xF3, 0x58,
57 0x21, 0xE7, 0x4A, 0x8D, 0xFC, 0x90, 0x35, 0x6B
60 prog_uint8_t e_permtab[] ={
61 4, 6, /* 4 bytes in 6 bytes out*/
65 12, 13, 14, 15, 16, 17,
66 16, 17, 18, 19, 20, 21,
67 20, 21, 22, 23, 24, 25,
68 24, 25, 26, 27, 28, 29,
72 prog_uint8_t p_permtab[] ={
73 4, 4, /* 32 bit -> 32 bit */
84 prog_uint8_t ip_permtab[] ={
85 8, 8, /* 64 bit -> 64 bit */
86 58, 50, 42, 34, 26, 18, 10, 2,
87 60, 52, 44, 36, 28, 20, 12, 4,
88 62, 54, 46, 38, 30, 22, 14, 6,
89 64, 56, 48, 40, 32, 24, 16, 8,
90 57, 49, 41, 33, 25, 17, 9, 1,
91 59, 51, 43, 35, 27, 19, 11, 3,
92 61, 53, 45, 37, 29, 21, 13, 5,
93 63, 55, 47, 39, 31, 23, 15, 7
96 prog_uint8_t inv_ip_permtab[] ={
97 8, 8, /* 64 bit -> 64 bit */
98 40, 8, 48, 16, 56, 24, 64, 32,
99 39, 7, 47, 15, 55, 23, 63, 31,
100 38, 6, 46, 14, 54, 22, 62, 30,
101 37, 5, 45, 13, 53, 21, 61, 29,
102 36, 4, 44, 12, 52, 20, 60, 28,
103 35, 3, 43, 11, 51, 19, 59, 27,
104 34, 2, 42, 10, 50, 18, 58, 26,
105 33, 1, 41, 9, 49, 17, 57, 25
108 prog_uint8_t pc1_permtab[] ={
109 8, 7, /* 64 bit -> 56 bit*/
110 57, 49, 41, 33, 25, 17, 9,
111 1, 58, 50, 42, 34, 26, 18,
112 10, 2, 59, 51, 43, 35, 27,
113 19, 11, 3, 60, 52, 44, 36,
114 63, 55, 47, 39, 31, 23, 15,
115 7, 62, 54, 46, 38, 30, 22,
116 14, 6, 61, 53, 45, 37, 29,
117 21, 13, 5, 28, 20, 12, 4
120 prog_uint8_t pc2_permtab[] ={
121 7, 6, /* 56 bit -> 48 bit */
122 14, 17, 11, 24, 1, 5,
123 3, 28, 15, 6, 21, 10,
124 23, 19, 12, 4, 26, 8,
125 16, 7, 27, 20, 13, 2,
126 41, 52, 31, 37, 47, 55,
127 30, 40, 51, 45, 33, 48,
128 44, 49, 39, 56, 34, 53,
129 46, 42, 50, 36, 29, 32
132 prog_uint8_t splitin6bitword_permtab[] = {
133 8, 8, /* 64 bit -> 64 bit */
134 64, 64, 1, 6, 2, 3, 4, 5,
135 64, 64, 7, 12, 8, 9, 10, 11,
136 64, 64, 13, 18, 14, 15, 16, 17,
137 64, 64, 19, 24, 20, 21, 22, 23,
138 64, 64, 25, 30, 26, 27, 28, 29,
139 64, 64, 31, 36, 32, 33, 34, 35,
140 64, 64, 37, 42, 38, 39, 40, 41,
141 64, 64, 43, 48, 44, 45, 46, 47
144 prog_uint8_t shiftkey_permtab[] = {
145 7, 7, /* 56 bit -> 56 bit */
146 2, 3, 4, 5, 6, 7, 8, 9,
147 10, 11, 12, 13, 14, 15, 16, 17,
148 18, 19, 20, 21, 22, 23, 24, 25,
150 30, 31, 32, 33, 34, 35, 36, 37,
151 38, 39, 40, 41, 42, 43, 44, 45,
152 46, 47, 48, 49, 50, 51, 52, 53,
156 prog_uint8_t shiftkeyinv_permtab[] = {
158 28, 1, 2, 3, 4, 5, 6, 7,
159 8, 9, 10, 11, 12, 13, 14, 15,
160 16, 17, 18, 19, 20, 21, 22, 23,
162 56, 29, 30, 31, 32, 33, 34, 35,
163 36, 37, 38, 39, 40, 41, 42, 43,
164 44, 45, 46, 47, 48, 49, 50, 51,
187 #define ROTTABLE 0x7EFC
188 #define ROTTABLE_INV 0x3F7E
189 /******************************************************************************/
191 void permute(prog_uint8_t *ptable, uint8_t *in, uint8_t *out){
192 uint8_t ib, ob; /* in-bytes and out-bytes */
193 uint8_t byte, bit; /* counter for bit and byte */
194 ib = pgm_read_byte(&(ptable[0]));
195 ob = pgm_read_byte(&(ptable[1]));
196 ptable = &(ptable[2]);
197 for(byte=0; byte<ob; ++byte){
199 for(bit=0; bit<8; ++bit){
200 x=pgm_read_byte(&(ptable[byte*8+bit])) -1 ;
202 if((in[x/8]) & (0x80>>(x%8)) ){
210 /******************************************************************************/
212 void changeendian32(uint32_t * a){
213 *a = (*a & 0x000000FF) << 24 |
214 (*a & 0x0000FF00) << 8 |
215 (*a & 0x00FF0000) >> 8 |
216 (*a & 0xFF000000) >> 24;
219 /******************************************************************************/
221 void shiftkey(uint8_t *key){
224 permute((prog_uint8_t*)shiftkey_permtab, k, key);
227 /******************************************************************************/
229 void shiftkey_inv(uint8_t *key){
232 permute((prog_uint8_t*)shiftkeyinv_permtab, k, key);
236 /******************************************************************************/
238 uint64_t splitin6bitwords(uint64_t a){
240 a &= 0x0000ffffffffffffLL;
241 permute((prog_uint8_t*)splitin6bitword_permtab, (uint8_t*)&a, (uint8_t*)&ret);
245 /******************************************************************************/
248 uint8_t substitute(uint8_t a, prog_uint8_t * sbp){
250 x = pgm_read_byte(&(sbp[a>>1]));
251 x = (a&1)?x&0x0F:x>>4;
256 /******************************************************************************/
258 uint32_t des_f(uint32_t r, uint8_t* kr){
262 prog_uint8_t *sbp; /* sboxpointer */
263 permute((prog_uint8_t*)e_permtab, (uint8_t*)&r, (uint8_t*)&data);
265 ((uint8_t*)&data)[i] ^= kr[i];
267 /* Sbox substitution */
268 data = splitin6bitwords(data);
269 sbp=(prog_uint8_t*)sbox;
272 x = substitute(((uint8_t*)&data)[i], sbp);
279 permute((prog_uint8_t*)p_permtab,(uint8_t*)&t, (uint8_t*)&ret);
284 /******************************************************************************/
286 void des_encrypt(uint8_t* out, uint8_t* in, uint8_t* key){
287 #define R *((uint32_t*)&(data[4]))
288 #define L *((uint32_t*)&(data[0]))
290 uint8_t data[8],kr[6],k[7];
293 permute((prog_uint8_t*)ip_permtab, in, data);
294 permute((prog_uint8_t*)pc1_permtab, key, k);
297 if(ROTTABLE&((1<<((i<<1)+0))) )
299 permute((prog_uint8_t*)pc2_permtab, k, kr);
303 if(ROTTABLE&((1<<((i<<1)+1))) )
305 permute((prog_uint8_t*)pc2_permtab, k, kr);
314 permute((prog_uint8_t*)inv_ip_permtab, data, out);
317 /******************************************************************************/
319 void des_decrypt(uint8_t* out, uint8_t* in, uint8_t* key){
320 #define R *((uint32_t*)&(data[4]))
321 #define L *((uint32_t*)&(data[0]))
323 uint8_t data[8],kr[6],k[7];
326 permute((prog_uint8_t*)ip_permtab, in, data);
327 permute((prog_uint8_t*)pc1_permtab, key, k);
330 permute((prog_uint8_t*)pc2_permtab, k, kr);
333 if(ROTTABLE&((1<<((i<<1)+1))) ){
337 permute((prog_uint8_t*)pc2_permtab, k, kr);
340 if(ROTTABLE&((1<<((i<<1)+0))) ){
350 permute((prog_uint8_t*)inv_ip_permtab, data, out);
353 /******************************************************************************/
355 void tdes_encrypt(uint8_t* out, uint8_t* in, uint8_t* key){
356 des_encrypt(out, in, key + 0);
357 des_decrypt(out, out, key + 8);
358 des_encrypt(out, out, key +16);
361 /******************************************************************************/
363 void tdes_decrypt(uint8_t* out, uint8_t* in, uint8_t* key){
364 des_decrypt(out, in, key + 0);
365 des_encrypt(out, out, key + 8);
366 des_decrypt(out, out, key +16);
369 /******************************************************************************/