/*!
 * Generates DX_IVPOOL_SIZE of random bytes by
 * encrypting 0's using AES128-CTR.
 *
 * \param ivgen iv-pool context
 * \param iv_seq IN/OUT array to the descriptors sequence
 * \param iv_seq_len IN/OUT pointer to the sequence length
 */
static void dx_ivgen_generate_pool(
	struct dx_ivgen_ctx *ivgen_ctx,
	HwDesc_s iv_seq[],
	unsigned int *iv_seq_len)
{
	unsigned int idx = *iv_seq_len;

	/* Setup key */
	HW_DESC_INIT(&iv_seq[idx]);
	HW_DESC_SET_DIN_SRAM(&iv_seq[idx], ivgen_ctx->ctr_key, AES_KEYSIZE_128);
	HW_DESC_SET_SETUP_MODE(&iv_seq[idx], SETUP_LOAD_KEY0);
	HW_DESC_SET_CIPHER_CONFIG0(&iv_seq[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT);
	HW_DESC_SET_FLOW_MODE(&iv_seq[idx], S_DIN_to_AES);
	HW_DESC_SET_KEY_SIZE_AES(&iv_seq[idx], SEP_AES_128_BIT_KEY_SIZE);
	HW_DESC_SET_CIPHER_MODE(&iv_seq[idx], SEP_CIPHER_CTR);
	idx++;

	/* Setup cipher state */
	HW_DESC_INIT(&iv_seq[idx]);
	HW_DESC_SET_DIN_SRAM(&iv_seq[idx], ivgen_ctx->ctr_iv, SEP_AES_IV_SIZE);
	HW_DESC_SET_CIPHER_CONFIG0(&iv_seq[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT);
	HW_DESC_SET_FLOW_MODE(&iv_seq[idx], S_DIN_to_AES);
	HW_DESC_SET_SETUP_MODE(&iv_seq[idx], SETUP_LOAD_STATE1);
	HW_DESC_SET_KEY_SIZE_AES(&iv_seq[idx], SEP_AES_128_BIT_KEY_SIZE);
	HW_DESC_SET_CIPHER_MODE(&iv_seq[idx], SEP_CIPHER_CTR);
	idx++;

	/* Perform dummy encrypt to skip first block */
	HW_DESC_INIT(&iv_seq[idx]);
	HW_DESC_SET_DIN_CONST(&iv_seq[idx], 0, SEP_AES_IV_SIZE);
	HW_DESC_SET_DOUT_SRAM(&iv_seq[idx], ivgen_ctx->pool, SEP_AES_IV_SIZE);
	HW_DESC_SET_FLOW_MODE(&iv_seq[idx], DIN_AES_DOUT);
	idx++;

	/* Generate IV pool */
	HW_DESC_INIT(&iv_seq[idx]);
	HW_DESC_SET_DIN_CONST(&iv_seq[idx], 0, DX_IVPOOL_SIZE);
	HW_DESC_SET_DOUT_SRAM(&iv_seq[idx], ivgen_ctx->pool, DX_IVPOOL_SIZE);
	HW_DESC_SET_FLOW_MODE(&iv_seq[idx], DIN_AES_DOUT);
	idx++;

	*iv_seq_len = idx; /* Update sequence length */

	/* queue ordering assures pool readiness */
	ivgen_ctx->next_iv_ofs = DX_IVPOOL_META_SIZE;
}
Example #2
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;
}
Example #3
0
void LoadCipherState(int qid, struct sep_ctx_cipher *pCtx,uint8_t is_zero_iv)
{
	SepCipherPrivateContext_s *pAesPrivateCtx = (SepCipherPrivateContext_s *)pCtx->reserved;
	HwDesc_s desc;
	uint32_t block_size;

	HW_DESC_INIT(&desc);

	switch (ReadContextWord(&pCtx->mode)) {
	case SEP_CIPHER_ECB:
		return;
	case SEP_CIPHER_CTR:
	case SEP_CIPHER_XTS:
	case SEP_CIPHER_OFB:
		HW_DESC_SET_SETUP_MODE(&desc, SETUP_LOAD_STATE1);
		break;
	case SEP_CIPHER_CMAC:
		HW_DESC_SET_CIPHER_DO(&desc, AES_CMAC_INIT);
		/* fall through */
	default:
		HW_DESC_SET_SETUP_MODE(&desc, SETUP_LOAD_STATE0);
	}

	HW_DESC_SET_CIPHER_MODE(&desc, ReadContextWord(&pCtx->mode));
	if (ReadContextWord(&pCtx->alg) == SEP_CRYPTO_ALG_AES) {
		HW_DESC_SET_CIPHER_CONFIG0(&desc, ReadContextWord(&pAesPrivateCtx->isTunnelOp)?ReadContextWord(&pAesPrivateCtx->tunnetDir):ReadContextWord(&pCtx->direction));
		block_size = SEP_AES_BLOCK_SIZE;
		HW_DESC_SET_KEY_SIZE_AES(&desc, ReadContextWord(&pCtx->key_size));
		HW_DESC_SET_CIPHER_CONFIG1(&desc, ReadContextWord(&pAesPrivateCtx->isTunnelOp));
		if (ReadContextWord(&pCtx->crypto_key_type) == DX_XOR_HDCP_KEY) {
			HW_DESC_SET_AES_XOR_CRYPTO_KEY(&desc);
		}
		if (ReadContextWord(&pAesPrivateCtx->engineCore) == SEP_AES_ENGINE2) {
			HW_DESC_SET_FLOW_MODE(&desc, S_DIN_to_AES2);
		} else {
			HW_DESC_SET_FLOW_MODE(&desc, S_DIN_to_AES);
		}
	} else { /* DES */
		block_size = SEP_DES_IV_SIZE;
		HW_DESC_SET_FLOW_MODE(&desc, S_DIN_to_DES);
		HW_DESC_SET_CIPHER_CONFIG0(&desc, ReadContextWord(&pCtx->direction));
	}
	/*if is_zero_iv use ZeroBlock as IV*/
	if (is_zero_iv ==1 ){
 	    HW_DESC_SET_DIN_CONST(&desc, 0, block_size);
	} else {
		HW_DESC_SET_STATE_DIN_PARAM(&desc, (uint32_t)pCtx->block_state, block_size);
	}
	AddHWDescSequence(qid, &desc);

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

}
Example #4
0
static void CalcXcbcKeys(int qid, struct sep_ctx_cipher *pCtx)
{
	int i;
	HwDesc_s setup_desc;
	HwDesc_s data_desc;
	/* Overload key+xex_key fields with Xcbc keys */
	XcbcMacRfcKeys_s *XcbcKeys = (XcbcMacRfcKeys_s*)pCtx->key;
	//const uint8_t *keyConst = XcbcKeysConst.K1;
	uint8_t *derivedKey = XcbcKeys->K1;
	uint32_t constKey = 0x01010101;

	/* Prepare key setup descriptor (same for all XCBC-MAC keys) */
	HW_DESC_INIT(&setup_desc);
	HW_DESC_SET_CIPHER_MODE(&setup_desc, SEP_CIPHER_ECB);
	HW_DESC_SET_CIPHER_CONFIG0(&setup_desc, SEP_CRYPTO_DIRECTION_ENCRYPT);
	HW_DESC_SET_STATE_DIN_PARAM(&setup_desc, (uint32_t)XcbcKeys->K, SEP_AES_128_BIT_KEY_SIZE);
	HW_DESC_SET_KEY_SIZE_AES(&setup_desc, SEP_AES_128_BIT_KEY_SIZE);
	HW_DESC_SET_FLOW_MODE(&setup_desc, S_DIN_to_AES);
	HW_DESC_SET_SETUP_MODE(&setup_desc, SETUP_LOAD_KEY0);

	/* load user key */
	AddHWDescSequence(qid, &setup_desc);

	HW_DESC_INIT(&data_desc);
	HW_DESC_SET_FLOW_MODE(&data_desc, DIN_AES_DOUT);

	for (i = 0; i < AES_XCBC_MAC_NUM_KEYS ; i++) {

		/* encrypt each XCBC constant with the user given key to get K1, K2, K3 */
		HW_DESC_SET_DIN_CONST(&data_desc, (constKey * (i+1)), SEP_AES_128_BIT_KEY_SIZE);
		HW_DESC_SET_STATE_DOUT_PARAM(&data_desc, (uint32_t)derivedKey, SEP_AES_128_BIT_KEY_SIZE);
		HW_DESC_LOCK_QUEUE(&data_desc, 1); /* Lock until RESET_CONST */
		AddHWDescSequence(qid, &data_desc);
		/* Procede to next derived key calculation */
		derivedKey += SEP_AES_128_BIT_KEY_SIZE;
	}
#ifdef DX_CONFIG_HW_RESET_CONST_SUPPORT
	HW_DESC_INIT(&data_desc);
	HW_DESC_RESET_CONST_INPUT(&data_desc);
	AddHWDescSequence(qid, &data_desc);
#endif
}
Example #5
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;
}
Example #6
0
void LoadCipherKey(int qid, struct sep_ctx_cipher *pCtx)
{
	HwDesc_s desc;
	uint32_t keySize = ReadContextWord(&pCtx->key_size);
	XcbcMacRfcKeys_s *XcbcKeys = (XcbcMacRfcKeys_s*)pCtx->key;
	SepCipherPrivateContext_s *pAesPrivateCtx = (SepCipherPrivateContext_s *)pCtx->reserved;
	enum sep_crypto_direction encDecFlag = ReadContextWord(&pCtx->direction);

	HW_DESC_INIT(&desc);

	/* key size 24 bytes count as 32 bytes, make sure to zero wise upper 8 bytes */
	if (keySize == 24) {
		keySize	= SEP_AES_KEY_SIZE_MAX;
		ClearCtxField(&pCtx->key[24], SEP_AES_KEY_SIZE_MAX - 24);
	}

	HW_DESC_SET_CIPHER_MODE(&desc, ReadContextWord(&pCtx->mode));
	if (ReadContextWord(&pCtx->alg) == SEP_CRYPTO_ALG_AES) {
		if ((ReadContextWord(&pCtx->crypto_key_type) == DX_XOR_HDCP_KEY) &&
		    (ReadContextWord(&pCtx->direction) == SEP_CRYPTO_DIRECTION_DECRYPT)) {
			/* if the crypto operation is DECRYPT we still order the HW for ENCRYPT operation 
			when using HDCP key. The next decriptor which loads the HDCP XOR key will direct DECRYPT
			operation. */
			encDecFlag = SEP_CRYPTO_DIRECTION_ENCRYPT;
		}
		HW_DESC_SET_CIPHER_CONFIG0(&desc, ReadContextWord(&pAesPrivateCtx->isTunnelOp) ? ReadContextWord(&pAesPrivateCtx->tunnetDir) : encDecFlag);
		HW_DESC_SET_CIPHER_CONFIG1(&desc, ReadContextWord(&pAesPrivateCtx->isTunnelOp));
		switch (ReadContextWord(&pCtx->mode)) {
		case SEP_CIPHER_XCBC_MAC:
			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);
			if (ReadContextWord(&pCtx->crypto_key_type) == DX_XOR_HDCP_KEY) {
				HW_DESC_SET_AES_XOR_CRYPTO_KEY(&desc);
			}
			break;
		default:
			switch (ReadContextWord(&pCtx->crypto_key_type)) {
			case DX_ROOT_KEY:
				HW_DESC_SET_CIPHER_DO(&desc, ReadContextWord(&pCtx->crypto_key_type));
				break;
			case DX_SESSION_KEY:
				HW_DESC_SET_CIPHER_DO(&desc, SESSION_KEY); //value to be written to DO when session key is used
				break;
			case DX_XOR_HDCP_KEY:
				HW_DESC_SET_AES_XOR_CRYPTO_KEY(&desc);
				/*FALLTHROUGH*/
			case DX_USER_KEY:
			case DX_APPLET_KEY:
			default:
				HW_DESC_SET_STATE_DIN_PARAM(&desc, (uint32_t)pCtx->key, keySize);
			}
			HW_DESC_SET_KEY_SIZE_AES(&desc, ReadContextWord(&pCtx->key_size));
		}

		if (ReadContextWord(&pAesPrivateCtx->engineCore) == SEP_AES_ENGINE2) {
			HW_DESC_SET_FLOW_MODE(&desc, S_DIN_to_AES2);
		} else {
			HW_DESC_SET_FLOW_MODE(&desc, S_DIN_to_AES);
		}
	} else {
		HW_DESC_SET_STATE_DIN_PARAM(&desc, (uint32_t)pCtx->key, ReadContextWord(&pCtx->key_size));
		HW_DESC_SET_FLOW_MODE(&desc, S_DIN_to_DES);
		HW_DESC_SET_KEY_SIZE_DES(&desc, ReadContextWord(&pCtx->key_size));
		HW_DESC_SET_CIPHER_CONFIG0(&desc, encDecFlag);
	}

	HW_DESC_SET_SETUP_MODE(&desc, SETUP_LOAD_KEY0);
	AddHWDescSequence(qid, &desc);

	if ((ReadContextWord(&pCtx->alg) == SEP_CRYPTO_ALG_AES) &&
	    (ReadContextWord(&pCtx->crypto_key_type) == DX_XOR_HDCP_KEY)) {
		/* in HDCP, the user key being XORed with SEP_HDCP_CONST registers on the fly.
		   We reusing the descriptor and overwrite the necessary bits so DO NOT
		   clear the descriptor before. */
		HW_DESC_SET_DIN_NO_DMA(&desc, NO_DMA, 0);
		HW_DESC_SET_CIPHER_CONFIG0(&desc, ReadContextWord(&pCtx->direction)); /* user direction */
		HW_DESC_SET_CIPHER_DO(&desc, ReadContextWord(&pCtx->crypto_key_type));
		AddHWDescSequence(qid, &desc);
	}

	if (ReadContextWord(&pCtx->mode) == SEP_CIPHER_XTS) {
		HW_DESC_INIT(&desc);

		/* load XEX key */
		HW_DESC_SET_CIPHER_MODE(&desc, ReadContextWord(&pCtx->mode));
		HW_DESC_SET_CIPHER_CONFIG0(&desc, ReadContextWord(&pAesPrivateCtx->isTunnelOp) ? ReadContextWord(&pAesPrivateCtx->tunnetDir) : encDecFlag);
		HW_DESC_SET_STATE_DIN_PARAM(&desc, (uint32_t)pCtx->xex_key, keySize);
		HW_DESC_SET_XEX_DATA_UNIT_SIZE(&desc, ReadContextWord(&pCtx->data_unit_size));
		HW_DESC_SET_CIPHER_CONFIG1(&desc, ReadContextWord(&pAesPrivateCtx->isTunnelOp));
		if (ReadContextWord(&pAesPrivateCtx->engineCore) == SEP_AES_ENGINE2) {
			HW_DESC_SET_FLOW_MODE(&desc, S_DIN_to_AES2);
		} else {
			HW_DESC_SET_FLOW_MODE(&desc, S_DIN_to_AES);
		}
		HW_DESC_SET_KEY_SIZE_AES(&desc, keySize);
		HW_DESC_SET_SETUP_MODE(&desc, SETUP_LOAD_XEX_KEY);
		AddHWDescSequence(qid, &desc);
	}

	if (ReadContextWord(&pCtx->mode) == SEP_CIPHER_XCBC_MAC) {

		/* load K2 key */
		/* NO init - reuse previous descriptor settings */
		HW_DESC_SET_STATE_DIN_PARAM(&desc,(uint32_t)XcbcKeys->K2, SEP_AES_128_BIT_KEY_SIZE);
		HW_DESC_SET_SETUP_MODE(&desc, SETUP_LOAD_STATE1);
		AddHWDescSequence(qid, &desc);

		/* load K3 key */
		/* NO init - reuse previous descriptor settings */
		HW_DESC_SET_STATE_DIN_PARAM(&desc, (uint32_t)XcbcKeys->K3, SEP_AES_128_BIT_KEY_SIZE);
		HW_DESC_SET_SETUP_MODE(&desc, SETUP_LOAD_STATE2);
		AddHWDescSequence(qid, &desc);
	}
}