Botan  1.11.15
src/lib/block/blowfish/blowfish.cpp
Go to the documentation of this file.
00001 /*
00002 * Blowfish
00003 * (C) 1999-2011 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/internal/block_utils.h>
00009 #include <botan/blowfish.h>
00010 
00011 namespace Botan {
00012 
00013 BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Blowfish);
00014 
00015 /*
00016 * Blowfish Encryption
00017 */
00018 void Blowfish::encrypt_n(const byte in[], byte out[], size_t blocks) const
00019    {
00020    const u32bit* S1 = &S[0];
00021    const u32bit* S2 = &S[256];
00022    const u32bit* S3 = &S[512];
00023    const u32bit* S4 = &S[768];
00024 
00025    for(size_t i = 0; i != blocks; ++i)
00026       {
00027       u32bit L = load_be<u32bit>(in, 0);
00028       u32bit R = load_be<u32bit>(in, 1);
00029 
00030       for(size_t j = 0; j != 16; j += 2)
00031          {
00032          L ^= P[j];
00033          R ^= ((S1[get_byte(0, L)]  + S2[get_byte(1, L)]) ^
00034                 S3[get_byte(2, L)]) + S4[get_byte(3, L)];
00035 
00036          R ^= P[j+1];
00037          L ^= ((S1[get_byte(0, R)]  + S2[get_byte(1, R)]) ^
00038                 S3[get_byte(2, R)]) + S4[get_byte(3, R)];
00039          }
00040 
00041       L ^= P[16]; R ^= P[17];
00042 
00043       store_be(out, R, L);
00044 
00045       in += BLOCK_SIZE;
00046       out += BLOCK_SIZE;
00047       }
00048    }
00049 
00050 /*
00051 * Blowfish Decryption
00052 */
00053 void Blowfish::decrypt_n(const byte in[], byte out[], size_t blocks) const
00054    {
00055    const u32bit* S1 = &S[0];
00056    const u32bit* S2 = &S[256];
00057    const u32bit* S3 = &S[512];
00058    const u32bit* S4 = &S[768];
00059 
00060    for(size_t i = 0; i != blocks; ++i)
00061       {
00062       u32bit L = load_be<u32bit>(in, 0);
00063       u32bit R = load_be<u32bit>(in, 1);
00064 
00065       for(size_t j = 17; j != 1; j -= 2)
00066          {
00067          L ^= P[j];
00068          R ^= ((S1[get_byte(0, L)]  + S2[get_byte(1, L)]) ^
00069                 S3[get_byte(2, L)]) + S4[get_byte(3, L)];
00070 
00071          R ^= P[j-1];
00072          L ^= ((S1[get_byte(0, R)]  + S2[get_byte(1, R)]) ^
00073                 S3[get_byte(2, R)]) + S4[get_byte(3, R)];
00074          }
00075 
00076       L ^= P[1]; R ^= P[0];
00077 
00078       store_be(out, R, L);
00079 
00080       in += BLOCK_SIZE;
00081       out += BLOCK_SIZE;
00082       }
00083    }
00084 
00085 /*
00086 * Blowfish Key Schedule
00087 */
00088 void Blowfish::key_schedule(const byte key[], size_t length)
00089    {
00090    P.resize(18);
00091    std::copy(P_INIT, P_INIT + 18, P.begin());
00092 
00093    S.resize(1024);
00094    std::copy(S_INIT, S_INIT + 1024, S.begin());
00095 
00096    const byte null_salt[16] = { 0 };
00097 
00098    key_expansion(key, length, null_salt);
00099    }
00100 
00101 void Blowfish::key_expansion(const byte key[],
00102                              size_t length,
00103                              const byte salt[16])
00104    {
00105    for(size_t i = 0, j = 0; i != 18; ++i, j += 4)
00106       P[i] ^= make_u32bit(key[(j  ) % length], key[(j+1) % length],
00107                           key[(j+2) % length], key[(j+3) % length]);
00108 
00109    u32bit L = 0, R = 0;
00110    generate_sbox(P, L, R, salt, 0);
00111    generate_sbox(S, L, R, salt, 2);
00112    }
00113 
00114 /*
00115 * Modified key schedule used for bcrypt password hashing
00116 */
00117 void Blowfish::eks_key_schedule(const byte key[], size_t length,
00118                                 const byte salt[16], size_t workfactor)
00119    {
00120    // Truncate longer passwords to the 56 byte limit Blowfish enforces
00121    length = std::min<size_t>(length, 55);
00122 
00123    if(workfactor == 0)
00124       throw std::invalid_argument("Bcrypt work factor must be at least 1");
00125 
00126    /*
00127    * On a 2.8 GHz Core-i7, workfactor == 18 takes about 25 seconds to
00128    * hash a password. This seems like a reasonable upper bound for the
00129    * time being.
00130    */
00131    if(workfactor > 18)
00132       throw std::invalid_argument("Requested Bcrypt work factor " +
00133                                   std::to_string(workfactor) + " too large");
00134 
00135    P.resize(18);
00136    std::copy(P_INIT, P_INIT + 18, P.begin());
00137 
00138    S.resize(1024);
00139    std::copy(S_INIT, S_INIT + 1024, S.begin());
00140 
00141    key_expansion(key, length, salt);
00142 
00143    const byte null_salt[16] = { 0 };
00144    const size_t rounds = static_cast<size_t>(1) << workfactor;
00145 
00146    for(size_t r = 0; r != rounds; ++r)
00147       {
00148       key_expansion(key, length, null_salt);
00149       key_expansion(salt, 16, null_salt);
00150       }
00151    }
00152 
00153 /*
00154 * Generate one of the Sboxes
00155 */
00156 void Blowfish::generate_sbox(secure_vector<u32bit>& box,
00157                              u32bit& L, u32bit& R,
00158                              const byte salt[16],
00159                              size_t salt_off) const
00160    {
00161    const u32bit* S1 = &S[0];
00162    const u32bit* S2 = &S[256];
00163    const u32bit* S3 = &S[512];
00164    const u32bit* S4 = &S[768];
00165 
00166    for(size_t i = 0; i != box.size(); i += 2)
00167       {
00168       L ^= load_be<u32bit>(salt, (i + salt_off) % 4);
00169       R ^= load_be<u32bit>(salt, (i + salt_off + 1) % 4);
00170 
00171       for(size_t j = 0; j != 16; j += 2)
00172          {
00173          L ^= P[j];
00174          R ^= ((S1[get_byte(0, L)]  + S2[get_byte(1, L)]) ^
00175                 S3[get_byte(2, L)]) + S4[get_byte(3, L)];
00176 
00177          R ^= P[j+1];
00178          L ^= ((S1[get_byte(0, R)]  + S2[get_byte(1, R)]) ^
00179                 S3[get_byte(2, R)]) + S4[get_byte(3, R)];
00180          }
00181 
00182       u32bit T = R; R = L ^ P[16]; L = T ^ P[17];
00183       box[i] = L;
00184       box[i+1] = R;
00185       }
00186    }
00187 
00188 /*
00189 * Clear memory of sensitive data
00190 */
00191 void Blowfish::clear()
00192    {
00193    zap(P);
00194    zap(S);
00195    }
00196 
00197 }