📄 scorebrd.c
字号:
assert( isWritePtr( scoreboardInfo, sizeof( SCOREBOARD_INFO ) ) );
assert( isReadPtr( key, keyLength ) && keyLength >= 8 );
assert( ( value == NULL && valueLength == 0 ) || \
isReadPtr( value, valueLength ) );
assert( ( action == SCOREBOARD_ACTION_PRESENCECHECK && value == NULL ) || \
( action == SCOREBOARD_ACTION_LOOKUP && value != NULL ) || \
( action == SCOREBOARD_ACTION_ADD && value != NULL ) );
assert( isWritePtr( scoreboardIndex,
scoreboardInfo->size * sizeof( SCOREBOARD_INDEX ) ) );
assert( isWritePtr( scoreboardData,
scoreboardInfo->size * sizeof( SCOREBOARD_DATA ) ) );
/* If there's something wrong with the time, we can't perform (time-
based) scoreboard management */
if( currentTime <= MIN_TIME_VALUE )
return( SCOREBOARD_UNIQUEID_NONE );
status = krnlEnterMutex( MUTEX_SCOREBOARD );
if( cryptStatusError( status ) )
return( status );
/* Try and find this entry in the scoreboard */
status = findEntry( scoreboardInfo, key, keyLength, currentTime,
&position );
assert( position >= 0 && position < scoreboardInfo->size );
if( cryptStatusError( status ) )
{
/* No match found, if we're adding a new entry, add it at the
appropriate location */
if( action == SCOREBOARD_ACTION_ADD )
uniqueID = addEntry( scoreboardInfo, position, key, keyLength,
value, valueLength, currentTime );
}
else
{
SCOREBOARD_INDEX *scorebordIndexEntry = &scoreboardIndex[ position ];
SCOREBOARD_DATA *scoreboardDataEntry = &scoreboardData[ position ];
/* If we're trying to add an entry that matches an existing key,
clear the existing entry and don't add the new one. Attempting
to re-add a value using an existing key is a sign that something
suspicious is going on, if we simply ignore the add attempt then
it'll appear to the caller that we've added the new value when in
fact we've retained the old value. If on the other hand we
overwrite the old value with the new one it'll allow an attacker
to replace existing scoreboard contents with attacker-controlled
ones */
if( action == SCOREBOARD_ACTION_ADD )
{
scoreboardIndex[ position ] = SCOREBOARD_INDEX_TEMPLATE;
zeroise( scoreboardDataEntry, sizeof( SCOREBOARD_DATA ) );
uniqueID = SCOREBOARD_UNIQUEID_NONE;
}
else
{
/* If we're looking for an existing entry return its data and
update the last-access date */
if( action == SCOREBOARD_ACTION_LOOKUP )
{
memcpy( value, scoreboardDataEntry, SCOREBOARD_DATA_SIZE );
scorebordIndexEntry->timeStamp = currentTime;
}
uniqueID = scorebordIndexEntry->uniqueID;
}
}
krnlExitMutex( MUTEX_SCOREBOARD );
return( uniqueID );
}
/****************************************************************************
* *
* Scoreboard Access Functions *
* *
****************************************************************************/
/* Add and delete entries to/from the scoreboard. These are just wrappers
for the local scoreboard-access function, for use by external code */
int findScoreboardEntry( SCOREBOARD_INFO *scoreboardInfo,
const void *key, const int keyLength,
void *value, const int maxValueLength,
int *valueLength )
{
int resumedSessionID;
assert( isWritePtr( scoreboardInfo, sizeof( SCOREBOARD_INFO ) ) );
assert( isReadPtr( key, keyLength ) );
assert( isWritePtr( value, maxValueLength ) );
assert( isWritePtr( valueLength, sizeof( int ) ) );
/* Clear return value */
memset( value, 0, maxValueLength );
*valueLength = 0;
resumedSessionID = handleScoreboard( scoreboardInfo,
SCOREBOARD_ACTION_LOOKUP,
key, keyLength, value, maxValueLength );
if( resumedSessionID != SCOREBOARD_UNIQUEID_NONE )
*valueLength = SCOREBOARD_DATA_SIZE;
return( resumedSessionID );
}
int findScoreboardEntryID( SCOREBOARD_INFO *scoreboardInfo,
const void *key, const int keyLength )
{
assert( isWritePtr( scoreboardInfo, sizeof( SCOREBOARD_INFO ) ) );
assert( isReadPtr( key, keyLength ) );
return( handleScoreboard( scoreboardInfo, SCOREBOARD_ACTION_PRESENCECHECK,
key, keyLength, NULL, 0 ) );
}
int addScoreboardEntry( SCOREBOARD_INFO *scoreboardInfo,
const void *key, const int keyLength,
const void *value, const int valueLength )
{
assert( isWritePtr( scoreboardInfo, sizeof( SCOREBOARD_INFO ) ) );
assert( isReadPtr( key, keyLength ) );
assert( isReadPtr( value, valueLength ) && \
valueLength <= SCOREBOARD_DATA_SIZE );
/* Add the entry to the scoreboard */
return( handleScoreboard( scoreboardInfo, SCOREBOARD_ACTION_ADD,
key, keyLength, ( void * ) value, valueLength ) );
}
void deleteScoreboardEntry( SCOREBOARD_INFO *scoreboardInfo,
const int uniqueID )
{
SCOREBOARD_INDEX *scoreboardIndex = scoreboardInfo->index;
SCOREBOARD_DATA *scoreboardData = scoreboardInfo->data;
int i, status;
assert( isWritePtr( scoreboardInfo, sizeof( SCOREBOARD_INFO ) ) );
assert( uniqueID > SCOREBOARD_UNIQUEID_NONE );
status = krnlEnterMutex( MUTEX_SCOREBOARD );
if( cryptStatusError( status ) )
return;
/* Search the scoreboard for the entry with the given ID */
for( i = 0; i < scoreboardInfo->lastEntry && \
i < FAILSAFE_ITERATIONS_MAX; i++ )
{
SCOREBOARD_INDEX *scorebordIndexEntry = &scoreboardIndex[ i ];
/* If we've found the entry that we're after, clear it and exit */
if( scorebordIndexEntry->uniqueID == uniqueID )
{
scoreboardIndex[ i ] = SCOREBOARD_INDEX_TEMPLATE;
zeroise( scoreboardData[ i ], sizeof( SCOREBOARD_DATA ) );
break;
}
}
if( i >= FAILSAFE_ITERATIONS_MAX )
retIntError_Void();
krnlExitMutex( MUTEX_SCOREBOARD );
}
/****************************************************************************
* *
* Scoreboard Init/Shutdown *
* *
****************************************************************************/
/* Initialise and shut down the scoreboard */
int initScoreboard( SCOREBOARD_INFO *scoreboardInfo,
const int scoreboardSize )
{
SCOREBOARD_INDEX *scoreboardIndex;
int i, status;
assert( isWritePtr( scoreboardInfo, sizeof( SCOREBOARD_INFO ) ) );
assert( scoreboardSize > 16 && scoreboardSize <= 8192 );
status = krnlEnterMutex( MUTEX_SCOREBOARD );
if( cryptStatusError( status ) )
return( status );
/* Initialise the scoreboard */
memset( scoreboardInfo, 0, sizeof( SCOREBOARD_INFO ) );
scoreboardInfo->uniqueID = SCOREBOARD_UNIQUEID_NONE + 1;
scoreboardInfo->lastEntry = 0;
scoreboardInfo->size = scoreboardSize;
/* Initialise the scoreboard data */
if( ( scoreboardInfo->index = clAlloc( "initScoreboard", \
scoreboardSize * sizeof( SCOREBOARD_INDEX ) ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
status = krnlMemalloc( &scoreboardInfo->data, \
scoreboardSize * sizeof( SCOREBOARD_DATA ) );
if( cryptStatusError( status ) )
{
clFree( "initScoreboard", scoreboardInfo->index );
memset( scoreboardInfo, 0, sizeof( SCOREBOARD_INFO ) );
return( status );
}
scoreboardIndex = scoreboardInfo->index;
for( i = 0; i < scoreboardSize; i++ )
scoreboardIndex[ i ] = SCOREBOARD_INDEX_TEMPLATE;
memset( scoreboardInfo->data, 0, scoreboardSize * \
sizeof( SCOREBOARD_DATA ) );
krnlExitMutex( MUTEX_SCOREBOARD );
return( CRYPT_OK );
}
void endScoreboard( SCOREBOARD_INFO *scoreboardInfo )
{
int status;
assert( isWritePtr( scoreboardInfo, sizeof( SCOREBOARD_INFO ) ) );
/* Shut down the scoreboard. We acquire the mutex while we're doing
this to ensure that any threads still using it have exited before we
destroy it. Exactly what to do if we can't acquire the mutex is a
bit complicated. Since failing to acquire the mutex is a special-
case exception condition it's not even possible to plan for this
since it's uncertain under which conditions (if ever) this situation
would occur. For now we play it by the book and don't do anything if
we can't acquire the mutex, which is at least consistent */
status = krnlEnterMutex( MUTEX_SCOREBOARD );
if( cryptStatusError( status ) )
retIntError_Void();
/* Clear and free the scoreboard */
krnlMemfree( ( void ** ) &scoreboardInfo->data );
zeroise( scoreboardInfo->index, \
scoreboardInfo->size * sizeof( SCOREBOARD_INDEX ) );
clFree( "endScoreboard", scoreboardInfo->index );
memset( scoreboardInfo, 0, sizeof( SCOREBOARD_INFO ) );
krnlExitMutex( MUTEX_SCOREBOARD );
}
#endif /* USE_SSL */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -