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