/****************************************************************************** * @fn AesLoadKey * * @brief Writes the key into the CC2540 * * input parameters * * @param AesKey - Pointer to AES Key. * * @return None */ void AesLoadKey( uint8 *AesKey ) { #if (defined HAL_AES_DMA) && (HAL_AES_DMA == TRUE) halDMADesc_t *ch = HAL_DMA_GET_DESC1234( HAL_DMA_AES_IN ); /* Modify descriptors for channel 1 */ HAL_DMA_SET_SOURCE( ch, AesKey ); HAL_DMA_SET_LEN( ch, KEY_BLENGTH ); /* Arm DMA channel 1 */ HAL_DMA_CLEAR_IRQ( HAL_DMA_AES_IN ); HAL_DMA_ARM_CH( HAL_DMA_AES_IN ); do { asm("NOP"); } while (!HAL_DMA_CH_ARMED(HAL_DMA_AES_IN)); /* Set AES mode */ AES_SET_ENCR_DECR_KEY_IV( AES_LOAD_KEY ); /* Kick it off, block until AES is ready */ AES_START(); while( !(ENCCS & 0x08) ); #else /* Set AES mode */ AES_SET_ENCR_DECR_KEY_IV( AES_LOAD_KEY ); /* Load the block */ AesLoadBlock( AesKey ); #endif }
/****************************************************************************** * @fn AesLoadBlock * * @brief Write a block to AES engine * * input parameters * * @param ptr - Pointer to date to be written. * * @return None */ void AesLoadBlock( uint8 *ptr ) { uint8 i; /* Kick it off */ AES_START(); /* Copy block to encryption input register */ for (i = 0; i < STATE_BLENGTH; i++) { ENCDI = *ptr++; } }
static void halAesLoadBlock(uint8* pData, uint8 op) { uint8 i; // Set operation AES_SET_OPERATION(op); // Starting loading of key or vector. AES_START(); // loading the data (key or vector) for(i = 0; i < 16; i++){ ENCDI = pData[i]; } return; }
/*********************************************************************************** * @fn halRfSecurityInit * * @brief Security init. Write nonces and key to chip. * * @param none * * @return none */ void halRfSecurityInit(uint8* pKey, uint8* pNonceRx, uint8* pNonceTx) { uint8 i; AES_SET_OPERATION(AES_LOAD_KEY); // Starting loading of key or vector. AES_START(); // Store key and nonces for (i=0; i<NONCE_LENGTH; i++) { nonceRx[i]= *pNonceRx; nonceTx[i]= *pNonceTx; pNonceTx++; pNonceRx++; ENCDI = *pKey++; } }
//----------------------------------------------------------------------------- // See hal.h for a description of this function. //----------------------------------------------------------------------------- void halAesLoadKeyOrInitVector(BYTE* pData, BOOL key){ UINT8 i; // Checking whether to load a key or an initialisation vector. if(key){ AES_SET_ENCR_DECR_KEY_IV(AES_LOAD_KEY); } else { AES_SET_ENCR_DECR_KEY_IV(AES_LOAD_IV); } // Starting loading of key or vector. AES_START(); // loading the data (key or vector) for(i = 0; i < 16; i++){ ENCDI = pData[i]; } return; }
/****************************************************************************** * @fn sspAesEncryptHW * * @brief Encrypts 16 byte block using AES encryption engine * * input parameters * * @param AesKey - Pointer to AES Key. * @param Cstate - Pointer to input data. * * output parameters * * @param Cstate - Pointer to encrypted data. * * @return None * */ void sspAesEncryptHW( uint8 *AesKey, uint8 *Cstate ) { (void)AesKey; #if (defined HAL_AES_DMA) && (HAL_AES_DMA == TRUE) /* Setup DMA for AES encryption */ AesDmaSetup( Cstate, STATE_BLENGTH, Cstate, STATE_BLENGTH ); AES_SET_ENCR_DECR_KEY_IV( AES_ENCRYPT ); /* Kick it off, block until DMA is done */ AES_START(); while( !HAL_DMA_CHECK_IRQ( HAL_DMA_AES_OUT ) ); #else /* Set ECB mode for AES encryption */ AES_SETMODE(ECB); AES_SET_ENCR_DECR_KEY_IV( AES_ENCRYPT ); /* Load and start the block */ AesStartBlock( Cstate, Cstate ); #endif }
/****************************************************************************** * @fn AesStartBlock * * @brief Write and read a block to and from the AES engine * * input parameters * * @param out - Pointer to result to be read. * in - pointer to data to be written. * * @return None */ void AesStartBlock( uint8 *out, uint8 *in ) { uint8 i; /* Kick it off */ AES_START(); /* Copy data to encryption input register */ for (i = 0; i < STATE_BLENGTH; i++) { ENCDI = *in++; } /* Delay is required for non-DMA AES */ HAL_AES_DELAY(); /* Copy encryption output register to out */ for (i = 0; i < STATE_BLENGTH; i++) { *out++ = ENCDO; } }
/****************************************************************************** * @fn AesStartShortBlock * * @brief Write and read a block to and from the AES engine. When using CFB, * OFB, and CTR mode, the 128 bits blocks are divided into four 32 bit * blocks. * * input parameters * * @param out - Pointer to result to be read. * in - pointer to data to be written. * * @return None */ void AesStartShortBlock( uint8 *out, uint8 *in ) { uint8 i, j; AES_START(); for (i = 0; i < 4; i++) { /* Copy in block to encryption input register */ for (j = 0; j < 4; j++) { ENCDI = *in++; } /* Delay is required for non-DMA AES */ HAL_AES_DELAY(); /* Copy encryptioon output register to out block */ for (j = 0; j < 4; j++) { *out++ = ENCDO; } } }
static void halAesOperation(uint8 oper,uint8 *pDataIn, uint16 length, uint8 *pDataOut, uint8 *pInitVector) { uint16 i; uint8 j, k; uint8 mode; uint16 nbrOfBlocks; uint16 convertedBlock; nbrOfBlocks = length / 0x10; if((length % 0x10) != 0){ // length not multiplum of 16, convert one block extra with zeropadding nbrOfBlocks++; } // Loading the IV. halAesLoadBlock(pInitVector, AES_LOAD_IV); // Start the operation AES_SET_OPERATION(oper); // Getting the operation mode. mode = ENCCS & 0x70; for(convertedBlock = 0; convertedBlock < nbrOfBlocks; convertedBlock++){ // Starting the conversion. AES_START(); i = convertedBlock * 16; // Counter, Output Feedback and Cipher Feedback operates on 4 bytes and not 16 bytes. if((mode == AES_MODE_CFB) || (mode == AES_MODE_OFB) || (mode == AES_MODE_CTR)) { for(j = 0; j < 4; j++){ // Writing the input data with zero-padding for(k = 0; k < 4; k++){ ENCDI = ((i + 4*j + k < length) ? pDataIn[i + 4*j + k] : 0x00 ); } // Read out data for every 4th byte for(k = 0; k < 4; k++){ pDataOut[i + 4*j + k] = ENCDO; } } } else if (mode == AES_MODE_CBCMAC){ // Writing the input data with zero-padding for(j = 0; j < 16; j++){ ENCDI = ((i + j < length) ? pDataIn[i + j] : 0x00 ); } // The last block of the CBC-MAC is computed by using CBC mode. if(convertedBlock == nbrOfBlocks - 2){ AES_SET_MODE(AES_MODE_CBC); // wait for data ready halMcuWaitUs(1); } // The CBC-MAC does not produce an output on the n-1 first blocks // only the last block is read out else if(convertedBlock == nbrOfBlocks - 1){ // wait for data ready halMcuWaitUs(1); for(j = 0; j < 16; j++){ pDataOut[j] = ENCDO; } } } // ECB or CBC else{ // Writing the input data with zero-padding for(j = 0; j < 16; j++){ ENCDI = ((i+j < length) ? pDataIn[i+j] : 0x00 ); } // wait for data ready halMcuWaitUs(1); // Read out data for(j = 0; j < 16; j++){ pDataOut[i+j] = ENCDO; } } } }