1/* 2 * DES encryption/decryption 3 * Copyright (c) 2007 Reimar Doeffinger 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21#include <inttypes.h> 22#include "avutil.h" 23#include "common.h" 24#include "intreadwrite.h" 25#include "des.h" 26 27typedef struct AVDES AVDES; 28 29#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 30static const uint8_t IP_shuffle[] = { 31 T(58, 50, 42, 34, 26, 18, 10, 2), 32 T(60, 52, 44, 36, 28, 20, 12, 4), 33 T(62, 54, 46, 38, 30, 22, 14, 6), 34 T(64, 56, 48, 40, 32, 24, 16, 8), 35 T(57, 49, 41, 33, 25, 17, 9, 1), 36 T(59, 51, 43, 35, 27, 19, 11, 3), 37 T(61, 53, 45, 37, 29, 21, 13, 5), 38 T(63, 55, 47, 39, 31, 23, 15, 7) 39}; 40#undef T 41 42#define T(a, b, c, d) 32-a,32-b,32-c,32-d 43static const uint8_t P_shuffle[] = { 44 T(16, 7, 20, 21), 45 T(29, 12, 28, 17), 46 T( 1, 15, 23, 26), 47 T( 5, 18, 31, 10), 48 T( 2, 8, 24, 14), 49 T(32, 27, 3, 9), 50 T(19, 13, 30, 6), 51 T(22, 11, 4, 25) 52}; 53#undef T 54 55#define T(a, b, c, d, e, f, g) 64-a,64-b,64-c,64-d,64-e,64-f,64-g 56static const uint8_t PC1_shuffle[] = { 57 T(57, 49, 41, 33, 25, 17, 9), 58 T( 1, 58, 50, 42, 34, 26, 18), 59 T(10, 2, 59, 51, 43, 35, 27), 60 T(19, 11, 3, 60, 52, 44, 36), 61 T(63, 55, 47, 39, 31, 23, 15), 62 T( 7, 62, 54, 46, 38, 30, 22), 63 T(14, 6, 61, 53, 45, 37, 29), 64 T(21, 13, 5, 28, 20, 12, 4) 65}; 66#undef T 67 68#define T(a, b, c, d, e, f) 56-a,56-b,56-c,56-d,56-e,56-f 69static const uint8_t PC2_shuffle[] = { 70 T(14, 17, 11, 24, 1, 5), 71 T( 3, 28, 15, 6, 21, 10), 72 T(23, 19, 12, 4, 26, 8), 73 T(16, 7, 27, 20, 13, 2), 74 T(41, 52, 31, 37, 47, 55), 75 T(30, 40, 51, 45, 33, 48), 76 T(44, 49, 39, 56, 34, 53), 77 T(46, 42, 50, 36, 29, 32) 78}; 79#undef T 80 81#if CONFIG_SMALL 82static const uint8_t S_boxes[8][32] = { 83 { 84 0x0e, 0xf4, 0x7d, 0x41, 0xe2, 0x2f, 0xdb, 0x18, 0xa3, 0x6a, 0xc6, 0xbc, 0x95, 0x59, 0x30, 0x87, 85 0xf4, 0xc1, 0x8e, 0x28, 0x4d, 0x96, 0x12, 0x7b, 0x5f, 0xbc, 0x39, 0xe7, 0xa3, 0x0a, 0x65, 0xd0, 86 }, { 87 0x3f, 0xd1, 0x48, 0x7e, 0xf6, 0x2b, 0x83, 0xe4, 0xc9, 0x07, 0x12, 0xad, 0x6c, 0x90, 0xb5, 0x5a, 88 0xd0, 0x8e, 0xa7, 0x1b, 0x3a, 0xf4, 0x4d, 0x21, 0xb5, 0x68, 0x7c, 0xc6, 0x09, 0x53, 0xe2, 0x9f, 89 }, { 90 0xda, 0x70, 0x09, 0x9e, 0x36, 0x43, 0x6f, 0xa5, 0x21, 0x8d, 0x5c, 0xe7, 0xcb, 0xb4, 0xf2, 0x18, 91 0x1d, 0xa6, 0xd4, 0x09, 0x68, 0x9f, 0x83, 0x70, 0x4b, 0xf1, 0xe2, 0x3c, 0xb5, 0x5a, 0x2e, 0xc7, 92 }, { 93 0xd7, 0x8d, 0xbe, 0x53, 0x60, 0xf6, 0x09, 0x3a, 0x41, 0x72, 0x28, 0xc5, 0x1b, 0xac, 0xe4, 0x9f, 94 0x3a, 0xf6, 0x09, 0x60, 0xac, 0x1b, 0xd7, 0x8d, 0x9f, 0x41, 0x53, 0xbe, 0xc5, 0x72, 0x28, 0xe4, 95 }, { 96 0xe2, 0xbc, 0x24, 0xc1, 0x47, 0x7a, 0xdb, 0x16, 0x58, 0x05, 0xf3, 0xaf, 0x3d, 0x90, 0x8e, 0x69, 97 0xb4, 0x82, 0xc1, 0x7b, 0x1a, 0xed, 0x27, 0xd8, 0x6f, 0xf9, 0x0c, 0x95, 0xa6, 0x43, 0x50, 0x3e, 98 }, { 99 0xac, 0xf1, 0x4a, 0x2f, 0x79, 0xc2, 0x96, 0x58, 0x60, 0x1d, 0xd3, 0xe4, 0x0e, 0xb7, 0x35, 0x8b, 100 0x49, 0x3e, 0x2f, 0xc5, 0x92, 0x58, 0xfc, 0xa3, 0xb7, 0xe0, 0x14, 0x7a, 0x61, 0x0d, 0x8b, 0xd6, 101 }, { 102 0xd4, 0x0b, 0xb2, 0x7e, 0x4f, 0x90, 0x18, 0xad, 0xe3, 0x3c, 0x59, 0xc7, 0x25, 0xfa, 0x86, 0x61, 103 0x61, 0xb4, 0xdb, 0x8d, 0x1c, 0x43, 0xa7, 0x7e, 0x9a, 0x5f, 0x06, 0xf8, 0xe0, 0x25, 0x39, 0xc2, 104 }, { 105 0x1d, 0xf2, 0xd8, 0x84, 0xa6, 0x3f, 0x7b, 0x41, 0xca, 0x59, 0x63, 0xbe, 0x05, 0xe0, 0x9c, 0x27, 106 0x27, 0x1b, 0xe4, 0x71, 0x49, 0xac, 0x8e, 0xd2, 0xf0, 0xc6, 0x9a, 0x0d, 0x3f, 0x53, 0x65, 0xb8, 107 } 108}; 109#else 110/** 111 * This table contains the results of applying both the S-box and P-shuffle. 112 * It can be regenerated by compiling this file with -DCONFIG_SMALL -DTEST -DGENTABLES 113 */ 114static const uint32_t S_boxes_P_shuffle[8][64] = { 115 { 116 0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000, 117 0x00000200, 0x00808200, 0x00808202, 0x00000200, 0x00800202, 0x00808002, 0x00800000, 0x00000002, 118 0x00000202, 0x00800200, 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202, 119 0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202, 0x00008202, 0x00800000, 120 0x00008000, 0x00808202, 0x00000002, 0x00808000, 0x00808200, 0x00800000, 0x00800000, 0x00000200, 121 0x00808002, 0x00008000, 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202, 122 0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202, 0x00008202, 0x00808200, 123 0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002, 124 }, 125 { 126 0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010, 127 0x40000010, 0x40084010, 0x40084000, 0x40000000, 0x40004000, 0x00080000, 0x00000010, 0x40080010, 128 0x00084000, 0x00080010, 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000, 129 0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000, 0x40080000, 0x00004010, 130 0x00000000, 0x00084010, 0x40080010, 0x00080000, 0x40004010, 0x40080000, 0x40084000, 0x00004000, 131 0x40080000, 0x40004000, 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000, 132 0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010, 0x40000010, 0x00080010, 133 0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000, 134 }, 135 { 136 0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100, 137 0x00010004, 0x04000004, 0x04000004, 0x00010000, 0x04010104, 0x00010004, 0x04010000, 0x00000104, 138 0x04000000, 0x00000004, 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104, 139 0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104, 0x00000100, 0x04000000, 140 0x04010100, 0x04000000, 0x00010004, 0x00000104, 0x00010000, 0x04010100, 0x04000100, 0x00000000, 141 0x00000100, 0x00010004, 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004, 142 0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104, 0x00010100, 0x04000004, 143 0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100, 144 }, 145 { 146 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000, 147 0x00000000, 0x00401000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00400040, 0x80400000, 148 0x80000000, 0x00001000, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040, 149 0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040, 0x80401040, 0x80000040, 150 0x00400040, 0x80400000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00000000, 0x00401000, 151 0x00001040, 0x00400040, 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040, 152 0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000, 0x00401040, 0x80400040, 153 0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040, 154 }, 155 { 156 0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000, 157 0x20040080, 0x00040000, 0x01000080, 0x20040080, 0x21000080, 0x21040000, 0x00040080, 0x20000000, 158 0x01000000, 0x20040000, 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080, 159 0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000, 0x21000000, 0x00040080, 160 0x00040000, 0x21000080, 0x00000080, 0x01000000, 0x20000000, 0x01040000, 0x21000080, 0x20040080, 161 0x01000080, 0x20000000, 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000, 162 0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000, 0x20040000, 0x21000000, 163 0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080, 164 }, 165 { 166 0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000, 167 0x10002000, 0x00202008, 0x00200000, 0x10000008, 0x00200008, 0x10002000, 0x10000000, 0x00002008, 168 0x00000000, 0x00200008, 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008, 169 0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000, 0x10202000, 0x10000000, 170 0x10002000, 0x00000008, 0x10200008, 0x00202000, 0x10202008, 0x00200000, 0x00002008, 0x10000008, 171 0x00200000, 0x10002000, 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000, 172 0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000, 0x10200000, 0x00202008, 173 0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008, 174 }, 175 { 176 0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400, 177 0x02100401, 0x00100000, 0x00000000, 0x02000001, 0x00000001, 0x02000000, 0x02100001, 0x00000401, 178 0x02000400, 0x00100401, 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001, 179 0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001, 0x02000000, 0x00100400, 180 0x02000000, 0x00100400, 0x00100000, 0x02000401, 0x02000401, 0x02100001, 0x02100001, 0x00000001, 181 0x00100001, 0x02000000, 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400, 182 0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000, 0x00000001, 0x02100401, 183 0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001, 184 }, 185 { 186 0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000, 187 0x00020020, 0x08020000, 0x08020820, 0x00020800, 0x08020800, 0x00020820, 0x00000800, 0x00000020, 188 0x08020000, 0x08000020, 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800, 189 0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800, 0x00020820, 0x00020000, 190 0x00020820, 0x00020000, 0x08020800, 0x00000800, 0x00000020, 0x08020020, 0x00000800, 0x00020820, 191 0x08000800, 0x00000020, 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820, 192 0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800, 0x08000820, 0x00000000, 193 0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800, 194 }, 195}; 196#endif 197 198static uint64_t shuffle(uint64_t in, const uint8_t *shuffle, int shuffle_len) { 199 int i; 200 uint64_t res = 0; 201 for (i = 0; i < shuffle_len; i++) 202 res += res + ((in >> *shuffle++) & 1); 203 return res; 204} 205 206static uint64_t shuffle_inv(uint64_t in, const uint8_t *shuffle, int shuffle_len) { 207 int i; 208 uint64_t res = 0; 209 shuffle += shuffle_len - 1; 210 for (i = 0; i < shuffle_len; i++) { 211 res |= (in & 1) << *shuffle--; 212 in >>= 1; 213 } 214 return res; 215} 216 217static uint32_t f_func(uint32_t r, uint64_t k) { 218 int i; 219 uint32_t out = 0; 220 // rotate to get first part of E-shuffle in the lowest 6 bits 221 r = (r << 1) | (r >> 31); 222 // apply S-boxes, those compress the data again from 8 * 6 to 8 * 4 bits 223 for (i = 7; i >= 0; i--) { 224 uint8_t tmp = (r ^ k) & 0x3f; 225#if CONFIG_SMALL 226 uint8_t v = S_boxes[i][tmp >> 1]; 227 if (tmp & 1) v >>= 4; 228 out = (out >> 4) | (v << 28); 229#else 230 out |= S_boxes_P_shuffle[i][tmp]; 231#endif 232 // get next 6 bits of E-shuffle and round key k into the lowest bits 233 r = (r >> 4) | (r << 28); 234 k >>= 6; 235 } 236#if CONFIG_SMALL 237 out = shuffle(out, P_shuffle, sizeof(P_shuffle)); 238#endif 239 return out; 240} 241 242/** 243 * \brief rotate the two halves of the expanded 56 bit key each 1 bit left 244 * 245 * Note: the specification calls this "shift", so I kept it although 246 * it is confusing. 247 */ 248static uint64_t key_shift_left(uint64_t CDn) { 249 uint64_t carries = (CDn >> 27) & 0x10000001; 250 CDn <<= 1; 251 CDn &= ~0x10000001; 252 CDn |= carries; 253 return CDn; 254} 255 256static void gen_roundkeys(uint64_t K[16], uint64_t key) { 257 int i; 258 // discard parity bits from key and shuffle it into C and D parts 259 uint64_t CDn = shuffle(key, PC1_shuffle, sizeof(PC1_shuffle)); 260 // generate round keys 261 for (i = 0; i < 16; i++) { 262 CDn = key_shift_left(CDn); 263 if (i > 1 && i != 8 && i != 15) 264 CDn = key_shift_left(CDn); 265 K[i] = shuffle(CDn, PC2_shuffle, sizeof(PC2_shuffle)); 266 } 267} 268 269static uint64_t des_encdec(uint64_t in, uint64_t K[16], int decrypt) { 270 int i; 271 // used to apply round keys in reverse order for decryption 272 decrypt = decrypt ? 15 : 0; 273 // shuffle irrelevant to security but to ease hardware implementations 274 in = shuffle(in, IP_shuffle, sizeof(IP_shuffle)); 275 for (i = 0; i < 16; i++) { 276 uint32_t f_res; 277 f_res = f_func(in, K[decrypt ^ i]); 278 in = (in << 32) | (in >> 32); 279 in ^= f_res; 280 } 281 in = (in << 32) | (in >> 32); 282 // reverse shuffle used to ease hardware implementations 283 in = shuffle_inv(in, IP_shuffle, sizeof(IP_shuffle)); 284 return in; 285} 286 287#if LIBAVUTIL_VERSION_MAJOR < 50 288uint64_t ff_des_encdec(uint64_t in, uint64_t key, int decrypt) { 289 uint64_t K[16]; 290 gen_roundkeys(K, key); 291 return des_encdec(in, K, decrypt); 292} 293#endif 294 295int av_des_init(AVDES *d, const uint8_t *key, int key_bits, int decrypt) { 296 if (key_bits != 64 && key_bits != 192) 297 return -1; 298 d->triple_des = key_bits > 64; 299 gen_roundkeys(d->round_keys[0], AV_RB64(key)); 300 if (d->triple_des) { 301 gen_roundkeys(d->round_keys[1], AV_RB64(key + 8)); 302 gen_roundkeys(d->round_keys[2], AV_RB64(key + 16)); 303 } 304 return 0; 305} 306 307void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) { 308 uint64_t iv_val = iv ? be2me_64(*(uint64_t *)iv) : 0; 309 while (count-- > 0) { 310 uint64_t dst_val; 311 uint64_t src_val = src ? be2me_64(*(const uint64_t *)src) : 0; 312 if (decrypt) { 313 uint64_t tmp = src_val; 314 if (d->triple_des) { 315 src_val = des_encdec(src_val, d->round_keys[2], 1); 316 src_val = des_encdec(src_val, d->round_keys[1], 0); 317 } 318 dst_val = des_encdec(src_val, d->round_keys[0], 1) ^ iv_val; 319 iv_val = iv ? tmp : 0; 320 } else { 321 dst_val = des_encdec(src_val ^ iv_val, d->round_keys[0], 0); 322 if (d->triple_des) { 323 dst_val = des_encdec(dst_val, d->round_keys[1], 1); 324 dst_val = des_encdec(dst_val, d->round_keys[2], 0); 325 } 326 iv_val = iv ? dst_val : 0; 327 } 328 *(uint64_t *)dst = be2me_64(dst_val); 329 src += 8; 330 dst += 8; 331 } 332 if (iv) 333 *(uint64_t *)iv = be2me_64(iv_val); 334} 335 336#ifdef TEST 337#undef printf 338#undef rand 339#undef srand 340#include <stdlib.h> 341#include <stdio.h> 342#include <sys/time.h> 343static uint64_t rand64(void) { 344 uint64_t r = rand(); 345 r = (r << 32) | rand(); 346 return r; 347} 348 349static const uint8_t test_key[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}; 350static const DECLARE_ALIGNED(8, uint8_t, plain[]) = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; 351static const DECLARE_ALIGNED(8, uint8_t, crypt[]) = {0x4a, 0xb6, 0x5b, 0x3d, 0x4b, 0x06, 0x15, 0x18}; 352static DECLARE_ALIGNED(8, uint8_t, tmp[8]); 353static DECLARE_ALIGNED(8, uint8_t, large_buffer[10002][8]); 354static const uint8_t cbc_key[] = { 355 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 356 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 357 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23 358}; 359 360int run_test(int cbc, int decrypt) { 361 AVDES d; 362 int delay = cbc && !decrypt ? 2 : 1; 363 uint64_t res; 364 AV_WB64(large_buffer[0], 0x4e6f772069732074ULL); 365 AV_WB64(large_buffer[1], 0x1234567890abcdefULL); 366 AV_WB64(tmp, 0x1234567890abcdefULL); 367 av_des_init(&d, cbc_key, 192, decrypt); 368 av_des_crypt(&d, large_buffer[delay], large_buffer[0], 10000, cbc ? tmp : NULL, decrypt); 369 res = AV_RB64(large_buffer[9999 + delay]); 370 if (cbc) { 371 if (decrypt) 372 return res == 0xc5cecf63ecec514cULL; 373 else 374 return res == 0xcb191f85d1ed8439ULL; 375 } else { 376 if (decrypt) 377 return res == 0x8325397644091a0aULL; 378 else 379 return res == 0xdd17e8b8b437d232ULL; 380 } 381} 382 383int main(void) { 384 AVDES d; 385 int i; 386#ifdef GENTABLES 387 int j; 388#endif 389 struct timeval tv; 390 uint64_t key[3]; 391 uint64_t data; 392 uint64_t ct; 393 gettimeofday(&tv, NULL); 394 srand(tv.tv_sec * 1000 * 1000 + tv.tv_usec); 395#if LIBAVUTIL_VERSION_MAJOR < 50 396 key[0] = AV_RB64(test_key); 397 data = AV_RB64(plain); 398 if (ff_des_encdec(data, key[0], 0) != AV_RB64(crypt)) { 399 printf("Test 1 failed\n"); 400 return 1; 401 } 402#endif 403 av_des_init(&d, test_key, 64, 0); 404 av_des_crypt(&d, tmp, plain, 1, NULL, 0); 405 if (memcmp(tmp, crypt, sizeof(crypt))) { 406 printf("Public API decryption failed\n"); 407 return 1; 408 } 409 if (!run_test(0, 0) || !run_test(0, 1) || !run_test(1, 0) || !run_test(1, 1)) { 410 printf("Partial Monte-Carlo test failed\n"); 411 return 1; 412 } 413 for (i = 0; i < 1000000; i++) { 414 key[0] = rand64(); key[1] = rand64(); key[2] = rand64(); 415 data = rand64(); 416 av_des_init(&d, key, 192, 0); 417 av_des_crypt(&d, &ct, &data, 1, NULL, 0); 418 av_des_init(&d, key, 192, 1); 419 av_des_crypt(&d, &ct, &ct, 1, NULL, 1); 420 if (ct != data) { 421 printf("Test 2 failed\n"); 422 return 1; 423 } 424 } 425#ifdef GENTABLES 426 printf("static const uint32_t S_boxes_P_shuffle[8][64] = {\n"); 427 for (i = 0; i < 8; i++) { 428 printf(" {"); 429 for (j = 0; j < 64; j++) { 430 uint32_t v = S_boxes[i][j >> 1]; 431 v = j & 1 ? v >> 4 : v & 0xf; 432 v <<= 28 - 4 * i; 433 v = shuffle(v, P_shuffle, sizeof(P_shuffle)); 434 printf((j & 7) == 0 ? "\n " : " "); 435 printf("0x%08X,", v); 436 } 437 printf("\n },\n"); 438 } 439 printf("};\n"); 440#endif 441 return 0; 442} 443#endif 444