• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavutil/des.c

Go to the documentation of this file.
00001 /*
00002  * DES encryption/decryption
00003  * Copyright (c) 2007 Reimar Doeffinger
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg 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  * FFmpeg 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 FFmpeg; 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 #if LIBAVUTIL_VERSION_MAJOR < 50
00288 uint64_t ff_des_encdec(uint64_t in, uint64_t key, int decrypt) {
00289     uint64_t K[16];
00290     gen_roundkeys(K, key);
00291     return des_encdec(in, K, decrypt);
00292 }
00293 #endif
00294 
00295 int av_des_init(AVDES *d, const uint8_t *key, int key_bits, int decrypt) {
00296     if (key_bits != 64 && key_bits != 192)
00297         return -1;
00298     d->triple_des = key_bits > 64;
00299     gen_roundkeys(d->round_keys[0], AV_RB64(key));
00300     if (d->triple_des) {
00301         gen_roundkeys(d->round_keys[1], AV_RB64(key +  8));
00302         gen_roundkeys(d->round_keys[2], AV_RB64(key + 16));
00303     }
00304     return 0;
00305 }
00306 
00307 void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) {
00308     uint64_t iv_val = iv ? be2me_64(*(uint64_t *)iv) : 0;
00309     while (count-- > 0) {
00310         uint64_t dst_val;
00311         uint64_t src_val = src ? be2me_64(*(const uint64_t *)src) : 0;
00312         if (decrypt) {
00313             uint64_t tmp = src_val;
00314             if (d->triple_des) {
00315                 src_val = des_encdec(src_val, d->round_keys[2], 1);
00316                 src_val = des_encdec(src_val, d->round_keys[1], 0);
00317             }
00318             dst_val = des_encdec(src_val, d->round_keys[0], 1) ^ iv_val;
00319             iv_val = iv ? tmp : 0;
00320         } else {
00321             dst_val = des_encdec(src_val ^ iv_val, d->round_keys[0], 0);
00322             if (d->triple_des) {
00323                 dst_val = des_encdec(dst_val, d->round_keys[1], 1);
00324                 dst_val = des_encdec(dst_val, d->round_keys[2], 0);
00325             }
00326             iv_val = iv ? dst_val : 0;
00327         }
00328         *(uint64_t *)dst = be2me_64(dst_val);
00329         src += 8;
00330         dst += 8;
00331     }
00332     if (iv)
00333         *(uint64_t *)iv = be2me_64(iv_val);
00334 }
00335 
00336 #ifdef TEST
00337 #undef printf
00338 #undef rand
00339 #undef srand
00340 #include <stdlib.h>
00341 #include <stdio.h>
00342 #include <sys/time.h>
00343 static uint64_t rand64(void) {
00344     uint64_t r = rand();
00345     r = (r << 32) | rand();
00346     return r;
00347 }
00348 
00349 static const uint8_t test_key[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
00350 static const DECLARE_ALIGNED(8, uint8_t, plain[]) = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
00351 static const DECLARE_ALIGNED(8, uint8_t, crypt[]) = {0x4a, 0xb6, 0x5b, 0x3d, 0x4b, 0x06, 0x15, 0x18};
00352 static DECLARE_ALIGNED(8, uint8_t, tmp[8]);
00353 static DECLARE_ALIGNED(8, uint8_t, large_buffer[10002][8]);
00354 static const uint8_t cbc_key[] = {
00355     0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
00356     0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
00357     0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
00358 };
00359 
00360 int run_test(int cbc, int decrypt) {
00361     AVDES d;
00362     int delay = cbc && !decrypt ? 2 : 1;
00363     uint64_t res;
00364     AV_WB64(large_buffer[0], 0x4e6f772069732074ULL);
00365     AV_WB64(large_buffer[1], 0x1234567890abcdefULL);
00366     AV_WB64(tmp,             0x1234567890abcdefULL);
00367     av_des_init(&d, cbc_key, 192, decrypt);
00368     av_des_crypt(&d, large_buffer[delay], large_buffer[0], 10000, cbc ? tmp : NULL, decrypt);
00369     res = AV_RB64(large_buffer[9999 + delay]);
00370     if (cbc) {
00371         if (decrypt)
00372             return res == 0xc5cecf63ecec514cULL;
00373         else
00374             return res == 0xcb191f85d1ed8439ULL;
00375     } else {
00376         if (decrypt)
00377             return res == 0x8325397644091a0aULL;
00378         else
00379             return res == 0xdd17e8b8b437d232ULL;
00380     }
00381 }
00382 
00383 int main(void) {
00384     AVDES d;
00385     int i;
00386 #ifdef GENTABLES
00387     int j;
00388 #endif
00389     struct timeval tv;
00390     uint64_t key[3];
00391     uint64_t data;
00392     uint64_t ct;
00393     gettimeofday(&tv, NULL);
00394     srand(tv.tv_sec * 1000 * 1000 + tv.tv_usec);
00395 #if LIBAVUTIL_VERSION_MAJOR < 50
00396     key[0] = AV_RB64(test_key);
00397     data = AV_RB64(plain);
00398     if (ff_des_encdec(data, key[0], 0) != AV_RB64(crypt)) {
00399         printf("Test 1 failed\n");
00400         return 1;
00401     }
00402 #endif
00403     av_des_init(&d, test_key, 64, 0);
00404     av_des_crypt(&d, tmp, plain, 1, NULL, 0);
00405     if (memcmp(tmp, crypt, sizeof(crypt))) {
00406         printf("Public API decryption failed\n");
00407         return 1;
00408     }
00409     if (!run_test(0, 0) || !run_test(0, 1) || !run_test(1, 0) || !run_test(1, 1)) {
00410         printf("Partial Monte-Carlo test failed\n");
00411         return 1;
00412     }
00413     for (i = 0; i < 1000000; i++) {
00414         key[0] = rand64(); key[1] = rand64(); key[2] = rand64();
00415         data = rand64();
00416         av_des_init(&d, key, 192, 0);
00417         av_des_crypt(&d, &ct, &data, 1, NULL, 0);
00418         av_des_init(&d, key, 192, 1);
00419         av_des_crypt(&d, &ct, &ct, 1, NULL, 1);
00420         if (ct != data) {
00421             printf("Test 2 failed\n");
00422             return 1;
00423         }
00424     }
00425 #ifdef GENTABLES
00426     printf("static const uint32_t S_boxes_P_shuffle[8][64] = {\n");
00427     for (i = 0; i < 8; i++) {
00428         printf("    {");
00429         for (j = 0; j < 64; j++) {
00430             uint32_t v = S_boxes[i][j >> 1];
00431             v = j & 1 ? v >> 4 : v & 0xf;
00432             v <<= 28 - 4 * i;
00433             v = shuffle(v, P_shuffle, sizeof(P_shuffle));
00434             printf((j & 7) == 0 ? "\n    " : " ");
00435             printf("0x%08X,", v);
00436         }
00437         printf("\n    },\n");
00438     }
00439     printf("};\n");
00440 #endif
00441     return 0;
00442 }
00443 #endif

Generated on Tue Nov 4 2014 12:59:24 for ffmpeg by  doxygen 1.7.1