📄 cryptos.h
字号:
/****************************************************************************
* *
* cryptlib OS-specific Macros *
* Copyright Peter Gutmann 1992-2002 *
* *
****************************************************************************/
#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 */
/* 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 */
#if defined( __WIN32__ ) && !defined( NT_DRIVER ) /* NT */
#include <process.h> /* For begin/endthreadex */
/* Declare the variables required to handle the object locking for internal
data structures */
#define DECLARE_OBJECT_LOCKING_VARS \
CRITICAL_SECTION criticalSection; \
BOOLEAN criticalSectionInitialised;
/* Initialise and delete the locking variables */
#define initResourceLock( objectPtr ) \
InitializeCriticalSection( &( objectPtr )->criticalSection ); \
( objectPtr )->criticalSectionInitialised = TRUE
#define deleteResourceLock( objectPtr ) \
if( ( objectPtr )->criticalSectionInitialised ) \
{ \
DeleteCriticalSection( &( objectPtr )->criticalSection ); \
( objectPtr )->criticalSectionInitialised = FALSE; \
}
/* Lock and unlock an object using the locking variables */
#define lockResource( objectPtr ) \
EnterCriticalSection( &( objectPtr )->criticalSection )
#define unlockResource( objectPtr ) \
LeaveCriticalSection( &( objectPtr )->criticalSection )
/* Some variables are protected by global object locks (for example the
internal data structures are accessed through a global object map which
maps handles to object information). Before we can read or write these
variables in a multithreaded environment we need to lock them so they
won't be accessed or modified by other threads. The following macros
provide this locking capability */
#define DECLARE_LOCKING_VARS( name ) \
CRITICAL_SECTION name##CriticalSection; \
BOOLEAN name##CriticalSectionInitialised = FALSE;
#define DEFINE_LOCKING_VARS( name ) \
extern CRITICAL_SECTION name##CriticalSection; \
extern BOOLEAN name##CriticalSectionInitialised;
#define initGlobalResourceLock( name ) \
if( !name##CriticalSectionInitialised ) \
{ \
InitializeCriticalSection( &name##CriticalSection ); \
name##CriticalSectionInitialised = TRUE; \
}
#define deleteGlobalResourceLock( name ) \
if( name##CriticalSectionInitialised ) \
{ \
DeleteCriticalSection( &name##CriticalSection ); \
name##CriticalSectionInitialised = FALSE; \
}
#define lockGlobalResource( name ) \
EnterCriticalSection( &name##CriticalSection )
#define unlockGlobalResource( name ) \
LeaveCriticalSection( &name##CriticalSection )
/* Some objects are owned by one thread and can't be accessed by any other
threads. The following macros provide facilities to declare the thread
ID variables and check that the current thread is allowed to access this
object.
There are two functions 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 staggering 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. We use GetCurrentThreadID() because it returns a DWORD
which is easier to manage since it's equivalent to an int */
#define OWNERSHIP_VAR_TYPE DWORD
#define DECLARE_OWNERSHIP_VARS DWORD objectOwner;
#define getCurrentIdentity() GetCurrentThreadId()
/* The types used for 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 )
/* Create a thread and check that the creation succeeded */
#define THREAD_CREATE( function, arg ) \
_beginthreadex( NULL, 0, ( function ), \
( arg ), 0, ( unsigned * ) &dummy );
#define THREAD_STATUS( status ) ( !( status ) ? CRYPT_ERROR : CRYPT_OK )
#define THREAD_EXIT() _endthreadex( 0 ); return( 0 )
/* The lock for the internal data structures is used throughout the library
so we make it globally visible */
extern CRITICAL_SECTION objectCriticalSection;
#elif defined( __WIN32__ ) && defined( NT_DRIVER ) /* NT kernel drvr */
/* Declare the variables required to handle the object locking for internal
data structures */
#define DECLARE_OBJECT_LOCKING_VARS \
KMUTEX criticalSection; \
BOOLEAN criticalSectionInitialised;
/* Initialise and delete the locking variables */
#define initResourceLock( objectPtr ) \
KeInitializeMutex( &( objectPtr )->criticalSection, 1 ); \
( objectPtr )->criticalSectionInitialised = TRUE
#define deleteResourceLock( objectPtr )
/* Lock and unlock an object using the locking variables */
#define lockResource( objectPtr ) \
KeWaitForMutexObject( &( objectPtr )->criticalSection, Executive, \
KernelMode, FALSE, NULL )
#define unlockResource( objectPtr ) \
KeReleaseMutex( &( objectPtr )->criticalSection, FALSE )
/* Some variables are protected by global object locks (for example the
internal data structures are accessed through a global object map which
maps handles to object information). Before we can read or write these
variables in a multithreaded environment we need to lock them so they
won't be accessed or modified by other threads. The following macros
provide this locking capability */
#define DECLARE_LOCKING_VARS( name ) \
KMUTEX name##CriticalSection; \
BOOLEAN name##CriticalSectionInitialised = FALSE;
#define DEFINE_LOCKING_VARS( name ) \
extern KMUTEX name##CriticalSection;
#define initGlobalResourceLock( name ) \
if( !name##CriticalSectionInitialised ) \
{ \
KeInitializeMutex( &name##CriticalSection, 1 ); \
name##CriticalSectionInitialised = TRUE; \
}
#define deleteGlobalResourceLock( name )
#define lockGlobalResource( name ) \
KeWaitForMutexObject( &name##CriticalSection, Executive, \
KernelMode, FALSE, NULL )
#define unlockGlobalResource( name ) \
KeReleaseMutex( &name##CriticalSection, FALSE )
/* The types used for handles to threads and system synchronisation objects */
#define THREAD_HANDLE HANDLE
#define SEMAPHORE_HANDLE HANDLE
/* The lock for the internal data structures is used throughout the library
so we make it globally visible */
extern KMUTEX objectCriticalSection;
#elif defined( __OS2__ ) /* OS/2 */
#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 );
/* Declare the variables required to handle the object locking for internal
data structures */
#define DECLARE_OBJECT_LOCKING_VARS \
HMTX mutex; \
BOOLEAN mutexInitialised;
/* Initialise and delete the locking variables */
#define initResourceLock( objectPtr ) \
DosCreateMutexSem( NULL, &( objectPtr )->mutex, 0L, FALSE ); \
( objectPtr )->mutexInitialised = TRUE
#define deleteResourceLock( objectPtr ) \
if( ( objectPtr )->mutexInitialised ) \
{ \
DosCloseMutexSem( ( objectPtr )->mutex ); \
( objectPtr )->mutexInitialised = FALSE; \
}
/* Lock and unlock a object using the locking variables */
#define lockResource( objectPtr ) \
DosRequestMutexSem( ( objectPtr )->mutex, ( ULONG ) SEM_INDEFINITE_WAIT )
#define unlockResource( objectPtr ) \
DosReleaseMutexSem( ( objectPtr )->mutex )
/* Some variables are protected by global object locks (for example the
internal data structures are accessed through a global object map which
maps handles to object information). Before we can read or write these
variables in a multithreaded environment we need to lock them so they
won't be accessed or modified by other threads. The following macros
provide this locking capability */
#define DECLARE_LOCKING_VARS( name ) \
HMTX name##Mutex; \
BOOLEAN name##MutexInitialised = FALSE;
#define DEFINE_LOCKING_VARS( name ) \
extern HMTX name##Mutex;
#define initGlobalResourceLock( name ) \
if( !name##MutexInitialised ) \
{ \
DosCreateMutexSem( NULL, &name##Mutex, 0L, FALSE ); \
name##MutexInitialised = TRUE; \
}
#define deleteGlobalResourceLock( name ) \
if( name##MutexInitialised ) \
{ \
DosCloseMutexSem( name##Mutex ); \
name##MutexInitialised = FALSE; \
}
#define lockGlobalResource( name ) \
DosRequestMutexSem( name##Mutex, ( ULONG ) SEM_INDEFINITE_WAIT )
#define unlockGlobalResource( name ) \
DosReleaseMutexSem( name##Mutex )
/* Some objects are owned by one thread and can't be accessed by any other
threads. The following macros provide facilities to declare the thread
ID variables and check that the current thread is allowed to access this
object */
#define OWNERSHIP_VAR_TYPE TID
#define DECLARE_OWNERSHIP_VARS TID objectOwner;
#define getCurrentIdentity() DosGetThreadID()
/* The types used for 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 )
/* Create a thread and check that the creation succeeded */
#define THREAD_CREATE( function, arg ) \
_beginthread( ( function ), NULL, 8192, \
( arg ) )
#define THREAD_STATUS( status ) ( ( status ) == -1 ? CRYPT_ERROR : CRYPT_OK )
#define THREAD_EXIT() _endthread()
/* The lock for the internal data structures is used throughout the library
so we make it globally visible */
extern HMTX objectMutex;
#elif defined( __UNIX__ ) && defined( USE_THREADS ) /* Unix threads */
/* Various Unix variants provide different threading implementations. The
following defines are used to map the abstract thread operations to the
appropriate low-level primitives.
Most of the mutex implementations are non-reentrant, 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 it
doesn't deadlock:
pthread_mutexattr_settype( attr, PTHREAD_MUTEX_RECURSIVE );
but this isn't universal. To fix the problem, we provide a check using
mutex_trylock() which doesn't re-lock the mutex if it's already locked.
This works as follows:
// Try and lock the mutex
if( mutex_trylock( mutex ) == error )
{
// The mutex is already locked, if someone else has it locked, we
// block until it becomes available
if( thread_self() != mutex_owner )
mutex_lock( mutex );
}
mutex_owner = thread_self();
// ....
// Since we don't do true nested locking, we may have already been
// unlocked, don't try and unlock a second time
if( mutex_owner != nil )
{
mutex_owner = nil;
mutex_unlock( mutex );
} */
#if defined( sun ) /* Solaris threads */
#include <thread.h>
#include <synch.h>
#define MUTEX mutex_t
#define MUTEX_INIT( mutex ) mutex_init( mutex, USYNC_THREAD, NULL )
#define MUTEX_DESTROY mutex_destroy
#define MUTEX_LOCK mutex_lock
#define MUTEX_TRYLOCK mutex_trylock
#define MUTEX_UNLOCK mutex_unlock
#define THREAD thread_t
#define THREAD_SELF thr_self
#define THREAD_CREATE( function, arg ) \
thr_create( NULL, 0, function, arg, 0, &dummy );
#define THREAD_STATUS( status ) ( ( status ) ? CRYPT_ERROR : CRYPT_OK )
#define THREAD_EXIT() thr_exit( ( void * ) 0 )
#elif defined( __Mach__ ) /* Mach threads */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -