• 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 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 ? be2me_64(*(uint64_t *)iv) : 0;
00301     while (count-- > 0) {
00302         uint64_t dst_val;
00303         uint64_t src_val = src ? be2me_64(*(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 = be2me_64(dst_val);
00321         src += 8;
00322         dst += 8;
00323     }
00324     if (iv)
00325         *(uint64_t *)iv = be2me_64(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

Generated on Fri Sep 16 2011 17:17:51 for FFmpeg by  doxygen 1.7.1