comparison src/aci2/aci_ext/aci_ext_pers.c @ 3:93999a60b835

src/aci2, src/condat2: import of g23m/condat source pieces from TCS211
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 26 Sep 2016 00:29:36 +0000
parents
children
comparison
equal deleted inserted replaced
2:c41a534f33c6 3:93999a60b835
1 /*
2 +-----------------------------------------------------------------------------
3 | Project :
4 | Modul : J:\g23m-aci\aci_ext\aci_ext_pers.c
5 +-----------------------------------------------------------------------------
6 | Copyright 2002 Texas Instruments Berlin, AG
7 | All rights reserved.
8 |
9 | This file is confidential and a trade secret of Texas
10 | Instruments Berlin, AG
11 | The receipt of or possession of this file does not convey
12 | any rights to reproduce or disclose its contents or to
13 | manufacture, use, or sell anything it may describe, in
14 | whole, or in part, without the specific written consent of
15 | Texas Instruments Berlin, AG.
16 +-----------------------------------------------------------------------------
17 | Purpose :
18 +-----------------------------------------------------------------------------
19 */
20 #include "aci_all.h"
21
22 #include "aci_cmh.h"
23 #include "ati_cmd.h"
24 #include "aci_cmd.h"
25
26 #ifdef FAX_AND_DATA
27 #include "aci_fd.h"
28 #endif /* of #ifdef FAX_AND_DATA */
29
30 #ifndef WIN32
31 #define ACI_PERSONALISTION_USE_FFS
32 #endif
33
34 #include "aci.h"
35 #include "psa.h"
36 #include "psa_sim.h"
37 #include "psa_sms.h"
38 #include "psa_mmi.h"
39 #include "cmh.h"
40 #include "phb.h"
41 #include "aoc.h"
42
43 #include "psa_sim.h" /* simShrdPrm */
44
45 #include "aci_ext_pers.h"
46 #include "aci_slock.h"
47
48 #ifdef SIM_PERS
49 #include "general.h" // inluded for UINT8 compilation error in sec_drv.h
50 #include "sec_drv.h"
51 #endif
52
53 #include "pcm.h" /* EF_SIMLCKEXT */
54
55 #ifdef MMI_SIMLOCK_TEST
56 #define ACI_PERSONALISTION_USE_FFS
57 #endif
58
59 #ifdef ACI_PERSONALISTION_USE_FFS
60 #include "ffs/ffs.h"
61 #include "ffs_coat.h"
62 #endif /* ACI_PERSONALISTION_USE_FFS */
63
64
65
66 #define SLOCK_PCM_NRM 1 /* SIM lock data is stored as SIMLOCK to the PCM */
67 #define SLOCK_PCM_EXT 2 /* SIM lock data is stored as SIMLOCKEXT to the PCM */
68
69 #ifdef SIM_PERS
70 #define TRUNCATION_KEY_LEN 8 /* */
71 #endif
72
73 #ifdef _SIMULATION_
74 EF_SIMLCKEXT simlock_pcm_memory; /* emulates the PCM memory in WIN32 environment. */
75 #endif
76
77 #include "aci_ext_pers_cus.h" /* the customer specific personalisation data. */
78
79
80
81 LOCAL void aci_ext_personalisation_MMI_save( void );
82
83 static BOOL in_firstsimpersonalisation = FALSE; /* this will be set when the phone is powered up after FIRST_SIMLOCK */
84 static BOOL pre_firstsimpersonalisation = FALSE; /* this will be set when a FIRST_SIM_LOCK is applied. All further locks
85 will not be applied but only prepare the lock for the next power-cycle */
86 LOCAL void decodeB2A (U8 *bcd, U8 bcd_len, U8 *ascii); /* decode a BCD to ASCII */
87 LOCAL void encodeA2B (char *ascii, UBYTE *bcd, UBYTE bcd_len); /* encode ASCII to BCD, fill up with 0xf */
88 #ifdef SIM_PERS
89 EXTERN T_SEC_DRV_CONFIGURATION *cfg_data ;
90 EXTERN T_ACI_SIM_CONFIG aci_slock_sim_config; /* SIM configuration, initialised by a T_SIM_MMI_INSERT_IND */
91 #endif
92
93
94
95
96 /*
97 +------------------------------------------------------------------------------
98 | Function : aci_ext_personalisation_init
99 +------------------------------------------------------------------------------
100 | Description : Initialisation of this extension. Might be used to initialise variables, set temporary data to default values and so on.
101 This method will be called once before any other public method of this extension.
102 |
103 | Parameters : void
104 |
105 | Return : void
106 |
107 +------------------------------------------------------------------------------
108 */
109
110
111 void aci_ext_personalisation_init( void )
112 {
113 #ifdef SIM_PERS
114 T_SIMLOCK_TYPE lock_type;
115 T_SEC_DRV_RETURN status ;
116 #endif
117
118 TRACE_FUNCTION("aci_ext_personalisation_init()");
119
120 #ifndef MMI_SIMLOCK_TEST
121
122 #ifdef SIM_PERS
123
124 for (lock_type=SIMLOCK_NETWORK;lock_type<= SIMLOCK_FIRST_SIM ;lock_type++) //prateek: changed loop till simlock_first_sim
125 {
126 switch (lock_type)
127 {
128 case SIMLOCK_NETWORK:
129 status =sec_get_REC (lock_type, &personalisation_nw);
130 if (status NEQ SEC_DRV_RET_Ok)
131 personalisation_nw = NULL;
132 else
133 {
134 AciSLockShrd.status[lock_type]=(T_SIMLOCK_STATUS)personalisation_nw->Header.Status;
135 AciSLockShrd.dependency[lock_type]=personalisation_nw->Header.Dependency;
136 }
137 break;
138
139 case SIMLOCK_NETWORK_SUBSET:
140 status =sec_get_REC (lock_type, &personalisation_ns);
141 if (status NEQ SEC_DRV_RET_Ok)
142 personalisation_ns= NULL;
143 else
144 {
145 AciSLockShrd.status[lock_type]=(T_SIMLOCK_STATUS)personalisation_ns->Header.Status;
146 AciSLockShrd.dependency[lock_type]=personalisation_ns->Header.Dependency;
147 }
148 break;
149
150 case SIMLOCK_SERVICE_PROVIDER:
151 status =sec_get_REC (lock_type, &personalisation_sp);
152 if (status NEQ SEC_DRV_RET_Ok)
153 personalisation_sp= NULL;
154 else
155 {
156 AciSLockShrd.status[lock_type]=(T_SIMLOCK_STATUS)personalisation_sp->Header.Status;
157 AciSLockShrd.dependency[lock_type]=personalisation_sp->Header.Dependency;
158 }
159 break;
160
161 case SIMLOCK_CORPORATE:
162 status =sec_get_REC (lock_type, &personalisation_cp);
163 if (status NEQ SEC_DRV_RET_Ok)
164 personalisation_cp = NULL;
165 else
166 {
167 AciSLockShrd.status[lock_type]=(T_SIMLOCK_STATUS)personalisation_cp->Header.Status;
168 AciSLockShrd.dependency[lock_type]=personalisation_cp->Header.Dependency;
169 }
170 break;
171
172 case SIMLOCK_SIM:
173 status =sec_get_REC (lock_type, &personalisation_sim);
174 if (status NEQ SEC_DRV_RET_Ok)
175 personalisation_sim = NULL;
176 else
177 {
178 AciSLockShrd.status[lock_type]=(T_SIMLOCK_STATUS)personalisation_sim->Header.Status;
179 AciSLockShrd.dependency[lock_type]=personalisation_sim->Header.Dependency;
180 }
181 break;
182
183 case SIMLOCK_FIRST_SIM:
184 status =sec_get_REC (lock_type, &personalisation_first_sim);
185 if (status NEQ SEC_DRV_RET_Ok)
186 {
187 TRACE_FUNCTION("personalisation_first_sim = NULL");
188 personalisation_first_sim = NULL;
189 }
190 else
191 {
192 AciSLockShrd.status[lock_type]=(T_SIMLOCK_STATUS)personalisation_first_sim->Header.Status;
193 AciSLockShrd.dependency[lock_type]=personalisation_first_sim->Header.Dependency;
194 }
195 break;
196 }
197 }
198 #endif //SIM_PERS
199
200 #else /*for mmi testing, just read FFS*/ //MMI_SIMLOCK_TEST
201
202 #endif //MMI_SIMLOCK_TEST
203 }
204
205 #ifdef SIM_PERS
206
207 /*
208 +------------------------------------------------------------------------------
209 | Function : aci_ext_personalisation_free
210 +------------------------------------------------------------------------------
211 | Description : Free the MEPD structure Memory
212 |
213 | Parameters : void
214 |
215 | Return : void
216 |
217 +------------------------------------------------------------------------------
218 */
219 void aci_ext_personalisation_free( void )
220 {
221 T_SIMLOCK_TYPE lock_type;
222
223 for (lock_type=SIMLOCK_NETWORK;lock_type<=SIMLOCK_FIRST_SIM;lock_type++)
224 {
225 switch (lock_type)
226 {
227 case SIMLOCK_NETWORK:
228 if(personalisation_nw NEQ NULL)
229 {
230 if(personalisation_nw->pBody NEQ NULL)
231 {
232 MFREE(personalisation_nw->pBody);
233 }
234 MFREE(personalisation_nw);
235 }
236 break;
237
238 case SIMLOCK_NETWORK_SUBSET:
239 if(personalisation_ns NEQ NULL)
240 {
241 if(personalisation_ns->pBody NEQ NULL)
242 {
243 MFREE(personalisation_ns->pBody);
244 }
245 MFREE(personalisation_ns);
246 }
247 break ;
248
249 case SIMLOCK_SERVICE_PROVIDER:
250 if(personalisation_sp NEQ NULL)
251 {
252 if(personalisation_sp->pBody NEQ NULL)
253 {
254 MFREE(personalisation_sp->pBody);
255 }
256 MFREE(personalisation_sp);
257 }
258 break ;
259
260 case SIMLOCK_CORPORATE:
261 if(personalisation_cp NEQ NULL)
262 {
263 if(personalisation_cp->pBody NEQ NULL)
264 {
265 MFREE(personalisation_cp->pBody);
266 }
267 MFREE(personalisation_cp);
268 }
269 break ;
270
271 case SIMLOCK_SIM:
272 if(personalisation_sim NEQ NULL)
273 {
274 if(personalisation_sim->pBody NEQ NULL)
275 {
276 MFREE(personalisation_sim->pBody);
277 }
278 MFREE(personalisation_sim);
279 }
280 break ;
281
282 case SIMLOCK_FIRST_SIM:
283 if(personalisation_first_sim NEQ NULL)
284 {
285 MFREE(personalisation_first_sim);
286 }
287 break;
288 }
289 }
290 }
291
292
293
294 /*
295 ACI extension method for retrieving the status of a single personalisation type.
296 The personalisation status is stored in a separate customer managed memory area
297 and the customer has to implement this extension method to return the actual status
298 of the questioned personalisation type.
299 */
300 T_SIMLOCK_STATUS aci_ext_personalisation_get_status( T_SIMLOCK_TYPE personalisation_type )
301 {
302 TRACE_FUNCTION("aci_ext_personalisation_get_status()");
303 #ifdef SIM_PERS
304 switch (personalisation_type)
305 {
306 case SIMLOCK_FIRST_SIM: /* should not occour */
307 case SIMLOCK_SIM:
308 if(personalisation_sim NEQ NULL)
309 return personalisation_sim->Header.Status;
310 else
311 return SIMLOCK_FAIL;
312
313 case SIMLOCK_NETWORK:
314 if(personalisation_nw NEQ NULL)
315 return personalisation_nw->Header.Status;
316 else
317 return SIMLOCK_FAIL;
318
319 case SIMLOCK_NETWORK_SUBSET:
320 if(personalisation_ns NEQ NULL)
321 return personalisation_ns->Header.Status;
322 else
323 return SIMLOCK_FAIL;
324
325 case SIMLOCK_SERVICE_PROVIDER:
326 if(personalisation_sp NEQ NULL)
327 return personalisation_sp->Header.Status;
328 else
329 return SIMLOCK_FAIL;
330
331 case SIMLOCK_CORPORATE:
332 if(personalisation_cp NEQ NULL)
333 return personalisation_cp->Header.Status;
334 else
335 return SIMLOCK_FAIL;
336
337 default: return SIMLOCK_FAIL; /* should not occour */
338 }
339 #endif
340 }
341
342
343 /*
344 +------------------------------------------------------------------------------
345 | Function : aci_ext_personalisation_verify_password
346 +------------------------------------------------------------------------------
347 | Description : ACI extension method for verifying the passowrd.
348 |f the password is false then the counter is increased. If maxcnt is reached then the key
349 |will been blocked. If the password is correct then the counter is set to 0
350 |
351 | Parameters : personalisation_type - category type (Network,Network subset, Service Provider,Corporate,SIM actegory)
352 | : passwd - category password
353 |
354 | Return : T_SIMLOCK_STATUS - Return SIMLOCK_DISABLED if compare key pass.
355 | - Return SIMLOCK_FAIL if compare key fails.
356 | - Return SIMLOCK_BLOCKED if FC counter is greater than
357 | FC Max.
358 +------------------------------------------------------------------------------
359 */
360
361
362 T_SIMLOCK_STATUS aci_ext_personalisation_verify_password( T_SIMLOCK_TYPE personalisation_type, char *passwd)
363 {
364
365 T_SEC_DRV_RETURN ret;
366 UINT8 key_len = 0; /* For truncation check -Samir */
367
368
369 TRACE_FUNCTION("aci_ext_personalisation_verify_password()");
370
371
372 aci_slock_set_CFG();
373 if(cfg_data EQ NULL)
374 {
375 return SIMLOCK_FAIL;
376 }
377
378 if(cfg_data->Flags & SEC_DRV_HDR_FLAG_Truncation)
379 {
380 key_len = TRUNCATION_KEY_LEN;
381 }
382 ret = sec_cmp_KEY(personalisation_type, passwd, key_len) ;
383 MFREE(cfg_data);
384
385 switch (ret)
386 {
387 case SEC_DRV_RET_Ok :
388 return SIMLOCK_DISABLED;
389 break;
390
391 case SEC_DRV_RET_KeyWrong :
392 case SEC_DRV_RET_KeyMismatch:
393 /*Increment failure counter since input password is wrong*/
394 ret = sec_FC_Increment();
395 aci_slock_set_CFG();
396 if(cfg_data EQ NULL)
397 {
398 return SIMLOCK_FAIL;
399 }
400 if(cfg_data->FC_Current >= cfg_data->FC_Max)
401 {
402 MFREE(cfg_data);
403 return SIMLOCK_BLOCKED;
404 }
405 else
406 {
407 MFREE(cfg_data);
408 return SIMLOCK_FAIL;
409 }
410 break;
411
412 default:/*ERROR!- invalid input to sec_cmp_key OR some error in sec_cmp_key*/
413 return SIMLOCK_FAIL;
414 break;
415 }
416 }
417
418
419 /*
420 +------------------------------------------------------------------------------
421 | Function : aci_ext_personalisation_change_password
422 +------------------------------------------------------------------------------
423 | Description : ACI extension method for verifying the passowrd.
424 |f the password is false then the counter is increased. If maxcnt is reached then the key
425 |will been blocked. If the password is correct then the counter is set to 0
426 |
427 | Parameters : personalisation_type - category type (Network,Network subset, Service Provider,Corporate,SIM actegory)
428 | : passwd - category password
429 | : new_passwd - New Password
430
431 | Return : T_SIMLOCK_STATUS - Return OPER_SUCCESS if changes password is successfull.
432 | - Return OPER_FAIL if changes password is fail.
433 |
434 +------------------------------------------------------------------------------
435 */
436
437 T_SIMLOCK_STATUS aci_ext_personalisation_change_password( T_SIMLOCK_TYPE personalisation_type, char *passwd, char *new_passwd )
438 {
439 T_SEC_DRV_RETURN retstat;
440
441 retstat = sec_set_KEY (personalisation_type, passwd, new_passwd, 0);
442 switch(retstat)
443 {
444 case SEC_DRV_RET_Ok :
445 return OPER_SUCCESS;
446 case SEC_DRV_RET_FCExeeded :
447 AciSLockShrd.blocked = TRUE;
448 return SIMLOCK_BLOCKED ;
449 default :
450 return OPER_FAIL;
451 }
452
453 }
454
455
456 /*
457 +------------------------------------------------------------------------------
458 | Function : aci_ext_personalisation_set_status
459 +------------------------------------------------------------------------------
460 | Description : ACI extension method for lock/unlock the category record
461 |
462 | Parameters : personalisation_type - category type (Network,Network subset, Service Provider,Corporate,SIM actegory)
463 | : lock - SIMLOCK_ENABLED to lock the category
464 | - SIMLOCK_DISABLED to unlock the category
465 | : passwd - category lock/unlock password
466 |
467 |
468 | Return : T_SIMLOCK_STATUS - Return SIMLOCK_ENABLED if lock is successfull.
469 | - Return SIMLOCK_DISABLED if unlock is successfull.
470 | - Return SIMLOCK_FAIL if lock or unlock fails
471 | - Return SIMLOCK_BLOCKED if FC exeeded for wrong password
472 | - Return SIMLOCK_FAIL if lock/unlock fail
473 +------------------------------------------------------------------------------
474 */
475
476 T_SIMLOCK_STATUS aci_ext_personalisation_set_status( T_SIMLOCK_TYPE personalisation_type,
477 T_SIMLOCK_STATUS lock, char* passwd)
478 {
479
480 //#ifdef SIM_PERS
481 int rec_num = personalisation_type;
482 int key_len = 0;
483 T_SEC_DRV_RETURN ret;
484
485 TRACE_FUNCTION("aci_ext_personalisation_set_status()");
486
487 if(lock EQ SIMLOCK_ENABLED)
488 {
489 ret=sec_rec_Lock(rec_num, passwd, key_len,0xffff/*depend mask*/);/*aci_ext_personalisation_verify_password(personalisation_type, passwd);*/
490 if (ret EQ SEC_DRV_RET_Ok){
491 return SIMLOCK_ENABLED;
492 }
493 else{
494 return SIMLOCK_FAIL;
495 }
496 }
497
498 if(lock EQ SIMLOCK_DISABLED)
499 {
500 if(cfg_data->Flags & SEC_DRV_HDR_FLAG_Truncation)
501 {
502 key_len = TRUNCATION_KEY_LEN;
503 }
504 ret = sec_rec_Unlock(rec_num,TEMPORARY_UNLOCK,passwd,key_len,0xffff/*depend mask*/);
505 if (ret EQ SEC_DRV_RET_Ok){
506 return SIMLOCK_DISABLED;
507 }
508 else{
509 if(ret EQ SEC_DRV_RET_FCExeeded)
510 {
511 return SIMLOCK_BLOCKED;
512 }
513 return SIMLOCK_FAIL;
514 }
515 }
516 return SIMLOCK_FAIL;
517 //#endif
518 }
519
520
521
522
523 //#ifdef SIM_PERS
524
525 /*
526 +------------------------------------------------------------------------------
527 | Function : aci_ext_slock_reset_fc
528 +------------------------------------------------------------------------------
529 | Description : For Failure Counter reset. Uses Security Drv. method to reset FC
530 |
531 | Parameters : fckey - Password for resetting FC counter
532 |
533 |
534 | Return : T_OPER_RET_STATUS - Return OPER_SUCCESS if FC reset is successfull.
535 | - Return OPER_FAIL if FC reset is fail
536 |
537 +------------------------------------------------------------------------------
538 */
539
540
541 T_OPER_RET_STATUS aci_ext_slock_reset_fc(char *fckey)
542 {
543 T_SEC_DRV_RETURN retstat;
544
545 TRACE_FUNCTION("aci_ext_slock_reset_fc ()");
546
547 if ((retstat= sec_FC_Reset(fckey,0)) NEQ SEC_DRV_RET_Ok)
548 {
549 return OPER_FAIL;
550 }
551 else{
552 return OPER_SUCCESS;
553 }
554 }
555
556
557
558 /*
559 +------------------------------------------------------------------------------
560 | Function : aci_ext_slock_sup_info
561 +------------------------------------------------------------------------------
562 | Description : For Supplementary Info( e.g. FC MAX, FC Current value).
563 |
564 | Parameters : sup_info -which has the element info type and Data value.
565 |
566 |
567 | Return : T_OPER_RET_STATUS - Return OPER_SUCCESS if successfully read the Info type data
568 | value from security driver. Info type data value is filled in this
569 | Function
570 | - Return OPER_FAIL if unable to read Info type data value from
571 | security driverl
572 |
573 +------------------------------------------------------------------------------
574 */
575
576
577 T_OPER_RET_STATUS aci_ext_slock_sup_info (T_SUP_INFO *sup_info)
578 {
579 T_SEC_DRV_RETURN retstat;
580 T_SEC_DRV_CONFIGURATION *cfg_data;
581
582 TRACE_FUNCTION("aci_ext_slock_sup_info ()");
583
584 if ((retstat= sec_get_CFG(&cfg_data)) NEQ SEC_DRV_RET_Ok)
585 return OPER_FAIL;
586 else
587 {
588 switch(sup_info->infoType )
589 {
590 case(FCMAX ): sup_info->datavalue = cfg_data->FC_Max; break;
591 case(FCATTEMPTSLEFT): sup_info->datavalue = ((cfg_data->FC_Max) - (cfg_data->FC_Current)); break;
592 case(FCRESETFAILMAX ): sup_info->datavalue = cfg_data->FC_Reset_Fail_Max ; break;
593 case(FCRESETFAILATTEMPTSLEFT): sup_info->datavalue = ((cfg_data->FC_Reset_Fail_Max) - (cfg_data->FC_Reset_Fail_Current)); break;
594 case(FCRESETSUCCESSMAX ): sup_info->datavalue = cfg_data->FC_Reset_Success_Max ; break;
595 case(FCRESETSUCCESSATTEMPTSLEFT): sup_info->datavalue = ((cfg_data->FC_Reset_Success_Max) - (cfg_data->FC_Reset_Success_Current)); break;
596 case (TIMERFLAG): sup_info->datavalue =(cfg_data->Flags & SEC_DRV_HDR_FLAG_Unlock_Timer)?(1):(0) ;break;
597 case (ETSIFLAG) : sup_info->datavalue =(cfg_data->Flags & SEC_DRV_HDR_FLAG_ETSI_Flag)?(1):(0) ; break;
598 case (AIRTELINDFLAG) : sup_info->datavalue =(cfg_data->Flags & SEC_DRV_HDR_FLAG_Airtel_Ind)?(1):(0) ; break;
599 } /*end of switch*/
600
601 MFREE(cfg_data);/* deallocate configuration data allocated from Security Driver; */
602 return OPER_SUCCESS;
603 }
604 }
605
606
607 /*
608 +------------------------------------------------------------------------------
609 | Function : aci_ext_auto_personalise
610 +------------------------------------------------------------------------------
611 | Description : It Auto personalise the sim. If Add new IMSI flag set and If Code is not present
612 | then adds the code in the MEPD data and lock the category ( Network, Sub Network,
613 | sim )
614 | Parameters : void
615 |
616 |
617 | Return : void
618 |
619 +------------------------------------------------------------------------------
620 */
621
622 T_AUTOLOCK_STATUS aci_ext_auto_personalise(T_SIMLOCK_TYPE current_lock)
623 {
624 UBYTE imsi_sim[MAX_IMSI_LEN+1];
625 T_SIMLOCK_TYPE type;
626 static UINT16 flag = 0xffff;
627 UINT16 dependMask = 0xffff;
628
629 TRACE_FUNCTION("aci_ext_auto_personalise()");
630
631 psaSIM_decodeIMSI(simShrdPrm.imsi.field, simShrdPrm.imsi.c_field, (char *)imsi_sim);
632
633 if((AciSLockShrd.dependency[SIMLOCK_FIRST_SIM] & NW_AUTO_LOCK)AND (flag & NW_AUTO_LOCK))
634 {
635 type = SIMLOCK_NETWORK;
636 sim_code_present_in_me = FALSE;
637 aci_slock_check_NWlock(imsi_sim,1);
638 flag &= ~(NW_AUTO_LOCK);
639
640 if(sim_code_present_in_me EQ FALSE)
641 {
642 aci_ext_add_code(type);
643 }
644 }
645
646 if((AciSLockShrd.dependency[SIMLOCK_FIRST_SIM] & NS_AUTO_LOCK)AND (flag & NS_AUTO_LOCK))
647 {
648 type = SIMLOCK_NETWORK_SUBSET;
649 flag &= ~(NS_AUTO_LOCK);
650 sim_code_present_in_me = FALSE;
651 aci_slock_check_NSlock(imsi_sim,1);
652 if(sim_code_present_in_me EQ FALSE)
653 {
654 aci_ext_add_code(type);
655 }
656 }
657
658 if((AciSLockShrd.dependency[SIMLOCK_FIRST_SIM] & SIM_AUTO_LOCK ) AND (flag & SIM_AUTO_LOCK))
659 {
660 flag &= ~(SIM_AUTO_LOCK);
661 type = SIMLOCK_SIM;
662 sim_code_present_in_me = FALSE;
663 aci_slock_check_SMlock(imsi_sim,1);
664 if(sim_code_present_in_me EQ FALSE)
665 {
666 aci_ext_add_code(type);
667 }
668 }
669
670 if((AciSLockShrd.dependency[SIMLOCK_FIRST_SIM] & SP_AUTO_LOCK) AND (flag & SP_AUTO_LOCK))
671 {
672 if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
673 {
674 if(aci_slock_sim_config.sim_read_gid1 EQ FALSE)
675 {
676 aci_slock_sim_read_sim(SIM_GID1, NOT_PRESENT_8BIT, MAX_GID);
677 return AUTOLOCK_EXCT ;
678 }
679 else
680 {
681 type = SIMLOCK_SERVICE_PROVIDER;
682 sim_code_present_in_me = FALSE;
683 aci_slock_check_SPlock(imsi_sim,1);
684 TRACE_FUNCTION_P1("SP sim_code_present_in_me = %d", sim_code_present_in_me);
685 switch(sim_code_present_in_me)
686 {
687 case FALSE :
688 aci_ext_add_code(type);
689 break;
690 case CHECK_FAIL :
691 dependMask &= ~(SP_AUTO_LOCK) ;
692 break;
693 case TRUE :
694 break;
695 }
696 flag &= ~(SP_AUTO_LOCK);
697
698 }
699 }
700 else
701 {
702 flag &= ~(SP_AUTO_LOCK);
703 dependMask &= ~(SP_AUTO_LOCK) ;
704 }
705 }
706
707
708 if((AciSLockShrd.dependency[SIMLOCK_FIRST_SIM] & CP_AUTO_LOCK)AND (flag & CP_AUTO_LOCK))
709 {
710
711 if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
712 {
713 if(aci_slock_sim_config.sim_read_gid1 EQ FALSE)
714 {
715 aci_slock_sim_read_sim(SIM_GID1, NOT_PRESENT_8BIT, MAX_GID);
716 return AUTOLOCK_EXCT ;
717 }
718 }
719
720 if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl2))
721 {
722 if(aci_slock_sim_config.sim_read_gid2 EQ FALSE)
723 {
724 aci_slock_sim_read_sim(SIM_GID2, NOT_PRESENT_8BIT, MAX_GID);
725 return AUTOLOCK_EXCT ;
726 }
727 }
728
729 if(psaSIM_ChkSIMSrvSup(SRV_GrpLvl1) AND psaSIM_ChkSIMSrvSup(SRV_GrpLvl2))
730 {
731 type = SIMLOCK_CORPORATE;
732 sim_code_present_in_me = FALSE;
733 aci_slock_check_CPlock(imsi_sim,1);
734 switch(sim_code_present_in_me)
735 {
736 case FALSE :
737 aci_ext_add_code(type);
738 break;
739 case CHECK_FAIL :
740 dependMask &= ~(CP_AUTO_LOCK) ;
741 break;
742 case TRUE :
743 break;
744 }
745 flag &= ~(CP_AUTO_LOCK);
746 }
747 else
748 {
749 flag &= ~(CP_AUTO_LOCK);
750 dependMask &= ~(CP_AUTO_LOCK) ;
751 }
752
753 }
754
755
756 sec_rec_Lock(SIMLOCK_FIRST_SIM,NULL,0,dependMask);
757 return AUTOLOCK_CMPL ;
758
759 }
760
761
762
763
764 /*
765 +------------------------------------------------------------------------------
766 | Function : aci_ext_add_code
767 +------------------------------------------------------------------------------
768 | Description : It append the category code in MEPD. It foolows FIFO procedure while adding the code
769 | Parameters : type -- category type (Network,Network subset, Service Provider,Corporate,SIM actegory)
770 | Return : void
771 |
772 +------------------------------------------------------------------------------
773 */
774
775
776 void aci_ext_add_code(T_SIMLOCK_TYPE type)
777 {
778 UINT16 index =0;
779 UBYTE max_num_user_codes;
780 UBYTE num_user_codes;
781 UBYTE curr_user_code_index;
782 UBYTE imsi_field[20];
783
784 TRACE_FUNCTION("aci_ext_add_code()");
785 switch (type)
786 {
787 case SIMLOCK_NETWORK :
788 max_num_user_codes =((UBYTE *) personalisation_nw->pBody)[index];
789 index += MAX_NUM_USERCODE_SIZE;
790 index += NUM_OPCODE_SIZE ;
791 index += OPCODE_LEN_SIZE + ((UBYTE *) personalisation_nw->pBody)[OPCODE_LEN_INDEX];
792
793 num_user_codes = ((UBYTE *)personalisation_nw->pBody)[index];
794 index +=NUM_USER_CODE_SIZE;
795 curr_user_code_index = ((UBYTE *)personalisation_nw->pBody)[index];
796 index += CURR_USER_CODE_INDEX_SIZE ;
797
798 memcpy(imsi_field,simShrdPrm.imsi.field,simShrdPrm.imsi.c_field);
799 if(simShrdPrm.mnc_len EQ 3)
800 imsi_field[NW_CODE_LEN-1] |= 0xf0;
801 else
802 imsi_field[NW_CODE_LEN-1] |= 0xff;
803
804 /*
805 * If no user code is present, curr_user_code_index will be ff. After that, curr_user_code_index starts from 0
806 */
807 if((curr_user_code_index EQ 0xff) || (curr_user_code_index EQ max_num_user_codes -1))
808 curr_user_code_index = 0;
809 else
810 curr_user_code_index++;
811
812 if(num_user_codes < max_num_user_codes)
813 num_user_codes++;
814
815 memcpy(&((UBYTE *)personalisation_nw->pBody)[index + curr_user_code_index*NW_CODE_LEN/*multiplication added*/],imsi_field,NW_CODE_LEN);
816 ((UBYTE *)personalisation_nw->pBody)[index - CURR_USER_CODE_INDEX_SIZE] = curr_user_code_index;
817 ((UBYTE *)personalisation_nw->pBody)[index - CURR_USER_CODE_INDEX_SIZE - NUM_USER_CODE_SIZE] = num_user_codes;
818 sec_set_REC(type, personalisation_nw);
819 break;
820
821
822 case SIMLOCK_NETWORK_SUBSET :
823 max_num_user_codes = ((UBYTE *)personalisation_ns->pBody)[index];
824 index += MAX_NUM_USERCODE_SIZE;
825 index += NUM_OPCODE_SIZE ;
826 index += OPCODE_LEN_SIZE + ((UBYTE *) personalisation_ns->pBody)[OPCODE_LEN_INDEX];
827
828 num_user_codes = ((UBYTE *) personalisation_ns->pBody)[index];
829 index +=NUM_USER_CODE_SIZE;
830 curr_user_code_index = ((UBYTE *)personalisation_ns->pBody)[index];
831 index += CURR_USER_CODE_INDEX_SIZE ;
832
833 memcpy(imsi_field,simShrdPrm.imsi.field,simShrdPrm.imsi.c_field);
834 if(simShrdPrm.mnc_len EQ 3)
835 imsi_field[NW_NS_CODE_LEN-1] |= 0xf0; //prateek: unused nibbles to be '00' and not 'FF' to avoid problems during decodeIMSI
836 else
837 imsi_field[NW_NS_CODE_LEN-1] |= 0xff;
838
839 /*
840 * If no user code is present, curr_user_code_index will be ff. After that, curr_user_code_index starts from 0
841 */
842 if((curr_user_code_index EQ 0xff) || (curr_user_code_index EQ max_num_user_codes -1))
843 curr_user_code_index = 0;
844 else
845 curr_user_code_index++;
846
847 if(num_user_codes < max_num_user_codes)
848 num_user_codes++;
849
850 memcpy(&((UBYTE *)personalisation_ns->pBody)[index + curr_user_code_index*NW_NS_CODE_LEN/*multiplication added*/],imsi_field,NW_NS_CODE_LEN);
851 ((UBYTE *)personalisation_ns->pBody)[index - CURR_USER_CODE_INDEX_SIZE] = curr_user_code_index;
852 ((UBYTE *)personalisation_ns->pBody)[index - CURR_USER_CODE_INDEX_SIZE - NUM_USER_CODE_SIZE] = num_user_codes;
853 sec_set_REC(type, personalisation_ns);
854 break;
855
856 case SIMLOCK_SERVICE_PROVIDER :
857 if(!psaSIM_ChkSIMSrvSup(SRV_GrpLvl1) OR (aci_slock_sim_config.sim_gidl1[0] EQ 0xff))
858 {
859 TRACE_FUNCTION("not adding sp as no service or maybe gid1 is ff");
860 break;
861 }
862
863 max_num_user_codes =((UBYTE *) personalisation_sp->pBody)[index];
864 index += MAX_NUM_USERCODE_SIZE;
865 index += NUM_OPCODE_SIZE ;
866 index += OPCODE_LEN_SIZE + ((UBYTE *)personalisation_sp->pBody)[OPCODE_LEN_INDEX];
867
868 num_user_codes = ((UBYTE *)personalisation_sp->pBody)[index];
869 index +=NUM_USER_CODE_SIZE;
870 curr_user_code_index = ((UBYTE *)personalisation_sp->pBody)[index];
871 index += CURR_USER_CODE_INDEX_SIZE ;
872
873 memcpy(imsi_field,simShrdPrm.imsi.field,simShrdPrm.imsi.c_field);
874 if(simShrdPrm.mnc_len EQ 3)
875 imsi_field[NW_CODE_LEN-1] |= 0xf0; //prateek: unused nibbles to be '00' and not 'FF' to avoid problems during decodeIMSI
876 else
877 imsi_field[NW_CODE_LEN-1] |= 0xff;
878
879 if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
880 {
881 memcpy(imsi_field+NW_CODE_LEN,aci_slock_sim_config.sim_gidl1,GID1_LEN);
882 /*
883 * If no user code is present, curr_user_code_index will be ff. After that, curr_user_code_index starts from 0
884 */
885 if((curr_user_code_index EQ 0xff) || (curr_user_code_index EQ max_num_user_codes -1))
886 curr_user_code_index = 0;
887 else
888 curr_user_code_index++;
889
890 if(num_user_codes < max_num_user_codes)
891 num_user_codes++;
892
893 memcpy(&((UBYTE *)personalisation_sp->pBody)[index + curr_user_code_index*(NW_CODE_LEN+GID1_LEN)],imsi_field,NW_CODE_LEN+GID1_LEN);
894 ((UBYTE *)personalisation_sp->pBody)[index - CURR_USER_CODE_INDEX_SIZE] = curr_user_code_index;
895 ((UBYTE *)personalisation_sp->pBody)[index - CURR_USER_CODE_INDEX_SIZE - NUM_USER_CODE_SIZE] = num_user_codes;
896 sec_set_REC(type, personalisation_sp);
897 }
898 break;
899
900 case SIMLOCK_CORPORATE :
901 if( !psaSIM_ChkSIMSrvSup(SRV_GrpLvl1) OR !psaSIM_ChkSIMSrvSup(SRV_GrpLvl2) OR (aci_slock_sim_config.sim_gidl1[0] EQ 0xff) OR (aci_slock_sim_config.sim_gidl2[0] EQ 0xff))
902 {
903 TRACE_FUNCTION("not adding cp as no service or maybe gid1/gid2 is ff");
904 break;
905 }
906
907 max_num_user_codes = ((UBYTE *)personalisation_cp->pBody)[index];
908 index += MAX_NUM_USERCODE_SIZE;
909 index += NUM_OPCODE_SIZE ;
910 index += OPCODE_LEN_SIZE + ((UBYTE *)personalisation_cp->pBody)[OPCODE_LEN_INDEX];
911
912 num_user_codes = ((UBYTE *)personalisation_cp->pBody)[index];
913 index +=NUM_USER_CODE_SIZE;
914 curr_user_code_index =((UBYTE *) personalisation_cp->pBody)[index];
915 index += CURR_USER_CODE_INDEX_SIZE ;
916
917 memcpy(imsi_field,simShrdPrm.imsi.field,simShrdPrm.imsi.c_field);
918 if(simShrdPrm.mnc_len EQ 3)
919 imsi_field[NW_CODE_LEN-1] |= 0xf0; //prateek: unused nibbles to be '00' and not 'FF' to avoid problems during decodeIMSI
920 else
921 /* if(curr_user_code_index NEQ 0) */
922 imsi_field[NW_CODE_LEN-1] |= 0xff;
923
924 if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl1))
925 {
926 memcpy(imsi_field+NW_CODE_LEN,aci_slock_sim_config.sim_gidl1,GID1_LEN);
927 if (psaSIM_ChkSIMSrvSup(SRV_GrpLvl2))
928 {
929 memcpy(imsi_field+NW_CODE_LEN+GID1_LEN,aci_slock_sim_config.sim_gidl2,GID2_LEN);
930 /*
931 * If no user code is present, curr_user_code_index will be ff. After that, curr_user_code_index starts from 0
932 */
933 if((curr_user_code_index EQ 0xff) || (curr_user_code_index EQ max_num_user_codes -1))
934 curr_user_code_index = 0;
935 else
936 curr_user_code_index++;
937
938 if(num_user_codes < max_num_user_codes)
939 num_user_codes++;
940
941 memcpy(&((UBYTE *)personalisation_cp->pBody)[index + (curr_user_code_index*(NW_CODE_LEN+GID1_LEN+GID2_LEN))],imsi_field,NW_CODE_LEN+GID1_LEN+GID2_LEN);
942 ((UBYTE *)personalisation_cp->pBody)[index - CURR_USER_CODE_INDEX_SIZE] = curr_user_code_index;
943 ((UBYTE *)personalisation_cp->pBody)[index - CURR_USER_CODE_INDEX_SIZE - NUM_USER_CODE_SIZE] = num_user_codes;
944 sec_set_REC(type, personalisation_cp);
945 }
946 }
947 break;
948
949 case SIMLOCK_SIM :
950 max_num_user_codes = ((UBYTE *)personalisation_sim->pBody)[index];
951 index += MAX_NUM_USERCODE_SIZE;
952 index += NUM_OPCODE_SIZE ;
953 index += OPCODE_LEN_SIZE + ((UBYTE *)personalisation_sim->pBody)[OPCODE_LEN_INDEX];
954
955 num_user_codes = ((UBYTE *)personalisation_sim->pBody)[index];
956 index +=NUM_USER_CODE_SIZE;
957 curr_user_code_index =((UBYTE *) personalisation_sim->pBody)[index];
958 index += CURR_USER_CODE_INDEX_SIZE ;
959
960 memcpy(imsi_field,simShrdPrm.imsi.field,simShrdPrm.imsi.c_field);
961
962 /*
963 * If no user code is present, curr_user_code_index will be ff. After that, curr_user_code_index starts from 0
964 */
965 if((curr_user_code_index EQ 0xff) || (curr_user_code_index EQ max_num_user_codes -1))
966 curr_user_code_index = 0;
967 else
968 curr_user_code_index++;
969
970 if(num_user_codes < max_num_user_codes)
971 num_user_codes++;
972
973 memcpy(&((UBYTE *)personalisation_sim->pBody)[index + (curr_user_code_index*NW_NS_MSIN_CODE_LEN)],imsi_field,NW_NS_MSIN_CODE_LEN);
974 ((UBYTE *)personalisation_sim->pBody)[index - CURR_USER_CODE_INDEX_SIZE] = curr_user_code_index;
975 ((UBYTE *)personalisation_sim->pBody)[index - CURR_USER_CODE_INDEX_SIZE - NUM_USER_CODE_SIZE] = num_user_codes;
976 sec_set_REC(type, personalisation_sim);
977 break;
978 }
979 }
980
981 #endif //SIM_PERS
982
983
984
985 /*
986 PURPOSE : convert bcd to ASCII
987
988 */
989
990 LOCAL void decodeB2A (U8 *bcd, U8 bcd_len, U8 *ascii)
991 {
992 int i;
993
994 TRACE_FUNCTION("decodeB2A()");
995
996 for (i=0; i<bcd_len*2; i++)
997 {
998 ascii[i] = (i & 1) ? (bcd[i/2]>>4)+'0' : (bcd[i/2]&0x0f)+'0';
999 if (ascii[i]>'9')
1000 break; /* stop if invalid digit */
1001 }
1002 ascii[i] = 0;
1003 }
1004
1005 LOCAL void encodeA2B (char *ascii, UBYTE *bcd, UBYTE bcd_len)
1006 {
1007 UBYTE i;
1008 UBYTE digit;
1009
1010 TRACE_FUNCTION("encodeA2B()");
1011
1012 for (i=0; i<bcd_len*2; i++) /* fill the whole field, pad remaining with 0xf */
1013 {
1014 if (i<strlen(ascii))
1015 {
1016 digit = ascii[i];
1017 if (digit >= '0' OR digit <= '9')
1018 {
1019 digit-= '0';
1020 }
1021 else
1022 {
1023 TRACE_EVENT_P1("[WRN] invalid digit in PIN \"%d\", skipping!", digit);
1024 digit = 0x0f;
1025 }
1026 }
1027 else
1028 {
1029 digit = 0x0f; /* unused nibbles are set to 'F'. */
1030 }
1031
1032 if ((i & 1) EQ 0)
1033 {
1034 /* process PIN digit 1,3,5,... at i=0,2,4,...*/
1035 bcd[i/2] = digit;
1036 }
1037 else
1038 {
1039 /* process PIN digit 2,4,6,... at i=1,3,5,...*/
1040 bcd[i/2] |= digit << 4;
1041 }
1042 }
1043 }
1044
1045 /* That is a workaround to buld simulation test cases */
1046 #ifdef _SIMULATION_
1047 #define effs_t int
1048 #define EFFS_OK 0
1049 #define FFS_fread(a, b, c) 0
1050 #define FFS_fwrite(a, b, c) 0
1051 #endif /*_SIMULATION_*/
1052
1053 #define FFS_MMILOCK_STATUS "/gsm/MELOCK/SecCode"
1054
1055 /*
1056 +------------------------------------------------------------------------------
1057 | Function : aci_ext_personalisation_CS_get_status
1058 +------------------------------------------------------------------------------
1059 | Description : Reads value of CS lock from file and returns it
1060 | Parameters : void
1061 |
1062 |
1063 | Return : status of CS lock
1064 | Remark: : It is proposed to implement through security driver
1065 |
1066 +------------------------------------------------------------------------------
1067 */
1068 T_SIMLOCK_STATUS aci_ext_personalisation_CS_get_status()
1069 {
1070 effs_t ffs_rslt;
1071 TRACE_FUNCTION("aci_ext_personalisation_CS_get_status()");
1072
1073 ffs_rslt = FFS_fread(FFS_MMILOCK_STATUS, &MMI_personalisation_status, sizeof(MMI_personalisation_status));
1074 if(ffs_rslt < EFFS_OK) /* error */
1075 {
1076 TRACE_EVENT_P1("unable to read %s", FFS_MMILOCK_STATUS);
1077 return SIMLOCK_FAIL;
1078 }
1079 return (T_SIMLOCK_STATUS) MMI_personalisation_status.State;
1080 }
1081
1082
1083 /*
1084 +------------------------------------------------------------------------------
1085 | Function : aci_ext_personalisation_CS_set_status
1086 +------------------------------------------------------------------------------
1087 | Description : Reads value of CS lock from file compare passwords and if correct, sets CS lock status
1088 | Parameters : lock - enable or disable
1089 | passwd - password to change lock
1090 |
1091 |
1092 | Return : status of operation
1093 | Remark: : It is proposed to implement through security driver
1094 |
1095 +------------------------------------------------------------------------------
1096 */
1097 T_SIMLOCK_STATUS aci_ext_personalisation_CS_set_status(T_SIMLOCK_STATUS lock , char * passwd)
1098 {
1099 effs_t ffs_rslt;
1100 U8 exp_pin[6+1]; /* +1 for '\0' */
1101 T_SIMLOCK_STATUS result;
1102 TRACE_FUNCTION("aci_ext_personalisation_CS_set_status()");
1103
1104 /* Read data from FFS */
1105
1106 ffs_rslt = FFS_fread(FFS_MMILOCK_STATUS, &MMI_personalisation_status, sizeof(MMI_personalisation_status));
1107
1108 if(ffs_rslt < EFFS_OK) /* error */
1109 {
1110 TRACE_EVENT_P1("unable to read %s", FFS_MMILOCK_STATUS);
1111 return SIMLOCK_FAIL;
1112 }
1113
1114 decodeB2A(MMI_personalisation_status.Cur_code, 3, exp_pin);
1115
1116 if (strncmp((char *)exp_pin, (char *)passwd, 3))
1117 {
1118 /* Block personalisation lock, if tried too often! */
1119 MMI_personalisation_status.cnt++;
1120 if (MMI_personalisation_status.cnt >= MMI_personalisation_status.maxcnt)
1121 {
1122 result = SIMLOCK_BLOCKED;
1123 }
1124 else
1125 {
1126 result = SIMLOCK_LOCKED;
1127 }
1128 }
1129 else
1130 {
1131 /* correct pin passed */
1132 MMI_personalisation_status.cnt = 0;
1133 MMI_personalisation_status.State = lock;
1134 result = lock;
1135 }
1136 ffs_rslt = FFS_fwrite(FFS_MMILOCK_STATUS, &MMI_personalisation_status, sizeof(MMI_personalisation_status));
1137
1138 if (ffs_rslt < EFFS_OK)
1139 {
1140 TRACE_EVENT_P1("unable to write %s", FFS_MMILOCK_STATUS);
1141 return SIMLOCK_FAIL;
1142 }
1143 return result;
1144 }
1145
1146 /*
1147 +------------------------------------------------------------------------------
1148 | Function : aci_ext_personalisation_CS_change_password
1149 +------------------------------------------------------------------------------
1150 | Description : Reads value of CS lock from file compare passwords and if correct, sets new password
1151 | Parameters : passwd - old password
1152 | new_passwd - new password
1153 |
1154 |
1155 | Return : status of operation
1156 | Remark: : It is proposed to implement through security driver
1157 |
1158 +------------------------------------------------------------------------------
1159 */
1160 T_SIMLOCK_STATUS aci_ext_personalisation_CS_change_password( char *passwd, char *new_passwd )
1161 {
1162 effs_t ffs_rslt;
1163 U8 exp_pin[6+1]; /* +1 for '\0' */
1164 T_SIMLOCK_STATUS result;
1165
1166 TRACE_FUNCTION("aci_ext_personalisation_CS_change_password()");
1167
1168 ffs_rslt = FFS_fread(FFS_MMILOCK_STATUS, &MMI_personalisation_status, sizeof(MMI_personalisation_status));
1169 if(ffs_rslt < EFFS_OK) /* error */
1170 {
1171 TRACE_EVENT_P1("unable to read %s", FFS_MMILOCK_STATUS);
1172 return SIMLOCK_FAIL;
1173 }
1174
1175
1176 decodeB2A(MMI_personalisation_status.Cur_code, 3, exp_pin);
1177
1178 if (strncmp((char *)exp_pin, (char *)passwd, 3))
1179 {
1180 /* Block personalisation lock, if tried too often! */
1181 MMI_personalisation_status.cnt++;
1182 if (MMI_personalisation_status.cnt >= MMI_personalisation_status.maxcnt)
1183 {
1184 result = SIMLOCK_BLOCKED;
1185 }
1186 else
1187 {
1188 result = SIMLOCK_LOCKED;
1189 }
1190 }
1191 else
1192 {
1193 /* correct pin passed */
1194 MMI_personalisation_status.cnt=0;
1195 if ((new_passwd NEQ NULL) AND (strlen(new_passwd) > 0))
1196 {
1197 encodeA2B(new_passwd, MMI_personalisation_status.Cur_code, 3);
1198 }
1199 result = (T_SIMLOCK_STATUS) MMI_personalisation_status.State;
1200 }
1201 ffs_rslt = FFS_fwrite(FFS_MMILOCK_STATUS, &MMI_personalisation_status, sizeof(MMI_personalisation_status));
1202
1203 if (ffs_rslt < EFFS_OK)
1204 {
1205 TRACE_EVENT_P1("unable to write %s", FFS_MMILOCK_STATUS);
1206 return SIMLOCK_FAIL;
1207 }
1208 return result;
1209 }
1210
1211