예제 #1
0
/*!
 * This function initiates reading of MLLI table in given host memory to
 * the MLLI buffer in SRAM. It pushes DLLI-to-SRAM BYPASS descriptor.
 *
 * \param qid [in] -The queue Id.
 * \param mlliHostAddr [in] - Host DMA address of a structure which represents the 
 *			MLLI table as follow:
 *		     1. A pointer to the first input MLLI table in system RAM
 *		     	and it's size.
 *		     2. The total number of MLLI tables.
 *		     3. The table direction (can be either MLLI_INPUT_TABLE or
 *		     	MLLI_OUTPUT_TABLE).
 * \param tableSize The size in bytes of the pointed MLLI table.
 * \param axiNs The AXI NS bit
 * \param direction Denotes whether this is MLLI for input or for output
*/
void FetchMlliTable(int qid, uint32_t pMlliData, uint32_t size, uint8_t axiNs, MLLIDirection_t direction)
{
	uint32_t mlliAdr;
	HwDesc_s desc;

	/* Check if already allocated by external module */
	if ( DX_GetIsMlliExternalAlloc(qid) == 1 ) {
		DX_PAL_Abort("MLLI workspace is already allocated by external module");
	}
	
	if (size > (MLLI_BUF_SIZE - SEP_LLI_ENTRY_BYTE_SIZE)) {
		DX_PAL_LOG_ERR("Given MLLI size=%u B is too large!\n", (unsigned int)size);
		DX_PAL_Abort("Given MLLI size is too large!");
	}

	mlliAdr = (uint32_t)(DX_GetMLLIWorkspace() + qid * MLLI_IN_OUT_BUF_SIZE);
	mlliAdr += ( direction == MLLI_INPUT_TABLE ? 0 : MLLI_BUF_SIZE );

	/* prepare the first MLLI mlliTable from host */
	HW_DESC_INIT(&desc);
	HW_DESC_SET_DIN_TYPE(&desc, DMA_DLLI, pMlliData, size, QID_TO_AXI_ID(qid), axiNs);
	HW_DESC_SET_DOUT_SRAM(&desc, mlliAdr, size);
	HW_DESC_SET_FLOW_MODE(&desc, BYPASS);
	AddHWDescSequence(qid, &desc);
}
예제 #2
0
/*!
 * This function is used to initialize the HASH machine to perform the 
 * HASH operations. This should be the first function called.
 * 
 * \param pCtx A pointer to the context buffer in SRAM.
 *  
 * \return int One of DX_SYM_* error codes defined in dx_error.h.
 */
int InitHash(struct sep_ctx_hash *pCtx)
{
	SepHashPrivateContext_s *PrivateContext = (SepHashPrivateContext_s *)pCtx;

	/* copy the hash initial digest to the user context */
	switch(ReadContextWord(&pCtx->mode)) {
	case SEP_HASH_SHA1:
		 WriteContextField(pCtx->digest, gLarvalSha1Digest, SEP_SHA1_DIGEST_SIZE);
		break;
	case SEP_HASH_SHA224:
		WriteContextField(pCtx->digest, gLarvalSha224Digest, SEP_SHA256_DIGEST_SIZE);
		break;
	case SEP_HASH_SHA256:
		WriteContextField(pCtx->digest, gLarvalSha256Digest, SEP_SHA256_DIGEST_SIZE);
		break;
#ifdef DX_CONFIG_HASH_SHA_512_SUPPORTED
	case SEP_HASH_SHA384:
		WriteContextField(pCtx->digest, gLarvalSha384Digest, SEP_SHA512_DIGEST_SIZE);
		break;
	case SEP_HASH_SHA512:
		WriteContextField(pCtx->digest, gLarvalSha512Digest, SEP_SHA512_DIGEST_SIZE);
		break;
#endif
	default:
		DX_PAL_LOG_ERR("Unsupported hash mode %d\n", ReadContextWord(&pCtx->mode));
		return DX_RET_UNSUPP_ALG_MODE;
	}

	/* clear hash length and load it to the hash machine -we're starting a new transaction */
	ClearCtxField(PrivateContext->CurrentDigestedLength, sizeof(PrivateContext->CurrentDigestedLength));
	WriteContextWord(&PrivateContext->dataCompleted,0);
	WriteContextWord(&PrivateContext->hmacFinalization,0);

	return DX_RET_OK;
}
예제 #3
0
/*!
 * This function is called from the SW queue manager in order to complete
 * a crypto operation. The SW queue manager calls this API when the
 * "Process" bit "0x2" is set in the SW descriptor header. This function
 * may be invoked after "DispatchDriverProcess" or "DispatchDriverInit" with any
 * number of IN/OUT MLLI tables.
 * 
 * \param pCtx A pointer to the context buffer in SRAM.
 * \param pDmaInputBuffer A structure which represents the DMA input buffer.
 * \param pDmaOutputBuffer A structure which represents the DMA output buffer.
 * 
 * \return int One of DX_SYM_* error codes defined in head of file.
 */
int SymDriverDispatchFinalize(struct sep_ctx_generic *pCtx, DmaBuffer_s *pDmaInputBuffer, DmaBuffer_s *pDmaOutputBuffer)
{
	int retcode;	
	uint32_t alg;

	DX_PAL_LOG_INFO("qid=%d pCtx=%p\n", CURR_QUEUE_ID(), pCtx);

	DX_PAL_LOG_INFO("pDmaInputBuffer: pData=%p DataSize=%d DmaMode=%d nTables=%d\n",
			(uint32_t *)pDmaInputBuffer->pData, (int)pDmaInputBuffer->size, 
			(int)pDmaInputBuffer->dmaBufType, (int)pDmaInputBuffer->nTables);
	
	DX_PAL_LOG_INFO("pDmaOutputBuffer: pData=%p DataSize=%d DmaMode=%d nTables=%d\n",
			(uint32_t *)pDmaOutputBuffer->pData, (int)pDmaOutputBuffer->size, 
			(int)pDmaOutputBuffer->dmaBufType, (int)pDmaOutputBuffer->nTables);
	//mdelay(1000);
	alg = ReadContextWord(&pCtx->alg);
		
	if (gFuncDispatchList[alg].finalizeFunc == NULL) {
		DX_PAL_LOG_ERR("Unsupported alg %d\n", alg);
		return DX_RET_UNSUPP_ALG;
	}

	HW_QUEUE_LOCK();

	retcode = (gFuncDispatchList[alg].finalizeFunc)(pCtx, pDmaInputBuffer, pDmaOutputBuffer);

	HW_QUEUE_UNLOCK();

	return retcode;
}
예제 #4
0
/*!
 * Revert operation of the last MAC block processing
 * This function is used for AES-XCBC-MAC and AES-CMAC when finalize
 * has not data. It reverts the last block operation in order to allow
 * redoing it as final.
 * 
 * \param qid 
 * \param pCtx 
 *
 * \return int One of DX_SYM_* error codes defined in dx_error.h.
 */
static int RevertLastMacBlock(int qid, struct sep_ctx_cipher *pCtx)
{
	HwDesc_s desc;
	XcbcMacRfcKeys_s *XcbcKeys = (XcbcMacRfcKeys_s*)pCtx->key;

	/* Relevant only for AES-CMAC and AES-XCBC-MAC */
	if ((ReadContextWord(&pCtx->mode) != SEP_CIPHER_XCBC_MAC) && (ReadContextWord(&pCtx->mode) != SEP_CIPHER_CMAC)) {
		DX_PAL_LOG_ERR("Wrong mode for this function (mode %d)\n", ReadContextWord(&pCtx->mode));
		return DX_RET_UNSUPP_ALG_MODE;
	}
	if (ReadContextWord(&pCtx->crypto_key_type) == DX_ROOT_KEY) {
		DX_PAL_LOG_ERR("RKEK not allowed for XCBC-MAC/CMAC\n");
		return DX_RET_UNSUPP_ALG_MODE;
	}
	/* CMAC and XCBC must use 128b keys */
	if ((ReadContextWord(&pCtx->mode) == SEP_CIPHER_XCBC_MAC) && (ReadContextWord(&pCtx->key_size) != SEP_AES_128_BIT_KEY_SIZE)) {
		DX_PAL_LOG_ERR("Bad key for XCBC-MAC %x\n", (unsigned int)ReadContextWord(&pCtx->key_size));
		return DX_RET_INVARG_KEY_SIZE;
	}

	/* Load key for ECB decryption */
	HW_DESC_INIT(&desc);
	HW_DESC_SET_CIPHER_MODE(&desc, SEP_CIPHER_ECB);
	HW_DESC_SET_CIPHER_CONFIG0(&desc, SEP_CRYPTO_DIRECTION_DECRYPT);
	if (ReadContextWord(&pCtx->mode) == SEP_CIPHER_XCBC_MAC) { /* XCBC K1 key is used (always 128b) */
		HW_DESC_SET_STATE_DIN_PARAM(&desc, (uint32_t)XcbcKeys->K1, SEP_AES_128_BIT_KEY_SIZE);
		HW_DESC_SET_KEY_SIZE_AES(&desc, SEP_AES_128_BIT_KEY_SIZE);
	} else  {/* CMAC */
		HW_DESC_SET_STATE_DIN_PARAM(&desc, (uint32_t)pCtx->key,
			(ReadContextWord(&pCtx->key_size) == 24) ? SEP_AES_KEY_SIZE_MAX : ReadContextWord(&pCtx->key_size));
		HW_DESC_SET_KEY_SIZE_AES(&desc, ReadContextWord(&pCtx->key_size));
	}
	HW_DESC_SET_FLOW_MODE(&desc, S_DIN_to_AES);
	HW_DESC_SET_SETUP_MODE(&desc, SETUP_LOAD_KEY0);
	AddHWDescSequence(qid, &desc);

	/* Initiate decryption of block state to previous block_state-XOR-M[n] */
	HW_DESC_INIT(&desc);
	HW_DESC_SET_STATE_DIN_PARAM(&desc, (uint32_t)pCtx->block_state, SEP_AES_BLOCK_SIZE);
	HW_DESC_SET_STATE_DOUT_PARAM(&desc, (uint32_t)pCtx->block_state, SEP_AES_BLOCK_SIZE);
	HW_DESC_SET_FLOW_MODE(&desc, DIN_AES_DOUT);
	AddHWDescSequence(qid, &desc);

	return DX_RET_OK;
}
예제 #5
0
/*!
 * Get Hash digest size in bytes.
 * 
 * \param mode Hash mode
 * \param digestSize [out] A pointer to the digest size return value
 * 
 * \return int One of DX_SYM_* error codes defined in dx_error.h.
 */
int GetHashDigestSize(const enum sep_hash_mode mode, uint32_t *digestSize)
{
	if (mode >= SEP_HASH_MODE_NUM) {
		DX_PAL_LOG_ERR("Unsupported hash mode");
		*digestSize = 0;
		return DX_RET_UNSUPP_ALG_MODE;
	}

	*digestSize = gHashDigestSize[mode];
	return DX_RET_OK;
}
예제 #6
0
/*!
 * Translate Hash mode to hardware specific Hash mode.
 * 
 * \param mode Hash mode
 * \param hwMode [out] A pointer to the hash mode return value
 * 
 * \return int One of DX_SYM_* error codes defined in dx_error.h.
 */
int GetHashHwMode(const enum sep_hash_mode mode, uint32_t *hwMode)
{
	if (mode >= SEP_HASH_MODE_NUM) {
		DX_PAL_LOG_ERR("Unsupported hash mode");
		*hwMode = SEP_HASH_NULL;
		return DX_RET_UNSUPP_ALG_MODE;
	}

	*hwMode = gHashHwMode[mode];
	return DX_RET_OK;
}
예제 #7
0
/*!
 * Get Hash block Size length in bytes.
 * 
 * \param mode Hash mode
 * 
 * \return int digest size return value.
 */
static int GetHmacBlocktSize(const enum sep_hash_mode mode)
{
	if (mode >= SEP_HASH_MODE_NUM) {
		DX_PAL_LOG_ERR("Unsupported hash mode");
		return 0;
	}

	if (mode <= SEP_HASH_SHA224)
		return CRYS_HASH_BLOCK_SIZE_IN_BYTES;
	else
		return CRYS_HASH_SHA512_BLOCK_SIZE_IN_BYTES;

}
예제 #8
0
/*!
 * Get Hash block size in bytes.
 * 
 * \param mode Hash mode
 * \param blockSize [out] A pointer to the hash block size return value
 * 
 * \return int One of DX_SYM_* error codes defined in dx_error.h.
 */
int GetHashBlockSize(const enum sep_hash_mode mode, uint32_t *blockSize)
{
	if (mode >= SEP_HASH_MODE_NUM) {
		DX_PAL_LOG_ERR("Unsupported hash mode");
		*blockSize = 0;
		return DX_RET_UNSUPP_ALG_MODE;
	}
	if (mode <= SEP_HASH_SHA224)
		*blockSize = SEP_SHA1_224_256_BLOCK_SIZE;
	else
		*blockSize = SEP_SHA512_BLOCK_SIZE;
	return DX_RET_OK;
}
예제 #9
0
/*!
 * This function is used to initialize the AES machine to perform the AES
 * operations. This should be the first function called.
 * 
 * \param pCtx A pointer to the context buffer in SRAM.
 * 
 * \return int One of DX_SYM_* error codes defined in dx_error.h.
 */
int InitCipher(struct sep_ctx_cipher *pCtx)
{
	SepCipherPrivateContext_s *pCipherPrivateCtx = (SepCipherPrivateContext_s *)pCtx->reserved;
	int qid = CURR_QUEUE_ID(); /* qid is stored in pxTaskTag field */

	if (ReadContextWord(&pCtx->alg) == SEP_CRYPTO_ALG_DES) {
	    /*in caes of double DES k1 = K3, copy k1-> K3*/
	    if (ReadContextWord(&pCtx->key_size) == SEP_DES_DOUBLE_KEY_SIZE){
#ifdef DX_CC_SRAM_INDIRECT_ACCESS
		    /*temporary buffer to allow key coping, must be aligned to words*/
		    uint32_t tKeybuff[SEP_DES_ONE_KEY_SIZE/sizeof(uint32_t)];
		    ReadContextField(pCtx->key, tKeybuff, SEP_DES_ONE_KEY_SIZE);
		    WriteContextField((pCtx->key + SEP_DES_DOUBLE_KEY_SIZE), tKeybuff, SEP_DES_ONE_KEY_SIZE);
		    WriteContextWord(&pCtx->key_size, SEP_DES_TRIPLE_KEY_SIZE);
#else
		    DX_PAL_MemCopy((pCtx->key + SEP_DES_DOUBLE_KEY_SIZE), pCtx->key, SEP_DES_ONE_KEY_SIZE);
		    pCtx->key_size = SEP_DES_TRIPLE_KEY_SIZE;
#endif
	    }
	    return DX_RET_OK;
	}

	switch (ReadContextWord(&pCtx->mode)) {
	case SEP_CIPHER_CMAC:
		ClearCtxField(pCtx->block_state, SEP_AES_BLOCK_SIZE);
		if(ReadContextWord(&pCtx->crypto_key_type) == DX_ROOT_KEY) {
			uint32_t keySize;
			GET_ROOT_KEY_SIZE(keySize);
			WriteContextWord(&pCtx->key_size,keySize);
		}
		break;
	case SEP_CIPHER_XCBC_MAC:
		if (ReadContextWord(&pCtx->key_size) != SEP_AES_128_BIT_KEY_SIZE) {
			DX_PAL_LOG_ERR("Invalid key size\n");
			return DX_RET_INVARG;
		}
		ClearCtxField(pCtx->block_state, SEP_AES_BLOCK_SIZE);
		CalcXcbcKeys(qid, pCtx);
		break;
	default:
		break;
	}
 	
	/* init private context */
	WriteContextWord(&pCipherPrivateCtx->engineCore,SEP_AES_ENGINE1);
	WriteContextWord(&pCipherPrivateCtx->isTunnelOp, TUNNEL_OFF);
	WriteContextWord(&pCipherPrivateCtx->isDataBlockProcessed,0);

	return DX_RET_OK;
}
예제 #10
0
/*!
 * This function is called from the SW queue manager which passes the
 * related context. The function casts the context buffer and diverts
 * to the specific CRYS Init API according to the cipher algorithm that
 * associated in the given context. It is also prepare the necessary
 * firmware private context parameters that are require for the crypto
 * operation, for example, computation of the AES-MAC k1, k2, k3 values.
 * The API has no affect on the user data buffers.
 * 
 * \param pCtx A pointer to the context buffer in SRAM.
 * 
 * \return int One of DX_SYM_* error codes defined in head of file.
 */
int SymDriverDispatchInit(struct sep_ctx_generic *pCtx)
{
	int retcode;
	uint32_t alg;

	DX_PAL_LOG_INFO("qid=%d pCtx=%p\n", CURR_QUEUE_ID(), pCtx);

	//mdelay(1000);
	alg = ReadContextWord(&pCtx->alg);

	if (gFuncDispatchList[alg].initFunc == NULL) {
		DX_PAL_LOG_ERR("Unsupported alg %d\n", alg);
		return DX_RET_UNSUPP_ALG;
	}

	HW_QUEUE_LOCK();

	retcode = (gFuncDispatchList[alg].initFunc)(pCtx);

	HW_QUEUE_UNLOCK();

	return retcode;
}
예제 #11
0
/*!
 * This function is used as finish operation of AES CTS mode.
 * The function may either be called after "InitCipher" or "ProcessCipher".
 * 
 * \param pCtx A pointer to the AES context buffer in SRAM.
 * \param pDmaInputBuffer A structure which represents the DMA input buffer.
 * \param pDmaOutputBuffer A structure which represents the DMA output buffer.
 * 
 * \return int One of DX_SYM_* error codes defined in dx_error.h.
 */
int ProcessCTSFinalizeCipher(struct sep_ctx_cipher *pCtx, DmaBuffer_s *pDmaInputBuffer, DmaBuffer_s *pDmaOutputBuffer)
{
	uint32_t numOfBlocks = 0;
	uint32_t DataInSize = 0;
	uint32_t lastBlockSize = 0;
	uint32_t dataSizeForDLLI = 0;
	DmaMode_t dmaMode = NO_DMA;
	uint8_t *pInputData = NULL, *pOutputData = NULL;
	uint32_t lastBlockOffset = 0,nextToLastBlkOffset = 0;
	HwDesc_s desc;
	uint8_t inAxiNs = pDmaInputBuffer->axiNs;
	uint8_t outAxiNs = pDmaOutputBuffer->axiNs;
	int qid = CURR_QUEUE_ID();
	dmaMode = DMA_BUF_TYPE_TO_MODE(pDmaInputBuffer->dmaBufType);
	int drvRc = DX_RET_OK;
	uint8_t *tempBuff= NULL;


	/*Use context buffer aw temp buffer for internal operations */
	tempBuff = pCtx->xex_key;
 
 	/* check if we have remaining data to process */
	switch (dmaMode) {
	case DMA_MLLI:
	case DMA_SRAM:
		DX_PAL_LOG_ERR("Invalid DMA mode\n");
		drvRc = DX_RET_INVARG;
		return drvRc;
	case DMA_DLLI:
		DataInSize = pDmaInputBuffer->size;		
		pInputData = (uint8_t*)pDmaInputBuffer->pData;
		pOutputData =(uint8_t*)pDmaOutputBuffer->pData;
		break;
	default:
		DX_PAL_LOG_ERR("Invalid DMA mode\n");
		drvRc = DX_RET_INVARG;
		return drvRc;
	}

	/*Calculate last block size*/
	lastBlockSize = pDmaInputBuffer->size& AES_BLOCK_MASK;

	if (lastBlockSize == 0) {
		lastBlockSize = SEP_AES_BLOCK_SIZE; 
	}
	/*Calculte dataSizeForDLLI for ProcessCipher operation*/
	if (pDmaInputBuffer->size > SEP_AES_BLOCK_SIZE){
		dataSizeForDLLI = pDmaInputBuffer->size -(lastBlockSize + SEP_AES_BLOCK_SIZE);
	}
	else if(pDmaInputBuffer->size ==SEP_AES_BLOCK_SIZE){
          	dataSizeForDLLI = SEP_AES_BLOCK_SIZE;
    	}
	/*Process data with ProcessCipher */
	if (dataSizeForDLLI>0){
		/*Update data size for ProcessCipher operation*/
		pDmaInputBuffer->size = dataSizeForDLLI;
		pDmaOutputBuffer->size = dataSizeForDLLI;
           
		/*Call ProcessCipher*/
		drvRc = ProcessCipher(pCtx, pDmaInputBuffer, pDmaOutputBuffer);
		if (drvRc != DX_RET_OK) {
			goto EndWithErr;
		}
		/*Revert original value of data szie */
		pDmaInputBuffer->size = DataInSize;
		pDmaOutputBuffer->size =DataInSize;
        
		if (DataInSize ==SEP_AES_BLOCK_SIZE) {
			return drvRc;
		}
	}
 
	/*Calculate offsets of two last blocks */
	numOfBlocks = (DataInSize + SEP_AES_BLOCK_SIZE -1)/SEP_AES_BLOCK_SIZE;
	lastBlockOffset = (numOfBlocks - 1)*SEP_AES_BLOCK_SIZE;
	nextToLastBlkOffset = lastBlockOffset - SEP_AES_BLOCK_SIZE;
	lastBlockSize = DataInSize - lastBlockOffset;
    
	/*Change mode to SEP_CIPHER_CBC*/
	WriteContextWord(&pCtx->mode ,SEP_CIPHER_CBC);
	LoadCipherState(qid, pCtx,0);
	LoadCipherKey(qid, pCtx);

	/*Initialize  context's buffer for internal use*/
	HW_DESC_INIT(&desc);
	HW_DESC_SET_DIN_CONST(&desc, 0, SEP_AES_BLOCK_SIZE*2);
	HW_DESC_SET_DOUT_SRAM(&desc, (uint32_t)pCtx->xex_key, SEP_AES_BLOCK_SIZE*2);
	HW_DESC_SET_FLOW_MODE(&desc, BYPASS);
	AddHWDescSequence(qid, &desc);

	#ifdef DX_CONFIG_HW_RESET_CONST_SUPPORT
	    HW_DESC_INIT(&desc);
	    HW_DESC_RESET_CONST_INPUT(&desc);
	    AddHWDescSequence(qid, &desc);
	#endif

	/*Encrypt mode */
	if(ReadContextWord(&pCtx->direction) == SEP_CRYPTO_DIRECTION_ENCRYPT){
    
		/* process regular AES CBC flow on next to last block */
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_TYPE(&desc, dmaMode, (uint32_t)pInputData+nextToLastBlkOffset,SEP_AES_BLOCK_SIZE, QID_TO_AXI_ID(qid), inAxiNs);
		HW_DESC_SET_DOUT_TYPE(&desc, dmaMode, (uint32_t)pOutputData+nextToLastBlkOffset,SEP_AES_BLOCK_SIZE, QID_TO_AXI_ID(qid), outAxiNs);
		HW_DESC_SET_FLOW_MODE(&desc, DIN_AES_DOUT);
		AddHWDescSequence(qid, &desc);

		/* 1. Copy next to last block to temp SRAM buff to save it*/
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_TYPE(&desc,dmaMode, (uint32_t)pOutputData + nextToLastBlkOffset, SEP_AES_BLOCK_SIZE, QID_TO_AXI_ID(qid), inAxiNs);
		HW_DESC_SET_DOUT_SRAM(&desc,(uint32_t)tempBuff, SEP_AES_BLOCK_SIZE); 
		HW_DESC_SET_FLOW_MODE(&desc, BYPASS);
		AddHWDescSequence(qid, &desc);

 		/*2. Copy zero buff to place of second to last block to create zero padding */
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_SRAM(&desc,(uint32_t)tempBuff + SEP_AES_BLOCK_SIZE, SEP_AES_BLOCK_SIZE);
		HW_DESC_SET_DOUT_TYPE(&desc,dmaMode, (uint32_t)pOutputData + nextToLastBlkOffset, SEP_AES_BLOCK_SIZE, QID_TO_AXI_ID(qid), inAxiNs);	
		HW_DESC_SET_FLOW_MODE(&desc, BYPASS);
		AddHWDescSequence(qid, &desc);
        
		/*3. Copy last block to place of second to last */
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_TYPE(&desc,dmaMode, (uint32_t)pInputData + lastBlockOffset, lastBlockSize, QID_TO_AXI_ID(qid), inAxiNs);
		HW_DESC_SET_DOUT_TYPE(&desc,dmaMode,(uint32_t)pOutputData + nextToLastBlkOffset,lastBlockSize, QID_TO_AXI_ID(qid), outAxiNs);
		HW_DESC_SET_FLOW_MODE(&desc, BYPASS);
		AddHWDescSequence(qid, &desc);


  		/*4.Encrypt padded last block to temp2 buff in sram*/
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_TYPE(&desc, dmaMode,(uint32_t)pOutputData + nextToLastBlkOffset,SEP_AES_BLOCK_SIZE, QID_TO_AXI_ID(qid), inAxiNs);
		HW_DESC_SET_DOUT_SRAM(&desc,(uint32_t)tempBuff + SEP_AES_BLOCK_SIZE, SEP_AES_BLOCK_SIZE);
		HW_DESC_SET_FLOW_MODE(&desc, DIN_AES_DOUT);
		AddHWDescSequence(qid, &desc);
		/* Perform CTS swaping operation */
  

		/*5. Copy saved in temp1 block to place of second to last output block */
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_SRAM(&desc,(uint32_t)tempBuff , SEP_AES_BLOCK_SIZE);
		HW_DESC_SET_DOUT_TYPE(&desc,dmaMode, (uint32_t)pOutputData + nextToLastBlkOffset, SEP_AES_BLOCK_SIZE, QID_TO_AXI_ID(qid), inAxiNs);	
		HW_DESC_SET_FLOW_MODE(&desc, BYPASS);
		AddHWDescSequence(qid, &desc);

 		/*6.Copy  using BYPASS, "next to last block" to "last" block and truncate it to last block size*/
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_TYPE(&desc,dmaMode, (uint32_t)pOutputData + nextToLastBlkOffset, lastBlockSize, QID_TO_AXI_ID(qid), inAxiNs);
		HW_DESC_SET_DOUT_TYPE(&desc, dmaMode,(uint32_t)pOutputData + lastBlockOffset, lastBlockSize, QID_TO_AXI_ID(qid), outAxiNs);
		HW_DESC_SET_FLOW_MODE(&desc, BYPASS);
		AddHWDescSequence(qid, &desc);

		/*7. Copy saved in temp2 block to place of second to last block */
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_SRAM(&desc,(uint32_t)tempBuff + SEP_AES_BLOCK_SIZE , SEP_AES_BLOCK_SIZE);
		HW_DESC_SET_DOUT_TYPE(&desc,dmaMode, (uint32_t)pOutputData + nextToLastBlkOffset, SEP_AES_BLOCK_SIZE, QID_TO_AXI_ID(qid), inAxiNs);	
		HW_DESC_SET_FLOW_MODE(&desc, BYPASS);
		AddHWDescSequence(qid, &desc);
	
	} else { /*decrypt operation*/
		
		/* Descriptor flow for Decrypt CBC CTS operation (by AlonZ):
		Decrypt the data up to block Cn-2 using regular AES-CBC; save the chaining value (output IV = Cn-2)
		Process the last one-plus-reminder blocks:
		1. BYPASS DMA blocks (Cn-1, Cn) into SRAM (Cn is a partial block of length k)
		2. Decrypt Cn-1 using AES-ECB into Dn-1
		3. BYPASS DMA 16-k last bytes of Dn-1 to the end of Cn producing Cn'
		4. Decrypt Cn' using AES-CBC (IV = Cn-2) to produce Pn-1 (in SRAM)
		5. Decrypt Cn-1 (again) using AES-CBC (IV = Cn') to produce padded Pn (in SRAM)
		6. BYPASS DMA Pn-1, Pn to output */
		
		/* 1 Save Cn-1 in temp buff (in SRAM) */		
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_TYPE(&desc, dmaMode, (uint32_t)pInputData + nextToLastBlkOffset, SEP_AES_BLOCK_SIZE, QID_TO_AXI_ID(qid), inAxiNs);
		HW_DESC_SET_DOUT_SRAM(&desc,(uint32_t)tempBuff,SEP_AES_BLOCK_SIZE);
		HW_DESC_SET_FLOW_MODE(&desc, BYPASS);
		AddHWDescSequence(qid, &desc);	
		 
		/*decrypt the next to last block with ECB operation*/
		/*change context aes mode to ecb*/
 		/*load key for ecb operation*/
		LoadCipherState(qid, pCtx,1);
		LoadCipherKey(qid, pCtx);
		
		/*2 perform ECB decrypt of next to last block*/
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_TYPE(&desc, dmaMode, (uint32_t)pInputData + nextToLastBlkOffset, SEP_AES_BLOCK_SIZE, QID_TO_AXI_ID(qid), inAxiNs);
		HW_DESC_SET_DOUT_TYPE(&desc, dmaMode, (uint32_t)pOutputData + nextToLastBlkOffset, SEP_AES_BLOCK_SIZE, QID_TO_AXI_ID(qid), outAxiNs);
		HW_DESC_SET_FLOW_MODE(&desc, DIN_AES_DOUT);
		AddHWDescSequence(qid, &desc);


		/*3. Copy Cn, using BYPASS, to 16-k last bytes of decrypted with ECB next to last block to produce Cn'*/
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_TYPE(&desc,dmaMode, pInputData + lastBlockOffset,lastBlockSize, QID_TO_AXI_ID(qid), inAxiNs);
		HW_DESC_SET_DOUT_TYPE(&desc, dmaMode,pOutputData + nextToLastBlkOffset, lastBlockSize, QID_TO_AXI_ID(qid), outAxiNs);
		HW_DESC_SET_FLOW_MODE(&desc, BYPASS);
		AddHWDescSequence(qid, &desc);
		
		
		/*4.Decrypt Cn' using AES-CBC and save it temp buff(IV = Cn-2, that was save in ctx by TST_StoreCipherState operation) 
		  to produce Dn-1 */
		/*restore aes mode to cbc for next operations*/
		LoadCipherState(qid, pCtx,0);
		LoadCipherKey(qid, pCtx);

		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_TYPE(&desc, dmaMode, (uint32_t)pOutputData + nextToLastBlkOffset, SEP_AES_BLOCK_SIZE, QID_TO_AXI_ID(qid), inAxiNs);
		HW_DESC_SET_DOUT_SRAM(&desc,(uint32_t)tempBuff + SEP_AES_BLOCK_SIZE,SEP_AES_BLOCK_SIZE);
		HW_DESC_SET_FLOW_MODE(&desc, DIN_AES_DOUT);
		AddHWDescSequence(qid, &desc);


		/*5. Decrypt Cn-1(was saved in temp buff) again using AES-CBC (IV = Cn') to produce padded Dn (in SRAM)*/		
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_SRAM(&desc,(uint32_t)tempBuff, SEP_AES_BLOCK_SIZE);
		HW_DESC_SET_DOUT_SRAM(&desc,(uint32_t)tempBuff,SEP_AES_BLOCK_SIZE);
		HW_DESC_SET_FLOW_MODE(&desc, DIN_AES_DOUT);
		AddHWDescSequence(qid, &desc);

		/*6. Copy the decrypted data to output*/
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_SRAM(&desc,(uint32_t)tempBuff, SEP_AES_BLOCK_SIZE);
		HW_DESC_SET_DOUT_TYPE(&desc, dmaMode,(uint32_t)pOutputData + nextToLastBlkOffset, SEP_AES_BLOCK_SIZE, QID_TO_AXI_ID(qid), outAxiNs);
		HW_DESC_SET_FLOW_MODE(&desc, BYPASS);
		AddHWDescSequence(qid, &desc);

		/*copy partitial block to last block */
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_TYPE(&desc,dmaMode,(uint32_t)pOutputData + nextToLastBlkOffset, lastBlockSize, QID_TO_AXI_ID(qid), inAxiNs);
		HW_DESC_SET_DOUT_TYPE(&desc, dmaMode,(uint32_t)pOutputData + lastBlockOffset, lastBlockSize, QID_TO_AXI_ID(qid), outAxiNs);
		HW_DESC_SET_FLOW_MODE(&desc, BYPASS);
		AddHWDescSequence(qid, &desc);

		/*Copy the last blocks Dn-1 from temp SRAM buffer to output data*/
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_SRAM(&desc,(uint32_t)tempBuff +SEP_AES_BLOCK_SIZE, SEP_AES_BLOCK_SIZE);
		HW_DESC_SET_DOUT_TYPE(&desc, dmaMode,(uint32_t)pOutputData + nextToLastBlkOffset, SEP_AES_BLOCK_SIZE, QID_TO_AXI_ID(qid), outAxiNs);
		HW_DESC_SET_FLOW_MODE(&desc, BYPASS);
		AddHWDescSequence(qid, &desc);
	} 
EndWithErr:
	return drvRc;
}
예제 #12
0
/*!
 * This function is used as finish operation of AES on XCBC, CMAC, CBC
 * and other modes besides XTS mode.
 * The function may either be called after "InitCipher" or "ProcessCipher".
 * 
 * \param pCtx A pointer to the AES context buffer in SRAM.
 * \param pDmaInputBuffer A structure which represents the DMA input buffer.
 * \param pDmaOutputBuffer A structure which represents the DMA output buffer.
 * 
 * \return int One of DX_SYM_* error codes defined in dx_error.h.
 */
int FinalizeCipher(struct sep_ctx_cipher *pCtx, DmaBuffer_s *pDmaInputBuffer, DmaBuffer_s *pDmaOutputBuffer)
{
	uint32_t isRemainingData = 0;
	uint32_t DataInSize = 0;
	uint8_t *pInputData = NULL;
	HwDesc_s desc;
	DmaMode_t dmaMode = NO_DMA;
	uint8_t inAxiNs = pDmaInputBuffer->axiNs;
	int qid = CURR_QUEUE_ID(); /* qid is stored in pxTaskTag field */
	int drvRc = DX_RET_OK;
	SepCipherPrivateContext_s *pAesPrivateCtx = (SepCipherPrivateContext_s *)pCtx->reserved;

	HW_DESC_INIT(&desc);

	dmaMode = DMA_BUF_TYPE_TO_MODE(pDmaInputBuffer->dmaBufType);

	/* check if we have remaining data to process */
	switch (dmaMode) {
	case DMA_MLLI:
		isRemainingData = pDmaInputBuffer->nTables;
		DataInSize = 0;
		break;
	case DMA_DLLI:
	case DMA_SRAM:
		isRemainingData = (pDmaInputBuffer->size > 0) ? 1 : 0;
		DataInSize = pDmaInputBuffer->size;
		break;
	case DMA_MODE_NULL:
		break;
	default:
		DX_PAL_LOG_ERR("Invalid DMA mode\n");
		drvRc = DX_RET_INVARG;
		goto EndWithErr;
	}	
	
	switch(ReadContextWord(&pCtx->mode)) {
	case SEP_CIPHER_CMAC:
	case SEP_CIPHER_XCBC_MAC:
	{
		if (isRemainingData > 1) {
			/* this case only apply to DMA_MLLI mode! */
			pDmaInputBuffer->nTables--;
			ProcessCipher(pCtx, pDmaInputBuffer, pDmaOutputBuffer);
			PrepareNextMLLITable(qid, inAxiNs, MLLI_INPUT_TABLE);
			pInputData = (uint8_t *)GetFirstLliPtr(qid, MLLI_INPUT_TABLE);
			DataInSize = 0;
		} else if (isRemainingData == 1) {
			if (dmaMode == DMA_MLLI) {
				PrepareFirstMLLITable(qid, pDmaInputBuffer, MLLI_INPUT_TABLE);
				pInputData = (uint8_t *)GetFirstLliPtr(qid, MLLI_INPUT_TABLE);
				DataInSize = 0;
			} else {
				pInputData = (uint8_t *)pDmaInputBuffer->pData;
				DataInSize = pDmaInputBuffer->size;
			}
		}


		/* Prepare processing descriptor to be pushed after loading state+key */
		HW_DESC_INIT(&desc);
		if (isRemainingData == 0) {
			if (ReadContextWord(&pAesPrivateCtx->isDataBlockProcessed) == 0) {
				/* MAC for 0 bytes */
				HW_DESC_SET_CIPHER_MODE(&desc, ReadContextWord(&pCtx->mode));
				HW_DESC_SET_KEY_SIZE_AES(&desc, ReadContextWord(&pCtx->key_size));
				HW_DESC_SET_CMAC_SIZE0_MODE(&desc);
				HW_DESC_SET_FLOW_MODE(&desc, S_DIN_to_AES);
			} else {
				/* final with 0 data but MAC total data size > 0 */
				drvRc = RevertLastMacBlock(qid, pCtx); /* Get C[n-1]-xor-M[n] */
				if (drvRc != DX_RET_OK) {
					goto EndWithErr;
				}
				/* Finish with data==0 is identical to "final"
				   op. on the last (prev.) block (XOR with 0) */
				HW_DESC_SET_DIN_CONST(&desc, 0x00, SEP_AES_BLOCK_SIZE);
				HW_DESC_SET_FLOW_MODE(&desc, DIN_AES_DOUT);
			}
		} else {
			HW_DESC_SET_DIN_TYPE(&desc, dmaMode, (uint32_t)pInputData, DataInSize, QID_TO_AXI_ID(qid), inAxiNs);
			HW_DESC_SET_FLOW_MODE(&desc, DIN_AES_DOUT);
		}

		/* load AES key and iv length and digest */
		LoadCipherState(qid, pCtx,0);
		LoadCipherKey(qid, pCtx);

		/* Process last block */
		AddHWDescSequence(qid, &desc);
#ifdef DX_CONFIG_HW_RESET_CONST_SUPPORT
		HW_DESC_INIT(&desc);
		HW_DESC_RESET_CONST_INPUT(&desc);
		AddHWDescSequence(qid, &desc);
#endif
		/* get machine state */
		StoreCipherState(qid, pCtx);
		break;
	}
	case SEP_CIPHER_CBC_CTS:
	{ 
		/*In case of data size = SEP_AES_BLOCK_SIZE check that no blocks were processed before*/
		if ((pDmaInputBuffer->size == SEP_AES_BLOCK_SIZE)&&
		    (ReadContextWord(&pAesPrivateCtx->isDataBlockProcessed) == 1)){  
			DX_PAL_LOG_ERR("Invalid dataIn size\n");
			drvRc = DX_RET_INVARG;
			goto EndWithErr;
		}
		/*Call ProcessCTSFinalizeCipher to process AES CTS finalize operation */
		drvRc = ProcessCTSFinalizeCipher(pCtx, pDmaInputBuffer, pDmaOutputBuffer);
		if (drvRc != DX_RET_OK) {
                goto EndWithErr;
		}
		break;
	}
	default:
		if (isRemainingData) {
			/* process all tables and get state from the AES machine */
			drvRc = ProcessCipher(pCtx, pDmaInputBuffer, pDmaOutputBuffer);
			if (drvRc != DX_RET_OK) {
				goto EndWithErr;
			}
		} else if (ReadContextWord(&pCtx->mode) == SEP_CIPHER_CBC_MAC) {
			/* in-case ZERO data has processed the output would be the encrypted IV */
			if (ReadContextWord(&pAesPrivateCtx->isDataBlockProcessed) == 0) {
				/* load AES key and iv length and digest */
				LoadCipherState(qid, pCtx,0);
				LoadCipherKey(qid, pCtx);

				HW_DESC_INIT(&desc);
				HW_DESC_SET_DIN_CONST(&desc, 0x00, SEP_AES_BLOCK_SIZE);
				HW_DESC_SET_FLOW_MODE(&desc, DIN_AES_DOUT);
				AddHWDescSequence(qid, &desc);
#ifdef DX_CONFIG_HW_RESET_CONST_SUPPORT
				HW_DESC_INIT(&desc);
				HW_DESC_RESET_CONST_INPUT(&desc);
				AddHWDescSequence(qid, &desc);
#endif
				/* get mac result */
				StoreCipherState(qid, pCtx);
			}
		}
	}

EndWithErr:
	return drvRc;
}
예제 #13
0
/*!
 * This function is used to process block(s) of data using the AES machine.
 * 
 * \param pCtx A pointer to the AES context buffer in SRAM.
 * \param pDmaInputBuffer A structure which represents the DMA input buffer.
 * \param pDmaOutputBuffer A structure which represents the DMA output buffer.
 * 
 * \return int One of DX_SYM_* error codes defined in dx_error.h.
 */
int ProcessCipher(struct sep_ctx_cipher *pCtx, DmaBuffer_s *pDmaInputBuffer, DmaBuffer_s *pDmaOutputBuffer)
{
	uint8_t *pInputData = NULL, *pOutputData = NULL;
	uint32_t isNotLastDescriptor = 0;
	uint32_t DataInSize = 0, DataOutSize = 0;
	uint32_t flowMode;
	HwDesc_s desc;
	DmaMode_t dmaMode = NO_DMA;
	uint8_t inAxiNs = pDmaInputBuffer->axiNs;
	uint8_t outAxiNs = pDmaOutputBuffer->axiNs;
	SepCipherPrivateContext_s *pAesPrivateCtx = (SepCipherPrivateContext_s *)pCtx->reserved;
	int nMlliTables = pDmaInputBuffer->nTables;
	int qid = CURR_QUEUE_ID(); /* qid is stored in pxTaskTag field */
	int drvRc = DX_RET_OK;
	const int isInplaceOp = (pDmaInputBuffer->pData == pDmaOutputBuffer->pData ||
				ReadContextWord(&pCtx->mode) == SEP_CIPHER_CBC_MAC ||
				ReadContextWord(&pCtx->mode) == SEP_CIPHER_XCBC_MAC ||
				ReadContextWord(&pCtx->mode) == SEP_CIPHER_CMAC);



	if (ReadContextWord(&pCtx->mode) == SEP_CIPHER_XTS) {
		/* in XTS the key must be loaded first */
		LoadCipherKey(qid, pCtx);
	 	LoadCipherState(qid, pCtx,0);
 	} else if(ReadContextWord(&pCtx->mode) == SEP_CIPHER_CBC_CTS){
		WriteContextWord(&pCtx->mode,SEP_CIPHER_CBC);
	 	LoadCipherState(qid, pCtx,0);
		LoadCipherKey(qid, pCtx);
		WriteContextWord(&pCtx->mode,SEP_CIPHER_CBC_CTS);
	} else {
		LoadCipherState(qid, pCtx,0);
		LoadCipherKey(qid, pCtx);
	}

	/* set the input/output pointers according to the DMA mode */
	if ((!isInplaceOp) && pDmaInputBuffer->dmaBufType != pDmaOutputBuffer->dmaBufType) {
		DX_PAL_LOG_ERR("Inconsistent DMA mode for in/out buffers");
		drvRc = DX_RET_INVARG;
		goto EndWithErr;
	}

	dmaMode = DMA_BUF_TYPE_TO_MODE(pDmaInputBuffer->dmaBufType);

	switch (dmaMode) {
	case DMA_MLLI:	
		pInputData = (uint8_t *)GetFirstLliPtr(qid, MLLI_INPUT_TABLE);
		PrepareFirstMLLITable(qid, pDmaInputBuffer, MLLI_INPUT_TABLE);

		/* get OUT MLLI tables pointer in SRAM (if not inplace operation) */
		if (isInplaceOp == 0) {
			pOutputData = (uint8_t *)GetFirstLliPtr(qid, MLLI_OUTPUT_TABLE);
			PrepareFirstMLLITable(qid, pDmaOutputBuffer, MLLI_OUTPUT_TABLE);
		} else {
			pOutputData = pInputData;
		}

		/* data size is meaningless in DMA-MLLI mode */
		DataInSize = 0;
		DataOutSize = 0;

		break;
	case DMA_DLLI:
	case DMA_SRAM:
		pInputData = (uint8_t *)pDmaInputBuffer->pData;
		if (isInplaceOp == 0) {
			pOutputData  = (uint8_t *)pDmaOutputBuffer->pData;
		} else {
			pOutputData = pInputData;
		}

		/* data processing is done */
		nMlliTables = 0;

		/* set the data size */
		DataInSize = pDmaInputBuffer->size;
		DataOutSize = pDmaOutputBuffer->size; 

		break;
	case DMA_MODE_NULL:
		pInputData = 0;
		pOutputData = 0;

		/* data processing is done */
		nMlliTables = 0;

		/* data size is meaningless in DMA-MLLI mode */
		DataInSize = 0;
		DataOutSize = 0;

		break;
	default:
		DX_PAL_LOG_ERR("Invalid DMA mode\n");
		drvRc = DX_RET_INVARG;
		goto EndWithErr;
	}

	if ((ReadContextWord(&pCtx->mode) == SEP_CIPHER_CMAC) || (ReadContextWord(&pCtx->mode) == SEP_CIPHER_XCBC_MAC)) {
		isNotLastDescriptor = 1; 
	}

	/* process the AES flow */
	HW_DESC_INIT(&desc);
	
	HW_DESC_SET_DIN_TYPE(&desc, dmaMode, (uint32_t)pInputData, DataInSize, QID_TO_AXI_ID(qid), inAxiNs);
	if (isNotLastDescriptor) {
		HW_DESC_SET_DIN_NOT_LAST_INDICATION(&desc);
	}

	switch (ReadContextWord(&pCtx->mode)) {
	case SEP_CIPHER_CBC_MAC:
	case SEP_CIPHER_CMAC:
	case SEP_CIPHER_XCBC_MAC:
		break;
	default:
		HW_DESC_SET_DOUT_TYPE(&desc, dmaMode, (uint32_t)pOutputData, DataOutSize, QID_TO_AXI_ID(qid), outAxiNs);
	}

	flowMode = (ReadContextWord(&pCtx->alg) == SEP_CRYPTO_ALG_AES) ? DIN_AES_DOUT : DIN_DES_DOUT;

	HW_DESC_SET_FLOW_MODE(&desc, flowMode);

#ifdef SEP_PERFORMANCE_TEST
	/* For testing exact HW time */
	HW_QUEUE_WAIT_UNTIL_EMPTY(qid);
	TIMING_MARK(1);
	TIMING_MARK(2);
#endif
	AddHWDescSequence(qid, &desc);
	
#ifdef SEP_PERFORMANCE_TEST
	TIMING_MARK(2);
	HW_QUEUE_WAIT_UNTIL_EMPTY(qid);
	TIMING_MARK(1);
#endif

	/* process each MLLI table (MLLI processing loop only) */
	while (--nMlliTables > 0) {
		/* prepare next input MLLI table in SRAM */
		PrepareNextMLLITable(qid, inAxiNs, MLLI_INPUT_TABLE);
		
		/* prepare next output MLLI table in SRAM */
		if (isInplaceOp == 0) {
			PrepareNextMLLITable(qid, outAxiNs, MLLI_OUTPUT_TABLE);
		}
		
		/* process the AES flow */
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_TYPE(&desc, DMA_MLLI, (uint32_t)pInputData, 0, QID_TO_AXI_ID(qid), inAxiNs);
		if (isNotLastDescriptor) {
			HW_DESC_SET_DIN_NOT_LAST_INDICATION(&desc);
		}

		switch (ReadContextWord(&pCtx->mode)) {
		case SEP_CIPHER_CMAC:
		case SEP_CIPHER_CBC_MAC:
		case SEP_CIPHER_XCBC_MAC:
			break;
		default:
			HW_DESC_SET_DOUT_TYPE(&desc, DMA_MLLI, (uint32_t)pOutputData, 0, QID_TO_AXI_ID(qid), outAxiNs);
		}
		HW_DESC_SET_FLOW_MODE(&desc, flowMode);

		AddHWDescSequence(qid, &desc);
	}

	/* at least one block of data processed */
	WriteContextWord(&pAesPrivateCtx->isDataBlockProcessed,1);

	/* get machine state */
	StoreCipherState(qid, pCtx);

EndWithErr:
	return drvRc;
}
예제 #14
0
/*!
 * This function is used as finish operation of the HASH machine.
 * The function may either be called after "InitHash" or "ProcessHash".
 * 
 * \param pCtx A pointer to the AES context buffer in SRAM.
 * \param pDmaInputBuffer A structure which represents the DMA input buffer.
 * \param pDmaOutputBuffer A structure which represents the DMA output buffer.
 * 
 * \return int One of DX_SYM_* error codes defined in dx_error.h.
 */
int FinalizeHash(struct sep_ctx_hash *pCtx, DmaBuffer_s *pDmaInputBuffer, DmaBuffer_s *pDmaOutputBuffer)
{
	HwDesc_s desc;
	uint32_t isRemainingData = 0;
	uint32_t DataInSize = 0;
	DmaMode_t dmaMode = NO_DMA;
	uint8_t *pInputData = NULL;
	uint32_t hw_mode;

	uint32_t DigestSize;
	uint8_t inAxiNs = pDmaInputBuffer->axiNs;

	/* qid is stored in pxTaskTag field */
	int qid = CURR_QUEUE_ID();
	int drvRc = DX_RET_OK;

	HW_DESC_INIT(&desc);

	drvRc = GetHashHwMode(ReadContextWord(&pCtx->mode), &hw_mode);
	if (drvRc != DX_RET_OK) {
		return drvRc; 
	}

	/* SHA224 uses SHA256 HW mode with different init. val. */
	/*same for SHA384 with SHA512*/ 
	drvRc = GetHashHwDigestSize(ReadContextWord(&pCtx->mode), &DigestSize);
	if (drvRc != DX_RET_OK) {
		goto EndWithErr; 
	}

	dmaMode = DMA_BUF_TYPE_TO_MODE(pDmaInputBuffer->dmaBufType);

	/* check if we have remaining data to process */
	switch (dmaMode) {
	case DMA_MLLI:
		isRemainingData = pDmaInputBuffer->nTables;
		DataInSize = 0;
		break;
	case DMA_DLLI:
	case DMA_SRAM:
		isRemainingData = (pDmaInputBuffer->size > 0) ? 1 : 0;
		DataInSize = pDmaInputBuffer->size;
		break;
	case DMA_MODE_NULL:
		break;
	default:
		DX_PAL_LOG_ERR("Invalid DMA mode\n");
		drvRc = DX_RET_INVARG;
		goto EndWithErr;
	}	

	/* check if there is a remainder */
	if (isRemainingData > 1) {
		/* this case only apply to DMA_MLLI mode! */
		pDmaInputBuffer->nTables--;
		ProcessHash(pCtx, pDmaInputBuffer, NULL);

		/* process the last MLLI table */
		PrepareNextMLLITable(qid, inAxiNs, MLLI_INPUT_TABLE);

		/* load hash length and digest */
		drvRc = LoadHashState(qid, pCtx, HASH_PADDING_ENABLED);
		if (drvRc != DX_RET_OK) {
			goto EndWithErr; 
		}

		/* get the pointer of the input MLLI in SRAM */
		pInputData = (uint8_t *)GetFirstLliPtr(qid, MLLI_INPUT_TABLE);

		/* clobber remaining HASH data */
		HW_DESC_SET_DIN_TYPE(&desc, dmaMode, (uint32_t)pInputData, 0, QID_TO_AXI_ID(qid), inAxiNs);
		HW_DESC_SET_FLOW_MODE(&desc, DIN_HASH);
		AddHWDescSequence(qid, &desc);
	} else if (isRemainingData == 1) {
		/* load hash length and digest */
		drvRc = LoadHashState(qid, pCtx, HASH_PADDING_ENABLED);
		if (drvRc != DX_RET_OK) {
			goto EndWithErr; 
		}

		/* we have a single MLLI table */
		if (dmaMode == DMA_MLLI) {
			pInputData = (uint8_t *)GetFirstLliPtr(qid, MLLI_INPUT_TABLE);
			PrepareFirstMLLITable(qid, pDmaInputBuffer, MLLI_INPUT_TABLE);
		} else {
			pInputData = (uint8_t *)pDmaInputBuffer->pData;

			//* check sram!
		}

		/* clobber remaining HASH data */
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_TYPE(&desc, dmaMode, (uint32_t)pInputData, DataInSize, QID_TO_AXI_ID(qid), inAxiNs);
		HW_DESC_SET_FLOW_MODE(&desc, DIN_HASH);
		AddHWDescSequence(qid, &desc);
	} else {
		/* (isRemainingData == 0) */

		SepHashPrivateContext_s *PrivateContext = (SepHashPrivateContext_s *)pCtx;
		/* load hash length and digest */
		drvRc = LoadHashState(qid, pCtx, HASH_PADDING_DISABLED);
		if (drvRc != DX_RET_OK) {
			goto EndWithErr; 
		}

		/* Workaround: do-pad must be enabled only when writing current length to HW */
		HW_DESC_INIT(&desc);
		HW_DESC_SET_CIPHER_MODE(&desc, hw_mode);
		HW_DESC_SET_CIPHER_CONFIG1(&desc, HASH_PADDING_DISABLED);
		HW_DESC_SET_CIPHER_DO(&desc, DO_PAD);
		HW_DESC_SET_STATE_DOUT_PARAM(&desc, (uint32_t)PrivateContext->CurrentDigestedLength,
				sizeof(PrivateContext->CurrentDigestedLength));
		HW_DESC_SET_FLOW_MODE(&desc, S_HASH_to_DOUT);
		HW_DESC_SET_SETUP_MODE(&desc, SETUP_WRITE_STATE1);
		AddHWDescSequence(qid, &desc);
	}



	/* store the hash digest result in the context */
	HW_DESC_INIT(&desc);
	HW_DESC_SET_CIPHER_MODE(&desc, hw_mode);

	HW_DESC_SET_STATE_DOUT_PARAM(&desc, (uint32_t)pCtx->digest, DigestSize);
	HW_DESC_SET_CIPHER_CONFIG0(&desc, HASH_DIGEST_RESULT_LITTLE_ENDIAN);
	HW_DESC_SET_CIPHER_CONFIG1(&desc, HASH_PADDING_DISABLED);
	HW_DESC_SET_CIPHER_DO(&desc, DO_NOT_PAD);
	HW_DESC_SET_FLOW_MODE(&desc, S_HASH_to_DOUT);
	HW_DESC_SET_SETUP_MODE(&desc, SETUP_WRITE_STATE0);
	AddHWDescSequence(qid, &desc);
#ifdef DX_CONFIG_HASH_SHA_512_SUPPORTED
{
	uint32_t tempUint,i;
	if ((ReadContextWord(&pCtx->mode) == SEP_HASH_SHA512 || (ReadContextWord(&pCtx->mode) == SEP_HASH_SHA384))){
		WaitForSequenceCompletion();
		for( i = 0 ; i < DigestSize/sizeof(uint32_t); i++ )
		{
			if(i%2){

				tempUint = ReadContextWord(&((uint32_t*)(pCtx->digest))[i - 1]);
				WriteContextWord(&((uint32_t*)(pCtx->digest))[i - 1],ReadContextWord(&((uint32_t*)(pCtx->digest))[i]));
				WriteContextWord(&((uint32_t*)(pCtx->digest))[i],tempUint);
			}
		}

	}
}
#endif


EndWithErr:
	return drvRc;
}
예제 #15
0
/*!
 * This function is used to process a block(s) of data on HASH machine.
 * It accepts an input data aligned to hash block size, any reminder which is not
 * aligned should be passed on calling to "FinalizeHash".
 * 
 * \param pCtx A pointer to the AES context buffer in SRAM.
 * \param pDmaInputBuffer A structure which represents the DMA input buffer.
 * \param pDmaOutputBuffer A structure which represents the DMA output buffer.
 * 
 * \return int One of DX_SYM_* error codes defined in dx_error.h.
 */
int ProcessHash(struct sep_ctx_hash *pCtx, DmaBuffer_s *pDmaInputBuffer, DmaBuffer_s *pDmaOutputBuffer)
{
	uint8_t *pInputData = NULL;
	HwDesc_s desc;
	uint32_t DataInSize = 0;
	DmaMode_t dmaMode = NO_DMA;
	int nMlliTables = pDmaInputBuffer->nTables;
	uint8_t inAxiNs = pDmaInputBuffer->axiNs;
	int qid = CURR_QUEUE_ID(); /* qid is stored in pxTaskTag field */
	int drvRc = DX_RET_OK;


	HW_DESC_INIT(&desc);

	/* load hash length and digest */
	drvRc = LoadHashState(qid, pCtx, HASH_PADDING_DISABLED);
	if (drvRc != DX_RET_OK) {
		goto EndWithErr; 
	}

	dmaMode = DMA_BUF_TYPE_TO_MODE(pDmaInputBuffer->dmaBufType);

	/* set the input pointer according to the DMA mode */
	switch (dmaMode) {
	case DMA_MLLI:
		pInputData = (uint8_t *)GetFirstLliPtr(qid, MLLI_INPUT_TABLE);
		PrepareFirstMLLITable(qid, pDmaInputBuffer, MLLI_INPUT_TABLE);

		/* data size is meaningless in DMA-MLLI mode */
		DataInSize = 0;

		break;
	case DMA_DLLI:
	case DMA_SRAM:
		pInputData = (uint8_t *)pDmaInputBuffer->pData;

		/* data processing is done */
		nMlliTables = 0;

		/* set the data size */
		DataInSize = pDmaInputBuffer->size;

		break;
	default:
		DX_PAL_LOG_ERR("Invalid DMA mode\n");
		drvRc = DX_RET_INVARG;
		goto EndWithErr;
	}

	/* process the HASH flow */
	HW_DESC_SET_DIN_TYPE(&desc, dmaMode, (uint32_t)pInputData, DataInSize, QID_TO_AXI_ID(qid), inAxiNs);
	HW_DESC_SET_FLOW_MODE(&desc, DIN_HASH);
	AddHWDescSequence(qid, &desc);

	/* process the rest of MLLI tables (MLLI processing loop only) */
	while (--nMlliTables > 0) {

		/* prepare next input MLLI table in SRAM */
		PrepareNextMLLITable(qid, inAxiNs, MLLI_INPUT_TABLE);

		/* process the HASH flow */
		HW_DESC_INIT(&desc);
		HW_DESC_SET_DIN_TYPE(&desc, DMA_MLLI, (uint32_t)pInputData, 0, QID_TO_AXI_ID(qid), inAxiNs);
		HW_DESC_SET_FLOW_MODE(&desc, DIN_HASH);
		AddHWDescSequence(qid, &desc);
	}

	/* write back digest and hash length */
	StoreHashState(qid, pCtx);

EndWithErr:
	return drvRc;
}
예제 #16
0
/*!
 * Memory copy using HW engines
 *  
 *  reserved [unused]
 *  pDmaInputBuffer [in] -A structure which represents the DMA input buffer.
 *  pDmaOutputBuffer [in/out] -A structure which represents the DMA output buffer.
 * 
 * \return int One of DX_SYM_* error codes defined in dx_error.h.
 */
int ProcessBypass(struct sep_ctx_generic *reserved, DmaBuffer_s *pDmaInputBuffer, DmaBuffer_s *pDmaOutputBuffer)
{
	Bypass_t dmaTypeIn, dmaTypeOut;
	int drvRc = DX_RET_OK;

	dmaTypeIn = GetBypassType(pDmaInputBuffer->dmaBufType, pDmaInputBuffer->pData);
	dmaTypeOut = GetBypassType(pDmaOutputBuffer->dmaBufType, pDmaOutputBuffer->pData);
	
	if ((dmaTypeIn == BYPASS_MAX) || (dmaTypeOut == BYPASS_MAX)) {
		DX_PAL_LOG_ERR("Invalid din/dout memory type\n");
		drvRc = DX_RET_INVARG;
		goto EndWithErr;
	}

	switch (dmaTypeIn) {
	case BYPASS_SRAM:
		switch (dmaTypeOut) {
		case BYPASS_DLLI:
			if (IS_ALIGNED(pDmaInputBuffer->pData, sizeof(uint32_t)) ||
			    IS_MULT(pDmaInputBuffer->size, sizeof(uint32_t))) { 
				DescBypass(
					DMA_SRAM, 
					pDmaInputBuffer->pData, 
					pDmaInputBuffer->size,
					pDmaInputBuffer->axiNs,
					DMA_DLLI, 
					pDmaOutputBuffer->pData,
					pDmaOutputBuffer->size,
					pDmaOutputBuffer->axiNs);
			} else {
				DX_PAL_LOG_ERR("Bad address or bad size. SRAM to DLLI copy -Input address %xl with %ul B\n",
					pDmaInputBuffer->pData, pDmaInputBuffer->size);
				drvRc = DX_RET_INVARG;
				goto EndWithErr;
			}
			break;
		default:
			DX_PAL_LOG_ERR("Invalid BYPASS mode\n");
			drvRc = DX_RET_UNSUPP_ALG_MODE;
			goto EndWithErr;
		}
		break;
	case BYPASS_DLLI:
		switch (dmaTypeOut) {
		case BYPASS_SRAM:
			if (IS_ALIGNED(pDmaInputBuffer->pData, sizeof(uint32_t)) ||
			    IS_MULT(pDmaInputBuffer->size, sizeof(uint32_t))) { 
				DescBypass(
					DMA_DLLI, 
					pDmaInputBuffer->pData, 
					pDmaInputBuffer->size,
					pDmaInputBuffer->axiNs,
					DMA_SRAM, 
					pDmaOutputBuffer->pData,
					pDmaOutputBuffer->size,
					pDmaOutputBuffer->axiNs);
			} else {
				DX_PAL_LOG_ERR("Bad address or bad size. SRAM to DLLI copy -Input address %xl with %ul B\n",
					pDmaInputBuffer->pData, pDmaInputBuffer->size);
				drvRc = DX_RET_INVARG;
				goto EndWithErr;
			}
			break;
		case BYPASS_DLLI:
			DescBypass(
				    DMA_BUF_TYPE_TO_MODE(pDmaInputBuffer->dmaBufType), 
				    pDmaInputBuffer->pData, 
				    pDmaInputBuffer->size,
				    pDmaInputBuffer->axiNs,
				    DMA_BUF_TYPE_TO_MODE(pDmaOutputBuffer->dmaBufType), 
				    pDmaOutputBuffer->pData,
				    pDmaOutputBuffer->size,
				    pDmaOutputBuffer->axiNs);
			break;
		default:
			DX_PAL_LOG_ERR("Invalid BYPASS mode\n");
			drvRc = DX_RET_UNSUPP_ALG_MODE;
			goto EndWithErr;
		}
		break;
	default:
		DX_PAL_LOG_ERR("Invalid BYPASS mode\n");
		drvRc = DX_RET_UNSUPP_ALG_MODE;
		break;
	}

EndWithErr:
	return drvRc;
}