[Feature]Upload Modem source code
Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/custom/protocol/common/ps/custom_sml.c b/mcu/custom/protocol/common/ps/custom_sml.c
new file mode 100644
index 0000000..95421e5
--- /dev/null
+++ b/mcu/custom/protocol/common/ps/custom_sml.c
@@ -0,0 +1,2789 @@
+/*****************************************************************************
+ *
+ * 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__) */