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

📄 testll.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*																			*
*						cryptlib Low-level Test Routines					*
*						Copyright Peter Gutmann 1995-2001					*
*																			*
****************************************************************************/

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

/* The size of the test buffers */

#define TESTBUFFER_SIZE		256

/****************************************************************************
*																			*
*							Low-level Routines Test							*
*																			*
****************************************************************************/

#if defined( TEST_LOWLEVEL ) || defined( TEST_DEVICE )

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

static void initTestBuffers( BYTE *buffer1, BYTE *buffer2, const int length )
	{
	/* Set the buffers to a known state */
	memset( buffer1, '*', length );
	memcpy( buffer1, "12345678", 8 );		/* For endianness check */
	memcpy( buffer2, buffer1, length );
	}

static BOOLEAN checkTestBuffers( const BYTE *buffer1, const BYTE *buffer2 )
	{
	/* Make sure 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 );
	}

/* Perform a test en/decryption */

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

	/* 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 );
			}

		return( CRYPT_OK );
		}
	if( cryptAlgo >= CRYPT_ALGO_FIRST_PKC && cryptAlgo <= CRYPT_ALGO_LAST_PKC )
		{
		static const BYTE rsa512Value[] = \
			"\x4E\x1F\x2F\x10\xA9\xFB\x4F\xD9\xC1\x25\x79\x7A\x36\x00\x58\xD0"
			"\x9E\x8B\x9F\xBA\xC7\x04\x10\x77\xDB\xBC\xC9\xD1\x70\xCD\xF6\x86"
			"\xA4\xDC\x39\xA9\x57\xD7\xC7\xE0\x87\xF2\x31\xDF\x83\x7d\x27\x0E"
			"\xB4\xA6\x93\x3D\x11\xEB\xA5\x0E\x42\x66\x7B\x30\x50\x84\xC1\x81";
		static const BYTE rsa1024Value[] = \
			"\x84\x8E\x00\x3E\x49\x11\x0D\x42\x4C\x71\x6B\xB4\xCF\x13\xDD\xCD"
			"\x12\x30\x56\xC2\x4A\x55\x3B\xD8\x30\xA2\xB8\x73\xA7\xAB\xF0\x7A"
			"\x2E\x07\x20\xCC\xBE\xEA\x58\x03\x56\xF6\x18\x27\x28\x4F\xE1\x02"
			"\xC6\x49\x79\x6C\xB4\x7E\x6C\xC6\x93\x2E\xF1\x46\x83\x15\x5A\xB7"
			"\x7D\xCC\x21\xEE\x4E\x3E\x0B\x8B\x85\xEE\x08\x21\xE6\xA7\x31\x53"
			"\x2E\x92\x3D\x2D\xB0\xD4\xA1\x30\xF4\xE9\xEB\x37\xBF\xCD\x2F\xE1"
			"\x60\x89\x19\xB6\x8C\x01\xFB\xD8\xAC\xF5\xC7\x4B\xB4\x74\x8A\x35"
			"\x79\xE6\xE0\x48\xBD\x9C\x9F\xD7\x4A\x1C\x8A\x58\xAB\xA9\x3C\x44";
		BYTE testBuffer[ TESTBUFFER_SIZE ], tmpBuffer[ 32 ];
		BOOLEAN encryptOK = TRUE;
		int length;

		/* Take a copy of the input so we can compare it with decrypted
		   output and find out how much data we need to process */
		memcpy( testBuffer, buffer, TESTBUFFER_SIZE );
		cryptGetAttribute( cryptContext, CRYPT_CTXINFO_KEYSIZE, &length );

		/* Since we're doing raw RSA encryption we need to format the data
		   specially to work with the RSA key being used.  If we're using the
		   cryptlib native routines, we need to ensure that the magnitude of 
		   the integer corresponding to the data to be encrypted is less than 
		   the modulus, which we do by setting the first byte of the buffer 
		   to 1.  If we're using a crypto device, we need to create a (dummy)
		   PKCS #1-like format since some devices expect to see PKCS #1-
		   formatted data as input to/output from the RSA encryption/
		   decryption operation */
		memcpy( tmpBuffer, buffer, 18 );
		if( isDevice )
			memcpy( buffer, "\x00\x02\xA5\xA5\xA5\xA5\xA5\xA5"
							"\xA5\xA5\xA5\xA5\xA5\xA5\xA5\xA5"
							"\xA5\x00", 18 );
		else
			buffer[ 0 ] = 1;

		/* Since the PKC algorithms only handle a single block, we only
		   perform a single encrypt and decrypt operation */
		status = cryptEncrypt( cryptContext, buffer, length );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't encrypt data, status = %d.\n", status );
			return( status );
			}
		if( cryptAlgo == CRYPT_ALGO_RSA && !isDevice && \
			memcmp( buffer, ( length == 64 ) ? rsa512Value : rsa1024Value, 
					length ) )
			{
			/* For a non-randomized PKC the encryption of the fixed value
			   produces known output, we make sure this matches the expected
			   value.  This makes diagnosing problems with crypto devices
			   rather easier */
			puts( "The actual encrypted value doesn't match the expected value." );
			encryptOK = FALSE;
			}
		status = cryptDecrypt( decryptContext, buffer, length );
		if( cryptStatusError( status ) )
			{
			if( encryptOK )
				printf( "Couldn't decrypt data even though the encrypted "
						"input data was valid,\nstatus = %d.\n", status );
			else
				printf( "Couldn't decrypt data, probably because the data "
						"produced by the encrypt step\nwas invalid, status = "
						"%d.\n", status );
			return( status );
			}
		if( isDevice )
			memcpy( buffer, tmpBuffer, 18 );
		else
			buffer[ 0 ] = tmpBuffer[ 0 ];

		/* Make sure the recovered result matches the input data */
		if( memcmp( buffer, testBuffer, length ) )
			{
			if( encryptOK )
				/* This could happen with simple-minded CRT implementations
				   which only work when p > q (the test key has p < q in
				   order to find this problem) */
				puts( "Decryption failed even though encryption produced "
					  "valid data.  The RSA\ndecryption step is broken." );
			else
				puts( "Decryption failed because the encryption step "
					  "produced invalid data. The RSA\nencryption step is "
					  "broken." );
			return( status );
			}
		else
			if( !encryptOK )
				{
				puts( "Decryption succeeded even though encryption produced "
					  "invalid data.  The RSA\nimplementation is broken." );
				return( status );
				}

		return( CRYPT_OK );
		}
	if( cryptAlgo >= CRYPT_ALGO_FIRST_HASH && \
		cryptAlgo <= CRYPT_ALGO_LAST_MAC )
		{
		/* Hash 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 hash data, status = %d.\n", status );
			return( status );
			}

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

		return( status );
		}

	printf( "Unknown encryption algorithm/mode %d.\n", cryptAlgo );
	return( CRYPT_OK );
	}

/* Load the encryption contexts */

static BOOLEAN loadContexts( CRYPT_CONTEXT *cryptContext, CRYPT_CONTEXT *decryptContext,
							 const CRYPT_DEVICE cryptDevice,
							 const CRYPT_ALGO cryptAlgo,
							 const CRYPT_MODE 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 */

⌨️ 快捷键说明

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