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(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 */
209 ptable
= &(ptable
[2]);
210 for(byte
=0; byte
<ob
; ++byte
){
212 for(bit
=0; bit
<8; ++bit
){
215 if((in
[x
/8]) & (0x80>>(x
%8)) ){
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 /******************************************************************************/
234 void shiftkey(uint8_t *key
){
237 permute((uint8_t*)shiftkey_permtab
, k
, key
);
240 /******************************************************************************/
242 void shiftkey_inv(uint8_t *key
){
245 permute((uint8_t*)shiftkeyinv_permtab
, k
, key
);
249 /******************************************************************************/
251 uint64_t splitin6bitwords(uint64_t a
){
253 a
&= 0x0000ffffffffffffLL
;
254 permute((uint8_t*)splitin6bitword_permtab
, (uint8_t*)&a
, (uint8_t*)&ret
);
258 /******************************************************************************/
261 uint8_t substitute(uint8_t a
, uint8_t * sbp
){
264 x
= (a
&1)?x
&0x0F:x
>>4;
269 /******************************************************************************/
271 uint32_t des_f(uint32_t r
, uint8_t* kr
){
275 uint8_t *sbp
; /* sboxpointer */
276 permute((uint8_t*)e_permtab
, (uint8_t*)&r
, (uint8_t*)&data
);
278 ((uint8_t*)&data
)[i
] ^= kr
[i
];
280 /* Sbox substitution */
281 data
= splitin6bitwords(data
);
285 x
= substitute(((uint8_t*)&data
)[i
], sbp
);
292 permute((uint8_t*)p_permtab
,(uint8_t*)&t
, (uint8_t*)&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];
306 permute((uint8_t*)ip_permtab
, (uint8_t*)in
, data
);
307 permute((uint8_t*)pc1_permtab
, (const uint8_t*)key
, k
);
310 if(ROTTABLE
&((1<<((i
<<1)+0))) )
312 permute((uint8_t*)pc2_permtab
, k
, kr
);
316 if(ROTTABLE
&((1<<((i
<<1)+1))) )
318 permute((uint8_t*)pc2_permtab
, k
, kr
);
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];
338 permute((uint8_t*)ip_permtab
, (uint8_t*)in
, data
);
339 permute((uint8_t*)pc1_permtab
, (const uint8_t*)key
, k
);
342 permute((uint8_t*)pc2_permtab
, k
, kr
);
345 if(ROTTABLE
&((1<<((i
<<1)+1))) ){
349 permute((uint8_t*)pc2_permtab
, k
, kr
);
352 if(ROTTABLE
&((1<<((i
<<1)+0))) ){
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 /******************************************************************************/