📄 cryptacm.h
字号:
/****************************************************************************
* *
* Mechanism Permission Information *
* Copyright Peter Gutmann 1999-2001 *
* *
****************************************************************************/
#ifndef _CRYPTACM_DEFINED
#define _CRYPTACM_DEFINED
/* Various includes and defines needed for range checking */
#include <limits.h> /* For INT_MAX */
/****************************************************************************
* *
* Crypto Mechanism ACL Handling *
* *
****************************************************************************/
/* Each mechanism has a mandatory ACL associated with it which controls the
parameters which may be passed to the mechanism. The ACL is enforced by
the kernel before dispatching mechanism-invocation messages to an object.
For example an attempt to write an internal object to a keyset or device
object using an external message wouldn't even make it to the object,
it'd be rejected immediately by the kernel.
Each mechanism ACL consists of a list of ACLs for the parameters used in
invoking the mechanism. The first entry in the parameter ACL is the
parameter's type. The basic values are boolean, numeric, or byte string,
there are also some special types such as object handles which place
extra constraints on the attribute */
typedef enum {
MECHPARAM_VALUE_NONE, /* Non-value */
MECHPARAM_VALUE_BOOLEAN, /* Boolean flag */
MECHPARAM_VALUE_NUMERIC, /* Numeric value */
MECHPARAM_VALUE_STRING, /* Byte string */
MECHPARAM_VALUE_STRING_OPT, /* Byte string or (NULL, 0) */
MECHPARAM_VALUE_STRING_NONE, /* Empty (NULL, 0) string */
MECHPARAM_VALUE_OBJECT, /* Object handle */
MECHPARAM_VALUE_UNUSED /* CRYPT_UNUSED */
} MECHPARAM_VALUE_TYPE;
/* In addition to the range and subtype-checking information, there are also
some general flags which control special-case handling. The flags are:
FLAG_ROUTE_TO_CTX
Whether routing should be applied to an object to locate and
underlying context. The need to apply routing is unfortunate but is
required in order to apply the subtype check to PKC objects, sorting
out which (pre-routed) object types are permissible is beyond the
scope of the mechanism validation routines which would have to take
into consideration the intricacies of all manner of certificate
objects paired with public and private keys */
#define MECHANISM_FLAG_ROUTE_TO_CTX 0x01
/* Each mechanism parameter has a parameter ACL entry which defines the
type and valid values for that mechanism. A list of these constitutes
a mechanism ACL */
typedef struct {
const MECHPARAM_VALUE_TYPE valueType; /* Parameter value type */
const int lowRange, highRange; /* Min/max value or length */
const int flags; /* General flags */
const unsigned int subTypeA, subTypeB;
/* Object subtypes for which param.valid */
} MECHANISM_PARAM_ACL;
/* A mechanism ACL is comprised of a list of mechanism parameter ACLs */
typedef struct {
const MECHANISM_TYPE type; /* Mechanism type */
const MECHANISM_PARAM_ACL paramACL[5];
/* Parameter ACL information */
} MECHANISM_ACL;
/* Macros to make it easy to set up mechanism ACL's. We have one for each of
the basic types and a few additional ones which provide more control over
the values */
#define MKACM_B() \
{ MECHPARAM_VALUE_BOOLEAN, 0, 0, 0, 0, 0 }
#define MKACM_N( min, max ) \
{ MECHPARAM_VALUE_NUMERIC, min, max, 0, 0, 0 }
#define MKACM_S( minLen, maxLen ) \
{ MECHPARAM_VALUE_STRING, minLen, maxLen, 0, 0, 0 }
#define MKACM_S_OPT( minLen, maxLen ) \
{ MECHPARAM_VALUE_STRING_OPT, minLen, maxLen, 0, 0, 0 }
#define MKACM_S_NONE() \
{ MECHPARAM_VALUE_STRING_NONE, 0, 0, 0, 0, 0 }
#define MKACM_O( subTypeA, subTypeB ) \
{ MECHPARAM_VALUE_OBJECT, 0, 0, 0, subTypeA, subTypeB }
#define MKACM_O_EX( subTypeA, subTypeB, flags ) \
{ MECHPARAM_VALUE_OBJECT, 0, 0, flags, subTypeA, subTypeB }
#define MKACM_UNUSED() \
{ MECHPARAM_VALUE_UNUSED, 0, 0, 0, 0, 0 }
/* End-of-mechanism-ACL marker */
#define MKACM_END() \
{ MECHPARAM_VALUE_NONE, 0, 0, 0, 0 }
/* Macro to access the ACL information for a given parameter in a list of
mechanism parameter ACLs, and to get the subtype of an object */
#define paramInfo( mechanismACL, paramNo ) mechanismACL->paramACL[ paramNo ]
#define objectST( objectHandle ) objectTable[ objectHandle ].subType
/* Macros to check each parameter against an ACL entry */
#define checkMechParamNumeric( paramACL, value ) \
( ( paramACL.valueType == MECHPARAM_VALUE_BOOLEAN && \
( value == TRUE || value == FALSE ) ) || \
( paramACL.valueType == MECHPARAM_VALUE_NUMERIC && \
( value >= paramACL.lowRange && value <= paramACL.highRange ) ) )
#define checkMechParamString( paramACL, data, dataLen ) \
( ( ( paramACL.valueType == MECHPARAM_VALUE_STRING_NONE || \
paramACL.valueType == MECHPARAM_VALUE_STRING_OPT ) && \
data == NULL && dataLen == 0 ) || \
( ( paramACL.valueType == MECHPARAM_VALUE_STRING || \
paramACL.valueType == MECHPARAM_VALUE_STRING_OPT ) && \
data != NULL && ( dataLen >= paramACL.lowRange && \
dataLen <= paramACL.highRange ) ) )
#define checkMechParamObject( paramACL, objectHandle ) \
( ( paramACL.valueType == MECHPARAM_VALUE_UNUSED && \
objectHandle == CRYPT_UNUSED ) || \
( paramACL.valueType == MECHPARAM_VALUE_OBJECT && \
( ( paramACL.subTypeA & objectST( objectHandle ) ) == \
objectST( objectHandle ) || \
( paramACL.subTypeB & objectST( objectHandle ) ) == \
objectST( objectHandle ) ) ) )
/* The ACL tables for each mechanism class */
static const MECHANISM_ACL mechanismWrapACL[] = {
{ MECHANISM_PKCS1, /* PKCS #1 encrypt */
{ MKACM_S_OPT( 64, CRYPT_MAX_PKCSIZE ),/* Wrapped key */
MKACM_S_NONE(),
MKACM_O( ST_CTX_CONV | ST_CTX_MAC, ST_NONE ),/* Ctx containing key */
MKACM_O_EX( ST_CTX_PKC, ST_NONE, /* Wrap PKC context */
MECHANISM_FLAG_ROUTE_TO_CTX ),
MKACM_UNUSED() } },
{ MECHANISM_PKCS1_PGP, /* PKCS #1 encrypt using PGP formatting */
{ MKACM_S_OPT( 64, CRYPT_MAX_PKCSIZE ),/* Wrapped key */
MKACM_S_NONE(),
MKACM_O( ST_CTX_CONV, ST_NONE ), /* Ctx containing key */
MKACM_O_EX( ST_CTX_PKC, ST_NONE, /* Wrap PKC context */
MECHANISM_FLAG_ROUTE_TO_CTX ),
MKACM_UNUSED() } },
{ MECHANISM_PKCS1_RAW, /* PKCS #1 encrypt of raw data */
{ MKACM_S_OPT( 64, CRYPT_MAX_PKCSIZE ),/* Wrapped raw data */
MKACM_S( 8, CRYPT_MAX_KEYSIZE ), /* Raw data */
MKACM_UNUSED(),
MKACM_O_EX( ST_CTX_PKC, ST_NONE, /* Wrap PKC context */
MECHANISM_FLAG_ROUTE_TO_CTX ),
MKACM_UNUSED() } },
{ MECHANISM_CMS, /* CMS key wrap */
{ MKACM_S_OPT( 8 + 8, CRYPT_MAX_KEYSIZE + 16 ),/* Wrapped key */
MKACM_S_NONE(),
MKACM_O( ST_CTX_CONV | ST_CTX_MAC, ST_NONE ),/* Ctx containing key */
MKACM_O( ST_CTX_CONV, ST_NONE ), /* Wrap context */
MKACM_UNUSED() } },
{ MECHANISM_KEA, /* KEA key agreement */
{ MKACM_S( 140, 140 ), /* sizeof( TEK( MEK ) + Ra ) */
MKACM_S_NONE(),
MKACM_O( ST_CTX_CONV, ST_NONE ), /* Skipjack session key */
MKACM_O_EX( ST_CTX_PKC, ST_NONE, /* Recipient KEA pubkey */
MECHANISM_FLAG_ROUTE_TO_CTX ),
MKACM_O( ST_CTX_PKC, ST_NONE ) } }, /* Sender KEA privkey */
{ MECHANISM_PRIVATEKEYWRAP, /* Private key wrap */
{ MKACM_S_OPT( 16, MAX_PRIVATE_KEYSIZE ),/* Wrapped key */
MKACM_S_NONE(), /* Ctx containing private key */
MKACM_O_EX( ST_CTX_PKC, ST_NONE,
MECHANISM_FLAG_ROUTE_TO_CTX ),
MKACM_O( ST_CTX_CONV, ST_NONE ), /* Wrap context */
MKACM_UNUSED() } },
{ MECHANISM_NONE,
{ MKACM_END() } }
};
static const MECHANISM_ACL mechanismUnwrapACL[] = {
{ MECHANISM_PKCS1, /* PKCS #1 decrypt */
{ MKACM_S_OPT( 60, CRYPT_MAX_PKCSIZE ),/* Wrapped key */
MKACM_S_NONE(),
MKACM_O( ST_CTX_CONV | ST_CTX_MAC, ST_NONE ),/* Ctx to contain key */
MKACM_O_EX( ST_CTX_PKC, ST_NONE, /* Unwrap PKC context */
MECHANISM_FLAG_ROUTE_TO_CTX ),
MKACM_UNUSED() } },
{ MECHANISM_PKCS1_PGP, /* PKCS #1 decrypt using PGP formatting */
{ MKACM_S_OPT( 60, CRYPT_MAX_PKCSIZE ),/* Wrapped key */
MKACM_S_NONE(),
MKACM_UNUSED(), /* Placeholder for ctx to contain key */
MKACM_O_EX( ST_CTX_PKC, ST_NONE, /* Unwrap PKC context */
MECHANISM_FLAG_ROUTE_TO_CTX ),
MKACM_UNUSED() } },
{ MECHANISM_PKCS1_RAW, /* PKCS #1 decrypt of raw data */
{ MKACM_S_OPT( 64, CRYPT_MAX_PKCSIZE ),/* Wrapped raw data */
MKACM_S( 8, CRYPT_MAX_PKCSIZE ), /* Raw data */
MKACM_UNUSED(),
MKACM_O_EX( ST_CTX_PKC, ST_NONE, /* Unwrap PKC context */
MECHANISM_FLAG_ROUTE_TO_CTX ),
MKACM_UNUSED() } },
{ MECHANISM_CMS, /* CMS key unwrap */
{ MKACM_S( 8 + 8, CRYPT_MAX_KEYSIZE + 16 ),/* Wrapped key */
MKACM_S_NONE(),
MKACM_O( ST_CTX_CONV | ST_CTX_MAC, ST_NONE ),/* Ctx to contain key */
MKACM_O( ST_CTX_CONV, ST_NONE ), /* Unwrap context */
MKACM_UNUSED() } },
{ MECHANISM_KEA, /* KEA key agreement */
{ MKACM_S( 140, 140 ), /* sizeof( TEK( MEK ) + Ra ) */
MKACM_S_NONE(),
MKACM_O( ST_CTX_CONV, ST_NONE ), /* Skipjack session key */
MKACM_O( ST_CTX_PKC, ST_NONE ), /* Recipient KEA privkey */
MKACM_O_EX( ST_CTX_PKC, ST_NONE, /* Sender KEA pubkey */
MECHANISM_FLAG_ROUTE_TO_CTX ) } },
{ MECHANISM_PRIVATEKEYWRAP, /* Private key unwrap */
{ MKACM_S( 16, MAX_PRIVATE_KEYSIZE ), /* Wrapped key */
MKACM_S_NONE(),
MKACM_O( ST_CTX_PKC, ST_NONE ), /* Ctx to contain private key */
MKACM_O( ST_CTX_CONV, ST_NONE ), /* Unwrap context */
MKACM_UNUSED() } },
{ MECHANISM_NONE,
{ MKACM_END() } }
};
static const MECHANISM_ACL mechanismSignACL[] = {
{ MECHANISM_PKCS1, /* PKCS #1 sign */
{ MKACM_S_OPT( 64, CRYPT_MAX_PKCSIZE ),/* Signature */
MKACM_O( ST_CTX_HASH, ST_NONE ), /* Hash context */
MKACM_O_EX( ST_CTX_PKC, ST_NONE, /* Signing context */
MECHANISM_FLAG_ROUTE_TO_CTX ) } },
{ MECHANISM_NONE,
{ MKACM_END() } }
};
static const MECHANISM_ACL mechanismSigCheckACL[] = {
{ MECHANISM_PKCS1, /* PKCS #1 sig check */
{ MKACM_S( 60, CRYPT_MAX_PKCSIZE ), /* Signature */
MKACM_O( ST_CTX_HASH, ST_NONE ), /* Hash context */
MKACM_O_EX( ST_CTX_PKC, ST_NONE, /* Sig.check context */
MECHANISM_FLAG_ROUTE_TO_CTX ) } },
{ MECHANISM_NONE,
{ MKACM_END() } }
};
static const MECHANISM_ACL mechanismDeriveACL[] = {
{ MECHANISM_PKCS5, /* PKCS #5 derive */
{ MKACM_S( 1, CRYPT_MAX_KEYSIZE ), /* Key data */
MKACM_S( 2, MAX_ATTRIBUTE_SIZE ), /* Keying material */
MKACM_N( CRYPT_ALGO_SHA, CRYPT_ALGO_SHA ),/* Hash algo */
MKACM_S( 4, 512 ), /* Salt */
MKACM_N( 1, INT_MAX ) } }, /* Iterations */
{ MECHANISM_SSL, /* SSL derive */
{ MKACM_S( 48, 512 ), /* Master secret/key data */
MKACM_S( 48, 512 ), /* Premaster secret/master secret */
MKACM_N( CRYPT_USE_DEFAULT, CRYPT_USE_DEFAULT ),/* SSL uses dual hash */
MKACM_S( 64, 64 ), /* Salt */
MKACM_N( 1, 1 ) } }, /* Iterations */
{ MECHANISM_TLS, /* TLS derive (the odd lower bounds on the output
and salt are needed when generating
the TLS hashed MAC) */
{ MKACM_S( 12, 512 ), /* Master secret/key data (usually 48) */
MKACM_S( 48, 512 ), /* Premaster secret/master secret */
MKACM_N( CRYPT_USE_DEFAULT, CRYPT_USE_DEFAULT ),/* TLS uses dual hash */
MKACM_S( 48, 512 ), /* Salt (usually 64) */
MKACM_N( 1, 1 ) } }, /* Iterations */
{ MECHANISM_CMP, /* CMP/Entrust derive */
{ MKACM_S( 20, 20 ), /* HMAC-SHA key */
MKACM_S( 1, 512 ), /* Key data */
MKACM_N( CRYPT_ALGO_SHA, CRYPT_ALGO_SHA ),/* Hash algo */
MKACM_S( 1, 512 ), /* Salt */
MKACM_N( 1, INT_MAX ) } }, /* Iterations */
{ MECHANISM_PGP, /* OpenPGP S2K derive */
{ MKACM_S( 16, CRYPT_MAX_KEYSIZE ), /* Key data */
MKACM_S( 2, MAX_ATTRIBUTE_SIZE ), /* Keying material */
MKACM_N( CRYPT_ALGO_MD5, CRYPT_ALGO_RIPEMD160 ),/* Hash algo */
MKACM_S( 8, 8 ), /* Salt */
MKACM_N( 0, INT_MAX ) } }, /* Iterations (0 = don't iterate) */
{ MECHANISM_NONE,
{ MKACM_END() } }
};
/* Functions to implement the checks in the mechanism ACL tables */
static int preDispatchCheckMechanismWrapAccess( const int objectHandle,
const RESOURCE_MESSAGE_TYPE message,
const void *messageDataPtr,
const int messageValue,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -