cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
ctx_rc2.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib RC2 Encryption Routines *
4 * Copyright Peter Gutmann 1996-2005 *
5 * *
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9  #include "crypt.h"
10  #include "context.h"
11  #include "rc2.h"
12 #else
13  #include "crypt.h"
14  #include "context/context.h"
15  #include "crypt/rc2.h"
16 #endif /* Compiler-specific includes */
17 
18 #ifdef USE_RC2
19 
20 /* Defines to map from EAY to native naming */
21 
22 #define RC2_BLOCKSIZE RC2_BLOCK
23 #define RC2_EXPANDED_KEYSIZE sizeof( RC2_KEY )
24 
25 /* The RC2 key schedule provides a mechanism for reducing the effective key
26  size for export-control purposes, typically used to create 40-bit
27  espionage-enabled keys. BSAFE always sets the bitcount to the actual
28  key size (so for example for a 128-bit key it first expands it up to 1024
29  bits and then folds it back down again to 128 bits). Because this scheme
30  was copied by early S/MIME implementations (which were just BSAFE
31  wrappers), it's become a part of CMS/SMIME so we use it here even though
32  other sources do it differently */
33 
34 #define effectiveKeysizeBits( keySize ) bytesToBits( keySize )
35 
36 /****************************************************************************
37 * *
38 * RC2 Self-test Routines *
39 * *
40 ****************************************************************************/
41 
42 #ifndef CONFIG_NO_SELFTEST
43 
44 /* RC2 test vectors from RFC 2268 */
45 
46 static const struct RC2_TEST {
47  const BYTE key[ 16 ];
48  const BYTE plaintext[ 8 ];
49  const BYTE ciphertext[ 8 ];
50  } FAR_BSS testRC2[] = {
51  { { 0x88, 0xBC, 0xA9, 0x0E, 0x90, 0x87, 0x5A, 0x7F,
52  0x0F, 0x79, 0xC3, 0x84, 0x62, 0x7B, 0xAF, 0xB2 },
53  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
54  { 0x22, 0x69, 0x55, 0x2A, 0xB0, 0xF8, 0x5C, 0xA6 } }
55  };
56 
57 /* Test the RC2 code against the RC2 test vectors */
58 
59 static int selfTest( void )
60  {
61  const CAPABILITY_INFO *capabilityInfo = getRC2Capability();
62  BYTE keyData[ RC2_EXPANDED_KEYSIZE + 8 ];
63  int i, status;
64 
65  for( i = 0; i < sizeof( testRC2 ) / sizeof( struct RC2_TEST ); i++ )
66  {
67  status = testCipher( capabilityInfo, keyData, testRC2[ i ].key,
68  16, testRC2[ i ].plaintext,
69  testRC2[ i ].ciphertext );
70  if( cryptStatusError( status ) )
71  return( status );
72  }
73 
74  return( CRYPT_OK );
75  }
76 #else
77  #define selfTest NULL
78 #endif /* !CONFIG_NO_SELFTEST */
79 
80 /****************************************************************************
81 * *
82 * Control Routines *
83 * *
84 ****************************************************************************/
85 
86 /* Return context subtype-specific information */
87 
89 static int getInfo( IN_ENUM( CAPABILITY_INFO ) const CAPABILITY_INFO_TYPE type,
91  OUT void *data,
92  IN_INT_Z const int length )
93  {
94  assert( contextInfoPtr == NULL || \
95  isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
96  assert( ( length == 0 && isWritePtr( data, sizeof( int ) ) ) || \
97  ( length > 0 && isWritePtr( data, length ) ) );
98 
100 
101  if( type == CAPABILITY_INFO_STATESIZE )
102  {
103  int *valuePtr = ( int * ) data;
104 
105  *valuePtr = RC2_EXPANDED_KEYSIZE;
106 
107  return( CRYPT_OK );
108  }
109 
110  return( getDefaultInfo( type, contextInfoPtr, data, length ) );
111  }
112 
113 /****************************************************************************
114 * *
115 * RC2 En/Decryption Routines *
116 * *
117 ****************************************************************************/
118 
119 /* Encrypt/decrypt data in ECB mode */
120 
121 static int encryptECB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
122  int noBytes )
123  {
124  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
125  RC2_KEY *rc2Key = ( RC2_KEY * ) convInfo->key;
126  int blockCount = noBytes / RC2_BLOCKSIZE;
127 
128  while( blockCount-- > 0 )
129  {
130  /* Encrypt a block of data */
131  RC2_ecb_encrypt( buffer, buffer, rc2Key, RC2_ENCRYPT );
132 
133  /* Move on to next block of data */
134  buffer += RC2_BLOCKSIZE;
135  }
136 
137  return( CRYPT_OK );
138  }
139 
140 static int decryptECB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
141  int noBytes )
142  {
143  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
144  RC2_KEY *rc2Key = ( RC2_KEY * ) convInfo->key;
145  int blockCount = noBytes / RC2_BLOCKSIZE;
146 
147  while( blockCount-- > 0 )
148  {
149  /* Decrypt a block of data */
150  RC2_ecb_encrypt( buffer, buffer, rc2Key, RC2_DECRYPT );
151 
152  /* Move on to next block of data */
153  buffer += RC2_BLOCKSIZE;
154  }
155 
156  return( CRYPT_OK );
157  }
158 
159 /* Encrypt/decrypt data in CBC mode */
160 
161 static int encryptCBC( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
162  int noBytes )
163  {
164  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
165 
166  /* Encrypt the buffer of data */
167  RC2_cbc_encrypt( buffer, buffer, noBytes, ( RC2_KEY * ) convInfo->key,
168  convInfo->currentIV, RC2_ENCRYPT );
169 
170  return( CRYPT_OK );
171  }
172 
173 static int decryptCBC( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
174  int noBytes )
175  {
176  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
177 
178  /* Decrypt the buffer of data */
179  RC2_cbc_encrypt( buffer, buffer, noBytes, ( RC2_KEY * ) convInfo->key,
180  convInfo->currentIV, RC2_DECRYPT );
181 
182  return( CRYPT_OK );
183  }
184 
185 /* Encrypt/decrypt data in CFB mode */
186 
187 static int encryptCFB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
188  int noBytes )
189  {
190  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
191  RC2_KEY *rc2Key = ( RC2_KEY * ) convInfo->key;
192  int i, ivCount = convInfo->ivCount;
193 
194  /* If there's any encrypted material left in the IV, use it now */
195  if( ivCount > 0 )
196  {
197  int bytesToUse;
198 
199  /* Find out how much material left in the encrypted IV we can use */
200  bytesToUse = RC2_BLOCKSIZE - ivCount;
201  if( noBytes < bytesToUse )
202  bytesToUse = noBytes;
203 
204  /* Encrypt the data */
205  for( i = 0; i < bytesToUse; i++ )
206  buffer[ i ] ^= convInfo->currentIV[ i + ivCount ];
207  memcpy( convInfo->currentIV + ivCount, buffer, bytesToUse );
208 
209  /* Adjust the byte count and buffer position */
210  noBytes -= bytesToUse;
211  buffer += bytesToUse;
212  ivCount += bytesToUse;
213  }
214 
215  while( noBytes > 0 )
216  {
217  ivCount = ( noBytes > RC2_BLOCKSIZE ) ? RC2_BLOCKSIZE : noBytes;
218 
219  /* Encrypt the IV */
220  RC2_ecb_encrypt( convInfo->currentIV, convInfo->currentIV, rc2Key,
221  RC2_ENCRYPT );
222 
223  /* XOR the buffer contents with the encrypted IV */
224  for( i = 0; i < ivCount; i++ )
225  buffer[ i ] ^= convInfo->currentIV[ i ];
226 
227  /* Shift the ciphertext into the IV */
228  memcpy( convInfo->currentIV, buffer, ivCount );
229 
230  /* Move on to next block of data */
231  noBytes -= ivCount;
232  buffer += ivCount;
233  }
234 
235  /* Remember how much of the IV is still available for use */
236  convInfo->ivCount = ( ivCount % RC2_BLOCKSIZE );
237 
238  return( CRYPT_OK );
239  }
240 
241 /* Decrypt data in CFB mode. Note that the transformation can be made
242  faster (but less clear) with temp = buffer, buffer ^= iv, iv = temp
243  all in one loop */
244 
245 static int decryptCFB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
246  int noBytes )
247  {
248  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
249  RC2_KEY *rc2Key = ( RC2_KEY * ) convInfo->key;
250  BYTE temp[ RC2_BLOCKSIZE + 8 ];
251  int i, ivCount = convInfo->ivCount;
252 
253  /* If there's any encrypted material left in the IV, use it now */
254  if( ivCount > 0 )
255  {
256  int bytesToUse;
257 
258  /* Find out how much material left in the encrypted IV we can use */
259  bytesToUse = RC2_BLOCKSIZE - ivCount;
260  if( noBytes < bytesToUse )
261  bytesToUse = noBytes;
262 
263  /* Decrypt the data */
264  memcpy( temp, buffer, bytesToUse );
265  for( i = 0; i < bytesToUse; i++ )
266  buffer[ i ] ^= convInfo->currentIV[ i + ivCount ];
267  memcpy( convInfo->currentIV + ivCount, temp, bytesToUse );
268 
269  /* Adjust the byte count and buffer position */
270  noBytes -= bytesToUse;
271  buffer += bytesToUse;
272  ivCount += bytesToUse;
273  }
274 
275  while( noBytes > 0 )
276  {
277  ivCount = ( noBytes > RC2_BLOCKSIZE ) ? RC2_BLOCKSIZE : noBytes;
278 
279  /* Encrypt the IV */
280  RC2_ecb_encrypt( convInfo->currentIV, convInfo->currentIV, rc2Key,
281  RC2_ENCRYPT );
282 
283  /* Save the ciphertext */
284  memcpy( temp, buffer, ivCount );
285 
286  /* XOR the buffer contents with the encrypted IV */
287  for( i = 0; i < ivCount; i++ )
288  buffer[ i ] ^= convInfo->currentIV[ i ];
289 
290  /* Shift the ciphertext into the IV */
291  memcpy( convInfo->currentIV, temp, ivCount );
292 
293  /* Move on to next block of data */
294  noBytes -= ivCount;
295  buffer += ivCount;
296  }
297 
298  /* Remember how much of the IV is still available for use */
299  convInfo->ivCount = ( ivCount % RC2_BLOCKSIZE );
300 
301  /* Clear the temporary buffer */
302  zeroise( temp, RC2_BLOCKSIZE );
303 
304  return( CRYPT_OK );
305  }
306 
307 /* Encrypt/decrypt data in OFB mode */
308 
309 static int encryptOFB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
310  int noBytes )
311  {
312  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
313  RC2_KEY *rc2Key = ( RC2_KEY * ) convInfo->key;
314  int i, ivCount = convInfo->ivCount;
315 
316  /* If there's any encrypted material left in the IV, use it now */
317  if( ivCount > 0 )
318  {
319  int bytesToUse;
320 
321  /* Find out how much material left in the encrypted IV we can use */
322  bytesToUse = RC2_BLOCKSIZE - ivCount;
323  if( noBytes < bytesToUse )
324  bytesToUse = noBytes;
325 
326  /* Encrypt the data */
327  for( i = 0; i < bytesToUse; i++ )
328  buffer[ i ] ^= convInfo->currentIV[ i + ivCount ];
329 
330  /* Adjust the byte count and buffer position */
331  noBytes -= bytesToUse;
332  buffer += bytesToUse;
333  ivCount += bytesToUse;
334  }
335 
336  while( noBytes > 0 )
337  {
338  ivCount = ( noBytes > RC2_BLOCKSIZE ) ? RC2_BLOCKSIZE : noBytes;
339 
340  /* Encrypt the IV */
341  RC2_ecb_encrypt( convInfo->currentIV, convInfo->currentIV, rc2Key,
342  RC2_ENCRYPT );
343 
344  /* XOR the buffer contents with the encrypted IV */
345  for( i = 0; i < ivCount; i++ )
346  buffer[ i ] ^= convInfo->currentIV[ i ];
347 
348  /* Move on to next block of data */
349  noBytes -= ivCount;
350  buffer += ivCount;
351  }
352 
353  /* Remember how much of the IV is still available for use */
354  convInfo->ivCount = ( ivCount % RC2_BLOCKSIZE );
355 
356  return( CRYPT_OK );
357  }
358 
359 /* Decrypt data in OFB mode */
360 
361 static int decryptOFB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
362  int noBytes )
363  {
364  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
365  RC2_KEY *rc2Key = ( RC2_KEY * ) convInfo->key;
366  int i, ivCount = convInfo->ivCount;
367 
368  /* If there's any encrypted material left in the IV, use it now */
369  if( ivCount > 0 )
370  {
371  int bytesToUse;
372 
373  /* Find out how much material left in the encrypted IV we can use */
374  bytesToUse = RC2_BLOCKSIZE - ivCount;
375  if( noBytes < bytesToUse )
376  bytesToUse = noBytes;
377 
378  /* Decrypt the data */
379  for( i = 0; i < bytesToUse; i++ )
380  buffer[ i ] ^= convInfo->currentIV[ i + ivCount ];
381 
382  /* Adjust the byte count and buffer position */
383  noBytes -= bytesToUse;
384  buffer += bytesToUse;
385  ivCount += bytesToUse;
386  }
387 
388  while( noBytes > 0 )
389  {
390  ivCount = ( noBytes > RC2_BLOCKSIZE ) ? RC2_BLOCKSIZE : noBytes;
391 
392  /* Encrypt the IV */
393  RC2_ecb_encrypt( convInfo->currentIV, convInfo->currentIV, rc2Key,
394  RC2_ENCRYPT );
395 
396  /* XOR the buffer contents with the encrypted IV */
397  for( i = 0; i < ivCount; i++ )
398  buffer[ i ] ^= convInfo->currentIV[ i ];
399 
400  /* Move on to next block of data */
401  noBytes -= ivCount;
402  buffer += ivCount;
403  }
404 
405  /* Remember how much of the IV is still available for use */
406  convInfo->ivCount = ( ivCount % RC2_BLOCKSIZE );
407 
408  return( CRYPT_OK );
409  }
410 
411 /****************************************************************************
412 * *
413 * RC2 Key Management Routines *
414 * *
415 ****************************************************************************/
416 
417 #if 1
418 
419 static int keyCrack( CONTEXT_INFO *contextInfoPtr )
420  {
421  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
422  RC2_KEY *rc2Key = ( RC2_KEY * ) convInfo->key;
423  BYTE data[ 32 ], key[ 32 ];
424 #if 0 /* Test data, key = "\x13\x25\x0c\x1a\x60" */
425  static const BYTE *plaintext = "\x11\x1C\xDB\x36\xDC\x6E\x19\xF5";
426  static const BYTE *ciphertext = "\x9C\x4E\x66\x8A\xC7\x6B\x97\xF5";
427 #else /* Actual data */
428  static const BYTE *plaintext = "\x69\xAB\x54\x23\x2D\x86\x92\x61";
429  static const BYTE *ciphertext = "\x34\xAA\xF1\x83\xBD\x9C\xC0\x15";
430 #endif /* 0 */
431  int i;
432 
433  /* Test file: IV = 17 17 F1 B0 94 E8 EE F8 encData + 0
434  PT = 06 0B 2A 86 48 86 F7 0D
435  -----------------------
436  XOR: 11 1C DB 36 DC 6E 19 F5
437 
438  So encr. above = CT block 2.
439  = 9C 4E 66 8A C7 6B 97 F5 encData + 8
440 
441  Actual: IV = 6F A0 7E A5 65 00 65 6C encData + 0
442  PT = 06 0B 2A 86 48 86 F7 0D
443  -----------------------
444  XOR: 69 AB 54 23 2D 86 92 61
445 
446  So encr. above = CT block 2.
447  = 34 AA F1 83 BD 9C C0 15 encData + 8 */
448 
449  memset( key, 0, 5 );
450 // memcpy( key, "\x13\x25\x0c\x1a\x60", 5 );
451  for( i = 0; i < 256; i++ )
452  {
453  int keyIndex;
454 
455  printf( "Trying keys %02X xx.\n", i );
456  fflush( stdout );
457  while( key[ 0 ] == i )
458  {
459  RC2_set_key( rc2Key, 5, key, effectiveKeysizeBits( 5 ) );
460  RC2_ecb_encrypt( plaintext, data, rc2Key, RC2_ENCRYPT );
461  if( data[ 0 ] == ciphertext[ 0 ] && \
462  !memcmp( data, ciphertext, 8 ) )
463  {
464  printf( "Found at %02X %02X %02X %02X %02X.\n",
465  key[ 0 ], key[ 1 ], key[ 2 ], key[ 3 ], key[ 4 ] );
466  fflush( stdout );
467  return( CRYPT_OK );
468  }
469  for( keyIndex = 4; keyIndex >= 0; keyIndex-- )
470  {
471  key[ keyIndex ]++;
472  if( key[ keyIndex ] > 0 )
473  break;
474  }
475  if( keyIndex == 1 )
476  {
477  printf( "Trying keys %02X %02X %02X %02X %02X.\n",
478  key[ 0 ], key[ 1 ], key[ 2 ], key[ 3 ], key[ 4 ] );
479  fflush( stdout );
480  }
481  }
482  }
483 
484  return( CRYPT_OK );
485  }
486 #endif /* 0 */
487 
488 /* Key schedule an RC2 key */
489 
490 static int initKey( CONTEXT_INFO *contextInfoPtr, const void *key,
491  const int keyLength )
492  {
493  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
494  RC2_KEY *rc2Key = ( RC2_KEY * ) convInfo->key;
495 
496 #if 1
497 if( !memcmp( key, "crackcrackcrack", 15 ) )
498  keyCrack( contextInfoPtr );
499 #endif /* 1 */
500 
501  /* Copy the key to internal storage */
502  if( convInfo->userKey != key )
503  memcpy( convInfo->userKey, key, keyLength );
504  convInfo->userKeyLength = keyLength;
505 
506 #ifdef USE_PKCS12
507  /* The only time that RC2 is ever likely to be used is as RC2-40 (since
508  it's disabled by default and is only enabled when PKCS #12 is
509  enabled), which is still universally used by Windows and possibly a
510  number of other implementations as well. To allow the use of keys
511  this short, the caller gives them an oddball length and prefixes them
512  with two copies of the string "PKCS#12", if we find this then we
513  shorten the keys back down to 40 bits */
514  if( convInfo->userKeyLength == 14 + bitsToBytes( 40 ) && \
515  !memcmp( convInfo->userKey, "PKCS#12PKCS#12", 14 ) )
516  {
517  memmove( convInfo->userKey, convInfo->userKey + 14,
518  bitsToBytes( 40 ) );
519  convInfo->userKeyLength = bitsToBytes( 40 );
520 
521  RC2_set_key( rc2Key, convInfo->userKeyLength, convInfo->userKey,
522  effectiveKeysizeBits( convInfo->userKeyLength ) );
523  return( CRYPT_OK );
524  }
525 #endif /* USE_PKCS12 */
526 
527  RC2_set_key( rc2Key, keyLength, key, effectiveKeysizeBits( keyLength ) );
528  return( CRYPT_OK );
529  }
530 
531 /****************************************************************************
532 * *
533 * Capability Access Routines *
534 * *
535 ****************************************************************************/
536 
537 static const CAPABILITY_INFO FAR_BSS capabilityInfo = {
538  CRYPT_ALGO_RC2, bitsToBytes( 64 ), "RC2", 3,
539  MIN_KEYSIZE, bitsToBytes( 128 ), bitsToBytes( 1024 ),
540  selfTest, getInfo, NULL, initGenericParams, initKey, NULL,
541  encryptECB, decryptECB, encryptCBC, decryptCBC,
542  encryptCFB, decryptCFB, encryptOFB, decryptOFB
543  };
544 
545 const CAPABILITY_INFO *getRC2Capability( void )
546  {
547  return( &capabilityInfo );
548  }
549 
550 #endif /* USE_RC2 */