• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • 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 Libav.
00006  *
00007  * Libav 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  * Libav 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 Libav; 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 #if CONFIG_SMALL || defined(GENTABLES)
00043 #define T(a, b, c, d) 32-a,32-b,32-c,32-d
00044 static const uint8_t P_shuffle[] = {
00045     T(16,  7, 20, 21),
00046     T(29, 12, 28, 17),
00047     T( 1, 15, 23, 26),
00048     T( 5, 18, 31, 10),
00049     T( 2,  8, 24, 14),
00050     T(32, 27,  3,  9),
00051     T(19, 13, 30,  6),
00052     T(22, 11,  4, 25)
00053 };
00054 #undef T
00055 #endif
00056 
00057 #define T(a, b, c, d, e, f, g) 64-a,64-b,64-c,64-d,64-e,64-f,64-g
00058 static const uint8_t PC1_shuffle[] = {
00059     T(57, 49, 41, 33, 25, 17,  9),
00060     T( 1, 58, 50, 42, 34, 26, 18),
00061     T(10,  2, 59, 51, 43, 35, 27),
00062     T(19, 11,  3, 60, 52, 44, 36),
00063     T(63, 55, 47, 39, 31, 23, 15),
00064     T( 7, 62, 54, 46, 38, 30, 22),
00065     T(14,  6, 61, 53, 45, 37, 29),
00066     T(21, 13,  5, 28, 20, 12,  4)
00067 };
00068 #undef T
00069 
00070 #define T(a, b, c, d, e, f) 56-a,56-b,56-c,56-d,56-e,56-f
00071 static const uint8_t PC2_shuffle[] = {
00072     T(14, 17, 11, 24,  1,  5),
00073     T( 3, 28, 15,  6, 21, 10),
00074     T(23, 19, 12,  4, 26,  8),
00075     T(16,  7, 27, 20, 13,  2),
00076     T(41, 52, 31, 37, 47, 55),
00077     T(30, 40, 51, 45, 33, 48),
00078     T(44, 49, 39, 56, 34, 53),
00079     T(46, 42, 50, 36, 29, 32)
00080 };
00081 #undef T
00082 
00083 #if CONFIG_SMALL
00084 static const uint8_t S_boxes[8][32] = {
00085     {
00086     0x0e, 0xf4, 0x7d, 0x41, 0xe2, 0x2f, 0xdb, 0x18, 0xa3, 0x6a, 0xc6, 0xbc, 0x95, 0x59, 0x30, 0x87,
00087     0xf4, 0xc1, 0x8e, 0x28, 0x4d, 0x96, 0x12, 0x7b, 0x5f, 0xbc, 0x39, 0xe7, 0xa3, 0x0a, 0x65, 0xd0,
00088     }, {
00089     0x3f, 0xd1, 0x48, 0x7e, 0xf6, 0x2b, 0x83, 0xe4, 0xc9, 0x07, 0x12, 0xad, 0x6c, 0x90, 0xb5, 0x5a,
00090     0xd0, 0x8e, 0xa7, 0x1b, 0x3a, 0xf4, 0x4d, 0x21, 0xb5, 0x68, 0x7c, 0xc6, 0x09, 0x53, 0xe2, 0x9f,
00091     }, {
00092     0xda, 0x70, 0x09, 0x9e, 0x36, 0x43, 0x6f, 0xa5, 0x21, 0x8d, 0x5c, 0xe7, 0xcb, 0xb4, 0xf2, 0x18,
00093     0x1d, 0xa6, 0xd4, 0x09, 0x68, 0x9f, 0x83, 0x70, 0x4b, 0xf1, 0xe2, 0x3c, 0xb5, 0x5a, 0x2e, 0xc7,
00094     }, {
00095     0xd7, 0x8d, 0xbe, 0x53, 0x60, 0xf6, 0x09, 0x3a, 0x41, 0x72, 0x28, 0xc5, 0x1b, 0xac, 0xe4, 0x9f,
00096     0x3a, 0xf6, 0x09, 0x60, 0xac, 0x1b, 0xd7, 0x8d, 0x9f, 0x41, 0x53, 0xbe, 0xc5, 0x72, 0x28, 0xe4,
00097     }, {
00098     0xe2, 0xbc, 0x24, 0xc1, 0x47, 0x7a, 0xdb, 0x16, 0x58, 0x05, 0xf3, 0xaf, 0x3d, 0x90, 0x8e, 0x69,
00099     0xb4, 0x82, 0xc1, 0x7b, 0x1a, 0xed, 0x27, 0xd8, 0x6f, 0xf9, 0x0c, 0x95, 0xa6, 0x43, 0x50, 0x3e,
00100     }, {
00101     0xac, 0xf1, 0x4a, 0x2f, 0x79, 0xc2, 0x96, 0x58, 0x60, 0x1d, 0xd3, 0xe4, 0x0e, 0xb7, 0x35, 0x8b,
00102     0x49, 0x3e, 0x2f, 0xc5, 0x92, 0x58, 0xfc, 0xa3, 0xb7, 0xe0, 0x14, 0x7a, 0x61, 0x0d, 0x8b, 0xd6,
00103     }, {
00104     0xd4, 0x0b, 0xb2, 0x7e, 0x4f, 0x90, 0x18, 0xad, 0xe3, 0x3c, 0x59, 0xc7, 0x25, 0xfa, 0x86, 0x61,
00105     0x61, 0xb4, 0xdb, 0x8d, 0x1c, 0x43, 0xa7, 0x7e, 0x9a, 0x5f, 0x06, 0xf8, 0xe0, 0x25, 0x39, 0xc2,
00106     }, {
00107     0x1d, 0xf2, 0xd8, 0x84, 0xa6, 0x3f, 0x7b, 0x41, 0xca, 0x59, 0x63, 0xbe, 0x05, 0xe0, 0x9c, 0x27,
00108     0x27, 0x1b, 0xe4, 0x71, 0x49, 0xac, 0x8e, 0xd2, 0xf0, 0xc6, 0x9a, 0x0d, 0x3f, 0x53, 0x65, 0xb8,
00109     }
00110 };
00111 #else
00112 
00116 static const uint32_t S_boxes_P_shuffle[8][64] = {
00117     {
00118     0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000,
00119     0x00000200, 0x00808200, 0x00808202, 0x00000200, 0x00800202, 0x00808002, 0x00800000, 0x00000002,
00120     0x00000202, 0x00800200, 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202,
00121     0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202, 0x00008202, 0x00800000,
00122     0x00008000, 0x00808202, 0x00000002, 0x00808000, 0x00808200, 0x00800000, 0x00800000, 0x00000200,
00123     0x00808002, 0x00008000, 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202,
00124     0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202, 0x00008202, 0x00808200,
00125     0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002,
00126     },
00127     {
00128     0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010,
00129     0x40000010, 0x40084010, 0x40084000, 0x40000000, 0x40004000, 0x00080000, 0x00000010, 0x40080010,
00130     0x00084000, 0x00080010, 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000,
00131     0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000, 0x40080000, 0x00004010,
00132     0x00000000, 0x00084010, 0x40080010, 0x00080000, 0x40004010, 0x40080000, 0x40084000, 0x00004000,
00133     0x40080000, 0x40004000, 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000,
00134     0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010, 0x40000010, 0x00080010,
00135     0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000,
00136     },
00137     {
00138     0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100,
00139     0x00010004, 0x04000004, 0x04000004, 0x00010000, 0x04010104, 0x00010004, 0x04010000, 0x00000104,
00140     0x04000000, 0x00000004, 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104,
00141     0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104, 0x00000100, 0x04000000,
00142     0x04010100, 0x04000000, 0x00010004, 0x00000104, 0x00010000, 0x04010100, 0x04000100, 0x00000000,
00143     0x00000100, 0x00010004, 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004,
00144     0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104, 0x00010100, 0x04000004,
00145     0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100,
00146     },
00147     {
00148     0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000,
00149     0x00000000, 0x00401000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00400040, 0x80400000,
00150     0x80000000, 0x00001000, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040,
00151     0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040, 0x80401040, 0x80000040,
00152     0x00400040, 0x80400000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00000000, 0x00401000,
00153     0x00001040, 0x00400040, 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040,
00154     0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000, 0x00401040, 0x80400040,
00155     0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040,
00156     },
00157     {
00158     0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000,
00159     0x20040080, 0x00040000, 0x01000080, 0x20040080, 0x21000080, 0x21040000, 0x00040080, 0x20000000,
00160     0x01000000, 0x20040000, 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080,
00161     0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000, 0x21000000, 0x00040080,
00162     0x00040000, 0x21000080, 0x00000080, 0x01000000, 0x20000000, 0x01040000, 0x21000080, 0x20040080,
00163     0x01000080, 0x20000000, 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000,
00164     0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000, 0x20040000, 0x21000000,
00165     0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080,
00166     },
00167     {
00168     0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000,
00169     0x10002000, 0x00202008, 0x00200000, 0x10000008, 0x00200008, 0x10002000, 0x10000000, 0x00002008,
00170     0x00000000, 0x00200008, 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008,
00171     0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000, 0x10202000, 0x10000000,
00172     0x10002000, 0x00000008, 0x10200008, 0x00202000, 0x10202008, 0x00200000, 0x00002008, 0x10000008,
00173     0x00200000, 0x10002000, 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000,
00174     0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000, 0x10200000, 0x00202008,
00175     0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008,
00176     },
00177     {
00178     0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400,
00179     0x02100401, 0x00100000, 0x00000000, 0x02000001, 0x00000001, 0x02000000, 0x02100001, 0x00000401,
00180     0x02000400, 0x00100401, 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001,
00181     0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001, 0x02000000, 0x00100400,
00182     0x02000000, 0x00100400, 0x00100000, 0x02000401, 0x02000401, 0x02100001, 0x02100001, 0x00000001,
00183     0x00100001, 0x02000000, 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400,
00184     0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000, 0x00000001, 0x02100401,
00185     0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001,
00186     },
00187     {
00188     0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000,
00189     0x00020020, 0x08020000, 0x08020820, 0x00020800, 0x08020800, 0x00020820, 0x00000800, 0x00000020,
00190     0x08020000, 0x08000020, 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800,
00191     0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800, 0x00020820, 0x00020000,
00192     0x00020820, 0x00020000, 0x08020800, 0x00000800, 0x00000020, 0x08020020, 0x00000800, 0x00020820,
00193     0x08000800, 0x00000020, 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820,
00194     0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800, 0x08000820, 0x00000000,
00195     0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800,
00196     },
00197 };
00198 #endif
00199 
00200 static uint64_t shuffle(uint64_t in, const uint8_t *shuffle, int shuffle_len) {
00201     int i;
00202     uint64_t res = 0;
00203     for (i = 0; i < shuffle_len; i++)
00204         res += res + ((in >> *shuffle++) & 1);
00205     return res;
00206 }
00207 
00208 static uint64_t shuffle_inv(uint64_t in, const uint8_t *shuffle, int shuffle_len) {
00209     int i;
00210     uint64_t res = 0;
00211     shuffle += shuffle_len - 1;
00212     for (i = 0; i < shuffle_len; i++) {
00213         res |= (in & 1) << *shuffle--;
00214         in >>= 1;
00215     }
00216     return res;
00217 }
00218 
00219 static uint32_t f_func(uint32_t r, uint64_t k) {
00220     int i;
00221     uint32_t out = 0;
00222     // rotate to get first part of E-shuffle in the lowest 6 bits
00223     r = (r << 1) | (r >> 31);
00224     // apply S-boxes, those compress the data again from 8 * 6 to 8 * 4 bits
00225     for (i = 7; i >= 0; i--) {
00226         uint8_t tmp = (r ^ k) & 0x3f;
00227 #if CONFIG_SMALL
00228         uint8_t v = S_boxes[i][tmp >> 1];
00229         if (tmp & 1) v >>= 4;
00230         out = (out >> 4) | (v << 28);
00231 #else
00232         out |= S_boxes_P_shuffle[i][tmp];
00233 #endif
00234         // get next 6 bits of E-shuffle and round key k into the lowest bits
00235         r = (r >> 4) | (r << 28);
00236         k >>= 6;
00237     }
00238 #if CONFIG_SMALL
00239     out = shuffle(out, P_shuffle, sizeof(P_shuffle));
00240 #endif
00241     return out;
00242 }
00243 
00250 static uint64_t key_shift_left(uint64_t CDn) {
00251     uint64_t carries = (CDn >> 27) & 0x10000001;
00252     CDn <<= 1;
00253     CDn &= ~0x10000001;
00254     CDn |= carries;
00255     return CDn;
00256 }
00257 
00258 static void gen_roundkeys(uint64_t K[16], uint64_t key) {
00259     int i;
00260     // discard parity bits from key and shuffle it into C and D parts
00261     uint64_t CDn = shuffle(key, PC1_shuffle, sizeof(PC1_shuffle));
00262     // generate round keys
00263     for (i = 0; i < 16; i++) {
00264         CDn = key_shift_left(CDn);
00265         if (i > 1 && i != 8 && i != 15)
00266             CDn = key_shift_left(CDn);
00267         K[i] = shuffle(CDn, PC2_shuffle, sizeof(PC2_shuffle));
00268     }
00269 }
00270 
00271 static uint64_t des_encdec(uint64_t in, uint64_t K[16], int decrypt) {
00272     int i;
00273     // used to apply round keys in reverse order for decryption
00274     decrypt = decrypt ? 15 : 0;
00275     // shuffle irrelevant to security but to ease hardware implementations
00276     in = shuffle(in, IP_shuffle, sizeof(IP_shuffle));
00277     for (i = 0; i < 16; i++) {
00278         uint32_t f_res;
00279         f_res = f_func(in, K[decrypt ^ i]);
00280         in = (in << 32) | (in >> 32);
00281         in ^= f_res;
00282     }
00283     in = (in << 32) | (in >> 32);
00284     // reverse shuffle used to ease hardware implementations
00285     in = shuffle_inv(in, IP_shuffle, sizeof(IP_shuffle));
00286     return in;
00287 }
00288 
00289 int av_des_init(AVDES *d, const uint8_t *key, int key_bits, int decrypt) {
00290     if (key_bits != 64 && key_bits != 192)
00291         return -1;
00292     d->triple_des = key_bits > 64;
00293     gen_roundkeys(d->round_keys[0], AV_RB64(key));
00294     if (d->triple_des) {
00295         gen_roundkeys(d->round_keys[1], AV_RB64(key +  8));
00296         gen_roundkeys(d->round_keys[2], AV_RB64(key + 16));
00297     }
00298     return 0;
00299 }
00300 
00301 static void av_des_crypt_mac(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt, int mac) {
00302     uint64_t iv_val = iv ? AV_RB64(iv) : 0;
00303     while (count-- > 0) {
00304         uint64_t dst_val;
00305         uint64_t src_val = src ? AV_RB64(src) : 0;
00306         if (decrypt) {
00307             uint64_t tmp = src_val;
00308             if (d->triple_des) {
00309                 src_val = des_encdec(src_val, d->round_keys[2], 1);
00310                 src_val = des_encdec(src_val, d->round_keys[1], 0);
00311             }
00312             dst_val = des_encdec(src_val, d->round_keys[0], 1) ^ iv_val;
00313             iv_val = iv ? tmp : 0;
00314         } else {
00315             dst_val = des_encdec(src_val ^ iv_val, d->round_keys[0], 0);
00316             if (d->triple_des) {
00317                 dst_val = des_encdec(dst_val, d->round_keys[1], 1);
00318                 dst_val = des_encdec(dst_val, d->round_keys[2], 0);
00319             }
00320             iv_val = iv ? dst_val : 0;
00321         }
00322         AV_WB64(dst, dst_val);
00323         src += 8;
00324         if (!mac)
00325             dst += 8;
00326     }
00327     if (iv)
00328         AV_WB64(iv, iv_val);
00329 }
00330 
00331 void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) {
00332     av_des_crypt_mac(d, dst, src, count, iv, decrypt, 0);
00333 }
00334 
00335 void av_des_mac(AVDES *d, uint8_t *dst, const uint8_t *src, int count) {
00336     av_des_crypt_mac(d, dst, src, count, (uint8_t[8]){0}, 0, 1);
00337 }
00338 
00339 #ifdef TEST
00340 #undef printf
00341 #undef rand
00342 #undef srand
00343 #include <stdlib.h>
00344 #include <stdio.h>
00345 #include <sys/time.h>
00346 static uint64_t rand64(void) {
00347     uint64_t r = rand();
00348     r = (r << 32) | rand();
00349     return r;
00350 }
00351 
00352 static const uint8_t test_key[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
00353 static const DECLARE_ALIGNED(8, uint8_t, plain)[] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
00354 static const DECLARE_ALIGNED(8, uint8_t, crypt)[] = {0x4a, 0xb6, 0x5b, 0x3d, 0x4b, 0x06, 0x15, 0x18};
00355 static DECLARE_ALIGNED(8, uint8_t, tmp)[8];
00356 static DECLARE_ALIGNED(8, uint8_t, large_buffer)[10002][8];
00357 static const uint8_t cbc_key[] = {
00358     0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
00359     0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
00360     0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23
00361 };
00362 
00363 static int run_test(int cbc, int decrypt) {
00364     AVDES d;
00365     int delay = cbc && !decrypt ? 2 : 1;
00366     uint64_t res;
00367     AV_WB64(large_buffer[0], 0x4e6f772069732074ULL);
00368     AV_WB64(large_buffer[1], 0x1234567890abcdefULL);
00369     AV_WB64(tmp,             0x1234567890abcdefULL);
00370     av_des_init(&d, cbc_key, 192, decrypt);
00371     av_des_crypt(&d, large_buffer[delay], large_buffer[0], 10000, cbc ? tmp : NULL, decrypt);
00372     res = AV_RB64(large_buffer[9999 + delay]);
00373     if (cbc) {
00374         if (decrypt)
00375             return res == 0xc5cecf63ecec514cULL;
00376         else
00377             return res == 0xcb191f85d1ed8439ULL;
00378     } else {
00379         if (decrypt)
00380             return res == 0x8325397644091a0aULL;
00381         else
00382             return res == 0xdd17e8b8b437d232ULL;
00383     }
00384 }
00385 
00386 int main(void) {
00387     AVDES d;
00388     int i;
00389 #ifdef GENTABLES
00390     int j;
00391 #endif
00392     struct timeval tv;
00393     uint64_t key[3];
00394     uint64_t data;
00395     uint64_t ct;
00396     uint64_t roundkeys[16];
00397     gettimeofday(&tv, NULL);
00398     srand(tv.tv_sec * 1000 * 1000 + tv.tv_usec);
00399     key[0] = AV_RB64(test_key);
00400     data = AV_RB64(plain);
00401     gen_roundkeys(roundkeys, key[0]);
00402     if (des_encdec(data, roundkeys, 0) != AV_RB64(crypt)) {
00403         printf("Test 1 failed\n");
00404         return 1;
00405     }
00406     av_des_init(&d, test_key, 64, 0);
00407     av_des_crypt(&d, tmp, plain, 1, NULL, 0);
00408     if (memcmp(tmp, crypt, sizeof(crypt))) {
00409         printf("Public API decryption failed\n");
00410         return 1;
00411     }
00412     if (!run_test(0, 0) || !run_test(0, 1) || !run_test(1, 0) || !run_test(1, 1)) {
00413         printf("Partial Monte-Carlo test failed\n");
00414         return 1;
00415     }
00416     for (i = 0; i < 1000; i++) {
00417         key[0] = rand64(); key[1] = rand64(); key[2] = rand64();
00418         data = rand64();
00419         av_des_init(&d, key, 192, 0);
00420         av_des_crypt(&d, &ct, &data, 1, NULL, 0);
00421         av_des_init(&d, key, 192, 1);
00422         av_des_crypt(&d, &ct, &ct, 1, NULL, 1);
00423         if (ct != data) {
00424             printf("Test 2 failed\n");
00425             return 1;
00426         }
00427     }
00428 #ifdef GENTABLES
00429     printf("static const uint32_t S_boxes_P_shuffle[8][64] = {\n");
00430     for (i = 0; i < 8; i++) {
00431         printf("    {");
00432         for (j = 0; j < 64; j++) {
00433             uint32_t v = S_boxes[i][j >> 1];
00434             v = j & 1 ? v >> 4 : v & 0xf;
00435             v <<= 28 - 4 * i;
00436             v = shuffle(v, P_shuffle, sizeof(P_shuffle));
00437             printf((j & 7) == 0 ? "\n    " : " ");
00438             printf("0x%08X,", v);
00439         }
00440         printf("\n    },\n");
00441     }
00442     printf("};\n");
00443 #endif
00444     return 0;
00445 }
00446 #endif
Generated on Thu Jan 24 2013 17:08:56 for Libav by doxygen 1.7.1