Botan  1.11.15
src/lib/block/des/des.cpp
Go to the documentation of this file.
00001 /*
00002 * DES
00003 * (C) 1999-2008 Jack Lloyd
00004 *
00005 * Based on a public domain implemenation by Phil Karn (who in turn
00006 * credited Richard Outerbridge and Jim Gillogly)
00007 *
00008 * Botan is released under the Simplified BSD License (see license.txt)
00009 */
00010 
00011 #include <botan/internal/block_utils.h>
00012 #include <botan/des.h>
00013 
00014 namespace Botan {
00015 
00016 BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(DES);
00017 BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(TripleDES);
00018 
00019 namespace {
00020 
00021 /*
00022 * DES Key Schedule
00023 */
00024 void des_key_schedule(u32bit round_key[32], const byte key[8])
00025    {
00026    static const byte ROT[16] = { 1, 1, 2, 2, 2, 2, 2, 2,
00027                                  1, 2, 2, 2, 2, 2, 2, 1 };
00028 
00029    u32bit C = ((key[7] & 0x80) << 20) | ((key[6] & 0x80) << 19) |
00030               ((key[5] & 0x80) << 18) | ((key[4] & 0x80) << 17) |
00031               ((key[3] & 0x80) << 16) | ((key[2] & 0x80) << 15) |
00032               ((key[1] & 0x80) << 14) | ((key[0] & 0x80) << 13) |
00033               ((key[7] & 0x40) << 13) | ((key[6] & 0x40) << 12) |
00034               ((key[5] & 0x40) << 11) | ((key[4] & 0x40) << 10) |
00035               ((key[3] & 0x40) <<  9) | ((key[2] & 0x40) <<  8) |
00036               ((key[1] & 0x40) <<  7) | ((key[0] & 0x40) <<  6) |
00037               ((key[7] & 0x20) <<  6) | ((key[6] & 0x20) <<  5) |
00038               ((key[5] & 0x20) <<  4) | ((key[4] & 0x20) <<  3) |
00039               ((key[3] & 0x20) <<  2) | ((key[2] & 0x20) <<  1) |
00040               ((key[1] & 0x20)      ) | ((key[0] & 0x20) >>  1) |
00041               ((key[7] & 0x10) >>  1) | ((key[6] & 0x10) >>  2) |
00042               ((key[5] & 0x10) >>  3) | ((key[4] & 0x10) >>  4);
00043    u32bit D = ((key[7] & 0x02) << 26) | ((key[6] & 0x02) << 25) |
00044               ((key[5] & 0x02) << 24) | ((key[4] & 0x02) << 23) |
00045               ((key[3] & 0x02) << 22) | ((key[2] & 0x02) << 21) |
00046               ((key[1] & 0x02) << 20) | ((key[0] & 0x02) << 19) |
00047               ((key[7] & 0x04) << 17) | ((key[6] & 0x04) << 16) |
00048               ((key[5] & 0x04) << 15) | ((key[4] & 0x04) << 14) |
00049               ((key[3] & 0x04) << 13) | ((key[2] & 0x04) << 12) |
00050               ((key[1] & 0x04) << 11) | ((key[0] & 0x04) << 10) |
00051               ((key[7] & 0x08) <<  8) | ((key[6] & 0x08) <<  7) |
00052               ((key[5] & 0x08) <<  6) | ((key[4] & 0x08) <<  5) |
00053               ((key[3] & 0x08) <<  4) | ((key[2] & 0x08) <<  3) |
00054               ((key[1] & 0x08) <<  2) | ((key[0] & 0x08) <<  1) |
00055               ((key[3] & 0x10) >>  1) | ((key[2] & 0x10) >>  2) |
00056               ((key[1] & 0x10) >>  3) | ((key[0] & 0x10) >>  4);
00057 
00058    for(size_t i = 0; i != 16; ++i)
00059       {
00060       C = ((C << ROT[i]) | (C >> (28-ROT[i]))) & 0x0FFFFFFF;
00061       D = ((D << ROT[i]) | (D >> (28-ROT[i]))) & 0x0FFFFFFF;
00062       round_key[2*i  ] = ((C & 0x00000010) << 22) | ((C & 0x00000800) << 17) |
00063                          ((C & 0x00000020) << 16) | ((C & 0x00004004) << 15) |
00064                          ((C & 0x00000200) << 11) | ((C & 0x00020000) << 10) |
00065                          ((C & 0x01000000) >>  6) | ((C & 0x00100000) >>  4) |
00066                          ((C & 0x00010000) <<  3) | ((C & 0x08000000) >>  2) |
00067                          ((C & 0x00800000) <<  1) | ((D & 0x00000010) <<  8) |
00068                          ((D & 0x00000002) <<  7) | ((D & 0x00000001) <<  2) |
00069                          ((D & 0x00000200)      ) | ((D & 0x00008000) >>  2) |
00070                          ((D & 0x00000088) >>  3) | ((D & 0x00001000) >>  7) |
00071                          ((D & 0x00080000) >>  9) | ((D & 0x02020000) >> 14) |
00072                          ((D & 0x00400000) >> 21);
00073       round_key[2*i+1] = ((C & 0x00000001) << 28) | ((C & 0x00000082) << 18) |
00074                          ((C & 0x00002000) << 14) | ((C & 0x00000100) << 10) |
00075                          ((C & 0x00001000) <<  9) | ((C & 0x00040000) <<  6) |
00076                          ((C & 0x02400000) <<  4) | ((C & 0x00008000) <<  2) |
00077                          ((C & 0x00200000) >>  1) | ((C & 0x04000000) >> 10) |
00078                          ((D & 0x00000020) <<  6) | ((D & 0x00000100)      ) |
00079                          ((D & 0x00000800) >>  1) | ((D & 0x00000040) >>  3) |
00080                          ((D & 0x00010000) >>  4) | ((D & 0x00000400) >>  5) |
00081                          ((D & 0x00004000) >> 10) | ((D & 0x04000000) >> 13) |
00082                          ((D & 0x00800000) >> 14) | ((D & 0x00100000) >> 18) |
00083                          ((D & 0x01000000) >> 24) | ((D & 0x08000000) >> 26);
00084       }
00085    }
00086 
00087 /*
00088 * DES Encryption
00089 */
00090 void des_encrypt(u32bit& L, u32bit& R,
00091                  const u32bit round_key[32])
00092    {
00093    for(size_t i = 0; i != 16; i += 2)
00094       {
00095       u32bit T0, T1;
00096 
00097       T0 = rotate_right(R, 4) ^ round_key[2*i];
00098       T1 =              R     ^ round_key[2*i + 1];
00099 
00100       L ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
00101            DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
00102            DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
00103            DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
00104 
00105       T0 = rotate_right(L, 4) ^ round_key[2*i + 2];
00106       T1 =              L     ^ round_key[2*i + 3];
00107 
00108       R ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
00109            DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
00110            DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
00111            DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
00112       }
00113    }
00114 
00115 /*
00116 * DES Decryption
00117 */
00118 void des_decrypt(u32bit& L, u32bit& R,
00119                  const u32bit round_key[32])
00120    {
00121    for(size_t i = 16; i != 0; i -= 2)
00122       {
00123       u32bit T0, T1;
00124 
00125       T0 = rotate_right(R, 4) ^ round_key[2*i - 2];
00126       T1 =              R     ^ round_key[2*i - 1];
00127 
00128       L ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
00129            DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
00130            DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
00131            DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
00132 
00133       T0 = rotate_right(L, 4) ^ round_key[2*i - 4];
00134       T1 =              L     ^ round_key[2*i - 3];
00135 
00136       R ^= DES_SPBOX1[get_byte(0, T0)] ^ DES_SPBOX2[get_byte(0, T1)] ^
00137            DES_SPBOX3[get_byte(1, T0)] ^ DES_SPBOX4[get_byte(1, T1)] ^
00138            DES_SPBOX5[get_byte(2, T0)] ^ DES_SPBOX6[get_byte(2, T1)] ^
00139            DES_SPBOX7[get_byte(3, T0)] ^ DES_SPBOX8[get_byte(3, T1)];
00140       }
00141    }
00142 
00143 }
00144 
00145 /*
00146 * DES Encryption
00147 */
00148 void DES::encrypt_n(const byte in[], byte out[], size_t blocks) const
00149    {
00150    for(size_t i = 0; i != blocks; ++i)
00151       {
00152       u64bit T = (DES_IPTAB1[in[0]]     ) | (DES_IPTAB1[in[1]] << 1) |
00153                  (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
00154                  (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
00155                  (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]]     );
00156 
00157       u32bit L = static_cast<u32bit>(T >> 32);
00158       u32bit R = static_cast<u32bit>(T);
00159 
00160       des_encrypt(L, R, &round_key[0]);
00161 
00162       T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
00163           (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
00164           (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
00165           (DES_FPTAB1[get_byte(2, R)]     ) | (DES_FPTAB2[get_byte(3, R)]     );
00166       T = rotate_left(T, 32);
00167 
00168       store_be(T, out);
00169 
00170       in += BLOCK_SIZE;
00171       out += BLOCK_SIZE;
00172       }
00173    }
00174 
00175 /*
00176 * DES Decryption
00177 */
00178 void DES::decrypt_n(const byte in[], byte out[], size_t blocks) const
00179    {
00180    for(size_t i = 0; i != blocks; ++i)
00181       {
00182       u64bit T = (DES_IPTAB1[in[0]]     ) | (DES_IPTAB1[in[1]] << 1) |
00183                  (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
00184                  (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
00185                  (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]]     );
00186 
00187       u32bit L = static_cast<u32bit>(T >> 32);
00188       u32bit R = static_cast<u32bit>(T);
00189 
00190       des_decrypt(L, R, &round_key[0]);
00191 
00192       T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
00193           (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
00194           (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
00195           (DES_FPTAB1[get_byte(2, R)]     ) | (DES_FPTAB2[get_byte(3, R)]     );
00196 
00197       T = rotate_left(T, 32);
00198 
00199       store_be(T, out);
00200 
00201       in += BLOCK_SIZE;
00202       out += BLOCK_SIZE;
00203       }
00204    }
00205 
00206 /*
00207 * DES Key Schedule
00208 */
00209 void DES::key_schedule(const byte key[], size_t)
00210    {
00211    round_key.resize(32);
00212    des_key_schedule(&round_key[0], key);
00213    }
00214 
00215 void DES::clear()
00216    {
00217    zap(round_key);
00218    }
00219 
00220 /*
00221 * TripleDES Encryption
00222 */
00223 void TripleDES::encrypt_n(const byte in[], byte out[], size_t blocks) const
00224    {
00225    for(size_t i = 0; i != blocks; ++i)
00226       {
00227       u64bit T = (DES_IPTAB1[in[0]]     ) | (DES_IPTAB1[in[1]] << 1) |
00228                  (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
00229                  (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
00230                  (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]]     );
00231 
00232       u32bit L = static_cast<u32bit>(T >> 32);
00233       u32bit R = static_cast<u32bit>(T);
00234 
00235       des_encrypt(L, R, &round_key[0]);
00236       des_decrypt(R, L, &round_key[32]);
00237       des_encrypt(L, R, &round_key[64]);
00238 
00239       T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
00240           (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
00241           (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
00242           (DES_FPTAB1[get_byte(2, R)]     ) | (DES_FPTAB2[get_byte(3, R)]     );
00243 
00244       T = rotate_left(T, 32);
00245 
00246       store_be(T, out);
00247 
00248       in += BLOCK_SIZE;
00249       out += BLOCK_SIZE;
00250       }
00251    }
00252 
00253 /*
00254 * TripleDES Decryption
00255 */
00256 void TripleDES::decrypt_n(const byte in[], byte out[], size_t blocks) const
00257    {
00258    for(size_t i = 0; i != blocks; ++i)
00259       {
00260       u64bit T = (DES_IPTAB1[in[0]]     ) | (DES_IPTAB1[in[1]] << 1) |
00261                  (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
00262                  (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
00263                  (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]]     );
00264 
00265       u32bit L = static_cast<u32bit>(T >> 32);
00266       u32bit R = static_cast<u32bit>(T);
00267 
00268       des_decrypt(L, R, &round_key[64]);
00269       des_encrypt(R, L, &round_key[32]);
00270       des_decrypt(L, R, &round_key[0]);
00271 
00272       T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
00273           (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
00274           (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
00275           (DES_FPTAB1[get_byte(2, R)]     ) | (DES_FPTAB2[get_byte(3, R)]     );
00276 
00277       T = rotate_left(T, 32);
00278 
00279       store_be(T, out);
00280 
00281       in += BLOCK_SIZE;
00282       out += BLOCK_SIZE;
00283       }
00284    }
00285 
00286 /*
00287 * TripleDES Key Schedule
00288 */
00289 void TripleDES::key_schedule(const byte key[], size_t length)
00290    {
00291    round_key.resize(3*32);
00292    des_key_schedule(&round_key[0], key);
00293    des_key_schedule(&round_key[32], key + 8);
00294 
00295    if(length == 24)
00296       des_key_schedule(&round_key[64], key + 16);
00297    else
00298       copy_mem(&round_key[64], &round_key[0], 32);
00299    }
00300 
00301 void TripleDES::clear()
00302    {
00303    zap(round_key);
00304    }
00305 
00306 }