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 "avutil.h"
00023 #include "common.h"
00024 #include "intreadwrite.h"
00025 #include "des.h"
00026
00027 typedef struct AVDES AVDES;
00028
00029 #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
00030 static const uint8_t IP_shuffle[] = {
00031 T(58, 50, 42, 34, 26, 18, 10, 2),
00032 T(60, 52, 44, 36, 28, 20, 12, 4),
00033 T(62, 54, 46, 38, 30, 22, 14, 6),
00034 T(64, 56, 48, 40, 32, 24, 16, 8),
00035 T(57, 49, 41, 33, 25, 17, 9, 1),
00036 T(59, 51, 43, 35, 27, 19, 11, 3),
00037 T(61, 53, 45, 37, 29, 21, 13, 5),
00038 T(63, 55, 47, 39, 31, 23, 15, 7)
00039 };
00040 #undef T
00041
00042 #define T(a, b, c, d) 32-a,32-b,32-c,32-d
00043 static const uint8_t P_shuffle[] = {
00044 T(16, 7, 20, 21),
00045 T(29, 12, 28, 17),
00046 T( 1, 15, 23, 26),
00047 T( 5, 18, 31, 10),
00048 T( 2, 8, 24, 14),
00049 T(32, 27, 3, 9),
00050 T(19, 13, 30, 6),
00051 T(22, 11, 4, 25)
00052 };
00053 #undef T
00054
00055 #define T(a, b, c, d, e, f, g) 64-a,64-b,64-c,64-d,64-e,64-f,64-g
00056 static const uint8_t PC1_shuffle[] = {
00057 T(57, 49, 41, 33, 25, 17, 9),
00058 T( 1, 58, 50, 42, 34, 26, 18),
00059 T(10, 2, 59, 51, 43, 35, 27),
00060 T(19, 11, 3, 60, 52, 44, 36),
00061 T(63, 55, 47, 39, 31, 23, 15),
00062 T( 7, 62, 54, 46, 38, 30, 22),
00063 T(14, 6, 61, 53, 45, 37, 29),
00064 T(21, 13, 5, 28, 20, 12, 4)
00065 };
00066 #undef T
00067
00068 #define T(a, b, c, d, e, f) 56-a,56-b,56-c,56-d,56-e,56-f
00069 static const uint8_t PC2_shuffle[] = {
00070 T(14, 17, 11, 24, 1, 5),
00071 T( 3, 28, 15, 6, 21, 10),
00072 T(23, 19, 12, 4, 26, 8),
00073 T(16, 7, 27, 20, 13, 2),
00074 T(41, 52, 31, 37, 47, 55),
00075 T(30, 40, 51, 45, 33, 48),
00076 T(44, 49, 39, 56, 34, 53),
00077 T(46, 42, 50, 36, 29, 32)
00078 };
00079 #undef T
00080
00081 #if CONFIG_SMALL
00082 static const uint8_t S_boxes[8][32] = {
00083 {
00084 0x0e, 0xf4, 0x7d, 0x41, 0xe2, 0x2f, 0xdb, 0x18, 0xa3, 0x6a, 0xc6, 0xbc, 0x95, 0x59, 0x30, 0x87,
00085 0xf4, 0xc1, 0x8e, 0x28, 0x4d, 0x96, 0x12, 0x7b, 0x5f, 0xbc, 0x39, 0xe7, 0xa3, 0x0a, 0x65, 0xd0,
00086 }, {
00087 0x3f, 0xd1, 0x48, 0x7e, 0xf6, 0x2b, 0x83, 0xe4, 0xc9, 0x07, 0x12, 0xad, 0x6c, 0x90, 0xb5, 0x5a,
00088 0xd0, 0x8e, 0xa7, 0x1b, 0x3a, 0xf4, 0x4d, 0x21, 0xb5, 0x68, 0x7c, 0xc6, 0x09, 0x53, 0xe2, 0x9f,
00089 }, {
00090 0xda, 0x70, 0x09, 0x9e, 0x36, 0x43, 0x6f, 0xa5, 0x21, 0x8d, 0x5c, 0xe7, 0xcb, 0xb4, 0xf2, 0x18,
00091 0x1d, 0xa6, 0xd4, 0x09, 0x68, 0x9f, 0x83, 0x70, 0x4b, 0xf1, 0xe2, 0x3c, 0xb5, 0x5a, 0x2e, 0xc7,
00092 }, {
00093 0xd7, 0x8d, 0xbe, 0x53, 0x60, 0xf6, 0x09, 0x3a, 0x41, 0x72, 0x28, 0xc5, 0x1b, 0xac, 0xe4, 0x9f,
00094 0x3a, 0xf6, 0x09, 0x60, 0xac, 0x1b, 0xd7, 0x8d, 0x9f, 0x41, 0x53, 0xbe, 0xc5, 0x72, 0x28, 0xe4,
00095 }, {
00096 0xe2, 0xbc, 0x24, 0xc1, 0x47, 0x7a, 0xdb, 0x16, 0x58, 0x05, 0xf3, 0xaf, 0x3d, 0x90, 0x8e, 0x69,
00097 0xb4, 0x82, 0xc1, 0x7b, 0x1a, 0xed, 0x27, 0xd8, 0x6f, 0xf9, 0x0c, 0x95, 0xa6, 0x43, 0x50, 0x3e,
00098 }, {
00099 0xac, 0xf1, 0x4a, 0x2f, 0x79, 0xc2, 0x96, 0x58, 0x60, 0x1d, 0xd3, 0xe4, 0x0e, 0xb7, 0x35, 0x8b,
00100 0x49, 0x3e, 0x2f, 0xc5, 0x92, 0x58, 0xfc, 0xa3, 0xb7, 0xe0, 0x14, 0x7a, 0x61, 0x0d, 0x8b, 0xd6,
00101 }, {
00102 0xd4, 0x0b, 0xb2, 0x7e, 0x4f, 0x90, 0x18, 0xad, 0xe3, 0x3c, 0x59, 0xc7, 0x25, 0xfa, 0x86, 0x61,
00103 0x61, 0xb4, 0xdb, 0x8d, 0x1c, 0x43, 0xa7, 0x7e, 0x9a, 0x5f, 0x06, 0xf8, 0xe0, 0x25, 0x39, 0xc2,
00104 }, {
00105 0x1d, 0xf2, 0xd8, 0x84, 0xa6, 0x3f, 0x7b, 0x41, 0xca, 0x59, 0x63, 0xbe, 0x05, 0xe0, 0x9c, 0x27,
00106 0x27, 0x1b, 0xe4, 0x71, 0x49, 0xac, 0x8e, 0xd2, 0xf0, 0xc6, 0x9a, 0x0d, 0x3f, 0x53, 0x65, 0xb8,
00107 }
00108 };
00109 #else
00110
00114 static const uint32_t S_boxes_P_shuffle[8][64] = {
00115 {
00116 0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000,
00117 0x00000200, 0x00808200, 0x00808202, 0x00000200, 0x00800202, 0x00808002, 0x00800000, 0x00000002,
00118 0x00000202, 0x00800200, 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202,
00119 0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202, 0x00008202, 0x00800000,
00120 0x00008000, 0x00808202, 0x00000002, 0x00808000, 0x00808200, 0x00800000, 0x00800000, 0x00000200,
00121 0x00808002, 0x00008000, 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202,
00122 0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202, 0x00008202, 0x00808200,
00123 0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002,
00124 },
00125 {
00126 0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010,
00127 0x40000010, 0x40084010, 0x40084000, 0x40000000, 0x40004000, 0x00080000, 0x00000010, 0x40080010,
00128 0x00084000, 0x00080010, 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000,
00129 0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000, 0x40080000, 0x00004010,
00130 0x00000000, 0x00084010, 0x40080010, 0x00080000, 0x40004010, 0x40080000, 0x40084000, 0x00004000,
00131 0x40080000, 0x40004000, 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000,
00132 0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010, 0x40000010, 0x00080010,
00133 0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000,
00134 },
00135 {
00136 0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100,
00137 0x00010004, 0x04000004, 0x04000004, 0x00010000, 0x04010104, 0x00010004, 0x04010000, 0x00000104,
00138 0x04000000, 0x00000004, 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104,
00139 0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104, 0x00000100, 0x04000000,
00140 0x04010100, 0x04000000, 0x00010004, 0x00000104, 0x00010000, 0x04010100, 0x04000100, 0x00000000,
00141 0x00000100, 0x00010004, 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004,
00142 0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104, 0x00010100, 0x04000004,
00143 0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100,
00144 },
00145 {
00146 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000,
00147 0x00000000, 0x00401000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00400040, 0x80400000,
00148 0x80000000, 0x00001000, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040,
00149 0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040, 0x80401040, 0x80000040,
00150 0x00400040, 0x80400000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00000000, 0x00401000,
00151 0x00001040, 0x00400040, 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040,
00152 0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000, 0x00401040, 0x80400040,
00153 0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040,
00154 },
00155 {
00156 0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000,
00157 0x20040080, 0x00040000, 0x01000080, 0x20040080, 0x21000080, 0x21040000, 0x00040080, 0x20000000,
00158 0x01000000, 0x20040000, 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080,
00159 0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000, 0x21000000, 0x00040080,
00160 0x00040000, 0x21000080, 0x00000080, 0x01000000, 0x20000000, 0x01040000, 0x21000080, 0x20040080,
00161 0x01000080, 0x20000000, 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000,
00162 0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000, 0x20040000, 0x21000000,
00163 0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080,
00164 },
00165 {
00166 0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000,
00167 0x10002000, 0x00202008, 0x00200000, 0x10000008, 0x00200008, 0x10002000, 0x10000000, 0x00002008,
00168 0x00000000, 0x00200008, 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008,
00169 0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000, 0x10202000, 0x10000000,
00170 0x10002000, 0x00000008, 0x10200008, 0x00202000, 0x10202008, 0x00200000, 0x00002008, 0x10000008,
00171 0x00200000, 0x10002000, 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000,
00172 0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000, 0x10200000, 0x00202008,
00173 0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008,
00174 },
00175 {
00176 0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400,
00177 0x02100401, 0x00100000, 0x00000000, 0x02000001, 0x00000001, 0x02000000, 0x02100001, 0x00000401,
00178 0x02000400, 0x00100401, 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001,
00179 0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001, 0x02000000, 0x00100400,
00180 0x02000000, 0x00100400, 0x00100000, 0x02000401, 0x02000401, 0x02100001, 0x02100001, 0x00000001,
00181 0x00100001, 0x02000000, 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400,
00182 0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000, 0x00000001, 0x02100401,
00183 0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001,
00184 },
00185 {
00186 0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000,
00187 0x00020020, 0x08020000, 0x08020820, 0x00020800, 0x08020800, 0x00020820, 0x00000800, 0x00000020,
00188 0x08020000, 0x08000020, 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800,
00189 0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800, 0x00020820, 0x00020000,
00190 0x00020820, 0x00020000, 0x08020800, 0x00000800, 0x00000020, 0x08020020, 0x00000800, 0x00020820,
00191 0x08000800, 0x00000020, 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820,
00192 0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800, 0x08000820, 0x00000000,
00193 0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800,
00194 },
00195 };
00196 #endif
00197
00198 static uint64_t shuffle(uint64_t in, const uint8_t *shuffle, int shuffle_len) {
00199 int i;
00200 uint64_t res = 0;
00201 for (i = 0; i < shuffle_len; i++)
00202 res += res + ((in >> *shuffle++) & 1);
00203 return res;
00204 }
00205
00206 static uint64_t shuffle_inv(uint64_t in, const uint8_t *shuffle, int shuffle_len) {
00207 int i;
00208 uint64_t res = 0;
00209 shuffle += shuffle_len - 1;
00210 for (i = 0; i < shuffle_len; i++) {
00211 res |= (in & 1) << *shuffle--;
00212 in >>= 1;
00213 }
00214 return res;
00215 }
00216
00217 static uint32_t f_func(uint32_t r, uint64_t k) {
00218 int i;
00219 uint32_t out = 0;
00220
00221 r = (r << 1) | (r >> 31);
00222
00223 for (i = 7; i >= 0; i--) {
00224 uint8_t tmp = (r ^ k) & 0x3f;
00225 #if CONFIG_SMALL
00226 uint8_t v = S_boxes[i][tmp >> 1];
00227 if (tmp & 1) v >>= 4;
00228 out = (out >> 4) | (v << 28);
00229 #else
00230 out |= S_boxes_P_shuffle[i][tmp];
00231 #endif
00232
00233 r = (r >> 4) | (r << 28);
00234 k >>= 6;
00235 }
00236 #if CONFIG_SMALL
00237 out = shuffle(out, P_shuffle, sizeof(P_shuffle));
00238 #endif
00239 return out;
00240 }
00241
00248 static uint64_t key_shift_left(uint64_t CDn) {
00249 uint64_t carries = (CDn >> 27) & 0x10000001;
00250 CDn <<= 1;
00251 CDn &= ~0x10000001;
00252 CDn |= carries;
00253 return CDn;
00254 }
00255
00256 static void gen_roundkeys(uint64_t K[16], uint64_t key) {
00257 int i;
00258
00259 uint64_t CDn = shuffle(key, PC1_shuffle, sizeof(PC1_shuffle));
00260
00261 for (i = 0; i < 16; i++) {
00262 CDn = key_shift_left(CDn);
00263 if (i > 1 && i != 8 && i != 15)
00264 CDn = key_shift_left(CDn);
00265 K[i] = shuffle(CDn, PC2_shuffle, sizeof(PC2_shuffle));
00266 }
00267 }
00268
00269 static uint64_t des_encdec(uint64_t in, uint64_t K[16], int decrypt) {
00270 int i;
00271
00272 decrypt = decrypt ? 15 : 0;
00273
00274 in = shuffle(in, IP_shuffle, sizeof(IP_shuffle));
00275 for (i = 0; i < 16; i++) {
00276 uint32_t f_res;
00277 f_res = f_func(in, K[decrypt ^ i]);
00278 in = (in << 32) | (in >> 32);
00279 in ^= f_res;
00280 }
00281 in = (in << 32) | (in >> 32);
00282
00283 in = shuffle_inv(in, IP_shuffle, sizeof(IP_shuffle));
00284 return in;
00285 }
00286
00287 int av_des_init(AVDES *d, const uint8_t *key, int key_bits, int decrypt) {
00288 if (key_bits != 64 && key_bits != 192)
00289 return -1;
00290 d->triple_des = key_bits > 64;
00291 gen_roundkeys(d->round_keys[0], AV_RB64(key));
00292 if (d->triple_des) {
00293 gen_roundkeys(d->round_keys[1], AV_RB64(key + 8));
00294 gen_roundkeys(d->round_keys[2], AV_RB64(key + 16));
00295 }
00296 return 0;
00297 }
00298
00299 void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) {
00300 uint64_t iv_val = iv ? av_be2ne64(*(uint64_t *)iv) : 0;
00301 while (count-- > 0) {
00302 uint64_t dst_val;
00303 uint64_t src_val = src ? av_be2ne64(*(const uint64_t *)src) : 0;
00304 if (decrypt) {
00305 uint64_t tmp = src_val;
00306 if (d->triple_des) {
00307 src_val = des_encdec(src_val, d->round_keys[2], 1);
00308 src_val = des_encdec(src_val, d->round_keys[1], 0);
00309 }
00310 dst_val = des_encdec(src_val, d->round_keys[0], 1) ^ iv_val;
00311 iv_val = iv ? tmp : 0;
00312 } else {
00313 dst_val = des_encdec(src_val ^ iv_val, d->round_keys[0], 0);
00314 if (d->triple_des) {
00315 dst_val = des_encdec(dst_val, d->round_keys[1], 1);
00316 dst_val = des_encdec(dst_val, d->round_keys[2], 0);
00317 }
00318 iv_val = iv ? dst_val : 0;
00319 }
00320 *(uint64_t *)dst = av_be2ne64(dst_val);
00321 src += 8;
00322 dst += 8;
00323 }
00324 if (iv)
00325 *(uint64_t *)iv = av_be2ne64(iv_val);
00326 }
00327
00328 #ifdef TEST
00329 #undef printf
00330 #undef rand
00331 #undef srand
00332 #include <stdlib.h>
00333 #include <stdio.h>
00334 #include <sys/time.h>
00335 static uint64_t rand64(void) {
00336 uint64_t r = rand();
00337 r = (r << 32) | rand();
00338 return r;
00339 }
00340
00341 static const uint8_t test_key[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
00342 static const DECLARE_ALIGNED(8, uint8_t, plain)[] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
00343 static const DECLARE_ALIGNED(8, uint8_t, crypt)[] = {0x4a, 0xb6, 0x5b, 0x3d, 0x4b, 0x06, 0x15, 0x18};
00344 static DECLARE_ALIGNED(8, uint8_t, tmp)[8];
00345 static DECLARE_ALIGNED(8, uint8_t, large_buffer)[10002][8];
00346 static const uint8_t cbc_key[] = {
00347 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
00348 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
00349 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
00350 };
00351
00352 static int run_test(int cbc, int decrypt) {
00353 AVDES d;
00354 int delay = cbc && !decrypt ? 2 : 1;
00355 uint64_t res;
00356 AV_WB64(large_buffer[0], 0x4e6f772069732074ULL);
00357 AV_WB64(large_buffer[1], 0x1234567890abcdefULL);
00358 AV_WB64(tmp, 0x1234567890abcdefULL);
00359 av_des_init(&d, cbc_key, 192, decrypt);
00360 av_des_crypt(&d, large_buffer[delay], large_buffer[0], 10000, cbc ? tmp : NULL, decrypt);
00361 res = AV_RB64(large_buffer[9999 + delay]);
00362 if (cbc) {
00363 if (decrypt)
00364 return res == 0xc5cecf63ecec514cULL;
00365 else
00366 return res == 0xcb191f85d1ed8439ULL;
00367 } else {
00368 if (decrypt)
00369 return res == 0x8325397644091a0aULL;
00370 else
00371 return res == 0xdd17e8b8b437d232ULL;
00372 }
00373 }
00374
00375 int main(void) {
00376 AVDES d;
00377 int i;
00378 #ifdef GENTABLES
00379 int j;
00380 #endif
00381 struct timeval tv;
00382 uint64_t key[3];
00383 uint64_t data;
00384 uint64_t ct;
00385 uint64_t roundkeys[16];
00386 gettimeofday(&tv, NULL);
00387 srand(tv.tv_sec * 1000 * 1000 + tv.tv_usec);
00388 key[0] = AV_RB64(test_key);
00389 data = AV_RB64(plain);
00390 gen_roundkeys(roundkeys, key[0]);
00391 if (des_encdec(data, roundkeys, 0) != AV_RB64(crypt)) {
00392 printf("Test 1 failed\n");
00393 return 1;
00394 }
00395 av_des_init(&d, test_key, 64, 0);
00396 av_des_crypt(&d, tmp, plain, 1, NULL, 0);
00397 if (memcmp(tmp, crypt, sizeof(crypt))) {
00398 printf("Public API decryption failed\n");
00399 return 1;
00400 }
00401 if (!run_test(0, 0) || !run_test(0, 1) || !run_test(1, 0) || !run_test(1, 1)) {
00402 printf("Partial Monte-Carlo test failed\n");
00403 return 1;
00404 }
00405 for (i = 0; i < 1000000; i++) {
00406 key[0] = rand64(); key[1] = rand64(); key[2] = rand64();
00407 data = rand64();
00408 av_des_init(&d, key, 192, 0);
00409 av_des_crypt(&d, &ct, &data, 1, NULL, 0);
00410 av_des_init(&d, key, 192, 1);
00411 av_des_crypt(&d, &ct, &ct, 1, NULL, 1);
00412 if (ct != data) {
00413 printf("Test 2 failed\n");
00414 return 1;
00415 }
00416 }
00417 #ifdef GENTABLES
00418 printf("static const uint32_t S_boxes_P_shuffle[8][64] = {\n");
00419 for (i = 0; i < 8; i++) {
00420 printf(" {");
00421 for (j = 0; j < 64; j++) {
00422 uint32_t v = S_boxes[i][j >> 1];
00423 v = j & 1 ? v >> 4 : v & 0xf;
00424 v <<= 28 - 4 * i;
00425 v = shuffle(v, P_shuffle, sizeof(P_shuffle));
00426 printf((j & 7) == 0 ? "\n " : " ");
00427 printf("0x%08X,", v);
00428 }
00429 printf("\n },\n");
00430 }
00431 printf("};\n");
00432 #endif
00433 return 0;
00434 }
00435 #endif