| /**************************************************************************** | |
| * | |
| * (C)Copyright 2015 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 "GEU_Provisioning.h" | |
| #include "Security.h" | |
| #include "Errors.h" | |
| #include "platform_geu_fuse_internal.h" | |
| #include "geu_interface.h" | |
| #include "GEU.h" | |
| #include "ProtocolManager.h" | |
| #include "timer.h" | |
| #include "nza3_fuse_config.h" | |
| /////////////////// Internal Functions /////////////////// | |
| /** | |
| * get fuse configuration spec | |
| */ | |
| // FixME: use generic fuse_conf_spec | |
| static fuse_conf_spec_t GetFuseConfSpec(void* parameter) | |
| { | |
| return nza3_fuse_conf_spec; | |
| } | |
| static UINT_T burn_security_usb_ecc(UINT_T prgecc) | |
| { | |
| UINT_T result; | |
| struct GEU_FuseBurnStatus burn_status; | |
| struct GEU_FuseBurnStatus* pburn_status = &burn_status; | |
| result = GEU_BurnFuseBlock_SecurityUSBIDECC(pburn_status); | |
| return result; | |
| } | |
| /** | |
| * set block seven non-active | |
| * | |
| */ | |
| static void reset_blk7_active_status(void) | |
| { | |
| s_blk_seven_active = 0; | |
| } | |
| /** | |
| * set block seven active | |
| * | |
| */ | |
| static UINT_T set_blk7_active(void) | |
| { | |
| UINT_T result; | |
| if (s_blk_seven_active == 0) { | |
| result = GEU_SetActiveFuseBlock(K_USBID_FUSEBLOCK); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| s_blk_seven_active = 1; | |
| } | |
| return NoError; | |
| } | |
| /** | |
| * Attention: this function must kept consistent with what is done by Boot ROM, | |
| * for exmaple, the pack order for public key | |
| * perform platform binding | |
| * @parameter ptim: pointer to TIM | |
| * @parameter parameter: should be NULL | |
| * @return: FUSE_FuseBurnPowerNotEnabled if UsbPhy band gap is not enabled | |
| * other error code otherwise | |
| * | |
| * Note: Due to the need of provisioning of non-trusted platform and minimize | |
| * the code size, we have a dummy implementation of this function for | |
| * non-trusted case. | |
| */ | |
| // FixME: set algorithm id using info form TIM | |
| extern UINT_T GEU_LIB_BindPlatform(pTIM ptim, void* parameter) | |
| { | |
| UINT_T result = NoError; | |
| UINT_T key_word_cnt, hash_data_size_in_bytes; | |
| UINT_T data[BINDKEYSIZE] = {0}; | |
| UINT_T fusedata[DIGEST_WLEN_MAX]; | |
| UINT_T digest[DIGEST_WLEN_MAX]; | |
| struct GEU_FuseBurnStatus burn_status; | |
| struct GEU_FuseBurnStatus* pburn_status = &burn_status; | |
| UINT_T programmed = 0; | |
| UINT_T i; | |
| pSECURITY_FUNCTIONS pSFs = GetSecurityFunctionsPointer(); | |
| if (parameter != NULL) { | |
| s_uart_logger = (logger) parameter; | |
| } | |
| GEU_UARTLOG("S OEMKeyHash...\n"); | |
| result = GEU_ReadOemHashKeyFuseBits(fusedata, K_SHA256_SIZE); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| for (i = 0; i < K_SHA256_SIZE >> 2; i++) { | |
| if (fusedata[i] != 0) { | |
| programmed = 1; | |
| break; | |
| } | |
| } | |
| if (ptim->pConsTIM->VersionBind.Version < (TIM_3_4_00)) { | |
| /* do not support TIM_3_3_00 and TIM_3_2_00 anymore */ | |
| return InvalidTIMVersionError; | |
| } | |
| /* compute platform verification key digest */ | |
| /* after TIM version 3.2.00 all key size is in bit */ | |
| key_word_cnt = ptim->pTBTIM_DS->KeySize / 32; | |
| hash_data_size_in_bytes = (key_word_cnt*2 + 1) * 4; // (crypto_scheme||modulus-or-X||exponent-or-Y) in bytes (*4) | |
| // 1) Pack the crypto_scheme | |
| //crypto_scheme: 0x0000A100 PKCSv1_SHA1_1024RSA | |
| // 0x0000A110 PKCSv1_SHA256_1024RSA | |
| // 0x0000A200 PKCSv1_SHA1_2048RSA | |
| // 0x0000A210 PKCSv1_SHA256_2048RSA | |
| if(ptim->pTBTIM_DS->HashAlgorithmID == SHA256) | |
| data[0] = (key_word_cnt == 64) ? PKCSv1_SHA256_2048RSA : PKCSv1_SHA256_1024RSA; | |
| else // Defaults to 160 | |
| data[0] = (key_word_cnt == 64) ? PKCSv1_SHA1_2048RSA : PKCSv1_SHA1_1024RSA; | |
| // 2) Pack the Modulus and Exponent | |
| for (i=0; i < key_word_cnt; i++) | |
| { | |
| data[i+1] = ptim->pTBTIM_DS->Rsa.RSAModulus[i]; | |
| data[i+key_word_cnt+1] = ptim->pTBTIM_DS->Rsa.RSAPublicExponent[i]; | |
| } | |
| //Key Padding is on by default | |
| hash_data_size_in_bytes = BINDKEYSIZE*4; // MaxKeySize*2+CryptoScheme in Bytes: 129*4 = 516 | |
| /* compute digest */ | |
| for (i = 0; i < DIGEST_WLEN_MAX; i++) { | |
| digest[i] = 0; | |
| } | |
| result = pSFs->pSHAMessageDigest((UINT8_T *)data, hash_data_size_in_bytes, | |
| (UINT8_T *)digest, ptim->pTBTIM_DS->HashAlgorithmID); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| /* allow reprogramming as it is often the case during development */ | |
| if (programmed) { | |
| for (i = 0; i < K_SHA256_SIZE >> 2; i++) { | |
| if (fusedata[i] != digest[i]) { | |
| return FUSE_BurnError; | |
| } | |
| } | |
| return NoError; | |
| } | |
| /* make sure power supply required for fuse programming is enabled */ | |
| result = GEU_EnableFuseBurnPower(); | |
| if (result != NoError) { | |
| return FUSE_FuseBurnPowerNotEnabled; | |
| } | |
| /* go burn the platform key hash */ | |
| result = GEU_SetActiveFuseBlock(K_OEM_FUSEBLOCK); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| result = GEU_SetupOemHashKeyFuseBits(digest, 4 * DIGEST_WLEN_MAX); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| result = GEU_BurnFuseBlock_OemHashKey(pburn_status); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| GEU_UARTLOG("E OEMKeyHash.\n"); | |
| return result; | |
| } | |
| // This function is called from OBM | |
| // Fully Implemented in WTM | |
| // Always returns NoError for GEU | |
| extern UINT_T GEU_LIB_VerifyPlatform(pTIM ptim) | |
| { | |
| UINT_T result; | |
| UINT_T key_word_cnt, hash_data_size_in_bytes; | |
| UINT_T data[BINDKEYSIZE]= {0}; | |
| UINT_T fusedata[DIGEST_WLEN_MAX]; | |
| UINT_T digest[DIGEST_WLEN_MAX]; | |
| UINT_T programmed = 0; | |
| UINT_T i; | |
| pSECURITY_FUNCTIONS pSFs = GetSecurityFunctionsPointer(); | |
| result = GEU_ReadOemHashKeyFuseBits(fusedata, K_SHA256_SIZE); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| for (i = 0; i < K_SHA256_SIZE >> 2; i++) { | |
| if (fusedata[i] != 0) { | |
| programmed = 1; | |
| break; | |
| } | |
| } | |
| if (ptim->pConsTIM->VersionBind.Version < (TIM_3_4_00)) { | |
| /* do not support TIM_3_3_00 and TIM_3_2_00 anymore */ | |
| return InvalidTIMVersionError; | |
| } | |
| /* after TIM version 3.2.00 all key size is in bit */ | |
| key_word_cnt = ptim->pTBTIM_DS->KeySize / 32; | |
| hash_data_size_in_bytes = (key_word_cnt*2 + 1) * 4; // (crypto_scheme||modulus-or-X||exponent-or-Y) in bytes (*4) | |
| // 1) Pack the crypto_scheme | |
| //crypto_scheme: 0x0000A100 PKCSv1_SHA1_1024RSA | |
| // 0x0000A110 PKCSv1_SHA256_1024RSA | |
| // 0x0000A200 PKCSv1_SHA1_2048RSA | |
| // 0x0000A210 PKCSv1_SHA256_2048RSA | |
| if(ptim->pTBTIM_DS->HashAlgorithmID == SHA256) | |
| data[0] = (key_word_cnt == 64) ? PKCSv1_SHA256_2048RSA : PKCSv1_SHA256_1024RSA; | |
| else // Defaults to 160 | |
| data[0] = (key_word_cnt == 64) ? PKCSv1_SHA1_2048RSA : PKCSv1_SHA1_1024RSA; | |
| // 2) Pack the Modulus and Exponent | |
| for (i=0; i < key_word_cnt; i++) | |
| { | |
| data[i+1] = ptim->pTBTIM_DS->Rsa.RSAModulus[i]; | |
| data[i+key_word_cnt+1] = ptim->pTBTIM_DS->Rsa.RSAPublicExponent[i]; | |
| } | |
| //Key Padding is on by default | |
| hash_data_size_in_bytes = BINDKEYSIZE*4; // MaxKeySize*2+CryptoScheme in Bytes: 129*4 = 516 | |
| /* compute digest */ | |
| for (i = 0; i < DIGEST_WLEN_MAX; i++) { | |
| digest[i] = 0; | |
| } | |
| result = pSFs->pSHAMessageDigest((UINT8_T *)data, hash_data_size_in_bytes, | |
| (UINT8_T *)digest, ptim->pTBTIM_DS->HashAlgorithmID); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| /* compare fuses against TIM */ | |
| if (programmed) { | |
| for (i = 0; i < K_SHA256_SIZE >> 2; i++) { | |
| if (fusedata[i] != digest[i]) { | |
| return FUSE_FuseBlockCompareFailed; | |
| } | |
| } | |
| } | |
| return NoError; | |
| } | |
| /** | |
| * program jtag key using data from {key, len} of pTIM | |
| * @parameter key: pointer to key | |
| * @parameter len: key length | |
| * @parameter ptim: pointer to tim | |
| * @parameter: should be NULL | |
| * | |
| * Note: Due to the need of provisioning of non-trusted platform and minimize | |
| * the code size, we have a dummy implementation of this function for | |
| * non-trusted case. | |
| */ | |
| // FixME: set algorithm id using info form TIM | |
| extern UINT_T GEU_LIB_BindJTAGKey(pTIM ptim, void* parameter) | |
| { | |
| UINT_T result; | |
| UINT_T key_word_cnt, hash_data_size_in_bytes; | |
| //pKEY_MOD_3_2_0 pTimKey; | |
| pKEY_MOD_3_4_0 pkey; | |
| UINT_T data[BINDKEYSIZE] = {0}; | |
| UINT_T fusedata[DIGEST_WLEN_MAX]; | |
| UINT_T digest[DIGEST_WLEN_MAX]; | |
| struct GEU_FuseBurnStatus burn_status; | |
| struct GEU_FuseBurnStatus* pburn_status = &burn_status; | |
| UINT_T programmed = 0; | |
| UINT_T i; | |
| UINT_T HashAlgorithmID; | |
| UINT_T EncryptAlgorithmID; | |
| UINT_T KeySize; | |
| pSECURITY_FUNCTIONS pSFs = GetSecurityFunctionsPointer(); | |
| GEU_UARTLOG("S JTAGKeyHash...\n"); | |
| pkey = FindKeyInTIM(ptim, JTAGIDENTIFIER); | |
| if ( pkey == NULL ) | |
| { | |
| return NoError; | |
| } | |
| result = GEU_ReadOemJtagHashKeyFuseBits(fusedata, K_SHA256_SIZE); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| for (i = 0; i < K_SHA256_SIZE >> 2; i++) { | |
| if (fusedata[i] != 0) { | |
| programmed = 1; | |
| break; | |
| } | |
| } | |
| if (ptim->pConsTIM->VersionBind.Version < (TIM_3_4_00)) { | |
| return InvalidTIMVersionError; | |
| } | |
| // /* compute jtag enable key digest */ | |
| // if (ptim->pConsTIM->VersionBind.Version < (TIM_3_3_00)) { | |
| // /* before and with TIM version 3.2.00 all key size is in byte */ | |
| // key_word_cnt = ptim->pTBTIM_DS->KeySize/4; | |
| // } | |
| // else { | |
| // /* after TIM version 3.2.00 all key size is in bit */ | |
| // key_word_cnt = ptim->pTBTIM_DS->KeySize / 32; | |
| // } | |
| HashAlgorithmID = pkey->HashAlgorithmID; | |
| KeySize = pkey->KeySize; | |
| EncryptAlgorithmID = pkey->EncryptAlgorithmID; | |
| key_word_cnt = KeySize/32; | |
| #if EMEI | |
| hash_data_size_in_bytes = key_word_cnt *2*4; // (exponent-or-X||modulus-or-Y) in bytes (*4) | |
| /* pack the Exponent */ | |
| for (i = 0; i < key_word_cnt; i++) { | |
| data[i] = ptim->pTBTIM_DS->Rsa.RSAPublicExponent[i]; | |
| } | |
| /* pack the Modulus */ | |
| for (i = 0; i < key_word_cnt; i++) { | |
| data[i + key_word_cnt] = ptim->pTBTIM_DS->Rsa.RSAModulus[i]; | |
| } | |
| #else //HELN | |
| hash_data_size_in_bytes = (key_word_cnt*2 + 1) * 4; // (crypto_scheme||modulus-or-X||exponent-or-Y) in bytes (*4) | |
| //for platforms other than EMEI, like HELN use 3_4 TIM and beyond | |
| if (EncryptAlgorithmID == PKCS1_v1_5_Ippcp) | |
| { | |
| // 1) Pack the crypto_scheme | |
| //crypto_scheme: 0x0000A100 PKCSv1_SHA1_1024RSA | |
| // 0x0000A110 PKCSv1_SHA256_1024RSA | |
| // 0x0000A200 PKCSv1_SHA1_2048RSA | |
| // 0x0000A210 PKCSv1_SHA256_2048RSA | |
| if(ptim->pTBTIM_DS->HashAlgorithmID == SHA256) | |
| data[0] = (key_word_cnt == 64) ? PKCSv1_SHA256_2048RSA : PKCSv1_SHA256_1024RSA; | |
| else // Defaults to 160 | |
| data[0] = (key_word_cnt == 64) ? PKCSv1_SHA1_2048RSA : PKCSv1_SHA1_1024RSA; | |
| // 2) Pack the Modulus and Exponent | |
| for (i=0; i < key_word_cnt; i++) | |
| { | |
| data[i+1] = ptim->pTBTIM_DS->Rsa.RSAModulus[i]; | |
| data[i+key_word_cnt+1] = ptim->pTBTIM_DS->Rsa.RSAPublicExponent[i]; | |
| } | |
| } | |
| else | |
| return InvalidDSAError; | |
| #endif | |
| //Key Padding is on by default | |
| hash_data_size_in_bytes = BINDKEYSIZE*4; // MaxKeySize*2+CryptoScheme in Bytes: 129*4 = 516 | |
| for (i = 0; i < DIGEST_WLEN_MAX; i++) { | |
| digest[i] = 0; | |
| } | |
| result = pSFs->pSHAMessageDigest((UINT8_T *)data, hash_data_size_in_bytes, | |
| (UINT8_T *)digest, HashAlgorithmID); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| /* allow reprogramming as it is often the case during development */ | |
| if (programmed) { | |
| for (i = 0; i < K_SHA256_SIZE >> 2; i++) { | |
| if (fusedata[i] != digest[i]) { | |
| return FUSE_FuseReprogrammingError; | |
| } | |
| } | |
| return NoError; | |
| } | |
| /* make sure power supply required for fuse programming is enabled */ | |
| result = GEU_EnableFuseBurnPower(); | |
| if (result != NoError) { | |
| return FUSE_FuseBurnPowerNotEnabled; | |
| } | |
| // go burn the platform key hash | |
| result = GEU_SetActiveFuseBlock(K_JTAG_FUSEBLOCK); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| result = GEU_SetupOemJtagHashKeyFuseBits(digest, 4 * DIGEST_WLEN_MAX); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| result = GEU_BurnFuseBlock_OemJtagHashKey(pburn_status); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| GEU_UARTLOG("E JTAGKeyHash.\n"); | |
| GEU_UARTLOG("S JTAGKeyHashECC...\n"); | |
| result = GEU_BurnECC(pburn_status); | |
| GEU_UARTLOG("E JTAGKeyHashECC.\n"); | |
| return result; | |
| } | |
| /** | |
| * Not Implemented for GEU | |
| * @return: always NoError | |
| */ | |
| extern UINT_T GEU_LIB_VerifyJTAGKey(pTIM ptim) | |
| { | |
| UINT_T result; | |
| UINT_T key_word_cnt, hash_data_size_in_bytes; | |
| //pKEY_MOD_3_2_0 pTimKey; | |
| pKEY_MOD_3_4_0 pkey; | |
| UINT_T data[BINDKEYSIZE] = {0}; | |
| UINT_T fusedata[DIGEST_WLEN_MAX]; | |
| UINT_T digest[DIGEST_WLEN_MAX]; | |
| UINT_T programmed = 0; | |
| UINT_T i; | |
| UINT_T HashAlgorithmID; | |
| UINT_T EncryptAlgorithmID; | |
| UINT_T KeySize; | |
| pSECURITY_FUNCTIONS pSFs = GetSecurityFunctionsPointer(); | |
| pkey = FindKeyInTIM(ptim, JTAGIDENTIFIER); | |
| if ( pkey == NULL ) | |
| { | |
| return NoError; | |
| } | |
| result = GEU_ReadOemJtagHashKeyFuseBits(fusedata, K_SHA256_SIZE); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| for (i = 0; i < K_SHA256_SIZE >> 2; i++) { | |
| if (fusedata[i] != 0) { | |
| programmed = 1; | |
| break; | |
| } | |
| } | |
| if (ptim->pConsTIM->VersionBind.Version < (TIM_3_4_00)) { | |
| return InvalidTIMVersionError; | |
| } | |
| HashAlgorithmID = pkey->HashAlgorithmID; | |
| KeySize = pkey->KeySize; | |
| EncryptAlgorithmID = pkey->EncryptAlgorithmID; | |
| key_word_cnt = KeySize/32; | |
| #if EMEI | |
| hash_data_size_in_bytes = key_word_cnt *2*4; // (exponent-or-X||modulus-or-Y) in bytes (*4) | |
| /* pack the Exponent */ | |
| for (i = 0; i < key_word_cnt; i++) { | |
| data[i] = ptim->pTBTIM_DS->Rsa.RSAPublicExponent[i]; | |
| } | |
| /* pack the Modulus */ | |
| for (i = 0; i < key_word_cnt; i++) { | |
| data[i + key_word_cnt] = ptim->pTBTIM_DS->Rsa.RSAModulus[i]; | |
| } | |
| #else //HELN | |
| hash_data_size_in_bytes = (key_word_cnt*2 + 1) * 4; // (crypto_scheme||modulus-or-X||exponent-or-Y) in bytes (*4) | |
| //for platforms other than EMEI, like HELN use 3_4 TIM and beyond | |
| if (EncryptAlgorithmID == PKCS1_v1_5_Ippcp) | |
| { | |
| // 1) Pack the crypto_scheme | |
| //crypto_scheme: 0x0000A100 PKCSv1_SHA1_1024RSA | |
| // 0x0000A110 PKCSv1_SHA256_1024RSA | |
| // 0x0000A200 PKCSv1_SHA1_2048RSA | |
| // 0x0000A210 PKCSv1_SHA256_2048RSA | |
| if(ptim->pTBTIM_DS->HashAlgorithmID == SHA256) | |
| data[0] = (key_word_cnt == 64) ? PKCSv1_SHA256_2048RSA : PKCSv1_SHA256_1024RSA; | |
| else // Defaults to 160 | |
| data[0] = (key_word_cnt == 64) ? PKCSv1_SHA1_2048RSA : PKCSv1_SHA1_1024RSA; | |
| // 2) Pack the Modulus and Exponent | |
| for (i=0; i < key_word_cnt; i++) | |
| { | |
| data[i+1] = ptim->pTBTIM_DS->Rsa.RSAModulus[i]; | |
| data[i+key_word_cnt+1] = ptim->pTBTIM_DS->Rsa.RSAPublicExponent[i]; | |
| } | |
| } | |
| else | |
| return InvalidDSAError; | |
| #endif | |
| //Key Padding is on by default | |
| hash_data_size_in_bytes = BINDKEYSIZE*4; // MaxKeySize*2+CryptoScheme in Bytes: 129*4 = 516 | |
| for (i = 0; i < DIGEST_WLEN_MAX; i++) { | |
| digest[i] = 0; | |
| } | |
| result = pSFs->pSHAMessageDigest((UINT8_T *)data, hash_data_size_in_bytes, | |
| (UINT8_T *)digest, HashAlgorithmID); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| /* compare fuses against TIM */ | |
| if (programmed) { | |
| for (i = 0; i < K_SHA256_SIZE >> 2; i++) { | |
| if (fusedata[i] != digest[i]) { | |
| return FUSE_FuseBlockCompareFailed; | |
| } | |
| } | |
| } | |
| return NoError; | |
| } | |
| /** | |
| * perform platform auto-configuration | |
| * @parameter ptim: pointer to TIM | |
| * @parameter parameter: NULL | |
| */ | |
| extern UINT_T GEU_LIB_AutoConfigPlatform(pTIM ptim, void* parameter) | |
| { | |
| UINT_T result = NoError; | |
| fuse_conf_spec_t fuse_conf; | |
| fuse_conf = GetFuseConfSpec(NULL); | |
| /* make sure power supply required for fuse programming is enabled */ | |
| result = GEU_EnableFuseBurnPower(); | |
| if (result != NoError) { | |
| return FUSE_FuseBurnPowerNotEnabled; | |
| } | |
| GEU_UARTLOG("S USBIDSecurityConfig...\n"); | |
| //GEU_UARTLOG("S ApCpECC...\n"); | |
| // ApCP in block 0 | |
| //reset_blk0_active_status(); | |
| // Security Config/USB ID in block 7 | |
| reset_blk7_active_status(); | |
| /* | |
| * configure USB ID, Security Config and their ECCs | |
| */ | |
| result = GEU_LIB_ProgramSecurityConfig(NULL, ptim); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| result = GEU_SetupSecurityConfigUsbIdEccFuseBits(); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| result = burn_security_usb_ecc(1); | |
| if ((result != NoError) && (result != FUSE_FuseBlockNotActive) && (result != FUSE_NoBurnRequest)) { | |
| return result; | |
| } | |
| return result; | |
| } | |
| /** | |
| * program security config fuse bits | |
| */ | |
| UINT_T GEU_LIB_ProgramSecurityConfig(void* parameter, pTIM ptim) | |
| { | |
| UINT_T result, flash_number; | |
| UINT_T security_config[1]; | |
| fuse_conf_spec_t fuse_conf; | |
| fuse_conf = GetFuseConfSpec(NULL); | |
| result = set_blk7_active(); | |
| result = GEU_ReadSecurityConfigFuseBits(&security_config[0], K_SECURITY_CONFIG_FUSE_SIZE); | |
| if (result != NoError) { | |
| return result; | |
| } | |
| if (ptim != NULL) { | |
| flash_number = (UINT8_T)((ptim->pConsTIM->FlashInfo.BootFlashSign) & 0x3F); | |
| fuse_conf.security_config[0] |= flash_number << FLASHNUMSHIFT; | |
| } | |
| if (ptim != NULL) { | |
| if (ptim->pConsTIM->VersionBind.Trusted) | |
| fuse_conf.security_config[0] |= (OPMODETRUSTED); // Trusted | |
| else | |
| fuse_conf.security_config[0] |= (OPMODENONTRUSTED); // Non-Trusted | |
| } | |
| if ( security_config[0]!= 0 && security_config[0] != fuse_conf.security_config[0] ) { | |
| return FUSE_FuseBlockFieldFull; | |
| } | |
| result = GEU_SetupSecurityConfigFuseBits(&fuse_conf.security_config[0], fuse_conf.security_config_bit_cnt/8); | |
| return result; | |
| } | |
| UINT_T GEU_ProgramMiscConfig(pTIM pTIM_h) | |
| { | |
| (VOID)pTIM_h; | |
| return NoError; | |
| } |