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

📄 cryptos.h

📁 老外写的加密库cryptlib(版本3.1)
💻 H
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*																			*
*							cryptlib OS-specific Macros  					*
*						Copyright Peter Gutmann 1992-2003					*
*																			*
****************************************************************************/

#ifndef _CRYPTOS_DEFINED

#define _CRYPTOS_DEFINED

/* Check the validity of a pointer passed to a cryptlib function.  Usually
   the best we can do is check that it's not null, but some OSes allow for
   better checking than this, for example that it points to a block of
   readable or writeable memory.  Under Windows IsBadReadPtr() will always
   succeed if the size is 0, so we have to add a separate check to make sure
   it's non-NULL */

#if defined( __WIN32__ )
  #define checkBadPtrRead( ptr, size )	( ( ptr ) == NULL || \
										  IsBadReadPtr( ( ptr ), ( size ) ) )
  #define checkBadPtrWrite( ptr, size )	( ( ptr ) == NULL || \
										  IsBadWritePtr( ( ptr ), ( size ) ) )
#else
  #define checkBadPtrRead( ptr, size )	( ( ptr ) == NULL )
  #define checkBadPtrWrite( ptr, size )	( ( ptr ) == NULL )
#endif /* Pointer check macros */
#define isReadPtr( ptr, dataType ) \
		!checkBadPtrRead( ptr, sizeof( dataType ) )
#define isReadPtrEx( ptr, dataType, count ) \
		!checkBadPtrRead( ptr, sizeof( dataType ) * count )
#define isWritePtr( ptr, dataType ) \
		!checkBadPtrWrite( ptr, sizeof( dataType ) )
#define isWritePtrEx( ptr, dataType, count ) \
		!checkBadPtrWrite( ptr, sizeof( dataType ) * count )

/* When working with secure memory we need to take the OS page size into
   account.  The following macro obtains the OS page size */

#if defined( __WIN32__ )
  /* This assumes Intel hardware, which is virtually always the case */
  #define getPageSize()			4096
#elif defined( __UNIX__ )
  #if defined( __hpux ) || defined( _M_XENIX ) || defined( __aux )
	#define getPageSize()		4096
  #else
	#define getPageSize()		getpagesize()
  #endif /* Unix variant-specific brokenness */
#endif /* OS-specifc page size determination */

/* Under OSF/1 pthread.h includes c_asm.h which contains a declaration

	long asm( const char *,...);

   which conflicts with the gcc asm keyword.  This asm stuff is only used
   when inline asm alternatives to the Posix threading functions are enabled,
   which isn't done by default so in theory we could also fix this by
   defining asm to something else before including pthread.h, but it's safer
   to just disable inclusion of c_asm.h by pre-defining the guard define,
   which should result in a more useful warning if for some reason inline
   threading functions with asm are enabled */

#if defined( __osf__ ) || defined( __alpha__ )
  #define __C_ASM_H
#endif /* Alpha */

/* Get the start address of a page and, given an address in a page and a
   size, determine on which page the data ends.  These are used to determine
   which pages a memory block covers.

   These macros have portability problems since they assume that
   sizeof( long ) == sizeof( void * ), but there's no easy way to avoid this
   since for some strange reason C doesn't allow the perfectly sensible use
   of logical operations on addresses */

#define getPageStartAddress( address ) \
			( ( long ) ( address ) & ~( getPageSize() - 1 ) )
#define getPageEndAddress( address, size ) \
			getPageStartAddress( ( long ) address + ( size ) - 1 )

/****************************************************************************
*																			*
*								Object Handling Macros						*
*																			*
****************************************************************************/

/* In multithreaded environments we need to protect the information inside
   cryptlib data structures from access by other threads while we use it.
   The following macros handle this object protection when we enter and
   exit cryptlib functions.  The initResourceLock() and deleteResourceLock()
   macros initialise the data structure needed to perform the object
   locking.  Note the before deleting the resource lock we lock and unlock
   it again to ensure that if some other thread is holding the resource,
   they'll release it before we delete the lock */

#if defined( __WIN32__ ) && !defined( NT_DRIVER )

#include <process.h>

/* Some variables are protected by locks.  Before we can read or write these
   variables in a multithreaded environment we need to lock them so they
   can't be accessed or modified by other threads while we're using them.
   The following macros provide this locking capability */

#define DECLARE_LOCKING_VARS( name ) \
		static CRITICAL_SECTION name##CriticalSection; \
		static BOOLEAN name##CriticalSectionInitialised = FALSE;
#define initResourceLock( name ) \
		if( !name##CriticalSectionInitialised ) \
			{ \
			InitializeCriticalSection( &name##CriticalSection ); \
			name##CriticalSectionInitialised = TRUE; \
			}
#define deleteResourceLock( name ) \
		if( name##CriticalSectionInitialised ) \
			{ \
			EnterCriticalSection( &name##CriticalSection ); \
			LeaveCriticalSection( &name##CriticalSection ); \
			DeleteCriticalSection( &name##CriticalSection ); \
			name##CriticalSectionInitialised = FALSE; \
			}
#define lockResource( name ) \
		EnterCriticalSection( &name##CriticalSection )
#define unlockResource( name ) \
		LeaveCriticalSection( &name##CriticalSection )

/* Handles to threads and system synchronisation objects */

#define THREAD_HANDLE			HANDLE
#define SEMAPHORE_HANDLE		HANDLE

/* Define a thread function */

#define THREADFUNC_DEFINE( name, arg ) \
								unsigned __stdcall name( void *arg )

/* Thread management functions.  There are two functions that we can call to
   get the current thread ID, GetCurrentThread() and GetCurrentThreadId().
   These are actually implemented as the same function (once you get past
   the outer wrapper), and the times for calling either are identical - a
   significant 10 us per call on a P5/166.  The only difference between the
   two is that GetCurrentThread() returns a per-process pseudohandle while
   GetCurrentThreadId() returns a systemwide, unique handle.

   Note that after we wait for the thread, we need to close the handle.
   This is complicated by the fact that we can only close it once all
   threads have exited the wait, which requires further calisthenics in
   the function that uses it to ensure that the last thread out closes the
   handle */

#define THREAD_CREATE( function, arg, handle ) \
								( !( handle = ( HANDLE ) _beginthreadex( NULL, 0, \
													( function ), ( arg ), 0, \
													( unsigned * ) &dummy ) ) ? \
									CRYPT_ERROR : CRYPT_OK )
#define THREAD_EXIT()			_endthreadex( 0 ); return( 0 )
#define THREAD_CREATE_VARS		int dummy
#define THREAD_INITIALISER		0
#define THREAD_SELF()			( THREAD_HANDLE ) GetCurrentThreadId()
#define THREAD_SAME( thread1, thread2 ) \
								( ( thread1 ) == ( thread2 ) )
#define THREAD_SLEEP( ms )		Sleep( ms )
#define THREAD_YIELD()			Sleep( 0 )
#define THREAD_WAIT( thread )	WaitForSingleObject( thread, INFINITE );
#define THREAD_CLOSE( thread )	CloseHandle( thread )

/* Remember that we're using threaded functions */

#define USE_THREADS

#elif defined( __WIN32__ ) && defined( NT_DRIVER )

/* Some variables are protected by locks.  Before we can read or write these
   variables in a multithreaded environment we need to lock them so they
   can't be accessed or modified by other threads while we're using them.
   The following macros provide this locking capability */

#define DECLARE_LOCKING_VARS( name ) \
		static KMUTEX name##CriticalSection; \
		static BOOLEAN name##CriticalSectionInitialised = FALSE;
#define initResourceLock( name ) \
		if( !name##CriticalSectionInitialised ) \
			{ \
			KeInitializeMutex( &name##CriticalSection, 1 ); \
			name##CriticalSectionInitialised = TRUE; \
			}
#define deleteResourceLock( name )

#define lockResource( name ) \
		KeWaitForMutexObject( &name##CriticalSection, Executive, \
							  KernelMode, FALSE, NULL )
#define unlockResource( name ) \
		KeReleaseMutex( &name##CriticalSection, FALSE )

/* Handles to threads and system synchronisation objects */

#define THREAD_HANDLE				HANDLE
#define SEMAPHORE_HANDLE			HANDLE

#elif defined( __OS2__ )

#define INCL_DOSSEMAPHORES
#define INCL_DOSMISC
#define INCL_DOSFILEMGR
#define INCL_DOSMISC
#define INCL_DOSDATETIME
#define INCL_DOSPROCESS
#define INCL_WINWINDOWMGR
#define INCL_WINSYS
#include <os2.h>
ULONG DosGetThreadID( void );

/* Some variables are protected by locks.  Before we can read or write these
   variables in a multithreaded environment we need to lock them so they
   can't be accessed or modified by other threads while we're using them.
   The following macros provide this locking capability */

#define DECLARE_LOCKING_VARS( name ) \
		static HMTX name##Mutex; \
		static BOOLEAN name##MutexInitialised = FALSE;
#define initResourceLock( name ) \
		if( !name##MutexInitialised ) \
			{ \
			DosCreateMutexSem( NULL, &name##Mutex, 0L, FALSE ); \
			name##MutexInitialised = TRUE; \
			}
#define deleteResourceLock( name ) \
		if( name##MutexInitialised ) \
			{ \
			DosRequestMutexSem( name##Mutex, ( ULONG ) SEM_INDEFINITE_WAIT ); \
			DosReleaseMutexSem( name##Mutex ); \
			DosCloseMutexSem( name##Mutex ); \
			name##MutexInitialised = FALSE; \
			}
#define lockResource( name ) \
		DosRequestMutexSem( name##Mutex, ( ULONG ) SEM_INDEFINITE_WAIT )
#define unlockResource( name ) \
		DosReleaseMutexSem( name##Mutex )

/* Handles to threads and system synchronisation objects */

#define THREAD_HANDLE			TID
#define SEMAPHORE_HANDLE		HEV

/* Define a thread function */

#define THREADFUNC_DEFINE( name, arg ) \
									void _Optlink name( void *arg )

/* Thead management functions */

#define THREAD_CREATE( function, arg, handle ) \
								( ( handle = _beginthread( ( function ), NULL, 8192, \
														 ( arg ) ) ) == -1 ? \
									CRYPT_ERROR : CRYPT_OK )
#define THREAD_EXIT()			_endthread()
#define THREAD_CREATE_VARS
#define THREAD_INITIALISER		0
#define THREAD_SELF()			DosGetThreadID()
#define THREAD_SAME( thread1, thread2 ) \
								( ( thread1 ) == ( thread2 ) )
#define THREAD_SLEEP( ms )		DosWait( ms )
#define THREAD_YIELD()			DosWait( 0 )
#define THREAD_WAIT( thread )	DosWaitThread( thread, INFINITE )
#define THREAD_CLOSE( thread )

/* Remember that we're using threaded functions */

#define USE_THREADS

#elif defined( __UNIX__ ) && defined( USE_THREADS )

/* Handles to threads and system synchronisation objects */

#define THREAD_HANDLE			THREAD
#define SEMAPHORE_HANDLE		THREAD

/* Define a thread function */

#define THREADFUNC_DEFINE( name, arg ) \
									void *name( void *arg )

/* Thead management functions.  Most Unix mutex implementations are non-
   re-entrant, which means that re-locking a mutex leads to deadlock (nice
   design, guys).  Some implementations can fix this by setting a mutex
   attribute to ensure that it doesn't deadlock:

	pthread_mutexattr_settype( attr, PTHREAD_MUTEX_RECURSIVE );

   but this isn't universal.  To fix the problem, we implement our own
   re-entrant mutexes on top of the Posix ones using mutex_trylock(), which
   doesn't re-lock the mutex if it's already locked (as a side-benefit,
   trylock() is roughly twice as fast as lock(), depending on the OS).  This
   works as follows:

	// Try and lock the mutex
	if( mutex_trylock( mutex ) == error )
		{
		// The mutex is already locked, see who owns it
		if( thread_self() != mutex_owner )
			// Someone else has it locked, wait for it to become available
			mutex_lock( mutex );
		else
			// We have it locked, increment its lock count
			mutex_lockcount++;
		}
	mutex_owner = thread_self();

	// ....

	// Decrement the lock count and if we reach zero, unlock the mutex
	if( mutex_lockcount > 0 )
		mutex_lockcount--;
	else
		mutex_unlock( mutex );

   Putting a thread to sleep for a number of milliseconds can be done with
   select() because it should be a thread-safe one in the presence of
   pthreads.  Yielding a thread's timeslice is rather more tricky and is done
   further on.  In addition there are some system-specific quirks, these are
   handled by re-defining the macros below in a system-specific manner further
   on */

#include <pthread.h>
#include <sys/time.h>

#define MUTEX					pthread_mutex_t
#define MUTEX_INIT( mutex )		pthread_mutex_init( mutex, NULL )
#define MUTEX_DESTROY			pthread_mutex_destroy
#define MUTEX_LOCK				pthread_mutex_lock
#define MUTEX_TRYLOCK			pthread_mutex_trylock
#define MUTEX_UNLOCK			pthread_mutex_unlock

#define THREAD					pthread_t
#define THREAD_CREATE( function, arg, handle ) \
								( pthread_create( &handle, NULL, function, arg ) ? \
									CRYPT_ERROR : CRYPT_OK )
#define THREAD_EXIT()			pthread_exit( ( void * ) 0 )
#define THREAD_CREATE_VARS
#define THREAD_INITIALISER		0

⌨️ 快捷键说明

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