FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
des.c
Go to the documentation of this file.
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 
27 typedef 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
30 static 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 #if CONFIG_SMALL || defined(GENTABLES)
43 #define T(a, b, c, d) 32-a,32-b,32-c,32-d
44 static 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
55 #endif
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
58 static 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
71 static 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 
83 #if CONFIG_SMALL
84 static 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  */
116 static 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 
200 static 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 
208 static 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 
219 static 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;
227 #if CONFIG_SMALL
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  }
238 #if CONFIG_SMALL
239  out = shuffle(out, P_shuffle, sizeof(P_shuffle));
240 #endif
241  return out;
242 }
243 
244 /**
245  * @brief rotate the two halves of the expanded 56 bit key each 1 bit left
246  *
247  * Note: the specification calls this "shift", so I kept it although
248  * it is confusing.
249  */
250 static 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 
258 static void gen_roundkeys(uint64_t K[16], uint64_t key) {
259  int i;
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  }
269 }
270 
271 static uint64_t des_encdec(uint64_t in, uint64_t K[16], int decrypt) {
272  int i;
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 
289 int av_des_init(AVDES *d, const uint8_t *key, int key_bits, av_unused int decrypt) {
290  if (key_bits != 64 && key_bits != 192)
291  return -1;
292  d->triple_des = key_bits > 64;
293  gen_roundkeys(d->round_keys[0], AV_RB64(key));
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  }
298  return 0;
299 }
300 
301 static void av_des_crypt_mac(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt, int mac) {
302  uint64_t iv_val = iv ? AV_RB64(iv) : 0;
303  while (count-- > 0) {
304  uint64_t dst_val;
305  uint64_t src_val = src ? AV_RB64(src) : 0;
306  if (decrypt) {
307  uint64_t tmp = src_val;
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  }
312  dst_val = des_encdec(src_val, d->round_keys[0], 1) ^ iv_val;
313  iv_val = iv ? tmp : 0;
314  } else {
315  dst_val = des_encdec(src_val ^ iv_val, d->round_keys[0], 0);
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  }
320  iv_val = iv ? dst_val : 0;
321  }
322  AV_WB64(dst, dst_val);
323  src += 8;
324  if (!mac)
325  dst += 8;
326  }
327  if (iv)
328  AV_WB64(iv, iv_val);
329 }
330 
331 void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) {
332  av_des_crypt_mac(d, dst, src, count, iv, decrypt, 0);
333 }
334 
335 void av_des_mac(AVDES *d, uint8_t *dst, const uint8_t *src, int count) {
336  av_des_crypt_mac(d, dst, src, count, (uint8_t[8]){0}, 0, 1);
337 }
338 
339 #ifdef TEST
340 #include <stdlib.h>
341 #include <stdio.h>
342 
343 #include "time.h"
344 
345 static uint64_t rand64(void) {
346  uint64_t r = rand();
347  r = (r << 32) | rand();
348  return r;
349 }
350 
351 static const uint8_t test_key[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
352 static const DECLARE_ALIGNED(8, uint8_t, plain)[] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
353 static const DECLARE_ALIGNED(8, uint8_t, crypt)[] = {0x4a, 0xb6, 0x5b, 0x3d, 0x4b, 0x06, 0x15, 0x18};
354 static DECLARE_ALIGNED(8, uint8_t, tmp)[8];
355 static DECLARE_ALIGNED(8, uint8_t, large_buffer)[10002][8];
356 static const uint8_t cbc_key[] = {
357  0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
358  0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
359  0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
360 };
361 
362 static int run_test(int cbc, int decrypt) {
363  AVDES d;
364  int delay = cbc && !decrypt ? 2 : 1;
365  uint64_t res;
366  AV_WB64(large_buffer[0], 0x4e6f772069732074ULL);
367  AV_WB64(large_buffer[1], 0x1234567890abcdefULL);
368  AV_WB64(tmp, 0x1234567890abcdefULL);
369  av_des_init(&d, cbc_key, 192, decrypt);
370  av_des_crypt(&d, large_buffer[delay], large_buffer[0], 10000, cbc ? tmp : NULL, decrypt);
371  res = AV_RB64(large_buffer[9999 + delay]);
372  if (cbc) {
373  if (decrypt)
374  return res == 0xc5cecf63ecec514cULL;
375  else
376  return res == 0xcb191f85d1ed8439ULL;
377  } else {
378  if (decrypt)
379  return res == 0x8325397644091a0aULL;
380  else
381  return res == 0xdd17e8b8b437d232ULL;
382  }
383 }
384 
385 int main(void) {
386  AVDES d;
387  int i;
388 #ifdef GENTABLES
389  int j;
390 #endif
391  uint64_t key[3];
392  uint64_t data;
393  uint64_t ct;
394  uint64_t roundkeys[16];
395  srand(av_gettime());
396  key[0] = AV_RB64(test_key);
397  data = AV_RB64(plain);
398  gen_roundkeys(roundkeys, key[0]);
399  if (des_encdec(data, roundkeys, 0) != AV_RB64(crypt)) {
400  printf("Test 1 failed\n");
401  return 1;
402  }
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 < 1000; i++) {
414  key[0] = rand64(); key[1] = rand64(); key[2] = rand64();
415  data = rand64();
416  av_des_init(&d, (uint8_t*)key, 192, 0);
417  av_des_crypt(&d, (uint8_t*)&ct, (uint8_t*)&data, 1, NULL, 0);
418  av_des_init(&d, (uint8_t*)key, 192, 1);
419  av_des_crypt(&d, (uint8_t*)&ct, (uint8_t*)&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