00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <inttypes.h>
00022 #include "des.h"
00023
00024 #define T(a, b, c, d, e, f, g, h) 64-a,64-b,64-c,64-d,64-e,64-f,64-g,64-h
00025 static const uint8_t IP_shuffle[] = {
00026 T(58, 50, 42, 34, 26, 18, 10, 2),
00027 T(60, 52, 44, 36, 28, 20, 12, 4),
00028 T(62, 54, 46, 38, 30, 22, 14, 6),
00029 T(64, 56, 48, 40, 32, 24, 16, 8),
00030 T(57, 49, 41, 33, 25, 17, 9, 1),
00031 T(59, 51, 43, 35, 27, 19, 11, 3),
00032 T(61, 53, 45, 37, 29, 21, 13, 5),
00033 T(63, 55, 47, 39, 31, 23, 15, 7)
00034 };
00035 #undef T
00036
00037 #define T(a, b, c, d) 32-a,32-b,32-c,32-d
00038 static const uint8_t P_shuffle[] = {
00039 T(16, 7, 20, 21),
00040 T(29, 12, 28, 17),
00041 T( 1, 15, 23, 26),
00042 T( 5, 18, 31, 10),
00043 T( 2, 8, 24, 14),
00044 T(32, 27, 3, 9),
00045 T(19, 13, 30, 6),
00046 T(22, 11, 4, 25)
00047 };
00048 #undef T
00049
00050 #define T(a, b, c, d, e, f, g) 64-a,64-b,64-c,64-d,64-e,64-f,64-g
00051 static const uint8_t PC1_shuffle[] = {
00052 T(57, 49, 41, 33, 25, 17, 9),
00053 T( 1, 58, 50, 42, 34, 26, 18),
00054 T(10, 2, 59, 51, 43, 35, 27),
00055 T(19, 11, 3, 60, 52, 44, 36),
00056 T(63, 55, 47, 39, 31, 23, 15),
00057 T( 7, 62, 54, 46, 38, 30, 22),
00058 T(14, 6, 61, 53, 45, 37, 29),
00059 T(21, 13, 5, 28, 20, 12, 4)
00060 };
00061 #undef T
00062
00063 #define T(a, b, c, d, e, f) 56-a,56-b,56-c,56-d,56-e,56-f
00064 static const uint8_t PC2_shuffle[] = {
00065 T(14, 17, 11, 24, 1, 5),
00066 T( 3, 28, 15, 6, 21, 10),
00067 T(23, 19, 12, 4, 26, 8),
00068 T(16, 7, 27, 20, 13, 2),
00069 T(41, 52, 31, 37, 47, 55),
00070 T(30, 40, 51, 45, 33, 48),
00071 T(44, 49, 39, 56, 34, 53),
00072 T(46, 42, 50, 36, 29, 32)
00073 };
00074 #undef T
00075
00076 #ifdef CONFIG_SMALL
00077 static const uint8_t S_boxes[8][32] = {
00078 {
00079 0x0e, 0xf4, 0x7d, 0x41, 0xe2, 0x2f, 0xdb, 0x18, 0xa3, 0x6a, 0xc6, 0xbc, 0x95, 0x59, 0x30, 0x87,
00080 0xf4, 0xc1, 0x8e, 0x28, 0x4d, 0x96, 0x12, 0x7b, 0x5f, 0xbc, 0x39, 0xe7, 0xa3, 0x0a, 0x65, 0xd0,
00081 }, {
00082 0x3f, 0xd1, 0x48, 0x7e, 0xf6, 0x2b, 0x83, 0xe4, 0xc9, 0x07, 0x12, 0xad, 0x6c, 0x90, 0xb5, 0x5a,
00083 0xd0, 0x8e, 0xa7, 0x1b, 0x3a, 0xf4, 0x4d, 0x21, 0xb5, 0x68, 0x7c, 0xc6, 0x09, 0x53, 0xe2, 0x9f,
00084 }, {
00085 0xda, 0x70, 0x09, 0x9e, 0x36, 0x43, 0x6f, 0xa5, 0x21, 0x8d, 0x5c, 0xe7, 0xcb, 0xb4, 0xf2, 0x18,
00086 0x1d, 0xa6, 0xd4, 0x09, 0x68, 0x9f, 0x83, 0x70, 0x4b, 0xf1, 0xe2, 0x3c, 0xb5, 0x5a, 0x2e, 0xc7,
00087 }, {
00088 0xd7, 0x8d, 0xbe, 0x53, 0x60, 0xf6, 0x09, 0x3a, 0x41, 0x72, 0x28, 0xc5, 0x1b, 0xac, 0xe4, 0x9f,
00089 0x3a, 0xf6, 0x09, 0x60, 0xac, 0x1b, 0xd7, 0x8d, 0x9f, 0x41, 0x53, 0xbe, 0xc5, 0x72, 0x28, 0xe4,
00090 }, {
00091 0xe2, 0xbc, 0x24, 0xc1, 0x47, 0x7a, 0xdb, 0x16, 0x58, 0x05, 0xf3, 0xaf, 0x3d, 0x90, 0x8e, 0x69,
00092 0xb4, 0x82, 0xc1, 0x7b, 0x1a, 0xed, 0x27, 0xd8, 0x6f, 0xf9, 0x0c, 0x95, 0xa6, 0x43, 0x50, 0x3e,
00093 }, {
00094 0xac, 0xf1, 0x4a, 0x2f, 0x79, 0xc2, 0x96, 0x58, 0x60, 0x1d, 0xd3, 0xe4, 0x0e, 0xb7, 0x35, 0x8b,
00095 0x49, 0x3e, 0x2f, 0xc5, 0x92, 0x58, 0xfc, 0xa3, 0xb7, 0xe0, 0x14, 0x7a, 0x61, 0x0d, 0x8b, 0xd6,
00096 }, {
00097 0xd4, 0x0b, 0xb2, 0x7e, 0x4f, 0x90, 0x18, 0xad, 0xe3, 0x3c, 0x59, 0xc7, 0x25, 0xfa, 0x86, 0x61,
00098 0x61, 0xb4, 0xdb, 0x8d, 0x1c, 0x43, 0xa7, 0x7e, 0x9a, 0x5f, 0x06, 0xf8, 0xe0, 0x25, 0x39, 0xc2,
00099 }, {
00100 0x1d, 0xf2, 0xd8, 0x84, 0xa6, 0x3f, 0x7b, 0x41, 0xca, 0x59, 0x63, 0xbe, 0x05, 0xe0, 0x9c, 0x27,
00101 0x27, 0x1b, 0xe4, 0x71, 0x49, 0xac, 0x8e, 0xd2, 0xf0, 0xc6, 0x9a, 0x0d, 0x3f, 0x53, 0x65, 0xb8,
00102 }
00103 };
00104 #else
00105
00109 static const uint32_t S_boxes_P_shuffle[8][64] = {
00110 {
00111 0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000,
00112 0x00000200, 0x00808200, 0x00808202, 0x00000200, 0x00800202, 0x00808002, 0x00800000, 0x00000002,
00113 0x00000202, 0x00800200, 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202,
00114 0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202, 0x00008202, 0x00800000,
00115 0x00008000, 0x00808202, 0x00000002, 0x00808000, 0x00808200, 0x00800000, 0x00800000, 0x00000200,
00116 0x00808002, 0x00008000, 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202,
00117 0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202, 0x00008202, 0x00808200,
00118 0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002,
00119 },
00120 {
00121 0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010,
00122 0x40000010, 0x40084010, 0x40084000, 0x40000000, 0x40004000, 0x00080000, 0x00000010, 0x40080010,
00123 0x00084000, 0x00080010, 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000,
00124 0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000, 0x40080000, 0x00004010,
00125 0x00000000, 0x00084010, 0x40080010, 0x00080000, 0x40004010, 0x40080000, 0x40084000, 0x00004000,
00126 0x40080000, 0x40004000, 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000,
00127 0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010, 0x40000010, 0x00080010,
00128 0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000,
00129 },
00130 {
00131 0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100,
00132 0x00010004, 0x04000004, 0x04000004, 0x00010000, 0x04010104, 0x00010004, 0x04010000, 0x00000104,
00133 0x04000000, 0x00000004, 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104,
00134 0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104, 0x00000100, 0x04000000,
00135 0x04010100, 0x04000000, 0x00010004, 0x00000104, 0x00010000, 0x04010100, 0x04000100, 0x00000000,
00136 0x00000100, 0x00010004, 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004,
00137 0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104, 0x00010100, 0x04000004,
00138 0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100,
00139 },
00140 {
00141 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000,
00142 0x00000000, 0x00401000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00400040, 0x80400000,
00143 0x80000000, 0x00001000, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040,
00144 0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040, 0x80401040, 0x80000040,
00145 0x00400040, 0x80400000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00000000, 0x00401000,
00146 0x00001040, 0x00400040, 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040,
00147 0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000, 0x00401040, 0x80400040,
00148 0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040,
00149 },
00150 {
00151 0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000,
00152 0x20040080, 0x00040000, 0x01000080, 0x20040080, 0x21000080, 0x21040000, 0x00040080, 0x20000000,
00153 0x01000000, 0x20040000, 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080,
00154 0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000, 0x21000000, 0x00040080,
00155 0x00040000, 0x21000080, 0x00000080, 0x01000000, 0x20000000, 0x01040000, 0x21000080, 0x20040080,
00156 0x01000080, 0x20000000, 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000,
00157 0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000, 0x20040000, 0x21000000,
00158 0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080,
00159 },
00160 {
00161 0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000,
00162 0x10002000, 0x00202008, 0x00200000, 0x10000008, 0x00200008, 0x10002000, 0x10000000, 0x00002008,
00163 0x00000000, 0x00200008, 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008,
00164 0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000, 0x10202000, 0x10000000,
00165 0x10002000, 0x00000008, 0x10200008, 0x00202000, 0x10202008, 0x00200000, 0x00002008, 0x10000008,
00166 0x00200000, 0x10002000, 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000,
00167 0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000, 0x10200000, 0x00202008,
00168 0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008,
00169 },
00170 {
00171 0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400,
00172 0x02100401, 0x00100000, 0x00000000, 0x02000001, 0x00000001, 0x02000000, 0x02100001, 0x00000401,
00173 0x02000400, 0x00100401, 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001,
00174 0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001, 0x02000000, 0x00100400,
00175 0x02000000, 0x00100400, 0x00100000, 0x02000401, 0x02000401, 0x02100001, 0x02100001, 0x00000001,
00176 0x00100001, 0x02000000, 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400,
00177 0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000, 0x00000001, 0x02100401,
00178 0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001,
00179 },
00180 {
00181 0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000,
00182 0x00020020, 0x08020000, 0x08020820, 0x00020800, 0x08020800, 0x00020820, 0x00000800, 0x00000020,
00183 0x08020000, 0x08000020, 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800,
00184 0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800, 0x00020820, 0x00020000,
00185 0x00020820, 0x00020000, 0x08020800, 0x00000800, 0x00000020, 0x08020020, 0x00000800, 0x00020820,
00186 0x08000800, 0x00000020, 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820,
00187 0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800, 0x08000820, 0x00000000,
00188 0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800,
00189 },
00190 };
00191 #endif
00192
00193 static uint64_t shuffle(uint64_t in, const uint8_t *shuffle, int shuffle_len) {
00194 int i;
00195 uint64_t res = 0;
00196 for (i = 0; i < shuffle_len; i++)
00197 res += res + ((in >> *shuffle++) & 1);
00198 return res;
00199 }
00200
00201 static uint64_t shuffle_inv(uint64_t in, const uint8_t *shuffle, int shuffle_len) {
00202 int i;
00203 uint64_t res = 0;
00204 shuffle += shuffle_len - 1;
00205 for (i = 0; i < shuffle_len; i++) {
00206 res |= (in & 1) << *shuffle--;
00207 in >>= 1;
00208 }
00209 return res;
00210 }
00211
00212 static uint32_t f_func(uint32_t r, uint64_t k) {
00213 int i;
00214 uint32_t out = 0;
00215
00216 r = (r << 1) | (r >> 31);
00217
00218 for (i = 7; i >= 0; i--) {
00219 uint8_t tmp = (r ^ k) & 0x3f;
00220 #ifdef CONFIG_SMALL
00221 uint8_t v = S_boxes[i][tmp >> 1];
00222 if (tmp & 1) v >>= 4;
00223 out = (out >> 4) | (v << 28);
00224 #else
00225 out |= S_boxes_P_shuffle[i][tmp];
00226 #endif
00227
00228 r = (r >> 4) | (r << 28);
00229 k >>= 6;
00230 }
00231 #ifdef CONFIG_SMALL
00232 out = shuffle(out, P_shuffle, sizeof(P_shuffle));
00233 #endif
00234 return out;
00235 }
00236
00243 static uint64_t key_shift_left(uint64_t CDn) {
00244 uint64_t carries = (CDn >> 27) & 0x10000001;
00245 CDn <<= 1;
00246 CDn &= ~0x10000001;
00247 CDn |= carries;
00248 return CDn;
00249 }
00250
00251 uint64_t ff_des_encdec(uint64_t in, uint64_t key, int decrypt) {
00252 int i;
00253 uint64_t K[16];
00254
00255 uint64_t CDn = shuffle(key, PC1_shuffle, sizeof(PC1_shuffle));
00256
00257 for (i = 0; i < 16; i++) {
00258 CDn = key_shift_left(CDn);
00259 if (i > 1 && i != 8 && i != 15)
00260 CDn = key_shift_left(CDn);
00261 K[i] = shuffle(CDn, PC2_shuffle, sizeof(PC2_shuffle));
00262 }
00263
00264 decrypt = decrypt ? 15 : 0;
00265
00266 in = shuffle(in, IP_shuffle, sizeof(IP_shuffle));
00267 for (i = 0; i < 16; i++) {
00268 uint32_t f_res;
00269 f_res = f_func(in, K[decrypt ^ i]);
00270 in = (in << 32) | (in >> 32);
00271 in ^= f_res;
00272 }
00273 in = (in << 32) | (in >> 32);
00274
00275 in = shuffle_inv(in, IP_shuffle, sizeof(IP_shuffle));
00276 return in;
00277 }
00278
00279 #ifdef TEST
00280 #include <stdlib.h>
00281 #include <stdio.h>
00282 #include <sys/time.h>
00283 static uint64_t rand64(void) {
00284 uint64_t r = rand();
00285 r = (r << 32) | rand();
00286 return r;
00287 }
00288
00289 int main(void) {
00290 int i, j;
00291 struct timeval tv;
00292 uint64_t key;
00293 uint64_t data;
00294 uint64_t ct;
00295 gettimeofday(&tv, NULL);
00296 srand(tv.tv_sec * 1000 * 1000 + tv.tv_usec);
00297 key = 0x123456789abcdef0ULL;
00298 data = 0xfedcba9876543210ULL;
00299 if (ff_des_encdec(data, key, 0) != 0x4ab65b3d4b061518ULL) {
00300 printf("Test 1 failed\n");
00301 return 1;
00302 }
00303 for (i = 0; i < 1000000; i++) {
00304 key = rand64();
00305 data = rand64();
00306 ct = ff_des_encdec(data, key, 0);
00307 if (ff_des_encdec(ct, key, 1) != data) {
00308 printf("Test 2 failed\n");
00309 return 1;
00310 }
00311 }
00312 #ifdef GENTABLES
00313 printf("static const uint32_t S_boxes_P_shuffle[8][64] = {\n");
00314 for (i = 0; i < 8; i++) {
00315 printf(" {");
00316 for (j = 0; j < 64; j++) {
00317 uint32_t v = S_boxes[i][j >> 1];
00318 v = j & 1 ? v >> 4 : v & 0xf;
00319 v <<= 28 - 4 * i;
00320 v = shuffle(v, P_shuffle, sizeof(P_shuffle));
00321 printf((j & 7) == 0 ? "\n " : " ");
00322 printf("0x%08X,", v);
00323 }
00324 printf("\n },\n");
00325 }
00326 printf("};\n");
00327 #endif
00328 return 0;
00329 }
00330 #endif