home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
crypl200.zip
/
LIB_RC4.C
< prev
next >
Wrap
Text File
|
1996-09-29
|
4KB
|
146 lines
/****************************************************************************
* *
* cryptlib RC4 Encryption Routines *
* Copyright Peter Gutmann 1992-1996 *
* *
****************************************************************************/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "crypt.h"
#ifdef INC_ALL
#include "rc4.h"
#else
#include "rc/rc4.h"
#endif /* Compiler-specific includes */
/* The size of the expanded IDEA keys */
#define RC4_EXPANDED_KEYSIZE sizeof( RC4KEY )
/****************************************************************************
* *
* RC4 Self-test Routines *
* *
****************************************************************************/
#include "testrc4.h"
/* Test the RC4 code against the test vectors from the BSAFE2 implementation */
static int rc4Test( BYTE *key, int keySize,
BYTE *plaintext, BYTE *ciphertext, int length )
{
BYTE temp[ 512 ];
RC4KEY rc4key;
memcpy( temp, plaintext, length );
rc4ExpandKey( &rc4key, key, keySize );
rc4Crypt( &rc4key, temp, length );
if( memcmp( ciphertext, temp, length ) )
return( CRYPT_ERROR );
return( CRYPT_OK );
}
int rc4SelfTest( void )
{
/* The testing gets somewhat messy here because of the variable-length
arrays, which isn't normally a problem with the fixed-length keys
and data used in the block ciphers */
if( rc4Test( testRC4key1, sizeof( testRC4key1 ), testRC4plaintext1,
testRC4ciphertext1, sizeof( testRC4plaintext1 ) ) != CRYPT_OK ||
rc4Test( testRC4key2, sizeof( testRC4key2 ), testRC4plaintext2,
testRC4ciphertext2, sizeof( testRC4plaintext2 ) ) != CRYPT_OK ||
rc4Test( testRC4key3, sizeof( testRC4key3 ), testRC4plaintext3,
testRC4ciphertext3, sizeof( testRC4plaintext3 ) ) != CRYPT_OK ||
rc4Test( testRC4key4, sizeof( testRC4key4 ), testRC4plaintext4,
testRC4ciphertext4, sizeof( testRC4plaintext4 ) ) != CRYPT_OK ||
rc4Test( testRC4key5, sizeof( testRC4key5 ), testRC4plaintext5,
testRC4ciphertext5, sizeof( testRC4plaintext5 ) ) != CRYPT_OK )
return( CRYPT_ERROR );
return( CRYPT_OK );
}
/****************************************************************************
* *
* Init/Shutdown Routines *
* *
****************************************************************************/
/* Perform auxiliary init and shutdown actions on an encryption context */
int rc4InitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx )
{
int status;
UNUSED( cryptInfoEx );
/* Allocate memory for the expanded key */
if( cryptInfo->key != NULL || cryptInfo->privateData != NULL )
return( CRYPT_INITED );
if( ( status = secureMalloc( &cryptInfo->key, RC4_EXPANDED_KEYSIZE ) ) != CRYPT_OK )
return( status );
cryptInfo->keyLength = RC4_EXPANDED_KEYSIZE;
return( CRYPT_OK );
}
int rc4Init( CRYPT_INFO *cryptInfo )
{
/* Just pass the call through to the extended setup routine */
return( rc4InitEx( cryptInfo, NULL ) );
}
int rc4End( CRYPT_INFO *cryptInfo )
{
/* Free any allocated memory */
secureFree( &cryptInfo->key );
return( CRYPT_OK );
}
/****************************************************************************
* *
* RC4 En/Decryption Routines *
* *
****************************************************************************/
/* Encrypt/decrypt data. Since RC4 is a stream cipher, encryption and
decryption are one and the same */
int rc4Encrypt( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
rc4Crypt( ( RC4KEY * ) cryptInfo->key, buffer, noBytes );
return( CRYPT_OK );
}
int rc4Decrypt( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
rc4Crypt( ( RC4KEY * ) cryptInfo->key, buffer, noBytes );
return( CRYPT_OK );
}
/****************************************************************************
* *
* RC4 Key Management Routines *
* *
****************************************************************************/
/* Create an expanded RC4 key */
int rc4InitKey( CRYPT_INFO *cryptInfo )
{
rc4ExpandKey( ( RC4KEY * ) cryptInfo->key, cryptInfo->userKey,
cryptInfo->userKeyLength );
return( CRYPT_OK );
}