Merge pull request #106 from p-l-/fix-hfmfeload
[legacy-proxmark3.git] / armsrc / des.c
bloba81df9c8d4234c7bd2bd5432b0a503f9a1c6ba36
1 /* des.c */
2 /*
3 This file is part of the ARM-Crypto-Lib.
4 Copyright (C) 2006-2010 Daniel Otte (daniel.otte@rub.de)
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 /**
20 * \file des.c
21 * \author Daniel Otte
22 * \email daniel.otte@rub.de
23 * \date 2007-06-16
24 * \brief DES and EDE-DES implementation
25 * \license GPLv3 or later
28 #include <stdint.h>
29 #include <string.h>
31 const uint8_t sbox[256] = {
32 /* S-box 1 */
33 0xE4, 0xD1, 0x2F, 0xB8, 0x3A, 0x6C, 0x59, 0x07,
34 0x0F, 0x74, 0xE2, 0xD1, 0xA6, 0xCB, 0x95, 0x38,
35 0x41, 0xE8, 0xD6, 0x2B, 0xFC, 0x97, 0x3A, 0x50,
36 0xFC, 0x82, 0x49, 0x17, 0x5B, 0x3E, 0xA0, 0x6D,
37 /* S-box 2 */
38 0xF1, 0x8E, 0x6B, 0x34, 0x97, 0x2D, 0xC0, 0x5A,
39 0x3D, 0x47, 0xF2, 0x8E, 0xC0, 0x1A, 0x69, 0xB5,
40 0x0E, 0x7B, 0xA4, 0xD1, 0x58, 0xC6, 0x93, 0x2F,
41 0xD8, 0xA1, 0x3F, 0x42, 0xB6, 0x7C, 0x05, 0xE9,
42 /* S-box 3 */
43 0xA0, 0x9E, 0x63, 0xF5, 0x1D, 0xC7, 0xB4, 0x28,
44 0xD7, 0x09, 0x34, 0x6A, 0x28, 0x5E, 0xCB, 0xF1,
45 0xD6, 0x49, 0x8F, 0x30, 0xB1, 0x2C, 0x5A, 0xE7,
46 0x1A, 0xD0, 0x69, 0x87, 0x4F, 0xE3, 0xB5, 0x2C,
47 /* S-box 4 */
48 0x7D, 0xE3, 0x06, 0x9A, 0x12, 0x85, 0xBC, 0x4F,
49 0xD8, 0xB5, 0x6F, 0x03, 0x47, 0x2C, 0x1A, 0xE9,
50 0xA6, 0x90, 0xCB, 0x7D, 0xF1, 0x3E, 0x52, 0x84,
51 0x3F, 0x06, 0xA1, 0xD8, 0x94, 0x5B, 0xC7, 0x2E,
52 /* S-box 5 */
53 0x2C, 0x41, 0x7A, 0xB6, 0x85, 0x3F, 0xD0, 0xE9,
54 0xEB, 0x2C, 0x47, 0xD1, 0x50, 0xFA, 0x39, 0x86,
55 0x42, 0x1B, 0xAD, 0x78, 0xF9, 0xC5, 0x63, 0x0E,
56 0xB8, 0xC7, 0x1E, 0x2D, 0x6F, 0x09, 0xA4, 0x53,
57 /* S-box 6 */
58 0xC1, 0xAF, 0x92, 0x68, 0x0D, 0x34, 0xE7, 0x5B,
59 0xAF, 0x42, 0x7C, 0x95, 0x61, 0xDE, 0x0B, 0x38,
60 0x9E, 0xF5, 0x28, 0xC3, 0x70, 0x4A, 0x1D, 0xB6,
61 0x43, 0x2C, 0x95, 0xFA, 0xBE, 0x17, 0x60, 0x8D,
62 /* S-box 7 */
63 0x4B, 0x2E, 0xF0, 0x8D, 0x3C, 0x97, 0x5A, 0x61,
64 0xD0, 0xB7, 0x49, 0x1A, 0xE3, 0x5C, 0x2F, 0x86,
65 0x14, 0xBD, 0xC3, 0x7E, 0xAF, 0x68, 0x05, 0x92,
66 0x6B, 0xD8, 0x14, 0xA7, 0x95, 0x0F, 0xE2, 0x3C,
67 /* S-box 8 */
68 0xD2, 0x84, 0x6F, 0xB1, 0xA9, 0x3E, 0x50, 0xC7,
69 0x1F, 0xD8, 0xA3, 0x74, 0xC5, 0x6B, 0x0E, 0x92,
70 0x7B, 0x41, 0x9C, 0xE2, 0x06, 0xAD, 0xF3, 0x58,
71 0x21, 0xE7, 0x4A, 0x8D, 0xFC, 0x90, 0x35, 0x6B
74 const uint8_t e_permtab[] ={
75 4, 6, /* 4 bytes in 6 bytes out*/
76 32, 1, 2, 3, 4, 5,
77 4, 5, 6, 7, 8, 9,
78 8, 9, 10, 11, 12, 13,
79 12, 13, 14, 15, 16, 17,
80 16, 17, 18, 19, 20, 21,
81 20, 21, 22, 23, 24, 25,
82 24, 25, 26, 27, 28, 29,
83 28, 29, 30, 31, 32, 1
86 const uint8_t p_permtab[] ={
87 4, 4, /* 32 bit -> 32 bit */
88 16, 7, 20, 21,
89 29, 12, 28, 17,
90 1, 15, 23, 26,
91 5, 18, 31, 10,
92 2, 8, 24, 14,
93 32, 27, 3, 9,
94 19, 13, 30, 6,
95 22, 11, 4, 25
98 const uint8_t ip_permtab[] ={
99 8, 8, /* 64 bit -> 64 bit */
100 58, 50, 42, 34, 26, 18, 10, 2,
101 60, 52, 44, 36, 28, 20, 12, 4,
102 62, 54, 46, 38, 30, 22, 14, 6,
103 64, 56, 48, 40, 32, 24, 16, 8,
104 57, 49, 41, 33, 25, 17, 9, 1,
105 59, 51, 43, 35, 27, 19, 11, 3,
106 61, 53, 45, 37, 29, 21, 13, 5,
107 63, 55, 47, 39, 31, 23, 15, 7
110 const uint8_t inv_ip_permtab[] ={
111 8, 8, /* 64 bit -> 64 bit */
112 40, 8, 48, 16, 56, 24, 64, 32,
113 39, 7, 47, 15, 55, 23, 63, 31,
114 38, 6, 46, 14, 54, 22, 62, 30,
115 37, 5, 45, 13, 53, 21, 61, 29,
116 36, 4, 44, 12, 52, 20, 60, 28,
117 35, 3, 43, 11, 51, 19, 59, 27,
118 34, 2, 42, 10, 50, 18, 58, 26,
119 33, 1, 41, 9, 49, 17, 57, 25
122 const uint8_t pc1_permtab[] ={
123 8, 7, /* 64 bit -> 56 bit*/
124 57, 49, 41, 33, 25, 17, 9,
125 1, 58, 50, 42, 34, 26, 18,
126 10, 2, 59, 51, 43, 35, 27,
127 19, 11, 3, 60, 52, 44, 36,
128 63, 55, 47, 39, 31, 23, 15,
129 7, 62, 54, 46, 38, 30, 22,
130 14, 6, 61, 53, 45, 37, 29,
131 21, 13, 5, 28, 20, 12, 4
134 const uint8_t pc2_permtab[] ={
135 7, 6, /* 56 bit -> 48 bit */
136 14, 17, 11, 24, 1, 5,
137 3, 28, 15, 6, 21, 10,
138 23, 19, 12, 4, 26, 8,
139 16, 7, 27, 20, 13, 2,
140 41, 52, 31, 37, 47, 55,
141 30, 40, 51, 45, 33, 48,
142 44, 49, 39, 56, 34, 53,
143 46, 42, 50, 36, 29, 32
146 const uint8_t splitin6bitword_permtab[] = {
147 8, 8, /* 64 bit -> 64 bit */
148 64, 64, 1, 6, 2, 3, 4, 5,
149 64, 64, 7, 12, 8, 9, 10, 11,
150 64, 64, 13, 18, 14, 15, 16, 17,
151 64, 64, 19, 24, 20, 21, 22, 23,
152 64, 64, 25, 30, 26, 27, 28, 29,
153 64, 64, 31, 36, 32, 33, 34, 35,
154 64, 64, 37, 42, 38, 39, 40, 41,
155 64, 64, 43, 48, 44, 45, 46, 47
158 const uint8_t shiftkey_permtab[] = {
159 7, 7, /* 56 bit -> 56 bit */
160 2, 3, 4, 5, 6, 7, 8, 9,
161 10, 11, 12, 13, 14, 15, 16, 17,
162 18, 19, 20, 21, 22, 23, 24, 25,
163 26, 27, 28, 1,
164 30, 31, 32, 33, 34, 35, 36, 37,
165 38, 39, 40, 41, 42, 43, 44, 45,
166 46, 47, 48, 49, 50, 51, 52, 53,
167 54, 55, 56, 29
170 const uint8_t shiftkeyinv_permtab[] = {
171 7, 7,
172 28, 1, 2, 3, 4, 5, 6, 7,
173 8, 9, 10, 11, 12, 13, 14, 15,
174 16, 17, 18, 19, 20, 21, 22, 23,
175 24, 25, 26, 27,
176 56, 29, 30, 31, 32, 33, 34, 35,
177 36, 37, 38, 39, 40, 41, 42, 43,
178 44, 45, 46, 47, 48, 49, 50, 51,
179 52, 53, 54, 55
191 ----
201 #define ROTTABLE 0x7EFC
202 #define ROTTABLE_INV 0x3F7E
203 /******************************************************************************/
205 void permute(const uint8_t *ptable, const uint8_t *in, uint8_t *out){
206 uint8_t ob; /* in-bytes and out-bytes */
207 uint8_t byte, bit; /* counter for bit and byte */
208 ob = ptable[1];
209 ptable = &(ptable[2]);
210 for(byte=0; byte<ob; ++byte){
211 uint8_t x,t=0;
212 for(bit=0; bit<8; ++bit){
213 x=*ptable++ -1 ;
214 t<<=1;
215 if((in[x/8]) & (0x80>>(x%8)) ){
216 t|=0x01;
219 out[byte]=t;
223 /******************************************************************************/
225 void changeendian32(uint32_t * a){
226 *a = (*a & 0x000000FF) << 24 |
227 (*a & 0x0000FF00) << 8 |
228 (*a & 0x00FF0000) >> 8 |
229 (*a & 0xFF000000) >> 24;
232 /******************************************************************************/
233 static inline
234 void shiftkey(uint8_t *key){
235 uint8_t k[7];
236 memcpy(k, key, 7);
237 permute((uint8_t*)shiftkey_permtab, k, key);
240 /******************************************************************************/
241 static inline
242 void shiftkey_inv(uint8_t *key){
243 uint8_t k[7];
244 memcpy(k, key, 7);
245 permute((uint8_t*)shiftkeyinv_permtab, k, key);
249 /******************************************************************************/
250 static inline
251 uint64_t splitin6bitwords(uint64_t a){
252 uint64_t ret=0;
253 a &= 0x0000ffffffffffffLL;
254 permute((uint8_t*)splitin6bitword_permtab, (uint8_t*)&a, (uint8_t*)&ret);
255 return ret;
258 /******************************************************************************/
260 static inline
261 uint8_t substitute(uint8_t a, uint8_t * sbp){
262 uint8_t x;
263 x = sbp[a>>1];
264 x = (a&1)?x&0x0F:x>>4;
265 return x;
269 /******************************************************************************/
271 uint32_t des_f(uint32_t r, uint8_t* kr){
272 uint8_t i;
273 uint32_t t=0,ret;
274 uint64_t data;
275 uint8_t *sbp; /* sboxpointer */
276 permute((uint8_t*)e_permtab, (uint8_t*)&r, (uint8_t*)&data);
277 for(i=0; i<7; ++i)
278 ((uint8_t*)&data)[i] ^= kr[i];
280 /* Sbox substitution */
281 data = splitin6bitwords(data);
282 sbp=(uint8_t*)sbox;
283 for(i=0; i<8; ++i){
284 uint8_t x;
285 x = substitute(((uint8_t*)&data)[i], sbp);
286 t<<=4;
287 t |= x;
288 sbp += 32;
290 changeendian32(&t);
292 permute((uint8_t*)p_permtab,(uint8_t*)&t, (uint8_t*)&ret);
294 return ret;
297 /******************************************************************************/
299 void des_enc(void* out, const void* in, const void* key){
300 #define R *((uint32_t*)&(data[4]))
301 #define L *((uint32_t*)&(data[0]))
303 uint8_t data[8],kr[6],k[7];
304 uint8_t i;
306 permute((uint8_t*)ip_permtab, (uint8_t*)in, data);
307 permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k);
308 for(i=0; i<8; ++i){
309 shiftkey(k);
310 if(ROTTABLE&((1<<((i<<1)+0))) )
311 shiftkey(k);
312 permute((uint8_t*)pc2_permtab, k, kr);
313 L ^= des_f(R, kr);
315 shiftkey(k);
316 if(ROTTABLE&((1<<((i<<1)+1))) )
317 shiftkey(k);
318 permute((uint8_t*)pc2_permtab, k, kr);
319 R ^= des_f(L, kr);
322 /* L <-> R*/
323 R ^= L;
324 L ^= R;
325 R ^= L;
327 permute((uint8_t*)inv_ip_permtab, data, (uint8_t*)out);
330 /******************************************************************************/
332 void des_dec(void* out, const void* in, const uint8_t* key){
333 #define R *((uint32_t*)&(data[4]))
334 #define L *((uint32_t*)&(data[0]))
336 uint8_t data[8],kr[6],k[7];
337 int8_t i;
338 permute((uint8_t*)ip_permtab, (uint8_t*)in, data);
339 permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k);
340 for(i=7; i>=0; --i){
342 permute((uint8_t*)pc2_permtab, k, kr);
343 L ^= des_f(R, kr);
344 shiftkey_inv(k);
345 if(ROTTABLE&((1<<((i<<1)+1))) ){
346 shiftkey_inv(k);
349 permute((uint8_t*)pc2_permtab, k, kr);
350 R ^= des_f(L, kr);
351 shiftkey_inv(k);
352 if(ROTTABLE&((1<<((i<<1)+0))) ){
353 shiftkey_inv(k);
357 /* L <-> R*/
358 R ^= L;
359 L ^= R;
360 R ^= L;
362 permute((uint8_t*)inv_ip_permtab, data, (uint8_t*)out);
365 /******************************************************************************/
367 void tdes_enc(void* out, void* in, const void* key){
368 des_enc(out, in, (uint8_t*)key + 0);
369 des_dec(out, out, (uint8_t*)key + 8);
370 des_enc(out, out, (uint8_t*)key +16);
373 /******************************************************************************/
375 void tdes_dec(void* out, void* in, const uint8_t* key){
376 des_dec(out, in, (uint8_t*)key +16);
377 des_enc(out, out, (uint8_t*)key + 8);
378 des_dec(out, out, (uint8_t*)key + 0);
381 void tdes_2key_enc(void* out, const void* in, size_t length, const void* key, unsigned char iv[8]){
383 if( length % 8 ) return;
385 uint8_t i;
386 uint8_t* tin = (uint8_t*) in;
387 uint8_t* tout = (uint8_t*) out;
389 while( length > 0 )
391 for ( i = 0; i < 8; i++ )
392 tout[i] = (unsigned char)(tin[i] ^ iv[i]);
394 des_enc(tout, tin, (uint8_t*)key + 0);
395 des_dec(tout, tout, (uint8_t*)key + 8);
396 des_enc(tout, tout, (uint8_t*)key + 0);
398 memcpy(iv, tout, 8);
400 tin += 8;
401 tout += 8;
402 length -= 8;
406 void tdes_2key_dec(void* out, const void* in, size_t length, const void* key, unsigned char iv[8]){
408 if( length % 8 ) return;
410 uint8_t i;
411 unsigned char temp[8];
412 uint8_t* tin = (uint8_t*) in;
413 uint8_t* tout = (uint8_t*) out;
415 while( length > 0 )
417 memcpy(temp, tin, 8);
419 des_dec(tout, tin, (uint8_t*)key + 0);
420 des_enc(tout, tout, (uint8_t*)key + 8);
421 des_dec(tout, tout, (uint8_t*)key + 0);
423 for (i = 0; i < 8; i++)
424 tout[i] = (unsigned char)(tout[i] ^ iv[i]);
426 memcpy(iv, temp, 8);
428 tin += 8;
429 tout += 8;
430 length -= 8;
435 /******************************************************************************/