📄 mdcmain.c
字号:
/***************************************************************************** ** MDCMAIN.C - MDC driver code ** ** Written by Peter Gutmann, pgut1@cs.aukuni.ac.nz, September 1992 ** You can use this code in any way you want, ** although it'd be nice if you kept my name + contact address on it ** *****************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include "mdc.h"/* The encryption password lengths. A minimum length of 8 bytes provides a reasonable level of security */#define MIN_KEYLENGTH 8#define MAX_KEYLENGTH 80 /* Any reasonable value will do *//* The buffer used by the MDC version of MD5 */BYTE cryptBuffer[ 2048 ];/***************************************************************************** ** Sample Program: File Encryption/Decryption using CFB mode ** *****************************************************************************/#ifndef TEST_VERSION#define MDC_ID "MDC "void main( const int argc, const char *argv[] ) {#if !defined( TIME_TRIAL ) && !defined( SETUP_TRIAL ) FILE *inFilePtr, *outFilePtr;#endif /* !( TIME_TRIAL || SETUP_TRIAL ) */#if defined( TIME_TRIAL ) || defined( SETUP_TRIAL ) time_t startTime, endTime;#endif /* TIME_TRIAL || SETUP_TRIAL */#ifndef SETUP_TRIAL BYTE buffer[ 512 ];#endif /* !SETUP_TRIAL */ char key[ MAX_KEYLENGTH + 1 ]; int count = 1; BYTE *iv;#if !defined( TIME_TRIAL ) && !defined( SETUP_TRIAL ) if( argc == 4 ) { if( ( inFilePtr = fopen( argv[ 2 ], "rb" ) ) == NULL ) { perror( argv[ 2 ] ); exit( ERROR ); } if( ( outFilePtr = fopen( argv[ 3 ], "r" ) ) != NULL ) { fclose( outFilePtr ); printf( "Won't overwrite existing file %s\n", argv[ 3 ] ); exit( ERROR ); } if( ( outFilePtr = fopen( argv[ 3 ], "wb" ) ) == NULL ) { perror( argv[ 3 ] ); exit( ERROR ); } } else { puts( "Usage: mdc e|d <infile> <outfile>" ); puts( " e to encrypt data" ); puts( " d to decrypt data" ); exit( ERROR ); }#endif /* !( TIME_TRIAL || SETUP_TRIAL ) */#if !defined( TIME_TRIAL ) && !defined( SETUP_TRIAL ) /* Read/write the header information */ if( *argv[ 1 ] == 'e' ) { iv = getIV(); fwrite( MDC_ID, 1, 4, outFilePtr ); fwrite( iv, 1, IV_SIZE, outFilePtr ); } else { if( fread( buffer, 1, 4 + IV_SIZE, inFilePtr ) != 4 + IV_SIZE || \ memcmp( buffer, MDC_ID, 4 ) ) { puts( "Not an MDC-encrypted file" ); exit( ERROR ); } memcpy( iv, buffer + 4, IV_SIZE ); }#endif /* !( TIME_TRIAL || SETUP_TRIAL ) */ /* Set up the S-Boxes */#if defined( TIME_TRIAL ) || defined( SETUP_TRIAL ) strcpy( key, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ); iv = getIV();#else *key = '\0'; while( strlen( key ) < MIN_KEYLENGTH ) { printf( "Key (%d-%d chars): ", MIN_KEYLENGTH, MAX_KEYLENGTH ); fgets( key, MAX_KEYLENGTH, stdin ); /* Should use something better */ key[ strlen( key ) - 1 ] = '\0'; /* Stomp '\n' */ putchar( '\n' ); }#endif /* TIME_TRIAL || SETUP_TRIAL */#ifdef SETUP_TRIAL puts( "Performing 100 key setup operations" ); time( &startTime ); for( count = 0; count < 100; count++ ) initKey( ( BYTE * ) key, strlen( key ), iv ); time( &endTime ); printf( "Seconds to 100 perform key setup operations: %ld\n", \ ( long ) ( endTime - startTime ) ); printf( "Setups per second: %ld\n", \ 100 / ( endTime - startTime ) ); /* Should really use FP */ puts( "Done" );#else initKey( ( BYTE * ) key, strlen( key ), iv );#endif /* SETUP_TRIAL */ /* We're done with the key, zap it */ memset( key, 0, MAX_KEYLENGTH + 1 );#if defined( TIME_TRIAL ) /* Encrypt 1MB of data in 512-byte blocks */ memset( buffer, 0, 512 ); puts( "Encrypting 20480 x 512-byte blocks (10MB)..." ); time( &startTime ); for( count = 0; count < 20480; count++ ) encryptCFB( buffer, 512 ); time( &endTime ); printf( "Seconds to encrypt: %ld\n", ( long ) ( endTime - startTime ) ); printf( "Bytes per second: %ld\n", 10000000L / ( endTime - startTime ) ); puts( "Done" );#elif !defined( SETUP_TRIAL ) /* Grovel through a file en/decrypting it */ while( count ) { /* Read in a block of chars */ count = fread( buffer, 1, 512, inFilePtr ); /* Encrypt/decrypt data block */ if( *argv[ 1 ] == 'e' ) encryptCFB( buffer, count ); else decryptCFB( buffer, count ); /* Write out block and reset counter */ fwrite( buffer, 1, count, outFilePtr ); } fclose( inFilePtr ); fclose( outFilePtr );#endif /* TIME_TRIAL */ }#endif /* !TEST_VERSION *//***************************************************************************** ** Sample Program: Perform Test En/Decryptions ** *****************************************************************************/#ifdef TEST_VERSION/* Sample code to encrypt/decrypt 128-bit values. Note that the sample keys are possibly somewhat shorter than what would normally be used (128 bits vs MIN_KEYLENGTH...MAX_KEYLENGTH bytes). Note that the following code only exercises the basic MDC transformation, not the CFB-mode encryption, since this is stream-oriented */typedef struct { BYTE key[ BLOCKSIZE ]; /* Sample key */ BYTE data[ BLOCKSIZE ]; /* Sample data */ } SAMPLE_VALUE;SAMPLE_VALUE testValues[] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, }, { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, }, { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, }, { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, }, { { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, }, { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, }, { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, }, { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, }, { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, }, { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, }, { { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, }, { { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, }, { { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }, { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }, }, { { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF } } };#define NO_TEST_VALUES 14/* Things internal to MDC which we normally don't need to know about but which are used by this test code */void longReverse( LONG *buffer, int byteCount );extern BYTE auxKey[ MD5_BLOCKSIZE ];/* Code to generate test encryption values */void printData( BYTE *data ) { int i = 0; while( i < BLOCKSIZE ) printf( "%02X", data[ i++ ] ); }void main( void ) { BYTE cipherText[ BLOCKSIZE ]; int i; puts( "Beginning test run..." ); for( i = 0; i < NO_TEST_VALUES; i++ ) { /* Set up the key */ initKey( testValues[ i ].key, BLOCKSIZE, DEFAULT_IV ); printf( "Key " ); printData( testValues[ i ].key ); printf( ", data " ); printData( testValues[ i ].data ); printf( ":\n " ); /* Perform test encryptions. Note that we can't test this by decrypting it like an ECB/CBC mode cipher since it's a one-way transformation */ memcpy( cipherText, testValues[ i ].data, BLOCKSIZE ); mdcTransform( cipherText ); printData( cipherText ); putchar( '\n' ); } }#endif /* TEST_VERSION */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -