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/>.
22 * \email daniel.otte@rub.de
24 * \brief DES and EDE-DES implementation
25 * \license GPLv3 or later
31 const uint8_t sbox[256] = {
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,
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,
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,
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,
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,
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,
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,
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*/
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,
86 const uint8_t p_permtab[] ={
87 4, 4, /* 32 bit -> 32 bit */
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,
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,
170 const uint8_t shiftkeyinv_permtab[] = {
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,
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,
201 #define ROTTABLE 0x7EFC
202 #define ROTTABLE_INV 0x3F7E
203 /******************************************************************************/
205 void permute(uint8_t *ptable, const uint8_t *in, uint8_t *out){
206 uint8_t ib, ob; /* in-bytes and out-bytes */
207 uint8_t byte, bit; /* counter for bit and byte */
210 ptable = &(ptable[2]);
211 for(byte=0; byte<ob; ++byte){
213 for(bit=0; bit<8; ++bit){
216 if((in[x/8]) & (0x80>>(x%8)) ){
224 /******************************************************************************/
226 void changeendian32(uint32_t * a){
227 *a = (*a & 0x000000FF) << 24 |
228 (*a & 0x0000FF00) << 8 |
229 (*a & 0x00FF0000) >> 8 |
230 (*a & 0xFF000000) >> 24;
233 /******************************************************************************/
235 void shiftkey(uint8_t *key){
238 permute((uint8_t*)shiftkey_permtab, k, key);
241 /******************************************************************************/
243 void shiftkey_inv(uint8_t *key){
246 permute((uint8_t*)shiftkeyinv_permtab, k, key);
250 /******************************************************************************/
252 uint64_t splitin6bitwords(uint64_t a){
254 a &= 0x0000ffffffffffffLL;
255 permute((uint8_t*)splitin6bitword_permtab, (uint8_t*)&a, (uint8_t*)&ret);
259 /******************************************************************************/
262 uint8_t substitute(uint8_t a, uint8_t * sbp){
265 x = (a&1)?x&0x0F:x>>4;
270 /******************************************************************************/
272 uint32_t des_f(uint32_t r, uint8_t* kr){
276 uint8_t *sbp; /* sboxpointer */
277 permute((uint8_t*)e_permtab, (uint8_t*)&r, (uint8_t*)&data);
279 ((uint8_t*)&data)[i] ^= kr[i];
281 /* Sbox substitution */
282 data = splitin6bitwords(data);
286 x = substitute(((uint8_t*)&data)[i], sbp);
293 permute((uint8_t*)p_permtab,(uint8_t*)&t, (uint8_t*)&ret);
298 /******************************************************************************/
300 void des_enc(void* out, const void* in, const void* key){
301 #define R *((uint32_t*)&(data[4]))
302 #define L *((uint32_t*)&(data[0]))
304 uint8_t data[8],kr[6],k[7];
307 permute((uint8_t*)ip_permtab, (uint8_t*)in, data);
308 permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k);
311 if(ROTTABLE&((1<<((i<<1)+0))) )
313 permute((uint8_t*)pc2_permtab, k, kr);
317 if(ROTTABLE&((1<<((i<<1)+1))) )
319 permute((uint8_t*)pc2_permtab, k, kr);
328 permute((uint8_t*)inv_ip_permtab, data, (uint8_t*)out);
331 /******************************************************************************/
333 void des_dec(void* out, const void* in, const uint8_t* key){
334 #define R *((uint32_t*)&(data[4]))
335 #define L *((uint32_t*)&(data[0]))
337 uint8_t data[8],kr[6],k[7];
339 permute((uint8_t*)ip_permtab, (uint8_t*)in, data);
340 permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k);
343 permute((uint8_t*)pc2_permtab, k, kr);
346 if(ROTTABLE&((1<<((i<<1)+1))) ){
350 permute((uint8_t*)pc2_permtab, k, kr);
353 if(ROTTABLE&((1<<((i<<1)+0))) ){
363 permute((uint8_t*)inv_ip_permtab, data, (uint8_t*)out);
366 /******************************************************************************/
368 void tdes_enc(void* out, void* in, const void* key){
369 des_enc(out, in, (uint8_t*)key + 0);
370 des_dec(out, out, (uint8_t*)key + 8);
371 des_enc(out, out, (uint8_t*)key +16);
374 /******************************************************************************/
376 void tdes_dec(void* out, void* in, const uint8_t* key){
377 des_dec(out, in, (uint8_t*)key +16);
378 des_enc(out, out, (uint8_t*)key + 8);
379 des_dec(out, out, (uint8_t*)key + 0);
382 /******************************************************************************/