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

📄 testll.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 2 页
字号:
				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 );
	}

/* Check for an algorithm/mode */

static BOOLEAN checkLowlevelInfo( const CRYPT_DEVICE cryptDevice,
								  const CRYPT_ALGO 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,
			bytesToBits( cryptQueryInfo.blockSize ) );
	if( cryptAlgo < CRYPT_ALGO_FIRST_HASH || cryptAlgo > CRYPT_ALGO_LAST_HASH )
		{
		printf( ", keysize %d-%d bits (recommended = %d bits)",
				bytesToBits( cryptQueryInfo.minKeySize ),
				bytesToBits( cryptQueryInfo.maxKeySize ),
				bytesToBits( cryptQueryInfo.keySize ) );
		}
	puts( "." );

	return( TRUE );
	}

/* Test an algorithm/mode implementation */

int testLowlevel( const CRYPT_DEVICE cryptDevice, const CRYPT_ALGO cryptAlgo,
				  const BOOLEAN checkOnly )
	{
	CRYPT_MODE cryptMode = CRYPT_MODE_ECB;
	CRYPT_CONTEXT cryptContext, decryptContext;
	BYTE buffer[ TESTBUFFER_SIZE ], testBuffer[ TESTBUFFER_SIZE ];
	const BOOLEAN isDevice = ( cryptDevice != CRYPT_UNUSED ) ? TRUE : FALSE;
	BOOLEAN modesTested[ 8 ] = { 0 }, testSucceeded = FALSE;
	int status;

	/* Initialise the test buffers */
	initTestBuffers( buffer, testBuffer, TESTBUFFER_SIZE );

	/* Check cryptlib's capabilities */
	if( !checkLowlevelInfo( cryptDevice, cryptAlgo ) )
		return( FALSE );

	/* If we're only doing a capability check, don't try anything else */
	if( checkOnly )
		return( TRUE );

	/* Since DH and KEA only perform key agreement rather than a true key
	   exchange, we can't test their encryption capabilities */
	if( cryptAlgo == CRYPT_ALGO_DH || cryptAlgo == CRYPT_ALGO_KEA )
		return( TRUE );

	do
		{
		/* Set up an encryption context, load a user key into it, and
		   perform a key setup */
		switch( cryptAlgo )
			{
			case CRYPT_ALGO_DES:
				status = loadContexts( &cryptContext, &decryptContext,
									   cryptDevice, cryptAlgo, cryptMode,
									   ( BYTE * ) "12345678", 8 );
				break;

			case CRYPT_ALGO_SKIPJACK:
				status = loadContexts( &cryptContext, &decryptContext,
									   cryptDevice, cryptAlgo, cryptMode,
									   ( BYTE * ) "1234567890", 10 );
				break;

			case CRYPT_ALGO_CAST:
			case CRYPT_ALGO_IDEA:
			case CRYPT_ALGO_AES:
				status = loadContexts( &cryptContext, &decryptContext,
									   cryptDevice, cryptAlgo, cryptMode,
									   ( BYTE * ) "1234567887654321", 16 );
				break;

			case CRYPT_ALGO_3DES:
				status = loadContexts( &cryptContext, &decryptContext,
									   cryptDevice, cryptAlgo, cryptMode,
									   ( BYTE * ) "123456788765432112345678", 24 );
				break;

			case CRYPT_ALGO_RC2:
			case CRYPT_ALGO_RC4:
			case CRYPT_ALGO_RC5:
			case CRYPT_ALGO_BLOWFISH:
			case CRYPT_ALGO_HMAC_MD5:
			case CRYPT_ALGO_HMAC_SHA:
			case CRYPT_ALGO_HMAC_RIPEMD160:
				status = loadContexts( &cryptContext, &decryptContext,
									   cryptDevice, cryptAlgo, cryptMode,
									   ( BYTE * ) "1234567890098765432112345678900987654321", 40 );
				break;

			case CRYPT_ALGO_MD2:
			case CRYPT_ALGO_MD4:
			case CRYPT_ALGO_MD5:
			case CRYPT_ALGO_SHA:
			case CRYPT_ALGO_RIPEMD160:
				status = loadContexts( &cryptContext, &decryptContext,
									   cryptDevice, cryptAlgo, CRYPT_MODE_NONE,
									   ( BYTE * ) "", 0 );
				break;

			case CRYPT_ALGO_RSA:
				status = loadRSAContexts( cryptDevice, &cryptContext,
										  &decryptContext );
				break;

			case CRYPT_ALGO_DSA:
				status = loadDSAContexts( cryptDevice, &cryptContext,
										  &decryptContext );
				break;

			case CRYPT_ALGO_ELGAMAL:
				status = loadElgamalContexts( &cryptContext, &decryptContext );
				break;

			default:
				printf( "Unknown encryption algorithm ID %d, cannot perform "
						"encryption test\n", cryptAlgo );
				return( FALSE );
			}
		if( status == CRYPT_ERROR_NOTAVAIL )
			{
			/* It's a conventional algorithm for which this mode isn't
			   available, try a different mode */
			cryptMode++;
			continue;
			}
		if( !status )
			return( FALSE );

		/* DLP-based algorithms can't be called directly from user code 
		   because of the special data-formatting requirements */
		if( cryptAlgo == CRYPT_ALGO_DSA || cryptAlgo == CRYPT_ALGO_ELGAMAL )
			{
			destroyContexts( cryptDevice, cryptContext, decryptContext );
			return( TRUE );
			}

		/* Perform a test en/decryption */
		status = testCrypt( cryptContext, decryptContext, buffer, isDevice );
		if( cryptStatusError( status ) )
			if( isDevice && status == CRYPT_ERROR_NOTAVAIL )
				{
				/* Some primitive tokens or accelerators support only the
				   barest minimum of functionality, which may include being
				   able to create objects but not use them (eg public key
				   objects in a device which is just an RSA private-key 
				   modexp engine).  Because of this we may get a 
				   CRYPT_ERROR_NOTAVAIL when we try and perform a low-level 
				   crypto test, this isn't normally a problem for cryptlib
				   high-level objects because public-key ops are always done
				   in software, but when we explicitly try to do them in the
				   token it's a problem.  Because of this we report a problem
				   but continue anyway */
				puts( "The crypto device reported that this operation isn't "
					  "available even though it\nsupports the use of "
					  "encryption objects which implement this algorithm.  "
					  "This\nis probably a bare-bones device which only "
					  "supports minimal functionality (eg\nprivate-key "
					  "decryption but not encryption)." );
				destroyContexts( cryptDevice, cryptContext, decryptContext );
				continue;
				}
			else
				return( FALSE );

		/* Make sure everything went OK */
		if( cryptAlgo >= CRYPT_ALGO_FIRST_HASH )
			{
			BYTE hash1[ CRYPT_MAX_HASHSIZE ], hash2[ CRYPT_MAX_HASHSIZE ];
			int length1, length2;

			status = cryptGetAttributeString( cryptContext, CRYPT_CTXINFO_HASHVALUE,
											  hash1, &length1 );
			cryptGetAttributeString( decryptContext, CRYPT_CTXINFO_HASHVALUE,
									 hash2, &length2 );
			if( cryptStatusError( status ) )
				{
				printf( "Couldn't get hash information, status = %d.\n", status );
				return( FALSE );
				}
			if( ( length1 != length2 ) || memcmp( hash1, hash2, length1 ) )
				{
				puts( "Error: Hash value of identical buffers differs." );
				return( FALSE );
				}
			if( !memcmp( hash1, "\x00\x00\x00\x00\x00\x00\x00\x00", 8 ) || \
				!memcmp( hash2, "\x00\x00\x00\x00\x00\x00\x00\x00", 8 ) )
				{
				puts( "Error: Hash contains all zeroes." );
				return( FALSE );
				}

			/* Make sure we can get repeatable results after deleting the 
			   hash/MAC and rehashing the data */
			status = cryptDeleteAttribute( cryptContext, 
										   CRYPT_CTXINFO_HASHVALUE );
			if( cryptStatusOK( status ) )
				status = cryptDeleteAttribute( decryptContext, 
											   CRYPT_CTXINFO_HASHVALUE );
			if( cryptStatusError( status ) )
				{
				printf( "Deletion of hash/MAC value failed with status %d.\n",
						status );
				return( FALSE );
				}
			if( cryptStatusError( testCrypt( cryptContext, decryptContext, 
											 buffer, isDevice ) ) )
				return( FALSE );
			status = cryptGetAttributeString( cryptContext, CRYPT_CTXINFO_HASHVALUE,
											  hash1, &length1 );
			if( cryptStatusError( status ) )
				{
				printf( "Couldn't get hash information for re-hashed data, "
						"status = %d.\n", status );
				return( FALSE );
				}
			if( ( length1 != length2 ) || memcmp( hash1, hash2, length1 ) )
				{
				puts( "Error: Hash value of re-hashed data differs." );
				return( FALSE );
				}
			}
		else
			/* If it's a PKC we'll have performed the check during the
			   encrypt/decrypt step */
			if( cryptAlgo < CRYPT_ALGO_FIRST_PKC && \
				!checkTestBuffers( buffer, testBuffer ) )
				return( FALSE );

		/* Remember that at least one test succeeded */
		testSucceeded = TRUE;
		if( cryptAlgo < CRYPT_ALGO_LAST_CONVENTIONAL )
			modesTested[ cryptMode++ ] = TRUE;

		/* Clean up */
		destroyContexts( cryptDevice, cryptContext, decryptContext );
		}
	while( cryptAlgo < CRYPT_ALGO_LAST_CONVENTIONAL && \
		   cryptMode < CRYPT_MODE_LAST );

	/* If it's a conventional algorithm, report the encryption modes which
	   were tested */
	if( cryptAlgo < CRYPT_ALGO_LAST_CONVENTIONAL )
		{
		printf( "  Encryption modes tested:" );
		if( modesTested[ CRYPT_MODE_ECB ] )
			printf( " ECB" );
		if( modesTested[ CRYPT_MODE_CBC ] )
			printf( " CBC" );
		if( modesTested[ CRYPT_MODE_CFB ] )
			printf( " CFB" );
		if( modesTested[ CRYPT_MODE_OFB ] )
			printf( " OFB" );
		puts( "." );
		}

	/* Make sure at least one of the algorithm's modes was tested */
	if( !testSucceeded )
		{
		puts( "No processing modes were found for this algorithm.\n" );
		return( FALSE );
		}

	return( TRUE );
	}
#endif /* TEST_LOWLEVEL || TEST_DEVICE */

⌨️ 快捷键说明

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