cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
ctx_bf.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib Blowfish Encryption Routines *
4 * Copyright Peter Gutmann 1994-2005 *
5 * *
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9  #include "crypt.h"
10  #include "context.h"
11  #include "blowfish.h"
12 #else
13  #include "crypt.h"
14  #include "context/context.h"
15  #include "crypt/blowfish.h"
16 #endif /* Compiler-specific includes */
17 
18 #ifdef USE_BLOWFISH
19 
20 /* The size of the expanded Blowfish keys */
21 
22 #define BLOWFISH_EXPANDED_KEYSIZE sizeof( BF_KEY )
23 
24 /****************************************************************************
25 * *
26 * Blowfish Self-test Routines *
27 * *
28 ****************************************************************************/
29 
30 #ifndef CONFIG_NO_SELFTEST
31 
32 /* Test the Blowfish code against Bruce Schneiers test vectors (1 & 2) and
33  Mike Morgans test vector (3) */
34 
35 static int selfTest( void )
36  {
37  const CAPABILITY_INFO *capabilityInfo = getBlowfishCapability();
38  BYTE keyData[ BLOWFISH_EXPANDED_KEYSIZE + 8 ];
39  BYTE *plain1 = ( BYTE * ) "BLOWFISH";
40  BYTE *key1 = ( BYTE * ) "abcdefghijklmnopqrstuvwxyz";
41  BYTE cipher1[] = { 0x32, 0x4E, 0xD0, 0xFE, 0xF4, 0x13, 0xA2, 0x03 };
42  BYTE plain2[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 };
43  BYTE *key2 = ( BYTE * ) "Who is John Galt?";
44  BYTE cipher2[] = { 0xCC, 0x91, 0x73, 0x2B, 0x80, 0x22, 0xF6, 0x84 };
45  BYTE plain3[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 };
46  BYTE key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 };
47  BYTE cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 };
48  int status;
49 
50  /* Test the Blowfish implementation */
51  status = testCipher( capabilityInfo, keyData, key1,
52  strlen( ( char * ) key1 ), plain1, cipher1 );
53  if( cryptStatusOK( status ) )
54  status = testCipher( capabilityInfo, keyData, key2,
55  strlen( ( char * ) key2 ), plain2, cipher2 );
56  if( cryptStatusOK( status ) )
57  status = testCipher( capabilityInfo, keyData, key3, 8, plain3,
58  cipher3 );
59  return( status );
60  }
61 #else
62  #define selfTest NULL
63 #endif /* !CONFIG_NO_SELFTEST */
64 
65 /****************************************************************************
66 * *
67 * Control Routines *
68 * *
69 ****************************************************************************/
70 
71 /* Return context subtype-specific information */
72 
74 static int getInfo( IN_ENUM( CAPABILITY_INFO ) const CAPABILITY_INFO_TYPE type,
76  OUT void *data,
77  IN_INT_Z const int length )
78  {
79  assert( contextInfoPtr == NULL || \
80  isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
81  assert( ( length == 0 && isWritePtr( data, sizeof( int ) ) ) || \
82  ( length > 0 && isWritePtr( data, length ) ) );
83 
85 
86  if( type == CAPABILITY_INFO_STATESIZE )
87  {
88  int *valuePtr = ( int * ) data;
89 
90  *valuePtr = BLOWFISH_EXPANDED_KEYSIZE;
91 
92  return( CRYPT_OK );
93  }
94 
95  return( getDefaultInfo( type, contextInfoPtr, data, length ) );
96  }
97 
98 /****************************************************************************
99 * *
100 * Blowfish En/Decryption Routines *
101 * *
102 ****************************************************************************/
103 
104 /* Encrypt/decrypt data in ECB mode */
105 
106 static int encryptECB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
107  int noBytes )
108  {
109  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
110  BF_KEY *blowfishKey = ( BF_KEY * ) convInfo->key;
111  int blockCount = noBytes / BF_BLOCK;
112 
113  while( blockCount-- > 0 )
114  {
115  /* Encrypt a block of data */
116  BF_ecb_encrypt( buffer, buffer, blowfishKey, BF_ENCRYPT );
117 
118  /* Move on to next block of data */
119  buffer += BF_BLOCK;
120  }
121 
122  return( CRYPT_OK );
123  }
124 
125 static int decryptECB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
126  int noBytes )
127  {
128  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
129  BF_KEY *blowfishKey = ( BF_KEY * ) convInfo->key;
130  int blockCount = noBytes / BF_BLOCK;
131 
132  while( blockCount-- > 0 )
133  {
134  /* Decrypt a block of data */
135  BF_ecb_encrypt( buffer, buffer, blowfishKey, BF_DECRYPT );
136 
137  /* Move on to next block of data */
138  buffer += BF_BLOCK;
139  }
140 
141  return( CRYPT_OK );
142  }
143 
144 /* Encrypt/decrypt data in CBC mode */
145 
146 static int encryptCBC( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
147  int noBytes )
148  {
149  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
150 
151  BF_cbc_encrypt( buffer, buffer, noBytes, convInfo->key,
152  convInfo->currentIV, BF_ENCRYPT );
153 
154  return( CRYPT_OK );
155  }
156 
157 static int decryptCBC( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
158  int noBytes )
159  {
160  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
161 
162  BF_cbc_encrypt( buffer, buffer, noBytes, convInfo->key,
163  convInfo->currentIV, BF_DECRYPT );
164 
165  return( CRYPT_OK );
166  }
167 
168 /* Encrypt/decrypt data in CFB mode */
169 
170 static int encryptCFB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
171  int noBytes )
172  {
173  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
174  BF_KEY *blowfishKey = ( BF_KEY * ) convInfo->key;
175  int i, ivCount = convInfo->ivCount;
176 
177  /* If there's any encrypted material left in the IV, use it now */
178  if( ivCount > 0 )
179  {
180  int bytesToUse;
181 
182  /* Find out how much material left in the encrypted IV we can use */
183  bytesToUse = BF_BLOCK - ivCount;
184  if( noBytes < bytesToUse )
185  bytesToUse = noBytes;
186 
187  /* Encrypt the data */
188  for( i = 0; i < bytesToUse; i++ )
189  buffer[ i ] ^= convInfo->currentIV[ i + ivCount ];
190  memcpy( convInfo->currentIV + ivCount, buffer, bytesToUse );
191 
192  /* Adjust the byte count and buffer position */
193  noBytes -= bytesToUse;
194  buffer += bytesToUse;
195  ivCount += bytesToUse;
196  }
197 
198  while( noBytes > 0 )
199  {
200  ivCount = ( noBytes > BF_BLOCK ) ? BF_BLOCK : noBytes;
201 
202  /* Encrypt the IV */
203  BF_ecb_encrypt( convInfo->currentIV, convInfo->currentIV,
204  blowfishKey, BF_ENCRYPT );
205 
206  /* XOR the buffer contents with the encrypted IV */
207  for( i = 0; i < ivCount; i++ )
208  buffer[ i ] ^= convInfo->currentIV[ i ];
209 
210  /* Shift the ciphertext into the IV */
211  memcpy( convInfo->currentIV, buffer, ivCount );
212 
213  /* Move on to next block of data */
214  noBytes -= ivCount;
215  buffer += ivCount;
216  }
217 
218  /* Remember how much of the IV is still available for use */
219  convInfo->ivCount = ( ivCount % BF_BLOCK );
220 
221  return( CRYPT_OK );
222  }
223 
224 /* Decrypt data in CFB mode. Note that the transformation can be made
225  faster (but less clear) with temp = buffer, buffer ^= iv, iv = temp
226  all in one loop */
227 
228 static int decryptCFB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
229  int noBytes )
230  {
231  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
232  BF_KEY *blowfishKey = ( BF_KEY * ) convInfo->key;
233  BYTE temp[ BF_BLOCK + 8 ];
234  int i, ivCount = convInfo->ivCount;
235 
236  /* If there's any encrypted material left in the IV, use it now */
237  if( ivCount > 0 )
238  {
239  int bytesToUse;
240 
241  /* Find out how much material left in the encrypted IV we can use */
242  bytesToUse = BF_BLOCK - ivCount;
243  if( noBytes < bytesToUse )
244  bytesToUse = noBytes;
245 
246  /* Decrypt the data */
247  memcpy( temp, buffer, bytesToUse );
248  for( i = 0; i < bytesToUse; i++ )
249  buffer[ i ] ^= convInfo->currentIV[ i + ivCount ];
250  memcpy( convInfo->currentIV + ivCount, temp, bytesToUse );
251 
252  /* Adjust the byte count and buffer position */
253  noBytes -= bytesToUse;
254  buffer += bytesToUse;
255  ivCount += bytesToUse;
256  }
257 
258  while( noBytes > 0 )
259  {
260  ivCount = ( noBytes > BF_BLOCK ) ? BF_BLOCK : noBytes;
261 
262  /* Encrypt the IV */
263  BF_ecb_encrypt( convInfo->currentIV, convInfo->currentIV,
264  blowfishKey, BF_ENCRYPT );
265 
266  /* Save the ciphertext */
267  memcpy( temp, buffer, ivCount );
268 
269  /* XOR the buffer contents with the encrypted IV */
270  for( i = 0; i < ivCount; i++ )
271  buffer[ i ] ^= convInfo->currentIV[ i ];
272 
273  /* Shift the ciphertext into the IV */
274  memcpy( convInfo->currentIV, temp, ivCount );
275 
276  /* Move on to next block of data */
277  noBytes -= ivCount;
278  buffer += ivCount;
279  }
280 
281  /* Remember how much of the IV is still available for use */
282  convInfo->ivCount = ( ivCount % BF_BLOCK );
283 
284  /* Clear the temporary buffer */
285  zeroise( temp, BF_BLOCK );
286 
287  return( CRYPT_OK );
288  }
289 
290 /* Encrypt/decrypt data in OFB mode */
291 
292 static int encryptOFB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
293  int noBytes )
294  {
295  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
296  BF_KEY *blowfishKey = ( BF_KEY * ) convInfo->key;
297  int i, ivCount = convInfo->ivCount;
298 
299  /* If there's any encrypted material left in the IV, use it now */
300  if( ivCount > 0 )
301  {
302  int bytesToUse;
303 
304  /* Find out how much material left in the encrypted IV we can use */
305  bytesToUse = BF_BLOCK - ivCount;
306  if( noBytes < bytesToUse )
307  bytesToUse = noBytes;
308 
309  /* Encrypt the data */
310  for( i = 0; i < bytesToUse; i++ )
311  buffer[ i ] ^= convInfo->currentIV[ i + ivCount ];
312 
313  /* Adjust the byte count and buffer position */
314  noBytes -= bytesToUse;
315  buffer += bytesToUse;
316  ivCount += bytesToUse;
317  }
318 
319  while( noBytes > 0 )
320  {
321  ivCount = ( noBytes > BF_BLOCK ) ? BF_BLOCK : noBytes;
322 
323  /* Encrypt the IV */
324  BF_ecb_encrypt( convInfo->currentIV, convInfo->currentIV,
325  blowfishKey, BF_ENCRYPT );
326 
327  /* XOR the buffer contents with the encrypted IV */
328  for( i = 0; i < ivCount; i++ )
329  buffer[ i ] ^= convInfo->currentIV[ i ];
330 
331  /* Move on to next block of data */
332  noBytes -= ivCount;
333  buffer += ivCount;
334  }
335 
336  /* Remember how much of the IV is still available for use */
337  convInfo->ivCount = ( ivCount % BF_BLOCK );
338 
339  return( CRYPT_OK );
340  }
341 
342 /* Decrypt data in OFB mode */
343 
344 static int decryptOFB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
345  int noBytes )
346  {
347  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
348  BF_KEY *blowfishKey = ( BF_KEY * ) convInfo->key;
349  int i, ivCount = convInfo->ivCount;
350 
351  /* If there's any encrypted material left in the IV, use it now */
352  if( ivCount > 0 )
353  {
354  int bytesToUse;
355 
356  /* Find out how much material left in the encrypted IV we can use */
357  bytesToUse = BF_BLOCK - ivCount;
358  if( noBytes < bytesToUse )
359  bytesToUse = noBytes;
360 
361  /* Decrypt the data */
362  for( i = 0; i < bytesToUse; i++ )
363  buffer[ i ] ^= convInfo->currentIV[ i + ivCount ];
364 
365  /* Adjust the byte count and buffer position */
366  noBytes -= bytesToUse;
367  buffer += bytesToUse;
368  ivCount += bytesToUse;
369  }
370 
371  while( noBytes > 0 )
372  {
373  ivCount = ( noBytes > BF_BLOCK ) ? BF_BLOCK : noBytes;
374 
375  /* Encrypt the IV */
376  BF_ecb_encrypt( convInfo->currentIV, convInfo->currentIV,
377  blowfishKey, BF_ENCRYPT );
378 
379  /* XOR the buffer contents with the encrypted IV */
380  for( i = 0; i < ivCount; i++ )
381  buffer[ i ] ^= convInfo->currentIV[ i ];
382 
383  /* Move on to next block of data */
384  noBytes -= ivCount;
385  buffer += ivCount;
386  }
387 
388  /* Remember how much of the IV is still available for use */
389  convInfo->ivCount = ( ivCount % BF_BLOCK );
390 
391  return( CRYPT_OK );
392  }
393 
394 /****************************************************************************
395 * *
396 * Blowfish Key Management Routines *
397 * *
398 ****************************************************************************/
399 
400 /* Key schedule a Blowfish key */
401 
402 static int initKey( CONTEXT_INFO *contextInfoPtr, const void *key,
403  const int keyLength )
404  {
405  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
406 
407  /* Copy the key to internal storage */
408  if( convInfo->userKey != key )
409  memcpy( convInfo->userKey, key, keyLength );
410  convInfo->userKeyLength = keyLength;
411 
412  BF_set_key( ( BF_KEY * ) convInfo->key, keyLength, ( void * ) key );
413  return( CRYPT_OK );
414  }
415 
416 /****************************************************************************
417 * *
418 * Capability Access Routines *
419 * *
420 ****************************************************************************/
421 
422 static const CAPABILITY_INFO FAR_BSS capabilityInfo = {
423  CRYPT_ALGO_BLOWFISH, bitsToBytes( 64 ), "Blowfish", 8,
424  MIN_KEYSIZE, bitsToBytes( 128 ), bitsToBytes( 448 ),
425  selfTest, getInfo, NULL, initGenericParams, initKey, NULL,
426  encryptECB, decryptECB, encryptCBC, decryptCBC,
427  encryptCFB, decryptCFB, encryptOFB, decryptOFB
428  };
429 
431  {
432  return( &capabilityInfo );
433  }
434 
435 #endif /* USE_BLOWFISH */