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