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

📄 pgpcfb.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	pgpCipherFeedback.c
	
	Copyright (C) 1997 Network Associates Inc. and affiliated companies.
	All rights reserved.

	$Id: pgpCFB.c,v 1.23 1999/03/10 02:47:11 heller Exp $
____________________________________________________________________________*/
#include "pgpConfig.h"
#include <string.h>

#include "pgpSDKBuildFlags.h"
#include "pgpMem.h"
#include "pgpErrors.h"
#include "pgpContext.h"
#include "pgpSymmetricCipherPriv.h"
#include "pgpCFBPriv.h"
#include "pgpUtilitiesPriv.h"



#define PGPValidateCFB( cfb )	\
	PGPValidateParam( pgpCFBIsValid( cfb ) );
	
/*____________________________________________________________________________
	Some stuff does double duty for CFB encryption/decryption,
	and for X9.17 random number generation.
	
	For random number generate, it is illegal to attempt to use
	an interleaved CFB.

	When used for CFB, iv[] is used as a circular buffer.  bufLeft is
	the number of bytes at the end which have to be filled in before we
	crank the block cipher again.  We do the block cipher operation
	lazily: bufLeft may be 0.  When we need one more byte, we
	crank the block cipher and set bufLeft to 7.

	prev[] holds the previous 8 bytes of ciphertext, for use
	by ideaCFBSync() and Phil's, ahem, unique (not insecure, just
	unusual) way of doing CFB encryption.

	When used for X9.17 random number generation, iv[] holds the V initial
	vector, and prev[] holds the R random output.  bufLeft indicates how
	much of R is still available before the generator has to be cranked again.
____________________________________________________________________________*/


/*____________________________________________________________________________
	Each interleaved CFB has its own data.
____________________________________________________________________________*/
typedef struct
{
	PGPSymmetricCipherContextRef	symmetricRef;
	PGPByte							prev[ PGP_CFB_MAXBLOCKSIZE ];
	PGPByte							iv[ PGP_CFB_MAXBLOCKSIZE ];
	/* note bufLeft could actually be in the main structure,
	but it's more convenient here */
	PGPSize							bufLeft;
} CFBInterleaveStruct;
#define kCFBSize		sizeof( CFBInterleaveStruct )


struct PGPCFBContext
{
#define kCFBMagic		0xBAABBAAB
	PGPUInt32						magic;
	PGPMemoryMgrRef					memoryMgr;
	PGPUInt16						interleave;
	PGPUInt16						curCFBIndex;
	PGPSize							bytesInCur;
	PGPBoolean						cfbInited;
	CFBInterleaveStruct				cfbData[ 1 ];	/* variable */
};
#define IndCFB( ref, x )	(ref)->cfbData[ x ]

	static PGPSize
CalcContextSize( PGPUInt16	numInterleaves )
{
	/* one CFBInterleaveStruct is already declared in main struct */
	return( sizeof( PGPCFBContext ) +
		numInterleaves * ( kCFBSize - 1 ) );
}


	static PGPBoolean
pgpCFBIsValid( const PGPCFBContext * ref)
{
	PGPBoolean	valid	= FALSE;
	
	valid	= IsntNull( ref ) && ref->magic	 == kCFBMagic;
	
	return( valid );
}



static void		pgpCFBSync(CFBInterleaveStruct *cfb);

static void		pgpCFBRandCycle(PGPCFBContext *ref,
					void const *salt);
					
static void		pgpCFBRandWash(PGPCFBContext *ref,
					void const *buf, PGPSize len);
					
static void		pgpCFBInit( PGPCFBContext *	ref,
					void const * key, void const * iv);
					
static void		pgpCFBEncrypt( CFBInterleaveStruct *ref,
					void const * src, PGPSize len, void * dest );
					
static void		pgpCFBDecrypt( CFBInterleaveStruct *ref,
					void const * src, PGPSize len, void * dest );


/* Returns as many bytes as are available before more salt is needed */
static PGPSize 	pgpCFBRandBytes(PGPCFBContext *ref,
						PGPSize len, void *dest );


/*____________________________________________________________________________
____________________________________________________________________________*/
	PGPError 
PGPNewCFBContext(
	PGPSymmetricCipherContextRef	symmetricRef,
	PGPUInt16						interleave,
	PGPCFBContextRef *	outRef )
{
	PGPCFBContextRef		newRef	= NULL;
	PGPError						err	= kPGPError_NoErr;
	
	PGPValidatePtr( outRef );
	*outRef	= NULL;
	PGPValidatePtr( symmetricRef );
	PGPValidateParam( interleave != 0 );
	
	newRef	= (PGPCFBContextRef)
			PGPNewData( pgpGetSymmetricCipherMemoryMgr( symmetricRef ),
				CalcContextSize( interleave ),
				0 | kPGPMemoryMgrFlags_Clear);
			
	if ( IsntNull( newRef ) )
	{
		PGPUInt32	cfbIndex;
		
#if PGP_DEBUG
		/* make original invalid to enforce semantics */
		PGPSymmetricCipherContextRef	tempRef;
		err	= PGPCopySymmetricCipherContext( symmetricRef, &tempRef );
		if ( IsntPGPError( err ) )
		{
			PGPFreeSymmetricCipherContext( symmetricRef );
			symmetricRef	= tempRef;
		}
		err	= kPGPError_NoErr;
#endif

		newRef->magic						= kCFBMagic;
		newRef->interleave					= interleave;	
		newRef->cfbInited					= FALSE;
		IndCFB( newRef, 0 ).symmetricRef	= symmetricRef;
		
		newRef->memoryMgr = pgpGetSymmetricCipherMemoryMgr( symmetricRef );
		
		/* create a separate symmetric cipher for each cfb */
		for ( cfbIndex = 1; cfbIndex < interleave; ++ cfbIndex )
		{
			err	= PGPCopySymmetricCipherContext( symmetricRef,
						&IndCFB( newRef, cfbIndex ).symmetricRef );
			if ( IsPGPError( err ) )
			{
				break;
			}
		}
		
		/* make sure we clean up */
		if ( IsPGPError( err ) )
		{
			PGPFreeCFBContext( newRef );
			newRef	= NULL;
		}
	}
	else
	{
		/* we own it, so dispose it */
		PGPFreeSymmetricCipherContext( symmetricRef );
		err	= kPGPError_OutOfMemory;
	}
	
	*outRef	= newRef;
	return( err );
}



/*____________________________________________________________________________
____________________________________________________________________________*/
	PGPError 
PGPFreeCFBContext( PGPCFBContextRef ref )
{
	PGPError		err	= kPGPError_NoErr;
	PGPUInt32		cfbIndex;
	
	PGPValidateCFB( ref );
	
	for( cfbIndex = 0; cfbIndex < ref->interleave; ++cfbIndex )
	{
		if ( IsntNull( IndCFB( ref, cfbIndex ).symmetricRef ) )
		{
			PGPFreeSymmetricCipherContext(
				IndCFB( ref, cfbIndex ).symmetricRef );
			IndCFB( ref, cfbIndex ).symmetricRef	= NULL;
		}
	}
	
	pgpClearMemory( ref, sizeof( *ref ) );
	PGPFreeData( ref );
	
	return( err );
}



/*____________________________________________________________________________
____________________________________________________________________________*/
	PGPError 
PGPCopyCFBContext(
	PGPCFBContextRef	inRef,
	PGPCFBContextRef *	outRef )
{
	PGPError					err	= kPGPError_NoErr;
	PGPCFBContextRef	newRef	= NULL;
	
	PGPValidatePtr( outRef );
	*outRef	= NULL;
	PGPValidateCFB( inRef );
	
	newRef	= (PGPCFBContextRef)
		PGPNewData( inRef->memoryMgr,
		CalcContextSize( inRef->interleave ), 0);
	if ( IsntNull( newRef ) )
	{
		PGPUInt32	cfbIndex;
		
		*newRef		= *inRef;
		
		/* clear each symmetric cipher in case later allocation fails */
		for ( cfbIndex = 0; cfbIndex < inRef->interleave; ++cfbIndex )
		{
			IndCFB( newRef, cfbIndex ).symmetricRef	= NULL;
		}
		
		/* copy each symmetric cipher */
		for ( cfbIndex = 0; cfbIndex < inRef->interleave; ++cfbIndex )
		{
			err	= PGPCopySymmetricCipherContext(
					IndCFB( inRef, cfbIndex ).symmetricRef,
					&IndCFB( newRef, cfbIndex ).symmetricRef );
			if ( IsPGPError( err ) )
			{
				break;
			}
		}
		
		if ( IsPGPError( err ) )
		{
			PGPFreeCFBContext( newRef );
			newRef	= NULL;
		}
	}
	else
	{
		err	= kPGPError_OutOfMemory;
	}
	
	*outRef	= newRef;
	return( err );
}



/*____________________________________________________________________________
____________________________________________________________________________*/
	PGPError 
PGPInitCFB(
	PGPCFBContextRef	ref,
	const void *		key,
	const void *		initializationVector )
{
	PGPError	err	= kPGPError_NoErr;
	
	PGPValidateCFB( ref );
	/* at least one param must be non-nil */
	PGPValidateParam( IsntNull( key ) || IsntNull( initializationVector ) );
		
	pgpCFBInit( ref, key, initializationVector);
	
	return( err );
}




	static void
pgpEncryptDecryptInterleaved(
	PGPBoolean			encrypt,
	PGPCFBContextRef	ref,
	const void *		in,
	PGPSize				bytesIn,
	void *				out )
{
	PGPSize			blockSize	= pgpCFBGetBlockSize( ref );
	PGPUInt16		cfbIndex;
	PGPSize			remaining;
	const PGPByte *	curIn	= (const PGPByte *) in;
	PGPByte *		curOut	= (PGPByte *) out;
	
	cfbIndex	= ref->curCFBIndex;
	remaining	= bytesIn;
	while ( remaining != 0 )
	{
		CFBInterleaveStruct *	cfb	= NULL;
		PGPUInt32				bytesAvail;
		
		bytesAvail	= blockSize - ref->bytesInCur;
		if ( bytesAvail > remaining )
			bytesAvail	= remaining;
		
		cfb	= &IndCFB( ref, cfbIndex );
		if ( encrypt )
			pgpCFBEncrypt( cfb, curIn, bytesAvail, curOut);
		else
			pgpCFBDecrypt( cfb, curIn, bytesAvail, curOut);
		
		ref->bytesInCur	+= bytesAvail;
		curIn			+= bytesAvail;
		curOut			+= bytesAvail;
		remaining		-= bytesAvail;
		
		/* do we need to go onto the next CFB? */
		pgpAssert( ref->bytesInCur <= blockSize );
		if ( ref->bytesInCur == blockSize )
		{
			++cfbIndex;
			/* wrap around to first CFB if necessary */
			if ( cfbIndex == ref->interleave )
			{
				cfbIndex	= 0;
			}
			ref->bytesInCur	= 0;
		}
	}
	
	ref->curCFBIndex	= cfbIndex;
	
	(void)encrypt;
	(void)ref;
	(void)in;
	(void)bytesIn;
	(void)out;
}

	PGPError 
pgpCFBEncryptInternal(
	PGPCFBContextRef	ref,
	const void *		in,
	PGPSize				bytesIn,
	void *				out )
{
	PGPError	err	= kPGPError_NoErr;
	
	if ( ref->cfbInited )
	{
		if ( ref->interleave == 1 )
		{
			/* keep it most efficient for common case */
			CFBInterleaveStruct *cfb	= &IndCFB( ref, 0);
			
			pgpCFBEncrypt( cfb, in, bytesIn, out);
		}
		else
		{
			pgpEncryptDecryptInterleaved( TRUE, ref, in, bytesIn, out );
		}
	}
	else
	{
		err	= kPGPError_ImproperInitialization;
	}
	
	return( err );
}

	PGPError 
PGPCFBEncrypt(
	PGPCFBContextRef	ref,
	const void *		in,
	PGPSize				bytesIn,
	void *				out )
{
	PGPValidatePtr( out );
	PGPValidateCFB( ref );
	PGPValidatePtr( in );
	PGPValidateParam( bytesIn != 0 );

#if PGP_ENCRYPT_DISABLE
	return( kPGPError_FeatureNotAvailable );
#else
	return( pgpCFBEncryptInternal( ref, in, bytesIn, out ) );
#endif
}

					
	PGPError 
pgpCFBDecryptInternal(
	PGPCFBContextRef	ref,
	const void *		in,
	PGPSize				bytesIn,
	void *				out )
{
	PGPError	err	= kPGPError_NoErr;
	
	if ( ref->cfbInited )
	{
		if ( ref->interleave == 1 )
		{
			/* keep it most efficient for common case */
			CFBInterleaveStruct *cfb	= &IndCFB( ref, 0);
			
			pgpCFBDecrypt( cfb, in, bytesIn, out);
		}
		else
		{
			pgpEncryptDecryptInterleaved( FALSE, ref, in, bytesIn, out );
		}
	}
	else
	{
		err	= kPGPError_ImproperInitialization;
	}
	
	return( err );
}

	PGPError 
PGPCFBDecrypt(
	PGPCFBContextRef	ref,
	const void *		in,
	PGPSize				bytesIn,
	void *				out )
{
	PGPValidatePtr( out );
	PGPValidateCFB( ref );
	PGPValidatePtr( in );
	PGPValidateParam( bytesIn != 0 );

#if PGP_DECRYPT_DISABLE
	return( kPGPError_FeatureNotAvailable );
#else
	return( pgpCFBDecryptInternal( ref, in, bytesIn, out ) );
#endif
}



	PGPError 
PGPCFBGetSymmetricCipher(
	PGPCFBContextRef		ref,
	PGPSymmetricCipherContextRef *	outRef )
{
	PGPError						err	= kPGPError_NoErr;
	PGPSymmetricCipherContextRef	symmetricRef	= NULL;
	
	PGPValidatePtr( outRef );
	*outRef	= NULL;
	PGPValidateCFB( ref );

	symmetricRef	= IndCFB( ref, 0).symmetricRef;
	
	*outRef	= symmetricRef;
	return( err );
}




/*____________________________________________________________________________
____________________________________________________________________________*/
	PGPError 
PGPCFBSync( PGPCFBContextRef ref )
{
	PGPError			err	= kPGPError_NoErr;
	
	PGPValidateCFB( ref );
	
	pgpCFBSync( &IndCFB( ref, ref->curCFBIndex ) );
	
	return( err );
}



/*____________________________________________________________________________
____________________________________________________________________________*/
	PGPError 
PGPCFBGetRandom(
	PGPCFBContextRef	ref,
	PGPSize				requestCount,
	void *				outBytes,
	PGPSize *			outCount )
{
	PGPError	err	= kPGPError_NoErr;
	
	PGPValidatePtr( outCount );
	*outCount	= 0;
	PGPValidateCFB( ref );
	PGPValidatePtr( outBytes );
	PGPValidateParam( ref->interleave == 1 );
		
	*outCount	= pgpCFBRandBytes( ref, requestCount, outBytes);
	
	return( err );
}

					
					
/*____________________________________________________________________________
____________________________________________________________________________*/
	PGPError 
PGPCFBRandomCycle(
	PGPCFBContextRef	ref,

⌨️ 快捷键说明

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