📄 crypt.h
字号:
is only really necessary on non-Unix systems since the makefile runtime
test will tell us the endianness under Unix */
#if !defined( DATA_LITTLEENDIAN ) && !defined( DATA_BIGENDIAN )
#if defined( _M_I86 ) || defined( _M_IX86 ) || defined( __TURBOC__ ) || \
defined( __OS2__ )
#define DATA_LITTLEENDIAN /* Intel architecture always little-endian */
#elif defined( AMIGA ) || defined( __MWERKS__ ) || defined( SYMANTEC_C ) || \
defined( THINK_C ) || defined( applec ) || defined( __MRC__ )
#define DATA_BIGENDIAN /* Motorola architecture always big-endian */
#elif defined( VMS ) || defined( __VMS )
#define DATA_LITTLEENDIAN /* VAX architecture always little-endian */
#elif defined( __TANDEM )
#define DATA_BIGENDIAN /* Tandem architecture always big-endian */
#elif defined( __AS400__ )
#define DATA_BIGENDIAN /* AS/400 always big-endian */
#elif defined( __VMCMS__ )
#define DATA_BIGENDIAN /* IBM big iron always big-endian */
#elif defined __GNUC__
#ifdef BYTES_BIG_ENDIAN
#define DATA_BIGENDIAN /* Big-endian byte order */
#else
#define DATA_LITTLEENDIAN /* Undefined = little-endian byte order */
#endif /* __GNUC__ */
#endif /* Compiler-specific endianness checks */
#endif /* !( DATA_LITTLEENDIAN || DATA_BIGENDIAN ) */
/* Some systems define both BIG_ENDIAN and LITTLE_ENDIAN, then define
BYTE_ORDER to the appropriate one, so we check this and define the
appropriate value */
#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN ) && defined( BYTE_ORDER )
#if ( BYTE_ORDER == BIG_ENDIAN ) && !defined( DATA_BIGENDIAN )
#define DATA_BIGENDIAN
#else
#if !defined( DATA_LITTLEENDIAN )
#define DATA_LITTLEENDIAN
#endif /* !DATA_LITTLEENDIAN */
#endif /* BYTE_ORDER-specific define */
#endif /* LITTLE_ENDIAN && BIG_ENDIAN && BYTE_ORDER */
/* The last-resort method. Thanks to Shawn Clifford
<sysop@robot.nuceng.ufl.edu> for this trick.
NB: A number of compilers aren't tough enough for this test */
#if !defined( DATA_LITTLEENDIAN ) && !defined( DATA_BIGENDIAN )
#if ( ( ( unsigned short ) ( 'AB' ) >> 8 ) == 'B' )
#define DATA_LITTLEENDIAN
#elif ( ( ( unsigned short ) ( 'AB' ) >> 8 ) == 'A' )
#define DATA_BIGENDIAN
#else
#error Cannot determine processor endianness - edit crypt.h and recompile
#endif /* Endianness test */
#endif /* !( DATA_LITTLEENDIAN || DATA_BIGENDIAN ) */
/* When performing file I/O we need to know how large path names can get in
order to perform range checking and allocate buffers. This gets a bit
tricky since not all systems have PATH_MAX, so we first try for PATH_MAX,
if that fails we try _POSIX_PATH_MAX (which is a generic 255 bytes and if
defined always seems to be less than whatever the real PATH_MAX should be),
if that also fails we grab stdio.h and try and get FILENAME_MAX, with an
extra check for PATH_MAX in case it's defined in stdio.h instead of
limits.h where it should be. FILENAME_MAX isn't really correct since it's
the maximum length of a filename rather than a path, but some environments
treat it as if it were PATH_MAX and in any case it's the best we can do in
the absence of anything better */
#if defined( PATH_MAX )
#define MAX_PATH_LENGTH PATH_MAX
#elif defined( _POSIX_PATH_MAX )
#define MAX_PATH_LENGTH _POSIX_PATH_MAX
#else
#ifndef FILENAME_MAX
#include <stdio.h>
#endif /* FILENAME_MAX */
#ifdef PATH_MAX
#define MAX_PATH_LENGTH PATH_MAX
#else
#define MAX_PATH_LENGTH FILENAME_MAX
#endif /* PATH_MAX or FILENAME_MAX */
#endif /* PATH_MAX */
#ifdef __UNIX__
/* SunOS 4.1.x doesn't define FILENAME_MAX in limits.h, however it does
define a POSIX path length limit so we use that instead. There are a
number of places in various headers in which a max.path length is
defined either as 255 or 1024, but we use the POSIX limit since this is
the only thing defined in limits.h */
#if defined( sun ) && ( OSVERSION == 4 ) && !defined( FILENAME_MAX )
#define FILENAME_MAX _POSIX_PATH_MAX
#endif /* SunOS 4.1.x FILENAME_MAX define */
#endif /* __UNIX__ */
/* SunOS 4 doesn't have memmove(), but SunOS 5 (Slowaris) does, so we define
memmove() to bcopy() under 4. In addition SunOS doesn't define the
fseek position indicators so we define those as well */
#if defined( __UNIX__ ) && defined( sun ) && ( OSVERSION == 4 )
#define memmove bcopy
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#endif /* SunOS 4 */
/* cryptlib contains a few static functions where are prototyped with block
scope inside a preceding function:
{
static int foo( int bar );
foo( 1 );
}
static int foo( int bar )
{
[...]
}
Compiler opinions on this vary. Some compile it as is, some don't allow
the 'static', some allow both variants, and some produce warnings with
both but allow them anyway (there are probably more variants with further
compilers). To get around this, we use the following define and then vary
it for broken compilers (the following is the minimum required to get it
to compile, other broken compilers will still produce warnings) */
#if ( defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x600 ) ) || \
defined( __VMCMS__ ) || defined( __MRC__ )
#define STATIC_FN
#else
#define STATIC_FN static
#endif /* Fn.prototyping workarounds for borken compilers */
/* Unlike the equivalent crypto code, the MD5 and SHA-1 hashing code needs
special defines set to enable the use of asm alternatives. Since this
works by triggering redefines of function names in the source code, we can
only do this under Windows because for other systems you'd need to
conditionally alter the makefile as well. Since these two defines were
left accidentally unset for about five years and were only noticed when
someone benchmarked the code against BSAFE, it's unlikely that this is of
any real concern */
#ifdef __WIN32__
#define MD5_ASM
#define SHA1_ASM
#endif /* Win32 */
/* Enable use of the AES ASM code where possible */
#ifdef __WIN32__
#define AES_ASM
#endif /* Win32 */
/* It's possible to disable certain of the less-useful and patented
algorithms to reduce the size of the code and/or eliminate problems due to
patents. Defining any of the following will eliminate the corresponding
algorithm from the code (at the moment we just allow the entire block to
be disabled with the CRYPTLIB_LITE define). We also automatically define
CRYPTLIB_LITE under 16-bit DOS to conserve memory, since this saves about
60K.
Although it would be nice to remove IDEA as well, it's needed for PGP 2.x
private keyring reads so we leave it in place - if you remove IDEA, the
ability to read PGP 2.x private keyrings will go as well. CAST is
excluded from the lite version not because of any problems but because of
the huge S-boxes.
For embedded environments we remove a different set of functions, PGP file
access isn't useful in an embedded system so we eliminate that as well as
some of the less-useful algorithms */
#ifdef __MSDOS16__
#define CRYPTLIB_LITE
#endif /* 16-bit DOS */
#ifdef CRYPTLIB_LITE
#define NO_CAST
#define NO_ELGAMAL
#define NO_HMAC_MD5
#define NO_HMAC_RIPEMD160
#define NO_IDEA
#define NO_MD4
#define NO_RC2
#define NO_RC4
#define NO_RC5
#define NO_SKIPJACK
#endif /* CRYPTLIB_LITE */
#ifdef __IBM4758__
#define NO_PGP
#define NO_IDEA
#define NO_MD4
#endif /* Embedded systems */
#if defined( CRYPTLIB_LITE ) || defined( __IBM4758__ ) || defined( __VMCMS__ )
#define NO_COMPRESSION
#endif /* Systems where it's not terribly useful */
/* Since SHA-2 use with S/MIME, SSL, PGP, ssh, etc hasn't been standardised
yet, there's not much we can do with it, so we disable it until it's
profiled for use with crypto formats and protocols */
#define NO_SHA2
/****************************************************************************
* *
* OS-Specific Macros *
* *
****************************************************************************/
/* cryptlib provides support for a number of extended OS-specific services
such as multithreading, resource locking, bounds checking, and so on.
The macros for the OS-specific services and resource management are
defined in their own include file */
#include "cryptos.h"
/* The cryptlib kernel has its own interface, defined in the kernel include
file */
#include "cryptkrn.h"
/****************************************************************************
* *
* Portability Defines *
* *
****************************************************************************/
/* If we're running on a 64-bit CPU we often need to mask values off to 32
bits. The following define enables this if the CPU word size is
> 64 bits */
#ifdef _BIG_WORDS
#define MASK32( x ) ( ( x ) & 0xFFFFFFFFUL )
#else
#define MASK32( x ) x
#endif /* _BIG_WORDS */
/* The odd algorithm needs masking to 16 bits */
#if UINT_MAX > 0xFFFFUL
#define MASK16( x ) ( ( x ) & 0xFFFFUL )
#else
#define MASK16( x ) x
#endif /* > 16-bit ints */
/* If we're running on a machine with > 32 bit wordsize we need to jump
through all sorts of hoops to convert data from arrays of bytes to arrays
of longints. The following macros pull bytes out of memory and assemble
them into a longword, and deposit a longword into memory as a series of
bytes. This code really blows on any processors which need to use it */
#ifdef DATA_BIGENDIAN
#define mgetLong(memPtr) \
( ( ( LONG ) memPtr[ 0 ] << 24 ) | ( ( LONG ) memPtr[ 1 ] << 16 ) | \
( ( LONG ) memPtr[ 2 ] << 8 ) | ( ( LONG ) memPtr[ 3 ] ) ); \
memPtr += 4
#define mputLong(memPtr,data) \
memPtr[ 0 ] = ( BYTE ) ( ( ( data ) >> 24 ) & 0xFF ); \
memPtr[ 1 ] = ( BYTE ) ( ( ( data ) >> 16 ) & 0xFF ); \
memPtr[ 2 ] = ( BYTE ) ( ( ( data ) >> 8 ) & 0xFF ); \
memPtr[ 3 ] = ( BYTE ) ( ( data ) & 0xFF ); \
memPtr += 4
#else
#define mgetLong(memPtr) \
( ( ( LONG ) memPtr[ 0 ] ) | ( ( LONG ) memPtr[ 1 ] << 8 ) | \
( ( LONG ) memPtr[ 2 ] << 16 ) | ( ( LONG ) memPtr[ 3 ] << 24 ) ); \
memPtr += 4
#define mputLong(memPtr,data) \
memPtr[ 0 ] = ( BYTE ) ( ( data ) & 0xFF ); \
memPtr[ 1 ] = ( BYTE ) ( ( ( data ) >> 8 ) & 0xFF ); \
memPtr[ 2 ] = ( BYTE ) ( ( ( data ) >> 16 ) & 0xFF ); \
memPtr[ 3 ] = ( BYTE ) ( ( ( data ) >> 24 ) & 0xFF ); \
memPtr += 4
#endif /* DATA_BIGENDIAN */
/* Copy an array of bytes to an array of 32-bit words. We need to take
special precautions when the machine word size is > 32 bits because we
can't just assume BYTE[] == LONG[] */
#ifdef _BIG_WORDS
#define copyToLong(dest,src,count) \
{ \
LONG *destPtr = ( LONG * ) dest; \
BYTE *srcPtr = src; \
int i; \
for( i = 0; i < count / 4; i++ ) \
{ \
destPtr[ i ] = mgetLong( srcPtr ); \
} \
}
#else
#define copyToLong(dest,src,count) \
memcpy( dest, src, count )
#endif /* _BIG_WORDS */
/* Versions of the above which are guaranteed to always be big or
little-endian (these are needed for some algorithms where the external
data format is always little-endian, eg anything designed by Ron
Rivest) */
#define mgetBWord(memPtr) \
( ( WORD ) memPtr[ 0 ] << 8 ) | ( ( WORD ) memPtr[ 1 ] ); \
memPtr += 2
#define mputBWord(memPtr,data) \
memPtr[ 0 ] = ( BYTE ) ( ( ( data ) >> 8 ) & 0xFF ); \
memPtr[ 1 ] = ( BYTE ) ( ( data ) & 0xFF ); \
memPtr += 2
#define mgetBLong(memPtr) \
( ( ( LONG ) memPtr[ 0 ] << 24 ) | ( ( LONG ) memPtr[ 1 ] << 16 ) | \
( ( LONG ) memPtr[ 2 ] << 8 ) | ( LONG ) memPtr[ 3 ] ); \
memPtr += 4
#define mputBLong(memPtr,data) \
memPtr[ 0 ] = ( BYTE ) ( ( ( data ) >> 24 ) & 0xFF ); \
memPtr[ 1 ] = ( BYTE ) ( ( ( data ) >> 16 ) & 0xFF ); \
memPtr[ 2 ] = ( BYTE ) ( ( ( data ) >> 8 ) & 0xFF ); \
memPtr[ 3 ] = ( BYTE ) ( ( data ) & 0xFF ); \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -