blob: 95421e5bf610a3c52d48dd262fd976bceed48035 [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001/*****************************************************************************
2 *
3 * Filename:
4 * ---------
5 * custom_sml.c
6 *
7 * Project:
8 * --------
9 * UMOLYA
10 *
11 * Description:
12 * ------------
13 * This file is for SIM ME Lock customization
14 *
15 * Author:
16 * -------
17 * -------
18 ****************************************************************************/
19#if !defined(__MAUI_BASIC__)
20
21#include <string.h>
22
23#include "kal_general_types.h"
24#include "kal_public_api.h"
25#include "global_def.h"
26
27#include "custom_sml.h"
28#include "custom_sml_trc.h"
29#include "custom_nvram_extra.h"
30
31#include "ps_public_enum.h"
32#include "sim_ps_enum.h"
33#include "smu_common_enums.h"
34
35#include "mcd_l3_inc_struct.h"
36
37#include "nvram_interface.h"
38#include "cust_chl_interface.h"
39#include "custom_sml_sec_verify.h"
40
41#include "l4c_utility.h"
42#include "ps_public_utility.h"
43
44
45extern void smu_nvram_write(nvram_lid_enum file_idx, kal_uint8 access_id, kal_bool is_write_protect2);
46
47
48
49#ifndef L4_NOT_PRESENT
50/****************************************************************************
51 *
52 * SIM ME Lock
53 *
54 ****************************************************************************/
55
56#ifdef __CUST_SML_RULE__
57const kal_uint8 sml_gblob_max_cust_rule[SML_LOCK_CUST_CODE_SIZE + 1] = SML_GBLOB_MAX_CUST_RULE_LIST;
58#endif
59
60/*******************************************************************************
61 * FUNCTION
62 * sml_mini_trace
63 * DESCRIPTION
64 * trace for short strings
65 * PARAMETERS
66 * title [const kal_char]
67 * data [kal_uint8]
68 * len [kal_uint8]
69 * RETURN
70 * void
71*******************************************************************************/
72void sml_mini_trace(const kal_char *title, kal_uint8 *data, kal_uint8 len)
73{
74 kal_uint8 *buf = NULL;
75 kal_uint8 buf_len = (len < 128 ? len : 128);
76
77 buf = get_ctrl_buffer(128 + 1);
78 kal_mem_set(buf, 0, 128 + 1);
79
80 kal_mem_cpy(buf, data, buf_len);
81 kal_prompt_trace(kal_get_active_module_id(), "%s: ", title);
82 kal_prompt_trace(kal_get_active_module_id(), "%s", (const kal_char *)buf);
83}
84
85/*******************************************************************************
86 * FUNCTION
87 * custom_sml_query_key_input_type
88 * DESCRIPTION
89 * This function is to query under particular protection algorithm and operation pair,
90 * whether our key input is plaintext key (e.g. '123456') or hashed key (e.g. {0xAA, 0xBB, ...})
91 * PARAMETERS
92 * algo key protection algorithm
93 * op operation for querying key input type
94 * RETURN
95 * SML_VERIFY_WITH_PLAINKEY: Input is plaintext key, may need to derive its hashed value for verification
96 * SML_VERIFY_WITH_HCK: Input is hashed key, directly compare its stored hashed value for verification
97 * GLOBALS AFFECTED
98 * N/A
99*******************************************************************************/
100sml_key_input_type_enum custom_sml_query_key_input_type(sml_key_algo_enum algo, sml_op_enum op)
101{
102 sml_key_input_type_enum input_type = SML_INPUT_WITH_PLAINKEY;
103
104 if (algo == SML_KEY_ALGO_BCD) /* algo == 0 */
105 {
106 input_type = SML_INPUT_WITH_PLAINKEY;
107 }
108
109 else if (algo == SML_KEY_ALGO_PBKDF2_HMAC_SHA256_SALT128) /* algo == 1 */
110 {
111 switch (op)
112 {
113 case SML_OP_VERIFY:
114 case SML_OP_CHANGE_PWD:
115 input_type = SML_INPUT_WITH_PLAINKEY;
116 break;
117
118 case SML_OP_UNLOCK:
119 case SML_OP_LOCK:
120 case SML_OP_ADD:
121 case SML_OP_REMOVE:
122 case SML_OP_DISABLE:
123 case SML_OP_UPDATE_AUTOLOCK_COUNT:
124 input_type = SML_INPUT_WITH_HCK;
125 break;
126
127 default:
128 break;
129 }
130 }
131
132 return input_type;
133}
134
135#ifdef __SML_PUK__
136/*******************************************************************************
137 * FUNCTION
138 * custom_sml_query_puk_key_input_type
139 * DESCRIPTION
140 * This function is to query under particular protection algorithm and operation pair,
141 * whether our key input is plaintext key (e.g. '123456') or hashed key (e.g. {0xAA, 0xBB, ...})
142 * PARAMETERS
143 * algo key protection algorithm
144 * op operation for querying key input type
145 * RETURN
146 * SML_VERIFY_WITH_PLAINKEY: Input is plaintext key, may need to derive its hashed value for verification
147 * SML_VERIFY_WITH_HCK: Input is hashed key, directly compare its stored hashed value for verification
148 * GLOBALS AFFECTED
149 * N/A
150*******************************************************************************/
151sml_key_input_type_enum custom_sml_query_puk_key_input_type(sml_key_algo_enum algo, sml_puk_key_op_enum op)
152{
153 sml_key_input_type_enum input_type = SML_INPUT_WITH_PLAINKEY;
154
155 if (algo == SML_KEY_ALGO_BCD) /* algo == 0 */
156 {
157 input_type = SML_INPUT_WITH_PLAINKEY; // Only PLAINTEXT allowed
158 }
159
160 else if (algo == SML_KEY_ALGO_PBKDF2_HMAC_SHA256_SALT128) /* algo == 1 */
161 {
162 switch (op)
163 {
164 case SML_PUK_OP_VERIFY:
165 input_type = SML_INPUT_WITH_PLAINKEY;
166 break;
167
168 case SML_PUK_OP_UPDATE:
169 input_type = SML_INPUT_WITH_HCK;
170 break;
171
172 default:
173 break;
174 }
175 }
176
177 return input_type;
178}
179#endif /* __SML_PUK__ */
180
181
182/****************************************************************************
183 *
184 * Verizon SIM Lock
185 *
186 ****************************************************************************/
187
188/* define the Local variable of VZW SML object */
189static sml_vzw_sim_lock_context_struct sml_vzw_cntxt_obj[MAX_SIM_NUM];
190static nvram_ef_sml_vzw_sim_lock_obj_struct SMLVZWOBJ[MAX_SIM_NUM];
191
192/* define the Global access pointer of VZW SML object */
193nvram_ef_sml_vzw_sim_lock_obj_struct * pSMLVZWg = &SMLVZWOBJ[0];
194
195
196/*******************************************************************************
197 * FUNCTION
198 * sml_clean_vzw_cntxt
199 * DESCRIPTION
200 * Clean sensitive data in MD Dump.
201 * PARAMETERS
202 * N/A
203 * RETURN
204 * N/A
205 * GLOBALS AFFECTED
206 * sml_vzw_cntxt_obj
207*******************************************************************************/
208void sml_clean_vzw_cntxt(void)
209{
210 kal_mem_set(sml_vzw_cntxt_obj, 0x00, sizeof(sml_vzw_cntxt_obj));
211}
212
213/*******************************************************************************
214 * FUNCTION
215 * custom_sml_vzw_is_test_purpose
216 * DESCRIPTION
217 * This function is to query if VzW testing functions are enabled
218 * PARAMETERS
219 * N/A
220 * RETURN
221 * KAL_TRUE: For test purpose, testing function enabled
222 * KAL_FALSE: Normal purpose
223 * GLOBALS AFFECTED
224 * N/A
225*******************************************************************************/
226kal_bool custom_sml_vzw_is_test_purpose(void)
227{
228#ifdef __VZW_RSU_TEST__
229 return KAL_TRUE;
230#else
231 return KAL_FALSE;
232#endif
233}
234
235
236/*******************************************************************************
237 * FUNCTION
238 * sml_vzw_give
239 * DESCRIPTION
240 * This method copys the LID files read from NVRAM to the SML obj
241 * PARAMETERS
242 * IN * pLidToObj
243 * RETURN
244 * void
245 * GLOBALS AFFECTED
246 * SMLOBJ
247*******************************************************************************/
248void sml_vzw_give(void *pLidToObj, kal_uint8 source)
249{
250 sml_vzw_sim_lock_context_struct * pObj = NULL;
251
252 if(NULL != pSMLVZWg[source].pObj)
253 {
254 pSMLVZWg[source].pObj = NULL;
255 }
256
257 pObj = &(sml_vzw_cntxt_obj[source]);
258
259 kal_mem_cpy(pObj,
260 pLidToObj,
261 sizeof(sml_vzw_sim_lock_context_struct)
262 );
263
264 pSMLVZWg[source].pObj = pObj;
265}
266
267/*******************************************************************************
268 * FUNCTION
269 * sml_vzw_take
270 * DESCRIPTION
271 * This method copys the contex of the SML object to the provided NVRAM LID.
272 * PARAMETERS
273 * OUT * pObjToLid
274 * RETURN
275 * void
276 * GLOBALS AFFECTED
277 * SMLOBJ
278 *******************************************************************************/
279void sml_vzw_take( void *pObjToLid, kal_uint8 source )
280{
281 sml_vzw_sim_lock_context_struct * pObj = (sml_vzw_sim_lock_context_struct *) pSMLVZWg[source].pObj;
282
283 kal_mem_cpy(pObjToLid,
284 pObj,
285 sizeof(sml_vzw_sim_lock_context_struct)
286 );
287}
288
289/*******************************************************************************
290 * FUNCTION
291 * sml_vzw_destory
292 * DESCRIPTION
293 * This method free the SML object in memory if it is not used.
294 * PARAMETERS
295 * void
296 * RETURN
297 * void
298 * GLOBALS AFFECTED
299 * SMLOBJ
300 *******************************************************************************/
301void sml_vzw_destory(kal_uint8 source)
302{
303 pSMLVZWg[source].pObj = NULL;
304}
305
306/*******************************************************************************
307 * FUNCTION
308 * sml_vzw_Load
309 * DESCRIPTION
310 * This function loads the SML obj from NVRAM LID (NVRAM_READ_CNF)
311 * PARAMETERS
312 * IN pLid
313 * RETURN
314 * kal_uint16 Obj size
315 * GLOBALS AFFECTED
316 * SMLOBJ
317 *******************************************************************************/
318kal_uint16 sml_vzw_Load( void *pLid, kal_uint8 source )
319{
320 nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source];
321
322 kal_uint16 length = sizeof(sml_vzw_sim_lock_context_struct);
323
324 /* Clean the old ones */
325 (*p->destory)(source);
326
327 /* Load the new one */
328 (*p->give)(pLid, source);
329
330 return length;
331}
332
333/*******************************************************************************
334 * FUNCTION
335 * sml_vzw_Save
336 * DESCRIPTION
337 * This function saves the SML obj to NVRAM LID (NVRAM_WRITE_REQ)
338 * PARAMETERS
339 * OUT pLid
340 * RETURN
341 * kal_uint16 Obj size
342 * GLOBALS AFFECTED
343 * SMLOBJ
344 *******************************************************************************/
345kal_uint16 sml_vzw_Save( void *pLid, kal_uint8 source )
346{
347 nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source];
348
349 kal_uint16 length = sizeof(sml_vzw_sim_lock_context_struct);
350
351 kal_uint8 lock_state = SML_VZW_LOCK_STATE_LOCK;
352
353 kal_bool ret_val = KAL_FALSE;
354
355 kal_bool temp_unlock_restore_required = KAL_FALSE;
356
357 /* 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.
358 Then restore back to Temp unlock after 'take' operation */
359
360 ret_val = sml_vzw_get_int_data(source, SML_VZW_CAT_NONE, SML_VZW_RSU_NETWORK_LOCK_OPERATION, &lock_state);
361
362 if (KAL_FALSE == ret_val)
363 {
364 DEBUG_ASSERT(0);
365 }
366 else
367 {
368 if (lock_state == SML_VZW_LOCK_STATE_TEMP_UNLOCK)
369 {
370 ret_val = sml_vzw_update_int_data(source, SML_VZW_CAT_NONE, SML_VZW_RSU_NETWORK_LOCK_OPERATION, SML_VZW_LOCK_STATE_LOCK);
371 if (ret_val == KAL_TRUE)
372 {
373 temp_unlock_restore_required = KAL_TRUE;
374 }
375 }
376 }
377
378 (*p->take)(pLid, source);
379
380 if (KAL_TRUE == temp_unlock_restore_required)
381 {
382 sml_vzw_update_int_data(source, SML_VZW_CAT_NONE, SML_VZW_RSU_NETWORK_LOCK_OPERATION, SML_VZW_LOCK_STATE_TEMP_UNLOCK);
383 }
384
385 return length;
386}
387
388/*******************************************************************************
389 * FUNCTION
390 * sml_vzw_getItem
391 * DESCRIPTION
392 * This method returns the structure pointer and length of the structure
393 * of the desired SML object items.
394 * PARAMETERS
395 * IN cat
396 * IN item
397 * OUT *length
398 * RETURN
399 * void *
400 * GLOBALS AFFECTED
401 * SMLOBJ
402 *******************************************************************************/
403void * sml_vzw_getItem(sml_vzw_cat_enum category,
404 sml_ctx_enum item,
405 kal_uint16 *plength,
406 kal_uint8 source)
407{
408 sml_vzw_sim_lock_context_struct *pObj = (sml_vzw_sim_lock_context_struct *) pSMLVZWg[source].pObj;
409
410 ASSERT(NULL != pObj);
411
412 switch(item)
413 {
414 case SML_VZW_RSU_MAJOR_VERSION:
415 *plength = sizeof(kal_uint8);
416 return (kal_uint8 *) &(pObj->major_version);
417
418 case SML_VZW_RSU_MINOR_VERSION:
419 *plength = sizeof(kal_uint8);
420 return (kal_uint8 *) &(pObj->minor_version);
421
422 case SML_VZW_RSU_PROTECTION_ALGORITHM:
423 *plength = sizeof(kal_uint8);
424 return (kal_uint8 *) &(pObj->protection_algo);
425
426 case SML_VZW_RSU_NETWORK_LOCK_OPERATION:
427 *plength = sizeof(kal_uint8);
428 return (kal_uint8 *) &(pObj->nw_lock_op);
429
430 case SML_VZW_RSU_TIME_STAMP:
431 *plength = SML_VZW_RSU_TIME_STAMP_LEN;
432 return (kal_uint8 *) &(pObj->timestamp[0]);
433
434 case SML_VZW_RSU_SESSION_ID:
435 *plength = SML_VZW_RSU_SESSION_ID_LEN;
436 return (kal_uint8 *) &(pObj->session_id[0]);
437
438 case SML_VZW_RSU_CAT_CODE:
439 switch(category)
440 {
441 case SML_VZW_CAT_N:
442 *plength = SML_VZW_RSU_NW_LIST_LEN;
443 return (kal_uint8 *) &(pObj->nw_list[0]);
444 break;
445
446 case SML_VZW_CAT_NS:
447 *plength = SML_VZW_RSU_NS_LIST_LEN;
448 return (kal_uint8 *) &(pObj->ns_list[0]);
449 break;
450
451 case SML_VZW_CAT_SP:
452 *plength = SML_VZW_RSU_SP_LIST_LEN;
453 return (kal_uint8 *) &(pObj->sp_list[0]);
454 break;
455
456 case SML_VZW_CAT_EHPLMN:
457 *plength = SML_VZW_RSU_EHPLMN_LIST_LEN;
458 return (kal_uint8 *) &(pObj->ehplmn_list[0]);
459 break;
460
461 default:
462 /* do nothing */
463 break;
464 }
465 break;
466
467 case SML_VZW_RSU_CAT_NUM:
468 switch(category)
469 {
470 case SML_VZW_CAT_N:
471 *plength = sizeof(kal_uint8);
472 return (kal_uint8 *) &(pObj->nw_num);
473 break;
474
475 case SML_VZW_CAT_NS:
476 *plength = sizeof(kal_uint8);
477 return (kal_uint8 *) &(pObj->ns_num);
478 break;
479
480 case SML_VZW_CAT_SP:
481 *plength = sizeof(kal_uint8);
482 return (kal_uint8 *) &(pObj->sp_num);
483 break;
484
485 case SML_VZW_CAT_EHPLMN:
486 *plength = sizeof(kal_uint8);
487 return (kal_uint8 *) &(pObj->ehplmn_num);
488 break;
489
490 default:
491 /* do nothing */
492 break;
493 }
494 break;
495
496 default:
497 break;
498 }
499
500 return NULL;
501}
502
503/*******************************************************************************
504 * FUNCTION
505 * sml_vzw_putItem
506 * DESCRIPTION
507 * This method set the desired items of the SML object.
508 * PARAMETERS
509 * IN cat
510 * IN item
511 * IN *pItem
512 * IN *plength
513 * RETURN
514 * void
515 * GLOBALS AFFECTED
516 * SMLOBJ
517 *******************************************************************************/
518void sml_vzw_putItem(sml_vzw_cat_enum cat,
519 sml_ctx_enum item,
520 void *pItem,
521 kal_uint16 *plength,
522 kal_uint8 source)
523{
524 sml_vzw_sim_lock_context_struct *pObj = (sml_vzw_sim_lock_context_struct *) pSMLVZWg[source].pObj;
525
526 switch (item)
527 {
528 case SML_VZW_RSU_MAJOR_VERSION:
529 kal_mem_cpy(&(pObj->major_version), pItem, *plength);
530 break;
531
532 case SML_VZW_RSU_MINOR_VERSION:
533 kal_mem_cpy(&(pObj->minor_version), pItem, *plength);
534 break;
535
536 case SML_VZW_RSU_PROTECTION_ALGORITHM:
537 kal_mem_cpy(&(pObj->protection_algo), pItem, *plength);
538 break;
539
540 case SML_VZW_RSU_NETWORK_LOCK_OPERATION:
541 kal_mem_cpy(&(pObj->nw_lock_op), pItem, *plength);
542 break;
543
544 case SML_VZW_RSU_SESSION_ID:
545 kal_mem_cpy(pObj->session_id, pItem, *plength);
546 break;
547
548 case SML_VZW_RSU_TIME_STAMP:
549 kal_mem_cpy(pObj->timestamp, pItem, *plength);
550 break;
551
552 case SML_VZW_RSU_CAT_CODE:
553 switch(cat)
554 {
555 case SML_VZW_CAT_N:
556 kal_mem_cpy(pObj->nw_list, pItem, *plength);
557 break;
558
559 case SML_VZW_CAT_NS:
560 kal_mem_cpy(pObj->ns_list, pItem, *plength);
561 break;
562
563 case SML_VZW_CAT_SP:
564 kal_mem_cpy(pObj->sp_list, pItem, *plength);
565 break;
566
567 case SML_VZW_CAT_EHPLMN:
568 kal_mem_cpy(pObj->ehplmn_list, pItem, *plength);
569 break;
570
571 default:
572 /* do nothing */
573 break;
574 }
575 break;
576
577 case SML_VZW_RSU_CAT_NUM:
578 switch(cat)
579 {
580 case SML_VZW_CAT_N:
581 kal_mem_cpy(&(pObj->nw_num), pItem, *plength);
582 break;
583
584 case SML_VZW_CAT_NS:
585 kal_mem_cpy(&(pObj->ns_num), pItem, *plength);
586 break;
587
588 case SML_VZW_CAT_SP:
589 kal_mem_cpy(&(pObj->sp_num), pItem, *plength);
590 break;
591
592 case SML_VZW_CAT_EHPLMN:
593 kal_mem_cpy(&(pObj->ehplmn_num), pItem, *plength);
594 break;
595
596 default:
597 /* do nothing */
598 break;
599 }
600 break;
601
602 default:
603 break;
604 }
605}
606
607/*******************************************************************************
608 * FUNCTION
609 * sml_vzw_Catcode
610 * DESCRIPTION
611 * This function is used to compose the code of each category
612 * PARAMETERS
613 * IN cat
614 * IN *imsi
615 * IN *vzw_gid1_len
616 * IN *gid1
617 * IN *ehplmn
618 * IN mnc_len
619 * OUT *code
620 * RETURN
621 * kal_uint8 code length
622 * GLOBALS AFFECTED
623 * NONE
624 *******************************************************************************/
625kal_uint8 sml_vzw_Catcode( sml_vzw_cat_enum cat,
626 kal_uint8 *imsi,
627 kal_uint8 vzw_gid1_len,
628 kal_uint8 *gid1,
629 kal_uint8 *ehplmn,
630 kal_uint8 mnc_len,
631 kal_uint8 *code )
632{
633 kal_uint8 i = 0;
634 kal_uint8 gid1_start_pos = 7;
635 kal_uint8 ehplmn_start_pos = (vzw_gid1_len < NUM_GID1)? (gid1_start_pos + vzw_gid1_len) : (gid1_start_pos + NUM_GID1);
636
637 if (imsi == NULL)
638 {
639 return 0;
640 }
641
642 if(mnc_len == 3)
643 {
644 /* MCC/MNC */
645 code[0] = ((imsi[1]&0xF0)>>4) + '0';
646 code[1] = (imsi[2]&0x0F) + '0';
647 code[2] = ((imsi[2]&0xF0)>>4) + '0';
648 code[3] = (imsi[3]&0x0F) + '0';
649 code[4] = ((imsi[3]&0xF0)>>4) + '0';
650 code[5] = (imsi[4]&0x0F) + '0';
651 code[6] = ((imsi[4]&0xF0)>>4) + '0';
652 code[7] = (imsi[5]&0x0F) + '0';
653 }
654 else
655 {
656 /* MCC/MNC */
657 code[0] = ((imsi[1]&0xF0)>>4) + '0';
658 code[1] = (imsi[2]&0x0F) + '0';
659 code[2] = ((imsi[2]&0xF0)>>4) + '0';
660 code[3] = (imsi[3]&0x0F) + '0';
661 code[4] = ((imsi[3]&0xF0)>>4) + '0';
662 code[5] = 'F';
663 code[6] = (imsi[4]&0x0F) + '0';
664 code[7] = ((imsi[4]&0xF0)>>4) + '0';
665 }
666
667 switch(cat)
668 {
669 case SML_VZW_CAT_N:
670 return SML_VZW_RSU_NW_CODE_LEN;
671 break;
672
673 case SML_VZW_CAT_NS:
674 return SML_VZW_RSU_NS_CODE_LEN;
675 break;
676
677 case SML_VZW_CAT_SP:
678 if (NULL != gid1)
679 {
680 code[6] = vzw_gid1_len;
681 /* GID */
682 for (i = 0; (i < vzw_gid1_len) && (i < NUM_GID1); i++)
683 {
684 code[gid1_start_pos+i] = gid1[i];
685 }
686 return gid1_start_pos + i;
687 }
688 else
689 {
690 return 0;
691 }
692 break;
693
694 case SML_VZW_CAT_EHPLMN:
695 if (NULL != gid1)
696 {
697 code[6] = vzw_gid1_len;
698 /* Verizon use 8 bytes of GID1 */
699 for (i = 0; (i < vzw_gid1_len) && (i < NUM_GID1); i++)
700 {
701 code[gid1_start_pos+i] = gid1[i];
702 }
703 }
704 else
705 {
706 return 0;
707 }
708
709 if (ehplmn != NULL)
710 {
711 if (*ehplmn == 0xff)
712 {
713 return 0;
714 }
715 else
716 {
717 /* EHPLMN format is :
718 MCC2|MCC1 MNC3(opt)|MCC3 MNC2|MNC1
719 */
720 code[ehplmn_start_pos] = (ehplmn[0]&0x0F) + '0'; //MCC1
721 code[ehplmn_start_pos+1] = ((ehplmn[0]&0xF0)>>4) + '0'; //MCC2
722 code[ehplmn_start_pos+2] = (ehplmn[1]&0x0F) + '0'; //MCC3
723 code[ehplmn_start_pos+3] = (ehplmn[2]&0x0F) + '0'; //MNC1
724 code[ehplmn_start_pos+4] = ((ehplmn[2]&0xF0)>>4) + '0'; //MNC2
725
726 if ((ehplmn[1] & 0xF0) == 0xF0) //this EHPLMN mnc len = 2
727 {
728 code[ehplmn_start_pos+5] = 0xFF;
729 }
730 else
731 {
732 code[ehplmn_start_pos+5] = ((ehplmn[1] & 0xF0)>>4) + '0'; //MNC3
733 }
734 return ehplmn_start_pos + 6;
735 }
736 }
737 else
738 {
739 return 0;
740 }
741 break;
742
743 default:
744
745 break;
746
747 }
748
749 return 0;
750}
751
752/*******************************************************************************
753 * FUNCTION
754 * sml_vzw_GetCode
755 * DESCRIPTION
756 * This function is used to compose the code of each category whether
757 * mnc length is 2 or 3
758 * PARAMETERS
759 * cat [IN] category of the SIM-ME-Lock
760 * imsi [IN] imsi of the code source
761 * vzw_gid1_len [IN] gid1 lengh from VZW code
762 * gid1 [IN] gid1 of the code source
763 * sim_mnc_len [IN] the mnc length decided by SIM
764 * pdata [IN] the saved code for comparing
765 * pdata_len [IN] the length of saved code for comparing
766 * code [OUT] the composed code according to all input parameters
767 *
768 * RETURN
769 * kal_uint16 file size
770 * GLOBALS AFFECTED
771 * SMLSLOBJ
772 *******************************************************************************/
773kal_uint8 sml_vzw_GetCode( sml_vzw_cat_enum cat,
774 kal_uint8 *imsi,
775 kal_uint8 vzw_gid1_len,
776 kal_uint8 *gid1,
777 kal_uint8 *ehplmn,
778 kal_uint8 sim_mnc_len,
779 kal_uint8 *pdata,
780 kal_uint8 *pdata_len,
781 kal_uint8 *code)
782{
783 kal_uint8 mnc_len=0;
784
785 if (SML_MNC_LENGTH_NEST == 1)
786 {
787 mnc_len = sim_mnc_len;
788 }
789 else
790 {
791 if (((*(pdata+5)) == 'F') || ((*(pdata+5)) == 'f'))
792 {
793 mnc_len = 2;
794 *(pdata+5) = 'F';
795 }
796 else
797 {
798 mnc_len = 3;
799 }
800 }
801
802 switch (cat)
803 {
804 case SML_VZW_CAT_N:
805 *pdata_len = SML_VZW_RSU_NW_CODE_LEN;
806 break;
807 case SML_VZW_CAT_NS:
808 *pdata_len = SML_VZW_RSU_NS_CODE_LEN;
809 break;
810 case SML_VZW_CAT_SP:
811 *pdata_len = SML_VZW_RSU_NW_CODE_LEN + 1 + vzw_gid1_len;
812 break;
813 case SML_VZW_CAT_EHPLMN:
814 *pdata_len = (SML_VZW_RSU_NW_CODE_LEN*2) + 1 + vzw_gid1_len;
815 break;
816 default:
817 DEBUG_ASSERT(0);
818 *pdata_len = 0;
819 }
820
821 return sml_vzw_Catcode(cat, imsi, vzw_gid1_len, gid1, ehplmn, mnc_len, code);
822}
823
824/*******************************************************************************
825 * FUNCTION
826 * sml_vzw_Check
827 * DESCRIPTION
828 * This function is used to check if the code is in the Pass list
829 * PARAMETERS
830 * IN cat
831 * IN *imsi
832 * IN *gid1
833 * IN ehplmn_num
834 * IN *ehplmn_ptr
835 * IN len
836 * IN source
837 * RETURN
838 * kal_bool
839 * GLOBALS AFFECTED
840 * SMLOBJ
841 *******************************************************************************/
842kal_bool sml_vzw_Check( sml_vzw_cat_enum cat,
843 kal_uint8 *imsi,
844 kal_uint8 *gid1,
845 kal_uint16 ehplmn_num,
846 kal_uint8 *ehplmn_ptr,
847 kal_uint8 sim_mnc_len,
848 kal_uint8 source)
849{
850 nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source];
851 kal_uint8 *num_list = NULL;
852 kal_uint8 *list_data = NULL;
853 kal_uint8 *vzw_code_ptr = NULL;
854 kal_uint8 vzw_code_len = 0;
855 kal_uint16 length = 0;
856 kal_uint8 code[SML_VZW_RSU_EHPLMN_CODE_LEN] = {0}; //use ehplmn code len as max code len
857 kal_uint8 code_len = 0;
858 kal_uint8 vzw_gid1_len;
859 kal_uint16 i = 0;
860 kal_uint8 code_dbg_str[(SML_VZW_RSU_EHPLMN_CODE_LEN)*3 + 1] = {0};
861 kal_uint8 iter = 1; //iteration for EHPLMN Configuration, limited by MD1_MAX_NUM_HPLMN
862
863 /* Check the integration of SIM Lock blob first */
864 if (p->pObj== NULL)
865 {
866 MD_TRC_WARNING_SML_CHECK_VALIDITY_FAILED();
867 }
868 else
869 {
870 num_list = (kal_uint8 *)(*p->getItem)(cat, SML_VZW_RSU_CAT_NUM, &length, source);
871
872 if (*num_list == 0)
873 {
874 // TODO: list is empty, always pass or blocked? currently is pass
875 return KAL_TRUE;
876 }
877 else
878 {
879 list_data = (kal_uint8 *)(*p->getItem)(cat, SML_VZW_RSU_CAT_CODE, &length, source);
880 vzw_code_ptr = list_data;
881 }
882
883 for (i = 0; i < *num_list; i++)
884 {
885 kal_uint8 *temp_ehplmn_ptr = ehplmn_ptr;
886
887 if (SML_VZW_CAT_EHPLMN == cat)
888 {
889 iter = (ehplmn_num < MD1_MAX_NUM_HPLMN)? ehplmn_num : MD1_MAX_NUM_HPLMN;
890 }
891 else
892 {
893 iter = 1;
894 }
895
896 if ((SML_VZW_CAT_SP == cat) || (SML_VZW_CAT_EHPLMN == cat))
897 {
898 vzw_gid1_len = vzw_code_ptr[6];
899 }
900 else
901 {
902 vzw_gid1_len = 0;
903 }
904
905 while (iter > 0)
906 {
907 kal_uint8 j = 0, k = 0;
908
909 iter--;
910
911 code_len = sml_vzw_GetCode(cat, imsi, vzw_gid1_len, gid1, temp_ehplmn_ptr, sim_mnc_len, vzw_code_ptr, &vzw_code_len, code);
912
913 if (iter >= 1)
914 {
915 temp_ehplmn_ptr += 3; //for next iteration if more than one EHPLMN from SIM
916 }
917
918 while ((j < code_len) && (k <= (sizeof(code_dbg_str) - 4)))
919 {
920 kal_int8 temp_len;
921
922 temp_len = kal_sprintf((kal_char*)code_dbg_str + k, "%02x ", code[j]);
923
924 if (temp_len <= 0)
925 {
926 kal_mem_cpy(code_dbg_str + k, "ERR", sizeof("ERR"));
927 k += 3;
928 break;
929 }
930
931 k += temp_len;
932 j++;
933 }
934 code_dbg_str[k] = '\0';
935 MD_TRC_INFO_SMU_CHECK_LENGTH(code_len, vzw_code_len, sim_mnc_len);
936 MD_TRC_INFO_SML_VZW_CODE_DEBUG((kal_char*)code_dbg_str);
937
938 /* we support dynamic comparing code length by using the code_len in stead of fixed length.
939 After that, vzw_code_ptr will shift according to each individual code length.
940 In addition, the VZW SIM Lock NVRAM structure is defined as max size.
941 */
942 if ((code_len > 0) && (kal_mem_cmp(code, vzw_code_ptr, code_len) == 0))
943 {
944 return KAL_TRUE;
945 }
946
947 kal_mem_set(code, 0, SML_VZW_RSU_EHPLMN_CODE_LEN);
948 }
949
950 //shift to next code of the compared category
951 vzw_code_ptr += vzw_code_len;
952 }
953 }
954
955 return KAL_FALSE;
956}
957
958kal_bool sml_vzw_update_int_data(kal_uint8 source, sml_vzw_cat_enum cat, sml_ctx_enum type, kal_uint8 data)
959{
960 nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source];
961 kal_uint16 length = sizeof(kal_uint8);
962
963 /* Check the integration of SIM Lock blob first */
964 if (p->pObj == NULL)
965 {
966 MD_TRC_WARNING_SML_CHECK_VALIDITY_FAILED();
967 return KAL_FALSE;
968 }
969
970 (*p->putItem)(cat, type, &data, &length, source);
971
972 return KAL_TRUE;
973}
974
975kal_bool sml_vzw_get_int_data(kal_uint8 source, sml_vzw_cat_enum cat, sml_ctx_enum type, kal_uint8* pData)
976{
977 nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source];
978 kal_uint16 length;
979 kal_bool ret_val = KAL_FALSE;
980
981 /* Check the integration of SIM Lock blob first */
982 if (p->pObj == NULL)
983 {
984 MD_TRC_WARNING_SML_CHECK_VALIDITY_FAILED();
985 }
986 else
987 {
988 *pData = *((kal_uint8 *)(*p->getItem)(cat, type, &length, source));
989
990 if (length == sizeof(kal_uint8))
991 {
992 ret_val = KAL_TRUE;
993 }
994 else
995 {
996 MD_TRC_WARNING_SML_VZW_RSU_GET_INT_DATA_FAILED(cat, type);
997 }
998 }
999
1000 return ret_val;
1001}
1002
1003kal_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)
1004{
1005 nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source];
1006
1007 /* Check the integration of SIM Lock blob first */
1008 if (p->pObj == NULL)
1009 {
1010 MD_TRC_WARNING_SML_CHECK_VALIDITY_FAILED();
1011 return KAL_FALSE;
1012 }
1013
1014 (*p->putItem)(cat, type, data, &data_len, source);
1015
1016 return KAL_TRUE;
1017}
1018
1019kal_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)
1020{
1021 nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source];
1022 kal_uint8* pData = NULL;
1023
1024 /* Check the integration of SIM Lock blob first */
1025 if (p->pObj == NULL)
1026 {
1027 MD_TRC_WARNING_SML_CHECK_VALIDITY_FAILED();
1028 return KAL_FALSE;
1029 }
1030
1031 pData = (kal_uint8 *)(*p->getItem)(cat, type, data_len, source);
1032
1033 kal_mem_cpy(data, pData, *data_len);
1034
1035 return KAL_TRUE;
1036}
1037
1038kal_uint8 sml_vzw_get_major_version(kal_uint8 source)
1039{
1040 nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source];
1041 kal_uint8 *pMajor_ver = NULL;
1042 kal_uint16 length = 0;
1043
1044 /* Check the integration of SIM Lock blob first */
1045 if (p->pObj == NULL)
1046 {
1047 MD_TRC_WARNING_SML_CHECK_VALIDITY_FAILED();
1048 return KAL_FALSE;
1049 }
1050
1051 pMajor_ver = (kal_uint8 *)(*p->getItem)(SML_VZW_CAT_NONE, SML_VZW_RSU_MAJOR_VERSION, &length, source);
1052
1053 return *pMajor_ver;
1054}
1055
1056kal_uint8 sml_vzw_get_max_support_major_version()
1057{
1058 return SML_VZW_RSU_MAX_SUPPORT_MAJOR_VER;
1059}
1060
1061kal_uint8 sml_vzw_get_minor_version(kal_uint8 source)
1062{
1063 nvram_ef_sml_vzw_sim_lock_obj_struct *p = &pSMLVZWg[source];
1064 kal_uint8 *pMinor_ver = NULL;
1065 kal_uint16 length = 0;
1066
1067 /* Check the integration of SIM Lock blob first */
1068 if (p->pObj == NULL)
1069 {
1070 MD_TRC_WARNING_SML_CHECK_VALIDITY_FAILED();
1071 return KAL_FALSE;
1072 }
1073
1074 pMinor_ver = (kal_uint8 *)(*p->getItem)(SML_VZW_CAT_NONE, SML_VZW_RSU_MINOR_VERSION, &length, source);
1075
1076 return *pMinor_ver;
1077}
1078
1079kal_uint8 sml_vzw_get_max_support_minor_version()
1080{
1081 return SML_VZW_RSU_MAX_SUPPORT_MINOR_VER;
1082}
1083
1084extern const nvram_sml_vzw_sim_lock_context_struct NVRAM_EF_L4_SML_VZW_SIM_LOCK_DEFAULT;
1085
1086kal_bool sml_vzw_reset_rsu_data(kal_uint8 source)
1087{
1088 nvram_ef_sml_vzw_sim_lock_obj_struct* p = &pSMLVZWg[source];
1089 sml_vzw_sim_lock_context_struct* pDefaultBlob = (sml_vzw_sim_lock_context_struct*)&NVRAM_EF_L4_SML_VZW_SIM_LOCK_DEFAULT;
1090
1091 /* Check the integration of SIM Lock blob first */
1092 if (p->pObj == NULL)
1093 {
1094 MD_TRC_WARNING_SML_CHECK_VALIDITY_FAILED();
1095 return KAL_FALSE;
1096 }
1097
1098 // Set Network Lock
1099 sml_vzw_update_int_data(source, SML_VZW_CAT_NONE, SML_VZW_RSU_NETWORK_LOCK_OPERATION, SML_VZW_LOCK_STATE_LOCK);
1100
1101 // Reset NW Configuration
1102 sml_vzw_update_int_data(source, SML_VZW_CAT_N, SML_VZW_RSU_CAT_NUM, pDefaultBlob->nw_num);
1103 sml_vzw_update_array_data(source, SML_VZW_CAT_N, SML_VZW_RSU_CAT_CODE, pDefaultBlob->nw_list, SML_VZW_RSU_NW_LIST_LEN);
1104
1105 // Reset NS Configuration
1106 sml_vzw_update_int_data(source, SML_VZW_CAT_NS, SML_VZW_RSU_CAT_NUM, pDefaultBlob->ns_num);
1107 sml_vzw_update_array_data(source, SML_VZW_CAT_NS, SML_VZW_RSU_CAT_CODE, pDefaultBlob->ns_list, SML_VZW_RSU_NS_LIST_LEN);
1108
1109 // Reset SP Configuration
1110 sml_vzw_update_int_data(source, SML_VZW_CAT_SP, SML_VZW_RSU_CAT_NUM, pDefaultBlob->sp_num);
1111 sml_vzw_update_array_data(source, SML_VZW_CAT_SP, SML_VZW_RSU_CAT_CODE, pDefaultBlob->sp_list, SML_VZW_RSU_SP_LIST_LEN);
1112
1113 // Reset EHPLMN Configuration
1114 sml_vzw_update_int_data(source, SML_VZW_CAT_EHPLMN, SML_VZW_RSU_CAT_NUM, pDefaultBlob->ehplmn_num);
1115 sml_vzw_update_array_data(source, SML_VZW_CAT_EHPLMN, SML_VZW_RSU_CAT_CODE, pDefaultBlob->ehplmn_list, SML_VZW_RSU_EHPLMN_LIST_LEN);
1116
1117 return KAL_TRUE;
1118}
1119
1120void custom_vzw_rsu_get_pub_key_handle(kal_uint8 index, TYPE_CUST_CHL_KEY *key)
1121{
1122 TYPE_CUST_CHL_KEY pub_key[] = {
1123 CUST_VZ_PUB_KEY // index == 0, do not change this.
1124 // Add test key handle here
1125 };
1126
1127 #define VZW_KEY_SET_MAX_NUM (sizeof(pub_key)/sizeof(pub_key[0]))
1128
1129 index = index > (VZW_KEY_SET_MAX_NUM - 1) ? 0 : index;
1130
1131 if (NULL != key)
1132 {
1133 *key = pub_key[index];
1134 MD_TRC_INFO_SML_RSU_PUB_KEY_HANDLE((*key));
1135 }
1136
1137 return;
1138}
1139
1140/****************************************************************************
1141 *
1142 * TMO SIM Lock with Movial Solution
1143 *
1144 ****************************************************************************/
1145#ifdef __TMO_RSU_OTP__
1146static kal_bool custom_check_is_default_tmo_blob(kal_uint8 *imei);
1147#endif /* __TMO_RSU_OTP__ */
1148/* define the Local variable of TMO MOVIAL SML object */
1149static sml_tmo_movial_sim_lock_context_struct sml_tmo_movial_cntxt_obj[MAX_SIM_NUM];
1150static nvram_ef_sml_tmo_movial_sim_lock_obj_struct SMLTMMOBJ[MAX_SIM_NUM];
1151
1152/* define the Global access pointer of TMO MOVIAL SML object */
1153nvram_ef_sml_tmo_movial_sim_lock_obj_struct* pSMLTMMg = &SMLTMMOBJ[0];
1154
1155/* time to temporary unlock expiry in seconds */
1156kal_uint32 sml_tmo_movial_seconds_to_expire = 0;
1157
1158#ifdef UNIT_TEST
1159kal_uint8 imei_bcd_ut[9];
1160#endif /* UNIT_TEST */
1161
1162/*******************************************************************************
1163 * FUNCTION
1164 * sml_clean_tmo_movial_cntxt
1165 * DESCRIPTION
1166 * Clean sensitive data in MD Dump.
1167 * PARAMETERS
1168 * N/A
1169 * RETURN
1170 * N/A
1171 * GLOBALS AFFECTED
1172 * sml_tmo_movial_cntxt_obj
1173*******************************************************************************/
1174void sml_clean_tmo_movial_cntxt(void)
1175{
1176 kal_mem_set(sml_tmo_movial_cntxt_obj, 0x00, sizeof(sml_tmo_movial_cntxt_obj));
1177}
1178
1179/*******************************************************************************
1180 * FUNCTION
1181 * sml_tmo_movial_give
1182 * DESCRIPTION
1183 * This method copys the LID files read from NVRAM to the SML obj
1184 * PARAMETERS
1185 * IN * pLidToObj
1186 * RETURN
1187 * void
1188 * GLOBALS AFFECTED
1189 * SMLTMMOBJ
1190*******************************************************************************/
1191void sml_tmo_movial_give( void *pLidToObj, kal_uint8 source )
1192{
1193 sml_tmo_movial_sim_lock_context_struct * pObj = NULL;
1194
1195 if(NULL != pSMLTMMg[source].pObj)
1196 {
1197 kal_sys_trace("SML: object is exist!");
1198 pSMLTMMg[source].pObj = NULL;
1199 }
1200
1201 pObj = &(sml_tmo_movial_cntxt_obj[source]);
1202
1203 kal_mem_cpy(pObj,
1204 pLidToObj,
1205 sizeof(sml_tmo_movial_sim_lock_context_struct)
1206 );
1207
1208 pSMLTMMg[source].pObj = pObj;
1209}
1210
1211
1212/*******************************************************************************
1213 * FUNCTION
1214 * sml_tmo_movial_take
1215 * DESCRIPTION
1216 * This method copys the contex of the SML object to the provided NVRAM LID.
1217 * PARAMETERS
1218 * OUT * pObjToLid
1219 * RETURN
1220 * void
1221 * GLOBALS AFFECTED
1222 * SMLTMMOBJ
1223 *******************************************************************************/
1224
1225void sml_tmo_movial_take( void *pObjToLid, kal_uint8 source )
1226{
1227 sml_tmo_movial_sim_lock_context_struct * pObj = (sml_tmo_movial_sim_lock_context_struct *) pSMLTMMg[source].pObj;
1228
1229 if (NULL == pObjToLid || NULL == pObj)
1230 {
1231 return;
1232 }
1233
1234 kal_mem_cpy(pObjToLid,
1235 pObj,
1236 sizeof(sml_tmo_movial_sim_lock_context_struct)
1237 );
1238}
1239
1240
1241/*******************************************************************************
1242 * FUNCTION
1243 * sml_tmo_movial_destory
1244 * DESCRIPTION
1245 * This method free the SML object in memory if it is not used.
1246 * PARAMETERS
1247 * void
1248 * RETURN
1249 * void
1250 * GLOBALS AFFECTED
1251 * SMLTMMOBJ
1252 *******************************************************************************/
1253void sml_tmo_movial_destory(kal_uint8 source)
1254{
1255 pSMLTMMg[source].pObj = NULL;
1256}
1257
1258
1259/*******************************************************************************
1260 * FUNCTION
1261 * sml_tmo_movial_getItem
1262 * DESCRIPTION
1263 * This method returns the structure pointer and length of the structure
1264 * of the desired SML object items.
1265 * PARAMETERS
1266 * IN cat
1267 * IN item
1268 * OUT *length
1269 * RETURN
1270 * void *
1271 * GLOBALS AFFECTED
1272 * SMLTMMOBJ
1273 *******************************************************************************/
1274void *sml_tmo_movial_getItem( sml_tmo_movial_cat_enum category,
1275 sml_ctx_enum item,
1276 kal_uint16 *plength,
1277 kal_uint8 source)
1278{
1279 sml_tmo_movial_sim_lock_context_struct *pObj = (sml_tmo_movial_sim_lock_context_struct *) pSMLTMMg[source].pObj;
1280
1281 ASSERT(NULL != pObj);
1282
1283 switch(item)
1284 {
1285 case SML_TMO_MOVIAL_CAT_MAJOR_VERSION:
1286 *plength = sizeof(kal_uint8);
1287 return (kal_uint8 *) &(pObj->major_version);
1288
1289 case SML_TMO_MOVIAL_CAT_MINOR_VERSION:
1290 *plength = sizeof(kal_uint8);
1291 return (kal_uint8 *) &(pObj->minor_version);
1292
1293 case SML_TMO_MOVIAL_CAT_PROTECTION_ALGORITHM:
1294 *plength = sizeof(kal_uint8);
1295 return (kal_uint8 *) &(pObj->protection_algorithm);
1296
1297 case SML_TMO_MOVIAL_CAT_LOCK_OPERATION:
1298 *plength = sizeof(kal_uint8);
1299 return (kal_uint8 *) &(pObj->lock_operation);
1300
1301 case SML_TMO_MOVIAL_CAT_IMEI:
1302 *plength = SML_TMO_MOVIAL_BLOB_IMEI_SIZE;
1303 return (kal_uint8 *) &(pObj->imei[0]);
1304
1305 case SML_TMO_MOVIAL_CAT_TIME_STAMP:
1306 *plength = SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE;
1307 return (kal_uint8 *) &(pObj->time_stamp[0]);
1308
1309 case SML_TMO_MOVIAL_CAT_START_TIME:
1310 *plength = SML_TMO_MOVIAL_SIZE_OF_START_TIME;
1311 return (kal_uint8 *) &(pObj->start_time[0]);
1312
1313 case SML_TMO_MOVIAL_CAT_UNLOCK_DURATION:
1314 *plength = SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION;
1315 return (kal_uint8 *) &(pObj->unlock_duration[0]);
1316
1317 case SML_TMO_MOVIAL_CAT_LENGTH:
1318 *plength = SML_TMO_MOVIAL_BLOB_LENGTH_SIZE;
1319 return (kal_uint16 *) &(pObj->length[0]);
1320
1321 case SML_TMO_MOVIAL_CAT_META:
1322 *plength = sizeof(sml_tmo_movial_blob_meta_struct);
1323 return (sml_tmo_movial_blob_meta_struct *) &(pObj->cat[category]);
1324
1325 case SML_TMO_MOVIAL_CAT_KEY:
1326 *plength = sizeof(sml_tmo_movial_blob_key_struct);
1327 return (sml_tmo_movial_blob_key_struct *) &(pObj->key[category]);
1328
1329 case SML_TMO_MOVIAL_CAT_SIGNATURE:
1330 *plength = SML_TMO_MOVIAL_BLOB_SIZE_OF_SIGNATURE;
1331 return (kal_uint8 *) &(pObj->signature[0]);
1332
1333 case SML_TMO_MOVIAL_CAT_UNLOCK_TIME_COUNTER:
1334 *plength = SML_TMO_MOVIAL_SIZE_OF_UNLOCK_TIME;
1335 return (kal_uint8 *) &(pObj->unlock_time[0]);
1336
1337 case SML_TMO_MOVIAL_CAT_CODE:
1338 switch(category)
1339 {
1340 case SML_TMO_MOVIAL_CAT_N:
1341 *plength = SML_TMO_MOVIAL_BLOB_CAT_N_SIZE;
1342 return (kal_uint8 *) &(pObj->code_cat_n[0]);
1343 break;
1344
1345 case SML_TMO_MOVIAL_CAT_NS:
1346 *plength = SML_TMO_MOVIAL_BLOB_CAT_NS_SIZE;
1347 return (kal_uint8 *) &(pObj->code_cat_ns[0]);
1348 break;
1349
1350 case SML_TMO_MOVIAL_CAT_SP:
1351 *plength = SML_TMO_MOVIAL_BLOB_CAT_SP_SIZE;
1352 return (kal_uint8 *) &(pObj->code_cat_sp[0]);
1353 break;
1354
1355 default:
1356 /* do nothing */
1357 break;
1358 }
1359 break;
1360
1361 default:
1362 break;
1363 }
1364
1365 return NULL;
1366}
1367
1368void sml_tmo_movial_putItem( sml_tmo_movial_cat_enum category,
1369 sml_ctx_enum item,
1370 void *pItem,
1371 kal_uint16 *plength,
1372 kal_uint8 source)
1373{
1374 sml_tmo_movial_sim_lock_context_struct *pObj = (sml_tmo_movial_sim_lock_context_struct *) pSMLTMMg[source].pObj;
1375
1376 ASSERT(NULL != pObj);
1377
1378 switch(item)
1379 {
1380 case SML_TMO_MOVIAL_CAT_UNLOCK_TIME_COUNTER:
1381
1382 kal_mem_cpy(&(pObj->unlock_time[0]),
1383 pItem,
1384 SML_TMO_MOVIAL_SIZE_OF_UNLOCK_TIME
1385 );
1386 break;
1387
1388 case SML_TMO_MOVIAL_CAT_LOCK_OPERATION:
1389
1390 kal_mem_cpy(&(pObj->lock_operation),
1391 pItem,
1392 *plength);
1393 break;
1394
1395 default:
1396 break;
1397 }
1398}
1399
1400
1401kal_bool sml_tmo_movial_ValidateIMEI(kal_uint8 *imei, kal_bool is_bypass_default, kal_uint8 source)
1402{
1403 kal_uint8 nvram_imei_bcd[8 + 1] = {0};
1404 kal_uint8 nvram_imei_ascii[16 + 1] = {0};
1405 kal_uint8 rec_id = 1 + l4c_gemini_get_actual_sim_id(source);
1406 kal_bool result = KAL_FALSE;
1407
1408#ifdef UNIT_TEST //Integrity check doesn't work on modis. Modify for UT.
1409 kal_mem_cpy(&nvram_imei_bcd[0], &imei_bcd_ut[0], 9);
1410#else
1411 if (nvram_get_imei_value(8, nvram_imei_bcd, rec_id) == KAL_TRUE)
1412#endif
1413 {
1414 if ((is_bypass_default == KAL_TRUE)
1415 && (KAL_TRUE == custom_check_is_default_imei(&nvram_imei_bcd[0])))
1416 {
1417 MD_TRC_INFO_SML_CUST_ALLOW_DEFAULT_IMEI();
1418 result = KAL_TRUE;
1419 }
1420 else
1421 {
1422 // ch2-ch1, last digit is 0
1423 nvram_imei_bcd[7] = nvram_imei_bcd[7] & 0x0f;
1424 nvram_imei_bcd[8] = 0xff;
1425 convert_to_digit((kal_uint8 *)nvram_imei_bcd, nvram_imei_ascii);
1426
1427 sml_mini_trace("UE IMEI", nvram_imei_ascii, SML_IMEI_PRINT_LEN);
1428 sml_mini_trace("BLOB IMEI", &imei[0], SML_TMO_MOVIAL_BLOB_IMEI_SIZE);
1429
1430 if (kal_mem_cmp(&imei[0], nvram_imei_ascii, 15) == 0)
1431 {
1432 result = KAL_TRUE;
1433 }
1434 }
1435 }
1436
1437 MD_TRC_INFO_SML_TMO_RSU_IMEI_CHECK_RESULT(result);
1438 return result;
1439}
1440
1441kal_bool sml_tmo_movial_ValidateTimeStamp(kal_uint8 *new_time_stamp, kal_uint8 source)
1442{
1443 nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source];
1444 kal_uint16 length = 0;
1445 kal_uint8 *blob_time_stamp;
1446 kal_uint64 new_time = 0;
1447 kal_uint64 blob_time = 0;
1448 kal_uint8 i = 0;
1449
1450 blob_time_stamp = (kal_uint8 *)(*p->getItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_TIME_STAMP, &length, source);
1451
1452 for (i = 0; i < SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE-1; i++)
1453 {
1454 blob_time += blob_time_stamp[i];
1455 blob_time = (blob_time << 8);
1456
1457 new_time += new_time_stamp[i];
1458 new_time = (new_time << 8);
1459 }
1460
1461 blob_time += blob_time_stamp[SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE-1];
1462 new_time += new_time_stamp[SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE-1];
1463
1464 if (new_time > blob_time)
1465 {
1466 return KAL_TRUE;
1467 }
1468
1469 return KAL_FALSE;
1470}
1471
1472kal_bool sml_tmo_movial_ValidateConfigData(sml_tmo_movial_sim_lock_context_struct *pBlob)
1473{
1474 kal_uint16 cat_idx, data_idx;
1475 kal_uint16 length = 0;
1476 kal_uint8 *data = NULL;
1477
1478 for (cat_idx = SML_TMO_MOVIAL_CAT_N ; cat_idx < SML_TMO_MOVIAL_CAT_SIZE ; cat_idx++)
1479 {
1480 switch (cat_idx)
1481 {
1482 case SML_TMO_MOVIAL_CAT_N:
1483 length = pBlob->cat[cat_idx].num * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_N;
1484 data = pBlob->code_cat_n;
1485 break;
1486
1487 case SML_TMO_MOVIAL_CAT_NS:
1488 length = pBlob->cat[cat_idx].num * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_NS;
1489 data = pBlob->code_cat_ns;
1490 break;
1491
1492 case SML_TMO_MOVIAL_CAT_SP:
1493 length = pBlob->cat[cat_idx].num * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_SP;
1494 data = pBlob->code_cat_sp;
1495 break;
1496
1497 default:
1498 break;
1499 }
1500
1501 for (data_idx = 0; data_idx < length; data_idx++)
1502 {
1503 if (!((data[data_idx] >= RMMI_CHAR_0) && (data[data_idx] <= RMMI_CHAR_9)) && (data[data_idx] != RMMI_CHAR_F))
1504 {
1505 return KAL_FALSE;
1506 }
1507 }
1508 }
1509
1510 return KAL_TRUE;
1511}
1512
1513/*******************************************************************************
1514 * FUNCTION
1515 * sml_tmo_movial_ConstructBlob
1516 * DESCRIPTION
1517 * This function construct full size Bolb (internal NV structure) from a variant length Blob received in response message
1518 * PARAMETERS
1519 * IN *pObj
1520 * OUT pLen
1521 * RETURN
1522 * kal_uint8 * construct data
1523 * GLOBALS AFFECTED
1524 * SMLTMMOBJ
1525 *******************************************************************************/
1526kal_uint8 *sml_tmo_movial_ConstructBlob(kal_uint8 *pObj, kal_uint16 slb_len, kal_uint8 *error_cause, kal_uint8 source)
1527{
1528 kal_uint16 sizeM, sizeN, sizeP;
1529 kal_uint16 length = 0;
1530 kal_uint16 idx;
1531 sml_tmo_movial_sim_lock_context_struct *pBlob;
1532 kal_uint8 cat_idx = 0;
1533
1534 MD_TRC_FUNC_SML_TMO_MOVIAL_CONSTRUCTBLOB();
1535
1536 pBlob = (sml_tmo_movial_sim_lock_context_struct *)get_ctrl_buffer(SML_TMO_MOVIAL_MAX_BLOB_SIZE);
1537 kal_mem_set(pBlob, 0, SML_TMO_MOVIAL_MAX_BLOB_SIZE);
1538
1539 /* major_version + minor_version + protection_algorithm + lock_operation */
1540 pBlob->major_version = pObj[length++];
1541 pBlob->minor_version = pObj[length++];
1542 pBlob->protection_algorithm = pObj[length++];
1543 pBlob->lock_operation = pObj[length++];
1544
1545 /* imei */
1546 kal_mem_cpy(pBlob->imei, &(pObj[length]), SML_TMO_MOVIAL_BLOB_IMEI_SIZE);
1547 length += SML_TMO_MOVIAL_BLOB_IMEI_SIZE;
1548
1549 /* time stamp */
1550 kal_mem_cpy(pBlob->time_stamp, &(pObj[length]), SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE);
1551 length += SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE;
1552
1553 /* Temporary unlock start timer */
1554 kal_mem_cpy(pBlob->start_time, &(pObj[length]), SML_TMO_MOVIAL_SIZE_OF_START_TIME);
1555 length += SML_TMO_MOVIAL_SIZE_OF_START_TIME;
1556
1557 /* Temporary unlock duration */
1558 kal_mem_cpy(pBlob->unlock_duration, &(pObj[length]), SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION);
1559 length += SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION;
1560
1561 /* length */
1562 kal_mem_cpy(pBlob->length, &(pObj[length]), SML_TMO_MOVIAL_BLOB_LENGTH_SIZE);
1563 length += SML_TMO_MOVIAL_BLOB_LENGTH_SIZE;
1564
1565 if (pBlob->protection_algorithm >= SML_TMO_MOVIAL_PROTECTION_SCHEME_SIZE)
1566 {
1567 *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC;
1568 free_ctrl_buffer(pBlob);
1569 return NULL;
1570 }
1571
1572 if (sml_tmo_movial_ValidateIMEI(pBlob->imei, KAL_FALSE, source) == KAL_FALSE)
1573 {
1574 *error_cause = SML_TMO_MOVIAL_SLB_ERR_IMEI_MISMATCH;
1575 free_ctrl_buffer(pBlob);
1576 return NULL;
1577 }
1578
1579 if (sml_tmo_movial_ValidateTimeStamp(pBlob->time_stamp, source) == KAL_FALSE)
1580 {
1581 *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC;
1582 free_ctrl_buffer(pBlob);
1583 return NULL;
1584 }
1585
1586 idx = length;
1587
1588 for (cat_idx = SML_TMO_MOVIAL_CAT_N ; cat_idx < SML_TMO_MOVIAL_CAT_SIZE ; cat_idx++)
1589 {
1590 pBlob->cat[cat_idx].change_flag = pObj[idx++];
1591
1592 /* iteration_count, salt, hck */
1593 kal_mem_cpy(pBlob->key[cat_idx].iteration_count, &(pObj[idx]), SML_TMO_MOVIAL_BLOB_ITERATION_COUNT_SIZE);
1594 idx += SML_TMO_MOVIAL_BLOB_ITERATION_COUNT_SIZE;
1595
1596 kal_mem_cpy(pBlob->key[cat_idx].salt, &(pObj[idx]), SML_TMO_MOVIAL_BLOB_SALT_SIZE);
1597 idx += SML_TMO_MOVIAL_BLOB_SALT_SIZE;
1598
1599 kal_mem_cpy(pBlob->key[cat_idx].hck, &(pObj[idx]), SML_TMO_MOVIAL_BLOB_HCK_SIZE);
1600 idx += SML_TMO_MOVIAL_BLOB_HCK_SIZE;
1601
1602 /* check m,n,p */
1603 if (pObj[idx] > 0)
1604 {
1605 switch (cat_idx)
1606 {
1607 case SML_TMO_MOVIAL_CAT_N:
1608 sizeM = pObj[idx] * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_N;
1609 if (sizeM > SML_TMO_MOVIAL_BLOB_CAT_N_SIZE)
1610 {
1611 *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC;
1612 free_ctrl_buffer(pBlob);
1613 return NULL;
1614 }
1615
1616 pBlob->cat[cat_idx].num = pObj[idx++];
1617 kal_mem_cpy(pBlob->code_cat_n, &(pObj[idx]), sizeM);
1618 idx += sizeM;
1619 break;
1620
1621 case SML_TMO_MOVIAL_CAT_NS:
1622 sizeN = pObj[idx] * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_NS;
1623 if (sizeN > SML_TMO_MOVIAL_BLOB_CAT_NS_SIZE)
1624 {
1625 *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC;
1626 free_ctrl_buffer(pBlob);
1627 return NULL;
1628 }
1629
1630 pBlob->cat[cat_idx].num = pObj[idx++];
1631 kal_mem_cpy(pBlob->code_cat_ns, &(pObj[idx]), sizeN);
1632 idx += sizeN;
1633 break;
1634
1635 case SML_TMO_MOVIAL_CAT_SP:
1636 sizeP = pObj[idx] * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_SP;
1637 if (sizeP > SML_TMO_MOVIAL_BLOB_CAT_SP_SIZE)
1638 {
1639 *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC;
1640 free_ctrl_buffer(pBlob);
1641 return NULL;
1642 }
1643
1644 pBlob->cat[cat_idx].num = pObj[idx++];
1645 kal_mem_cpy(pBlob->code_cat_sp, &(pObj[idx]), sizeP);
1646 idx += sizeP;
1647 break;
1648
1649 default:
1650 break;
1651 }
1652 }
1653 else /* m/n/p = 0 */
1654 {
1655 /* memset ensures pBlob->cat[cat_idx].num set to 0 */
1656 idx += 1;
1657 }
1658 }
1659
1660 if (sml_tmo_movial_ValidateConfigData(pBlob) == KAL_FALSE)
1661 {
1662 *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC;
1663 free_ctrl_buffer(pBlob);
1664 return NULL;
1665 }
1666
1667 kal_mem_cpy(pBlob->signature, &(pObj[idx]), SML_TMO_MOVIAL_BLOB_SIZE_OF_SIGNATURE);
1668
1669 sml_Dump("constructed blob", (kal_uint8 *)pBlob, SML_TMO_MOVIAL_MAX_BLOB_SIZE);
1670
1671 return (kal_uint8 *)pBlob;
1672}
1673
1674
1675/*******************************************************************************
1676 * FUNCTION
1677 * sml_tmo_movial_ConstructSmlBlob
1678 * DESCRIPTION
1679 * This function constructs BLOB for NVRAM updating based on change_flag param
1680 * change_flag == 0 => get cat / key / lock data from NVRAM
1681 * change_flag == 1 => get cat / key / lock data from pObj
1682 * PARAMETERS
1683 * IN *pObj (constructed blob data)
1684 * OUT pLen
1685 * RETURN
1686 * kal_uint8 * construct data
1687 * GLOBALS AFFECTED
1688 * SMLTMMOBJ
1689 *******************************************************************************/
1690kal_uint8 *sml_tmo_movial_ConstructSmlBlob(sml_tmo_movial_sim_lock_context_struct *pObj, kal_uint8 source)
1691{
1692 sml_tmo_movial_sim_lock_context_struct *psmlBlob;
1693 kal_uint8 cat_idx = 0;
1694 kal_uint16 obj_len = 0;
1695 nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source];
1696 sml_tmo_movial_blob_meta_struct *cat = NULL;
1697 sml_tmo_movial_blob_key_struct *key = NULL;
1698 kal_uint8 *pdata = NULL;
1699
1700 psmlBlob = (sml_tmo_movial_sim_lock_context_struct *)get_ctrl_buffer(SML_TMO_MOVIAL_MAX_BLOB_SIZE);
1701 kal_mem_set(psmlBlob, 0, SML_TMO_MOVIAL_MAX_BLOB_SIZE);
1702
1703 /* major_version + minor_version + protection_algorithm + lock_operation */
1704 psmlBlob->major_version = pObj->major_version;
1705 psmlBlob->minor_version= pObj->minor_version;
1706 psmlBlob->protection_algorithm= pObj->protection_algorithm;
1707 psmlBlob->lock_operation= pObj->lock_operation;
1708
1709 /* imei */
1710 kal_mem_cpy(psmlBlob->imei, pObj->imei, SML_TMO_MOVIAL_BLOB_IMEI_SIZE);
1711
1712 /* time stamp */
1713 kal_mem_cpy(psmlBlob->time_stamp, pObj->time_stamp, SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE);
1714
1715 /* Temporary unlock start time */
1716 kal_mem_cpy(psmlBlob->start_time, pObj->start_time, SML_TMO_MOVIAL_SIZE_OF_START_TIME);
1717
1718 /* Temporary unlock duration */
1719 kal_mem_cpy(psmlBlob->unlock_duration, pObj->unlock_duration, SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION);
1720
1721 /* length */
1722 kal_mem_cpy(psmlBlob->length, pObj->length, SML_TMO_MOVIAL_BLOB_LENGTH_SIZE);
1723
1724 for (cat_idx = SML_TMO_MOVIAL_CAT_N ; cat_idx < SML_TMO_MOVIAL_CAT_SIZE ; cat_idx++)
1725 {
1726 /* existing configuration should be used if change_flag=0 */
1727 if (pObj->cat[cat_idx].change_flag == 0 || SML_TMO_MOVIAL_STATE_TEMPORARY_UNLOCK == psmlBlob->lock_operation)
1728 {
1729 cat = (sml_tmo_movial_blob_meta_struct *) (*p->getItem)(cat_idx, SML_TMO_MOVIAL_CAT_META, &obj_len, source);
1730 key = (sml_tmo_movial_blob_key_struct *) (*p->getItem)(cat_idx, SML_TMO_MOVIAL_CAT_KEY, &obj_len, source);
1731 pdata = (kal_uint8 *) (*p->getItem)(cat_idx, SML_TMO_MOVIAL_CAT_CODE, &obj_len, source);
1732 }
1733 else
1734 {
1735 cat = &(pObj->cat[cat_idx]);
1736 key = &(pObj->key[cat_idx]);
1737
1738 switch (cat_idx)
1739 {
1740 case SML_TMO_MOVIAL_CAT_N:
1741 pdata = pObj->code_cat_n;
1742 break;
1743
1744 case SML_TMO_MOVIAL_CAT_NS:
1745 pdata = pObj->code_cat_ns;
1746 break;
1747
1748 case SML_TMO_MOVIAL_CAT_SP:
1749 pdata = pObj->code_cat_sp;
1750 break;
1751
1752 default:
1753 break;
1754 }
1755 }
1756
1757 kal_mem_cpy(&(psmlBlob->cat[cat_idx]), cat, sizeof(sml_tmo_movial_blob_meta_struct));
1758 kal_mem_cpy(&(psmlBlob->key[cat_idx]), key, sizeof(sml_tmo_movial_blob_key_struct));
1759
1760 switch (cat_idx)
1761 {
1762 case SML_TMO_MOVIAL_CAT_N:
1763 kal_mem_cpy(psmlBlob->code_cat_n, pdata, SML_TMO_MOVIAL_BLOB_CAT_N_SIZE);
1764 break;
1765
1766 case SML_TMO_MOVIAL_CAT_NS:
1767 kal_mem_cpy(psmlBlob->code_cat_ns, pdata, SML_TMO_MOVIAL_BLOB_CAT_NS_SIZE);
1768 break;
1769
1770 case SML_TMO_MOVIAL_CAT_SP:
1771 kal_mem_cpy(psmlBlob->code_cat_sp, pdata, SML_TMO_MOVIAL_BLOB_CAT_SP_SIZE);
1772 break;
1773
1774 default:
1775 break;
1776 }
1777 }
1778
1779 kal_mem_cpy(psmlBlob->signature, pObj->signature, SML_TMO_MOVIAL_BLOB_SIZE_OF_SIGNATURE);
1780
1781 sml_Dump("constructed sml blob", (kal_uint8 *)psmlBlob, SML_TMO_MOVIAL_MAX_BLOB_SIZE);
1782
1783 return (kal_uint8 *)psmlBlob;
1784}
1785
1786
1787/*******************************************************************************
1788 * FUNCTION
1789 * sml_tmo_movial_ReconstructBlob
1790 * DESCRIPTION
1791 * This function restores the original message raw data from constructed internal blob structure
1792 * (used for signature verification)
1793 * PARAMETERS
1794 * IN *pObj (constructed blob data)
1795 * OUT pLen, length of returned raw data
1796 * OUT error_cause
1797 * RETURN
1798 * kal_uint8 * raw data
1799 * GLOBALS AFFECTED
1800 * N/A
1801 *******************************************************************************/
1802kal_uint8 *sml_tmo_movial_ReconstructBlob(sml_tmo_movial_sim_lock_context_struct *pObj, kal_uint32 *pLen, kal_uint8 *error_cause)
1803{
1804 kal_uint8 *pData = NULL;
1805 kal_uint32 blob_len, data_len;
1806 kal_uint32 sizeM, sizeN, sizeP;
1807 kal_uint32 len;
1808 kal_uint8 cat_idx;
1809
1810 blob_len = sml_GetCount(&(pObj->length[0]));
1811 sizeM = pObj->cat[SML_TMO_MOVIAL_CAT_N].num * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_N;
1812 sizeN = pObj->cat[SML_TMO_MOVIAL_CAT_NS].num * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_NS;
1813 sizeP = pObj->cat[SML_TMO_MOVIAL_CAT_SP].num * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_SP;
1814
1815 /* RSA-PSS scheme */
1816 if (pObj->protection_algorithm == 1)
1817 {
1818 data_len = blob_len - SML_TMO_MOVIAL_BLOB_SIZE_OF_SIGNATURE;
1819 }
1820 else
1821 {
1822 *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC;
1823 return NULL;
1824 }
1825
1826 pData = (kal_uint8 *)get_ctrl_buffer(data_len);
1827
1828 if (NULL == pData)
1829 {
1830 *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC;
1831 return NULL;
1832 }
1833 /* major_version + minor_version + protection_algorithm + lock_operation */
1834 len = 0;
1835
1836 pData[len++] = pObj->major_version;
1837 pData[len++] = pObj->minor_version;
1838 pData[len++] = pObj->protection_algorithm;
1839 pData[len++] = pObj->lock_operation;
1840
1841 /* imei */
1842 kal_mem_cpy((pData+len), pObj->imei, SML_TMO_MOVIAL_BLOB_IMEI_SIZE);
1843 len += SML_TMO_MOVIAL_BLOB_IMEI_SIZE;
1844
1845 /* time stamp */
1846 kal_mem_cpy((pData+len), pObj->time_stamp, SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE);
1847 len += SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE;
1848
1849 /* temporary unlock start time */
1850 kal_mem_cpy((pData+len), pObj->start_time, SML_TMO_MOVIAL_SIZE_OF_START_TIME);
1851 len += SML_TMO_MOVIAL_SIZE_OF_START_TIME;
1852
1853 /* temporary unlock duration */
1854 kal_mem_cpy((pData+len), pObj->unlock_duration, SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION);
1855 len += SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION;
1856
1857 /* length */
1858 kal_mem_cpy((pData+len), pObj->length, SML_TMO_MOVIAL_BLOB_LENGTH_SIZE);
1859 len += SML_TMO_MOVIAL_BLOB_LENGTH_SIZE;
1860
1861 for (cat_idx = SML_TMO_MOVIAL_CAT_N ; cat_idx < SML_TMO_MOVIAL_CAT_SIZE; cat_idx++)
1862 {
1863 pData[len++] = pObj->cat[cat_idx].change_flag;
1864
1865 kal_mem_cpy((pData+len), (kal_uint8 *)&(pObj->key[cat_idx].iteration_count[0]), SML_TMO_MOVIAL_BLOB_ITERATION_COUNT_SIZE);
1866 len += SML_TMO_MOVIAL_BLOB_ITERATION_COUNT_SIZE;
1867
1868 kal_mem_cpy((pData+len), (kal_uint8 *)&(pObj->key[cat_idx].salt[0]), SML_TMO_MOVIAL_BLOB_SALT_SIZE);
1869 len += SML_TMO_MOVIAL_BLOB_SALT_SIZE;
1870
1871 kal_mem_cpy((pData+len), (kal_uint8 *)&(pObj->key[cat_idx].hck[0]), SML_TMO_MOVIAL_BLOB_HCK_SIZE);
1872 len += SML_TMO_MOVIAL_BLOB_HCK_SIZE;
1873
1874 pData[len++] = pObj->cat[cat_idx].num;
1875
1876 switch (cat_idx)
1877 {
1878 case SML_TMO_MOVIAL_CAT_N:
1879 kal_mem_cpy((pData+len), (kal_uint8 *)&(pObj->code_cat_n[0]), sizeM);
1880 len += sizeM;
1881 break;
1882
1883 case SML_TMO_MOVIAL_CAT_NS:
1884 kal_mem_cpy((pData+len), (kal_uint8 *)&(pObj->code_cat_ns[0]), sizeN);
1885 len += sizeN;
1886 break;
1887
1888 case SML_TMO_MOVIAL_CAT_SP:
1889 kal_mem_cpy((pData+len), (kal_uint8 *)&(pObj->code_cat_sp[0]), sizeP);
1890 len += sizeP;
1891 break;
1892
1893 default:
1894 break;
1895 }
1896 }
1897
1898 *pLen = len;
1899 sml_Dump("re-construct blob", pData, len);
1900
1901 return pData;
1902}
1903
1904kal_bool sml_tmo_movial_checkValidity(void *pObj, kal_uint8 source, kal_uint8 *error_cause)
1905{
1906 sml_tmo_movial_sim_lock_context_struct *pSmlObj = (sml_tmo_movial_sim_lock_context_struct *) pObj;
1907 kal_uint8 *pData = NULL;
1908 kal_bool result = KAL_FALSE;
1909 kal_uint32 data_len;
1910
1911 if (sml_tmo_movial_ValidateIMEI(pSmlObj->imei, KAL_FALSE, source) == KAL_FALSE)
1912 {
1913 *error_cause = SML_TMO_MOVIAL_SLB_ERR_IMEI_MISMATCH;
1914 return KAL_FALSE;
1915 }
1916
1917 if (pSmlObj == NULL)
1918 {
1919 *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC;
1920 return KAL_FALSE;
1921 }
1922
1923#ifdef UNIT_TEST
1924 *error_cause = SML_TMO_MOVIAL_SLB_ERR_SUCCESS;
1925 return KAL_TRUE;
1926#endif /* UNIT_TEST */
1927
1928 pData = sml_tmo_movial_ReconstructBlob(pSmlObj, &data_len, error_cause);
1929
1930 if (pData == NULL)
1931 {
1932 *error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC;
1933 return KAL_FALSE;
1934 }
1935
1936 if (pSmlObj->protection_algorithm == SML_TMO_MOVIAL_PROTECTION_SCHEME_RSA2048)
1937 {
1938 TYPE_CUST_CHL_KEY key_handle = CUST_TM_PUB_KEY2;
1939 t_cust_chl_asym_key key;
1940 kal_uint32 ret;
1941 kal_uint8 key_index = sbp_query_md_feature_data_by_ps(SBP_TMO_MOVIAL_SELECT_KEY_SET, source);
1942
1943 custom_tmo_movial_rsu_get_pub_key_handle(key_index, NULL, &key_handle);
1944 ret = CustCHL_Get_Asym_Key(key_handle, &key);
1945 if (ret == CUST_CHL_ERROR_NONE)
1946 {
1947 ret = CustCHL_Verify_PSS_Signature(CUST_CHL_ALG_RSA_PSS_SHA256, pData, data_len,
1948 &pSmlObj->signature[0], &key);
1949
1950 MD_TRC_INFO_SMU_RSA_PSS_VERIFY_SIGNATURE_CUST(ret);
1951 }
1952 result = (ret == CUST_CHL_ERROR_NONE) ? KAL_TRUE : KAL_FALSE;
1953 }
1954 else
1955 {
1956 result = KAL_FALSE;
1957 }
1958
1959 if (KAL_TRUE == result)
1960 {
1961 *error_cause = SML_TMO_MOVIAL_SLB_ERR_SUCCESS;
1962 }
1963 else
1964 {
1965 *error_cause = SML_TMO_MOVIAL_SLB_ERR_VERIFY_FAIL;
1966 }
1967
1968 free_ctrl_buffer(pData);
1969
1970 return result;
1971}
1972
1973void sml_tmo_movial_Load(void *pLid, kal_uint8 source)
1974{
1975 nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source];
1976
1977 /* Clean the old ones */
1978 (*p->destory)(source);
1979
1980 /* Load the new one */
1981 (*p->give)(pLid, source);
1982
1983}
1984
1985void sml_tmo_movial_FirstLoad(void *pLid, kal_uint8 source)
1986{
1987 nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source];
1988 nvram_sml_tmo_movial_sim_lock_context_struct *pSmlObj = NULL;
1989#ifdef __TMO_RSU_OTP__
1990 kal_bool is_default_blob = KAL_FALSE;
1991#endif /* __TMO_RSU_OTP__ */
1992
1993 pSmlObj = (nvram_sml_tmo_movial_sim_lock_context_struct *) pLid;
1994 // Allow UE default IMEI (e.g. under factory procedure) in validate check
1995 if (KAL_FALSE == sml_tmo_movial_ValidateIMEI(pSmlObj->imei, KAL_TRUE, source))
1996 {
1997 #ifdef __TMO_RSU_OTP__
1998 is_default_blob = custom_check_is_default_tmo_blob(&(pSmlObj->imei[0]));
1999 if (KAL_TRUE == is_default_blob)
2000 {
2001 kal_uint8 imei_bcd[8+1] = {0};
2002 kal_uint8 rec_id = 1 + l4c_gemini_get_actual_sim_id(source);
2003
2004 if (nvram_get_imei_value(8, imei_bcd, rec_id) == KAL_TRUE)
2005 {
2006 kal_uint8 imei_ascii[16 + 1] = {0};
2007 imei_bcd[7] = imei_bcd[7] & 0x0f;
2008 imei_bcd[8] = 0xff;
2009 convert_to_digit((kal_uint8 *)imei_bcd, imei_ascii);
2010 MD_TRC_INFO_SML_TMO_RSU_COPY_IMEI();
2011 kal_mem_cpy(&(pSmlObj->imei[0]), imei_ascii, SML_TMO_MOVIAL_BLOB_IMEI_SIZE);
2012 }
2013 }
2014 else
2015 #endif /* __TMO_RSU_OTP__ */
2016 {
2017 /* This can hit when BLOB/device IMEI is corrupted or hacked,
2018 * hence ASSERT
2019 */
2020 MD_TRC_WARNING_SML_CHECK_IMEI_FAILED();
2021 // ASSERT(0);
2022 }
2023 }
2024
2025 /* Clean the old ones */
2026 (*p->destory)(source);
2027
2028 /* Load the new one */
2029 (*p->give)((void *)pSmlObj, source);
2030
2031#ifdef __TMO_RSU_OTP__
2032 if (KAL_TRUE == is_default_blob)
2033 {
2034 smu_nvram_write(NVRAM_EF_L4_SML_TMO_MOVIAL_SIM_LOCK_LID,
2035 SML_TMO_MOVIAL_NVRAM_ACCESS_ID_UPDATE_SLB, KAL_FALSE);
2036 }
2037#endif /* __TMO_RSU_OTP__ */
2038
2039 return;
2040}
2041
2042
2043/*******************************************************************************
2044 * FUNCTION
2045 * sml_tmo_movial_Save
2046 * DESCRIPTION
2047 * This function saves the SML obj to NVRAM LID
2048 * PARAMETERS
2049 * OUT pLid
2050 * RETURN
2051 * kal_uint16 Obj size
2052 * GLOBALS AFFECTED
2053 * SMLTMMOBJ
2054 *******************************************************************************/
2055kal_uint16 sml_tmo_movial_Save(void *pLid, kal_uint8 source)
2056{
2057 nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source];
2058
2059 kal_uint16 length = sizeof(sml_tmo_movial_sim_lock_context_struct);
2060
2061 (*p->take)(pLid, source);
2062
2063 return length;
2064}
2065
2066/*******************************************************************************
2067 * FUNCTION
2068 * sml_tmo_movial_CheckTempUnlock
2069 * DESCRIPTION
2070 * This method is to check if temporary unlock expires
2071 * PARAMETERS
2072 * IN source
2073 * RETURN
2074 * TRUE Temporary unlock expires
2075 * FALSE Temporary unlock does not expire
2076 * GLOBALS AFFECTED
2077 * SMLTMMOBJ
2078 *******************************************************************************/
2079kal_bool sml_tmo_movial_CheckTempUnlock(kal_uint8 source)
2080{
2081 nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source];
2082 kal_uint8 *lock_operation, *unlock_duration;
2083 kal_uint16 length;
2084 kal_uint32 duration_seconds = 0;
2085 kal_uint8 i;
2086
2087 lock_operation = (kal_uint8 *)(*p->getItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_LOCK_OPERATION, &length, source);
2088 unlock_duration = (kal_uint8 *)(*p->getItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_UNLOCK_DURATION, &length, source);
2089
2090 for (i = 0; i < SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION-1; i++)
2091 {
2092 duration_seconds += unlock_duration[i];
2093 duration_seconds = (duration_seconds << 8);
2094 }
2095 duration_seconds += unlock_duration[SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION-1];
2096
2097 MD_TRC_INFO_SML_CHECK_TEMP_UNLOCK(sml_tmo_movial_seconds_to_expire, duration_seconds);
2098
2099 if ((sml_tmo_movial_seconds_to_expire + (SML_TMO_MOVIAL_TIMEOUT_PERIODIC_CHECK/KAL_TICKS_1_SEC)) >= duration_seconds)
2100 {
2101 *lock_operation = SML_TMO_MOVIAL_STATE_PERMANENT_LOCK;
2102 // Should reset SLB/NVRAM in following action
2103 return KAL_TRUE;
2104 }
2105 else
2106 {
2107 sml_tmo_movial_seconds_to_expire += (SML_TMO_MOVIAL_TIMEOUT_PERIODIC_CHECK/KAL_TICKS_1_SEC);
2108 (*p->putItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_UNLOCK_TIME_COUNTER, &sml_tmo_movial_seconds_to_expire, &length, source);
2109 // Should write back to NVRAM in following action
2110 return KAL_FALSE;
2111 }
2112}
2113
2114
2115/*******************************************************************************
2116 * FUNCTION
2117 * sml_tmo_movial_Catcode
2118 * DESCRIPTION
2119 * This function is used to compose the code of each category
2120 * PARAMETERS
2121 * IN cat
2122 * IN *imsi
2123 * IN *gid1
2124 * IN mnc_len
2125 * OUT *code
2126 * RETURN
2127 * kal_uint8 code length
2128 * GLOBALS AFFECTED
2129 * NONE
2130 *******************************************************************************/
2131kal_uint8 sml_tmo_movial_Catcode( sml_tmo_movial_cat_enum cat,
2132 kal_uint8 *imsi,
2133 kal_uint8 *gid1,
2134 kal_uint8 mnc_len,
2135 kal_uint8 *code)
2136{
2137 if(mnc_len == 3)
2138 {
2139 code[0] = ((imsi[1] & 0xF0) >> 4) + RMMI_CHAR_0;
2140 code[1] = (imsi[2] & 0x0F) + RMMI_CHAR_0;
2141 code[2] = ((imsi[2] & 0xF0) >> 4) + RMMI_CHAR_0;
2142 code[3] = (imsi[3] & 0x0F) + RMMI_CHAR_0;
2143 code[4] = ((imsi[3] & 0xF0) >> 4) + RMMI_CHAR_0;
2144 code[5] = (imsi[4] & 0x0F) + RMMI_CHAR_0;
2145 code[6] = ((imsi[4] & 0xF0) >> 4) + RMMI_CHAR_0;
2146 code[7] = (imsi[5] & 0x0F) + RMMI_CHAR_0;
2147 }
2148 else
2149 {
2150 code[0] = ((imsi[1] & 0xF0) >> 4) + RMMI_CHAR_0;
2151 code[1] = (imsi[2] & 0x0F) + RMMI_CHAR_0;
2152 code[2] = ((imsi[2] & 0xF0) >> 4) + RMMI_CHAR_0;
2153 code[3] = (imsi[3] & 0x0F) + RMMI_CHAR_0;
2154 code[4] = ((imsi[3] & 0xF0) >> 4) + RMMI_CHAR_0;
2155 code[5] = RMMI_CHAR_F; // MNC length is 2, so the 3rd digit will be 'F'
2156 code[6] = (imsi[4] & 0x0F) + RMMI_CHAR_0;
2157 code[7] = ((imsi[4] & 0xF0) >> 4) + RMMI_CHAR_0;
2158 }
2159
2160 switch(cat)
2161 {
2162 case SML_TMO_MOVIAL_CAT_N:
2163 return SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_N;
2164 break;
2165
2166 case SML_TMO_MOVIAL_CAT_NS:
2167 return SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_NS;
2168 break;
2169
2170 case SML_TMO_MOVIAL_CAT_SP:
2171 if(gid1 != NULL)
2172 {
2173 code[6] = gid1[0]; // + RMMI_CHAR_0
2174 return SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_SP;
2175 }
2176 break;
2177
2178 default:
2179 break;
2180 }
2181
2182 return 0;
2183}
2184
2185
2186/*******************************************************************************
2187 * FUNCTION
2188 * sml_tmo_movial_GetCode
2189 * DESCRIPTION
2190 * This function is used to compose the code of each category whether
2191 * mnc length is 2 or 3
2192 * PARAMETERS
2193 * cat [IN] category of the SIM-ME-Lock
2194 * imsi [IN] imsi of the code source
2195 * gid1 [IN] gid1 of the code source
2196 * sim_mnc_len [IN] the mnc length decided by SIM
2197 * pdata [IN] the saved code for comparing
2198 * code [OUT] the composed code according to all input parameters
2199 *
2200 * RETURN
2201 * kal_uint8
2202 * GLOBALS AFFECTED
2203 * SMLTMMOBJ
2204 *******************************************************************************/
2205kal_uint8 sml_tmo_movial_GetCode( sml_tmo_movial_cat_enum cat,
2206 kal_uint8 * imsi,
2207 kal_uint8 * gid1,
2208 kal_uint8 sim_mnc_len,
2209 kal_uint8 * pdata,
2210 kal_uint8 * code)
2211{
2212 kal_uint8 mnc_len=0;
2213
2214 if (SML_MNC_LENGTH_NEST == 1)
2215 {
2216 mnc_len = sim_mnc_len;
2217 }
2218 else
2219 {
2220 if((*(pdata+5)) == 0x46 /* 'F' */)
2221 {
2222 mnc_len = 2;
2223 }
2224 else
2225 {
2226 mnc_len = 3;
2227 }
2228 }
2229
2230 return sml_tmo_movial_Catcode(cat, imsi, gid1, mnc_len, code);
2231}
2232
2233
2234/*******************************************************************************
2235 * FUNCTION
2236 * sml_tmo_movial_Check
2237 * DESCRIPTION
2238 * This function is used to check if the code is in the Pass list
2239 * PARAMETERS
2240 * IN cat
2241 * IN *imsi
2242 * IN *gid1
2243 * IN sim_mnc_len
2244 * IN source
2245 * RETURN
2246 * kal_bool
2247 * GLOBALS AFFECTED
2248 * SMLTMMOBJ
2249 *******************************************************************************/
2250kal_bool sml_tmo_movial_Check( sml_tmo_movial_cat_enum cat, // category
2251 kal_uint8 *imsi, // 9 bytes array, read from SIM, mandatory file
2252 kal_uint8 *gid1, // 20 bytes array, read from SIM, NULL means gid1 invalid(file not exist)
2253 kal_uint8 sim_mnc_len, // MNC length, read from SIM
2254 kal_uint8 source) // 0:SIM1, 1:SIM2
2255{
2256 nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source];
2257 sml_tmo_movial_blob_meta_struct *meta = NULL;
2258 kal_uint8 *pdata = NULL;
2259 kal_uint8 idx = 0;
2260 kal_uint16 length = 0, offset = 0;
2261 kal_bool result = KAL_FALSE;
2262 kal_uint8 code_len = 0;
2263 kal_uint8 code[10] = {0x00};
2264 kal_uint8 size_of_cat = 0;
2265
2266 meta = (sml_tmo_movial_blob_meta_struct *) (*p->getItem)(cat, SML_TMO_MOVIAL_CAT_META, &length, source);
2267 pdata = (kal_uint8 *) (*p->getItem)(cat, SML_TMO_MOVIAL_CAT_CODE, &length, source);
2268
2269
2270 if ((meta->cat_lock == SML_TMO_MOVIAL_CAT_UNLOCKED) || (meta->num == 0))
2271 {
2272 return KAL_TRUE;
2273 }
2274
2275 switch(cat)
2276 {
2277 case SML_TMO_MOVIAL_CAT_N:
2278 {
2279 size_of_cat = SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_N;
2280 break;
2281 }
2282 case SML_TMO_MOVIAL_CAT_NS:
2283 {
2284 size_of_cat = SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_NS;
2285 break;
2286 }
2287 case SML_TMO_MOVIAL_CAT_SP:
2288 {
2289 size_of_cat = SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_SP;
2290 break;
2291 }
2292 default:
2293 break;
2294 }
2295
2296 for (idx = 0; idx < meta->num; idx++)
2297 {
2298 offset = idx * size_of_cat;
2299 code_len = sml_tmo_movial_GetCode(cat,
2300 imsi,
2301 gid1,
2302 sim_mnc_len,
2303 (pdata+offset),
2304 code);
2305
2306 if (size_of_cat == code_len)
2307 {
2308 if (kal_mem_cmp(code, (pdata+offset), code_len) == 0)
2309 {
2310 result = KAL_TRUE;
2311 break;
2312 }
2313 }
2314 }
2315
2316 return result;
2317}
2318
2319
2320/*******************************************************************************
2321 * FUNCTION
2322 * sml_tmo_movial_UpdateNwTimeAndCheckTempLock
2323 * DESCRIPTION
2324 * This method is to update newtork time and check if temporary lock expires
2325 * PARAMETERS
2326 * IN source
2327 * IN nw_time_zone
2328 * IN nw_time
2329 * RETURN
2330 * TRUE Temporary unlock expires
2331 * FALSE Temporary unlock does not expire
2332 * GLOBALS AFFECTED
2333 * SMLOBJ
2334 *******************************************************************************/
2335kal_bool sml_tmo_movial_UpdateNwTimeAndCheckTempLock(kal_uint8 source, kal_uint8 nw_time_zone, nw_time_zone_time_struct *nw_time)
2336{
2337 nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source];
2338 kal_uint8 *start_time, *unlock_duration;
2339 kal_uint8 *lock_operation = NULL;
2340 kal_uint16 length;
2341 kal_uint32 current_seconds = 0;
2342 kal_uint64 start_seconds = 0;
2343 kal_uint32 start_seconds_u32 = 0;
2344 kal_uint32 duration_seconds = 0;
2345 kal_uint8 i;
2346
2347 lock_operation = (kal_uint8 *)(*p->getItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_LOCK_OPERATION, &length, source);
2348 start_time = (kal_uint8 *)(*p->getItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_START_TIME, &length, source);
2349 unlock_duration = (kal_uint8 *)(*p->getItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_UNLOCK_DURATION, &length, source);
2350
2351 if (*lock_operation != SML_TMO_MOVIAL_STATE_TEMPORARY_UNLOCK)
2352 {
2353 return KAL_FALSE;
2354 }
2355
2356 /* calculate start time and duration in seconds */
2357 start_seconds = 0;
2358 for (i = 0; i < SML_TMO_MOVIAL_SIZE_OF_START_TIME-1; i++)
2359 {
2360 start_seconds += start_time[i];
2361 start_seconds = (start_seconds << 8);
2362 }
2363 start_seconds += start_time[SML_TMO_MOVIAL_SIZE_OF_START_TIME-1];
2364 start_seconds /= 1000; /* from milliseconds to seconds */
2365
2366 start_seconds_u32 = (kal_uint32)start_seconds;
2367
2368 duration_seconds = 0;
2369 for (i = 0; i < SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION-1; i++)
2370 {
2371 duration_seconds += unlock_duration[i];
2372 duration_seconds = (duration_seconds << 8);
2373 }
2374 duration_seconds += unlock_duration[SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION-1];
2375
2376 /* calculate current time in seconds */
2377 current_seconds = sml_rsu_nwTimeToSeconds(nw_time_zone, nw_time);
2378
2379 MD_TRC_INFO_SML_TEMP_UNLOCK_TIME(start_seconds_u32, duration_seconds, current_seconds);
2380
2381 if (current_seconds >= (start_seconds_u32 + duration_seconds))
2382 {
2383 MD_TRC_INFO_SML_NW_TIME_EXPIRED();
2384 return KAL_TRUE;
2385 }
2386 else
2387 {
2388 /* update unlock time for power off accuracy: start ---> unlock time ---> NITZ ---> power off/on ---> end */
2389 sml_tmo_movial_seconds_to_expire = current_seconds - start_seconds_u32;
2390 (*p->putItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_UNLOCK_TIME_COUNTER, &sml_tmo_movial_seconds_to_expire, &length, source);
2391 smu_nvram_write(NVRAM_EF_L4_SML_TMO_MOVIAL_SIM_LOCK_LID, SML_TMO_MOVIAL_NVRAM_ACCESS_ID_UNLOCK_EXPIRE, KAL_FALSE);
2392
2393 return KAL_FALSE;
2394 }
2395}
2396
2397
2398/*******************************************************************************
2399 * FUNCTION
2400 * sml_tmo_movial_Verify
2401 * DESCRIPTION
2402 * This function is used to verify the SML lock keys
2403 * PARAMETERS
2404 * void
2405 * RETURN
2406 * kal_bool result
2407 * GLOBALS AFFECTED
2408 * SMLTMMOBJ
2409 *******************************************************************************/
2410kal_bool sml_tmo_movial_Verify(sml_tmo_movial_cat_enum cat,
2411 kal_uint8 * key,
2412 kal_uint8 len,
2413 kal_uint8 source)
2414{
2415 nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source];
2416 sml_tmo_movial_blob_key_struct *catkey = NULL;
2417 sml_tmo_movial_blob_meta_struct *meta = NULL;
2418 kal_bool result = KAL_FALSE;
2419 kal_uint16 length = 0;
2420 kal_uint16 plength = 0;
2421 kal_uint8 i = 0;
2422 kal_uint32 blob_iter_count = 0;
2423
2424 catkey = (sml_tmo_movial_blob_key_struct *) (*p->getItem)(cat, SML_TMO_MOVIAL_CAT_KEY, &length, source);
2425 meta = (sml_tmo_movial_blob_meta_struct *) (*p->getItem)(cat, SML_TMO_MOVIAL_CAT_META, &plength, source);
2426
2427 for (i = 0; i < SML_TMO_MOVIAL_BLOB_ITERATION_COUNT_SIZE-1; i++)
2428 {
2429 blob_iter_count += catkey->iteration_count[i];
2430 blob_iter_count = (blob_iter_count << 8);
2431 }
2432 blob_iter_count += catkey->iteration_count[SML_TMO_MOVIAL_BLOB_ITERATION_COUNT_SIZE-1];
2433
2434 if (blob_iter_count != 0) /* blob has valid key data */
2435 {
2436 kal_uint32 verify_result = 0;
2437
2438 verify_result = cust_sec_hck_verify(TYPE_HCK_PBKDF2_HMAC_SHA256_SALT128,
2439 (kal_char *)key, (kal_uint32)len,
2440 catkey->salt,
2441 blob_iter_count,
2442 catkey->hck);
2443
2444 if (verify_result == ERR_SEC_CHECK_HCK_SUCCESS)
2445 {
2446 result = KAL_TRUE;
2447 }
2448 }
2449
2450 if (result == KAL_TRUE)
2451 {
2452 MD_TRC_INFO_SML_KEY_VERIFY_PASS_INFO_CUST();
2453
2454 /* Local unlock success; Unlock device permanently */
2455 meta->cat_lock = SML_TMO_MOVIAL_CAT_UNLOCKED;
2456 smu_nvram_write(NVRAM_EF_L4_SML_TMO_MOVIAL_SIM_LOCK_LID, SML_TMO_MOVIAL_NVRAM_ACCESS_ID_UPDATE_CAT_LOCK, KAL_FALSE);
2457 }
2458 else
2459 {
2460 MD_TRC_INFO_SML_KEY_VERIFY_FAIL_INFO_CUST();
2461 }
2462
2463 return result;
2464}
2465
2466
2467kal_uint8 sml_tmo_movial_update_slb(void *blob, kal_uint8 source)
2468{
2469 kal_uint8 *psmlBlob = NULL;
2470 kal_uint8 error_cause = SML_TMO_MOVIAL_SLB_ERR_GENERIC;
2471 sml_tmo_movial_sim_lock_context_struct *pBlob = (sml_tmo_movial_sim_lock_context_struct *)blob;
2472
2473 if (NULL == pBlob)
2474 {
2475 MD_TRC_INFO_SML_TMO_RSU_EMPTY_BLOB();
2476 return SML_TMO_MOVIAL_SLB_ERR_BLOB_TOO_SHORT;
2477 }
2478
2479 if (KAL_FALSE == sml_tmo_movial_checkValidity(pBlob, source, &error_cause))
2480 {
2481 MD_TRC_INFO_SML_TMO_RSU_BLOB_VALIDITY_FAIL();
2482 return error_cause;
2483 }
2484
2485 psmlBlob = sml_tmo_movial_ConstructSmlBlob((sml_tmo_movial_sim_lock_context_struct *)pBlob, source);
2486
2487 if (NULL != psmlBlob)
2488 {
2489 sml_tmo_movial_Load(psmlBlob, source);
2490 free_ctrl_buffer(psmlBlob);
2491 error_cause = SML_TMO_MOVIAL_SLB_ERR_SUCCESS;
2492 }
2493
2494 return error_cause;
2495}
2496
2497
2498/*******************************************************************************
2499 * FUNCTION
2500 * sml_tmm_GetLockState
2501 * DESCRIPTION
2502 * This method is used to get SLB lock state
2503 * PARAMETERS
2504 * OUT lock state
2505 * IN source
2506 * RETURN
2507 * void
2508 * GLOBALS AFFECTED
2509 * none
2510 *******************************************************************************/
2511void sml_tmm_GetLockState(kal_uint8 *lock_state, kal_uint8 source)
2512{
2513 nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source];
2514 kal_uint16 length;
2515 kal_uint8 *slb_state;
2516
2517 slb_state = (kal_uint8 *)(*p->getItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_LOCK_OPERATION, &length, source);
2518
2519 kal_mem_cpy(lock_state, slb_state, 1);
2520}
2521
2522
2523/*******************************************************************************
2524 * FUNCTION
2525 * sml_tmm_GetUnlockTimeLeft
2526 * DESCRIPTION
2527 * This method is used to get SLB unlock time left in seconds
2528 * PARAMETERS
2529 * IN source
2530 * RETURN
2531 * unlock time left
2532 * GLOBALS AFFECTED
2533 * none
2534 *******************************************************************************/
2535kal_uint32 sml_tmm_GetUnlockTimeLeft(kal_uint8 source)
2536{
2537 nvram_ef_sml_tmo_movial_sim_lock_obj_struct *p = &pSMLTMMg[source];
2538 kal_uint16 length;
2539 kal_uint8 *slb_end_time;
2540 kal_uint32 duration_seconds = 0;
2541 kal_uint8 i;
2542
2543 slb_end_time = (kal_uint8 *)(*p->getItem)(SML_TMO_MOVIAL_CAT_NULL, SML_TMO_MOVIAL_CAT_UNLOCK_DURATION, &length, source);
2544
2545 for (i = 0; i < (SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION - 1); i++)
2546 {
2547 duration_seconds += slb_end_time[i];
2548 duration_seconds = (duration_seconds << 8);
2549 }
2550 duration_seconds += slb_end_time[SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION - 1];
2551
2552 MD_TRC_INFO_SML_TMO_RSU_GET_UNLOCK_TIME_LEFT(duration_seconds, sml_tmo_movial_seconds_to_expire);
2553
2554 if (sml_tmo_movial_seconds_to_expire >= duration_seconds)
2555 {
2556 return 0;
2557 }
2558 else
2559 {
2560 return (duration_seconds - sml_tmo_movial_seconds_to_expire);
2561 }
2562}
2563
2564
2565/*******************************************************************************
2566 * FUNCTION
2567 * sml_tmo_movial_ConstructFirstBlob
2568 * DESCRIPTION
2569 * This function construct full size Bolb (internal NV structure) from a variant length Blob received from AP
2570 * PARAMETERS
2571 * IN *pObj
2572 * OUT pLen
2573 * RETURN
2574 * kal_uint8 * construct data
2575 * GLOBALS AFFECTED
2576 * SMLTMMOBJ
2577 *******************************************************************************/
2578kal_uint8 *sml_tmo_movial_ConstructFirstBlob(kal_uint8 *pObj, kal_uint16 slb_len, kal_uint8 source)
2579{
2580 kal_uint16 sizeM, sizeN, sizeP;
2581 kal_uint16 length = 0;
2582 kal_uint16 idx;
2583 sml_tmo_movial_sim_lock_context_struct *pBlob;
2584 kal_uint8 cat_idx = 0;
2585
2586 MD_TRC_FUNC_SML_TMO_MOVIAL_CONSTRUCTFIRSTBLOB();
2587
2588 pBlob = (sml_tmo_movial_sim_lock_context_struct *)get_ctrl_buffer(SML_TMO_MOVIAL_MAX_BLOB_SIZE);
2589 kal_mem_set(pBlob, 0, SML_TMO_MOVIAL_MAX_BLOB_SIZE);
2590
2591 /* major_version + minor_version + protection_algorithm + lock_operation */
2592 pBlob->major_version = pObj[length++];
2593 pBlob->minor_version = pObj[length++];
2594 pBlob->protection_algorithm = pObj[length++];
2595 pBlob->lock_operation = pObj[length++];
2596
2597 /* imei */
2598 kal_mem_cpy(pBlob->imei, &(pObj[length]), SML_TMO_MOVIAL_BLOB_IMEI_SIZE);
2599 length += SML_TMO_MOVIAL_BLOB_IMEI_SIZE;
2600
2601 /* time stamp */
2602 kal_mem_cpy(pBlob->time_stamp, &(pObj[length]), SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE);
2603 length += SML_TMO_MOVIAL_BLOB_TIME_STAMP_SIZE;
2604
2605 /* Temporary unlock start timer */
2606 kal_mem_cpy(pBlob->start_time, &(pObj[length]), SML_TMO_MOVIAL_SIZE_OF_START_TIME);
2607 length += SML_TMO_MOVIAL_SIZE_OF_START_TIME;
2608
2609 /* Temporary unlock duration */
2610 kal_mem_cpy(pBlob->unlock_duration, &(pObj[length]), SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION);
2611 length += SML_TMO_MOVIAL_SIZE_OF_UNLOCK_DURATION;
2612
2613 /* length */
2614 kal_mem_cpy(pBlob->length, &(pObj[length]), SML_TMO_MOVIAL_BLOB_LENGTH_SIZE);
2615 length += SML_TMO_MOVIAL_BLOB_LENGTH_SIZE;
2616
2617 if (pBlob->protection_algorithm >= SML_TMO_MOVIAL_PROTECTION_SCHEME_SIZE)
2618 {
2619 free_ctrl_buffer(pBlob);
2620 return NULL;
2621 }
2622
2623 if (sml_tmo_movial_ValidateIMEI(pBlob->imei, KAL_FALSE, source) == KAL_FALSE)
2624 {
2625 MD_TRC_WARNING_SML_CHECK_IMEI_FAILED();
2626 }
2627
2628 idx = length;
2629
2630 for (cat_idx = SML_TMO_MOVIAL_CAT_N ; cat_idx < SML_TMO_MOVIAL_CAT_SIZE ; cat_idx++)
2631 {
2632 pBlob->cat[cat_idx].change_flag = pObj[idx++];
2633
2634 /* iteration_count, salt, hck */
2635 kal_mem_cpy(pBlob->key[cat_idx].iteration_count, &(pObj[idx]), SML_TMO_MOVIAL_BLOB_ITERATION_COUNT_SIZE);
2636 idx += SML_TMO_MOVIAL_BLOB_ITERATION_COUNT_SIZE;
2637
2638 kal_mem_cpy(pBlob->key[cat_idx].salt, &(pObj[idx]), SML_TMO_MOVIAL_BLOB_SALT_SIZE);
2639 idx += SML_TMO_MOVIAL_BLOB_SALT_SIZE;
2640
2641 kal_mem_cpy(pBlob->key[cat_idx].hck, &(pObj[idx]), SML_TMO_MOVIAL_BLOB_HCK_SIZE);
2642 idx += SML_TMO_MOVIAL_BLOB_HCK_SIZE;
2643
2644 /* check m,n,p */
2645 if (pObj[idx] > 0)
2646 {
2647 switch (cat_idx)
2648 {
2649 case SML_TMO_MOVIAL_CAT_N:
2650 sizeM = pObj[idx] * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_N;
2651 if (sizeM > SML_TMO_MOVIAL_BLOB_CAT_N_SIZE)
2652 {
2653 free_ctrl_buffer(pBlob);
2654 return NULL;
2655 }
2656
2657 pBlob->cat[cat_idx].num = pObj[idx++];
2658 kal_mem_cpy(pBlob->code_cat_n, &(pObj[idx]), sizeM);
2659 idx += sizeM;
2660 break;
2661
2662 case SML_TMO_MOVIAL_CAT_NS:
2663 sizeN = pObj[idx] * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_NS;
2664 if (sizeN > SML_TMO_MOVIAL_BLOB_CAT_NS_SIZE)
2665 {
2666 free_ctrl_buffer(pBlob);
2667 return NULL;
2668 }
2669
2670 pBlob->cat[cat_idx].num = pObj[idx++];
2671 kal_mem_cpy(pBlob->code_cat_ns, &(pObj[idx]), sizeN);
2672 idx += sizeN;
2673 break;
2674
2675 case SML_TMO_MOVIAL_CAT_SP:
2676 sizeP = pObj[idx] * SML_TMO_MOVIAL_BLOB_SIZE_OF_CAT_SP;
2677 if (sizeP > SML_TMO_MOVIAL_BLOB_CAT_SP_SIZE)
2678 {
2679 free_ctrl_buffer(pBlob);
2680 return NULL;
2681 }
2682
2683 pBlob->cat[cat_idx].num = pObj[idx++];
2684 kal_mem_cpy(pBlob->code_cat_sp, &(pObj[idx]), sizeP);
2685 idx += sizeP;
2686 break;
2687
2688 default:
2689 break;
2690 }
2691 }
2692 else /* m/n/p = 0 */
2693 {
2694 /* memset ensures pBlob->cat[cat_idx].num set to 0 */
2695 idx += 1;
2696 }
2697 }
2698
2699 if (sml_tmo_movial_ValidateConfigData(pBlob) == KAL_FALSE)
2700 {
2701 free_ctrl_buffer(pBlob);
2702 return NULL;
2703 }
2704
2705 kal_mem_cpy(pBlob->signature, &(pObj[idx]), SML_TMO_MOVIAL_BLOB_SIZE_OF_SIGNATURE);
2706
2707 sml_Dump("constructed blob", (kal_uint8 *)pBlob, SML_TMO_MOVIAL_MAX_BLOB_SIZE);
2708
2709 return (kal_uint8 *)pBlob;
2710}
2711
2712#ifdef __TMO_RSU_OTP__
2713static kal_bool custom_check_is_default_tmo_blob(kal_uint8 *imei)
2714{
2715 kal_uint8 otp_default_imei[SML_TMO_MOVIAL_BLOB_IMEI_SIZE] = {0x00};
2716
2717 if (kal_mem_cmp(&imei[0], &otp_default_imei[0], SML_TMO_MOVIAL_BLOB_IMEI_SIZE) == 0)
2718 {
2719 return KAL_TRUE;
2720 }
2721 else
2722 {
2723 return KAL_FALSE;
2724 }
2725}
2726#endif /* __TMO_RSU_OTP__ */
2727
2728/*******************************************************************************
2729 * FUNCTION
2730 * custom_check_is_default_imei
2731 * DESCRIPTION
2732 * Check if the IMEI is default IMEI
2733 * PARAMETERS
2734 * imei [kal_uint8 *]
2735 * RETURN
2736 * kal_bool
2737*******************************************************************************/
2738kal_bool custom_check_is_default_imei(kal_uint8 *imei)
2739{
2740#if defined(__SECURITY_OTP__) && defined(__NVRAM_OTP__)
2741 kal_uint8 default_imei_bcd[8] = {0x00};
2742#else
2743 kal_uint8 default_imei_bcd[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2744#endif
2745
2746 if (NULL == imei)
2747 {
2748 return KAL_FALSE;
2749 }
2750
2751 if (kal_mem_cmp(&imei[0], &default_imei_bcd[0], 8) == 0)
2752 {
2753 return KAL_TRUE;
2754 }
2755 else
2756 {
2757 return KAL_FALSE;
2758 }
2759}
2760
2761void custom_tmo_movial_rsu_get_pub_key_handle(kal_uint8 index,
2762 TYPE_CUST_CHL_KEY *key1, TYPE_CUST_CHL_KEY *key2)
2763{
2764 TYPE_CUST_CHL_KEY pub_key_group[][2] = {
2765 // Pub Key 1, Pub Key 2
2766 {CUST_TM_PUB_KEY1, CUST_TM_PUB_KEY2}, // index == 0
2767 // Add handles of new pub keys sets here
2768 };
2769
2770 #define TMO_MOVIAL_KEY_SET_MAX_NUM (sizeof(pub_key_group)/sizeof(pub_key_group[0]))
2771
2772 index = index > (TMO_MOVIAL_KEY_SET_MAX_NUM - 1) ? 0 : index;
2773
2774 if (NULL != key1)
2775 {
2776 *key1 = pub_key_group[index][0];
2777 MD_TRC_INFO_SML_RSU_PUB_KEY_HANDLE((*key1));
2778 }
2779
2780 if (NULL != key2)
2781 {
2782 *key2 = pub_key_group[index][1];
2783 MD_TRC_INFO_SML_RSU_PUB_KEY_HANDLE((*key2));
2784 }
2785
2786 return;
2787}
2788#endif /* L4_NOT_PRESENT */
2789#endif /* !defined(__MAUI_BASIC__) */