Ejemplo n.º 1
0
uint32_t Cipher(uint8_t* out, const uint8_t* in, uint32_t len, uint8_t mode, const uint8_t* key, const uint8_t* IV, bool inverse)
{
	Cipher_CTX ctx;
	CipherInit(&ctx, mode, key, IV);
	uint32_t ret = CipherUpdate(&ctx, out, in, len, inverse);
	ret += CipherFinal(&ctx, out, inverse);
	return ret;
}
Ejemplo n.º 2
0
NTSTATUS Ext_Initialize(_Out_ PEVHD_EXT_CAPABILITIES pCaps)
{
    NTSTATUS Status = STATUS_SUCCESS;
    TRACE_FUNCTION_IN();
    pCaps->StateSize = 0;
    Status = CipherInit();
    TRACE_FUNCTION_OUT_STATUS(Status);
    return Status;
}
Ejemplo n.º 3
0
VLT_STS DoFinalSetup( VLT_PU8 pIV, VLT_U8 IvLen )
{
    VLT_U16 status = VLT_FAIL;
    
    /**
     * Check the IV ptr is not null
     */
    if ( NULL == pIV )
    {
        return ( SIGNER_DOFSUP_NULL_PARAM );
    }

    switch (params.algoID)
    {
        case VLT_ALG_SIG_MAC_ISO9797_ALG1:
            /* No setup is required */
            break;          
        case VLT_ALG_SIG_MAC_ISO9797_ALG3:
            if (VLT_OK != ( status = CipherClose() ) )
            {
                return ( status );
            }
            /**
             * The final step for a MAC Algo 3 is a
             * switch to TDES! So re-init the Cipher.
             */
            cipherParams.algoID = VLT_ALG_CIP_TDES_2K_EDE;
            cipherParams.pIV = pIV;
            
            if ( VLT_OK != (status = CipherInit( 
                VLT_ENCRYPT_MODE, 
                &theKey, 
                (VLT_PU8)&cipherParams ) ) )
            {
                return ( status );
            }

            /**
             * Job done, the final block should now perform 
             * a 3DES using the same both parts of the 2K
             * DES Key. 
             * (k1 DES) -> (k2 DES-1) -> (k1 DES) = MAC
             */
            break;          
        case VLT_ALG_SIG_CMAC_AES:            
        default:
            return( SIGNER_ALGO_ID_NOT_SUP );
    }

    return ( VLT_OK );
}
Ejemplo n.º 4
0
// Return values: 0 = success, ERR_CIPHER_INIT_FAILURE (fatal), ERR_CIPHER_INIT_WEAK_KEY (non-fatal)
int EAInit (int ea, unsigned char *key, unsigned __int8 *ks)
{
	int c, retVal = ERR_SUCCESS;

	if (ea == 0)
		return ERR_CIPHER_INIT_FAILURE;

	for (c = EAGetFirstCipher (ea); c != 0; c = EAGetNextCipher (ea, c))
	{
		switch (CipherInit (c, key, ks))
		{
		case ERR_CIPHER_INIT_FAILURE:
			return ERR_CIPHER_INIT_FAILURE;

		case ERR_CIPHER_INIT_WEAK_KEY:
			retVal = ERR_CIPHER_INIT_WEAK_KEY;		// Non-fatal error
			break;
		}

		key += CipherGetKeySize (c);
		ks += CipherGetKeyScheduleSize (c);
	}
	return retVal;
}
Ejemplo n.º 5
0
VLT_STS SignerIso9797Init( VLT_U8 opMode, const KEY_BLOB* pKey, VLT_PU8 pParams )
{   
    VLT_STS status = VLT_FAIL;
            
    /**
     * Make sure we have a valid params pointers
     */
    if( ( NULL == pParams ) ||
        ( NULL == pKey ) )
    {
        return( INVALID_NULL_PARAMS );
    }
    else if ( VLT_SIGN_MODE != opMode )
    {
        return ( SIGNER_OPMODE_NOT_SUP );
    }
    else
    {
        /**
         * Cache the parameters.
         */
        params = *((SIGNER_PARAMS*)pParams);

        /**
         * Make sure we have a valid params pointers
         */
        if ( NULL == params.pIV )
        {
            return( INVALID_NULL_PARAMS );
        }

        if( ( params.algoID != VLT_ALG_SIG_MAC_ISO9797_ALG1 ) &&
            ( params.algoID != VLT_ALG_SIG_MAC_ISO9797_ALG3 ) )
        {
            /**
             * Clear the singerState to signify the
             * fact that something has gone pear
             * shaped and we shouldn't deligate
             * any further calls to the concrete
             * methods.
             */
            signerState = ST_UNKNOWN;

            /**
             * Return the appropriate error and
             * exit gracefully. 
             */
            return( SIGNER_ALGO_ID_NOT_SUP );
        }
    }
    
    /**
     * Save a copy of the key!
     * Mac Algo 3 and AES CMAC
     * require key switching 
     * in the final block!
     * This should only be done
     * on success but tweeking of
     * the key length is required
     * for Mac Alg3.
     */
    theKey = *pKey;

    /**
     * Check and setup the required parameters for 
     * the Chipher init method call.
     */
    switch(params.algoID)
    {
        case VLT_ALG_SIG_MAC_ISO9797_ALG1:
            cipherParams.algoID = VLT_ALG_CIP_TDES_2K_EDE;
            cipherParams.chainMode = BLOCK_MODE_CBC;
            /**
             * The signer has to do padding itself
             * because of Cipher mode switching 
             * in MAC algorithm 3, on the last block
             * if the Cipher does the padding, the 
             * last block, can become the second last
             * block, due to padding method 2, PKCS5 etc.
             * The result is the last two blocks are 
             * processed in the mode switch, and the 
             * wrong answer is produced.
             */
            cipherParams.paddingScheme = PADDING_NONE;
            break;          
        case VLT_ALG_SIG_MAC_ISO9797_ALG3:
            cipherParams.algoID = VLT_ALG_CIP_DES;
            cipherParams.chainMode = BLOCK_MODE_CBC;
            cipherParams.paddingScheme = PADDING_NONE;
            theKey.keyType = VLT_KEY_DES;
            theKey.keySize = DES_KEY_SIZE;
            break;          
        case VLT_ALG_SIG_CMAC_AES:            
        default:
            return( SIGNER_ALGO_ID_NOT_SUP );
    }

    /**
     * Check the padding scheme.
     */
    switch( params.paddingScheme )
    {   
        case PADDING_ISO9797_METHOD2:                   
        case PADDING_NONE:
        case PADDING_PKCS5:
        case PADDING_PKCS7:
            break;
        default:
            return(SIGNER_PADDING_UNKNOWN);
    }       

    
    /*
     * Check the IV length is supported.
     */
    if( VLT_DES_IV_SIZE != params.ivSize )
    {
        return (SIGNER_IV_LEN_NOT_SUP);
    }

    /**
     * Store the address of the IV into the Cipher params IV ptr.
     */
    cipherParams.pIV = params.pIV;
    
    /**
     * Delegate the call to the initialisation method
     * to the cipher, and let the cipher use the appropriate algorithm.
     */
    status = CipherInit( VLT_ENCRYPT_MODE, &theKey, (VLT_PU8)&cipherParams );

    /**
     * Prepare to accept the first block 
     * of data.
     */
    if( VLT_OK == status )
    {
        signerState = ST_INITIALISED; 

        /**
         * Save a copy again!
         * Mac Algo 3 does a mixture 
         * of DES and TDSES so the 
         * keyLen has been modified
         * to DES_KEY_SIZE for the 
         * first part, TDES_KEY_SIZE
         * is needed for the final 
         * part!
         */
        theKey = *pKey;

        /**
         * Setup the IV in the IV buffer if the 
         * do final is called with a message 
         * shorter or equal to the block size.
         * In this case the cipher will be re-
         * initalized with a new algorithm.
         */
        /*
        * No need to check the return type as pointer has been validated
        */
        (void)host_memcpy(&aIv[0], &params.pIV[0], params.ivSize);

        /**
         * This is used to determine if do final 
         * was called empty and update has not 
         * been called (sign an empty message).
         */
        blockCounter = 0;
    }

    return( status );
}
Ejemplo n.º 6
0
VLT_STS VltUnwrapKey( VLT_U8 u8KeyGroup,
    VLT_U8 u8KeyIndex,
    const VLT_FILE_PRIVILEGES *pKeyFilePrivileges,
    const VLT_KEY_OBJ_RAW* pKeyObj )
{
#if( VLT_ENABLE_KEY_WRAPPING == VLT_ENABLE )
    VLT_STS status = VLT_FAIL;
    VLT_U8 u8SecChnlState = VLT_USER_NOT_AUTHENTICATED;
    
    /*
    * Check the validity of the input parameters
    */
    if( ( NULL == pKeyFilePrivileges ) || 
        ( NULL == pKeyObj ) || 
        ( NULL == pKeyObj->pu16ClearKeyObjectLen ) || 
        ( NULL == pKeyObj->pu8KeyObject ) )
    {
        return( EKWWKNULLPARAM );
    }

    /*
    * Check that the key wrapping has been initialised
    */
    if( ST_UNINIT == keyWrappingState )
    {
        return ( EKWWKUNINIT );
    }

    /*
    * Check if a Secure channel is enabled.  If it is, don't allow the wrap
    */
    if( VLT_OK == VltScpGetState( &u8SecChnlState ) )
    {
        if( u8SecChnlState == VLT_USER_AUTHENTICATED )
        {
            status = EKWWKSCPENBLD;
        }
        else
        {
            status = VLT_OK;
        }
    }
    else
    {
        /*
        * As Secure Channel hasn't been enabled the wrap call can proceed
        */
        status = VLT_OK;
    }

    if( VLT_OK == status )
    {
        /*
        * Initialise the Cipher
        */
        status = CipherInit( VLT_ENCRYPT_MODE,
            &theKey,
            (VLT_PU8)&theWrapParams );

        if( VLT_OK == status )
        {
            /*
            * The cipher was initialised correctly so update the state
            */
            keyWrappingState = ST_CIPHER_INIT;
        }
    }

    if( ( VLT_OK == status ) && ( WRAP_MODE != keyWrappingMode ) )
    {
        /*
        * Call Initialize Algorithm on the VaultIC to set it up to unwrap the
        * wrapped key we are about to send down. Only do this if it hasn't 
        * already been called
        */
        VLT_ALGO_PARAMS algorithm;

        algorithm.u8AlgoID = theWrapParams.algoID;
        algorithm.data.SymCipher.u8Padding = theWrapParams.paddingScheme;
        algorithm.data.SymCipher.u8Mode = theWrapParams.chainMode;

		if (theWrapParams.pIV != NULL)
		{
        /*
        * No need to check the return type as pointer has been validated
        */
        (void)host_memcpy( &(algorithm.data.SymCipher.u8Iv[0]),
            theWrapParams.pIV,
            CipherGetBlockSize() );

        algorithm.data.SymCipher.u8IvLength = (VLT_U8)CipherGetBlockSize();
		}
		else
			 algorithm.data.SymCipher.u8IvLength = 0;

        status = VltInitializeAlgorithm( u8CachedKTSKeyGroup, 
            u8CachedKTSKeyIndex,
            VLT_UNWRAP_KEY_MODE,
            &algorithm );

        if( VLT_OK == status )
        {
            /*
            * Update the mode to wrap
            */
            keyWrappingMode = WRAP_MODE;
        }
    }

    if( VLT_OK == status )
    {
        VLT_U16 u16Remaining = 
                VLT_PUTKEY_FIXED_DATA_LENGTH + *pKeyObj->pu16ClearKeyObjectLen;
        VLT_U16 u16KeyBytesRemaining = *(pKeyObj->pu16ClearKeyObjectLen);
        VLT_U16 u16MaxChunk = VltCommsGetMaxSendSize();
        VLT_U16 u16Offset = 0;

        while( 0 != u16Remaining )
        {
            VLT_SW Sw = VLT_STATUS_NONE;
            VLT_U16 u16Avail = 0;
            VLT_U16 u16PartialKeyLen = 0;
            VLT_U32 u32CipherDataLen = 0;
            VLT_U8 u8Final = 0;

            /*
            * Set index at the start of the data portion of the buffer
            */
            idx = VLT_APDU_DATA_OFFSET;

            /*
            * Build the data in
            */
            if( 0 == u16Offset )
            {
                /* 
                * Add the Key Priviliges 
                */
                Command.pu8Data[idx++] = pKeyFilePrivileges->u8Read;
                Command.pu8Data[idx++] = pKeyFilePrivileges->u8Write;
                Command.pu8Data[idx++] = pKeyFilePrivileges->u8Delete;
                Command.pu8Data[idx++] = pKeyFilePrivileges->u8Execute;

                /*
                * Add the Key Length
                */
                Command.pu8Data[idx++] = 
                    (VLT_U8)( (*pKeyObj->pu16ClearKeyObjectLen >> 8 ) & 0xFF );

                Command.pu8Data[idx++] = 
                    (VLT_U8)( (*pKeyObj->pu16ClearKeyObjectLen >> 0 ) & 0xFF );
            }

            u16Avail = NumBufferBytesAvail( u16MaxChunk, idx );

            if(u16KeyBytesRemaining > u16Avail)
            {
                /*
                * There is more key data remaining than can be transferred
                * in one transaction
                */
                u16PartialKeyLen = ( u16Avail / CipherGetBlockSize() )
                    * CipherGetBlockSize();
            }
            else
            {
                /*
                * The remaining data might all be able to be transferred in
                * one transaction
                */
                if( u16Avail >= (u16KeyBytesRemaining + CipherGetBlockSize() ) )
                {
                    u16PartialKeyLen = u16KeyBytesRemaining;

                    /*
                    * Flag that this will be the final block to be encrypted
                    */
                    u8Final = 1;
                }
                else
                {
                    u16PartialKeyLen = 
                        u16KeyBytesRemaining - CipherGetBlockSize();
                }
            }

            /*
            * Copy the number of bytes of the partial key into the buffer
            */
            /*
            * No need to check the return type as pointer has been validated
            */
            (void)host_memcpy( &(Command.pu8Data[idx]),
                &( (pKeyObj->pu8KeyObject[u16Offset]) ), 
                u16PartialKeyLen  );

            /*
            * Now encrypt the data in the buffer
            */
            if( 1 == u8Final )
            {
                status = CipherDoFinal( &(Command.pu8Data[idx]), 
                    u16PartialKeyLen, 
                    Command.u16Capacity - VLT_APDU_DATA_OFFSET, 
                    &(Command.pu8Data[idx]),
                    &u32CipherDataLen,
                    Command.u16Capacity - VLT_APDU_DATA_OFFSET );
            }
            else
            {
                status = CipherUpdate( &(Command.pu8Data[idx]), 
                    u16PartialKeyLen, 
                    Command.u16Capacity - VLT_APDU_DATA_OFFSET, 
                    &(Command.pu8Data[idx]),
                    &u32CipherDataLen,
                    Command.u16Capacity - VLT_APDU_DATA_OFFSET );
            }

            if( VLT_OK == status )
            {
                /*
                * Update the index to reflect the data that has just been added
                */
                idx += (VLT_U16)u32CipherDataLen;

                /*
                * Subtract the number of key bytes that have just been added to
                * the buffer from the number of key bytes remaining to be sent
                */
                u16KeyBytesRemaining -= u16PartialKeyLen;

                /*
                * Decrement the remaining number of bytes to be sent.
                */
                if( 0 == u16Offset )
                {
                    /*
                    * The first time the File Privileges and the length are
                    * included so include them plus the partial key length
                    * which won't incude any padding bytes if some have been
                    * added
                    */
                    u16Remaining -= 
                        ( VLT_PUTKEY_FIXED_DATA_LENGTH - NUM_CRC_BYTES ) +
                        u16PartialKeyLen;
                }
                else
                {
                    /*
                    * Subtract the partial key length that was added to
                    * the buffer
                    */
                    u16Remaining -= u16PartialKeyLen;
                }

                /*
                * Update the offset into the key
                */
                u16Offset += u16PartialKeyLen;

                /*
                * We need two bytes free in the buffer for the wCRC field.
                */
                if( ( NUM_CRC_BYTES == u16Remaining ) &&
                    ( NumBufferBytesAvail( u16MaxChunk, idx ) >= NUM_CRC_BYTES ) )
                {
                    Command.pu8Data[idx++] = 
                        (VLT_U8)( ( pKeyObj->u16Crc >> 8 ) & 0xFF );

                    Command.pu8Data[idx++] = 
                        (VLT_U8)( (pKeyObj->u16Crc >> 0 ) & 0xFF );

                    u16Remaining -= NUM_CRC_BYTES;
                }
Ejemplo n.º 7
0
void DecryptInit(Decrypt_CTX* ctx, uint8_t mode, const uint8_t* key, const uint8_t* IV)
{
	CipherInit(ctx, mode, key, IV);
}