Botan  1.10.9
blowfish.cpp
Go to the documentation of this file.
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 */
16 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 */
51 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 */
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 
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 */
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 */
146 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 */
182  {
183  std::copy(P_INIT, P_INIT + 18, P.begin());
184  std::copy(S_INIT, S_INIT + 1024, S.begin());
185  }
186 
187 }
void eks_key_schedule(const byte key[], size_t key_length, const byte salt[16], size_t workfactor)
Definition: blowfish.cpp:111
void encrypt_n(const byte in[], byte out[], size_t blocks) const
Definition: blowfish.cpp:16
byte get_byte(size_t byte_num, T input)
Definition: get_byte.h:21
unsigned char byte
Definition: types.h:22
void decrypt_n(const byte in[], byte out[], size_t blocks) const
Definition: blowfish.cpp:51
size_t size() const
Definition: secmem.h:29
u32bit load_be< u32bit >(const byte in[], size_t off)
Definition: loadstor.h:166
void store_be(u16bit in, byte out[2])
Definition: loadstor.h:412
BigInt r
Definition: numthry.cpp:26
u32bit make_u32bit(byte i0, byte i1, byte i2, byte i3)
Definition: loadstor.h:60
unsigned int u32bit
Definition: types.h:32