1 /*
2 * Blowfish
3 * (C) 1999-2011 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/blowfish.h>
9 #include <botan/loadstor.h>
10 
11 namespace Botan {
12 
13 /*
14 * Blowfish Encryption
15 */
encrypt_n(const byte in[],byte out[],size_t blocks) const16 void Blowfish::encrypt_n(const byte in[], byte out[], size_t blocks) const
17    {
18    const u32bit* S1 = &S[0];
19    const u32bit* S2 = &S[256];
20    const u32bit* S3 = &S[512];
21    const u32bit* S4 = &S[768];
22 
23    for(size_t i = 0; i != blocks; ++i)
24       {
25       u32bit L = load_be<u32bit>(in, 0);
26       u32bit R = load_be<u32bit>(in, 1);
27 
28       for(size_t j = 0; j != 16; j += 2)
29          {
30          L ^= P[j];
31          R ^= ((S1[get_byte(0, L)]  + S2[get_byte(1, L)]) ^
32                 S3[get_byte(2, L)]) + S4[get_byte(3, L)];
33 
34          R ^= P[j+1];
35          L ^= ((S1[get_byte(0, R)]  + S2[get_byte(1, R)]) ^
36                 S3[get_byte(2, R)]) + S4[get_byte(3, R)];
37          }
38 
39       L ^= P[16]; R ^= P[17];
40 
41       store_be(out, R, L);
42 
43       in += BLOCK_SIZE;
44       out += BLOCK_SIZE;
45       }
46    }
47 
48 /*
49 * Blowfish Decryption
50 */
decrypt_n(const byte in[],byte out[],size_t blocks) const51 void Blowfish::decrypt_n(const byte in[], byte out[], size_t blocks) const
52    {
53    const u32bit* S1 = &S[0];
54    const u32bit* S2 = &S[256];
55    const u32bit* S3 = &S[512];
56    const u32bit* S4 = &S[768];
57 
58    for(size_t i = 0; i != blocks; ++i)
59       {
60       u32bit L = load_be<u32bit>(in, 0);
61       u32bit R = load_be<u32bit>(in, 1);
62 
63       for(size_t j = 17; j != 1; j -= 2)
64          {
65          L ^= P[j];
66          R ^= ((S1[get_byte(0, L)]  + S2[get_byte(1, L)]) ^
67                 S3[get_byte(2, L)]) + S4[get_byte(3, L)];
68 
69          R ^= P[j-1];
70          L ^= ((S1[get_byte(0, R)]  + S2[get_byte(1, R)]) ^
71                 S3[get_byte(2, R)]) + S4[get_byte(3, R)];
72          }
73 
74       L ^= P[1]; R ^= P[0];
75 
76       store_be(out, R, L);
77 
78       in += BLOCK_SIZE;
79       out += BLOCK_SIZE;
80       }
81    }
82 
83 /*
84 * Blowfish Key Schedule
85 */
key_schedule(const byte key[],size_t length)86 void Blowfish::key_schedule(const byte key[], size_t length)
87    {
88    clear();
89 
90    const byte null_salt[16] = { 0 };
91 
92    key_expansion(key, length, null_salt);
93    }
94 
key_expansion(const byte key[],size_t length,const byte salt[16])95 void Blowfish::key_expansion(const byte key[],
96                              size_t length,
97                              const byte salt[16])
98    {
99    for(size_t i = 0, j = 0; i != 18; ++i, j += 4)
100       P[i] ^= make_u32bit(key[(j  ) % length], key[(j+1) % length],
101                           key[(j+2) % length], key[(j+3) % length]);
102 
103    u32bit L = 0, R = 0;
104    generate_sbox(P, L, R, salt, 0);
105    generate_sbox(S, L, R, salt, 2);
106    }
107 
108 /*
109 * Modified key schedule used for bcrypt password hashing
110 */
eks_key_schedule(const byte key[],size_t length,const byte salt[16],size_t workfactor)111 void Blowfish::eks_key_schedule(const byte key[], size_t length,
112                                 const byte salt[16], size_t workfactor)
113    {
114    if(length == 0 || length >= 56)
115       throw Invalid_Key_Length("EKSBlowfish", length);
116 
117    if(workfactor == 0)
118       throw std::invalid_argument("Bcrypt work factor must be at least 1");
119 
120    /*
121    * On a 2.8 GHz Core-i7, workfactor == 18 takes about 25 seconds to
122    * hash a password. This seems like a reasonable upper bound for the
123    * time being.
124    */
125    if(workfactor > 18)
126       throw std::invalid_argument("Requested Bcrypt work factor too large");
127 
128    clear();
129 
130    const byte null_salt[16] = { 0 };
131 
132    key_expansion(key, length, salt);
133 
134    const size_t rounds = 1 << workfactor;
135 
136    for(size_t r = 0; r != rounds; ++r)
137       {
138       key_expansion(key, length, null_salt);
139       key_expansion(salt, 16, null_salt);
140       }
141    }
142 
143 /*
144 * Generate one of the Sboxes
145 */
generate_sbox(MemoryRegion<u32bit> & box,u32bit & L,u32bit & R,const byte salt[16],size_t salt_off) const146 void Blowfish::generate_sbox(MemoryRegion<u32bit>& box,
147                              u32bit& L, u32bit& R,
148                              const byte salt[16],
149                              size_t salt_off) const
150    {
151    const u32bit* S1 = &S[0];
152    const u32bit* S2 = &S[256];
153    const u32bit* S3 = &S[512];
154    const u32bit* S4 = &S[768];
155 
156    for(size_t i = 0; i != box.size(); i += 2)
157       {
158       L ^= load_be<u32bit>(salt, (i + salt_off) % 4);
159       R ^= load_be<u32bit>(salt, (i + salt_off + 1) % 4);
160 
161       for(size_t j = 0; j != 16; j += 2)
162          {
163          L ^= P[j];
164          R ^= ((S1[get_byte(0, L)]  + S2[get_byte(1, L)]) ^
165                 S3[get_byte(2, L)]) + S4[get_byte(3, L)];
166 
167          R ^= P[j+1];
168          L ^= ((S1[get_byte(0, R)]  + S2[get_byte(1, R)]) ^
169                 S3[get_byte(2, R)]) + S4[get_byte(3, R)];
170          }
171 
172       u32bit T = R; R = L ^ P[16]; L = T ^ P[17];
173       box[i] = L;
174       box[i+1] = R;
175       }
176    }
177 
178 /*
179 * Clear memory of sensitive data
180 */
clear()181 void Blowfish::clear()
182    {
183    std::copy(P_INIT, P_INIT + 18, P.begin());
184    std::copy(S_INIT, S_INIT + 1024, S.begin());
185    }
186 
187 }
188