diff --git a/marvell/obm/Common/SecureBoot/Security.c b/marvell/obm/Common/SecureBoot/Security.c
new file mode 100644
index 0000000..73b47b5
--- /dev/null
+++ b/marvell/obm/Common/SecureBoot/Security.c
@@ -0,0 +1,814 @@
+/****************************************************************************
+ *
+ *  (C)Copyright 2005 - 2010 Marvell. All Rights Reserved.
+ *
+ *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL.
+ *  The copyright notice above does not evidence any actual or intended
+ *  publication of such source code. This Module contains Proprietary
+ *  Information of Marvell and should be treated as Confidential. The
+ *  information in this file is provided for the exclusive use of the
+ *  licensees of Marvell. Such users have the right to use, modify, and
+ *  incorporate this code into products for purposes authorized by the
+ *  license agreement provided they include this notice and the associated
+ *  copyright notice with any such product.
+ *
+ *  The information in this file is provided "AS IS" without warranty.
+ *
+ ***************************************************************************/
+
+#include "Security.h"
+#include "tim.h"
+#include "misc.h"
+#include "PlatformConfig.h"
+
+#if USE_WTM3_TBR
+	#include "WTM3_TBR_Lib.h"
+	//#include "WTM3_TBR_Interrupts.h"
+	#include "self_test_vectors.h"
+#elif BL_USE_WTM_CRYPTO
+	#include "WTM3_MBOX_Interface.h"
+#elif ( USE_IPPCP_LIB || BL_USE_SECURITY_CALLBACK )
+	#include "crypt_lib.h"
+#endif
+
+#if ( USE_IPPCP_LIB || BL_USE_SECURITY_CALLBACK )
+#if (AARCH64)
+__align(8)
+#endif
+	// Passed in data buffer to replace the IPPCP Read/Write space in the library. 
+#if ( ECDSA_SUPPORTED ) 
+	UINT8_T pECDSA_DataBuffer[10540]={0};	// For ECDSA - KeyBitLen=521
+#else
+	UINT8_T* pECDSA_DataBuffer = NULL;
+#endif
+#else
+	UINT8_T* pECDSA_DataBuffer = NULL;	// Used mainly for building non-IPPCP platforms.
+#endif
+
+
+// Generic pointers to security functions dynamically bound based on underlying security architecture.
+static SECURITY_FUNCTIONS SFs;
+
+pSECURITY_FUNCTIONS GetSecurityFunctionsPointer()
+{
+    return &SFs;
+}
+
+UINT8_T* GetECDSADataBufferPointer()
+{
+	return pECDSA_DataBuffer;
+}
+
+static UINT_T (*P_SHAMessageDigest) (const UINT8_T* pSrcMesgIn, UINT_T SrcMesgByteLen, \
+									UINT8_T* pMesgDigestOut, UINT_T DigestByteLen) = NULL;
+
+static UINT_T (*P_PKCS_DSA_Verify) (const UINT8_T* pSrcMesgIn, UINT_T SrcMesgByteLen, \
+									const pPLAT_DS pDSA, UINT8_T* DataBuffer) = NULL;	
+
+static UINT_T SHAMessageDigest(const UINT8_T* pSrcMesgIn, UINT_T SrcMesgByteLen, \
+								UINT8_T* pMesgDigestOut, UINT_T DigestByteLen)
+{
+#if LAPW && !CP_BOOT
+	if(PlatformIsLapwB0() && HwHashIsUsed()) {
+		dcache_clean_range(pSrcMesgIn, SrcMesgByteLen);
+		dcache_clean_invalidate_range(pMesgDigestOut, DigestByteLen);
+	}
+#endif
+
+	if (!P_SHAMessageDigest)
+		return SecurityFunctionNotSupported;
+
+	return P_SHAMessageDigest(pSrcMesgIn, SrcMesgByteLen, pMesgDigestOut, DigestByteLen);
+}
+
+static UINT_T PKCS_DSA_Verify(const UINT8_T* pSrcMesgIn, UINT_T SrcMesgByteLen, \
+								const pPLAT_DS pDSA, UINT8_T* DataBuffer)
+{
+#if LAPW && !CP_BOOT
+	if(PlatformIsLapwB0() && HwHashIsUsed()) {
+		dcache_clean_range(pSrcMesgIn, SrcMesgByteLen);
+		dcache_clean_invalidate_range(DataBuffer, DATABUFFERSIZE);
+	}
+#endif
+
+	if (!P_PKCS_DSA_Verify)
+		return SecurityFunctionNotSupported;
+
+	return P_PKCS_DSA_Verify(pSrcMesgIn, SrcMesgByteLen, pDSA, DataBuffer);
+}
+
+/********************	SecurityInitialization ***************************************
+*	 This routine is in charge of doing any security Initialization needed
+********************************************************************************************/
+UINT_T SecurityInitialization(UINT_T ver_adv)
+{
+ 	UINT_T Retval = NoError;
+
+#if USE_WTM3_TBR
+	//WTM3_TBR_Enable_AES_Interrupts();
+	SFs.pInitializeSecurity		= &WTM3_TBR_SecurityInitialization;
+	SFs.pSHAMessageDigest		= &WTM3_TBR_SHAMessageDigest;
+	SFs.pPKCS_DSA_Verify		= &WTM3_TBR_PKCS_DSA_Verify;
+  #if ECDSA_SUPPORTED
+	SFs.pECCP_DSA_Verify		= &WTM3_TBR_ECCP_DSA_Verify;
+  #else
+	SFs.pECCP_DSA_Verify		= NULL;
+  #endif
+	SFs.pGet_NonceBitLen		= &WTM3_TBR_Get_NonceBitLen;
+	SFs.pGet_Nonce				= &WTM3_TBR_Get_Nonce;
+	SFs.pAES_Decrypt			= &WTM3_TBR_AES_DECRYPT;
+	SFs.pAES_Encrypt			= &WTM3_TBR_AES_ENCRYPT;
+	SFs.pHMAC					= NULL;
+#elif BL_USE_WTM_CRYPTO
+	
+	SFs.pInitializeSecurity		= &WTM3_MBOX_SecurityInitialization;
+	SFs.pSHAMessageDigest		= &WTM3_MBOX_SHAMessageDigest;
+	SFs.pPKCS_DSA_Verify		= &WTM3_MBOX_PKCS_DSA_Verify;
+#if ECDSA_SUPPORTED
+	SFs.pECCP_DSA_Verify		= &WTM3_MBOX_ECCP_DSA_Verify;
+#else
+	SFs.pECCP_DSA_Verify		= NULL;
+#endif
+	SFs.pGet_NonceBitLen		= NULL;	// This maybe implemented in future 
+	SFs.pGet_Nonce				= NULL;	// This is supported by WTM Kernel (WTM_DRBG_GEN_RAN_BITS), maybe implemented in future
+	SFs.pAES_Decrypt			= &WTM3_MBOX_AES_Decrypt;
+	SFs.pAES_Encrypt			= &WTM3_MBOX_AES_Encrypt;
+	SFs.pHMAC					= NULL;
+#elif USE_IPPCP_LIB
+	SFs.pInitializeSecurity		= &IPPCP_SecurityInitialization;
+	SFs.pSHAMessageDigest		= &IPPCP_SHAMessageDigest;
+	SFs.pPKCS_DSA_Verify		= &IPPCP_PKCS_DSA_Verify;
+#if ECDSA_SUPPORTED
+#if ENABLE_NEON	 
+	SFs.pECCP_DSA_Verify		= &IPPCP_ECCP_DSA_Verify;
+#else
+	SFs.pECCP_DSA_Verify		= NULL;
+#endif
+#endif
+	SFs.pGet_NonceBitLen		= IPPCP_Get_NonceBitLen;
+	SFs.pGet_Nonce				= IPPCP_Get_Nonce;
+	SFs.pAES_Decrypt			= NULL;
+	SFs.pAES_Encrypt			= NULL;
+	SFs.pHMAC					= NULL;
+#elif BL_USE_SECURITY_CALLBACK
+	SetSecurityCallBackFunctionPointers();	// Sets the SFs function pointers with supported call back functions
+											// This needs to be a platform specific call as different ROMs
+											// support different security functions.
+#endif
+
+	P_SHAMessageDigest = SFs.pSHAMessageDigest;
+	SFs.pSHAMessageDigest = &SHAMessageDigest;
+
+	P_PKCS_DSA_Verify = SFs.pPKCS_DSA_Verify;
+	SFs.pPKCS_DSA_Verify = &PKCS_DSA_Verify;
+		 	
+ 	Retval = SFs.pInitializeSecurity(ver_adv);
+ 	return Retval;
+}
+
+/******************** SecurityShutdown*********************************************************
+* This routine should do Security Driver related cleanup and hardware shutdown 
+************************************************************************************************/
+
+UINT_T SecurityShutdown()
+{
+	UINT_T Retval = NoError;
+#if BL_USE_WTM_CRYPTO	
+	Retval = WTM3_MBOX_SecurityShutdown();
+#endif
+	return Retval;
+}
+
+/********************	ValidateTIMSignature ******************************************************
+*  Validate the TIM structure 
+*    It is assumed that the TIM structure has already been loaded with a call to LoadTIM()
+*	  in flash.c
+*
+********************************************************************************************/
+UINT_T ValidateTIMSignature(pTIM pTIM_h)
+{
+	UINT_T Retval = NoError;
+	CHAR *Buffer = NULL, *AlignedBuffer;
+
+	switch (pTIM_h->pTBTIM_DS->DSAlgorithmID)
+	{
+		case PKCS1_v1_5_Ippcp:
+#if ECDSA_SUPPORTED
+		case ECDSA_256:
+		case ECDSA_521:
+#endif
+		case PKCS1_v2_2_Ippcp:
+			break;
+		default:
+			return InvalidSecureBootMethodError;
+	}
+
+	if ((pTIM_h->pTBTIM_DS->DSAlgorithmID == PKCS1_v1_5_Ippcp) || (pTIM_h->pTBTIM_DS->DSAlgorithmID == PKCS1_v2_2_Ippcp))
+	{
+		if (SFs.pPKCS_DSA_Verify != NULL)	// Verify signature if this function is supported
+		{
+			if ( pTIM_h->pTBTIM_DS->HashAlgorithmID == SHA512)	// SHA512 is not supported with PKCS
+			{
+				return SecurityFunctionNotSupported;
+			}
+			Buffer = malloc(ALIGN_UP(DATABUFFERSIZE, DCACHE_LINE_SIZE));
+			if (Buffer) {
+				AlignedBuffer = ALIGN_UP((UINT_T)Buffer, DCACHE_LINE_SIZE);
+	 			Retval = SFs.pPKCS_DSA_Verify( (UINT8_T*) pTIM_h->pConsTIM, pTIM_h->pImg[0].ImageSizeToHash, pTIM_h->pTBTIM_DS, AlignedBuffer);
+				free(Buffer);
+			} else{
+				return HeapExhaustedError;
+			}
+		}
+		else	// Else, return not supported error
+		{
+			return SecurityFunctionNotSupported;
+		}		
+	}
+#if ECDSA_SUPPORTED
+	else if ((pTIM_h->pTBTIM_DS->DSAlgorithmID == ECDSA_256) || (pTIM_h->pTBTIM_DS->DSAlgorithmID == ECDSA_521))
+	{
+		if (SFs.pECCP_DSA_Verify != NULL)	// Verify signature if this function is supported
+		{
+	 		Retval = SFs.pECCP_DSA_Verify( (UINT8_T*) pTIM_h->pConsTIM, pTIM_h->pImg[0].ImageSizeToHash, pTIM_h->pTBTIM_DS, pECDSA_DataBuffer);
+		}
+		else	// Else, return not supported error
+		{
+			return SecurityFunctionNotSupported;
+		}
+	}
+#endif
+	else { 
+		return InvalidDSAError;
+	}
+	
+	if (Retval != NoError)
+		return InvalidTIMImageError; 
+ 	
+ 	return NoError;
+}
+
+/********************	VerifySignature ******************************************************
+*  Verify the DSA for any signature
+********************************************************************************************/
+UINT_T VerifySignature(const UINT8_T* pBufferToVerifyIn, UINT_T NumBytesToVerify, const UINT_T* pSignatureIn, const pKEY_MOD_3_4_0 pKeyIn, UINT_T ReverseSignatureBytes)
+{
+	UINT_T Retval = NoError;
+	//UINT_T KeyByteLen = (pKeyIn->KeySize +7)>>3;
+	UINT_T KeySizeInWords = (pKeyIn->KeySize==521) ? 17 : pKeyIn->KeySize/32;
+	PLAT_DS Signature;
+	CHAR *Buffer = NULL, *AlignedBuffer;
+	UINT_T i;
+	const pPLAT_DS pSignature = & Signature;
+
+	/* abandoned, ReverseSignatureBytes is always 0 in OBM
+	if(ReverseSignatureBytes) {
+		ReverseBytes((UINT8_T *)pSignatureIn, KeyByteLen);	//reverse bytes for signature
+	}
+	*/
+
+	Signature.DSAlgorithmID = pKeyIn->EncryptAlgorithmID;
+	Signature.KeySize = pKeyIn->KeySize;
+	Signature.HashAlgorithmID = pKeyIn->HashAlgorithmID;
+
+	if ((pKeyIn->EncryptAlgorithmID == PKCS1_v1_5_Ippcp) || (pKeyIn->EncryptAlgorithmID == PKCS1_v2_2_Ippcp))
+	{
+		if (SFs.pPKCS_DSA_Verify != NULL)	// Verify signature if this function is supported
+		{
+			for (i=0; i < KeySizeInWords; i++)
+			{
+				Signature.Rsa.RSAModulus[i] = pKeyIn->Rsa.RSAModulus[i];
+				Signature.Rsa.RSAPublicExponent[i] = pKeyIn->Rsa.RSAPublicExponent[i];
+				Signature.Rsa.RSADigS[i] = pSignatureIn[i];
+			}
+			Buffer = malloc(ALIGN_UP(DATABUFFERSIZE, DCACHE_LINE_SIZE));
+			if (Buffer) {
+ 				AlignedBuffer = ALIGN_UP((UINT_T)Buffer, DCACHE_LINE_SIZE);
+ 				Retval = SFs.pPKCS_DSA_Verify(pBufferToVerifyIn, NumBytesToVerify, pSignature, AlignedBuffer);
+				free(Buffer);
+			} else {
+				return HeapExhaustedError;
+			}
+		}
+		else	// Else, return not supported error
+		{
+			return SecurityFunctionNotSupported;
+		}		
+	}
+#if ECDSA_SUPPORTED
+	else if ((pKeyIn->EncryptAlgorithmID == ECDSA_256) || (pKeyIn->EncryptAlgorithmID == ECDSA_521)) 
+	{
+		if (SFs.pECCP_DSA_Verify != NULL)	// Verify signature if this function is supported
+		{
+			for (i=0; i < KeySizeInWords; i++)
+			{
+				Signature.Ecdsa.ECDSAPublicKeyCompX[i] = pKeyIn->Ecdsa.PublicKeyCompX[i];
+				Signature.Ecdsa.ECDSAPublicKeyCompY[i] = pKeyIn->Ecdsa.PublicKeyCompY[i];
+				Signature.Ecdsa.ECDSADigS_R[i] = pSignatureIn[i];
+				Signature.Ecdsa.ECDSADigS_S[i] = pSignatureIn[MAXECCKEYSIZEWORDS+i];
+			}
+ 			Retval = SFs.pECCP_DSA_Verify(pBufferToVerifyIn, NumBytesToVerify, pSignature, pECDSA_DataBuffer);
+		}
+		else	// Else, return not supported error
+		{
+			return SecurityFunctionNotSupported;
+		}
+	}
+#endif
+	else { 
+		return InvalidDSAError;
+	}  
+
+    return Retval;
+}
+
+
+/********************	ValidateImage ******************************************************
+*  Validate the Image based on a Hash passed in for the TIM or the hash for individual images
+*  can be determined from IMAGE_INFO structure.
+*
+********************************************************************************************/
+UINT_T ValidateImage(UINT_T ImageAddr, UINT_T ImageID, pTIM pTIM_h)
+{
+	UINT_T Retval = NoError;
+	UINT_T HashSize = 0;
+	UINT_T i, ImageSize, HashAlgorithmID;
+	UINT_T *Buffer = NULL;
+	UINT_T *CalculatedHash;//Contains 16 32-bit words
+	UINT_T HashInTIM[WordLengthOf_SHA512];				// Contains 16 32-bit words
+	UINT_T ImageType;
+
+
+	pIMAGE_INFO_3_4_0 pImageInfo = NULL;
+	pImageInfo = FindImageInTIM(pTIM_h, ImageID);
+	if (pImageInfo == NULL)
+		return NoError; // return no error if not tim included
+
+	// If (TRUSTED TIM) or (TRUSTED FUSE BIT is set)
+	if (pTIM_h->pConsTIM->VersionBind.Trusted)
+	{
+		// If we are trying to Validate the TIM, it requires checking the DS. Special method to do that.
+		if ((pImageInfo->ImageID == TIMIDENTIFIER) ||  (pImageInfo->ImageID == NONTZDTIMID) )
+		{
+			Retval = ValidateTIMSignature(pTIM_h);
+			if (Retval != NoError)
+				return InvalidTIMImageError;
+			else
+				return Retval;
+	 	}
+	}
+
+	// First get relavant image data.
+	ImageSize = pImageInfo->ImageSize;	
+	HashSize  = pImageInfo->ImageSizeToHash;
+	HashAlgorithmID = pImageInfo->HashAlgorithmID; 
+
+	// Make sure we got an expected HashAlgorithmID
+	switch (HashAlgorithmID)
+	{
+		case SHA160:
+		case SHA256:
+		case SHA512:
+			break;
+		default:
+			return InvalidSecureBootMethodError;
+	}
+
+	ImageType = pImageInfo->PartitionNumber.bits.ImageType;
+
+	switch(ImageType) {
+	case DLCMD_LZMA_IMAGE_TYPE:
+	case DLCMD_LZMA2_IMAGE_TYPE:
+	case DLCMD_YAFFS_LZMA_IMAGE_TYPE:
+	case DLCMD_UBIFS_LZMA_IMAGE_TYPE:
+	case DLCMD_JFFS2_LZMA_IMAGE_TYPE:
+	case DLCMD_RAW_LZMA_IMAGE_TYPE:
+	case DLCMD_IMG_LZMA_IMAGE_TYPE:
+	case DLCMD_IMG_MXZ_IMAGE_TYPE:
+		break;
+	default:
+		if(ImageSize < HashSize)
+			return (HashSizeMismatch);
+	}
+
+	if( HashSize == 0 ) 
+		return NoError;
+
+	// Read the image hash into a local variable.
+	for (i = 0; i < (HashAlgorithmID / 4); i++)
+	{
+		HashInTIM[i] = pImageInfo->Hash[i];			// Save the actual hash value
+	}
+
+	// If the image that will be validated is the TIM itself, we
+	// need to sample the TIM.bin hash out of the TIM image struct
+	// and fill it with zeroes so that we can compute the correct
+	// hash again.
+	if ( (pImageInfo->ImageID == TIMIDENTIFIER)  || (pImageInfo->ImageID == NONTZDTIMID) )
+	{
+		for (i = 0; i < (HashAlgorithmID / 4); i++)
+		{
+			pImageInfo->Hash[i] = 0x0; 				// Overwrite the actual hash value with zeroes.
+		}
+	}
+
+	Buffer = malloc(ALIGN_UP((WordLengthOf_SHA256 << 2), DCACHE_LINE_SIZE));
+	if (Buffer == NULL) {
+		return HeapExhaustedError;
+	}
+	CalculatedHash = ALIGN_UP((UINT_T)Buffer, DCACHE_LINE_SIZE);
+
+	// If HASHing is supported, compute the hash
+	if (SFs.pSHAMessageDigest != NULL)
+	{
+		Retval = SFs.pSHAMessageDigest((UINT8_T*)ImageAddr, HashSize, (UINT8_T*) CalculatedHash, (HASHALGORITHMID_T) HashAlgorithmID);
+	}
+	else	// Else, return not supported error
+	{
+		free(Buffer);
+		return SecurityFunctionNotSupported;
+	}
+
+	// Write back the hash value to the hash field of the TIM image.
+	if ( (pImageInfo->ImageID == TIMIDENTIFIER)  || (pImageInfo->ImageID == NONTZDTIMID) )
+	{
+		for (i = 0; i < (HashAlgorithmID / 4); i++)
+		{
+			pImageInfo->Hash[i] = HashInTIM[i]; 	// Write the hash values back.
+		}
+	}
+
+	// Check the return value coming from the SHAMessageDigest function.
+	// If there is an error, return with this error code.
+	if (Retval != NoError) {
+		free(Buffer);
+		return Retval;
+	}
+
+	// Compare the 2 hashes
+	for (i = 0; i < (HashAlgorithmID / 4); i++)
+	{
+		if (HashInTIM[i] != CalculatedHash[i]) {
+			free(Buffer);
+			return (InvalidImageHash);
+		}
+	}
+
+	free(Buffer);
+ 	return Retval;
+}
+
+UINT_T ValidateImageSDTim(UINT_T ImageAddr, UINT_T ImageID, pTIM pDTIM, pTIM pTIM_h)
+{
+#ifdef CONFIG_ASR_SDTIM
+	UINT_T Retval = NoError;
+	pTIM pSDTIM_h = NULL;
+	pIMAGE_INFO_3_4_0 pImageInfo = NULL;
+	pIMAGE_INFO_3_4_0 pSdtimInfo = NULL;
+	UINT_T SecCfg = 0;
+
+	pImageInfo = FindImageInTIM(pDTIM, ImageID);
+	if (pImageInfo == NULL)
+		return NoError; // return no error if not tim included
+
+	if(!ImageIsSDTIMIncluded(pImageInfo))
+		return ValidateImage(ImageAddr, ImageID, pDTIM);
+
+	pSDTIM_h = malloc(sizeof(TIM));
+	if(pSDTIM_h == NULL)
+		return HeapExhaustedError;
+
+	Retval = SetTIMPointers(ImageAddr, pSDTIM_h);
+	if(Retval) {
+		free(pSDTIM_h);
+		return InvalidTIMImageError;
+	}
+
+	pSdtimInfo = FindImageInTIM(pSDTIM_h, SDTIM);
+	if(pSdtimInfo == NULL) {
+		free(pSDTIM_h);
+		return TIMNotFound;
+	}
+
+	SecCfg = GetSDTimSecureConfig(pSdtimInfo);
+	if(SecCfg == 0) {
+		free(pSDTIM_h);
+		return NoError;
+	}
+
+	Retval = ValiateDTIM(pSDTIM_h, pTIM_h);
+	if(Retval != NoError) {
+		free(pSDTIM_h);
+		return Retval;
+	}
+
+	ImageAddr += GetSDTimSpaceSize(pSdtimInfo);
+	Retval = ValidateImage(ImageAddr, ImageID, pSDTIM_h);
+	free(pSDTIM_h);
+
+	return Retval;
+#else
+	(VOID)pTIM_h;
+	return ValidateImage(ImageAddr, ImageID, pDTIM);
+#endif
+}
+
+#if TRUSTED
+/******************** VerifyPlatformKey *********************************************************
+* 	Verify that the hash of the keys stored in this Digital Signature match what's burned on the processor
+************************************************************************************************/
+UINT_T VerifyPlatformKey (pTIM pTIM_h)
+{
+	UINT_T Retval = NoError;
+	UINT_T FusedOEMKeyHash[WordLengthOf_SHA256];
+	UINT_T zero[WordLengthOf_SHA256];
+	UINT_T HashDataSizeInBytes, KeySizeInWords;
+	UINT_T KeyData[BINDKEYSIZE] = {0};
+	CHAR *Buffer = NULL;
+	UINT_T *CalculatedHash;			// Contains 8 words
+	UINT_T	i;
+
+	memset(zero, 0, ByteLengthOf_SHA256); //clear out 32 bytes
+
+	// Read out the fuse hashes
+	Retval = ReadOemHashKeyFuseBits(FusedOEMKeyHash, ByteLengthOf_SHA256 );
+	if (Retval != NoError)
+		 return Retval;
+
+	if (memcmp(zero, FusedOEMKeyHash, ByteLengthOf_SHA256) == 0) // No OEM key Hash is burnt, just return NoError
+		return NoError;
+	
+	switch (pTIM_h->pTBTIM_DS->DSAlgorithmID)
+	{
+		case PKCS1_v1_5_Ippcp:
+#if ECDSA_SUPPORTED
+		case ECDSA_256:
+		case ECDSA_521:
+#endif
+		case PKCS1_v2_2_Ippcp:
+			break;
+		default:
+			return InvalidSecureBootMethodError;
+	} 
+
+	switch (pTIM_h->pTBTIM_DS->HashAlgorithmID)
+	{
+		case SHA160:
+		case SHA256:
+		case SHA512:
+			break;
+		default:
+			return InvalidSecureBootMethodError;
+	} 
+
+	KeySizeInWords = (pTIM_h->pTBTIM_DS->KeySize==521)?17:pTIM_h->pTBTIM_DS->KeySize/32; // Convert Bits to Words
+	
+	if (pTIM_h->pConsTIM->VersionBind.Version >= (TIM_3_4_00))
+		HashDataSizeInBytes = (KeySizeInWords*2 + 1) * 4;	// (crypto_scheme||modulus-or-X||exponent-or-Y) in bytes (*4)
+	else
+		HashDataSizeInBytes = KeySizeInWords *4*2;			// (exponent-or-X||modulus-or-Y) in bytes (*4)	
+
+		
+	// If LONG_KEYS == 1, hash algorithm has to be SHA512
+	//if ( (pFuses->bits.LongKeys == LONGKEYSENABLED) && (pTIM_h->pTBTIM_DS->HashAlgorithmID != SHA512) )
+	//	return InvalidKeyHashError;
+			
+
+	// Prepare the KeyData to calculate Hash of the Keys
+	if ((pTIM_h->pTBTIM_DS->DSAlgorithmID == PKCS1_v1_5_Ippcp) || (pTIM_h->pTBTIM_DS->DSAlgorithmID == PKCS1_v2_2_Ippcp))
+	{
+
+		if (pTIM_h->pConsTIM->VersionBind.Version >= (TIM_3_4_00)) {
+
+			// 1) Pack the crypto_scheme
+			//crypto_scheme:	0x0000A100	PKCSv1_SHA1_1024RSA  
+			//					0x0000A110	PKCSv1_SHA256_1024RSA
+			//					0x0000A200	PKCSv1_SHA1_2048RSA  
+			//					0x0000A210	PKCSv1_SHA256_2048RSA
+			//					0x0000A300	PKCSv1_PSS_SHA1_1024RSA  
+			//					0x0000A310	PKCSv1_PSS_SHA256_1024RSA
+			//					0x0000A400	PKCSv1_PSS_SHA1_2048RSA  
+			//					0x0000A410	PKCSv1_PSS_SHA256_2048RSA
+			if(pTIM_h->pTBTIM_DS->HashAlgorithmID == SHA256)
+			{
+				if (pTIM_h->pTBTIM_DS->DSAlgorithmID == PKCS1_v1_5_Ippcp)
+					KeyData[0] = (KeySizeInWords == 64) ? PKCSv1_SHA256_2048RSA : PKCSv1_SHA256_1024RSA;
+				else if (pTIM_h->pTBTIM_DS->DSAlgorithmID == PKCS1_v2_2_Ippcp)
+					KeyData[0] = (KeySizeInWords == 64) ? PKCSv1_PSS_SHA256_2048RSA : PKCSv1_PSS_SHA256_1024RSA;
+			}
+			else	 // Defaults to 160
+			{
+				if (pTIM_h->pTBTIM_DS->DSAlgorithmID == PKCS1_v1_5_Ippcp)
+					KeyData[0] = (KeySizeInWords == 64) ? PKCSv1_SHA1_2048RSA : PKCSv1_SHA1_1024RSA;
+				else if (pTIM_h->pTBTIM_DS->DSAlgorithmID == PKCS1_v2_2_Ippcp)
+					KeyData[0] = (KeySizeInWords == 64) ? PKCSv1_PSS_SHA1_2048RSA : PKCSv1_PSS_SHA1_1024RSA;
+			}
+
+			// 2) Pack the Modulus and Exponent
+			for (i=0; i < KeySizeInWords; i++)
+			{
+				KeyData[i+1] = pTIM_h->pTBTIM_DS->Rsa.RSAModulus[i];
+				KeyData[i+KeySizeInWords+1] = pTIM_h->pTBTIM_DS->Rsa.RSAPublicExponent[i];
+			}
+		}
+		else {	// DO NOT include crypto_scheme and DO NOT swap exponent and modulus !!!
+			// Pack the Exponent and Modulus
+			for (i=0; i < KeySizeInWords; i++)
+			{
+				KeyData[i] = pTIM_h->pTBTIM_DS->Rsa.RSAPublicExponent[i];
+				KeyData[i+KeySizeInWords] = pTIM_h->pTBTIM_DS->Rsa.RSAModulus[i];
+			}
+		}
+	}
+#if ECDSA_SUPPORTED
+	else // ECDSA
+	{
+		if (pTIM_h->pConsTIM->VersionBind.Version >= (TIM_3_4_00)) {
+		    // 1) Pack the crypto_scheme
+			//crypto_scheme:	0x0000B101	ECCP256_FIPS_DSA_SHA1  
+			//					0x0000B111	ECCP256_FIPS_DSA_SHA256
+			//					0x0000B141	ECCP256_FIPS_DSA_SHA512  
+			//					0x0000B301	ECCP521_FIPS_DSA_SHA1  
+			//					0x0000B311	ECCP521_FIPS_DSA_SHA256
+			//					0x0000B341	ECCP521_FIPS_DSA_SHA512
+			if(pTIM_h->pTBTIM_DS->HashAlgorithmID == SHA512)
+				KeyData[0] = (KeySizeInWords == 17) ? ECCP521_FIPS_DSA_SHA512 : ECCP256_FIPS_DSA_SHA512;				
+			else if(pTIM_h->pTBTIM_DS->HashAlgorithmID == SHA256)
+				KeyData[0] = (KeySizeInWords == 17) ? ECCP521_FIPS_DSA_SHA256 : ECCP256_FIPS_DSA_SHA256;
+			else	 // Defaults to 160
+				KeyData[0] = (KeySizeInWords == 17) ? ECCP521_FIPS_DSA_SHA1 : ECCP256_FIPS_DSA_SHA1;
+			
+			// 2) Pack the X-coordinate and Y-coordinate
+			for (i=0; i < KeySizeInWords; i++)
+			{
+				KeyData[i+1] = pTIM_h->pTBTIM_DS->Ecdsa.ECDSAPublicKeyCompX[i]; 
+				KeyData[i+KeySizeInWords+1] = pTIM_h->pTBTIM_DS->Ecdsa.ECDSAPublicKeyCompY[i];
+			}
+		}
+		else {	// DO NOT include crypto_scheme !!!
+			// Pack the X-coordinate and Y-coordinate
+			for (i=0; i < KeySizeInWords; i++)
+			{
+				KeyData[i] = pTIM_h->pTBTIM_DS->Ecdsa.ECDSAPublicKeyCompX[i]; 
+				KeyData[i+KeySizeInWords] = pTIM_h->pTBTIM_DS->Ecdsa.ECDSAPublicKeyCompY[i];
+			}
+		}
+	}
+#endif
+
+	//Key Padding is on by default
+	HashDataSizeInBytes = BINDKEYSIZE*4; // MaxKeySize*2+CryptoScheme in Bytes: 129*4 = 516
+
+	Buffer = malloc(ALIGN_UP((WordLengthOf_SHA256 << 2), DCACHE_LINE_SIZE));
+	if (Buffer == NULL) {
+		return HeapExhaustedError;
+	}
+	CalculatedHash = ALIGN_UP((UINT_T)Buffer, DCACHE_LINE_SIZE);
+
+	// Do the SHA Hash				
+	Retval =  SFs.pSHAMessageDigest((unsigned char *)KeyData, HashDataSizeInBytes,
+									(unsigned char *)CalculatedHash, 
+									(HASHALGORITHMID_T) pTIM_h->pTBTIM_DS->HashAlgorithmID);
+										
+	if (Retval != NoError){
+		free(Buffer);
+		return Retval;
+	}
+
+	// Compare Hash of the Keys from the TIM vs. what's stored in the fuses.
+	for (i = 0; i < (pTIM_h->pTBTIM_DS->HashAlgorithmID / 4); i++)
+	{
+		if (CalculatedHash[i] != FusedOEMKeyHash[i]) {
+			free(Buffer);
+			return (InvalidOTPHashError);
+		}
+	}
+	
+	free(Buffer);
+	return Retval;
+}
+
+/********************	ValidateKeyHashes ******************************************************
+*  Validate the Keys based on a OTP Hash passed or from the Hash stored in TIM
+*	If the OEM keys are being verified (TIMIDENTIFIER) do the platform verify PI as well
+********************************************************************************************/
+UINT_T VerifyKey(KEYMODULES_T KeyType, pTIM pTIM_h)
+{
+	UINT_T Retval = NoError;
+	
+	// Check if we are to Perform Platform Verification.
+	if (KeyType == PlatformVerificationKey)
+		Retval = VerifyPlatformKey(pTIM_h);
+
+	// TBD Add support to verify other keys as well as needed.
+
+	return Retval;
+}
+
+/********************	CalcBufferHash ******************************************************
+*  Calc the Hash of Input Buffer, Not Useds
+********************************************************************************************/
+INT_T CalcBufferHash(UINT_T *Buffer, UINT_T NumBytesToHash, UINT_T *HashBuff, HASHALGORITHMID_T HashType)
+{
+	UINT_T Retval = NoError;
+	switch (HashType)
+	{
+		case SHA160:
+		case SHA256:
+		case SHA512:
+			break;
+		default:
+			return InvalidSecureBootMethodError;
+	}
+	Retval = SFs.pSHAMessageDigest((UINT8_T*)Buffer, NumBytesToHash, (UINT8_T*) HashBuff, HashType);			
+
+	return Retval;
+}
+
+/********************	VerifyBufferHash ******************************************************
+*  Verify the Hash of Input Buffer, Not Used
+********************************************************************************************/
+UINT_T VerifyBufferHash(UINT_T BufferAddr, UINT_T NumBytesToVerify, HASHALGORITHMID_T HashType, const UINT_T * pHashValueIn)
+{
+	UINT_T Retval, i;
+	UINT_T CalculatedHash[WordLengthOf_SHA512];			// Contains 16 32-bit words
+
+	if( NumBytesToVerify == 0 ) 
+		return NoError;
+
+	switch (HashType)
+	{
+		case SHA160:
+		case SHA256:
+		case SHA512:
+			break;
+		default:
+			return InvalidSecureBootMethodError;
+	} 
+
+
+	// Compute the hash
+	Retval = SFs.pSHAMessageDigest((UINT8_T*)BufferAddr, NumBytesToVerify, (UINT8_T*) CalculatedHash, HashType);			
+
+	// Check the return value coming from the SHAMessageDigest function.
+	// If there is an error, return with this error code.
+	if (Retval != NoError)
+		return Retval;
+
+	// Compare the 2 hashes
+	for (i = 0; i < (HashType / 4); i++)
+	{
+		if (pHashValueIn[i] != CalculatedHash[i])
+			return (InvalidImageHash);
+	}
+
+ 	return NoError;
+}
+    
+#endif //BOOTROM
+
+
+#if !BOOTROM	// BootLoader Only
+/******************** VerifyEncryptedKey ***************************************************
+*  Verify the Signature of Encrypted Key
+********************************************************************************************/
+UINT_T VerifyEncryptedKey(pKEY_MOD_3_4_0 PlainTextKey, pKEY_MOD_3_4_0 EncryptedKey, pKEY_MOD_3_4_0 DecryptionKey)
+{		
+	UINT_T Retval = NoError; 
+ 
+	if ((DecryptionKey->EncryptAlgorithmID == PKCS1_v1_5_Ippcp) || (DecryptionKey->EncryptAlgorithmID == PKCS1_v2_2_Ippcp))
+	{
+		// First verify the signature of the public exponent 	
+		Retval = VerifySignature((UINT8_T*) PlainTextKey->Rsa.RSAPublicExponent, (PlainTextKey->KeySize)/8, (UINT_T*) EncryptedKey->EncryptedRsa.EncryptedHashRSAPublicExponent, DecryptionKey, 0);
+		if (Retval != NoError)	// Signature of the exponent is NOT valid
+		{
+			return Retval;
+		}
+		else					// Signature of the exponent is valid
+		{
+			// Verify the signature of the public modulus 	
+			Retval = VerifySignature((UINT8_T*) PlainTextKey->Rsa.RSAModulus, (PlainTextKey->KeySize)/8, (UINT_T*) EncryptedKey->EncryptedRsa.EncryptedHashRSAModulus, DecryptionKey, 0);
+		}
+	}
+#if ECDSA_SUPPORTED
+	else if ((DecryptionKey->EncryptAlgorithmID == ECDSA_256) || (DecryptionKey->EncryptAlgorithmID == ECDSA_521))
+	{
+		// First verify the signature of the X component 	
+		Retval = VerifySignature((UINT8_T*) PlainTextKey->Ecdsa.PublicKeyCompX, ((PlainTextKey->KeySize+31)/32)*4, (UINT_T*) EncryptedKey->EncryptedEcdsa.EncryptedHashPublicKeyCompX_R, DecryptionKey, 0);
+		if (Retval != NoError)	// Signature of the X component is NOT valid
+		{
+			return Retval;
+		}
+		else					// Signature of the X component is valid
+		{
+			// Verify the signature of the Y component 	
+			Retval = VerifySignature((UINT8_T*) PlainTextKey->Ecdsa.PublicKeyCompY, ((PlainTextKey->KeySize+31)/32)*4, (UINT_T*) EncryptedKey->EncryptedEcdsa.EncryptedHashPublicKeyCompY_R, DecryptionKey, 0);
+		}
+	}
+#endif
+	else
+		return InvalidEncAlgorithmID; 
+	return Retval;
+}
+
+#endif	// #if !BOOTROM
