Beispiel #1
0
BOOLEAN sanityCheckCapability( const CAPABILITY_INFO *capabilityInfoPtr )
	{
	CRYPT_ALGO_TYPE cryptAlgo = capabilityInfoPtr->cryptAlgo;

	assert( isReadPtr( capabilityInfoPtr, sizeof( CAPABILITY_INFO ) ) );

	/* Check the algorithm and mode parameters.  We check for an algorithm
	   name one shorter than the maximum because as returned to an external
	   caller it's an ASCIZ string so we need to allow room for the
	   terminator */
	if( cryptAlgo <= CRYPT_ALGO_NONE || cryptAlgo >= CRYPT_ALGO_LAST )
		return( FALSE );
	if( capabilityInfoPtr->algoName == NULL || \
		capabilityInfoPtr->algoNameLen < 3 || \
		capabilityInfoPtr->algoNameLen > CRYPT_MAX_TEXTSIZE - 1 )
		return( FALSE );

	/* Make sure that the minimum functions are present.  We don't check for
	   the presence of the keygen function since the symmetric capabilities
	   use the generic keygen and the hash capabilities don't do keygen at 
	   all */
	if( capabilityInfoPtr->selfTestFunction == NULL || \
		capabilityInfoPtr->getInfoFunction == NULL )
		return( FALSE );
	if( !sanityCheckFunctionality( capabilityInfoPtr, cryptAlgo ) )
		return( FALSE );

	/* Make sure that the algorithm/mode-specific parameters are
	   consistent */
	if( capabilityInfoPtr->minKeySize > capabilityInfoPtr->keySize || \
		capabilityInfoPtr->maxKeySize < capabilityInfoPtr->keySize )
		return( FALSE );
	if( isConvAlgo( cryptAlgo ) )
		{
		if( ( capabilityInfoPtr->blockSize < bitsToBytes( 8 ) || \
        	  capabilityInfoPtr->blockSize > CRYPT_MAX_IVSIZE ) || \
			( capabilityInfoPtr->minKeySize < MIN_KEYSIZE || \
			  capabilityInfoPtr->maxKeySize > CRYPT_MAX_KEYSIZE ) )
			return( FALSE );
		if( capabilityInfoPtr->keySize > MAX_WORKING_KEYSIZE )
			return( FALSE );	/* Requirement for key wrap */
		if( capabilityInfoPtr->initParamsFunction == NULL || \
			capabilityInfoPtr->initKeyFunction == NULL )
			return( FALSE );
		if( !isStreamCipher( cryptAlgo ) && \
			 capabilityInfoPtr->blockSize < bitsToBytes( 64 ) )
			return( FALSE );

		return( TRUE );
		}

	/* Check any remaining algorithm types */
	if( isPkcAlgo( cryptAlgo ) )
		{
		const int minKeySize = isEccAlgo( cryptAlgo ) ? \
							   MIN_PKCSIZE_ECC : MIN_PKCSIZE;

		if( capabilityInfoPtr->blockSize != 0 || \
			( capabilityInfoPtr->minKeySize < minKeySize || \
			  capabilityInfoPtr->maxKeySize > CRYPT_MAX_PKCSIZE ) )
			return( FALSE );
		if( capabilityInfoPtr->initKeyFunction == NULL || \
			capabilityInfoPtr->generateKeyFunction == NULL )
			return( FALSE );

		return( TRUE );
		}
	if( isHashAlgo( cryptAlgo ) )
		{
		if( ( capabilityInfoPtr->blockSize < bitsToBytes( 128 ) || \
			  capabilityInfoPtr->blockSize > CRYPT_MAX_HASHSIZE ) || \
			( capabilityInfoPtr->minKeySize != 0 || \
			  capabilityInfoPtr->keySize != 0 || \
			  capabilityInfoPtr->maxKeySize != 0 ) )
			return( FALSE );

		return( TRUE );
		}
	if( isMacAlgo( cryptAlgo ) )
		{
		if( ( capabilityInfoPtr->blockSize < bitsToBytes( 128 ) || \
			  capabilityInfoPtr->blockSize > CRYPT_MAX_HASHSIZE ) || \
			( capabilityInfoPtr->minKeySize < MIN_KEYSIZE || \
			  capabilityInfoPtr->maxKeySize > CRYPT_MAX_KEYSIZE ) )
			return( FALSE );
		if( capabilityInfoPtr->keySize > MAX_WORKING_KEYSIZE )
			return( FALSE );	/* Requirement for key wrap */
		if( capabilityInfoPtr->initKeyFunction == NULL )
			return( FALSE );

		return( TRUE );
		}
	if( isSpecialAlgo( cryptAlgo ) )
		{
		if( capabilityInfoPtr->blockSize != 0 || \
			capabilityInfoPtr->minKeySize < bitsToBytes( 128 ) || \
			capabilityInfoPtr->maxKeySize > CRYPT_MAX_KEYSIZE )
			return( FALSE );
		if( capabilityInfoPtr->initKeyFunction == NULL )
			return( FALSE );

		return( TRUE );
		}

	retIntError_Boolean();
	}
Beispiel #2
0
static BOOLEAN sanityCheckFunctionality( const CAPABILITY_INFO *capabilityInfoPtr,
										 IN_ALGO CRYPT_ALGO_TYPE cryptAlgo )
	{
	const BOOLEAN isCrypt = \
		( capabilityInfoPtr->encryptCBCFunction != NULL || \
		  capabilityInfoPtr->decryptCBCFunction != NULL || \
		  capabilityInfoPtr->encryptCFBFunction != NULL || \
		  capabilityInfoPtr->decryptCFBFunction != NULL || \
		  capabilityInfoPtr->encryptGCMFunction != NULL || \
		  capabilityInfoPtr->decryptGCMFunction != NULL ) ? TRUE : FALSE;
	const BOOLEAN isSig = \
		( capabilityInfoPtr->signFunction != NULL || \
		  capabilityInfoPtr->sigCheckFunction != NULL ) ? TRUE : FALSE;

	assert( isReadPtr( capabilityInfoPtr, sizeof( CAPABILITY_INFO ) ) );

	REQUIRES( cryptAlgo > CRYPT_ALGO_NONE && cryptAlgo < CRYPT_ALGO_LAST );

	/* Generic-secret algorithms are non-capabilities used to to store
	   keying data, but that can't perform any operations themselves */
	if( isSpecialAlgo( cryptAlgo ) )
		{
		if( capabilityInfoPtr->encryptFunction != NULL || \
			capabilityInfoPtr->decryptFunction != NULL || \
			isCrypt || isSig )
			return( FALSE );

		return( TRUE );
		}

	/* We need at least one mechanism pair to be able to do anything useful 
	   with the capability */
	if( ( capabilityInfoPtr->encryptFunction == NULL || \
		  capabilityInfoPtr->decryptFunction == NULL ) && \
		( capabilityInfoPtr->encryptCBCFunction == NULL || \
		  capabilityInfoPtr->decryptCBCFunction == NULL ) && \
		( capabilityInfoPtr->encryptCFBFunction == NULL || \
		  capabilityInfoPtr->decryptCFBFunction == NULL ) && \
		( capabilityInfoPtr->encryptGCMFunction == NULL || \
		  capabilityInfoPtr->decryptGCMFunction == NULL ) && \
		( capabilityInfoPtr->signFunction == NULL || \
		  capabilityInfoPtr->sigCheckFunction == NULL ) )
		return( FALSE );

	/* Perform algorithm class-specific checks */
	if( isConvAlgo( cryptAlgo ) )
		{
		if( isSig )
			return( FALSE );
		if( isStreamCipher( cryptAlgo ) )
			{
			if( capabilityInfoPtr->encryptCFBFunction == NULL || \
				capabilityInfoPtr->decryptCFBFunction == NULL )
				return( FALSE );
			if( capabilityInfoPtr->encryptFunction != NULL || \
				capabilityInfoPtr->decryptFunction != NULL || \
				capabilityInfoPtr->encryptCBCFunction != NULL || \
				capabilityInfoPtr->decryptCBCFunction != NULL || \
				capabilityInfoPtr->encryptCFBFunction != NULL || \
				capabilityInfoPtr->decryptCFBFunction != NULL || \
				capabilityInfoPtr->encryptGCMFunction != NULL || \
				capabilityInfoPtr->decryptGCMFunction != NULL )
				return( FALSE );
			}
		else
			{
			if( capabilityInfoPtr->encryptFunction == NULL && \
				capabilityInfoPtr->decryptFunction == NULL && \
				!isCrypt )
				return( FALSE );
			}
		if( ( capabilityInfoPtr->encryptCBCFunction != NULL && \
			  capabilityInfoPtr->decryptCBCFunction == NULL ) || \
			( capabilityInfoPtr->encryptCBCFunction == NULL && \
			  capabilityInfoPtr->decryptCBCFunction != NULL ) )
			return( FALSE );
		if( ( capabilityInfoPtr->encryptCFBFunction != NULL && \
			  capabilityInfoPtr->decryptCFBFunction == NULL ) || \
			( capabilityInfoPtr->encryptCFBFunction == NULL && \
			  capabilityInfoPtr->decryptCFBFunction != NULL ) )
			return( FALSE );
		if( ( capabilityInfoPtr->encryptGCMFunction != NULL && \
			  capabilityInfoPtr->decryptGCMFunction == NULL ) || \
			( capabilityInfoPtr->encryptGCMFunction == NULL && \
			  capabilityInfoPtr->decryptGCMFunction != NULL ) )
			return( FALSE );
		
		return( TRUE );
		}
	if( isPkcAlgo( cryptAlgo ) )
		{
		if( capabilityInfoPtr->encryptFunction == NULL && \
			capabilityInfoPtr->decryptFunction == NULL && \
			capabilityInfoPtr->signFunction == NULL && \
			capabilityInfoPtr->sigCheckFunction == NULL )
			return( FALSE );
		if( isCrypt )
			return( FALSE );

		return( TRUE );
		}
	if( isHashAlgo( cryptAlgo ) || isMacAlgo( cryptAlgo ) )
		{
		if( capabilityInfoPtr->encryptFunction == NULL || \
			capabilityInfoPtr->decryptFunction == NULL )
			return( FALSE );
		if( isCrypt || isSig )
			return( FALSE );

		return( TRUE );
		}

	retIntError_Boolean();
	}
Beispiel #3
0
BOOLEAN sanityCheckCapability( const CAPABILITY_INFO *capabilityInfoPtr,
							   const BOOLEAN asymmetricOK )
	{
	CRYPT_ALGO_TYPE cryptAlgo = capabilityInfoPtr->cryptAlgo;

	assert( isReadPtr( capabilityInfoPtr, sizeof( CAPABILITY_INFO ) ) );

	/* Check the algorithm and mode parameters.  We check for an algorithm
	   name one shorter than the maximum because as returned to an external
	   caller it's an ASCIZ string so we need to allow room for the
	   terminator */
	if( cryptAlgo <= CRYPT_ALGO_NONE || cryptAlgo >= CRYPT_ALGO_LAST || \
		capabilityInfoPtr->algoName == NULL || \
		capabilityInfoPtr->algoNameLen < 3 || \
		capabilityInfoPtr->algoNameLen > CRYPT_MAX_TEXTSIZE - 1 )
		return( FALSE );

	/* Make sure that the minimum functions are present.  We don't check for
	   the presence of the keygen function since the symmetric capabilities
	   use the generic keygen and the hash capabilities don't do keygen at 
	   all */
	if( capabilityInfoPtr->selfTestFunction == NULL || \
		capabilityInfoPtr->getInfoFunction == NULL )
		return( FALSE );
	if( isStreamCipher( cryptAlgo ) )
		{
		if( capabilityInfoPtr->encryptOFBFunction == NULL || \
			capabilityInfoPtr->decryptOFBFunction == NULL )
			return( FALSE );
		}
	else
		{
		if( asymmetricOK )
			{
			/* If asymmetric capabilities (e.g. decrypt but not encrypt,
			   present in some tinkertoy tokens) are permitted then we only 
			   check that there's at least one useful capability available */
			if( capabilityInfoPtr->decryptFunction == NULL && \
				capabilityInfoPtr->signFunction == NULL )
				return( FALSE );
			}
		else
			{
			if( !isSpecialAlgo( cryptAlgo ) )
				{
				/* We need at least one mechanism pair to be able to do 
				   anything useful with the capability */
				if( ( capabilityInfoPtr->encryptFunction == NULL || \
					  capabilityInfoPtr->decryptFunction == NULL ) && \
					( capabilityInfoPtr->encryptCBCFunction == NULL || \
					  capabilityInfoPtr->decryptCBCFunction == NULL ) && \
					( capabilityInfoPtr->encryptCFBFunction == NULL || \
					  capabilityInfoPtr->decryptCFBFunction == NULL ) && \
					( capabilityInfoPtr->encryptOFBFunction == NULL || \
					  capabilityInfoPtr->decryptOFBFunction == NULL ) && \
					( capabilityInfoPtr->encryptGCMFunction == NULL || \
					  capabilityInfoPtr->decryptGCMFunction == NULL ) && \
					( capabilityInfoPtr->signFunction == NULL || \
					  capabilityInfoPtr->sigCheckFunction == NULL ) )
					return( FALSE );
				}
			}
		}

	/* Make sure that the algorithm/mode-specific parameters are
	   consistent */
	if( capabilityInfoPtr->minKeySize > capabilityInfoPtr->keySize || \
		capabilityInfoPtr->maxKeySize < capabilityInfoPtr->keySize )
		return( FALSE );
	if( isConvAlgo( cryptAlgo ) )
		{
		if( ( capabilityInfoPtr->blockSize < bitsToBytes( 8 ) || \
        	  capabilityInfoPtr->blockSize > CRYPT_MAX_IVSIZE ) || \
			( capabilityInfoPtr->minKeySize < MIN_KEYSIZE || \
			  capabilityInfoPtr->maxKeySize > CRYPT_MAX_KEYSIZE ) )
			return( FALSE );
		if( capabilityInfoPtr->keySize > MAX_WORKING_KEYSIZE )
			return( FALSE );	/* Requirement for key wrap */
		if( capabilityInfoPtr->initParamsFunction == NULL || \
			capabilityInfoPtr->initKeyFunction == NULL )
			return( FALSE );
		if( !isStreamCipher( cryptAlgo ) && \
			 capabilityInfoPtr->blockSize < bitsToBytes( 64 ) )
			return( FALSE );
		if( ( capabilityInfoPtr->encryptCBCFunction != NULL && \
			  capabilityInfoPtr->decryptCBCFunction == NULL ) || \
			( capabilityInfoPtr->encryptCBCFunction == NULL && \
			  capabilityInfoPtr->decryptCBCFunction != NULL ) )
			return( FALSE );
		if( ( capabilityInfoPtr->encryptCFBFunction != NULL && \
			  capabilityInfoPtr->decryptCFBFunction == NULL ) || \
			( capabilityInfoPtr->encryptCFBFunction == NULL && \
			  capabilityInfoPtr->decryptCFBFunction != NULL ) )
			return( FALSE );
		if( ( capabilityInfoPtr->encryptOFBFunction != NULL && \
			  capabilityInfoPtr->decryptOFBFunction == NULL ) || \
			( capabilityInfoPtr->encryptOFBFunction == NULL && \
			  capabilityInfoPtr->decryptOFBFunction != NULL ) )
			return( FALSE );
		if( ( capabilityInfoPtr->encryptGCMFunction != NULL && \
			  capabilityInfoPtr->decryptGCMFunction == NULL ) || \
			( capabilityInfoPtr->encryptGCMFunction == NULL && \
			  capabilityInfoPtr->decryptGCMFunction != NULL ) )
			return( FALSE );

		return( TRUE );
		}

	/* We've checked the conventional algorithms, beyond this point there
	   shouldn't be any conventional encryption modes present */
	if( capabilityInfoPtr->encryptCBCFunction != NULL || \
		capabilityInfoPtr->decryptCBCFunction != NULL || \
		capabilityInfoPtr->encryptCFBFunction != NULL || \
		capabilityInfoPtr->decryptCFBFunction != NULL || \
		capabilityInfoPtr->encryptOFBFunction != NULL || \
		capabilityInfoPtr->decryptOFBFunction != NULL || \
		capabilityInfoPtr->encryptGCMFunction != NULL || \
		capabilityInfoPtr->decryptGCMFunction != NULL )
		return( FALSE );

	/* Check any remaining algorithm types */
	if( isPkcAlgo( cryptAlgo ) )
		{
		const int minKeySize = isEccAlgo( cryptAlgo ) ? \
							   MIN_PKCSIZE_ECC : MIN_PKCSIZE;

		if( capabilityInfoPtr->blockSize != 0 || \
			( capabilityInfoPtr->minKeySize < minKeySize || \
			  capabilityInfoPtr->maxKeySize > CRYPT_MAX_PKCSIZE ) )
			return( FALSE );
		if( capabilityInfoPtr->initKeyFunction == NULL || \
			capabilityInfoPtr->generateKeyFunction == NULL )
			return( FALSE );

		return( TRUE );
		}
	if( isHashAlgo( cryptAlgo ) )
		{
		if( ( capabilityInfoPtr->blockSize < bitsToBytes( 128 ) || \
			  capabilityInfoPtr->blockSize > CRYPT_MAX_HASHSIZE ) || \
			( capabilityInfoPtr->minKeySize != 0 || \
			  capabilityInfoPtr->keySize != 0 || \
			  capabilityInfoPtr->maxKeySize != 0 ) )
			return( FALSE );

		return( TRUE );
		}
	if( isMacAlgo( cryptAlgo ) )
		{
		if( ( capabilityInfoPtr->blockSize < bitsToBytes( 128 ) || \
			  capabilityInfoPtr->blockSize > CRYPT_MAX_HASHSIZE ) || \
			( capabilityInfoPtr->minKeySize < MIN_KEYSIZE || \
			  capabilityInfoPtr->maxKeySize > CRYPT_MAX_KEYSIZE ) )
			return( FALSE );
		if( capabilityInfoPtr->keySize > MAX_WORKING_KEYSIZE )
			return( FALSE );	/* Requirement for key wrap */
		if( capabilityInfoPtr->initKeyFunction == NULL )
			return( FALSE );

		return( TRUE );
		}
	if( isSpecialAlgo( cryptAlgo ) )
		{
		if( capabilityInfoPtr->blockSize != 0 || \
			capabilityInfoPtr->minKeySize < bitsToBytes( 128 ) || \
			capabilityInfoPtr->maxKeySize > CRYPT_MAX_KEYSIZE )
			return( FALSE );
		if( capabilityInfoPtr->encryptFunction != NULL || \
			capabilityInfoPtr->decryptFunction != NULL )
			return( FALSE );
		if( capabilityInfoPtr->initKeyFunction == NULL )
			return( FALSE );

		return( TRUE );
		}

	retIntError_Boolean();
	}