| /***************************************************************************** |
| * |
| * Filename: |
| * --------- |
| * custom_sml.c |
| * |
| * Project: |
| * -------- |
| * UMOLYA |
| * |
| * Description: |
| * ------------ |
| * This file is for SIM ME Lock customization |
| * |
| * Author: |
| * ------- |
| * ------- |
| ****************************************************************************/ |
| #if !defined(__MAUI_BASIC__) |
| |
| #include <string.h> |
| |
| #include "kal_general_types.h" |
| #include "kal_public_api.h" |
| #include "global_def.h" |
| |
| #include "custom_sml.h" |
| #include "custom_sml_trc.h" |
| #include "custom_nvram_extra.h" |
| |
| #include "ps_public_enum.h" |
| #include "sim_ps_enum.h" |
| #include "smu_common_enums.h" |
| |
| #include "mcd_l3_inc_struct.h" |
| |
| #include "nvram_interface.h" |
| #include "cust_chl_interface.h" |
| #include "custom_sml_sec_verify.h" |
| |
| #include "l4c_utility.h" |
| #include "ps_public_utility.h" |
| |
| |
| extern void smu_nvram_write(nvram_lid_enum file_idx, kal_uint8 access_id, kal_bool is_write_protect2); |
| |
| |
| |
| #ifndef L4_NOT_PRESENT |
| /**************************************************************************** |
| * |
| * SIM ME Lock |
| * |
| ****************************************************************************/ |
| |
| #ifdef __CUST_SML_RULE__ |
| const kal_uint8 sml_gblob_max_cust_rule[SML_LOCK_CUST_CODE_SIZE + 1] = SML_GBLOB_MAX_CUST_RULE_LIST; |
| #endif |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_mini_trace |
| * DESCRIPTION |
| * trace for short strings |
| * PARAMETERS |
| * title [const kal_char] |
| * data [kal_uint8] |
| * len [kal_uint8] |
| * RETURN |
| * void |
| *******************************************************************************/ |
| void sml_mini_trace(const kal_char *title, kal_uint8 *data, kal_uint8 len) |
| { |
| kal_uint8 *buf = NULL; |
| kal_uint8 buf_len = (len < 128 ? len : 128); |
| |
| buf = get_ctrl_buffer(128 + 1); |
| kal_mem_set(buf, 0, 128 + 1); |
| |
| kal_mem_cpy(buf, data, buf_len); |
| kal_prompt_trace(kal_get_active_module_id(), "%s: ", title); |
| kal_prompt_trace(kal_get_active_module_id(), "%s", (const kal_char *)buf); |
| } |
| |
| /******************************************************************************* |
| * FUNCTION |
| * custom_sml_query_key_input_type |
| * DESCRIPTION |
| * This function is to query under particular protection algorithm and operation pair, |
| * whether our key input is plaintext key (e.g. '123456') or hashed key (e.g. {0xAA, 0xBB, ...}) |
| * PARAMETERS |
| * algo key protection algorithm |
| * op operation for querying key input type |
| * RETURN |
| * SML_VERIFY_WITH_PLAINKEY: Input is plaintext key, may need to derive its hashed value for verification |
| * SML_VERIFY_WITH_HCK: Input is hashed key, directly compare its stored hashed value for verification |
| * GLOBALS AFFECTED |
| * N/A |
| *******************************************************************************/ |
| sml_key_input_type_enum custom_sml_query_key_input_type(sml_key_algo_enum algo, sml_op_enum op) |
| { |
| sml_key_input_type_enum input_type = SML_INPUT_WITH_PLAINKEY; |
| |
| if (algo == SML_KEY_ALGO_BCD) /* algo == 0 */ |
| { |
| input_type = SML_INPUT_WITH_PLAINKEY; |
| } |
| |
| else if (algo == SML_KEY_ALGO_PBKDF2_HMAC_SHA256_SALT128) /* algo == 1 */ |
| { |
| switch (op) |
| { |
| case SML_OP_VERIFY: |
| case SML_OP_CHANGE_PWD: |
| input_type = SML_INPUT_WITH_PLAINKEY; |
| break; |
| |
| case SML_OP_UNLOCK: |
| case SML_OP_LOCK: |
| case SML_OP_ADD: |
| case SML_OP_REMOVE: |
| case SML_OP_DISABLE: |
| case SML_OP_UPDATE_AUTOLOCK_COUNT: |
| input_type = SML_INPUT_WITH_HCK; |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| return input_type; |
| } |
| |
| #ifdef __SML_PUK__ |
| /******************************************************************************* |
| * FUNCTION |
| * custom_sml_query_puk_key_input_type |
| * DESCRIPTION |
| * This function is to query under particular protection algorithm and operation pair, |
| * whether our key input is plaintext key (e.g. '123456') or hashed key (e.g. {0xAA, 0xBB, ...}) |
| * PARAMETERS |
| * algo key protection algorithm |
| * op operation for querying key input type |
| * RETURN |
| * SML_VERIFY_WITH_PLAINKEY: Input is plaintext key, may need to derive its hashed value for verification |
| * SML_VERIFY_WITH_HCK: Input is hashed key, directly compare its stored hashed value for verification |
| * GLOBALS AFFECTED |
| * N/A |
| *******************************************************************************/ |
| sml_key_input_type_enum custom_sml_query_puk_key_input_type(sml_key_algo_enum algo, sml_puk_key_op_enum op) |
| { |
| sml_key_input_type_enum input_type = SML_INPUT_WITH_PLAINKEY; |
| |
| if (algo == SML_KEY_ALGO_BCD) /* algo == 0 */ |
| { |
| input_type = SML_INPUT_WITH_PLAINKEY; // Only PLAINTEXT allowed |
| } |
| |
| else if (algo == SML_KEY_ALGO_PBKDF2_HMAC_SHA256_SALT128) /* algo == 1 */ |
| { |
| switch (op) |
| { |
| case SML_PUK_OP_VERIFY: |
| input_type = SML_INPUT_WITH_PLAINKEY; |
| break; |
| |
| case SML_PUK_OP_UPDATE: |
| input_type = SML_INPUT_WITH_HCK; |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| return input_type; |
| } |
| #endif /* __SML_PUK__ */ |
| |
| |
| /**************************************************************************** |
| * |
| * Verizon SIM Lock |
| * |
| ****************************************************************************/ |
| |
| /* define the Local variable of VZW SML object */ |
| static sml_vzw_sim_lock_context_struct sml_vzw_cntxt_obj[MAX_SIM_NUM]; |
| static nvram_ef_sml_vzw_sim_lock_obj_struct SMLVZWOBJ[MAX_SIM_NUM]; |
| |
| /* define the Global access pointer of VZW SML object */ |
| nvram_ef_sml_vzw_sim_lock_obj_struct * pSMLVZWg = &SMLVZWOBJ[0]; |
| |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_clean_vzw_cntxt |
| * DESCRIPTION |
| * Clean sensitive data in MD Dump. |
| * PARAMETERS |
| * N/A |
| * RETURN |
| * N/A |
| * GLOBALS AFFECTED |
| * sml_vzw_cntxt_obj |
| *******************************************************************************/ |
| void sml_clean_vzw_cntxt(void) |
| { |
| kal_mem_set(sml_vzw_cntxt_obj, 0x00, sizeof(sml_vzw_cntxt_obj)); |
| } |
| |
| /******************************************************************************* |
| * FUNCTION |
| * custom_sml_vzw_is_test_purpose |
| * DESCRIPTION |
| * This function is to query if VzW testing functions are enabled |
| * PARAMETERS |
| * N/A |
| * RETURN |
| * KAL_TRUE: For test purpose, testing function enabled |
| * KAL_FALSE: Normal purpose |
| * GLOBALS AFFECTED |
| * N/A |
| *******************************************************************************/ |
| kal_bool custom_sml_vzw_is_test_purpose(void) |
| { |
| #ifdef __VZW_RSU_TEST__ |
| return KAL_TRUE; |
| #else |
| return KAL_FALSE; |
| #endif |
| } |
| |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_vzw_give |
| * DESCRIPTION |
| * This method copys the LID files read from NVRAM to the SML obj |
| * PARAMETERS |
| * IN * pLidToObj |
| * RETURN |
| * void |
| * GLOBALS AFFECTED |
| * SMLOBJ |
| *******************************************************************************/ |
| void sml_vzw_give(void *pLidToObj, kal_uint8 source) |
| { |
| sml_vzw_sim_lock_context_struct * pObj = NULL; |
| |
| if(NULL != pSMLVZWg[source].pObj) |
| { |
| pSMLVZWg[source].pObj = NULL; |
| } |
| |
| pObj = &(sml_vzw_cntxt_obj[source]); |
| |
| kal_mem_cpy(pObj, |
| pLidToObj, |
| sizeof(sml_vzw_sim_lock_context_struct) |
| ); |
| |
| pSMLVZWg[source].pObj = pObj; |
| } |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_vzw_take |
| * DESCRIPTION |
| * This method copys the contex of the SML object to the provided NVRAM LID. |
| * PARAMETERS |
| * OUT * pObjToLid |
| * RETURN |
| * void |
| * GLOBALS AFFECTED |
| * SMLOBJ |
| *******************************************************************************/ |
| void sml_vzw_take( void *pObjToLid, kal_uint8 source ) |
| { |
| sml_vzw_sim_lock_context_struct * pObj = (sml_vzw_sim_lock_context_struct *) pSMLVZWg[source].pObj; |
| |
| kal_mem_cpy(pObjToLid, |
| pObj, |
| sizeof(sml_vzw_sim_lock_context_struct) |
| ); |
| } |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_vzw_destory |
| * DESCRIPTION |
| * This method free the SML object in memory if it is not used. |
| * PARAMETERS |
| * void |
| * RETURN |
| * void |
| * GLOBALS AFFECTED |
| * SMLOBJ |
| *******************************************************************************/ |
| void sml_vzw_destory(kal_uint8 source) |
| { |
| pSMLVZWg[source].pObj = NULL; |
| } |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_vzw_Load |
| * DESCRIPTION |
| * This function loads the SML obj from NVRAM LID (NVRAM_READ_CNF) |
| * PARAMETERS |
| * IN pLid |
| * RETURN |
| * kal_uint16 Obj size |
| * GLOBALS AFFECTED |
| * SMLOBJ |
| *******************************************************************************/ |
| kal_uint16 sml_vzw_Load( void *pLid, kal_uint8 source ) |
| { |
| nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source]; |
| |
| kal_uint16 length = sizeof(sml_vzw_sim_lock_context_struct); |
| |
| /* Clean the old ones */ |
| (*p->destory)(source); |
| |
| /* Load the new one */ |
| (*p->give)(pLid, source); |
| |
| return length; |
| } |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_vzw_Save |
| * DESCRIPTION |
| * This function saves the SML obj to NVRAM LID (NVRAM_WRITE_REQ) |
| * PARAMETERS |
| * OUT pLid |
| * RETURN |
| * kal_uint16 Obj size |
| * GLOBALS AFFECTED |
| * SMLOBJ |
| *******************************************************************************/ |
| kal_uint16 sml_vzw_Save( void *pLid, kal_uint8 source ) |
| { |
| nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source]; |
| |
| kal_uint16 length = sizeof(sml_vzw_sim_lock_context_struct); |
| |
| kal_uint8 lock_state = SML_VZW_LOCK_STATE_LOCK; |
| |
| kal_bool ret_val = KAL_FALSE; |
| |
| kal_bool temp_unlock_restore_required = KAL_FALSE; |
| |
| /* Check if NW lock op is set to Temp unlock in SML VzW OBJ. If yes, then change it to Lock before performing 'take' operation. |
| Then restore back to Temp unlock after 'take' operation */ |
| |
| ret_val = sml_vzw_get_int_data(source, SML_VZW_CAT_NONE, SML_VZW_RSU_NETWORK_LOCK_OPERATION, &lock_state); |
| |
| if (KAL_FALSE == ret_val) |
| { |
| DEBUG_ASSERT(0); |
| } |
| else |
| { |
| if (lock_state == SML_VZW_LOCK_STATE_TEMP_UNLOCK) |
| { |
| ret_val = sml_vzw_update_int_data(source, SML_VZW_CAT_NONE, SML_VZW_RSU_NETWORK_LOCK_OPERATION, SML_VZW_LOCK_STATE_LOCK); |
| if (ret_val == KAL_TRUE) |
| { |
| temp_unlock_restore_required = KAL_TRUE; |
| } |
| } |
| } |
| |
| (*p->take)(pLid, source); |
| |
| if (KAL_TRUE == temp_unlock_restore_required) |
| { |
| sml_vzw_update_int_data(source, SML_VZW_CAT_NONE, SML_VZW_RSU_NETWORK_LOCK_OPERATION, SML_VZW_LOCK_STATE_TEMP_UNLOCK); |
| } |
| |
| return length; |
| } |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_vzw_getItem |
| * DESCRIPTION |
| * This method returns the structure pointer and length of the structure |
| * of the desired SML object items. |
| * PARAMETERS |
| * IN cat |
| * IN item |
| * OUT *length |
| * RETURN |
| * void * |
| * GLOBALS AFFECTED |
| * SMLOBJ |
| *******************************************************************************/ |
| void * sml_vzw_getItem(sml_vzw_cat_enum category, |
| sml_ctx_enum item, |
| kal_uint16 *plength, |
| kal_uint8 source) |
| { |
| sml_vzw_sim_lock_context_struct *pObj = (sml_vzw_sim_lock_context_struct *) pSMLVZWg[source].pObj; |
| |
| ASSERT(NULL != pObj); |
| |
| switch(item) |
| { |
| case SML_VZW_RSU_MAJOR_VERSION: |
| *plength = sizeof(kal_uint8); |
| return (kal_uint8 *) &(pObj->major_version); |
| |
| case SML_VZW_RSU_MINOR_VERSION: |
| *plength = sizeof(kal_uint8); |
| return (kal_uint8 *) &(pObj->minor_version); |
| |
| case SML_VZW_RSU_PROTECTION_ALGORITHM: |
| *plength = sizeof(kal_uint8); |
| return (kal_uint8 *) &(pObj->protection_algo); |
| |
| case SML_VZW_RSU_NETWORK_LOCK_OPERATION: |
| *plength = sizeof(kal_uint8); |
| return (kal_uint8 *) &(pObj->nw_lock_op); |
| |
| case SML_VZW_RSU_TIME_STAMP: |
| *plength = SML_VZW_RSU_TIME_STAMP_LEN; |
| return (kal_uint8 *) &(pObj->timestamp[0]); |
| |
| case SML_VZW_RSU_SESSION_ID: |
| *plength = SML_VZW_RSU_SESSION_ID_LEN; |
| return (kal_uint8 *) &(pObj->session_id[0]); |
| |
| case SML_VZW_RSU_CAT_CODE: |
| switch(category) |
| { |
| case SML_VZW_CAT_N: |
| *plength = SML_VZW_RSU_NW_LIST_LEN; |
| return (kal_uint8 *) &(pObj->nw_list[0]); |
| break; |
| |
| case SML_VZW_CAT_NS: |
| *plength = SML_VZW_RSU_NS_LIST_LEN; |
| return (kal_uint8 *) &(pObj->ns_list[0]); |
| break; |
| |
| case SML_VZW_CAT_SP: |
| *plength = SML_VZW_RSU_SP_LIST_LEN; |
| return (kal_uint8 *) &(pObj->sp_list[0]); |
| break; |
| |
| case SML_VZW_CAT_EHPLMN: |
| *plength = SML_VZW_RSU_EHPLMN_LIST_LEN; |
| return (kal_uint8 *) &(pObj->ehplmn_list[0]); |
| break; |
| |
| default: |
| /* do nothing */ |
| break; |
| } |
| break; |
| |
| case SML_VZW_RSU_CAT_NUM: |
| switch(category) |
| { |
| case SML_VZW_CAT_N: |
| *plength = sizeof(kal_uint8); |
| return (kal_uint8 *) &(pObj->nw_num); |
| break; |
| |
| case SML_VZW_CAT_NS: |
| *plength = sizeof(kal_uint8); |
| return (kal_uint8 *) &(pObj->ns_num); |
| break; |
| |
| case SML_VZW_CAT_SP: |
| *plength = sizeof(kal_uint8); |
| return (kal_uint8 *) &(pObj->sp_num); |
| break; |
| |
| case SML_VZW_CAT_EHPLMN: |
| *plength = sizeof(kal_uint8); |
| return (kal_uint8 *) &(pObj->ehplmn_num); |
| break; |
| |
| default: |
| /* do nothing */ |
| break; |
| } |
| break; |
| |
| default: |
| break; |
| } |
| |
| return NULL; |
| } |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_vzw_putItem |
| * DESCRIPTION |
| * This method set the desired items of the SML object. |
| * PARAMETERS |
| * IN cat |
| * IN item |
| * IN *pItem |
| * IN *plength |
| * RETURN |
| * void |
| * GLOBALS AFFECTED |
| * SMLOBJ |
| *******************************************************************************/ |
| void sml_vzw_putItem(sml_vzw_cat_enum cat, |
| sml_ctx_enum item, |
| void *pItem, |
| kal_uint16 *plength, |
| kal_uint8 source) |
| { |
| sml_vzw_sim_lock_context_struct *pObj = (sml_vzw_sim_lock_context_struct *) pSMLVZWg[source].pObj; |
| |
| switch (item) |
| { |
| case SML_VZW_RSU_MAJOR_VERSION: |
| kal_mem_cpy(&(pObj->major_version), pItem, *plength); |
| break; |
| |
| case SML_VZW_RSU_MINOR_VERSION: |
| kal_mem_cpy(&(pObj->minor_version), pItem, *plength); |
| break; |
| |
| case SML_VZW_RSU_PROTECTION_ALGORITHM: |
| kal_mem_cpy(&(pObj->protection_algo), pItem, *plength); |
| break; |
| |
| case SML_VZW_RSU_NETWORK_LOCK_OPERATION: |
| kal_mem_cpy(&(pObj->nw_lock_op), pItem, *plength); |
| break; |
| |
| case SML_VZW_RSU_SESSION_ID: |
| kal_mem_cpy(pObj->session_id, pItem, *plength); |
| break; |
| |
| case SML_VZW_RSU_TIME_STAMP: |
| kal_mem_cpy(pObj->timestamp, pItem, *plength); |
| break; |
| |
| case SML_VZW_RSU_CAT_CODE: |
| switch(cat) |
| { |
| case SML_VZW_CAT_N: |
| kal_mem_cpy(pObj->nw_list, pItem, *plength); |
| break; |
| |
| case SML_VZW_CAT_NS: |
| kal_mem_cpy(pObj->ns_list, pItem, *plength); |
| break; |
| |
| case SML_VZW_CAT_SP: |
| kal_mem_cpy(pObj->sp_list, pItem, *plength); |
| break; |
| |
| case SML_VZW_CAT_EHPLMN: |
| kal_mem_cpy(pObj->ehplmn_list, pItem, *plength); |
| break; |
| |
| default: |
| /* do nothing */ |
| break; |
| } |
| break; |
| |
| case SML_VZW_RSU_CAT_NUM: |
| switch(cat) |
| { |
| case SML_VZW_CAT_N: |
| kal_mem_cpy(&(pObj->nw_num), pItem, *plength); |
| break; |
| |
| case SML_VZW_CAT_NS: |
| kal_mem_cpy(&(pObj->ns_num), pItem, *plength); |
| break; |
| |
| case SML_VZW_CAT_SP: |
| kal_mem_cpy(&(pObj->sp_num), pItem, *plength); |
| break; |
| |
| case SML_VZW_CAT_EHPLMN: |
| kal_mem_cpy(&(pObj->ehplmn_num), pItem, *plength); |
| break; |
| |
| default: |
| /* do nothing */ |
| break; |
| } |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_vzw_Catcode |
| * DESCRIPTION |
| * This function is used to compose the code of each category |
| * PARAMETERS |
| * IN cat |
| * IN *imsi |
| * IN *vzw_gid1_len |
| * IN *gid1 |
| * IN *ehplmn |
| * IN mnc_len |
| * OUT *code |
| * RETURN |
| * kal_uint8 code length |
| * GLOBALS AFFECTED |
| * NONE |
| *******************************************************************************/ |
| kal_uint8 sml_vzw_Catcode( sml_vzw_cat_enum cat, |
| kal_uint8 *imsi, |
| kal_uint8 vzw_gid1_len, |
| kal_uint8 *gid1, |
| kal_uint8 *ehplmn, |
| kal_uint8 mnc_len, |
| kal_uint8 *code ) |
| { |
| kal_uint8 i = 0; |
| kal_uint8 gid1_start_pos = 7; |
| kal_uint8 ehplmn_start_pos = (vzw_gid1_len < NUM_GID1)? (gid1_start_pos + vzw_gid1_len) : (gid1_start_pos + NUM_GID1); |
| |
| if (imsi == NULL) |
| { |
| return 0; |
| } |
| |
| if(mnc_len == 3) |
| { |
| /* MCC/MNC */ |
| code[0] = ((imsi[1]&0xF0)>>4) + '0'; |
| code[1] = (imsi[2]&0x0F) + '0'; |
| code[2] = ((imsi[2]&0xF0)>>4) + '0'; |
| code[3] = (imsi[3]&0x0F) + '0'; |
| code[4] = ((imsi[3]&0xF0)>>4) + '0'; |
| code[5] = (imsi[4]&0x0F) + '0'; |
| code[6] = ((imsi[4]&0xF0)>>4) + '0'; |
| code[7] = (imsi[5]&0x0F) + '0'; |
| } |
| else |
| { |
| /* MCC/MNC */ |
| code[0] = ((imsi[1]&0xF0)>>4) + '0'; |
| code[1] = (imsi[2]&0x0F) + '0'; |
| code[2] = ((imsi[2]&0xF0)>>4) + '0'; |
| code[3] = (imsi[3]&0x0F) + '0'; |
| code[4] = ((imsi[3]&0xF0)>>4) + '0'; |
| code[5] = 'F'; |
| code[6] = (imsi[4]&0x0F) + '0'; |
| code[7] = ((imsi[4]&0xF0)>>4) + '0'; |
| } |
| |
| switch(cat) |
| { |
| case SML_VZW_CAT_N: |
| return SML_VZW_RSU_NW_CODE_LEN; |
| break; |
| |
| case SML_VZW_CAT_NS: |
| return SML_VZW_RSU_NS_CODE_LEN; |
| break; |
| |
| case SML_VZW_CAT_SP: |
| if (NULL != gid1) |
| { |
| code[6] = vzw_gid1_len; |
| /* GID */ |
| for (i = 0; (i < vzw_gid1_len) && (i < NUM_GID1); i++) |
| { |
| code[gid1_start_pos+i] = gid1[i]; |
| } |
| return gid1_start_pos + i; |
| } |
| else |
| { |
| return 0; |
| } |
| break; |
| |
| case SML_VZW_CAT_EHPLMN: |
| if (NULL != gid1) |
| { |
| code[6] = vzw_gid1_len; |
| /* Verizon use 8 bytes of GID1 */ |
| for (i = 0; (i < vzw_gid1_len) && (i < NUM_GID1); i++) |
| { |
| code[gid1_start_pos+i] = gid1[i]; |
| } |
| } |
| else |
| { |
| return 0; |
| } |
| |
| if (ehplmn != NULL) |
| { |
| if (*ehplmn == 0xff) |
| { |
| return 0; |
| } |
| else |
| { |
| /* EHPLMN format is : |
| MCC2|MCC1 MNC3(opt)|MCC3 MNC2|MNC1 |
| */ |
| code[ehplmn_start_pos] = (ehplmn[0]&0x0F) + '0'; //MCC1 |
| code[ehplmn_start_pos+1] = ((ehplmn[0]&0xF0)>>4) + '0'; //MCC2 |
| code[ehplmn_start_pos+2] = (ehplmn[1]&0x0F) + '0'; //MCC3 |
| code[ehplmn_start_pos+3] = (ehplmn[2]&0x0F) + '0'; //MNC1 |
| code[ehplmn_start_pos+4] = ((ehplmn[2]&0xF0)>>4) + '0'; //MNC2 |
| |
| if ((ehplmn[1] & 0xF0) == 0xF0) //this EHPLMN mnc len = 2 |
| { |
| code[ehplmn_start_pos+5] = 0xFF; |
| } |
| else |
| { |
| code[ehplmn_start_pos+5] = ((ehplmn[1] & 0xF0)>>4) + '0'; //MNC3 |
| } |
| return ehplmn_start_pos + 6; |
| } |
| } |
| else |
| { |
| return 0; |
| } |
| break; |
| |
| default: |
| |
| break; |
| |
| } |
| |
| return 0; |
| } |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_vzw_GetCode |
| * DESCRIPTION |
| * This function is used to compose the code of each category whether |
| * mnc length is 2 or 3 |
| * PARAMETERS |
| * cat [IN] category of the SIM-ME-Lock |
| * imsi [IN] imsi of the code source |
| * vzw_gid1_len [IN] gid1 lengh from VZW code |
| * gid1 [IN] gid1 of the code source |
| * sim_mnc_len [IN] the mnc length decided by SIM |
| * pdata [IN] the saved code for comparing |
| * pdata_len [IN] the length of saved code for comparing |
| * code [OUT] the composed code according to all input parameters |
| * |
| * RETURN |
| * kal_uint16 file size |
| * GLOBALS AFFECTED |
| * SMLSLOBJ |
| *******************************************************************************/ |
| kal_uint8 sml_vzw_GetCode( sml_vzw_cat_enum cat, |
| kal_uint8 *imsi, |
| kal_uint8 vzw_gid1_len, |
| kal_uint8 *gid1, |
| kal_uint8 *ehplmn, |
| kal_uint8 sim_mnc_len, |
| kal_uint8 *pdata, |
| kal_uint8 *pdata_len, |
| kal_uint8 *code) |
| { |
| kal_uint8 mnc_len=0; |
| |
| if (SML_MNC_LENGTH_NEST == 1) |
| { |
| mnc_len = sim_mnc_len; |
| } |
| else |
| { |
| if (((*(pdata+5)) == 'F') || ((*(pdata+5)) == 'f')) |
| { |
| mnc_len = 2; |
| *(pdata+5) = 'F'; |
| } |
| else |
| { |
| mnc_len = 3; |
| } |
| } |
| |
| switch (cat) |
| { |
| case SML_VZW_CAT_N: |
| *pdata_len = SML_VZW_RSU_NW_CODE_LEN; |
| break; |
| case SML_VZW_CAT_NS: |
| *pdata_len = SML_VZW_RSU_NS_CODE_LEN; |
| break; |
| case SML_VZW_CAT_SP: |
| *pdata_len = SML_VZW_RSU_NW_CODE_LEN + 1 + vzw_gid1_len; |
| break; |
| case SML_VZW_CAT_EHPLMN: |
| *pdata_len = (SML_VZW_RSU_NW_CODE_LEN*2) + 1 + vzw_gid1_len; |
| break; |
| default: |
| DEBUG_ASSERT(0); |
| *pdata_len = 0; |
| } |
| |
| return sml_vzw_Catcode(cat, imsi, vzw_gid1_len, gid1, ehplmn, mnc_len, code); |
| } |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_vzw_Check |
| * DESCRIPTION |
| * This function is used to check if the code is in the Pass list |
| * PARAMETERS |
| * IN cat |
| * IN *imsi |
| * IN *gid1 |
| * IN ehplmn_num |
| * IN *ehplmn_ptr |
| * IN len |
| * IN source |
| * RETURN |
| * kal_bool |
| * GLOBALS AFFECTED |
| * SMLOBJ |
| *******************************************************************************/ |
| kal_bool sml_vzw_Check( sml_vzw_cat_enum cat, |
| kal_uint8 *imsi, |
| kal_uint8 *gid1, |
| kal_uint16 ehplmn_num, |
| kal_uint8 *ehplmn_ptr, |
| kal_uint8 sim_mnc_len, |
| kal_uint8 source) |
| { |
| nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source]; |
| kal_uint8 *num_list = NULL; |
| kal_uint8 *list_data = NULL; |
| kal_uint8 *vzw_code_ptr = NULL; |
| kal_uint8 vzw_code_len = 0; |
| kal_uint16 length = 0; |
| kal_uint8 code[SML_VZW_RSU_EHPLMN_CODE_LEN] = {0}; //use ehplmn code len as max code len |
| kal_uint8 code_len = 0; |
| kal_uint8 vzw_gid1_len; |
| kal_uint16 i = 0; |
| kal_uint8 code_dbg_str[(SML_VZW_RSU_EHPLMN_CODE_LEN)*3 + 1] = {0}; |
| kal_uint8 iter = 1; //iteration for EHPLMN Configuration, limited by MD1_MAX_NUM_HPLMN |
| |
| /* Check the integration of SIM Lock blob first */ |
| if (p->pObj== NULL) |
| { |
| MD_TRC_WARNING_SML_CHECK_VALIDITY_FAILED(); |
| } |
| else |
| { |
| num_list = (kal_uint8 *)(*p->getItem)(cat, SML_VZW_RSU_CAT_NUM, &length, source); |
| |
| if (*num_list == 0) |
| { |
| // TODO: list is empty, always pass or blocked? currently is pass |
| return KAL_TRUE; |
| } |
| else |
| { |
| list_data = (kal_uint8 *)(*p->getItem)(cat, SML_VZW_RSU_CAT_CODE, &length, source); |
| vzw_code_ptr = list_data; |
| } |
| |
| for (i = 0; i < *num_list; i++) |
| { |
| kal_uint8 *temp_ehplmn_ptr = ehplmn_ptr; |
| |
| if (SML_VZW_CAT_EHPLMN == cat) |
| { |
| iter = (ehplmn_num < MD1_MAX_NUM_HPLMN)? ehplmn_num : MD1_MAX_NUM_HPLMN; |
| } |
| else |
| { |
| iter = 1; |
| } |
| |
| if ((SML_VZW_CAT_SP == cat) || (SML_VZW_CAT_EHPLMN == cat)) |
| { |
| vzw_gid1_len = vzw_code_ptr[6]; |
| } |
| else |
| { |
| vzw_gid1_len = 0; |
| } |
| |
| while (iter > 0) |
| { |
| kal_uint8 j = 0, k = 0; |
| |
| iter--; |
| |
| code_len = sml_vzw_GetCode(cat, imsi, vzw_gid1_len, gid1, temp_ehplmn_ptr, sim_mnc_len, vzw_code_ptr, &vzw_code_len, code); |
| |
| if (iter >= 1) |
| { |
| temp_ehplmn_ptr += 3; //for next iteration if more than one EHPLMN from SIM |
| } |
| |
| while ((j < code_len) && (k <= (sizeof(code_dbg_str) - 4))) |
| { |
| kal_int8 temp_len; |
| |
| temp_len = kal_sprintf((kal_char*)code_dbg_str + k, "%02x ", code[j]); |
| |
| if (temp_len <= 0) |
| { |
| kal_mem_cpy(code_dbg_str + k, "ERR", sizeof("ERR")); |
| k += 3; |
| break; |
| } |
| |
| k += temp_len; |
| j++; |
| } |
| code_dbg_str[k] = '\0'; |
| MD_TRC_INFO_SMU_CHECK_LENGTH(code_len, vzw_code_len, sim_mnc_len); |
| MD_TRC_INFO_SML_VZW_CODE_DEBUG((kal_char*)code_dbg_str); |
| |
| /* we support dynamic comparing code length by using the code_len in stead of fixed length. |
| After that, vzw_code_ptr will shift according to each individual code length. |
| In addition, the VZW SIM Lock NVRAM structure is defined as max size. |
| */ |
| if ((code_len > 0) && (kal_mem_cmp(code, vzw_code_ptr, code_len) == 0)) |
| { |
| return KAL_TRUE; |
| } |
| |
| kal_mem_set(code, 0, SML_VZW_RSU_EHPLMN_CODE_LEN); |
| } |
| |
| //shift to next code of the compared category |
| vzw_code_ptr += vzw_code_len; |
| } |
| } |
| |
| return KAL_FALSE; |
| } |
| |
| kal_bool sml_vzw_update_int_data(kal_uint8 source, sml_vzw_cat_enum cat, sml_ctx_enum type, kal_uint8 data) |
| { |
| nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source]; |
| kal_uint16 length = sizeof(kal_uint8); |
| |
| /* Check the integration of SIM Lock blob first */ |
| if (p->pObj == NULL) |
| { |
| MD_TRC_WARNING_SML_CHECK_VALIDITY_FAILED(); |
| return KAL_FALSE; |
| } |
| |
| (*p->putItem)(cat, type, &data, &length, source); |
| |
| return KAL_TRUE; |
| } |
| |
| kal_bool sml_vzw_get_int_data(kal_uint8 source, sml_vzw_cat_enum cat, sml_ctx_enum type, kal_uint8* pData) |
| { |
| nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source]; |
| kal_uint16 length; |
| kal_bool ret_val = KAL_FALSE; |
| |
| /* Check the integration of SIM Lock blob first */ |
| if (p->pObj == NULL) |
| { |
| MD_TRC_WARNING_SML_CHECK_VALIDITY_FAILED(); |
| } |
| else |
| { |
| *pData = *((kal_uint8 *)(*p->getItem)(cat, type, &length, source)); |
| |
| if (length == sizeof(kal_uint8)) |
| { |
| ret_val = KAL_TRUE; |
| } |
| else |
| { |
| MD_TRC_WARNING_SML_VZW_RSU_GET_INT_DATA_FAILED(cat, type); |
| } |
| } |
| |
| return ret_val; |
| } |
| |
| kal_bool sml_vzw_update_array_data(kal_uint8 source, sml_vzw_cat_enum cat, sml_ctx_enum type, kal_uint8* data, kal_uint16 data_len) |
| { |
| nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source]; |
| |
| /* Check the integration of SIM Lock blob first */ |
| if (p->pObj == NULL) |
| { |
| MD_TRC_WARNING_SML_CHECK_VALIDITY_FAILED(); |
| return KAL_FALSE; |
| } |
| |
| (*p->putItem)(cat, type, data, &data_len, source); |
| |
| return KAL_TRUE; |
| } |
| |
| kal_bool sml_vzw_get_array_data(kal_uint8 source, sml_vzw_cat_enum cat, sml_ctx_enum type, kal_uint8* data, kal_uint16* data_len) |
| { |
| nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source]; |
| kal_uint8* pData = NULL; |
| |
| /* Check the integration of SIM Lock blob first */ |
| if (p->pObj == NULL) |
| { |
| MD_TRC_WARNING_SML_CHECK_VALIDITY_FAILED(); |
| return KAL_FALSE; |
| } |
| |
| pData = (kal_uint8 *)(*p->getItem)(cat, type, data_len, source); |
| |
| kal_mem_cpy(data, pData, *data_len); |
| |
| return KAL_TRUE; |
| } |
| |
| kal_uint8 sml_vzw_get_major_version(kal_uint8 source) |
| { |
| nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source]; |
| kal_uint8 *pMajor_ver = NULL; |
| kal_uint16 length = 0; |
| |
| /* Check the integration of SIM Lock blob first */ |
| if (p->pObj == NULL) |
| { |
| MD_TRC_WARNING_SML_CHECK_VALIDITY_FAILED(); |
| return KAL_FALSE; |
| } |
| |
| pMajor_ver = (kal_uint8 *)(*p->getItem)(SML_VZW_CAT_NONE, SML_VZW_RSU_MAJOR_VERSION, &length, source); |
| |
| return *pMajor_ver; |
| } |
| |
| kal_uint8 sml_vzw_get_max_support_major_version() |
| { |
| return SML_VZW_RSU_MAX_SUPPORT_MAJOR_VER; |
| } |
| |
| kal_uint8 sml_vzw_get_minor_version(kal_uint8 source) |
| { |
| nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source]; |
| kal_uint8 *pMinor_ver = NULL; |
| kal_uint16 length = 0; |
| |
| /* Check the integration of SIM Lock blob first */ |
| if (p->pObj == NULL) |
| { |
| MD_TRC_WARNING_SML_CHECK_VALIDITY_FAILED(); |
| return KAL_FALSE; |
| } |
| |
| pMinor_ver = (kal_uint8 *)(*p->getItem)(SML_VZW_CAT_NONE, SML_VZW_RSU_MINOR_VERSION, &length, source); |
| |
| return *pMinor_ver; |
| } |
| |
| kal_uint8 sml_vzw_get_max_support_minor_version() |
| { |
| return SML_VZW_RSU_MAX_SUPPORT_MINOR_VER; |
| } |
| |
| extern const nvram_sml_vzw_sim_lock_context_struct NVRAM_EF_L4_SML_VZW_SIM_LOCK_DEFAULT; |
| |
| kal_bool sml_vzw_reset_rsu_data(kal_uint8 source) |
| { |
| nvram_ef_sml_vzw_sim_lock_obj_struct* p = &pSMLVZWg[source]; |
| sml_vzw_sim_lock_context_struct* pDefaultBlob = (sml_vzw_sim_lock_context_struct*)&NVRAM_EF_L4_SML_VZW_SIM_LOCK_DEFAULT; |
| |
| /* Check the integration of SIM Lock blob first */ |
| if (p->pObj == NULL) |
| { |
| MD_TRC_WARNING_SML_CHECK_VALIDITY_FAILED(); |
| return KAL_FALSE; |
| } |
| |
| // Set Network Lock |
| sml_vzw_update_int_data(source, SML_VZW_CAT_NONE, SML_VZW_RSU_NETWORK_LOCK_OPERATION, SML_VZW_LOCK_STATE_LOCK); |
| |
| // Reset NW Configuration |
| sml_vzw_update_int_data(source, SML_VZW_CAT_N, SML_VZW_RSU_CAT_NUM, pDefaultBlob->nw_num); |
| sml_vzw_update_array_data(source, SML_VZW_CAT_N, SML_VZW_RSU_CAT_CODE, pDefaultBlob->nw_list, SML_VZW_RSU_NW_LIST_LEN); |
| |
| // Reset NS Configuration |
| sml_vzw_update_int_data(source, SML_VZW_CAT_NS, SML_VZW_RSU_CAT_NUM, pDefaultBlob->ns_num); |
| sml_vzw_update_array_data(source, SML_VZW_CAT_NS, SML_VZW_RSU_CAT_CODE, pDefaultBlob->ns_list, SML_VZW_RSU_NS_LIST_LEN); |
| |
| // Reset SP Configuration |
| sml_vzw_update_int_data(source, SML_VZW_CAT_SP, SML_VZW_RSU_CAT_NUM, pDefaultBlob->sp_num); |
| sml_vzw_update_array_data(source, SML_VZW_CAT_SP, SML_VZW_RSU_CAT_CODE, pDefaultBlob->sp_list, SML_VZW_RSU_SP_LIST_LEN); |
| |
| // Reset EHPLMN Configuration |
| sml_vzw_update_int_data(source, SML_VZW_CAT_EHPLMN, SML_VZW_RSU_CAT_NUM, pDefaultBlob->ehplmn_num); |
| sml_vzw_update_array_data(source, SML_VZW_CAT_EHPLMN, SML_VZW_RSU_CAT_CODE, pDefaultBlob->ehplmn_list, SML_VZW_RSU_EHPLMN_LIST_LEN); |
| |
| return KAL_TRUE; |
| } |
| |
| void custom_vzw_rsu_get_pub_key_handle(kal_uint8 index, TYPE_CUST_CHL_KEY *key) |
| { |
| TYPE_CUST_CHL_KEY pub_key[] = { |
| CUST_VZ_PUB_KEY // index == 0, do not change this. |
| // Add test key handle here |
| }; |
| |
| #define VZW_KEY_SET_MAX_NUM (sizeof(pub_key)/sizeof(pub_key[0])) |
| |
| index = index > (VZW_KEY_SET_MAX_NUM - 1) ? 0 : index; |
| |
| if (NULL != key) |
| { |
| *key = pub_key[index]; |
| MD_TRC_INFO_SML_RSU_PUB_KEY_HANDLE((*key)); |
| } |
| |
| return; |
| } |
| |
| /**************************************************************************** |
| * |
| * TMO SIM Lock with Movial Solution |
| * |
| ****************************************************************************/ |
| #ifdef __TMO_RSU_OTP__ |
| static kal_bool custom_check_is_default_tmo_blob(kal_uint8 *imei); |
| #endif /* __TMO_RSU_OTP__ */ |
| /* define the Local variable of TMO MOVIAL SML object */ |
| static sml_tmo_movial_sim_lock_context_struct sml_tmo_movial_cntxt_obj[MAX_SIM_NUM]; |
| static nvram_ef_sml_tmo_movial_sim_lock_obj_struct SMLTMMOBJ[MAX_SIM_NUM]; |
| |
| /* define the Global access pointer of TMO MOVIAL SML object */ |
| nvram_ef_sml_tmo_movial_sim_lock_obj_struct* pSMLTMMg = &SMLTMMOBJ[0]; |
| |
| /* time to temporary unlock expiry in seconds */ |
| kal_uint32 sml_tmo_movial_seconds_to_expire = 0; |
| |
| #ifdef UNIT_TEST |
| kal_uint8 imei_bcd_ut[9]; |
| #endif /* UNIT_TEST */ |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_clean_tmo_movial_cntxt |
| * DESCRIPTION |
| * Clean sensitive data in MD Dump. |
| * PARAMETERS |
| * N/A |
| * RETURN |
| * N/A |
| * GLOBALS AFFECTED |
| * sml_tmo_movial_cntxt_obj |
| *******************************************************************************/ |
| void sml_clean_tmo_movial_cntxt(void) |
| { |
| kal_mem_set(sml_tmo_movial_cntxt_obj, 0x00, sizeof(sml_tmo_movial_cntxt_obj)); |
| } |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmo_movial_give |
| * DESCRIPTION |
| * This method copys the LID files read from NVRAM to the SML obj |
| * PARAMETERS |
| * IN * pLidToObj |
| * RETURN |
| * void |
| * GLOBALS AFFECTED |
| * SMLTMMOBJ |
| *******************************************************************************/ |
| void sml_tmo_movial_give( void *pLidToObj, kal_uint8 source ) |
| { |
| sml_tmo_movial_sim_lock_context_struct * pObj = NULL; |
| |
| if(NULL != pSMLTMMg[source].pObj) |
| { |
| kal_sys_trace("SML: object is exist!"); |
| pSMLTMMg[source].pObj = NULL; |
| } |
| |
| pObj = &(sml_tmo_movial_cntxt_obj[source]); |
| |
| kal_mem_cpy(pObj, |
| pLidToObj, |
| sizeof(sml_tmo_movial_sim_lock_context_struct) |
| ); |
| |
| pSMLTMMg[source].pObj = pObj; |
| } |
| |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmo_movial_take |
| * DESCRIPTION |
| * This method copys the contex of the SML object to the provided NVRAM LID. |
| * PARAMETERS |
| * OUT * pObjToLid |
| * RETURN |
| * void |
| * GLOBALS AFFECTED |
| * SMLTMMOBJ |
| *******************************************************************************/ |
| |
| void sml_tmo_movial_take( void *pObjToLid, kal_uint8 source ) |
| { |
| sml_tmo_movial_sim_lock_context_struct * pObj = (sml_tmo_movial_sim_lock_context_struct *) pSMLTMMg[source].pObj; |
| |
| if (NULL == pObjToLid || NULL == pObj) |
| { |
| return; |
| } |
| |
| kal_mem_cpy(pObjToLid, |
| pObj, |
| sizeof(sml_tmo_movial_sim_lock_context_struct) |
| ); |
| } |
| |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmo_movial_destory |
| * DESCRIPTION |
| * This method free the SML object in memory if it is not used. |
| * PARAMETERS |
| * void |
| * RETURN |
| * void |
| * GLOBALS AFFECTED |
| * SMLTMMOBJ |
| *******************************************************************************/ |
| void sml_tmo_movial_destory(kal_uint8 source) |
| { |
| pSMLTMMg[source].pObj = NULL; |
| } |
| |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmo_movial_getItem |
| * DESCRIPTION |
| * This method returns the structure pointer and length of the structure |
| * of the desired SML object items. |
| * PARAMETERS |
| * IN cat |
| * IN item |
| * OUT *length |
| * RETURN |
| * void * |
| * GLOBALS AFFECTED |
| * SMLTMMOBJ |
| *******************************************************************************/ |
| void *sml_tmo_movial_getItem( sml_tmo_movial_cat_enum category, |
| sml_ctx_enum item, |
| kal_uint16 *plength, |
| kal_uint8 source) |
| { |
| sml_tmo_movial_sim_lock_context_struct *pObj = (sml_tmo_movial_sim_lock_context_struct *) pSMLTMMg[source].pObj; |
| |
| ASSERT(NULL != pObj); |
| |
| switch(item) |
| { |
| case SML_TMO_MOVIAL_CAT_MAJOR_VERSION: |
| *plength = sizeof(kal_uint8); |
| return (kal_uint8 *) &(pObj->major_version); |
| |
| case SML_TMO_MOVIAL_CAT_MINOR_VERSION: |
| *plength = sizeof(kal_uint8); |
| return (kal_uint8 *) &(pObj->minor_version); |
| |
| case SML_TMO_MOVIAL_CAT_PROTECTION_ALGORITHM: |
| *plength = sizeof(kal_uint8); |
| return (kal_uint8 *) &(pObj->protection_algorithm); |
| |
| case SML_TMO_MOVIAL_CAT_LOCK_OPERATION: |
| *plength = sizeof(kal_uint8); |
| return (kal_uint8 *) &(pObj->lock_operation); |
| |
| case SML_TMO_MOVIAL_CAT_IMEI: |
| *plength = SML_TMO_MOVIAL_BLOB_IMEI_SIZE; |
| return (kal_uint8 *) &(pObj->imei[0]); |
| |
| case SML_TMO_MOVIAL_CAT_TIME_STAMP: |
| *plength = SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE; |
| return (kal_uint8 *) &(pObj->time_stamp[0]); |
| |
| case SML_TMO_MOVIAL_CAT_START_TIME: |
| *plength = SML_TMO_MOVIAL_SIZE_OF_START_TIME; |
| return (kal_uint8 *) &(pObj->start_time[0]); |
| |
| case SML_TMO_MOVIAL_CAT_UNLOCK_DURATION: |
| *plength = SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION; |
| return (kal_uint8 *) &(pObj->unlock_duration[0]); |
| |
| case SML_TMO_MOVIAL_CAT_LENGTH: |
| *plength = SML_TMO_MOVIAL_BLOB_LENGTH_SIZE; |
| return (kal_uint16 *) &(pObj->length[0]); |
| |
| case SML_TMO_MOVIAL_CAT_META: |
| *plength = sizeof(sml_tmo_movial_blob_meta_struct); |
| return (sml_tmo_movial_blob_meta_struct *) &(pObj->cat[category]); |
| |
| case SML_TMO_MOVIAL_CAT_KEY: |
| *plength = sizeof(sml_tmo_movial_blob_key_struct); |
| return (sml_tmo_movial_blob_key_struct *) &(pObj->key[category]); |
| |
| case SML_TMO_MOVIAL_CAT_SIGNATURE: |
| *plength = SML_TMO_MOVIAL_BLOB_SIZE_OF_SIGNATURE; |
| return (kal_uint8 *) &(pObj->signature[0]); |
| |
| case SML_TMO_MOVIAL_CAT_UNLOCK_TIME_COUNTER: |
| *plength = SML_TMO_MOVIAL_SIZE_OF_UNLOCK_TIME; |
| return (kal_uint8 *) &(pObj->unlock_time[0]); |
| |
| case SML_TMO_MOVIAL_CAT_CODE: |
| switch(category) |
| { |
| case SML_TMO_MOVIAL_CAT_N: |
| *plength = SML_TMO_MOVIAL_BLOB_CAT_N_SIZE; |
| return (kal_uint8 *) &(pObj->code_cat_n[0]); |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_NS: |
| *plength = SML_TMO_MOVIAL_BLOB_CAT_NS_SIZE; |
| return (kal_uint8 *) &(pObj->code_cat_ns[0]); |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_SP: |
| *plength = SML_TMO_MOVIAL_BLOB_CAT_SP_SIZE; |
| return (kal_uint8 *) &(pObj->code_cat_sp[0]); |
| break; |
| |
| default: |
| /* do nothing */ |
| break; |
| } |
| break; |
| |
| default: |
| break; |
| } |
| |
| return NULL; |
| } |
| |
| void sml_tmo_movial_putItem( sml_tmo_movial_cat_enum category, |
| sml_ctx_enum item, |
| void *pItem, |
| kal_uint16 *plength, |
| kal_uint8 source) |
| { |
| sml_tmo_movial_sim_lock_context_struct *pObj = (sml_tmo_movial_sim_lock_context_struct *) pSMLTMMg[source].pObj; |
| |
| ASSERT(NULL != pObj); |
| |
| switch(item) |
| { |
| case SML_TMO_MOVIAL_CAT_UNLOCK_TIME_COUNTER: |
| |
| kal_mem_cpy(&(pObj->unlock_time[0]), |
| pItem, |
| SML_TMO_MOVIAL_SIZE_OF_UNLOCK_TIME |
| ); |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_LOCK_OPERATION: |
| |
| kal_mem_cpy(&(pObj->lock_operation), |
| pItem, |
| *plength); |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| |
| kal_bool sml_tmo_movial_ValidateIMEI(kal_uint8 *imei, kal_bool is_bypass_default, kal_uint8 source) |
| { |
| kal_uint8 nvram_imei_bcd[8 + 1] = {0}; |
| kal_uint8 nvram_imei_ascii[16 + 1] = {0}; |
| kal_uint8 rec_id = 1 + l4c_gemini_get_actual_sim_id(source); |
| kal_bool result = KAL_FALSE; |
| |
| #ifdef UNIT_TEST //Integrity check doesn't work on modis. Modify for UT. |
| kal_mem_cpy(&nvram_imei_bcd[0], &imei_bcd_ut[0], 9); |
| #else |
| if (nvram_get_imei_value(8, nvram_imei_bcd, rec_id) == KAL_TRUE) |
| #endif |
| { |
| if ((is_bypass_default == KAL_TRUE) |
| && (KAL_TRUE == custom_check_is_default_imei(&nvram_imei_bcd[0]))) |
| { |
| MD_TRC_INFO_SML_CUST_ALLOW_DEFAULT_IMEI(); |
| result = KAL_TRUE; |
| } |
| else |
| { |
| // ch2-ch1, last digit is 0 |
| nvram_imei_bcd[7] = nvram_imei_bcd[7] & 0x0f; |
| nvram_imei_bcd[8] = 0xff; |
| convert_to_digit((kal_uint8 *)nvram_imei_bcd, nvram_imei_ascii); |
| |
| sml_mini_trace("UE IMEI", nvram_imei_ascii, SML_IMEI_PRINT_LEN); |
| sml_mini_trace("BLOB IMEI", &imei[0], SML_TMO_MOVIAL_BLOB_IMEI_SIZE); |
| |
| if (kal_mem_cmp(&imei[0], nvram_imei_ascii, 15) == 0) |
| { |
| result = KAL_TRUE; |
| } |
| } |
| } |
| |
| MD_TRC_INFO_SML_TMO_RSU_IMEI_CHECK_RESULT(result); |
| return result; |
| } |
| |
| kal_bool sml_tmo_movial_ValidateTimeStamp(kal_uint8 *new_time_stamp, kal_uint8 source) |
| { |
| nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source]; |
| kal_uint16 length = 0; |
| kal_uint8 *blob_time_stamp; |
| kal_uint64 new_time = 0; |
| kal_uint64 blob_time = 0; |
| kal_uint8 i = 0; |
| |
| blob_time_stamp = (kal_uint8 *)(*p->getItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_TIME_STAMP, &length, source); |
| |
| for (i = 0; i < SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE-1; i++) |
| { |
| blob_time += blob_time_stamp[i]; |
| blob_time = (blob_time << 8); |
| |
| new_time += new_time_stamp[i]; |
| new_time = (new_time << 8); |
| } |
| |
| blob_time += blob_time_stamp[SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE-1]; |
| new_time += new_time_stamp[SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE-1]; |
| |
| if (new_time > blob_time) |
| { |
| return KAL_TRUE; |
| } |
| |
| return KAL_FALSE; |
| } |
| |
| kal_bool sml_tmo_movial_ValidateConfigData(sml_tmo_movial_sim_lock_context_struct *pBlob) |
| { |
| kal_uint16 cat_idx, data_idx; |
| kal_uint16 length = 0; |
| kal_uint8 *data = NULL; |
| |
| for (cat_idx = SML_TMO_MOVIAL_CAT_N ; cat_idx < SML_TMO_MOVIAL_CAT_SIZE ; cat_idx++) |
| { |
| switch (cat_idx) |
| { |
| case SML_TMO_MOVIAL_CAT_N: |
| length = pBlob->cat[cat_idx].num * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_N; |
| data = pBlob->code_cat_n; |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_NS: |
| length = pBlob->cat[cat_idx].num * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_NS; |
| data = pBlob->code_cat_ns; |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_SP: |
| length = pBlob->cat[cat_idx].num * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_SP; |
| data = pBlob->code_cat_sp; |
| break; |
| |
| default: |
| break; |
| } |
| |
| for (data_idx = 0; data_idx < length; data_idx++) |
| { |
| if (!((data[data_idx] >= RMMI_CHAR_0) && (data[data_idx] <= RMMI_CHAR_9)) && (data[data_idx] != RMMI_CHAR_F)) |
| { |
| return KAL_FALSE; |
| } |
| } |
| } |
| |
| return KAL_TRUE; |
| } |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmo_movial_ConstructBlob |
| * DESCRIPTION |
| * This function construct full size Bolb (internal NV structure) from a variant length Blob received in response message |
| * PARAMETERS |
| * IN *pObj |
| * OUT pLen |
| * RETURN |
| * kal_uint8 * construct data |
| * GLOBALS AFFECTED |
| * SMLTMMOBJ |
| *******************************************************************************/ |
| kal_uint8 *sml_tmo_movial_ConstructBlob(kal_uint8 *pObj, kal_uint16 slb_len, kal_uint8 *error_cause, kal_uint8 source) |
| { |
| kal_uint16 sizeM, sizeN, sizeP; |
| kal_uint16 length = 0; |
| kal_uint16 idx; |
| sml_tmo_movial_sim_lock_context_struct *pBlob; |
| kal_uint8 cat_idx = 0; |
| |
| MD_TRC_FUNC_SML_TMO_MOVIAL_CONSTRUCTBLOB(); |
| |
| pBlob = (sml_tmo_movial_sim_lock_context_struct *)get_ctrl_buffer(SML_TMO_MOVIAL_MAX_BLOB_SIZE); |
| kal_mem_set(pBlob, 0, SML_TMO_MOVIAL_MAX_BLOB_SIZE); |
| |
| /* major_version + minor_version + protection_algorithm + lock_operation */ |
| pBlob->major_version = pObj[length++]; |
| pBlob->minor_version = pObj[length++]; |
| pBlob->protection_algorithm = pObj[length++]; |
| pBlob->lock_operation = pObj[length++]; |
| |
| /* imei */ |
| kal_mem_cpy(pBlob->imei, &(pObj[length]), SML_TMO_MOVIAL_BLOB_IMEI_SIZE); |
| length += SML_TMO_MOVIAL_BLOB_IMEI_SIZE; |
| |
| /* time stamp */ |
| kal_mem_cpy(pBlob->time_stamp, &(pObj[length]), SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE); |
| length += SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE; |
| |
| /* Temporary unlock start timer */ |
| kal_mem_cpy(pBlob->start_time, &(pObj[length]), SML_TMO_MOVIAL_SIZE_OF_START_TIME); |
| length += SML_TMO_MOVIAL_SIZE_OF_START_TIME; |
| |
| /* Temporary unlock duration */ |
| kal_mem_cpy(pBlob->unlock_duration, &(pObj[length]), SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION); |
| length += SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION; |
| |
| /* length */ |
| kal_mem_cpy(pBlob->length, &(pObj[length]), SML_TMO_MOVIAL_BLOB_LENGTH_SIZE); |
| length += SML_TMO_MOVIAL_BLOB_LENGTH_SIZE; |
| |
| if (pBlob->protection_algorithm >= SML_TMO_MOVIAL_PROTECTION_SCHEME_SIZE) |
| { |
| *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC; |
| free_ctrl_buffer(pBlob); |
| return NULL; |
| } |
| |
| if (sml_tmo_movial_ValidateIMEI(pBlob->imei, KAL_FALSE, source) == KAL_FALSE) |
| { |
| *error_cause = SML_TMO_MOVIAL_SLB_ERR_IMEI_MISMATCH; |
| free_ctrl_buffer(pBlob); |
| return NULL; |
| } |
| |
| if (sml_tmo_movial_ValidateTimeStamp(pBlob->time_stamp, source) == KAL_FALSE) |
| { |
| *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC; |
| free_ctrl_buffer(pBlob); |
| return NULL; |
| } |
| |
| idx = length; |
| |
| for (cat_idx = SML_TMO_MOVIAL_CAT_N ; cat_idx < SML_TMO_MOVIAL_CAT_SIZE ; cat_idx++) |
| { |
| pBlob->cat[cat_idx].change_flag = pObj[idx++]; |
| |
| /* iteration_count, salt, hck */ |
| kal_mem_cpy(pBlob->key[cat_idx].iteration_count, &(pObj[idx]), SML_TMO_MOVIAL_BLOB_ITERATION_COUNT_SIZE); |
| idx += SML_TMO_MOVIAL_BLOB_ITERATION_COUNT_SIZE; |
| |
| kal_mem_cpy(pBlob->key[cat_idx].salt, &(pObj[idx]), SML_TMO_MOVIAL_BLOB_SALT_SIZE); |
| idx += SML_TMO_MOVIAL_BLOB_SALT_SIZE; |
| |
| kal_mem_cpy(pBlob->key[cat_idx].hck, &(pObj[idx]), SML_TMO_MOVIAL_BLOB_HCK_SIZE); |
| idx += SML_TMO_MOVIAL_BLOB_HCK_SIZE; |
| |
| /* check m,n,p */ |
| if (pObj[idx] > 0) |
| { |
| switch (cat_idx) |
| { |
| case SML_TMO_MOVIAL_CAT_N: |
| sizeM = pObj[idx] * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_N; |
| if (sizeM > SML_TMO_MOVIAL_BLOB_CAT_N_SIZE) |
| { |
| *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC; |
| free_ctrl_buffer(pBlob); |
| return NULL; |
| } |
| |
| pBlob->cat[cat_idx].num = pObj[idx++]; |
| kal_mem_cpy(pBlob->code_cat_n, &(pObj[idx]), sizeM); |
| idx += sizeM; |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_NS: |
| sizeN = pObj[idx] * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_NS; |
| if (sizeN > SML_TMO_MOVIAL_BLOB_CAT_NS_SIZE) |
| { |
| *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC; |
| free_ctrl_buffer(pBlob); |
| return NULL; |
| } |
| |
| pBlob->cat[cat_idx].num = pObj[idx++]; |
| kal_mem_cpy(pBlob->code_cat_ns, &(pObj[idx]), sizeN); |
| idx += sizeN; |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_SP: |
| sizeP = pObj[idx] * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_SP; |
| if (sizeP > SML_TMO_MOVIAL_BLOB_CAT_SP_SIZE) |
| { |
| *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC; |
| free_ctrl_buffer(pBlob); |
| return NULL; |
| } |
| |
| pBlob->cat[cat_idx].num = pObj[idx++]; |
| kal_mem_cpy(pBlob->code_cat_sp, &(pObj[idx]), sizeP); |
| idx += sizeP; |
| break; |
| |
| default: |
| break; |
| } |
| } |
| else /* m/n/p = 0 */ |
| { |
| /* memset ensures pBlob->cat[cat_idx].num set to 0 */ |
| idx += 1; |
| } |
| } |
| |
| if (sml_tmo_movial_ValidateConfigData(pBlob) == KAL_FALSE) |
| { |
| *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC; |
| free_ctrl_buffer(pBlob); |
| return NULL; |
| } |
| |
| kal_mem_cpy(pBlob->signature, &(pObj[idx]), SML_TMO_MOVIAL_BLOB_SIZE_OF_SIGNATURE); |
| |
| sml_Dump("constructed blob", (kal_uint8 *)pBlob, SML_TMO_MOVIAL_MAX_BLOB_SIZE); |
| |
| return (kal_uint8 *)pBlob; |
| } |
| |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmo_movial_ConstructSmlBlob |
| * DESCRIPTION |
| * This function constructs BLOB for NVRAM updating based on change_flag param |
| * change_flag == 0 => get cat / key / lock data from NVRAM |
| * change_flag == 1 => get cat / key / lock data from pObj |
| * PARAMETERS |
| * IN *pObj (constructed blob data) |
| * OUT pLen |
| * RETURN |
| * kal_uint8 * construct data |
| * GLOBALS AFFECTED |
| * SMLTMMOBJ |
| *******************************************************************************/ |
| kal_uint8 *sml_tmo_movial_ConstructSmlBlob(sml_tmo_movial_sim_lock_context_struct *pObj, kal_uint8 source) |
| { |
| sml_tmo_movial_sim_lock_context_struct *psmlBlob; |
| kal_uint8 cat_idx = 0; |
| kal_uint16 obj_len = 0; |
| nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source]; |
| sml_tmo_movial_blob_meta_struct *cat = NULL; |
| sml_tmo_movial_blob_key_struct *key = NULL; |
| kal_uint8 *pdata = NULL; |
| |
| psmlBlob = (sml_tmo_movial_sim_lock_context_struct *)get_ctrl_buffer(SML_TMO_MOVIAL_MAX_BLOB_SIZE); |
| kal_mem_set(psmlBlob, 0, SML_TMO_MOVIAL_MAX_BLOB_SIZE); |
| |
| /* major_version + minor_version + protection_algorithm + lock_operation */ |
| psmlBlob->major_version = pObj->major_version; |
| psmlBlob->minor_version= pObj->minor_version; |
| psmlBlob->protection_algorithm= pObj->protection_algorithm; |
| psmlBlob->lock_operation= pObj->lock_operation; |
| |
| /* imei */ |
| kal_mem_cpy(psmlBlob->imei, pObj->imei, SML_TMO_MOVIAL_BLOB_IMEI_SIZE); |
| |
| /* time stamp */ |
| kal_mem_cpy(psmlBlob->time_stamp, pObj->time_stamp, SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE); |
| |
| /* Temporary unlock start time */ |
| kal_mem_cpy(psmlBlob->start_time, pObj->start_time, SML_TMO_MOVIAL_SIZE_OF_START_TIME); |
| |
| /* Temporary unlock duration */ |
| kal_mem_cpy(psmlBlob->unlock_duration, pObj->unlock_duration, SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION); |
| |
| /* length */ |
| kal_mem_cpy(psmlBlob->length, pObj->length, SML_TMO_MOVIAL_BLOB_LENGTH_SIZE); |
| |
| for (cat_idx = SML_TMO_MOVIAL_CAT_N ; cat_idx < SML_TMO_MOVIAL_CAT_SIZE ; cat_idx++) |
| { |
| /* existing configuration should be used if change_flag=0 */ |
| if (pObj->cat[cat_idx].change_flag == 0 || SML_TMO_MOVIAL_STATE_TEMPORARY_UNLOCK == psmlBlob->lock_operation) |
| { |
| cat = (sml_tmo_movial_blob_meta_struct *) (*p->getItem)(cat_idx, SML_TMO_MOVIAL_CAT_META, &obj_len, source); |
| key = (sml_tmo_movial_blob_key_struct *) (*p->getItem)(cat_idx, SML_TMO_MOVIAL_CAT_KEY, &obj_len, source); |
| pdata = (kal_uint8 *) (*p->getItem)(cat_idx, SML_TMO_MOVIAL_CAT_CODE, &obj_len, source); |
| } |
| else |
| { |
| cat = &(pObj->cat[cat_idx]); |
| key = &(pObj->key[cat_idx]); |
| |
| switch (cat_idx) |
| { |
| case SML_TMO_MOVIAL_CAT_N: |
| pdata = pObj->code_cat_n; |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_NS: |
| pdata = pObj->code_cat_ns; |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_SP: |
| pdata = pObj->code_cat_sp; |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| kal_mem_cpy(&(psmlBlob->cat[cat_idx]), cat, sizeof(sml_tmo_movial_blob_meta_struct)); |
| kal_mem_cpy(&(psmlBlob->key[cat_idx]), key, sizeof(sml_tmo_movial_blob_key_struct)); |
| |
| switch (cat_idx) |
| { |
| case SML_TMO_MOVIAL_CAT_N: |
| kal_mem_cpy(psmlBlob->code_cat_n, pdata, SML_TMO_MOVIAL_BLOB_CAT_N_SIZE); |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_NS: |
| kal_mem_cpy(psmlBlob->code_cat_ns, pdata, SML_TMO_MOVIAL_BLOB_CAT_NS_SIZE); |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_SP: |
| kal_mem_cpy(psmlBlob->code_cat_sp, pdata, SML_TMO_MOVIAL_BLOB_CAT_SP_SIZE); |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| kal_mem_cpy(psmlBlob->signature, pObj->signature, SML_TMO_MOVIAL_BLOB_SIZE_OF_SIGNATURE); |
| |
| sml_Dump("constructed sml blob", (kal_uint8 *)psmlBlob, SML_TMO_MOVIAL_MAX_BLOB_SIZE); |
| |
| return (kal_uint8 *)psmlBlob; |
| } |
| |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmo_movial_ReconstructBlob |
| * DESCRIPTION |
| * This function restores the original message raw data from constructed internal blob structure |
| * (used for signature verification) |
| * PARAMETERS |
| * IN *pObj (constructed blob data) |
| * OUT pLen, length of returned raw data |
| * OUT error_cause |
| * RETURN |
| * kal_uint8 * raw data |
| * GLOBALS AFFECTED |
| * N/A |
| *******************************************************************************/ |
| kal_uint8 *sml_tmo_movial_ReconstructBlob(sml_tmo_movial_sim_lock_context_struct *pObj, kal_uint32 *pLen, kal_uint8 *error_cause) |
| { |
| kal_uint8 *pData = NULL; |
| kal_uint32 blob_len, data_len; |
| kal_uint32 sizeM, sizeN, sizeP; |
| kal_uint32 len; |
| kal_uint8 cat_idx; |
| |
| blob_len = sml_GetCount(&(pObj->length[0])); |
| sizeM = pObj->cat[SML_TMO_MOVIAL_CAT_N].num * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_N; |
| sizeN = pObj->cat[SML_TMO_MOVIAL_CAT_NS].num * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_NS; |
| sizeP = pObj->cat[SML_TMO_MOVIAL_CAT_SP].num * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_SP; |
| |
| /* RSA-PSS scheme */ |
| if (pObj->protection_algorithm == 1) |
| { |
| data_len = blob_len - SML_TMO_MOVIAL_BLOB_SIZE_OF_SIGNATURE; |
| } |
| else |
| { |
| *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC; |
| return NULL; |
| } |
| |
| pData = (kal_uint8 *)get_ctrl_buffer(data_len); |
| |
| if (NULL == pData) |
| { |
| *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC; |
| return NULL; |
| } |
| /* major_version + minor_version + protection_algorithm + lock_operation */ |
| len = 0; |
| |
| pData[len++] = pObj->major_version; |
| pData[len++] = pObj->minor_version; |
| pData[len++] = pObj->protection_algorithm; |
| pData[len++] = pObj->lock_operation; |
| |
| /* imei */ |
| kal_mem_cpy((pData+len), pObj->imei, SML_TMO_MOVIAL_BLOB_IMEI_SIZE); |
| len += SML_TMO_MOVIAL_BLOB_IMEI_SIZE; |
| |
| /* time stamp */ |
| kal_mem_cpy((pData+len), pObj->time_stamp, SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE); |
| len += SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE; |
| |
| /* temporary unlock start time */ |
| kal_mem_cpy((pData+len), pObj->start_time, SML_TMO_MOVIAL_SIZE_OF_START_TIME); |
| len += SML_TMO_MOVIAL_SIZE_OF_START_TIME; |
| |
| /* temporary unlock duration */ |
| kal_mem_cpy((pData+len), pObj->unlock_duration, SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION); |
| len += SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION; |
| |
| /* length */ |
| kal_mem_cpy((pData+len), pObj->length, SML_TMO_MOVIAL_BLOB_LENGTH_SIZE); |
| len += SML_TMO_MOVIAL_BLOB_LENGTH_SIZE; |
| |
| for (cat_idx = SML_TMO_MOVIAL_CAT_N ; cat_idx < SML_TMO_MOVIAL_CAT_SIZE; cat_idx++) |
| { |
| pData[len++] = pObj->cat[cat_idx].change_flag; |
| |
| kal_mem_cpy((pData+len), (kal_uint8 *)&(pObj->key[cat_idx].iteration_count[0]), SML_TMO_MOVIAL_BLOB_ITERATION_COUNT_SIZE); |
| len += SML_TMO_MOVIAL_BLOB_ITERATION_COUNT_SIZE; |
| |
| kal_mem_cpy((pData+len), (kal_uint8 *)&(pObj->key[cat_idx].salt[0]), SML_TMO_MOVIAL_BLOB_SALT_SIZE); |
| len += SML_TMO_MOVIAL_BLOB_SALT_SIZE; |
| |
| kal_mem_cpy((pData+len), (kal_uint8 *)&(pObj->key[cat_idx].hck[0]), SML_TMO_MOVIAL_BLOB_HCK_SIZE); |
| len += SML_TMO_MOVIAL_BLOB_HCK_SIZE; |
| |
| pData[len++] = pObj->cat[cat_idx].num; |
| |
| switch (cat_idx) |
| { |
| case SML_TMO_MOVIAL_CAT_N: |
| kal_mem_cpy((pData+len), (kal_uint8 *)&(pObj->code_cat_n[0]), sizeM); |
| len += sizeM; |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_NS: |
| kal_mem_cpy((pData+len), (kal_uint8 *)&(pObj->code_cat_ns[0]), sizeN); |
| len += sizeN; |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_SP: |
| kal_mem_cpy((pData+len), (kal_uint8 *)&(pObj->code_cat_sp[0]), sizeP); |
| len += sizeP; |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| *pLen = len; |
| sml_Dump("re-construct blob", pData, len); |
| |
| return pData; |
| } |
| |
| kal_bool sml_tmo_movial_checkValidity(void *pObj, kal_uint8 source, kal_uint8 *error_cause) |
| { |
| sml_tmo_movial_sim_lock_context_struct *pSmlObj = (sml_tmo_movial_sim_lock_context_struct *) pObj; |
| kal_uint8 *pData = NULL; |
| kal_bool result = KAL_FALSE; |
| kal_uint32 data_len; |
| |
| if (sml_tmo_movial_ValidateIMEI(pSmlObj->imei, KAL_FALSE, source) == KAL_FALSE) |
| { |
| *error_cause = SML_TMO_MOVIAL_SLB_ERR_IMEI_MISMATCH; |
| return KAL_FALSE; |
| } |
| |
| if (pSmlObj == NULL) |
| { |
| *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC; |
| return KAL_FALSE; |
| } |
| |
| #ifdef UNIT_TEST |
| *error_cause = SML_TMO_MOVIAL_SLB_ERR_SUCCESS; |
| return KAL_TRUE; |
| #endif /* UNIT_TEST */ |
| |
| pData = sml_tmo_movial_ReconstructBlob(pSmlObj, &data_len, error_cause); |
| |
| if (pData == NULL) |
| { |
| *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC; |
| return KAL_FALSE; |
| } |
| |
| if (pSmlObj->protection_algorithm == SML_TMO_MOVIAL_PROTECTION_SCHEME_RSA2048) |
| { |
| TYPE_CUST_CHL_KEY key_handle = CUST_TM_PUB_KEY2; |
| t_cust_chl_asym_key key; |
| kal_uint32 ret; |
| kal_uint8 key_index = sbp_query_md_feature_data_by_ps(SBP_TMO_MOVIAL_SELECT_KEY_SET, source); |
| |
| custom_tmo_movial_rsu_get_pub_key_handle(key_index, NULL, &key_handle); |
| ret = CustCHL_Get_Asym_Key(key_handle, &key); |
| if (ret == CUST_CHL_ERROR_NONE) |
| { |
| ret = CustCHL_Verify_PSS_Signature(CUST_CHL_ALG_RSA_PSS_SHA256, pData, data_len, |
| &pSmlObj->signature[0], &key); |
| |
| MD_TRC_INFO_SMU_RSA_PSS_VERIFY_SIGNATURE_CUST(ret); |
| } |
| result = (ret == CUST_CHL_ERROR_NONE) ? KAL_TRUE : KAL_FALSE; |
| } |
| else |
| { |
| result = KAL_FALSE; |
| } |
| |
| if (KAL_TRUE == result) |
| { |
| *error_cause = SML_TMO_MOVIAL_SLB_ERR_SUCCESS; |
| } |
| else |
| { |
| *error_cause = SML_TMO_MOVIAL_SLB_ERR_VERIFY_FAIL; |
| } |
| |
| free_ctrl_buffer(pData); |
| |
| return result; |
| } |
| |
| void sml_tmo_movial_Load(void *pLid, kal_uint8 source) |
| { |
| nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source]; |
| |
| /* Clean the old ones */ |
| (*p->destory)(source); |
| |
| /* Load the new one */ |
| (*p->give)(pLid, source); |
| |
| } |
| |
| void sml_tmo_movial_FirstLoad(void *pLid, kal_uint8 source) |
| { |
| nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source]; |
| nvram_sml_tmo_movial_sim_lock_context_struct *pSmlObj = NULL; |
| #ifdef __TMO_RSU_OTP__ |
| kal_bool is_default_blob = KAL_FALSE; |
| #endif /* __TMO_RSU_OTP__ */ |
| |
| pSmlObj = (nvram_sml_tmo_movial_sim_lock_context_struct *) pLid; |
| // Allow UE default IMEI (e.g. under factory procedure) in validate check |
| if (KAL_FALSE == sml_tmo_movial_ValidateIMEI(pSmlObj->imei, KAL_TRUE, source)) |
| { |
| #ifdef __TMO_RSU_OTP__ |
| is_default_blob = custom_check_is_default_tmo_blob(&(pSmlObj->imei[0])); |
| if (KAL_TRUE == is_default_blob) |
| { |
| kal_uint8 imei_bcd[8+1] = {0}; |
| kal_uint8 rec_id = 1 + l4c_gemini_get_actual_sim_id(source); |
| |
| if (nvram_get_imei_value(8, imei_bcd, rec_id) == KAL_TRUE) |
| { |
| kal_uint8 imei_ascii[16 + 1] = {0}; |
| imei_bcd[7] = imei_bcd[7] & 0x0f; |
| imei_bcd[8] = 0xff; |
| convert_to_digit((kal_uint8 *)imei_bcd, imei_ascii); |
| MD_TRC_INFO_SML_TMO_RSU_COPY_IMEI(); |
| kal_mem_cpy(&(pSmlObj->imei[0]), imei_ascii, SML_TMO_MOVIAL_BLOB_IMEI_SIZE); |
| } |
| } |
| else |
| #endif /* __TMO_RSU_OTP__ */ |
| { |
| /* This can hit when BLOB/device IMEI is corrupted or hacked, |
| * hence ASSERT |
| */ |
| MD_TRC_WARNING_SML_CHECK_IMEI_FAILED(); |
| // ASSERT(0); |
| } |
| } |
| |
| /* Clean the old ones */ |
| (*p->destory)(source); |
| |
| /* Load the new one */ |
| (*p->give)((void *)pSmlObj, source); |
| |
| #ifdef __TMO_RSU_OTP__ |
| if (KAL_TRUE == is_default_blob) |
| { |
| smu_nvram_write(NVRAM_EF_L4_SML_TMO_MOVIAL_SIM_LOCK_LID, |
| SML_TMO_MOVIAL_NVRAM_ACCESS_ID_UPDATE_SLB, KAL_FALSE); |
| } |
| #endif /* __TMO_RSU_OTP__ */ |
| |
| return; |
| } |
| |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmo_movial_Save |
| * DESCRIPTION |
| * This function saves the SML obj to NVRAM LID |
| * PARAMETERS |
| * OUT pLid |
| * RETURN |
| * kal_uint16 Obj size |
| * GLOBALS AFFECTED |
| * SMLTMMOBJ |
| *******************************************************************************/ |
| kal_uint16 sml_tmo_movial_Save(void *pLid, kal_uint8 source) |
| { |
| nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source]; |
| |
| kal_uint16 length = sizeof(sml_tmo_movial_sim_lock_context_struct); |
| |
| (*p->take)(pLid, source); |
| |
| return length; |
| } |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmo_movial_CheckTempUnlock |
| * DESCRIPTION |
| * This method is to check if temporary unlock expires |
| * PARAMETERS |
| * IN source |
| * RETURN |
| * TRUE Temporary unlock expires |
| * FALSE Temporary unlock does not expire |
| * GLOBALS AFFECTED |
| * SMLTMMOBJ |
| *******************************************************************************/ |
| kal_bool sml_tmo_movial_CheckTempUnlock(kal_uint8 source) |
| { |
| nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source]; |
| kal_uint8 *lock_operation, *unlock_duration; |
| kal_uint16 length; |
| kal_uint32 duration_seconds = 0; |
| kal_uint8 i; |
| |
| lock_operation = (kal_uint8 *)(*p->getItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_LOCK_OPERATION, &length, source); |
| unlock_duration = (kal_uint8 *)(*p->getItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_UNLOCK_DURATION, &length, source); |
| |
| for (i = 0; i < SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION-1; i++) |
| { |
| duration_seconds += unlock_duration[i]; |
| duration_seconds = (duration_seconds << 8); |
| } |
| duration_seconds += unlock_duration[SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION-1]; |
| |
| MD_TRC_INFO_SML_CHECK_TEMP_UNLOCK(sml_tmo_movial_seconds_to_expire, duration_seconds); |
| |
| if ((sml_tmo_movial_seconds_to_expire + (SML_TMO_MOVIAL_TIMEOUT_PERIODIC_CHECK/KAL_TICKS_1_SEC)) >= duration_seconds) |
| { |
| *lock_operation = SML_TMO_MOVIAL_STATE_PERMANENT_LOCK; |
| // Should reset SLB/NVRAM in following action |
| return KAL_TRUE; |
| } |
| else |
| { |
| sml_tmo_movial_seconds_to_expire += (SML_TMO_MOVIAL_TIMEOUT_PERIODIC_CHECK/KAL_TICKS_1_SEC); |
| (*p->putItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_UNLOCK_TIME_COUNTER, &sml_tmo_movial_seconds_to_expire, &length, source); |
| // Should write back to NVRAM in following action |
| return KAL_FALSE; |
| } |
| } |
| |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmo_movial_Catcode |
| * DESCRIPTION |
| * This function is used to compose the code of each category |
| * PARAMETERS |
| * IN cat |
| * IN *imsi |
| * IN *gid1 |
| * IN mnc_len |
| * OUT *code |
| * RETURN |
| * kal_uint8 code length |
| * GLOBALS AFFECTED |
| * NONE |
| *******************************************************************************/ |
| kal_uint8 sml_tmo_movial_Catcode( sml_tmo_movial_cat_enum cat, |
| kal_uint8 *imsi, |
| kal_uint8 *gid1, |
| kal_uint8 mnc_len, |
| kal_uint8 *code) |
| { |
| if(mnc_len == 3) |
| { |
| code[0] = ((imsi[1] & 0xF0) >> 4) + RMMI_CHAR_0; |
| code[1] = (imsi[2] & 0x0F) + RMMI_CHAR_0; |
| code[2] = ((imsi[2] & 0xF0) >> 4) + RMMI_CHAR_0; |
| code[3] = (imsi[3] & 0x0F) + RMMI_CHAR_0; |
| code[4] = ((imsi[3] & 0xF0) >> 4) + RMMI_CHAR_0; |
| code[5] = (imsi[4] & 0x0F) + RMMI_CHAR_0; |
| code[6] = ((imsi[4] & 0xF0) >> 4) + RMMI_CHAR_0; |
| code[7] = (imsi[5] & 0x0F) + RMMI_CHAR_0; |
| } |
| else |
| { |
| code[0] = ((imsi[1] & 0xF0) >> 4) + RMMI_CHAR_0; |
| code[1] = (imsi[2] & 0x0F) + RMMI_CHAR_0; |
| code[2] = ((imsi[2] & 0xF0) >> 4) + RMMI_CHAR_0; |
| code[3] = (imsi[3] & 0x0F) + RMMI_CHAR_0; |
| code[4] = ((imsi[3] & 0xF0) >> 4) + RMMI_CHAR_0; |
| code[5] = RMMI_CHAR_F; // MNC length is 2, so the 3rd digit will be 'F' |
| code[6] = (imsi[4] & 0x0F) + RMMI_CHAR_0; |
| code[7] = ((imsi[4] & 0xF0) >> 4) + RMMI_CHAR_0; |
| } |
| |
| switch(cat) |
| { |
| case SML_TMO_MOVIAL_CAT_N: |
| return SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_N; |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_NS: |
| return SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_NS; |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_SP: |
| if(gid1 != NULL) |
| { |
| code[6] = gid1[0]; // + RMMI_CHAR_0 |
| return SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_SP; |
| } |
| break; |
| |
| default: |
| break; |
| } |
| |
| return 0; |
| } |
| |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmo_movial_GetCode |
| * DESCRIPTION |
| * This function is used to compose the code of each category whether |
| * mnc length is 2 or 3 |
| * PARAMETERS |
| * cat [IN] category of the SIM-ME-Lock |
| * imsi [IN] imsi of the code source |
| * gid1 [IN] gid1 of the code source |
| * sim_mnc_len [IN] the mnc length decided by SIM |
| * pdata [IN] the saved code for comparing |
| * code [OUT] the composed code according to all input parameters |
| * |
| * RETURN |
| * kal_uint8 |
| * GLOBALS AFFECTED |
| * SMLTMMOBJ |
| *******************************************************************************/ |
| kal_uint8 sml_tmo_movial_GetCode( sml_tmo_movial_cat_enum cat, |
| kal_uint8 * imsi, |
| kal_uint8 * gid1, |
| kal_uint8 sim_mnc_len, |
| kal_uint8 * pdata, |
| kal_uint8 * code) |
| { |
| kal_uint8 mnc_len=0; |
| |
| if (SML_MNC_LENGTH_NEST == 1) |
| { |
| mnc_len = sim_mnc_len; |
| } |
| else |
| { |
| if((*(pdata+5)) == 0x46 /* 'F' */) |
| { |
| mnc_len = 2; |
| } |
| else |
| { |
| mnc_len = 3; |
| } |
| } |
| |
| return sml_tmo_movial_Catcode(cat, imsi, gid1, mnc_len, code); |
| } |
| |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmo_movial_Check |
| * DESCRIPTION |
| * This function is used to check if the code is in the Pass list |
| * PARAMETERS |
| * IN cat |
| * IN *imsi |
| * IN *gid1 |
| * IN sim_mnc_len |
| * IN source |
| * RETURN |
| * kal_bool |
| * GLOBALS AFFECTED |
| * SMLTMMOBJ |
| *******************************************************************************/ |
| kal_bool sml_tmo_movial_Check( sml_tmo_movial_cat_enum cat, // category |
| kal_uint8 *imsi, // 9 bytes array, read from SIM, mandatory file |
| kal_uint8 *gid1, // 20 bytes array, read from SIM, NULL means gid1 invalid(file not exist) |
| kal_uint8 sim_mnc_len, // MNC length, read from SIM |
| kal_uint8 source) // 0:SIM1, 1:SIM2 |
| { |
| nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source]; |
| sml_tmo_movial_blob_meta_struct *meta = NULL; |
| kal_uint8 *pdata = NULL; |
| kal_uint8 idx = 0; |
| kal_uint16 length = 0, offset = 0; |
| kal_bool result = KAL_FALSE; |
| kal_uint8 code_len = 0; |
| kal_uint8 code[10] = {0x00}; |
| kal_uint8 size_of_cat = 0; |
| |
| meta = (sml_tmo_movial_blob_meta_struct *) (*p->getItem)(cat, SML_TMO_MOVIAL_CAT_META, &length, source); |
| pdata = (kal_uint8 *) (*p->getItem)(cat, SML_TMO_MOVIAL_CAT_CODE, &length, source); |
| |
| |
| if ((meta->cat_lock == SML_TMO_MOVIAL_CAT_UNLOCKED) || (meta->num == 0)) |
| { |
| return KAL_TRUE; |
| } |
| |
| switch(cat) |
| { |
| case SML_TMO_MOVIAL_CAT_N: |
| { |
| size_of_cat = SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_N; |
| break; |
| } |
| case SML_TMO_MOVIAL_CAT_NS: |
| { |
| size_of_cat = SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_NS; |
| break; |
| } |
| case SML_TMO_MOVIAL_CAT_SP: |
| { |
| size_of_cat = SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_SP; |
| break; |
| } |
| default: |
| break; |
| } |
| |
| for (idx = 0; idx < meta->num; idx++) |
| { |
| offset = idx * size_of_cat; |
| code_len = sml_tmo_movial_GetCode(cat, |
| imsi, |
| gid1, |
| sim_mnc_len, |
| (pdata+offset), |
| code); |
| |
| if (size_of_cat == code_len) |
| { |
| if (kal_mem_cmp(code, (pdata+offset), code_len) == 0) |
| { |
| result = KAL_TRUE; |
| break; |
| } |
| } |
| } |
| |
| return result; |
| } |
| |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmo_movial_UpdateNwTimeAndCheckTempLock |
| * DESCRIPTION |
| * This method is to update newtork time and check if temporary lock expires |
| * PARAMETERS |
| * IN source |
| * IN nw_time_zone |
| * IN nw_time |
| * RETURN |
| * TRUE Temporary unlock expires |
| * FALSE Temporary unlock does not expire |
| * GLOBALS AFFECTED |
| * SMLOBJ |
| *******************************************************************************/ |
| kal_bool sml_tmo_movial_UpdateNwTimeAndCheckTempLock(kal_uint8 source, kal_uint8 nw_time_zone, nw_time_zone_time_struct *nw_time) |
| { |
| nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source]; |
| kal_uint8 *start_time, *unlock_duration; |
| kal_uint8 *lock_operation = NULL; |
| kal_uint16 length; |
| kal_uint32 current_seconds = 0; |
| kal_uint64 start_seconds = 0; |
| kal_uint32 start_seconds_u32 = 0; |
| kal_uint32 duration_seconds = 0; |
| kal_uint8 i; |
| |
| lock_operation = (kal_uint8 *)(*p->getItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_LOCK_OPERATION, &length, source); |
| start_time = (kal_uint8 *)(*p->getItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_START_TIME, &length, source); |
| unlock_duration = (kal_uint8 *)(*p->getItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_UNLOCK_DURATION, &length, source); |
| |
| if (*lock_operation != SML_TMO_MOVIAL_STATE_TEMPORARY_UNLOCK) |
| { |
| return KAL_FALSE; |
| } |
| |
| /* calculate start time and duration in seconds */ |
| start_seconds = 0; |
| for (i = 0; i < SML_TMO_MOVIAL_SIZE_OF_START_TIME-1; i++) |
| { |
| start_seconds += start_time[i]; |
| start_seconds = (start_seconds << 8); |
| } |
| start_seconds += start_time[SML_TMO_MOVIAL_SIZE_OF_START_TIME-1]; |
| start_seconds /= 1000; /* from milliseconds to seconds */ |
| |
| start_seconds_u32 = (kal_uint32)start_seconds; |
| |
| duration_seconds = 0; |
| for (i = 0; i < SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION-1; i++) |
| { |
| duration_seconds += unlock_duration[i]; |
| duration_seconds = (duration_seconds << 8); |
| } |
| duration_seconds += unlock_duration[SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION-1]; |
| |
| /* calculate current time in seconds */ |
| current_seconds = sml_rsu_nwTimeToSeconds(nw_time_zone, nw_time); |
| |
| MD_TRC_INFO_SML_TEMP_UNLOCK_TIME(start_seconds_u32, duration_seconds, current_seconds); |
| |
| if (current_seconds >= (start_seconds_u32 + duration_seconds)) |
| { |
| MD_TRC_INFO_SML_NW_TIME_EXPIRED(); |
| return KAL_TRUE; |
| } |
| else |
| { |
| /* update unlock time for power off accuracy: start ---> unlock time ---> NITZ ---> power off/on ---> end */ |
| sml_tmo_movial_seconds_to_expire = current_seconds - start_seconds_u32; |
| (*p->putItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_UNLOCK_TIME_COUNTER, &sml_tmo_movial_seconds_to_expire, &length, source); |
| smu_nvram_write(NVRAM_EF_L4_SML_TMO_MOVIAL_SIM_LOCK_LID, SML_TMO_MOVIAL_NVRAM_ACCESS_ID_UNLOCK_EXPIRE, KAL_FALSE); |
| |
| return KAL_FALSE; |
| } |
| } |
| |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmo_movial_Verify |
| * DESCRIPTION |
| * This function is used to verify the SML lock keys |
| * PARAMETERS |
| * void |
| * RETURN |
| * kal_bool result |
| * GLOBALS AFFECTED |
| * SMLTMMOBJ |
| *******************************************************************************/ |
| kal_bool sml_tmo_movial_Verify(sml_tmo_movial_cat_enum cat, |
| kal_uint8 * key, |
| kal_uint8 len, |
| kal_uint8 source) |
| { |
| nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source]; |
| sml_tmo_movial_blob_key_struct *catkey = NULL; |
| sml_tmo_movial_blob_meta_struct *meta = NULL; |
| kal_bool result = KAL_FALSE; |
| kal_uint16 length = 0; |
| kal_uint16 plength = 0; |
| kal_uint8 i = 0; |
| kal_uint32 blob_iter_count = 0; |
| |
| catkey = (sml_tmo_movial_blob_key_struct *) (*p->getItem)(cat, SML_TMO_MOVIAL_CAT_KEY, &length, source); |
| meta = (sml_tmo_movial_blob_meta_struct *) (*p->getItem)(cat, SML_TMO_MOVIAL_CAT_META, &plength, source); |
| |
| for (i = 0; i < SML_TMO_MOVIAL_BLOB_ITERATION_COUNT_SIZE-1; i++) |
| { |
| blob_iter_count += catkey->iteration_count[i]; |
| blob_iter_count = (blob_iter_count << 8); |
| } |
| blob_iter_count += catkey->iteration_count[SML_TMO_MOVIAL_BLOB_ITERATION_COUNT_SIZE-1]; |
| |
| if (blob_iter_count != 0) /* blob has valid key data */ |
| { |
| kal_uint32 verify_result = 0; |
| |
| verify_result = cust_sec_hck_verify(TYPE_HCK_PBKDF2_HMAC_SHA256_SALT128, |
| (kal_char *)key, (kal_uint32)len, |
| catkey->salt, |
| blob_iter_count, |
| catkey->hck); |
| |
| if (verify_result == ERR_SEC_CHECK_HCK_SUCCESS) |
| { |
| result = KAL_TRUE; |
| } |
| } |
| |
| if (result == KAL_TRUE) |
| { |
| MD_TRC_INFO_SML_KEY_VERIFY_PASS_INFO_CUST(); |
| |
| /* Local unlock success; Unlock device permanently */ |
| meta->cat_lock = SML_TMO_MOVIAL_CAT_UNLOCKED; |
| smu_nvram_write(NVRAM_EF_L4_SML_TMO_MOVIAL_SIM_LOCK_LID, SML_TMO_MOVIAL_NVRAM_ACCESS_ID_UPDATE_CAT_LOCK, KAL_FALSE); |
| } |
| else |
| { |
| MD_TRC_INFO_SML_KEY_VERIFY_FAIL_INFO_CUST(); |
| } |
| |
| return result; |
| } |
| |
| |
| kal_uint8 sml_tmo_movial_update_slb(void *blob, kal_uint8 source) |
| { |
| kal_uint8 *psmlBlob = NULL; |
| kal_uint8 error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC; |
| sml_tmo_movial_sim_lock_context_struct *pBlob = (sml_tmo_movial_sim_lock_context_struct *)blob; |
| |
| if (NULL == pBlob) |
| { |
| MD_TRC_INFO_SML_TMO_RSU_EMPTY_BLOB(); |
| return SML_TMO_MOVIAL_SLB_ERR_BLOB_TOO_SHORT; |
| } |
| |
| if (KAL_FALSE == sml_tmo_movial_checkValidity(pBlob, source, &error_cause)) |
| { |
| MD_TRC_INFO_SML_TMO_RSU_BLOB_VALIDITY_FAIL(); |
| return error_cause; |
| } |
| |
| psmlBlob = sml_tmo_movial_ConstructSmlBlob((sml_tmo_movial_sim_lock_context_struct *)pBlob, source); |
| |
| if (NULL != psmlBlob) |
| { |
| sml_tmo_movial_Load(psmlBlob, source); |
| free_ctrl_buffer(psmlBlob); |
| error_cause = SML_TMO_MOVIAL_SLB_ERR_SUCCESS; |
| } |
| |
| return error_cause; |
| } |
| |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmm_GetLockState |
| * DESCRIPTION |
| * This method is used to get SLB lock state |
| * PARAMETERS |
| * OUT lock state |
| * IN source |
| * RETURN |
| * void |
| * GLOBALS AFFECTED |
| * none |
| *******************************************************************************/ |
| void sml_tmm_GetLockState(kal_uint8 *lock_state, kal_uint8 source) |
| { |
| nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source]; |
| kal_uint16 length; |
| kal_uint8 *slb_state; |
| |
| slb_state = (kal_uint8 *)(*p->getItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_LOCK_OPERATION, &length, source); |
| |
| kal_mem_cpy(lock_state, slb_state, 1); |
| } |
| |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmm_GetUnlockTimeLeft |
| * DESCRIPTION |
| * This method is used to get SLB unlock time left in seconds |
| * PARAMETERS |
| * IN source |
| * RETURN |
| * unlock time left |
| * GLOBALS AFFECTED |
| * none |
| *******************************************************************************/ |
| kal_uint32 sml_tmm_GetUnlockTimeLeft(kal_uint8 source) |
| { |
| nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source]; |
| kal_uint16 length; |
| kal_uint8 *slb_end_time; |
| kal_uint32 duration_seconds = 0; |
| kal_uint8 i; |
| |
| slb_end_time = (kal_uint8 *)(*p->getItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_UNLOCK_DURATION, &length, source); |
| |
| for (i = 0; i < (SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION - 1); i++) |
| { |
| duration_seconds += slb_end_time[i]; |
| duration_seconds = (duration_seconds << 8); |
| } |
| duration_seconds += slb_end_time[SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION - 1]; |
| |
| MD_TRC_INFO_SML_TMO_RSU_GET_UNLOCK_TIME_LEFT(duration_seconds, sml_tmo_movial_seconds_to_expire); |
| |
| if (sml_tmo_movial_seconds_to_expire >= duration_seconds) |
| { |
| return 0; |
| } |
| else |
| { |
| return (duration_seconds - sml_tmo_movial_seconds_to_expire); |
| } |
| } |
| |
| |
| /******************************************************************************* |
| * FUNCTION |
| * sml_tmo_movial_ConstructFirstBlob |
| * DESCRIPTION |
| * This function construct full size Bolb (internal NV structure) from a variant length Blob received from AP |
| * PARAMETERS |
| * IN *pObj |
| * OUT pLen |
| * RETURN |
| * kal_uint8 * construct data |
| * GLOBALS AFFECTED |
| * SMLTMMOBJ |
| *******************************************************************************/ |
| kal_uint8 *sml_tmo_movial_ConstructFirstBlob(kal_uint8 *pObj, kal_uint16 slb_len, kal_uint8 source) |
| { |
| kal_uint16 sizeM, sizeN, sizeP; |
| kal_uint16 length = 0; |
| kal_uint16 idx; |
| sml_tmo_movial_sim_lock_context_struct *pBlob; |
| kal_uint8 cat_idx = 0; |
| |
| MD_TRC_FUNC_SML_TMO_MOVIAL_CONSTRUCTFIRSTBLOB(); |
| |
| pBlob = (sml_tmo_movial_sim_lock_context_struct *)get_ctrl_buffer(SML_TMO_MOVIAL_MAX_BLOB_SIZE); |
| kal_mem_set(pBlob, 0, SML_TMO_MOVIAL_MAX_BLOB_SIZE); |
| |
| /* major_version + minor_version + protection_algorithm + lock_operation */ |
| pBlob->major_version = pObj[length++]; |
| pBlob->minor_version = pObj[length++]; |
| pBlob->protection_algorithm = pObj[length++]; |
| pBlob->lock_operation = pObj[length++]; |
| |
| /* imei */ |
| kal_mem_cpy(pBlob->imei, &(pObj[length]), SML_TMO_MOVIAL_BLOB_IMEI_SIZE); |
| length += SML_TMO_MOVIAL_BLOB_IMEI_SIZE; |
| |
| /* time stamp */ |
| kal_mem_cpy(pBlob->time_stamp, &(pObj[length]), SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE); |
| length += SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE; |
| |
| /* Temporary unlock start timer */ |
| kal_mem_cpy(pBlob->start_time, &(pObj[length]), SML_TMO_MOVIAL_SIZE_OF_START_TIME); |
| length += SML_TMO_MOVIAL_SIZE_OF_START_TIME; |
| |
| /* Temporary unlock duration */ |
| kal_mem_cpy(pBlob->unlock_duration, &(pObj[length]), SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION); |
| length += SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION; |
| |
| /* length */ |
| kal_mem_cpy(pBlob->length, &(pObj[length]), SML_TMO_MOVIAL_BLOB_LENGTH_SIZE); |
| length += SML_TMO_MOVIAL_BLOB_LENGTH_SIZE; |
| |
| if (pBlob->protection_algorithm >= SML_TMO_MOVIAL_PROTECTION_SCHEME_SIZE) |
| { |
| free_ctrl_buffer(pBlob); |
| return NULL; |
| } |
| |
| if (sml_tmo_movial_ValidateIMEI(pBlob->imei, KAL_FALSE, source) == KAL_FALSE) |
| { |
| MD_TRC_WARNING_SML_CHECK_IMEI_FAILED(); |
| } |
| |
| idx = length; |
| |
| for (cat_idx = SML_TMO_MOVIAL_CAT_N ; cat_idx < SML_TMO_MOVIAL_CAT_SIZE ; cat_idx++) |
| { |
| pBlob->cat[cat_idx].change_flag = pObj[idx++]; |
| |
| /* iteration_count, salt, hck */ |
| kal_mem_cpy(pBlob->key[cat_idx].iteration_count, &(pObj[idx]), SML_TMO_MOVIAL_BLOB_ITERATION_COUNT_SIZE); |
| idx += SML_TMO_MOVIAL_BLOB_ITERATION_COUNT_SIZE; |
| |
| kal_mem_cpy(pBlob->key[cat_idx].salt, &(pObj[idx]), SML_TMO_MOVIAL_BLOB_SALT_SIZE); |
| idx += SML_TMO_MOVIAL_BLOB_SALT_SIZE; |
| |
| kal_mem_cpy(pBlob->key[cat_idx].hck, &(pObj[idx]), SML_TMO_MOVIAL_BLOB_HCK_SIZE); |
| idx += SML_TMO_MOVIAL_BLOB_HCK_SIZE; |
| |
| /* check m,n,p */ |
| if (pObj[idx] > 0) |
| { |
| switch (cat_idx) |
| { |
| case SML_TMO_MOVIAL_CAT_N: |
| sizeM = pObj[idx] * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_N; |
| if (sizeM > SML_TMO_MOVIAL_BLOB_CAT_N_SIZE) |
| { |
| free_ctrl_buffer(pBlob); |
| return NULL; |
| } |
| |
| pBlob->cat[cat_idx].num = pObj[idx++]; |
| kal_mem_cpy(pBlob->code_cat_n, &(pObj[idx]), sizeM); |
| idx += sizeM; |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_NS: |
| sizeN = pObj[idx] * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_NS; |
| if (sizeN > SML_TMO_MOVIAL_BLOB_CAT_NS_SIZE) |
| { |
| free_ctrl_buffer(pBlob); |
| return NULL; |
| } |
| |
| pBlob->cat[cat_idx].num = pObj[idx++]; |
| kal_mem_cpy(pBlob->code_cat_ns, &(pObj[idx]), sizeN); |
| idx += sizeN; |
| break; |
| |
| case SML_TMO_MOVIAL_CAT_SP: |
| sizeP = pObj[idx] * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_SP; |
| if (sizeP > SML_TMO_MOVIAL_BLOB_CAT_SP_SIZE) |
| { |
| free_ctrl_buffer(pBlob); |
| return NULL; |
| } |
| |
| pBlob->cat[cat_idx].num = pObj[idx++]; |
| kal_mem_cpy(pBlob->code_cat_sp, &(pObj[idx]), sizeP); |
| idx += sizeP; |
| break; |
| |
| default: |
| break; |
| } |
| } |
| else /* m/n/p = 0 */ |
| { |
| /* memset ensures pBlob->cat[cat_idx].num set to 0 */ |
| idx += 1; |
| } |
| } |
| |
| if (sml_tmo_movial_ValidateConfigData(pBlob) == KAL_FALSE) |
| { |
| free_ctrl_buffer(pBlob); |
| return NULL; |
| } |
| |
| kal_mem_cpy(pBlob->signature, &(pObj[idx]), SML_TMO_MOVIAL_BLOB_SIZE_OF_SIGNATURE); |
| |
| sml_Dump("constructed blob", (kal_uint8 *)pBlob, SML_TMO_MOVIAL_MAX_BLOB_SIZE); |
| |
| return (kal_uint8 *)pBlob; |
| } |
| |
| #ifdef __TMO_RSU_OTP__ |
| static kal_bool custom_check_is_default_tmo_blob(kal_uint8 *imei) |
| { |
| kal_uint8 otp_default_imei[SML_TMO_MOVIAL_BLOB_IMEI_SIZE] = {0x00}; |
| |
| if (kal_mem_cmp(&imei[0], &otp_default_imei[0], SML_TMO_MOVIAL_BLOB_IMEI_SIZE) == 0) |
| { |
| return KAL_TRUE; |
| } |
| else |
| { |
| return KAL_FALSE; |
| } |
| } |
| #endif /* __TMO_RSU_OTP__ */ |
| |
| /******************************************************************************* |
| * FUNCTION |
| * custom_check_is_default_imei |
| * DESCRIPTION |
| * Check if the IMEI is default IMEI |
| * PARAMETERS |
| * imei [kal_uint8 *] |
| * RETURN |
| * kal_bool |
| *******************************************************************************/ |
| kal_bool custom_check_is_default_imei(kal_uint8 *imei) |
| { |
| #if defined(__SECURITY_OTP__) && defined(__NVRAM_OTP__) |
| kal_uint8 default_imei_bcd[8] = {0x00}; |
| #else |
| kal_uint8 default_imei_bcd[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; |
| #endif |
| |
| if (NULL == imei) |
| { |
| return KAL_FALSE; |
| } |
| |
| if (kal_mem_cmp(&imei[0], &default_imei_bcd[0], 8) == 0) |
| { |
| return KAL_TRUE; |
| } |
| else |
| { |
| return KAL_FALSE; |
| } |
| } |
| |
| void custom_tmo_movial_rsu_get_pub_key_handle(kal_uint8 index, |
| TYPE_CUST_CHL_KEY *key1, TYPE_CUST_CHL_KEY *key2) |
| { |
| TYPE_CUST_CHL_KEY pub_key_group[][2] = { |
| // Pub Key 1, Pub Key 2 |
| {CUST_TM_PUB_KEY1, CUST_TM_PUB_KEY2}, // index == 0 |
| // Add handles of new pub keys sets here |
| }; |
| |
| #define TMO_MOVIAL_KEY_SET_MAX_NUM (sizeof(pub_key_group)/sizeof(pub_key_group[0])) |
| |
| index = index > (TMO_MOVIAL_KEY_SET_MAX_NUM - 1) ? 0 : index; |
| |
| if (NULL != key1) |
| { |
| *key1 = pub_key_group[index][0]; |
| MD_TRC_INFO_SML_RSU_PUB_KEY_HANDLE((*key1)); |
| } |
| |
| if (NULL != key2) |
| { |
| *key2 = pub_key_group[index][1]; |
| MD_TRC_INFO_SML_RSU_PUB_KEY_HANDLE((*key2)); |
| } |
| |
| return; |
| } |
| #endif /* L4_NOT_PRESENT */ |
| #endif /* !defined(__MAUI_BASIC__) */ |