static void dummyEncrypt( const PERSONALITY_INFO *personalityInfoPtr, BYTE *data, const int length, const CRYPT_ALGO_TYPE cryptAlgo, const CRYPT_MODE_TYPE cryptMode ) { int i; assert( isReadPtr( personalityInfoPtr, sizeof( PERSONALITY_INFO ) ) ); assert( isWritePtr( data, length ) ); REQUIRES_V( cryptAlgo > CRYPT_ALGO_NONE && \ cryptAlgo < CRYPT_ALGO_LAST_EXTERNAL ); REQUIRES_V( cryptMode >= CRYPT_MODE_NONE && \ cryptMode < CRYPT_MODE_LAST ); if( isPkcAlgo( cryptAlgo ) ) { BYTE bignumData[ CRYPT_MAX_PKCSIZE + 8 ]; int bignumDataLength; bignumToExternal( bignumData, &bignumDataLength, personalityInfoPtr->keyInfo.pkcKeyInfo[ 0 ].data, personalityInfoPtr->keyInfo.pkcKeyInfo[ 0 ].dataSize ); for( i = 0; i < length; i++ ) data[ i ] ^= bignumData[ i ]; return; } /* We have to be a bit careful with the conventional encryption because the self-tests encrypt data in variable-length quantities to check for things like chaining problems, which means that for stream ciphers we really can't do anything more than repeatedly XOR with a fixed key byte */ if( cryptMode == CRYPT_MODE_CFB || cryptMode == CRYPT_MODE_OFB ) { const int keyDataOffset = CRYPT_MODE_CFB ? 0 : 1; for( i = 0; i < length; i++ ) data[ i ] ^= personalityInfoPtr->keyInfo.convKeyInfo[ keyDataOffset ]; } else { /* It's a block mode, we can at least use ECB, although we still can't chain because we don't know where we are in the data stream */ for( i = 0; i < length; i++ ) data[ i ] ^= personalityInfoPtr->keyInfo.convKeyInfo[ i % 16 ]; } }
static void sendErrorResponse( INOUT SESSION_INFO *sessionInfoPtr, INOUT SCEP_PROTOCOL_INFO *protocolInfo, IN_ERROR const int scepStatus ) { CRYPT_CERTIFICATE iCmsAttributes; int status; assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) ); assert( isWritePtr( protocolInfo, sizeof( SCEP_PROTOCOL_INFO ) ) ); REQUIRES_V( cryptStatusError( scepStatus ) ); /* Sign the error response using the CA key and SCEP attributes */ status = createScepAttributes( sessionInfoPtr, protocolInfo, &iCmsAttributes, MESSAGETYPE_CERTREP, scepStatus ); if( cryptStatusOK( status ) ) { ERROR_INFO errorInfo; /* Since this message is being sent in response to an existing error, we don't care about the possible error information returned from the function that sends the error response, so the errorInfo result is ignored */ status = envelopeSign( NULL, 0, sessionInfoPtr->receiveBuffer, sessionInfoPtr->receiveBufSize, &sessionInfoPtr->receiveBufEnd, CRYPT_CONTENT_NONE, sessionInfoPtr->privateKey, iCmsAttributes, &errorInfo ); krnlSendNotifier( iCmsAttributes, IMESSAGE_DECREFCOUNT ); } if( cryptStatusError( status ) ) { HTTP_DATA_INFO httpDataInfo; /* If we encounter an error processing the initial request then there won't be enough information available to create an error response. Similarly if we run into problems generating the response then there won't be anything available to send. At this point the best that we can do is send an error at the HTTP level */ initHttpDataInfo( &httpDataInfo, sessionInfoPtr->receiveBuffer, sessionInfoPtr->receiveBufSize ); httpDataInfo.reqStatus = scepStatus; swrite( &sessionInfoPtr->stream, &httpDataInfo, sizeof( HTTP_DATA_INFO ) ); return; } DEBUG_DUMP_FILE( "scep_srespx", sessionInfoPtr->receiveBuffer, sessionInfoPtr->receiveBufEnd ); /* Return the response to the client, discarding any error indication from the write. Since we're already in an error state there's not much that we can do in terms of alerting the user if a further error occurs when writing the error response, so we ignore any potential write errors that occur at this point */ sioctlSet( &sessionInfoPtr->stream, STREAM_IOCTL_LASTMESSAGE, TRUE ); ( void ) writePkiDatagram( sessionInfoPtr, SCEP_CONTENT_TYPE, SCEP_CONTENT_TYPE_LEN ); }
static void dummyGenRandom( void *buffer, const int length ) { HASHFUNCTION_ATOMIC hashFunctionAtomic; BYTE hashBuffer[ CRYPT_MAX_HASHSIZE ], *bufPtr = buffer; static int counter = 0; int hashSize, i; assert( isWritePtr( buffer, length ) ); REQUIRES_V( length >= 1 && length < MAX_BUFFER_SIZE ); /* Fill the buffer with random-ish data. This gets a bit tricky because we need to fool the entropy tests so we can't just fill it with a fixed (or even semi-random) pattern but have to set up a somewhat kludgy PRNG */ getHashAtomicParameters( CRYPT_ALGO_SHA1, 0, &hashFunctionAtomic, &hashSize ); memset( hashBuffer, counter, hashSize ); counter++; for( i = 0; i < length; i++ ) { if( i % hashSize == 0 ) { hashFunctionAtomic( hashBuffer, CRYPT_MAX_HASHSIZE, hashBuffer, hashSize ); } bufPtr[ i ] = hashBuffer[ i % hashSize ]; } }
static void deletePersonality( const int keyHandle ) { PERSONALITY_INFO *personalityInfoPtr; REQUIRES_V( keyHandle >= 0 && keyHandle < NO_PERSONALITIES ); if( keyHandle < 0 || keyHandle >= NO_PERSONALITIES ) return; personalityInfoPtr = &personalityInfo[ keyHandle ]; zeroise( personalityInfoPtr, sizeof( PERSONALITY_INFO ) ); }
static void bignumToInternal( LONG *outData, int *outDataLength, const BYTE *inData, const int inDataLength ) { int inIndex, outIndex = 0, i; assert( isWritePtr( outData, CRYPT_MAX_PKCSIZE ) ); assert( isWritePtr( outDataLength, sizeof( int ) ) ); assert( isReadPtr( inData, inDataLength ) ); REQUIRES_V( inDataLength > 0 && inDataLength <= CRYPT_MAX_PKCSIZE ); for( i = 0; i < CRYPT_MAX_PKCSIZE / sizeof( LONG ); i++ ) outData[ i ] = 0L; for( inIndex = 0; inIndex < inDataLength; inIndex += sizeof( LONG ) ) { outData[ outIndex++ ] = mgetLong( inData ); } *outDataLength = outIndex; }
void endSemaphores( void ) { REQUIRES_V( ( krnlData->initLevel == INIT_LEVEL_KRNLDATA && \ krnlData->shutdownLevel == SHUTDOWN_LEVEL_NONE ) || \ ( krnlData->initLevel == INIT_LEVEL_KRNLDATA && \ krnlData->shutdownLevel == SHUTDOWN_LEVEL_MESSAGES ) || \ ( krnlData->initLevel == INIT_LEVEL_FULL && \ krnlData->shutdownLevel >= SHUTDOWN_LEVEL_MESSAGES ) ); /* Signal that kernel mechanisms are no longer available */ krnlData->shutdownLevel = SHUTDOWN_LEVEL_MUTEXES; /* Shut down the mutexes */ MUTEX_DESTROY( mutex3); MUTEX_DESTROY( mutex2 ); MUTEX_DESTROY( mutex1 ); /* Destroy any data structures required to make the semaphore table thread-safe */ MUTEX_DESTROY( semaphore ); }
static void bignumToExternal( BYTE *outData, int *outDataLength, const LONG *inData, const int inDataLength ) { int inIndex = 0, outIndex; assert( isWritePtr( outData, CRYPT_MAX_PKCSIZE ) ); assert( isWritePtr( outDataLength, sizeof( int ) ) ); assert( isReadPtr( inData, inDataLength * sizeof( LONG ) ) ); REQUIRES_V( inDataLength > 0 && \ inDataLength <= CRYPT_MAX_PKCSIZE / sizeof( LONG ) ); memset( outData, 0, CRYPT_MAX_PKCSIZE ); for( outIndex = 0; outIndex < inDataLength; outIndex++ ) { const LONG value = inData[ inIndex++ ]; mputLong( outData, value ); } *outDataLength = outIndex * sizeof( LONG ); }