📄 obj_acc.c
字号:
return( CRYPT_ERROR_PERMISSION );
}
/* It's a valid object, get its info */
objectInfoPtr = &objectTable[ objectHandle ];
STORE_ORIGINAL_INT( lockCount, objectInfoPtr->lockCount );
objectInfoPtr->lockCount--;
/* Postcondition: The object's lock count has been decremented and is
non-negative */
POST( objectInfoPtr->lockCount == \
ORIGINAL_VALUE( lockCount ) - 1 );
POST( objectInfoPtr->lockCount >= 0 );
MUTEX_UNLOCK( objectTable );
return( CRYPT_OK );
}
/****************************************************************************
* *
* Init/Shutdown Functions *
* *
****************************************************************************/
int initObjectAltAccess( KERNEL_DATA *krnlDataPtr )
{
/* Set up the reference to the kernel data block */
krnlData = krnlDataPtr;
return( CRYPT_OK );
}
void endObjectAltAccess( void )
{
krnlData = NULL;
}
/****************************************************************************
* *
* Direct Object Access Functions *
* *
****************************************************************************/
/* Acquire/release an object */
int krnlAcquireObject( const int objectHandle, const OBJECT_TYPE type,
void **objectPtr, const int errorCode )
{
return( getObject( objectHandle, type, ACCESS_CHECK_EXTERNAL,
objectPtr, errorCode ) );
}
int krnlReleaseObject( const int objectHandle )
{
return( releaseObject( objectHandle, ACCESS_CHECK_EXTERNAL_RELEASE ) );
}
/* Relinquish ownership of the system object to another thread. This
procedure is needed to allow a background polling thread to add entropy
to the system device. The way it works is that the calling thread hands
ownership over to the polling thread and suspends itself until the
polling thread completes. When the polling thread has completed, it
terminates, whereupon the original thread wakes up and reacquires
ownership. The value passed to the release call is actually a thread ID,
but since this type isn't visible outside the kernel we just us a generic
int */
int krnlRelinquishSystemObject( const int /* THREAD_HANDLE */ objectOwner )
{
OBJECT_INFO *objectTable = krnlData->objectTable;
#ifdef USE_THREADS
OBJECT_INFO *objectInfoPtr = &objectTable[ SYSTEM_OBJECT_HANDLE ];
#endif /* USE_THREADS */
/* Preconditions: The object is valid and in use */
PRE( isValidObject( SYSTEM_OBJECT_HANDLE ) );
PRE( isInUse( SYSTEM_OBJECT_HANDLE ) );
MUTEX_LOCK( objectTable );
/* Precondition: We're relinquishing ownership, we must currently be
the owner */
PRE( isObjectOwner( SYSTEM_OBJECT_HANDLE ) );
/* Check that the access is valid */
if( !isValidObject( SYSTEM_OBJECT_HANDLE ) || \
!isInUse( SYSTEM_OBJECT_HANDLE ) || \
!checkObjectOwnership( objectTable[ SYSTEM_OBJECT_HANDLE ] ) )
{
MUTEX_UNLOCK( objectTable );
assert( NOTREACHED );
return( CRYPT_ERROR_PERMISSION );
}
#ifdef USE_THREADS
objectInfoPtr->lockOwner = ( THREAD_HANDLE ) objectOwner;
#endif /* USE_THREADS */
MUTEX_UNLOCK( objectTable );
return( CRYPT_OK );
}
int krnlReacquireSystemObject( void )
{
#ifdef USE_THREADS
OBJECT_INFO *objectInfoPtr = &krnlData->objectTable[ SYSTEM_OBJECT_HANDLE ];
#endif /* USE_THREADS */
/* Preconditions: The object is valid and in use */
PRE( isValidObject( SYSTEM_OBJECT_HANDLE ) );
PRE( isInUse( SYSTEM_OBJECT_HANDLE ) );
MUTEX_LOCK( objectTable );
/* Precondition: Since we're reacquiring ownership, we're not currently
the owner */
PRE( !isObjectOwner( SYSTEM_OBJECT_HANDLE ) );
/* Check that the access is valid */
if( !isValidObject( SYSTEM_OBJECT_HANDLE ) || \
!isInUse( SYSTEM_OBJECT_HANDLE ) )
{
MUTEX_UNLOCK( objectTable );
assert( NOTREACHED );
return( CRYPT_ERROR_PERMISSION );
}
#ifdef USE_THREADS
objectInfoPtr->lockOwner = THREAD_SELF();
#endif /* USE_THREADS */
MUTEX_UNLOCK( objectTable );
return( CRYPT_OK );
}
/****************************************************************************
* *
* Key Extract Functions *
* *
****************************************************************************/
/* The cryptlib equivalent of trusted downgraders in other security models:
Functions that extract a key from a context. These functions need to
bypass the kernel's security checking in order to allow key export and
are the only ones that can do this. This is an unavoidable requirement
in the complete-isolation model - some bypass mechanism needs to be
present in order to allow a key to be exported from an encryption action
object. The three functions that perform the necessary operations are:
extractKeyData: Extract a session key from a conventional/MAC context
prior to encryption with a KEK.
exportPrivateKey: Write private key data to a stream prior to encryption
with a KEK.
importPrivateKey: Read private key data from a stream after decryption
with a KEK */
#define PKC_CONTEXT /* Indicate that we're working with PKC context */
#if defined( INC_ALL )
#include "context.h"
#elif defined( INC_CHILD )
#include "../context/context.h"
#else
#include "context/context.h"
#endif /* Compiler-specific includes */
int extractKeyData( const CRYPT_CONTEXT iCryptContext, void *keyData )
{
CONTEXT_INFO *contextInfoPtr;
int status;
/* Clear return value */
memset( keyData, 0, bitsToBytes( MIN_KEYSIZE_BITS ) );
/* Make sure that we've been given a conventional encryption or MAC
context with a key loaded. This has already been checked at a higher
level, but we perform a sanity check here to be safe */
status = getObject( iCryptContext, OBJECT_TYPE_CONTEXT,
ACCESS_CHECK_KEYACCESS,
( void ** ) &contextInfoPtr, CRYPT_ARGERROR_OBJECT );
if( cryptStatusError( status ) )
return( status );
if( ( contextInfoPtr->type != CONTEXT_CONV && \
contextInfoPtr->type != CONTEXT_MAC ) || \
!( contextInfoPtr->flags & CONTEXT_KEY_SET ) )
{
releaseObject( iCryptContext, ACCESS_CHECK_KEYACCESS );
return( CRYPT_ARGERROR_OBJECT );
}
/* Export the key data from the context */
switch( contextInfoPtr->type )
{
case CONTEXT_CONV:
memcpy( keyData, contextInfoPtr->ctxConv->userKey,
contextInfoPtr->ctxConv->userKeyLength );
break;
case CONTEXT_MAC:
memcpy( keyData, contextInfoPtr->ctxMAC->userKey,
contextInfoPtr->ctxMAC->userKeyLength );
break;
default:
assert( NOTREACHED );
status = CRYPT_ARGERROR_OBJECT;
}
releaseObject( iCryptContext, ACCESS_CHECK_KEYACCESS );
return( status );
}
int exportPrivateKeyData( STREAM *stream, const CRYPT_CONTEXT iCryptContext,
const KEYFORMAT_TYPE formatType )
{
CONTEXT_INFO *contextInfoPtr;
int status;
/* Make sure that we've been given a PKC context with a private key
loaded. This has already been checked at a higher level, but we
perform a sanity check here to be safe */
status = getObject( iCryptContext, OBJECT_TYPE_CONTEXT,
ACCESS_CHECK_KEYACCESS,
( void ** ) &contextInfoPtr, CRYPT_ARGERROR_OBJECT );
if( cryptStatusError( status ) )
return( status );
if( contextInfoPtr->type != CONTEXT_PKC ||
!( contextInfoPtr->flags & CONTEXT_KEY_SET ) || \
( contextInfoPtr->flags & CONTEXT_ISPUBLICKEY ) )
{
releaseObject( iCryptContext, ACCESS_CHECK_KEYACCESS );
return( CRYPT_ARGERROR_OBJECT );
}
/* Export the key data from the context */
status = contextInfoPtr->ctxPKC->writePrivateKeyFunction( stream,
contextInfoPtr, formatType, "private" );
releaseObject( iCryptContext, ACCESS_CHECK_KEYACCESS );
return( status );
}
int importPrivateKeyData( STREAM *stream, const CRYPT_CONTEXT iCryptContext,
const KEYFORMAT_TYPE formatType )
{
CONTEXT_INFO *contextInfoPtr;
int status;
/* Make sure that we've been given a PKC context with no private key
loaded. This has already been checked at a higher level, but we
perform a sanity check here to be safe */
status = getObject( iCryptContext, OBJECT_TYPE_CONTEXT,
ACCESS_CHECK_KEYACCESS,
( void ** ) &contextInfoPtr, CRYPT_ARGERROR_OBJECT );
if( cryptStatusError( status ) )
return( status );
if( contextInfoPtr->type != CONTEXT_PKC ||
( contextInfoPtr->flags & CONTEXT_KEY_SET ) || \
( contextInfoPtr->flags & CONTEXT_ISPUBLICKEY ) )
{
releaseObject( iCryptContext, ACCESS_CHECK_KEYACCESS );
return( CRYPT_ARGERROR_OBJECT );
}
/* Import the key data into the context */
status = contextInfoPtr->ctxPKC->readPrivateKeyFunction( stream,
contextInfoPtr, formatType );
if( cryptStatusOK( status ) )
{
/* If everything went OK, perform an internal load that uses the
values already present in the context */
status = contextInfoPtr->loadKeyFunction( contextInfoPtr, NULL, 0 );
if( cryptStatusOK( status ) )
{
krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE,
MESSAGE_VALUE_UNUSED,
CRYPT_IATTRIBUTE_INITIALISED );
contextInfoPtr->flags |= CONTEXT_KEY_SET;
}
else
if( cryptArgError( status ) )
/* Map the status to a more appropriate code */
status = CRYPT_ERROR_BADDATA;
}
releaseObject( iCryptContext, ACCESS_CHECK_KEYACCESS );
return( status );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -