Libav 0.7.1
|
00001 /* 00002 * DES encryption/decryption 00003 * Copyright (c) 2007 Reimar Doeffinger 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 // rotate to get first part of E-shuffle in the lowest 6 bits 00221 r = (r << 1) | (r >> 31); 00222 // apply S-boxes, those compress the data again from 8 * 6 to 8 * 4 bits 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 // get next 6 bits of E-shuffle and round key k into the lowest bits 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 // discard parity bits from key and shuffle it into C and D parts 00259 uint64_t CDn = shuffle(key, PC1_shuffle, sizeof(PC1_shuffle)); 00260 // generate round keys 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 // used to apply round keys in reverse order for decryption 00272 decrypt = decrypt ? 15 : 0; 00273 // shuffle irrelevant to security but to ease hardware implementations 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 // reverse shuffle used to ease hardware implementations 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