| b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | /****************************************************************************
|
| 2 | *
|
| 3 | * (C)Copyright 2015 Marvell. All Rights Reserved.
|
| 4 | *
|
| 5 | * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL.
|
| 6 | * The copyright notice above does not evidence any actual or intended
|
| 7 | * publication of such source code. This Module contains Proprietary
|
| 8 | * Information of Marvell and should be treated as Confidential. The
|
| 9 | * information in this file is provided for the exclusive use of the
|
| 10 | * licensees of Marvell. Such users have the right to use, modify, and
|
| 11 | * incorporate this code into products for purposes authorized by the
|
| 12 | * license agreement provided they include this notice and the associated
|
| 13 | * copyright notice with any such product.
|
| 14 | *
|
| 15 | * The information in this file is provided "AS IS" without warranty.
|
| 16 | *
|
| 17 | ***************************************************************************/
|
| 18 |
|
| 19 | #include "GEU_Provisioning.h"
|
| 20 | #include "Security.h"
|
| 21 | #include "Errors.h"
|
| 22 | #include "platform_geu_fuse_internal.h"
|
| 23 | #include "geu_interface.h"
|
| 24 | #include "GEU.h"
|
| 25 | #include "ProtocolManager.h"
|
| 26 | #include "timer.h"
|
| 27 | #include "nza3_fuse_config.h"
|
| 28 |
|
| 29 | /////////////////// Internal Functions ///////////////////
|
| 30 |
|
| 31 | /**
|
| 32 | * get fuse configuration spec
|
| 33 | */
|
| 34 | // FixME: use generic fuse_conf_spec
|
| 35 | static fuse_conf_spec_t GetFuseConfSpec(void* parameter)
|
| 36 | {
|
| 37 | return nza3_fuse_conf_spec;
|
| 38 | }
|
| 39 |
|
| 40 | static UINT_T burn_security_usb_ecc(UINT_T prgecc)
|
| 41 | {
|
| 42 | UINT_T result;
|
| 43 | struct GEU_FuseBurnStatus burn_status;
|
| 44 | struct GEU_FuseBurnStatus* pburn_status = &burn_status;
|
| 45 |
|
| 46 | result = GEU_BurnFuseBlock_SecurityUSBIDECC(pburn_status);
|
| 47 |
|
| 48 | return result;
|
| 49 | }
|
| 50 |
|
| 51 |
|
| 52 | /**
|
| 53 | * set block seven non-active
|
| 54 | *
|
| 55 | */
|
| 56 | static void reset_blk7_active_status(void)
|
| 57 | {
|
| 58 | s_blk_seven_active = 0;
|
| 59 | }
|
| 60 | /**
|
| 61 | * set block seven active
|
| 62 | *
|
| 63 | */
|
| 64 | static UINT_T set_blk7_active(void)
|
| 65 | {
|
| 66 | UINT_T result;
|
| 67 | if (s_blk_seven_active == 0) {
|
| 68 | result = GEU_SetActiveFuseBlock(K_USBID_FUSEBLOCK);
|
| 69 | if (result != NoError) {
|
| 70 | return result;
|
| 71 | }
|
| 72 | s_blk_seven_active = 1;
|
| 73 | }
|
| 74 | return NoError;
|
| 75 | }
|
| 76 |
|
| 77 | /**
|
| 78 | * Attention: this function must kept consistent with what is done by Boot ROM,
|
| 79 | * for exmaple, the pack order for public key
|
| 80 | * perform platform binding
|
| 81 | * @parameter ptim: pointer to TIM
|
| 82 | * @parameter parameter: should be NULL
|
| 83 | * @return: FUSE_FuseBurnPowerNotEnabled if UsbPhy band gap is not enabled
|
| 84 | * other error code otherwise
|
| 85 | *
|
| 86 | * Note: Due to the need of provisioning of non-trusted platform and minimize
|
| 87 | * the code size, we have a dummy implementation of this function for
|
| 88 | * non-trusted case.
|
| 89 | */
|
| 90 | // FixME: set algorithm id using info form TIM
|
| 91 | extern UINT_T GEU_LIB_BindPlatform(pTIM ptim, void* parameter)
|
| 92 | {
|
| 93 | UINT_T result = NoError;
|
| 94 | UINT_T key_word_cnt, hash_data_size_in_bytes;
|
| 95 | UINT_T data[BINDKEYSIZE] = {0};
|
| 96 | UINT_T fusedata[DIGEST_WLEN_MAX];
|
| 97 | UINT_T digest[DIGEST_WLEN_MAX];
|
| 98 | struct GEU_FuseBurnStatus burn_status;
|
| 99 | struct GEU_FuseBurnStatus* pburn_status = &burn_status;
|
| 100 | UINT_T programmed = 0;
|
| 101 | UINT_T i;
|
| 102 | pSECURITY_FUNCTIONS pSFs = GetSecurityFunctionsPointer();
|
| 103 |
|
| 104 | if (parameter != NULL) {
|
| 105 | s_uart_logger = (logger) parameter;
|
| 106 | }
|
| 107 |
|
| 108 |
|
| 109 | GEU_UARTLOG("S OEMKeyHash...\n");
|
| 110 | result = GEU_ReadOemHashKeyFuseBits(fusedata, K_SHA256_SIZE);
|
| 111 | if (result != NoError) {
|
| 112 | return result;
|
| 113 | }
|
| 114 | for (i = 0; i < K_SHA256_SIZE >> 2; i++) {
|
| 115 | if (fusedata[i] != 0) {
|
| 116 | programmed = 1;
|
| 117 | break;
|
| 118 | }
|
| 119 | }
|
| 120 |
|
| 121 | if (ptim->pConsTIM->VersionBind.Version < (TIM_3_4_00)) {
|
| 122 | /* do not support TIM_3_3_00 and TIM_3_2_00 anymore */
|
| 123 | return InvalidTIMVersionError;
|
| 124 | }
|
| 125 |
|
| 126 | /* compute platform verification key digest */
|
| 127 | /* after TIM version 3.2.00 all key size is in bit */
|
| 128 | key_word_cnt = ptim->pTBTIM_DS->KeySize / 32;
|
| 129 |
|
| 130 | hash_data_size_in_bytes = (key_word_cnt*2 + 1) * 4; // (crypto_scheme||modulus-or-X||exponent-or-Y) in bytes (*4)
|
| 131 |
|
| 132 |
|
| 133 |
|
| 134 | // 1) Pack the crypto_scheme
|
| 135 | //crypto_scheme: 0x0000A100 PKCSv1_SHA1_1024RSA
|
| 136 | // 0x0000A110 PKCSv1_SHA256_1024RSA
|
| 137 | // 0x0000A200 PKCSv1_SHA1_2048RSA
|
| 138 | // 0x0000A210 PKCSv1_SHA256_2048RSA
|
| 139 | if(ptim->pTBTIM_DS->HashAlgorithmID == SHA256)
|
| 140 | data[0] = (key_word_cnt == 64) ? PKCSv1_SHA256_2048RSA : PKCSv1_SHA256_1024RSA;
|
| 141 | else // Defaults to 160
|
| 142 | data[0] = (key_word_cnt == 64) ? PKCSv1_SHA1_2048RSA : PKCSv1_SHA1_1024RSA;
|
| 143 |
|
| 144 | // 2) Pack the Modulus and Exponent
|
| 145 | for (i=0; i < key_word_cnt; i++)
|
| 146 | {
|
| 147 | data[i+1] = ptim->pTBTIM_DS->Rsa.RSAModulus[i];
|
| 148 | data[i+key_word_cnt+1] = ptim->pTBTIM_DS->Rsa.RSAPublicExponent[i];
|
| 149 | }
|
| 150 |
|
| 151 |
|
| 152 | //Key Padding is on by default
|
| 153 | hash_data_size_in_bytes = BINDKEYSIZE*4; // MaxKeySize*2+CryptoScheme in Bytes: 129*4 = 516
|
| 154 |
|
| 155 | /* compute digest */
|
| 156 | for (i = 0; i < DIGEST_WLEN_MAX; i++) {
|
| 157 | digest[i] = 0;
|
| 158 | }
|
| 159 | result = pSFs->pSHAMessageDigest((UINT8_T *)data, hash_data_size_in_bytes,
|
| 160 | (UINT8_T *)digest, ptim->pTBTIM_DS->HashAlgorithmID);
|
| 161 | if (result != NoError) {
|
| 162 | return result;
|
| 163 | }
|
| 164 |
|
| 165 | /* allow reprogramming as it is often the case during development */
|
| 166 | if (programmed) {
|
| 167 | for (i = 0; i < K_SHA256_SIZE >> 2; i++) {
|
| 168 | if (fusedata[i] != digest[i]) {
|
| 169 | return FUSE_BurnError;
|
| 170 | }
|
| 171 | }
|
| 172 | return NoError;
|
| 173 | }
|
| 174 |
|
| 175 |
|
| 176 | /* make sure power supply required for fuse programming is enabled */
|
| 177 | result = GEU_EnableFuseBurnPower();
|
| 178 | if (result != NoError) {
|
| 179 | return FUSE_FuseBurnPowerNotEnabled;
|
| 180 | }
|
| 181 |
|
| 182 | /* go burn the platform key hash */
|
| 183 | result = GEU_SetActiveFuseBlock(K_OEM_FUSEBLOCK);
|
| 184 | if (result != NoError) {
|
| 185 | return result;
|
| 186 | }
|
| 187 | result = GEU_SetupOemHashKeyFuseBits(digest, 4 * DIGEST_WLEN_MAX);
|
| 188 | if (result != NoError) {
|
| 189 | return result;
|
| 190 | }
|
| 191 | result = GEU_BurnFuseBlock_OemHashKey(pburn_status);
|
| 192 | if (result != NoError) {
|
| 193 | return result;
|
| 194 | }
|
| 195 |
|
| 196 | GEU_UARTLOG("E OEMKeyHash.\n");
|
| 197 |
|
| 198 | return result;
|
| 199 | }
|
| 200 |
|
| 201 |
|
| 202 | // This function is called from OBM
|
| 203 | // Fully Implemented in WTM
|
| 204 | // Always returns NoError for GEU
|
| 205 | extern UINT_T GEU_LIB_VerifyPlatform(pTIM ptim)
|
| 206 | {
|
| 207 | UINT_T result;
|
| 208 | UINT_T key_word_cnt, hash_data_size_in_bytes;
|
| 209 | UINT_T data[BINDKEYSIZE]= {0};
|
| 210 | UINT_T fusedata[DIGEST_WLEN_MAX];
|
| 211 | UINT_T digest[DIGEST_WLEN_MAX];
|
| 212 | UINT_T programmed = 0;
|
| 213 | UINT_T i;
|
| 214 | pSECURITY_FUNCTIONS pSFs = GetSecurityFunctionsPointer();
|
| 215 |
|
| 216 | result = GEU_ReadOemHashKeyFuseBits(fusedata, K_SHA256_SIZE);
|
| 217 | if (result != NoError) {
|
| 218 | return result;
|
| 219 | }
|
| 220 | for (i = 0; i < K_SHA256_SIZE >> 2; i++) {
|
| 221 | if (fusedata[i] != 0) {
|
| 222 | programmed = 1;
|
| 223 | break;
|
| 224 | }
|
| 225 | }
|
| 226 |
|
| 227 | if (ptim->pConsTIM->VersionBind.Version < (TIM_3_4_00)) {
|
| 228 | /* do not support TIM_3_3_00 and TIM_3_2_00 anymore */
|
| 229 | return InvalidTIMVersionError;
|
| 230 | }
|
| 231 |
|
| 232 | /* after TIM version 3.2.00 all key size is in bit */
|
| 233 | key_word_cnt = ptim->pTBTIM_DS->KeySize / 32;
|
| 234 |
|
| 235 | hash_data_size_in_bytes = (key_word_cnt*2 + 1) * 4; // (crypto_scheme||modulus-or-X||exponent-or-Y) in bytes (*4)
|
| 236 |
|
| 237 |
|
| 238 | // 1) Pack the crypto_scheme
|
| 239 | //crypto_scheme: 0x0000A100 PKCSv1_SHA1_1024RSA
|
| 240 | // 0x0000A110 PKCSv1_SHA256_1024RSA
|
| 241 | // 0x0000A200 PKCSv1_SHA1_2048RSA
|
| 242 | // 0x0000A210 PKCSv1_SHA256_2048RSA
|
| 243 | if(ptim->pTBTIM_DS->HashAlgorithmID == SHA256)
|
| 244 | data[0] = (key_word_cnt == 64) ? PKCSv1_SHA256_2048RSA : PKCSv1_SHA256_1024RSA;
|
| 245 | else // Defaults to 160
|
| 246 | data[0] = (key_word_cnt == 64) ? PKCSv1_SHA1_2048RSA : PKCSv1_SHA1_1024RSA;
|
| 247 |
|
| 248 | // 2) Pack the Modulus and Exponent
|
| 249 | for (i=0; i < key_word_cnt; i++)
|
| 250 | {
|
| 251 | data[i+1] = ptim->pTBTIM_DS->Rsa.RSAModulus[i];
|
| 252 | data[i+key_word_cnt+1] = ptim->pTBTIM_DS->Rsa.RSAPublicExponent[i];
|
| 253 | }
|
| 254 |
|
| 255 | //Key Padding is on by default
|
| 256 | hash_data_size_in_bytes = BINDKEYSIZE*4; // MaxKeySize*2+CryptoScheme in Bytes: 129*4 = 516
|
| 257 |
|
| 258 | /* compute digest */
|
| 259 | for (i = 0; i < DIGEST_WLEN_MAX; i++) {
|
| 260 | digest[i] = 0;
|
| 261 | }
|
| 262 | result = pSFs->pSHAMessageDigest((UINT8_T *)data, hash_data_size_in_bytes,
|
| 263 | (UINT8_T *)digest, ptim->pTBTIM_DS->HashAlgorithmID);
|
| 264 | if (result != NoError) {
|
| 265 | return result;
|
| 266 | }
|
| 267 |
|
| 268 | /* compare fuses against TIM */
|
| 269 | if (programmed) {
|
| 270 | for (i = 0; i < K_SHA256_SIZE >> 2; i++) {
|
| 271 | if (fusedata[i] != digest[i]) {
|
| 272 | return FUSE_FuseBlockCompareFailed;
|
| 273 | }
|
| 274 | }
|
| 275 | }
|
| 276 | return NoError;
|
| 277 | }
|
| 278 |
|
| 279 |
|
| 280 | /**
|
| 281 | * program jtag key using data from {key, len} of pTIM
|
| 282 | * @parameter key: pointer to key
|
| 283 | * @parameter len: key length
|
| 284 | * @parameter ptim: pointer to tim
|
| 285 | * @parameter: should be NULL
|
| 286 | *
|
| 287 | * Note: Due to the need of provisioning of non-trusted platform and minimize
|
| 288 | * the code size, we have a dummy implementation of this function for
|
| 289 | * non-trusted case.
|
| 290 | */
|
| 291 | // FixME: set algorithm id using info form TIM
|
| 292 | extern UINT_T GEU_LIB_BindJTAGKey(pTIM ptim, void* parameter)
|
| 293 | {
|
| 294 | UINT_T result;
|
| 295 | UINT_T key_word_cnt, hash_data_size_in_bytes;
|
| 296 | //pKEY_MOD_3_2_0 pTimKey;
|
| 297 | pKEY_MOD_3_4_0 pkey;
|
| 298 | UINT_T data[BINDKEYSIZE] = {0};
|
| 299 | UINT_T fusedata[DIGEST_WLEN_MAX];
|
| 300 | UINT_T digest[DIGEST_WLEN_MAX];
|
| 301 | struct GEU_FuseBurnStatus burn_status;
|
| 302 | struct GEU_FuseBurnStatus* pburn_status = &burn_status;
|
| 303 | UINT_T programmed = 0;
|
| 304 | UINT_T i;
|
| 305 | UINT_T HashAlgorithmID;
|
| 306 | UINT_T EncryptAlgorithmID;
|
| 307 | UINT_T KeySize;
|
| 308 | pSECURITY_FUNCTIONS pSFs = GetSecurityFunctionsPointer();
|
| 309 |
|
| 310 | GEU_UARTLOG("S JTAGKeyHash...\n");
|
| 311 | pkey = FindKeyInTIM(ptim, JTAGIDENTIFIER);
|
| 312 | if ( pkey == NULL )
|
| 313 | {
|
| 314 | return NoError;
|
| 315 | }
|
| 316 |
|
| 317 | result = GEU_ReadOemJtagHashKeyFuseBits(fusedata, K_SHA256_SIZE);
|
| 318 | if (result != NoError) {
|
| 319 | return result;
|
| 320 | }
|
| 321 | for (i = 0; i < K_SHA256_SIZE >> 2; i++) {
|
| 322 | if (fusedata[i] != 0) {
|
| 323 | programmed = 1;
|
| 324 | break;
|
| 325 | }
|
| 326 | }
|
| 327 |
|
| 328 | if (ptim->pConsTIM->VersionBind.Version < (TIM_3_4_00)) {
|
| 329 | return InvalidTIMVersionError;
|
| 330 | }
|
| 331 |
|
| 332 | // /* compute jtag enable key digest */
|
| 333 | // if (ptim->pConsTIM->VersionBind.Version < (TIM_3_3_00)) {
|
| 334 | // /* before and with TIM version 3.2.00 all key size is in byte */
|
| 335 | // key_word_cnt = ptim->pTBTIM_DS->KeySize/4;
|
| 336 | // }
|
| 337 | // else {
|
| 338 | // /* after TIM version 3.2.00 all key size is in bit */
|
| 339 | // key_word_cnt = ptim->pTBTIM_DS->KeySize / 32;
|
| 340 | // }
|
| 341 |
|
| 342 | HashAlgorithmID = pkey->HashAlgorithmID;
|
| 343 | KeySize = pkey->KeySize;
|
| 344 | EncryptAlgorithmID = pkey->EncryptAlgorithmID;
|
| 345 | key_word_cnt = KeySize/32;
|
| 346 |
|
| 347 | #if EMEI
|
| 348 | hash_data_size_in_bytes = key_word_cnt *2*4; // (exponent-or-X||modulus-or-Y) in bytes (*4)
|
| 349 | /* pack the Exponent */
|
| 350 | for (i = 0; i < key_word_cnt; i++) {
|
| 351 | data[i] = ptim->pTBTIM_DS->Rsa.RSAPublicExponent[i];
|
| 352 | }
|
| 353 | /* pack the Modulus */
|
| 354 | for (i = 0; i < key_word_cnt; i++) {
|
| 355 | data[i + key_word_cnt] = ptim->pTBTIM_DS->Rsa.RSAModulus[i];
|
| 356 | }
|
| 357 |
|
| 358 | #else //HELN
|
| 359 | hash_data_size_in_bytes = (key_word_cnt*2 + 1) * 4; // (crypto_scheme||modulus-or-X||exponent-or-Y) in bytes (*4)
|
| 360 |
|
| 361 | //for platforms other than EMEI, like HELN use 3_4 TIM and beyond
|
| 362 | if (EncryptAlgorithmID == PKCS1_v1_5_Ippcp)
|
| 363 | {
|
| 364 | // 1) Pack the crypto_scheme
|
| 365 | //crypto_scheme: 0x0000A100 PKCSv1_SHA1_1024RSA
|
| 366 | // 0x0000A110 PKCSv1_SHA256_1024RSA
|
| 367 | // 0x0000A200 PKCSv1_SHA1_2048RSA
|
| 368 | // 0x0000A210 PKCSv1_SHA256_2048RSA
|
| 369 | if(ptim->pTBTIM_DS->HashAlgorithmID == SHA256)
|
| 370 | data[0] = (key_word_cnt == 64) ? PKCSv1_SHA256_2048RSA : PKCSv1_SHA256_1024RSA;
|
| 371 | else // Defaults to 160
|
| 372 | data[0] = (key_word_cnt == 64) ? PKCSv1_SHA1_2048RSA : PKCSv1_SHA1_1024RSA;
|
| 373 |
|
| 374 | // 2) Pack the Modulus and Exponent
|
| 375 | for (i=0; i < key_word_cnt; i++)
|
| 376 | {
|
| 377 | data[i+1] = ptim->pTBTIM_DS->Rsa.RSAModulus[i];
|
| 378 | data[i+key_word_cnt+1] = ptim->pTBTIM_DS->Rsa.RSAPublicExponent[i];
|
| 379 | }
|
| 380 | }
|
| 381 | else
|
| 382 | return InvalidDSAError;
|
| 383 | #endif
|
| 384 |
|
| 385 | //Key Padding is on by default
|
| 386 | hash_data_size_in_bytes = BINDKEYSIZE*4; // MaxKeySize*2+CryptoScheme in Bytes: 129*4 = 516
|
| 387 |
|
| 388 | for (i = 0; i < DIGEST_WLEN_MAX; i++) {
|
| 389 | digest[i] = 0;
|
| 390 | }
|
| 391 | result = pSFs->pSHAMessageDigest((UINT8_T *)data, hash_data_size_in_bytes,
|
| 392 | (UINT8_T *)digest, HashAlgorithmID);
|
| 393 | if (result != NoError) {
|
| 394 | return result;
|
| 395 | }
|
| 396 |
|
| 397 | /* allow reprogramming as it is often the case during development */
|
| 398 | if (programmed) {
|
| 399 | for (i = 0; i < K_SHA256_SIZE >> 2; i++) {
|
| 400 | if (fusedata[i] != digest[i]) {
|
| 401 | return FUSE_FuseReprogrammingError;
|
| 402 | }
|
| 403 | }
|
| 404 | return NoError;
|
| 405 | }
|
| 406 |
|
| 407 | /* make sure power supply required for fuse programming is enabled */
|
| 408 | result = GEU_EnableFuseBurnPower();
|
| 409 | if (result != NoError) {
|
| 410 | return FUSE_FuseBurnPowerNotEnabled;
|
| 411 | }
|
| 412 | // go burn the platform key hash
|
| 413 | result = GEU_SetActiveFuseBlock(K_JTAG_FUSEBLOCK);
|
| 414 | if (result != NoError) {
|
| 415 | return result;
|
| 416 | }
|
| 417 | result = GEU_SetupOemJtagHashKeyFuseBits(digest, 4 * DIGEST_WLEN_MAX);
|
| 418 | if (result != NoError) {
|
| 419 | return result;
|
| 420 | }
|
| 421 | result = GEU_BurnFuseBlock_OemJtagHashKey(pburn_status);
|
| 422 | if (result != NoError) {
|
| 423 | return result;
|
| 424 | }
|
| 425 |
|
| 426 | GEU_UARTLOG("E JTAGKeyHash.\n");
|
| 427 | GEU_UARTLOG("S JTAGKeyHashECC...\n");
|
| 428 | result = GEU_BurnECC(pburn_status);
|
| 429 | GEU_UARTLOG("E JTAGKeyHashECC.\n");
|
| 430 |
|
| 431 | return result;
|
| 432 | }
|
| 433 |
|
| 434 |
|
| 435 | /**
|
| 436 | * Not Implemented for GEU
|
| 437 | * @return: always NoError
|
| 438 | */
|
| 439 | extern UINT_T GEU_LIB_VerifyJTAGKey(pTIM ptim)
|
| 440 | {
|
| 441 |
|
| 442 | UINT_T result;
|
| 443 | UINT_T key_word_cnt, hash_data_size_in_bytes;
|
| 444 | //pKEY_MOD_3_2_0 pTimKey;
|
| 445 | pKEY_MOD_3_4_0 pkey;
|
| 446 | UINT_T data[BINDKEYSIZE] = {0};
|
| 447 | UINT_T fusedata[DIGEST_WLEN_MAX];
|
| 448 | UINT_T digest[DIGEST_WLEN_MAX];
|
| 449 | UINT_T programmed = 0;
|
| 450 | UINT_T i;
|
| 451 | UINT_T HashAlgorithmID;
|
| 452 | UINT_T EncryptAlgorithmID;
|
| 453 | UINT_T KeySize;
|
| 454 | pSECURITY_FUNCTIONS pSFs = GetSecurityFunctionsPointer();
|
| 455 |
|
| 456 | pkey = FindKeyInTIM(ptim, JTAGIDENTIFIER);
|
| 457 | if ( pkey == NULL )
|
| 458 | {
|
| 459 | return NoError;
|
| 460 | }
|
| 461 |
|
| 462 | result = GEU_ReadOemJtagHashKeyFuseBits(fusedata, K_SHA256_SIZE);
|
| 463 | if (result != NoError) {
|
| 464 | return result;
|
| 465 | }
|
| 466 | for (i = 0; i < K_SHA256_SIZE >> 2; i++) {
|
| 467 | if (fusedata[i] != 0) {
|
| 468 | programmed = 1;
|
| 469 | break;
|
| 470 | }
|
| 471 | }
|
| 472 |
|
| 473 | if (ptim->pConsTIM->VersionBind.Version < (TIM_3_4_00)) {
|
| 474 | return InvalidTIMVersionError;
|
| 475 | }
|
| 476 |
|
| 477 | HashAlgorithmID = pkey->HashAlgorithmID;
|
| 478 | KeySize = pkey->KeySize;
|
| 479 | EncryptAlgorithmID = pkey->EncryptAlgorithmID;
|
| 480 | key_word_cnt = KeySize/32;
|
| 481 |
|
| 482 | #if EMEI
|
| 483 | hash_data_size_in_bytes = key_word_cnt *2*4; // (exponent-or-X||modulus-or-Y) in bytes (*4)
|
| 484 | /* pack the Exponent */
|
| 485 | for (i = 0; i < key_word_cnt; i++) {
|
| 486 | data[i] = ptim->pTBTIM_DS->Rsa.RSAPublicExponent[i];
|
| 487 | }
|
| 488 | /* pack the Modulus */
|
| 489 | for (i = 0; i < key_word_cnt; i++) {
|
| 490 | data[i + key_word_cnt] = ptim->pTBTIM_DS->Rsa.RSAModulus[i];
|
| 491 | }
|
| 492 |
|
| 493 | #else //HELN
|
| 494 | hash_data_size_in_bytes = (key_word_cnt*2 + 1) * 4; // (crypto_scheme||modulus-or-X||exponent-or-Y) in bytes (*4)
|
| 495 |
|
| 496 | //for platforms other than EMEI, like HELN use 3_4 TIM and beyond
|
| 497 | if (EncryptAlgorithmID == PKCS1_v1_5_Ippcp)
|
| 498 | {
|
| 499 | // 1) Pack the crypto_scheme
|
| 500 | //crypto_scheme: 0x0000A100 PKCSv1_SHA1_1024RSA
|
| 501 | // 0x0000A110 PKCSv1_SHA256_1024RSA
|
| 502 | // 0x0000A200 PKCSv1_SHA1_2048RSA
|
| 503 | // 0x0000A210 PKCSv1_SHA256_2048RSA
|
| 504 | if(ptim->pTBTIM_DS->HashAlgorithmID == SHA256)
|
| 505 | data[0] = (key_word_cnt == 64) ? PKCSv1_SHA256_2048RSA : PKCSv1_SHA256_1024RSA;
|
| 506 | else // Defaults to 160
|
| 507 | data[0] = (key_word_cnt == 64) ? PKCSv1_SHA1_2048RSA : PKCSv1_SHA1_1024RSA;
|
| 508 |
|
| 509 | // 2) Pack the Modulus and Exponent
|
| 510 | for (i=0; i < key_word_cnt; i++)
|
| 511 | {
|
| 512 | data[i+1] = ptim->pTBTIM_DS->Rsa.RSAModulus[i];
|
| 513 | data[i+key_word_cnt+1] = ptim->pTBTIM_DS->Rsa.RSAPublicExponent[i];
|
| 514 | }
|
| 515 | }
|
| 516 | else
|
| 517 | return InvalidDSAError;
|
| 518 | #endif
|
| 519 |
|
| 520 | //Key Padding is on by default
|
| 521 | hash_data_size_in_bytes = BINDKEYSIZE*4; // MaxKeySize*2+CryptoScheme in Bytes: 129*4 = 516
|
| 522 |
|
| 523 |
|
| 524 | for (i = 0; i < DIGEST_WLEN_MAX; i++) {
|
| 525 | digest[i] = 0;
|
| 526 | }
|
| 527 | result = pSFs->pSHAMessageDigest((UINT8_T *)data, hash_data_size_in_bytes,
|
| 528 | (UINT8_T *)digest, HashAlgorithmID);
|
| 529 | if (result != NoError) {
|
| 530 | return result;
|
| 531 | }
|
| 532 |
|
| 533 | /* compare fuses against TIM */
|
| 534 | if (programmed) {
|
| 535 | for (i = 0; i < K_SHA256_SIZE >> 2; i++) {
|
| 536 | if (fusedata[i] != digest[i]) {
|
| 537 | return FUSE_FuseBlockCompareFailed;
|
| 538 | }
|
| 539 | }
|
| 540 | }
|
| 541 | return NoError;
|
| 542 | }
|
| 543 |
|
| 544 | /**
|
| 545 | * perform platform auto-configuration
|
| 546 | * @parameter ptim: pointer to TIM
|
| 547 | * @parameter parameter: NULL
|
| 548 | */
|
| 549 | extern UINT_T GEU_LIB_AutoConfigPlatform(pTIM ptim, void* parameter)
|
| 550 | {
|
| 551 | UINT_T result = NoError;
|
| 552 | fuse_conf_spec_t fuse_conf;
|
| 553 |
|
| 554 | fuse_conf = GetFuseConfSpec(NULL);
|
| 555 |
|
| 556 | /* make sure power supply required for fuse programming is enabled */
|
| 557 | result = GEU_EnableFuseBurnPower();
|
| 558 | if (result != NoError) {
|
| 559 | return FUSE_FuseBurnPowerNotEnabled;
|
| 560 | }
|
| 561 |
|
| 562 |
|
| 563 | GEU_UARTLOG("S USBIDSecurityConfig...\n");
|
| 564 | //GEU_UARTLOG("S ApCpECC...\n");
|
| 565 | // ApCP in block 0
|
| 566 | //reset_blk0_active_status();
|
| 567 | // Security Config/USB ID in block 7
|
| 568 | reset_blk7_active_status();
|
| 569 |
|
| 570 | /*
|
| 571 | * configure USB ID, Security Config and their ECCs
|
| 572 | */
|
| 573 | result = GEU_LIB_ProgramSecurityConfig(NULL, ptim);
|
| 574 | if (result != NoError) {
|
| 575 | return result;
|
| 576 | }
|
| 577 |
|
| 578 | result = GEU_SetupSecurityConfigUsbIdEccFuseBits();
|
| 579 | if (result != NoError) {
|
| 580 | return result;
|
| 581 | }
|
| 582 |
|
| 583 | result = burn_security_usb_ecc(1);
|
| 584 | if ((result != NoError) && (result != FUSE_FuseBlockNotActive) && (result != FUSE_NoBurnRequest)) {
|
| 585 | return result;
|
| 586 | }
|
| 587 |
|
| 588 | return result;
|
| 589 | }
|
| 590 |
|
| 591 |
|
| 592 | /**
|
| 593 | * program security config fuse bits
|
| 594 | */
|
| 595 | UINT_T GEU_LIB_ProgramSecurityConfig(void* parameter, pTIM ptim)
|
| 596 | {
|
| 597 | UINT_T result, flash_number;
|
| 598 | UINT_T security_config[1];
|
| 599 | fuse_conf_spec_t fuse_conf;
|
| 600 |
|
| 601 | fuse_conf = GetFuseConfSpec(NULL);
|
| 602 |
|
| 603 | result = set_blk7_active();
|
| 604 |
|
| 605 | result = GEU_ReadSecurityConfigFuseBits(&security_config[0], K_SECURITY_CONFIG_FUSE_SIZE);
|
| 606 | if (result != NoError) {
|
| 607 | return result;
|
| 608 | }
|
| 609 |
|
| 610 | if (ptim != NULL) {
|
| 611 | flash_number = (UINT8_T)((ptim->pConsTIM->FlashInfo.BootFlashSign) & 0x3F);
|
| 612 | fuse_conf.security_config[0] |= flash_number << FLASHNUMSHIFT;
|
| 613 | }
|
| 614 |
|
| 615 | if (ptim != NULL) {
|
| 616 | if (ptim->pConsTIM->VersionBind.Trusted)
|
| 617 | fuse_conf.security_config[0] |= (OPMODETRUSTED); // Trusted
|
| 618 | else
|
| 619 | fuse_conf.security_config[0] |= (OPMODENONTRUSTED); // Non-Trusted
|
| 620 | }
|
| 621 |
|
| 622 | if ( security_config[0]!= 0 && security_config[0] != fuse_conf.security_config[0] ) {
|
| 623 | return FUSE_FuseBlockFieldFull;
|
| 624 | }
|
| 625 |
|
| 626 | result = GEU_SetupSecurityConfigFuseBits(&fuse_conf.security_config[0], fuse_conf.security_config_bit_cnt/8);
|
| 627 |
|
| 628 | return result;
|
| 629 | }
|
| 630 |
|
| 631 | UINT_T GEU_ProgramMiscConfig(pTIM pTIM_h)
|
| 632 | {
|
| 633 | (VOID)pTIM_h;
|
| 634 | return NoError;
|
| 635 | } |