📄 stress.c
字号:
if( cryptStatusError( status ) )
{
printf( "\nAlgorithm %d CBC mode processing failed with "
"status %d.\n", cryptAlgo, status );
errorCount++;
}
status = testProcessing( cryptAlgo, CRYPT_MODE_CFB,
cryptQueryInfo );
if( cryptStatusError( status ) )
{
printf( "\nAlgorithm %d CFB mode processing failed with "
"status %d.\n", cryptAlgo, status );
errorCount++;
}
}
status = testProcessing( cryptAlgo, CRYPT_MODE_OFB,
cryptQueryInfo );
if( cryptStatusError( status ) )
{
printf( "\nAlgorithm %d OFB mode processing failed with "
"status %d.\n", cryptAlgo, status );
errorCount++;
}
}
for( cryptAlgo = CRYPT_ALGO_FIRST_HASH;
cryptAlgo <= CRYPT_ALGO_LAST_HASH; cryptAlgo++ )
if( cryptStatusOK( cryptQueryCapability( cryptAlgo, &cryptQueryInfo ) ) )
{
status = testProcessing( cryptAlgo, CRYPT_UNUSED,
cryptQueryInfo );
if( cryptStatusError( status ) )
{
printf( "\nAlgorithm %d processing failed with status %d.\n",
cryptAlgo, status );
errorCount++;
}
}
for( cryptAlgo = CRYPT_ALGO_FIRST_MAC;
cryptAlgo <= CRYPT_ALGO_LAST_MAC; cryptAlgo++ )
if( cryptStatusOK( cryptQueryCapability( cryptAlgo, &cryptQueryInfo ) ) )
{
status = testProcessing( cryptAlgo, CRYPT_UNUSED,
cryptQueryInfo );
if( cryptStatusError( status ) )
{
printf( "\nAlgorithm %d processing failed with status %d.\n",
cryptAlgo, status );
errorCount++;
}
}
if( errorCount )
printf( "%d errors detected.\n", errorCount );
}
/****************************************************************************
* *
* Kernel Check Test *
* *
****************************************************************************/
/* Kernel check test */
static void smokeTestAttributes( const CRYPT_HANDLE cryptHandle )
{
int attribute;
printf( "." );
for( attribute = CRYPT_ATTRIBUTE_NONE; attribute < 8000; attribute++ )
{
char buffer[ 1024 ];
int value;
cryptGetAttribute( cryptHandle, attribute, &value );
cryptGetAttributeString( cryptHandle, attribute, buffer, &value );
}
cryptDestroyObject( cryptHandle );
}
static void testKernelChecks( void )
{
CRYPT_HANDLE cryptHandle;
int subType;
printf( "Running kernel smoke test:\n Contexts" );
for( subType = 0; subType < 500; subType++ )
if( cryptStatusOK( cryptCreateContext( &cryptHandle, CRYPT_UNUSED,
subType ) ) )
smokeTestAttributes( cryptHandle );
printf( "\n Certs" );
for( subType = 0; subType < 500; subType++ )
if( cryptStatusOK( cryptCreateCert( &cryptHandle, CRYPT_UNUSED,
subType ) ) )
smokeTestAttributes( cryptHandle );
printf( "\n Envelopes" );
for( subType = 0; subType < 500; subType++ )
if( cryptStatusOK( cryptCreateEnvelope( &cryptHandle, CRYPT_UNUSED,
subType ) ) )
smokeTestAttributes( cryptHandle );
printf( "\n Sessions" );
for( subType = 0; subType < 500; subType++ )
if( cryptStatusOK( cryptCreateSession( &cryptHandle, CRYPT_UNUSED,
subType ) ) )
smokeTestAttributes( cryptHandle );
printf( "\n" );
}
/****************************************************************************
* *
* Threading Stress Test *
* *
****************************************************************************/
/* Multi-threaded processing stress test. In order to add a little
nondeterminism on single-threaded machines, we need to add some sleep()
calls between crypto operations. Even this isn't perfect, there's no
real way to guarantee that they aren't simply executed in round-robin
fashion with only one thread in the kernel at a time without modifying
the kernel to provide diagnostic info */
#ifdef WINDOWS_THREADS
#define NO_THREADS 45
static void randSleep( void )
{
Sleep( ( rand() % 150 ) + 1 );
}
unsigned __stdcall processDataThread( void *arg )
{
CRYPT_CONTEXT cryptContext;
BYTE buffer[ 1024 ];
int threadNo = ( int ) arg;
int status;
randSleep();
memset( buffer, '*', 1024 );
status = cryptCreateContext( &cryptContext, CRYPT_UNUSED,
CRYPT_ALGO_3DES );
if( cryptStatusOK( status ) )
{
randSleep();
status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEY,
"123456781234567812345678", 24 );
}
if( cryptStatusOK( status ) )
{
randSleep();
status = cryptEncrypt( cryptContext, buffer, 1024 );
}
if( cryptStatusOK( status ) )
{
randSleep();
status = cryptEncrypt( cryptContext, buffer, 0 );
}
if( cryptStatusOK( status ) )
{
randSleep();
status = cryptDestroyContext( cryptContext );
}
if( cryptStatusError( status ) )
printf( "\nEncryption failed with status %d.\n", status );
else
printf( "%d ", threadNo );
_endthreadex( 0 );
return( 0 );
}
static void testStressThreads( void )
{
HANDLE hThreadArray[ NO_THREADS ];
int i;
/* Start the threads */
for( i = 0; i < NO_THREADS; i++ )
{
unsigned threadID;
hThreadArray[ i ] = ( HANDLE ) \
_beginthreadex( NULL, 0, &processDataThread, ( void * ) i, 0,
&threadID );
if( hThreadArray[ i ] == 0 )
printf( "Thread %d couldn't be created.\n", i );
}
printf( "Threads completed: " );
/* Wait for all the threads to complete */
if( WaitForMultipleObjects( NO_THREADS, hThreadArray, TRUE,
15000 ) == WAIT_TIMEOUT )
puts( "\nNot all threads completed in 15s." );
else
puts( "." );
for( i = 0; i < NO_THREADS; i++ )
CloseHandle( hThreadArray[ i ] );
}
#endif /* WINDOWS_THREADS */
#if defined( UNIX_THREADS ) || defined( WINDOWS_THREADS )
#ifdef UNIX_THREADS
void *envelopeDataThread( void *arg )
#else
unsigned __stdcall envelopeDataThread( void *arg )
#endif /* Different threading models */
{
static const char *envData = "qwertyuiopasdfghjklzxcvbnm";
BYTE fileBuffer[ BUFFER_SIZE ];
const unsigned uThread = ( unsigned ) arg;
const time_t startTime = time( NULL );
int count, status;
printf( "Thread %d started.\n", uThread );
fflush( stdout );
filenameFromTemplate( fileBuffer, CERT_FILE_TEMPLATE, 13 );
for( count = 0; count < 150; count++ )
{
CRYPT_ENVELOPE cryptEnvelope;
CRYPT_CERTIFICATE cryptCert;
BYTE envBuffer[ BUFFER_SIZE ];
int bytesCopied;
/* Create the cert and envelope and add the cert to the envelope */
status = importCertFile( &cryptCert, fileBuffer );
if( cryptStatusOK( status ) )
status = cryptCreateEnvelope( &cryptEnvelope, CRYPT_UNUSED,
CRYPT_FORMAT_CRYPTLIB );
if( cryptStatusOK( status ) )
status = cryptSetAttribute( cryptEnvelope,
CRYPT_ENVINFO_PUBLICKEY, cryptCert );
if( cryptStatusError( status ) )
break;
/* Envelope data and destroy the envelope */
status = cryptPushData( cryptEnvelope, envData, strlen( envData ),
&bytesCopied );
if( cryptStatusOK( status ) )
status = cryptPushData( cryptEnvelope, NULL, 0, NULL );
if( cryptStatusOK( status ) )
status = cryptPopData( cryptEnvelope, envBuffer, BUFFER_SIZE,
&bytesCopied );
if( cryptStatusOK( status ) )
status = cryptDestroyEnvelope( cryptEnvelope );
if( cryptStatusError( status ) )
break;
printf( "%c", uThread + '0' );
}
printf( "Thread %u exited after %d seconds.\n", uThread,
time( NULL ) - startTime );
fflush( stdout );
#ifdef UNIX_THREADS
pthread_exit( NULL );
#else
_endthreadex( 0 );
#endif /* Different threading models */
return( 0 );
}
static void testContinuousThreads( void )
{
unsigned threadID1, threadID2;
#ifdef UNIX_THREADS
pthread_t thread1, thread2;
#else
HANDLE hThread1, hThread2;
#endif /* Different threading models */
cryptAddRandom( "xyzzy", 5 );
#ifdef UNIX_THREADS
pthread_create( &thread1, NULL, envelopeDataThread, ( void * ) 1 );
pthread_create( &thread2, NULL, envelopeDataThread, ( void * ) 2 );
#else
hThread1 = ( HANDLE ) _beginthreadex( NULL, 0, envelopeDataThread,
( void * ) 1, 0, &threadID1 );
hThread2 = ( HANDLE ) _beginthreadex( NULL, 0, envelopeDataThread,
( void * ) 2, 0, &threadID2 );
#endif /* Different threading models */
delayThread( 30 );
printf( "Hit a key..." );
fflush( stdout );
getchar();
cryptEnd();
exit( EXIT_SUCCESS );
}
#endif /* UNIX_THREADS || WINDOWS_THREADS */
/****************************************************************************
* *
* Test Interface *
* *
****************************************************************************/
void smokeTest( void )
{
testDataProcessing();
testKernelChecks();
testStressObjects();
#if defined( UNIX_THREADS ) || defined( WINDOWS_THREADS )
testStressThreads();
#endif /* UNIX_THREADS || WINDOWS_THREADS */
}
#endif /* SMOKE_TEST */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -