⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 testll.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
*																			*
*						cryptlib Low-level Test Routines					*
*						Copyright Peter Gutmann 1995-2003					*
*																			*
****************************************************************************/

#ifdef _MSC_VER
  #include "../cryptlib.h"
  #include "../test/test.h"
#else
  #include "cryptlib.h"
  #include "test/test.h"
#endif /* Braindamaged VC++ include handling */

#if defined( __MVS__ ) || defined( __VMCMS__ )
  /* Suspend conversion of literals to ASCII. */
  #pragma convlit( suspend )
#endif /* EBCDIC systems */

/* The size of the test buffers */

#define TESTBUFFER_SIZE		256

/****************************************************************************
*																			*
*								Utility Functions							*
*																			*
****************************************************************************/

/* Check for an algorithm/mode */

static BOOLEAN checkLowlevelInfo( const CRYPT_DEVICE cryptDevice,
								  const CRYPT_ALGO_TYPE cryptAlgo )
	{
	CRYPT_QUERY_INFO cryptQueryInfo;
	const BOOLEAN isDevice = ( cryptDevice != CRYPT_UNUSED ) ? TRUE : FALSE;
	int status;

	if( isDevice )
		status = cryptDeviceQueryCapability( cryptDevice, cryptAlgo,
											 &cryptQueryInfo );
	else
		status = cryptQueryCapability( cryptAlgo, &cryptQueryInfo );
	if( cryptStatusError( status ) )
		{
		printf( "crypt%sQueryCapability() reports algorithm %d is not "
				"available, status = %d.\n", isDevice ? "Device" : "",
				cryptAlgo, status );
		return( FALSE );
		}
	printf( "cryptQueryCapability() reports availability of %s algorithm "
			"with\n  block size %d bits", cryptQueryInfo.algoName,
			cryptQueryInfo.blockSize << 3 );
	if( cryptAlgo < CRYPT_ALGO_FIRST_HASH || cryptAlgo > CRYPT_ALGO_LAST_HASH )
		{
		printf( ", keysize %d-%d bits (recommended = %d bits)",
				cryptQueryInfo.minKeySize << 3, 
				cryptQueryInfo.maxKeySize << 3, cryptQueryInfo.keySize << 3 );
		}
	puts( "." );

	return( TRUE );
	}

/* Set a pair of encrypt/decrypt buffers to a known state, and make sure 
   that they're still in that known state */

static void initTestBuffers( BYTE *buffer1, BYTE *buffer2, const int length )
	{
#if defined( __MVS__ ) || defined( __VMCMS__ )
  #pragma convlit( resume )
#endif /* EBCDIC systems */
	/* Set the buffers to a known state */
	memset( buffer1, '*', length );
	memcpy( buffer1, "12345678", 8 );		/* For endianness check */
	if( buffer2 != NULL )
		memcpy( buffer2, buffer1, length );
#if defined( __MVS__ ) || defined( __VMCMS__ )
  #pragma convlit( suspend )
#endif /* EBCDIC systems */
	}

static BOOLEAN checkTestBuffers( const BYTE *buffer1, const BYTE *buffer2 )
	{
	/* Make sure that everything went OK */
	if( memcmp( buffer1, buffer2, TESTBUFFER_SIZE ) )
		{
		puts( "Error: Decrypted data != original plaintext." );

		/* Try and guess at block chaining problems */
		if( !memcmp( buffer1, "12345678****", 12 ) )
			puts( "\t\bIt looks like there's a problem with block chaining." );
		else
			/* Try and guess at endianness problems - we want "1234" */
			if( !memcmp( buffer1, "4321", 4 ) )
				puts( "\t\bIt looks like the 32-bit word endianness is "
					  "reversed." );
			else
				if( !memcmp( buffer1, "2143", 4 ) )
					puts( "\t\bIt looks like the 16-bit word endianness is "
						  "reversed." );
			else
				if( buffer1[ 0 ] >= '1' && buffer1[ 0 ] <= '9' )
					puts( "\t\bIt looks like there's some sort of endianness "
						  "problem which is\n\t more complex than just a "
						  "reversal." );
				else
					puts( "\t\bIt's probably more than just an endianness "
						  "problem." );
		return( FALSE );
		}

	return( TRUE );
	}

/* Load the encryption contexts */

static BOOLEAN loadContexts( CRYPT_CONTEXT *cryptContext, CRYPT_CONTEXT *decryptContext,
							 const CRYPT_DEVICE cryptDevice,
							 const CRYPT_ALGO_TYPE cryptAlgo,
							 const CRYPT_MODE_TYPE cryptMode,
							 const BYTE *key, const int length )
	{
	const BOOLEAN isDevice = ( cryptDevice != CRYPT_UNUSED ) ? TRUE : FALSE;
	const BOOLEAN hasKey = ( cryptAlgo >= CRYPT_ALGO_FIRST_CONVENTIONAL && \
							 cryptAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL ) || \
						   ( cryptAlgo >= CRYPT_ALGO_FIRST_MAC && \
							 cryptAlgo <= CRYPT_ALGO_LAST_MAC );
	BOOLEAN adjustKey = FALSE;
	int status;

	/* Create the encryption context */
	if( isDevice )
		status = cryptDeviceCreateContext( cryptDevice, cryptContext,
										   cryptAlgo );
	else
		status = cryptCreateContext( cryptContext, CRYPT_UNUSED, cryptAlgo );
	if( cryptStatusError( status ) )
		{
		printf( "crypt%sCreateContext() failed with error code %d.\n",
				isDevice ? "Device" : "", status );
		return( FALSE );
		}
	if( cryptAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL )
		{
		status = cryptSetAttribute( *cryptContext, CRYPT_CTXINFO_MODE,
									cryptMode );
		if( cryptStatusError( status ) )
			{
			cryptDestroyContext( *cryptContext );
			if( status == CRYPT_ERROR_NOTAVAIL )
				/* This mode isn't available, return a special-case value to
				   tell the calling code to continue */
				return( status );
			printf( "Encryption mode %d selection failed with status %d.\n",
					cryptMode, status );
			return( FALSE );
			}
		}
	if( hasKey )
		{
		status = cryptSetAttributeString( *cryptContext, CRYPT_CTXINFO_KEY,
										  key, length );
		if( length > 16 && status == CRYPT_ERROR_PARAM4 )
			{
			status = cryptSetAttributeString( *cryptContext, CRYPT_CTXINFO_KEY,
											  key, 16 );
			if( cryptStatusOK( status ) )
				{
				puts( "  Load of full-length key failed, using shorter 128-"
					  "bit key." );
				adjustKey = TRUE;
				}
			}
		if( cryptStatusError( status ) )
			{
			printf( "Key load failed with error code %d.\n", status );
			return( FALSE );
			}
		}
	if( decryptContext == NULL )
		return( TRUE );

	/* Create the decryption context */
	if( cryptDevice == CRYPT_UNUSED )
		status = cryptCreateContext( decryptContext, CRYPT_UNUSED, cryptAlgo );
	else
		status = cryptDeviceCreateContext( cryptDevice, decryptContext,
										   cryptAlgo );
	if( cryptStatusError( status ) )
		{
		printf( "crypt%sCreateContext() failed with error code %d.\n",
				( cryptDevice != CRYPT_UNUSED ) ? "Device" : "", status );
		return( FALSE );
		}
	if( cryptAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL )
		{
		status = cryptSetAttribute( *decryptContext, CRYPT_CTXINFO_MODE,
									cryptMode );
		if( cryptStatusError( status ) )
			{
			cryptDestroyContext( *cryptContext );
			if( status == CRYPT_ERROR_NOTAVAIL )
				/* This mode isn't available, return a special-case value to
				   tell the calling code to continue */
				return( status );
			printf( "Encryption mode %d selection failed with status %d.\n",
					cryptMode, status );
			return( FALSE );
			}
		}
	if( hasKey )
		{
		status = cryptSetAttributeString( *decryptContext, CRYPT_CTXINFO_KEY,
										  key, adjustKey ? 16 : length );
		if( cryptStatusError( status ) )
			{
			printf( "Key load failed with error code %d.\n", status );
			return( FALSE );
			}
		}

	return( TRUE );
	}

/* Perform a test en/decryption */

int testCrypt( CRYPT_CONTEXT cryptContext, CRYPT_CONTEXT decryptContext,
			   BYTE *buffer, const BOOLEAN isDevice,
			   const BOOLEAN noWarnFail )
	{
	BYTE iv[ CRYPT_MAX_IVSIZE ];
	BYTE localBuffer[ TESTBUFFER_SIZE ];
	int cryptAlgo, cryptMode, status;

	/* If the user hasn't supplied a test buffer, use our own one */
	if( buffer == NULL )
		{
		buffer = localBuffer;
		initTestBuffers( buffer, NULL, TESTBUFFER_SIZE );
		}

	/* Find out about the algorithm we're using */
	cryptGetAttribute( cryptContext, CRYPT_CTXINFO_ALGO, &cryptAlgo );
	cryptGetAttribute( cryptContext, CRYPT_CTXINFO_MODE, &cryptMode );
	if( cryptAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL && \
		( cryptMode == CRYPT_MODE_CFB || cryptMode == CRYPT_MODE_OFB ) )
		{
		/* Encrypt the buffer in two odd-sized chunks */
		status = cryptEncrypt( cryptContext, buffer, 79 );
		if( cryptStatusOK( status ) )
			status = cryptEncrypt( cryptContext, buffer + 79,
								   TESTBUFFER_SIZE - 79 );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't encrypt data, status = %d.\n", status );
			return( status );
			}

		/* Copy the IV from the encryption to the decryption context if
		   necessary */
		if( cryptAlgo != CRYPT_ALGO_RC4 )
			{
			int ivLength;

			status = cryptGetAttributeString( cryptContext, CRYPT_CTXINFO_IV,
											  iv, &ivLength );
			if( cryptStatusError( status ) )
				{
				printf( "Couldn't retrieve IV after encryption, status = %d.\n",
						status );
				return( status );
				}
			status = cryptSetAttributeString( decryptContext, CRYPT_CTXINFO_IV,
											  iv, ivLength );
			if( cryptStatusError( status ) )
				{
				printf( "Couldn't load IV for decryption, status = %d.\n", status );
				return( status );
				}
			}

		/* Decrypt the buffer in different odd-size chunks */
		status = cryptDecrypt( decryptContext, buffer, 125 );
		if( cryptStatusOK( status ) )
			status = cryptDecrypt( decryptContext, buffer + 125,
								   TESTBUFFER_SIZE - 125 );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't decrypt data, status = %d.\n", status );
			return( status );
			}

		return( CRYPT_OK );
		}
	if( cryptAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL && \
		( cryptMode == CRYPT_MODE_ECB || cryptMode == CRYPT_MODE_CBC ) )
		{
		/* Encrypt the buffer in two odd-sized chunks */
		status = cryptEncrypt( cryptContext, buffer, 80 );
		if( cryptStatusOK( status ) )
			status = cryptEncrypt( cryptContext, buffer + 80,
								   TESTBUFFER_SIZE - 80 );
		if( cryptStatusOK( status ) )
			status = cryptEncrypt( cryptContext, buffer + TESTBUFFER_SIZE, 0 );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't encrypt data, status = %d.\n", status );
			return( status );
			}

		/* Copy the IV from the encryption to the decryption context if
		   necessary */
		if( cryptMode != CRYPT_MODE_ECB )
			{
			int ivLength;

			status = cryptGetAttributeString( cryptContext, CRYPT_CTXINFO_IV,
											  iv, &ivLength );
			if( cryptStatusError( status ) )
				printf( "Couldn't retrieve IV after encryption, status = %d.\n",
						status );
			status = cryptSetAttributeString( decryptContext, CRYPT_CTXINFO_IV,
											  iv, ivLength );
			if( cryptStatusError( status ) )
				printf( "Couldn't load IV for decryption, status = %d.\n", status );
			status = cryptEncrypt( cryptContext, buffer + TESTBUFFER_SIZE, 0 );
			}

		/* Decrypt the buffer in different odd-size chunks */
		status = cryptDecrypt( decryptContext, buffer, 128 );
		if( cryptStatusOK( status ) )
			status = cryptDecrypt( decryptContext, buffer + 128,
								   TESTBUFFER_SIZE - 128 );
		if( cryptStatusOK( status ) )
			status = cryptDecrypt( decryptContext, buffer + TESTBUFFER_SIZE, 0 );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't decrypt data, status = %d.\n", status );
			return( status );
			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -