📄 testhl.c
字号:
/****************************************************************************
* *
* cryptlib Mid and High-Level Test Routines *
* Copyright Peter Gutmann 1995-2002 *
* *
****************************************************************************/
#include <limits.h> /* To determine max.buffer size we can encrypt */
#ifdef _MSC_VER
#include "../cryptlib.h"
#include "../test/test.h"
#else
#include "cryptlib.h"
#include "test/test.h"
#endif /* Braindamaged MSC include handling */
/****************************************************************************
* *
* Mid-level Routines Test *
* *
****************************************************************************/
#if defined( TEST_MIDLEVEL ) || defined( TEST_DEVICE ) || \
defined( TEST_HIGHLEVEL )
#ifndef max /* Some compilers don't define this */
#define max( a, b ) ( ( ( a ) > ( b ) ) ? ( ( int ) a ) : ( ( int ) b ) )
#endif /* !max */
/* Test whether two session keys are identical */
static int compareSessionKeys( const CRYPT_CONTEXT cryptContext1,
const CRYPT_CONTEXT cryptContext2 )
{
BYTE buffer[ CRYPT_MAX_IVSIZE ];
int blockSize, ivSize, status;
cryptGetAttribute( cryptContext1, CRYPT_CTXINFO_BLOCKSIZE, &blockSize );
cryptGetAttribute( cryptContext1, CRYPT_CTXINFO_IVSIZE, &ivSize );
cryptSetAttributeString( cryptContext1, CRYPT_CTXINFO_IV,
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00", ivSize );
cryptSetAttributeString( cryptContext2, CRYPT_CTXINFO_IV,
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00", ivSize );
memcpy( buffer, "0123456789ABCDEF", max( blockSize, 8 ) );
status = cryptEncrypt( cryptContext1, buffer, max( blockSize, 8 ) );
if( cryptStatusError( status ) )
{
printf( "cryptEncrypt() with first key failed with error "
"code %d, line %d.\n", status, __LINE__ );
return( FALSE );
}
status = cryptDecrypt( cryptContext2, buffer, max( blockSize, 8 ) );
if( cryptStatusError( status ) )
{
printf( "cryptDecrypt() with second key failed with error "
"code %d, line %d.\n", status, __LINE__ );
return( FALSE );
}
if( memcmp( buffer, "012345678ABCDEF", max( blockSize, 8 ) ) )
{
puts( "Data decrypted with key2 != plaintext encrypted with key1." );
return( FALSE );
}
return( TRUE );
}
#endif /* TEST_MIDLEVEL || TEST_DEVICE || TEST_HIGHLEVEL */
#if defined( TEST_MIDLEVEL ) || defined( TEST_DEVICE )
/* General-purpose routines to perform a key exchange and sign and sig
check data */
static int signData( const char *algoName, const CRYPT_ALGO algorithm,
const CRYPT_CONTEXT externalSignContext,
const CRYPT_CONTEXT externalCheckContext )
{
CRYPT_OBJECT_INFO cryptObjectInfo;
CRYPT_CONTEXT signContext, checkContext;
CRYPT_CONTEXT hashContext;
BYTE *buffer, hashBuffer[] = "abcdefghijklmnopqrstuvwxyz";
int status, length;
printf( "Testing %s digital signature...\n", algoName );
/* Create an SHA hash context and hash the test buffer */
cryptCreateContext( &hashContext, CRYPT_UNUSED, CRYPT_ALGO_SHA );
cryptEncrypt( hashContext, hashBuffer, 26 );
cryptEncrypt( hashContext, hashBuffer, 0 );
/* Create the appropriate en/decryption contexts */
if( externalSignContext != CRYPT_UNUSED )
{
signContext = externalSignContext;
checkContext = externalCheckContext;
}
else
{
if( algorithm == CRYPT_ALGO_DSA )
status = loadDSAContexts( CRYPT_UNUSED, &signContext,
&checkContext );
else
if( algorithm == CRYPT_ALGO_ELGAMAL )
status = loadElgamalContexts( &checkContext, &signContext );
else
status = loadRSAContexts( CRYPT_UNUSED, &checkContext,
&signContext );
if( !status )
return( FALSE );
}
/* Find out how big the signature will be */
status = cryptCreateSignature( NULL, &length, signContext, hashContext );
if( cryptStatusError( status ) )
{
printf( "cryptCreateSignature() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
printf( "cryptCreateSignature() reports signature object will be %d "
"bytes long\n", length );
if( ( buffer = malloc( length ) ) == NULL )
return( FALSE );
/* Sign the hashed data */
status = cryptCreateSignature( buffer, &length, signContext, hashContext );
if( cryptStatusError( status ) )
{
printf( "cryptCreateSignature() failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
/* Query the signed object */
status = cryptQueryObject( buffer, &cryptObjectInfo );
if( cryptStatusError( status ) )
{
printf( "cryptQueryObject() failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
printf( "cryptQueryObject() reports object type %d, algorithm %d, mode "
"%d.\n", cryptObjectInfo.objectType, cryptObjectInfo.cryptAlgo,
cryptObjectInfo.cryptMode );
memset( &cryptObjectInfo, 0, sizeof( CRYPT_OBJECT_INFO ) );
debugDump( "signature", buffer, length );
/* Check the signature on the hash */
status = cryptCheckSignature( buffer, checkContext, hashContext );
if( cryptStatusError( status ) )
{
printf( "cryptCheckSignature() failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
/* Clean up */
cryptDestroyContext( hashContext );
if( externalSignContext == CRYPT_UNUSED )
destroyContexts( CRYPT_UNUSED, checkContext, signContext );
printf( "Generation and checking of %s digital signature via %d-bit "
"data block\n succeeded.\n\n", algoName, PKC_KEYSIZE );
free( buffer );
return( TRUE );
}
static int keyExportImport( const char *algoName, const CRYPT_ALGO algorithm,
const CRYPT_CONTEXT externalCryptContext,
const CRYPT_CONTEXT externalDecryptContext )
{
CRYPT_OBJECT_INFO cryptObjectInfo;
CRYPT_CONTEXT cryptContext, decryptContext;
CRYPT_CONTEXT sessionKeyContext1, sessionKeyContext2;
BYTE *buffer;
int status, length;
printf( "Testing %s public-key export/import...\n", algoName );
/* Create RC2 encryption contexts for the session key */
cryptCreateContext( &sessionKeyContext1, CRYPT_UNUSED,
selectCipher( CRYPT_ALGO_RC2 ) );
cryptSetAttribute( sessionKeyContext1, CRYPT_CTXINFO_MODE, CRYPT_MODE_OFB );
cryptGenerateKey( sessionKeyContext1 );
cryptCreateContext( &sessionKeyContext2, CRYPT_UNUSED,
selectCipher( CRYPT_ALGO_RC2 ) );
cryptSetAttribute( sessionKeyContext2, CRYPT_CTXINFO_MODE, CRYPT_MODE_OFB );
/* Create the appropriate en/decryption contexts */
if( externalCryptContext != CRYPT_UNUSED )
{
cryptContext = externalCryptContext;
decryptContext = externalDecryptContext;
}
else
{
if( algorithm == CRYPT_ALGO_ELGAMAL )
status = loadElgamalContexts( &cryptContext, &decryptContext );
else
status = loadRSAContexts( CRYPT_UNUSED, &cryptContext, &decryptContext );
if( !status )
return( FALSE );
}
/* Find out how big the exported key will be */
status = cryptExportKey( NULL, &length, cryptContext, sessionKeyContext1 );
if( cryptStatusError( status ) )
{
printf( "cryptExportKey() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
printf( "cryptExportKey() reports exported key object will be %d bytes "
"long\n", length );
if( ( buffer = malloc( length ) ) == NULL )
return( FALSE );
/* Export the session key */
status = cryptExportKey( buffer, &length, cryptContext, sessionKeyContext1 );
if( cryptStatusError( status ) )
{
printf( "cryptExportKey() failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
/* Query the encrypted key object */
status = cryptQueryObject( buffer, &cryptObjectInfo );
if( cryptStatusError( status ) )
{
printf( "cryptQueryObject() failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
printf( "cryptQueryObject() reports object type %d, algorithm %d, mode "
"%d.\n", cryptObjectInfo.objectType, cryptObjectInfo.cryptAlgo,
cryptObjectInfo.cryptMode );
memset( &cryptObjectInfo, 0, sizeof( CRYPT_OBJECT_INFO ) );
debugDump( "keytrans", buffer, length );
/* Recreate the session key by importing the encrypted key */
status = cryptImportKey( buffer, decryptContext, sessionKeyContext2 );
if( cryptStatusError( status ) )
{
printf( "cryptImportKey() failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
/* Make sure the two keys match */
if( !compareSessionKeys( sessionKeyContext1, sessionKeyContext2 ) )
return( FALSE );
/* Clean up */
destroyContexts( CRYPT_UNUSED, sessionKeyContext1, sessionKeyContext2 );
if( externalCryptContext == CRYPT_UNUSED )
destroyContexts( CRYPT_UNUSED, cryptContext, decryptContext );
printf( "Export/import of session key via %d-bit %s-encrypted data "
"block succeeded.\n\n", PKC_KEYSIZE, algoName );
free( buffer );
return( TRUE );
}
#endif /* TEST_MIDLEVEL || TEST_DEVICE */
#ifdef TEST_RANDOM
/* Test the randomness gathering routines */
int testRandomRoutines( void )
{
CRYPT_CONTEXT cryptContext;
int status;
puts( "Testing randomness routines. This may take a few seconds..." );
/* Create an encryption context to generate a key into */
cryptCreateContext( &cryptContext, CRYPT_UNUSED, CRYPT_ALGO_DES );
status = cryptGenerateKey( cryptContext );
cryptDestroyContext( cryptContext );
/* Check whether we got enough randomness */
if( status == CRYPT_ERROR_RANDOM )
{
puts( "The randomness-gathering routines in the library can't acquire enough" );
puts( "random information to allow key generation and public-key encryption to" );
puts( "function. You will need to change lib_rand.c or reconfigure your system" );
puts( "to allow the randomness-gathering routines to function. The code to" );
puts( "change can be found in misc/rndXXXX.c\n" );
return( FALSE );
}
puts( "Randomness-gathering self-test succeeded.\n" );
return( TRUE );
}
#endif /* TEST_RANDOM */
#ifdef TEST_MIDLEVEL
/* Test the ability to encrypt a large amount of data */
int testLargeBufferEncrypt( void )
{
CRYPT_CONTEXT cryptContext;
BYTE *buffer;
const size_t length = ( INT_MAX <= 32768L ) ? 16384 : 1048576;
int i, status;
puts( "Testing encryption of large data quantity..." );
/* Allocate a large buffer and fill it with a known value */
if( ( buffer = malloc( length ) ) == NULL )
{
printf( "Couldn't allocate buffer of %d bytes, skipping large buffer "
"encryption test.\n", length );
return( TRUE );
}
memset( buffer, '*', length );
/* Encrypt the buffer */
cryptCreateContext( &cryptContext, CRYPT_UNUSED, CRYPT_ALGO_DES );
cryptSetAttribute( cryptContext, CRYPT_CTXINFO_MODE, CRYPT_MODE_CBC );
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEY, "12345678", 8 );
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_IV,
"\x00\x00\x00\x00\x00\x00\x00\x00", 8 );
status = cryptEncrypt( cryptContext, buffer, length );
if( cryptStatusError( status ) )
{
printf( "cryptEncrypt() of large data quantity failed with error "
"code %d, line %d.\n", status, __LINE__ );
return( FALSE );
}
cryptDestroyContext( cryptContext );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -