📄 crypt.h
字号:
signing/sig checking, so we cant just pass in a single buffer full of
data as we can with RSA. In addition the data length changes, for
example for a DSA sig we pass in a 20-byte hash and get back a ~50-byte
sig, for sig.checking we pass in a 20-byte hash and ~50-byte sig and get
back nothing. Because of this we have to use the following structure to
pass data to the DLP-based PKCs */
typedef struct {
const BYTE *inParam1, *inParam2; /* Input parameters */
BYTE *outParam; /* Output parameter */
int inLen1, inLen2, outLen; /* Parameter lengths */
CRYPT_FORMAT_TYPE formatType; /* Paramter format type */
} DLP_PARAMS;
#define setDLPParams( dlpDataPtr, dataIn, dataInLen, dataOut, dataOutLen ) \
{ \
memset( ( dlpDataPtr ), 0, sizeof( DLP_PARAMS ) ); \
( dlpDataPtr )->formatType = CRYPT_FORMAT_CRYPTLIB; \
( dlpDataPtr )->inParam1 = ( dataIn ); \
( dlpDataPtr )->inLen1 = ( dataInLen ); \
( dlpDataPtr )->outParam = ( dataOut ); \
( dlpDataPtr )->outLen = ( dataOutLen ); \
}
/* When calling key agreement functions we have to pass a mass of cruft
around instead of the usual flat data (even more than the generic DLP
parameter information) for which we use the following structure. The
public value is the public key value used for the agreement process,
typically y = g^x mod p for DH-like mechanisms. The ukm is the user
keying material, typically something which is mixed into the DH process
to make the new key unique. The wrapped key is the output (originator)/
input(recipient) to the keyagreement process. The session key context
contains a context into which the derived key is loaded. Typical
examples of use are:
PKCS #3: publicValue = y
Fortezza: publicValue = y, ukm = Ra, wrappedKey = TEK-wrapped MEK
S/MIME: publicValue = y, ukm = 512-bit nonce, wrappedKey = g^x mod p */
typedef struct {
BYTE publicValue[ CRYPT_MAX_PKCSIZE ];
int publicValueLen; /* Public key value */
BYTE ukm[ CRYPT_MAX_PKCSIZE ];
int ukmLen; /* User keying material */
BYTE wrappedKey[ CRYPT_MAX_PKCSIZE ];
int wrappedKeyLen; /* Wrapped key */
CRYPT_CONTEXT sessionKeyContext;/* Context for derived key */
} KEYAGREE_PARAMS;
/****************************************************************************
* *
* Useful General Macros *
* *
****************************************************************************/
/* Reasonably reliable way to get rid of unused argument warnings in a
compiler-independant manner */
#define UNUSED( arg ) ( ( arg ) = ( arg ) )
/* Although min() and max() aren't in the ANSI standard, most stdlib.h's have
them anyway for historical reasons. Just in case they're not defined
there by some pedantic compiler (some versions of Borland C do this), we
define them here */
#ifndef max
#define max( a, b ) ( ( ( a ) > ( b ) ) ? ( ( int ) ( a ) ) : \
( ( int ) ( b ) ) )
#endif /* !max */
#ifndef min
#define min( a, b ) ( ( ( a ) < ( b ) ) ? ( ( int ) ( a ) ) : \
( ( int ) ( b ) ) )
#endif /* !min */
/* Macros to convert to and from the bit counts used for some encryption
parameters */
#define bitsToBytes( bits ) ( ( ( bits ) + 7 ) >> 3 )
#define bytesToBits( bytes ) ( ( bytes ) << 3 )
/* Macro to round a value up to the nearest multiple of a second value,
second value a power of 2 */
#define roundUp( size, roundSize ) \
( ( ( size ) + ( ( roundSize ) - 1 ) ) & ~( ( roundSize ) - 1 ) )
/* A macro to clear sensitive data from memory. This is somewhat easier to
use than calling memset with the second parameter 0 all the time, and
makes it obvious where sensitive data is being erased */
#define zeroise( memory, size ) memset( memory, 0, size )
/* A macro to check that a value is a possibly valid handle. This doesn't
check that the handle refers to a valid object, merely that the value is
in the range for valid handles. The alternative function isValidHandle()
in cryptkrn.c does check that the handle (potentially) refers to a valid
object, being more than just a range check */
#define checkHandleRange( handle ) \
( ( handle ) > NO_SYSTEM_OBJECTS - 1 && ( handle ) < MAX_OBJECTS )
/* A macro to check whether an encryption mode needs an IV or not */
#define needsIV( mode ) ( ( mode ) == CRYPT_MODE_CBC || \
( mode ) == CRYPT_MODE_CFB || \
( mode ) == CRYPT_MODE_OFB )
/* A macro to check whether an algorithm is a pure stream cipher (that is,
a real stream cipher rather than a block cipher run in a stream mode) */
#define isStreamCipher( algorithm ) ( ( algorithm ) == CRYPT_ALGO_RC4 )
/* A macro to check whether an algorithm is regarded as being (relatively)
insecure or not. This is used by some of the higher-level internal
routines that normally use the default algorithm set in the configuration
database if nothing else is explicitly specified, but that specifically
check for the weaker algorithms and use something stronger instead if a
weak algorithm is specified. This is done both for luser-proofing and to
avoid possible problems from a trojan patching the configuration
database */
#define isWeakCryptAlgo( algorithm ) ( ( algorithm ) == CRYPT_ALGO_DES || \
( algorithm ) == CRYPT_ALGO_RC4 )
/* Macros to check whether a PKC algorithm is useful for a certain purpose or
requires special-case handling */
#define isSigAlgo( algorithm ) \
( ( algorithm ) == CRYPT_ALGO_RSA || ( algorithm ) == CRYPT_ALGO_DSA || \
( algorithm ) == CRYPT_ALGO_ELGAMAL )
#define isCryptAlgo( algorithm ) \
( ( algorithm ) == CRYPT_ALGO_RSA || ( algorithm ) == CRYPT_ALGO_ELGAMAL )
#define isKeyxAlgo( algorithm ) \
( ( algorithm ) == CRYPT_ALGO_DH || ( algorithm ) == CRYPT_ALGO_KEA )
#define isDlpAlgo( algorithm ) \
( ( algorithm ) == CRYPT_ALGO_DSA || ( algorithm ) == CRYPT_ALGO_ELGAMAL || \
( algorithm ) == CRYPT_ALGO_DH || ( algorithm ) == CRYPT_ALGO_KEA )
/* Almost all objects require object-subtype-specific amounts of memory to
store object information. In addition some objects such as certificates
contain arbitrary numbers of arbitrary-sized bits and pieces, most of
which are quite small. To avoid having to allocate worst-case sized
blocks of memory for objects (a problem in embedded environments) or large
numbers of tiny little blocks of memory for certificate attributes, we use
variable-length structures in which the payload is stored after the
structure, with a pointer inside the structure pointing into the payload
storage. To make this easier to handle, we use macros to set up and tear
down the necessary variables */
#define DECLARE_VARSTRUCT_VARS \
int storageSize; \
BYTE storage[ 1 ]
#define initVarStruct( structure, structureType, size ) \
memset( structure, 0, sizeof( structureType ) ); \
structure->value = structure->storage; \
structure->storageSize = size
#define copyVarStruct( destStructure, srcStructure, structureType ) \
memcpy( destStructure, srcStructure, \
sizeof( structureType ) + srcStructure->storageSize ); \
destStructure->value = destStructure->storage;
#define endVarStruct( structure, structureType ) \
zeroise( structure, sizeof( structureType ) + structure->storageSize )
#define sizeofVarStruct( structure, structureType ) \
( sizeof( structureType ) + structure->storageSize )
/* Clear/set object error information */
#define clearErrorInfo( objectInfoPtr ) \
{ \
( objectInfoPtr )->errorLocus = CRYPT_ATTRIBUTE_NONE; \
( objectInfoPtr )->errorType = CRYPT_OK; \
}
#define setErrorInfo( objectInfoPtr, locus, type ) \
{ \
( objectInfoPtr )->errorLocus = locus; \
( objectInfoPtr )->errorType = type; \
}
/* Insert a new element into singly-linked and doubly-lined lists. This is
the sort of thing we'd really need templates for */
#define insertSingleListElement( listHead, insertPoint, newElement ) \
{ \
if( *( listHead ) == NULL ) \
/* It's an empty list, make this the new list */ \
*( listHead ) = ( newElement ); \
else \
if( ( insertPoint ) == NULL ) \
{ \
/* We're inserting at the start of the list, make this the \
new first element */ \
( newElement )->next = *( listHead ); \
*( listHead ) = ( newElement ); \
} \
else \
{ \
/* Insert the element in the middle or the end of the list */ \
( newElement )->next = ( insertPoint )->next; \
( insertPoint )->next = ( newElement ); \
} \
}
#define insertDoubleListElements( listHead, insertPoint, newStartElement, newEndElement ) \
{ \
if( *( listHead ) == NULL ) \
/* If it's an empty list, make this the new list */ \
*( listHead ) = ( newStartElement ); \
else \
if( ( insertPoint ) == NULL ) \
{ \
/* We're inserting at the start of the list, make this the \
new first element */ \
( newEndElement )->next = *( listHead ); \
( *( listHead ) )->prev = ( newEndElement ); \
*( listHead ) = ( newStartElement ); \
} \
else \
{ \
/* Insert the element in the middle or the end of the list */ \
( newEndElement )->next = ( insertPoint )->next; \
\
/* Update the links for the next and previous elements */ \
if( ( insertPoint )->next != NULL ) \
( insertPoint )->next->prev = ( newEndElement ); \
( insertPoint )->next = ( newStartElement ); \
( newStartElement )->prev = ( insertPoint ); \
} \
}
#define insertDoubleListElement( listHead, insertPoint, newElement ) \
insertDoubleListElements( listHead, insertPoint, newElement, newElement )
/****************************************************************************
* *
* Object Class Functions *
* *
****************************************************************************/
/* Some operations apply to object classes rather than individual object
types. These have to be handled as globally visible functions rather than
object messages */
/****************************************************************************
* *
* Internal API Functions *
* *
****************************************************************************/
/* Internal forms of various external functions. These work with internal
resources that are marked as being inaccessible to the corresponding
external functions, and don't perform all the checking that their
external equivalents perform, since the parameters have already been
checked by cryptlib */
int iCryptCreateSignatureEx( void *signature, int *signatureLength,
const int sigMaxLength,
const CRYPT_FORMAT_TYPE formatType,
const CRYPT_CONTEXT iSignContext,
const CRYPT_CONTEXT iHashContext,
const CRYPT_CERTIFICATE iExtraData,
const CRYPT_SESSION iTspSession );
int iCryptCheckSignatureEx( const void *signature, const int signatureLength,
const CRYPT_FORMAT_TYPE formatType,
const CRYPT_HANDLE iSigCheckKey,
const CRYPT_CONTEXT iHashContext,
CRYPT_HANDLE *extraData );
int iCryptImportKeyEx( const void *encryptedKey, const int encryptedKeyLength,
const CRYPT_FORMAT_TYPE formatType,
const CRYPT_CONTEXT iImportKey,
const CRYPT_CONTEXT iSessionKeyContext,
CRYPT_CONTEXT *iReturnedContext );
int iCryptExportKeyEx( void *encryptedKey, int *encryptedKeyLength,
const int encryptedKeyMaxLength,
const CRYPT_FORMAT_TYPE formatType,
const CRYPT_CONTEXT iSessionKeyContext,
const CRYPT_CONTEXT iExportKey,
const CRYPT_CONTEXT iAuxContext );
/* Special-case certificate functions. The indirect-import function works
somewhat like the import cert messages, but reads certs by sending
get_next_cert messages to the message source and provides extended control
over the format of the imported object. The public-key read function
converts an X.509 SubjectPublicKeyInfo record into a context. The first
parameter for this function is actually a STREAM *, but we can't use this
here since STREAM * hasn't been defined yet.
Neither of these are strictly speaking certificate functions, but the
best place (meaning least inappropriate) place to put them is with the
cert-management code */
int iCryptImportCertIndirect( CRYPT_CERTIFICATE *iCertificate,
const CRYPT_HANDLE iCertSource,
const CRYPT_KEYID_TYPE keyIDtype,
const void *keyID, const int keyIDlength,
const int options );
int iCryptReadSubjectPublicKey( void *streamPtr, CRYPT_CONTEXT *iCryptContext,
const BOOLEAN deferredLoad );
/* Copy a string attribute to external storage, with various range checks
to follow the cryptlib semantics */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -