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 #if LIBAVUTIL_VERSION_MAJOR < 50
00288 uint64_t ff_des_encdec(uint64_t in, uint64_t key, int decrypt) {
00289 uint64_t K[16];
00290 gen_roundkeys(K, key);
00291 return des_encdec(in, K, decrypt);
00292 }
00293 #endif
00294
00295 int av_des_init(AVDES *d, const uint8_t *key, int key_bits, int decrypt) {
00296 if (key_bits != 64 && key_bits != 192)
00297 return -1;
00298 d->triple_des = key_bits > 64;
00299 gen_roundkeys(d->round_keys[0], AV_RB64(key));
00300 if (d->triple_des) {
00301 gen_roundkeys(d->round_keys[1], AV_RB64(key + 8));
00302 gen_roundkeys(d->round_keys[2], AV_RB64(key + 16));
00303 }
00304 return 0;
00305 }
00306
00307 void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) {
00308 uint64_t iv_val = iv ? be2me_64(*(uint64_t *)iv) : 0;
00309 while (count-- > 0) {
00310 uint64_t dst_val;
00311 uint64_t src_val = src ? be2me_64(*(const uint64_t *)src) : 0;
00312 if (decrypt) {
00313 uint64_t tmp = src_val;
00314 if (d->triple_des) {
00315 src_val = des_encdec(src_val, d->round_keys[2], 1);
00316 src_val = des_encdec(src_val, d->round_keys[1], 0);
00317 }
00318 dst_val = des_encdec(src_val, d->round_keys[0], 1) ^ iv_val;
00319 iv_val = iv ? tmp : 0;
00320 } else {
00321 dst_val = des_encdec(src_val ^ iv_val, d->round_keys[0], 0);
00322 if (d->triple_des) {
00323 dst_val = des_encdec(dst_val, d->round_keys[1], 1);
00324 dst_val = des_encdec(dst_val, d->round_keys[2], 0);
00325 }
00326 iv_val = iv ? dst_val : 0;
00327 }
00328 *(uint64_t *)dst = be2me_64(dst_val);
00329 src += 8;
00330 dst += 8;
00331 }
00332 if (iv)
00333 *(uint64_t *)iv = be2me_64(iv_val);
00334 }
00335
00336 #ifdef TEST
00337 #undef printf
00338 #undef rand
00339 #undef srand
00340 #include <stdlib.h>
00341 #include <stdio.h>
00342 #include <sys/time.h>
00343 static uint64_t rand64(void) {
00344 uint64_t r = rand();
00345 r = (r << 32) | rand();
00346 return r;
00347 }
00348
00349 static const uint8_t test_key[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
00350 static const DECLARE_ALIGNED(8, uint8_t, plain[]) = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
00351 static const DECLARE_ALIGNED(8, uint8_t, crypt[]) = {0x4a, 0xb6, 0x5b, 0x3d, 0x4b, 0x06, 0x15, 0x18};
00352 static DECLARE_ALIGNED(8, uint8_t, tmp[8]);
00353 static DECLARE_ALIGNED(8, uint8_t, large_buffer[10002][8]);
00354 static const uint8_t cbc_key[] = {
00355 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
00356 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
00357 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
00358 };
00359
00360 int run_test(int cbc, int decrypt) {
00361 AVDES d;
00362 int delay = cbc && !decrypt ? 2 : 1;
00363 uint64_t res;
00364 AV_WB64(large_buffer[0], 0x4e6f772069732074ULL);
00365 AV_WB64(large_buffer[1], 0x1234567890abcdefULL);
00366 AV_WB64(tmp, 0x1234567890abcdefULL);
00367 av_des_init(&d, cbc_key, 192, decrypt);
00368 av_des_crypt(&d, large_buffer[delay], large_buffer[0], 10000, cbc ? tmp : NULL, decrypt);
00369 res = AV_RB64(large_buffer[9999 + delay]);
00370 if (cbc) {
00371 if (decrypt)
00372 return res == 0xc5cecf63ecec514cULL;
00373 else
00374 return res == 0xcb191f85d1ed8439ULL;
00375 } else {
00376 if (decrypt)
00377 return res == 0x8325397644091a0aULL;
00378 else
00379 return res == 0xdd17e8b8b437d232ULL;
00380 }
00381 }
00382
00383 int main(void) {
00384 AVDES d;
00385 int i;
00386 #ifdef GENTABLES
00387 int j;
00388 #endif
00389 struct timeval tv;
00390 uint64_t key[3];
00391 uint64_t data;
00392 uint64_t ct;
00393 gettimeofday(&tv, NULL);
00394 srand(tv.tv_sec * 1000 * 1000 + tv.tv_usec);
00395 #if LIBAVUTIL_VERSION_MAJOR < 50
00396 key[0] = AV_RB64(test_key);
00397 data = AV_RB64(plain);
00398 if (ff_des_encdec(data, key[0], 0) != AV_RB64(crypt)) {
00399 printf("Test 1 failed\n");
00400 return 1;
00401 }
00402 #endif
00403 av_des_init(&d, test_key, 64, 0);
00404 av_des_crypt(&d, tmp, plain, 1, NULL, 0);
00405 if (memcmp(tmp, crypt, sizeof(crypt))) {
00406 printf("Public API decryption failed\n");
00407 return 1;
00408 }
00409 if (!run_test(0, 0) || !run_test(0, 1) || !run_test(1, 0) || !run_test(1, 1)) {
00410 printf("Partial Monte-Carlo test failed\n");
00411 return 1;
00412 }
00413 for (i = 0; i < 1000000; i++) {
00414 key[0] = rand64(); key[1] = rand64(); key[2] = rand64();
00415 data = rand64();
00416 av_des_init(&d, key, 192, 0);
00417 av_des_crypt(&d, &ct, &data, 1, NULL, 0);
00418 av_des_init(&d, key, 192, 1);
00419 av_des_crypt(&d, &ct, &ct, 1, NULL, 1);
00420 if (ct != data) {
00421 printf("Test 2 failed\n");
00422 return 1;
00423 }
00424 }
00425 #ifdef GENTABLES
00426 printf("static const uint32_t S_boxes_P_shuffle[8][64] = {\n");
00427 for (i = 0; i < 8; i++) {
00428 printf(" {");
00429 for (j = 0; j < 64; j++) {
00430 uint32_t v = S_boxes[i][j >> 1];
00431 v = j & 1 ? v >> 4 : v & 0xf;
00432 v <<= 28 - 4 * i;
00433 v = shuffle(v, P_shuffle, sizeof(P_shuffle));
00434 printf((j & 7) == 0 ? "\n " : " ");
00435 printf("0x%08X,", v);
00436 }
00437 printf("\n },\n");
00438 }
00439 printf("};\n");
00440 #endif
00441 return 0;
00442 }
00443 #endif