コード例 #1
0
/** 
 *	@brief This function is responsible to change storage
 *	       addresses of the SW components in the VRL.
 *         
 *	@param[in] vrlPtr - a pointer to the VRL
 *	@param[in] address - the address to insert into the VRL
 *	@param[in] numOfAddressesInArray - number of addresses in the
 *	      previous array
 *
 * @return DxError_t - On success the value DX_OK is returned, 
 *         on failure - a value from BootImagesVerifier_error.h
 */
DxError_t DX_BIV_VRLChangeSwCompStoreAddr(DxUint32_t *vrlPtr, DxUint32_t adresses, DxUint32_t indexOfAddress)
{
    /* temp vrl header */
    VRL_Header_t *vrlHeaderPtr;
    
    /* number of SW components, offset to comps data */
    DxUint32_t numOfComps = 0, offsetToSwCompsData = 0;
    
    /* temporary pointer to SW comps data */
    VRL_ParamRecordInfo_t *swCompDataPtr;
    
    /* temp pointer to VRL */
    DxUint32_t *tempVRLPtr = vrlPtr;
    
    /*------------------
        CODE
    -------------------*/
    
    /* Check inputs */
    if (vrlPtr == DX_NULL){
    	DX_PAL_LOG_DEBUG("VRL ptr is NULL\n");
    	return DX_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
    }
    
    /* In case there is additional data - need to skip it */
    #ifdef DX_SB_ADDITIONAL_DATA_SUPPORTED  
    /* set the temporary address to after the additional data header */
    tempVRLPtr = tempVRLPtr + ADDITIONAL_DATA_SIZE_IN_BYTES/sizeof(DxUint32_t);
    #endif
    /* parse the VRL to point to the storage addresses */
    /*-------------------------------------------------*/
    vrlHeaderPtr = (VRL_Header_t*)tempVRLPtr;
    
    /* Calculate the VRL size according to offset to signature + sec address + num of comps * (comps params) */
    /*-------------------------------------------------------------------------------------------------------*/
    /* Get the number of sw comnponents from the header vrlSize field */
    numOfComps = (vrlHeaderPtr->vrlSize & VRL_LEN_NUM_OF_COMPS_BIT_MASK ) >> VRL_LEN_NUM_OF_COMPS_BIT_LOCATION;
    
    if (indexOfAddress > (numOfComps-1)) {
        DX_PAL_LOG_DEBUG("Invalid index\n");
    	return DX_BOOT_IMG_VERIFIER_INV_INPUT_PARAM; 
    }
    offsetToSwCompsData = (DxUint32_t)(vrlHeaderPtr->vrlSize & VRL_LEN_SIGNATURE_OFFSET_BIT_MASK) /* signature offset */
    		      + sizeof(VRL_Sign_t)/sizeof(DxUint32_t) /* signature */
    		      + sizeof(VRL_SecAddress_t)/sizeof(DxUint32_t); /* secondary address */
    
    /* Point to the SW comps data */
    tempVRLPtr = tempVRLPtr + offsetToSwCompsData;
    
    /* Change the relevant address */
    swCompDataPtr = (VRL_ParamRecordInfo_t*)(tempVRLPtr + indexOfAddress*sizeof(VRL_ParamRecordInfo_t)/sizeof(DxUint32_t));
    swCompDataPtr->StoreAddr = adresses;
    
    return DX_OK;

}/* End of DX_BIV_VRLChangeSwCompStoreAddr */
コード例 #2
0
/*!
 * This function adds a completion report to the completion fifo.
 *
 * \param qid The queue id.
 * \param taskId Completion task ID as set by vTaskSetCurrentTaskTag().
 * \param completionType COMPLETION_INTERNAL or COMPLETION_EXTERNAL.
 * \param axiWriteCount AXI transactions counter from previous completion report.
 */
void CompletionFifoInsert(int qid, uint32_t taskId, CompletionType_t *completionType, uint32_t axiWriteCount)
{
	uint8_t	fifoItem = 0;
	uint32_t fifoIdx;
	
	if (((CompletionType_t)completionType != COMPLETION_INTERNAL) &&
	    ((CompletionType_t)completionType != COMPLETION_EXTERNAL)) {
		DX_PAL_Abort("Bad completionType");
	}
	if (taskId >= BITMASK(FIFO_TASK_ID_BIT_SIZE)) {
		DX_PAL_Abort("Bad completionTaskId");
	}
	if (axiWriteCount >= BITMASK(FIFO_AXI_COUNTER_BIT_SIZE)) {
		DX_PAL_Abort("Bad axiWriteCount");
	}
	if ((gCompletionFifoHead[qid] - gCompletionFifoTail[qid]) >= COMPLETION_FIFO_LEN) {
		DX_PAL_Abort("Completion FIFO overflow");
	}
	
	SET_FIFO_COMPLETION_TYPE(fifoItem, (CompletionType_t)completionType);
	SET_FIFO_AXI_COUNTER(fifoItem, axiWriteCount);
	SET_FIFO_COMPLETION_TASK_ID(fifoItem, taskId);
	fifoIdx = gCompletionFifoHead[qid] & (COMPLETION_FIFO_LEN - 1);
	gCompletionFifo[qid][fifoIdx] = fifoItem;
	
	gCompletionFifoHead[qid]++;
			
	DX_PAL_LOG_DEBUG("qid=%d taskId=%d fifoIdx=%d gCompletionFifoHead[qid]=%d completionType=%s axiWriteCount=%d\n", 
		(int)qid, (int)taskId, (int)fifoIdx, (int)gCompletionFifoHead[qid],
		((CompletionType_t)completionType==COMPLETION_INTERNAL)?"INTERNAL":"EXTERNAL", (int)axiWriteCount);
}
コード例 #3
0
/*!
 * This function initializes the completion counter event, clears the
 * state structure and sets completion counter "0" as the first available
 * counter to be used when calling "AllocCounter".
 * 
 * \return int one of the error codes defined in err.h
 */
int InitCompletionPlat(void)
{
	uint8_t dummy;
	int qid;

	/* Clear completion fifo */
	for ( qid=0; qid < MAX_NUM_HW_QUEUES; qid++ ) {
		/* Clear FIFO head/tail */
		gCompletionFifoHead[qid] = 0;
		gCompletionFifoTail[qid] = 0;

		/* The global AXI write counter is reset only once */
		gAxiWriteCompleted[qid] = 0;

		gCompletionCount[qid] = 0;
		gExpectedAxiWrites[qid] = 0;
		gCompletionCtx[qid] = COMPLETION_INVALID;

		DX_PAL_MemSetZero( gCompletionFifo, MAX_NUM_HW_QUEUES*COMPLETION_FIFO_LEN );
		
		/* Clear all past AXI completion counters */
		/* Actual bus values of AXI IDs for queues (0-3) DMA are 8, 9, A, B */
		dummy = DX_HAL_ReadCcRegister(DX_CC_REG_OFFSET(CRY_KERNEL, AXIM_MON_COMP8) + QID_TO_AXI_ID(qid)*sizeof(uint32_t));
		DX_PAL_LOG_DEBUG("Initial AXI_MON_COMP%d value=0x%08X\n", (int)qid, (unsigned int)dummy);
		dummy = dummy; /*avoid compiler warning*/
	}
	
	return DX_RET_OK;
}
コード例 #4
0
static void InitCombinedContext(
	struct sep_ctx_combined *pCtx,
	CrysCombinedConfig_t *pConfig)
{
	CrysCombinedEngineSource_e engineSrc = INPUT_NULL;
	enum sep_engine_type engineType = SEP_ENGINE_NULL;
	int engineIdx;
	int done = 0;

	/* set alg */
	pCtx->alg = SEP_CRYPTO_ALG_COMBINED;
	pCtx->mode = 0;

	/* encode engines connections into SEP format */
	for (engineIdx = 0; (engineIdx < CRYS_COMBINED_MAX_NODES) && (!done); engineIdx++) {

		if(pConfig->node[engineIdx].pContext) {
			/* set context's pointers */
			pCtx->sub_ctx[engineIdx] = (struct sep_ctx_cache_entry *)DX_GetUserCtxLocation(pConfig->node[engineIdx].pContext);
		}
		else {
			pCtx->sub_ctx[engineIdx] = NULL;
		}
		/* set engine source */
		engineSrc = CrysCombinedEngineSrcGet(pConfig, engineIdx);

		/* set engine type */
		if (pCtx->sub_ctx[engineIdx] != NULL) {
			engineType = GetCryptoEngineType(pCtx->sub_ctx[engineIdx]->alg);
		} else if (engineSrc != INPUT_NULL) {
			/* incase engine source is not NULL and NULL sub-context
			is passed then DOUT is -DOUT */
			engineType = SEP_ENGINE_DOUT;
			done = 1; /* do not allow to set DOUT twice! */
		} else {
			/* both context pointer & input type are NULL -we're done */
			engineType = SEP_ENGINE_NULL;
			done = 1;
		}

		SepCombinedEnginePropsSet(&pCtx->mode, engineIdx, engineSrc, engineType);
		DX_PAL_LOG_DEBUG("engineSrc=%d  engineType=%d\n", engineSrc, engineType);
	}
}
コード例 #5
0
/** 
 * @brief This function gets the index of the OTP in which the HASH of the public key resides.
 *        
 *         
 * @param[in] hwBaseAddress - base address for the CC HW engines
 * @param[in] indexInOTP - index in OTP in which the required HASH resides 
 * @param[out] hashOutput - the HASH of the public key
 * @param[in] hashBufSize - the HASH buffer size in bytes
 *
 * @return DxError_t - On success the value DX_OK is returned, 
 *         on failure - a value from BootImagesVerifier_error.h
 */
DxError_t DX_BIV_GetPubKeyHASH(DxUint32_t hwBaseAddress,
			       DxUint32_t indexInOTP,
			       DxUint32_t *hashOutput,
			       DxUint32_t hashBufSize)
{
DxError_t error = DX_OK;

#ifdef BIG__ENDIAN
DxUint32_t i;
#endif    

/*------------------
    CODE
-------------------*/

/* Verify that the output buffer is in sufficient size */
if (hashBufSize < DX_SB_HASH_LENGTH_IN_WORDS* sizeof(DxUint32_t)){
	DX_PAL_LOG_DEBUG("HASH buf too small\n");
	return DX_BOOT_IMG_VERIFIER_HASH_BUF_TOO_SMALL;
}

/* Aquire control on the CC */
/*--------------------------*/
error = GEN_AcquireCCLock(hwBaseAddress);
if (error != DX_OK)
	return error;

/* Get the HASH from the SRAM */
/*----------------------------*/
error = NVM_ReadHASHPubKey(hwBaseAddress, indexInOTP, hashOutput);

#ifdef BIG__ENDIAN
for (i = 0; i < DX_SB_HASH_LENGTH_IN_WORDS; i++) {
	/* If in BIG__ENDIAN platforms revert the key (back to its original representation) */
	UTIL_ReverseBuff( (DxUint8_t*)&hashOutput[i] , sizeof(DxUint32_t) );
}
#endif
/* Release control on the CC */
/*---------------------------*/
GEN_ReleaseCCLock(hwBaseAddress);

return error;
}
コード例 #6
0
/** 
 * @brief This function is responsible to verification of the VRL list.
 *        The function will go over the VRL list starting from the first and verify it, in case 
 *        the verification fail, the function will go to the next VRL and verify it, till a suuccessfull 
 *        verification or the end of the list is reached.
 *        The verification process verifies the following:
 *        1. The primary public key as saved in the VRL versus the HASHd public key that is saved in the NVM/OTP
 *        2. The RSA signature of the VRL
 *        3. The SW version that should be bigger than the SW minimum version as is saved in the NVM/OTP
 *        4. Each of the SW components HASH as appear in the VRL 
 *         
 *
 * @param[in] flashRead_func - User's Flash read function used to read data from the flash to memory location
 * @param[in] userContext - User's context for the usage of flashRead_func
 * @param[in] hwBaseAddress - base address for the CC HW engines
 * @param[in] vrlList - VRL list ordered, the first item will be the first to be verified  
 * @param[in] numOfVrlInList - number of VRLs in the given list
 * @param[out] index_ptr - the index in the VRL list of the VRL that passed verification
 * @param[in] workspace_ptr - temporary buffer to load the VRL and SW components to
 * @param[in] workspaceSize - the temporary buffer size in bytes
 *
 * @return DxError_t - On success the value DX_OK is returned, 
 *         on failure - a value from BootImagesVerifier_error.h
 */
DxError_t DX_BIV_SwImageVerification(DX_SB_FlashRead flashRead_func,
				     void *userContext,
				     DxUint32_t hwBaseAddress,
				     DX_BIM_VRL_TABLE_t vrlList,
				     DxUint32_t numOfVrlInList,
				     DxUint32_t *index_ptr,
				     DxUint32_t *workspace_ptr,
				     DxUint32_t workspaceSize)
{
/* error variable */
DxError_t error = DX_OK;

/* internal index */
DxUint32_t i = 0;

/* secondary N hash that is saved in the Primary VRL to be verified with the secondary 
   N hash in secondary VRL */
DxUint32_t secondaryNHash[DX_SB_HASH_LENGTH_IN_WORDS];

/* s/w component data */
VRL_Parser_CompsData_t swCompsData;

/* indicator if secondary vrl exists */
DxUint8_t isSecExist = 0;

/* VRL info for secondary usage */
SW_Verification_Data_t secVrlData;

/*------------------
    CODE
-------------------*/

/* Verify input parameters */
if (flashRead_func == DX_NULL){
	DX_PAL_LOG_DEBUG("flashRead_func is NULL\n");
	return DX_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
}

/* Verify vrlLis */
if (vrlList == DX_NULL || numOfVrlInList == 0){
	DX_PAL_LOG_DEBUG("vrlList or numOfVrlInList are 0\n");
	return DX_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
}

if (index_ptr == DX_NULL || workspace_ptr == DX_NULL || workspaceSize == 0){
	DX_PAL_LOG_DEBUG("index_ptr || workspace_ptr || workspaceSize are zero\n");
	return DX_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
}

/* aquire control on the CC */
/*--------------------------*/
error = GEN_AcquireCCLock(hwBaseAddress);
if (error != DX_OK)
	return error;


/* Go over the VRL list in a loop till a VRL passes verification */
/*---------------------------------------------------------------*/
for (i = 0; i < numOfVrlInList; i++) {	
	/* 1. Verify the VRL RSA signature and public key */
	/*------------------------------------------------*/    
	error = DX_BIV_VRLVerification(NVM_ReadHASHPubKey, /* Get OTP */
				       flashRead_func,
				       userContext,
				       hwBaseAddress,
				       DX_TRUE,
				       &vrlList[i],
				       DX_NOT_TO_SET_PKA_OFFSET,
				       secondaryNHash,
				       workspace_ptr,
				       workspaceSize);                             

	/* In case of error continue to the next VRL in list */
	if (error != DX_OK) {
		DX_PAL_LOG_DEBUG("DX_BIV_VRLVerification returned 0x%X\n", (unsigned int)error);
		continue;
	}

	/* 2. Validate the SW components */
	/*-------------------------------*/
	/* For each SW component in a loop load (if required) the SW component and verify its HASH */
	error = DX_BIV_SWCompValidation(flashRead_func, userContext,
					hwBaseAddress,                                  
					&swCompsData,  
					&isSecExist,
					workspace_ptr,
					workspaceSize);

	if (error != DX_OK) {
		DX_PAL_LOG_DEBUG("DX_BIV_SWCompValidation returned 0x%X\n", (unsigned int)error);
		continue;
	}

	/* If operation succeeded => quit from the loop and return the index of the VRL that 
	passed the verification */
	if (error == DX_OK && isSecExist == DX_FALSE) {
		/* the validated index */
		*index_ptr = i;      
		goto RELEASE_AND_RETURN;
	}

	/* 5. In case there is a secondary VRL, need to verify it */
	/*--------------------------------------------------------*/
	if (error == DX_OK && isSecExist == DX_TRUE) {
		/* Get secondary data (if exist) */

		DX_BIV_ParseVrlGetSecData(workspace_ptr, secondaryNHash, swCompsData.hashSizeWords, 
					  &secVrlData.VRL_Address);
		secVrlData.Magic_Number = vrlList[i].Magic_Number;

		/* 1. Load the VRL from the Flash */
		/*--------------------------------*/
		error = DX_BIV_VRLVerification(NVM_ReadHASHPubKey, /* Get OTP */
					       flashRead_func,
					       userContext,
					       hwBaseAddress,
					       DX_FALSE,
					       &secVrlData,
					       DX_NOT_TO_SET_PKA_OFFSET,
					       secondaryNHash,
					       workspace_ptr,
					       workspaceSize);                       
		/* In case of failure go to the next VRL in the table */
		if (error != DX_OK){
			DX_PAL_LOG_DEBUG("DX_BIV_VRLVerification returned 0x%X\n", (unsigned int)error);
			continue;
		}

		/* 2. Validate the SW components */
		/*-------------------------------*/
		/* For each SW component in a loop load (if required) the SW component and verify its HASH */
		error = DX_BIV_SWCompValidation(flashRead_func, userContext,
						hwBaseAddress,                                  
						&swCompsData,  
						&isSecExist,
						workspace_ptr,
						workspaceSize);

		if (error != DX_OK) {
			DX_PAL_LOG_DEBUG("DX_BIV_SWCompValidation returned 0x%X\n", (unsigned int)error);
			continue;
		} else {
			/* If verification succeeded of the secondary VRL return the index of the Primary VRL that 
			   was validated */
			/* the validated index */
			*index_ptr = i;      
			goto RELEASE_AND_RETURN;
		}       
	}/* End of Secondary VRL verification */
}/* End of VRL table loop */

/* If the loop ended without a validated VRL return error */
error = DX_BOOT_IMG_VERIFIER_NO_VRL_PASSED_VALIDATION;
DX_PAL_LOG_DEBUG("no VRL passes validation\n");
RELEASE_AND_RETURN:

GEN_ReleaseCCLock(hwBaseAddress);  
return error;

} /* End of DX_BIV_SwImageVerification */
コード例 #7
0
/** 
 * @brief This function is responsible to verification of a VRL.
 *        The verification process verifies the following:
 *        1. The primary public key as saved in the VRL versus the HASHd public key that is saved in the NVM/OTP
 *        2. The RSA signature of the VRL
 *         
 * @param[in] SB_GetOTPHASH_func - Function pointer to user's	
 * 	      get public key HASH function
 * @param[in] flashRead_func - User's Flash read function used
 *	     to read data from the flash to memory location
 * @param[in] userContext - User's context for the usage of flashRead_func
 * @param[in] hwBaseAddress - base address for the CC HW engines
 * @param[in] isPrimaryVRL - an indicator if this is a primary
 *	      VRL (TRUE for primary, FALSE for secondary)
 * @param[in] vrlData - VRL data including storage address,
 *	  magic number etc.
 * @param[out] secondaryNHASH - will contain the secondary
 *	      public key HASH
 * @param[in] workspace_ptr - temporary buffer to load the VRL and SW components to
 * @param[in] workspaceSize - the temporary buffer size in bytes
 *
 * @return DxError_t - On success the value DX_OK is returned, 
 *         on failure - a value from BootImagesVerifier_error.h
 */
DxError_t DX_BIV_VRLVerification(Dx_SB_GetOTPHASH SB_GetOTPHASH_func, 
				 DX_SB_FlashRead flashRead_func,
				 void *userContext,
				 DxUint32_t hwBaseAddress,
				 DxUint8_t isPrimaryVRL,
				 SW_Verification_Data_t *vrlData,
				 DxUint32_t pkaOffset,
				 DxUint32_t *secondaryNHASH,
				 DxUint32_t *workspace_ptr,
				 DxUint32_t workspaceSize)
{
    /* error return */
    DxError_t error = DX_OK;
    
    /* pointers to inside the VRL */  
    DxUint32_t *VRL_ptr = workspace_ptr;
    
    /* public key hash saved in the NVM/OTP */
    HASH_Result_t savedPublicKeyHASH;
    
    /* temporary buffer */
    DxUint32_t VRLBufferSize = workspaceSize;
    
    /* SW minimum version */
    DxUint32_t savedSwMinVersion = 0;
    
    /* secondary VRL address */
    VRL_SecAddress_t secVRLAddress;
    
    /*------------------
        CODE
    -------------------*/

    #ifndef DX_SB_USE_RSA_SW
    /* Set the PKA offset if it is not set */
    if (pkaOffset != DX_NOT_TO_SET_PKA_OFFSET) {
	    DX_PAL_LOG_DEBUG("PKA offset is not set\n");
	    return DX_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
    }
    #endif

    /* 1. Get the sw minimum version from the NVM/OTP (if supported) */
    /*---------------------------------------------------------------*/
    #ifndef DX_OTP_SW_VERSION_NOT_SUPPORTED
    error = NVM_GetSwVersion(hwBaseAddress, &savedSwMinVersion);
    if (error != DX_OK)
    	return error;
    #endif
    
    /* 2. Get the public key (N||Np) hash from the NVM/OTP or from the external HASH */
    /*-------------------------------------------------------------------------------*/
    if (isPrimaryVRL == DX_TRUE) {
    	error = DX_BIV_GetPrimaryKeyHash(SB_GetOTPHASH_func, hwBaseAddress, savedPublicKeyHASH, vrlData->OTP_Key_Index,
    					 vrlData->Ext_HASH_Value);    
    	if (error != DX_OK){
    		DX_PAL_LOG_DEBUG("DX_BIV_GetPrimaryKeyHash returned 0x%X\n", (unsigned int)error);
    		return error;
    	}
    }
    
    /* 3. Load the VRL from the Flash */
    /*--------------------------------*/
    error = DX_BIV_VRLParserLoadVRL(flashRead_func, userContext, /* Flash read function & parameter */
    				vrlData->VRL_Address,	 /* VRL address inside the array */
    				vrlData->Magic_Number,	/* expected magic number */
    				VRL_ptr,       /* start of the workspace buffer */
    				&VRLBufferSize /* Size of the workspace buffer */ );
    if (error != DX_OK){
    	DX_PAL_LOG_DEBUG("DX_BIV_VRLParserLoadVRL  returned 0x%X\n", (unsigned int)error);
    	return error;
    }
    
    /* 4. Parse the VRL, verify the RSA signature */
    /*--------------------------------------------*/
    error = DX_BIV_VRLParser(isPrimaryVRL,		/* indicating if this is Primary VRL */ 
    			 hwBaseAddress,		/* base address for CC HW */                         
    			 savedPublicKeyHASH,	/* PubHash*/
    			 savedSwMinVersion,	/* Sw Min Version */ 
    			 VRL_ptr,		/* a pointer to the VRL */ 
    			 &secVRLAddress,	/* Secondary VRL address, 0 means there is no second VRL */                         
    			 secondaryNHASH);	/* N buffer, secondary N will be copied to it if secondary VRL exist*/                      
    
    if (error != DX_OK){
    	DX_PAL_LOG_DEBUG("DX_BIV_VRLParser returned 0x%X\n", (unsigned int)error);
    }
    
    return error;
}/*End of DX_BIV_VRLVerification */
コード例 #8
0
/** 
 * @brief This function is responsible to return the load 
 *        address and the sw image size according to given index
 *         
 * @param[in] vrlPtr - pointer to the vrl 
 * @param[in] swCompIndex - index of the imgae 
 * @param[out] swCompInfo - load address and size
 *  
 * @return DxError_t - On success the value DX_OK is returned, 
 *         on failure - a value from BootImagesVerifier_error.h
 */
DxError_t DX_BIV_GetSWImageInfo(DxUint32_t *vrlPtr, DxUint32_t swCompIndex, VRL_Internal_SW_Comp_Data_t *swCompInfo)
{
    /* error */
    DxError_t error = DX_OK;
    
    /* sw comp data */
    VRL_Parser_CompsData_t swCompsData;
    
    /* pointer to required additional data */
    VRL_ParamRecordInfo_t *recInfo_ptr;

    /* temp vrl header */
    VRL_Header_t *vrlHeaderPtr;
    
    /* number of SW components */
    DxUint32_t numOfComps = 0;
        
    /* temp pointer to VRL */
    DxUint32_t *tempVRLPtr = vrlPtr;
        
    /*------------------
        CODE
    -------------------*/
    /* Check inputs */
    if (vrlPtr == DX_NULL){
    	DX_PAL_LOG_DEBUG("VRL ptr is NULL\n");
    	return DX_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
    }
    
    /* In case there is additional data - need to skip it */
    #ifdef DX_SB_ADDITIONAL_DATA_SUPPORTED  
    /* set the temporary address to after the additional data header */
    tempVRLPtr = tempVRLPtr + ADDITIONAL_DATA_SIZE_IN_BYTES/sizeof(DxUint32_t);
    #endif
    /* parse the VRL to point to the storage addresses */
    /*-------------------------------------------------*/
    vrlHeaderPtr = (VRL_Header_t*)tempVRLPtr;
    
    /* Calculate the VRL size according to offset to signature + sec address + num of comps * (comps params) */
    /*-------------------------------------------------------------------------------------------------------*/
    /* Get the number of sw comnponents from the header vrlSize field */
    numOfComps = (vrlHeaderPtr->vrlSize & VRL_LEN_NUM_OF_COMPS_BIT_MASK ) >> VRL_LEN_NUM_OF_COMPS_BIT_LOCATION;
    
    if (swCompIndex > (numOfComps-1)) {
        DX_PAL_LOG_DEBUG("Invalid index\n");
    	return DX_BOOT_IMG_VERIFIER_INV_INPUT_PARAM; 
    }

    /* parse the vrl get the sw comp data */
    error = DX_BIV_ParseVrlGetSWComponentData(vrlPtr, &swCompsData, DX_NULL);
    if (error != DX_OK) {
        return error;
    }
    
    /* according to the index get the load address */
    swCompInfo->loadAddress = *(swCompsData.swHASHData_ptr + swCompIndex*(swCompsData.hashSizeWords + 1) + swCompsData.hashSizeWords);
    
    /* Point to record additional info */
    recInfo_ptr = (VRL_ParamRecordInfo_t*)(swCompsData.swAdditionalData_ptr + swCompIndex*(sizeof(VRL_ParamRecordInfo_t)/sizeof(DxUint32_t)));
    
    /* return the size */
    swCompInfo->swCompSizeBytes = recInfo_ptr->Len * sizeof(DxUint32_t);
    
    return DX_OK;
}/* End of DX_BIV_SetSramPkaAddr */