[mobile] Adding security warning, if default IMEI is not changed
[osmocom-bb.git] / src / host / layer23 / src / mobile / subscriber.c
1 /*
2  * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
3  *
4  * All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  */
21
22 #include <stdint.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <arpa/inet.h>
26 #include <osmocom/core/talloc.h>
27 #include <osmocom/gsm/comp128.h>
28
29 #include <osmocom/bb/common/logging.h>
30 #include <osmocom/bb/common/osmocom_data.h>
31 #include <osmocom/bb/common/networks.h>
32 #include <osmocom/bb/mobile/vty.h>
33
34 void *l23_ctx;
35
36 static void subscr_sim_query_cb(struct osmocom_ms *ms, struct msgb *msg);
37 static void subscr_sim_update_cb(struct osmocom_ms *ms, struct msgb *msg);
38 static void subscr_sim_key_cb(struct osmocom_ms *ms, struct msgb *msg);
39
40 /*
41  * support
42  */
43
44 char *gsm_check_imsi(const char *imsi)
45 {
46         int i;
47
48         if (!imsi || strlen(imsi) != 15)
49                 return "IMSI must have 15 digits!";
50
51         for (i = 0; i < strlen(imsi); i++) {
52                 if (imsi[i] < '0' || imsi[i] > '9')
53                         return "IMSI must have digits 0 to 9 only!";
54         }
55
56         return NULL;
57 }
58
59 static char *sim_decode_bcd(uint8_t *data, uint8_t length)
60 {
61         int i, j = 0;
62         static char result[32], c;
63
64         for (i = 0; i < (length << 1); i++) {
65                 if ((i & 1))
66                         c = (data[i >> 1] >> 4);
67                 else
68                         c = (data[i >> 1] & 0xf);
69                 if (c == 0xf)
70                         break;
71                 result[j++] = c + '0';
72                 if (j == sizeof(result) - 1)
73                         break;
74         }
75         result[j] = '\0';
76
77         return result;
78 }
79
80 static void xor96(uint8_t *ki, uint8_t *rand, uint8_t *sres, uint8_t *kc)
81 {
82         int i;
83
84         for (i=0; i < 4; i++)
85                 sres[i] = rand[i] ^ ki[i];
86         for (i=0; i < 8; i++)
87                 kc[i] = rand[i] ^ ki[i+4];
88 }
89
90 /*
91  * init/exit
92  */
93
94 int gsm_subscr_init(struct osmocom_ms *ms)
95 {
96         struct gsm_subscriber *subscr = &ms->subscr;
97
98         memset(subscr, 0, sizeof(*subscr));
99         subscr->ms = ms;
100
101         /* set TMSI / LAC invalid */
102         subscr->tmsi = 0xffffffff;
103         subscr->lac = 0x0000;
104
105         /* set key invalid */
106         subscr->key_seq = 7;
107
108         /* init lists */
109         INIT_LLIST_HEAD(&subscr->plmn_list);
110         INIT_LLIST_HEAD(&subscr->plmn_na);
111
112         /* open SIM */
113         subscr->sim_handle_query = sim_open(ms, subscr_sim_query_cb);
114         subscr->sim_handle_update = sim_open(ms, subscr_sim_update_cb);
115         subscr->sim_handle_key = sim_open(ms, subscr_sim_key_cb);
116
117         return 0;
118 }
119
120 int gsm_subscr_exit(struct osmocom_ms *ms)
121 {
122         struct gsm_subscriber *subscr = &ms->subscr;
123         struct llist_head *lh, *lh2;
124
125         if (subscr->sim_handle_query) {
126                 sim_close(ms, subscr->sim_handle_query);
127                 subscr->sim_handle_query = 0;
128         }
129         if (subscr->sim_handle_update) {
130                 sim_close(ms, subscr->sim_handle_update);
131                 subscr->sim_handle_update = 0;
132         }
133         if (subscr->sim_handle_key) {
134                 sim_close(ms, subscr->sim_handle_key);
135                 subscr->sim_handle_key = 0;
136         }
137
138         /* flush lists */
139         llist_for_each_safe(lh, lh2, &subscr->plmn_list) {
140                 llist_del(lh);
141                 talloc_free(lh);
142         }
143         llist_for_each_safe(lh, lh2, &subscr->plmn_na) {
144                 llist_del(lh);
145                 talloc_free(lh);
146         }
147
148         return 0;
149 }
150
151 /*
152  * test card
153  */
154
155 /* Attach test card, no SIM must be currently attached */
156 int gsm_subscr_testcard(struct osmocom_ms *ms, uint16_t mcc, uint16_t mnc,
157         uint16_t lac, uint32_t tmsi)
158 {
159         struct gsm_settings *set = &ms->settings;
160         struct gsm_subscriber *subscr = &ms->subscr;
161         struct msgb *nmsg;
162         char *error;
163
164         if (subscr->sim_valid) {
165                 LOGP(DMM, LOGL_ERROR, "Cannot insert card, until current card "
166                         "is detached.\n");
167                 return -EBUSY;
168         }
169
170         error = gsm_check_imsi(set->test_imsi);
171         if (error) {
172                 LOGP(DMM, LOGL_ERROR, "%s\n", error);
173                 return -EINVAL;
174         }
175
176         /* reset subscriber */
177         gsm_subscr_exit(ms);
178         gsm_subscr_init(ms);
179
180         subscr->sim_type = GSM_SIM_TYPE_TEST;
181         sprintf(subscr->sim_name, "test");
182         subscr->sim_valid = 1;
183         subscr->ustate = GSM_SIM_U2_NOT_UPDATED;
184         subscr->acc_barr = set->test_barr; /* we may access barred cell */
185         subscr->acc_class = 0xffff; /* we have any access class */
186         subscr->plmn_valid = set->test_rplmn_valid;
187         subscr->plmn_mcc = mcc;
188         subscr->plmn_mnc = mnc;
189         subscr->mcc = mcc;
190         subscr->mnc = mnc;
191         subscr->lac = lac;
192         subscr->tmsi = tmsi;
193         subscr->always_search_hplmn = set->test_always;
194         subscr->t6m_hplmn = 1; /* try to find home network every 6 min */
195         strcpy(subscr->imsi, set->test_imsi);
196
197         LOGP(DMM, LOGL_INFO, "(ms %s) Inserting test card (IMSI=%s %s, %s)\n",
198                 ms->name, subscr->imsi, gsm_imsi_mcc(subscr->imsi),
199                 gsm_imsi_mnc(subscr->imsi));
200
201         if (subscr->plmn_valid)
202                 LOGP(DMM, LOGL_INFO, "-> Test card registered to %s %s 0x%04x"
203                         "(%s, %s)\n", gsm_print_mcc(mcc),
204                         gsm_print_mnc(mnc), lac, gsm_get_mcc(mcc),
205                         gsm_get_mnc(mcc, mnc));
206         else
207                 LOGP(DMM, LOGL_INFO, "-> Test card not registered\n");
208
209         /* insert card */
210         nmsg = gsm48_mmr_msgb_alloc(GSM48_MMR_REG_REQ);
211         if (!nmsg)
212                 return -ENOMEM;
213         gsm48_mmr_downmsg(ms, nmsg);
214
215         return 0;
216 }
217
218 /*
219  * sim card
220  */
221
222 static int subscr_sim_iccid(struct osmocom_ms *ms, uint8_t *data,
223         uint8_t length)
224 {
225         struct gsm_subscriber *subscr = &ms->subscr;
226
227         strcpy(subscr->iccid, sim_decode_bcd(data, length));
228         sprintf(subscr->sim_name, "sim-%s", subscr->iccid);
229         LOGP(DMM, LOGL_INFO, "received ICCID %s from SIM\n", subscr->iccid);
230
231         return 0;
232 }
233
234 static int subscr_sim_imsi(struct osmocom_ms *ms, uint8_t *data,
235         uint8_t length)
236 {
237         struct gsm_subscriber *subscr = &ms->subscr;
238         char *imsi;
239
240         /* get actual length */
241         if (length < 1)
242                 return -EINVAL;
243         if (data[0] + 1 < length) {
244                 LOGP(DMM, LOGL_NOTICE, "invalid length = %d\n", length);
245                 return -EINVAL;
246         }
247         length = data[0];
248
249         /* decode IMSI, skip first digit (parity) */
250         imsi = sim_decode_bcd(data + 1, length);
251         if (strlen(imsi) - 1 > GSM_IMSI_LENGTH - 1 || strlen(imsi) - 1 < 6) {
252                 LOGP(DMM, LOGL_NOTICE, "IMSI invalid length = %d\n",
253                         strlen(imsi) - 1);
254                 return -EINVAL;
255         }
256
257         strncpy(subscr->imsi, imsi + 1, sizeof(subscr->imsi) - 1);
258
259         LOGP(DMM, LOGL_INFO, "received IMSI %s from SIM\n", subscr->imsi);
260
261         return 0;
262 }
263
264 static int subscr_sim_loci(struct osmocom_ms *ms, uint8_t *data,
265         uint8_t length)
266 {
267         struct gsm_subscriber *subscr = &ms->subscr;
268         struct gsm1111_ef_loci *loci;
269
270         if (length < 11)
271                 return -EINVAL;
272         loci = (struct gsm1111_ef_loci *) data;
273
274         /* TMSI */
275         subscr->tmsi = ntohl(loci->tmsi);
276
277         /* LAI */
278         gsm48_decode_lai(&loci->lai, &subscr->mcc, &subscr->mnc, &subscr->lac);
279
280         /* location update status */
281         switch (loci->lupd_status & 0x07) {
282         case 0x00:
283                 subscr->ustate = GSM_SIM_U1_UPDATED;
284                 break;
285         case 0x02:
286         case 0x03:
287                 subscr->ustate = GSM_SIM_U3_ROAMING_NA;
288                 break;
289         default:
290                 subscr->ustate = GSM_SIM_U2_NOT_UPDATED;
291         }
292
293         LOGP(DMM, LOGL_INFO, "received LOCI from SIM (mcc=%s mnc=%s lac=0x%04x "
294                 "U%d)\n", gsm_print_mcc(subscr->mcc),
295                 gsm_print_mnc(subscr->mnc), subscr->lac, subscr->ustate);
296
297         return 0;
298 }
299
300 static int subscr_sim_msisdn(struct osmocom_ms *ms, uint8_t *data,
301         uint8_t length)
302 {
303         struct gsm_subscriber *subscr = &ms->subscr;
304         struct gsm1111_ef_adn *adn;
305
306         if (length < sizeof(*adn))
307                 return -EINVAL;
308         adn = (struct gsm1111_ef_adn *) (data + length - sizeof(*adn));
309
310         /* empty */
311         subscr->msisdn[0] = '\0';
312         if (adn->len_bcd <= 1)
313                 return 0;
314
315         /* number */
316         if (adn->ton_npi == 1)
317                 strcpy(subscr->msisdn, "+");
318         if (adn->ton_npi == 2)
319                 strcpy(subscr->msisdn, "0");
320         strncat(subscr->msisdn, sim_decode_bcd(adn->number, adn->len_bcd - 1),
321                 sizeof(subscr->msisdn) - 2);
322
323         LOGP(DMM, LOGL_INFO, "received MSISDN %s from SIM\n", subscr->msisdn);
324
325         return 0;
326 }
327
328 static int subscr_sim_kc(struct osmocom_ms *ms, uint8_t *data,
329         uint8_t length)
330 {
331         struct gsm_subscriber *subscr = &ms->subscr;
332
333         if (length < 9)
334                 return -EINVAL;
335
336         /* key */
337         memcpy(subscr->key, data, 8);
338
339         /* key sequence */
340         subscr->key_seq = data[8] & 0x07;
341
342         LOGP(DMM, LOGL_INFO, "received KEY from SIM\n");
343
344         return 0;
345 }
346
347 static int subscr_sim_plmnsel(struct osmocom_ms *ms, uint8_t *data,
348         uint8_t length)
349 {
350         struct gsm_subscriber *subscr = &ms->subscr;
351         struct gsm_sub_plmn_list *plmn;
352         struct llist_head *lh, *lh2;
353         uint8_t lai[5];
354         uint16_t dummy_lac;
355
356         /* flush list */
357         llist_for_each_safe(lh, lh2, &subscr->plmn_list) {
358                 llist_del(lh);
359                 talloc_free(lh);
360         }
361
362         while(length >= 3) {
363                 /* end of list inside mandatory fields */
364                 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0x0ff)
365                         break;
366
367                 /* add to list */
368                 plmn = talloc_zero(l23_ctx, struct gsm_sub_plmn_list);
369                 if (!plmn)
370                         return -ENOMEM;
371                 lai[0] = data[0];
372                 lai[1] = data[1];
373                 lai[2] = data[2];
374                 gsm48_decode_lai((struct gsm48_loc_area_id *)lai, &plmn->mcc,
375                         &plmn->mnc, &dummy_lac);
376                 llist_add_tail(&plmn->entry, &subscr->plmn_list);
377
378                 LOGP(DMM, LOGL_INFO, "received PLMN selector (mcc=%s mnc=%s) "
379                         "from SIM\n",
380                         gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc));
381
382                 data += 3;
383                 length -= 3;
384         }
385
386         return 0;
387 }
388
389 static int subscr_sim_hpplmn(struct osmocom_ms *ms, uint8_t *data,
390         uint8_t length)
391 {
392         struct gsm_subscriber *subscr = &ms->subscr;
393
394         if (length < 1)
395                 return -EINVAL;
396
397         /* HPLMN search interval */
398         subscr->t6m_hplmn = *data; /* multiple of 6 minutes */
399
400         LOGP(DMM, LOGL_INFO, "received HPPLMN %d (%d mins) from SIM\n",
401                 subscr->t6m_hplmn, subscr->t6m_hplmn * 6);
402
403         return 0;
404 }
405
406 static int subscr_sim_spn(struct osmocom_ms *ms, uint8_t *data,
407         uint8_t length)
408 {
409         struct gsm_subscriber *subscr = &ms->subscr;
410         int i;
411
412         /* UCS2 code not supported */
413         if (length < 17 || data[1] >= 0x80)
414                 return -ENOTSUP;
415
416         data++;
417         for (i = 0; i < 16; i++) {
418                 if (*data == 0xff)
419                         break;
420                 subscr->sim_spn[i] = *data++;
421         }
422         subscr->sim_spn[i] = '\0';
423
424         LOGP(DMM, LOGL_INFO, "received SPN %s from SIM\n", subscr->sim_spn);
425
426         return 0;
427 }
428
429 static int subscr_sim_acc(struct osmocom_ms *ms, uint8_t *data,
430         uint8_t length)
431 {
432         struct gsm_subscriber *subscr = &ms->subscr;
433         uint16_t ac;
434
435         if (length < 2)
436                 return -EINVAL;
437
438         /* cell access */
439         memcpy(&ac, data, sizeof(ac));
440         subscr->acc_class = ntohs(ac);
441
442         LOGP(DMM, LOGL_INFO, "received ACC %04x from SIM\n", subscr->acc_class);
443
444         return 0;
445 }
446
447 static int subscr_sim_fplmn(struct osmocom_ms *ms, uint8_t *data,
448         uint8_t length)
449 {
450         struct gsm_subscriber *subscr = &ms->subscr;
451         struct gsm_sub_plmn_na *na;
452         struct llist_head *lh, *lh2;
453         uint8_t lai[5];
454         uint16_t dummy_lac;
455
456         /* flush list */
457         llist_for_each_safe(lh, lh2, &subscr->plmn_na) {
458                 llist_del(lh);
459                 talloc_free(lh);
460         }
461
462         while (length >= 3) {
463                 /* end of list inside mandatory fields */
464                 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0x0ff)
465                         break;
466
467                 /* add to list */
468                 na = talloc_zero(l23_ctx, struct gsm_sub_plmn_na);
469                 if (!na)
470                         return -ENOMEM;
471                 lai[0] = data[0];
472                 lai[1] = data[1];
473                 lai[2] = data[2];
474                 gsm48_decode_lai((struct gsm48_loc_area_id *)lai, &na->mcc,
475                         &na->mnc, &dummy_lac);
476                 na->cause = 0;
477                 llist_add_tail(&na->entry, &subscr->plmn_na);
478
479                 data += 3;
480                 length -= 3;
481         }
482         return 0;
483 }
484
485 static struct subscr_sim_file {
486         uint8_t         mandatory;
487         uint16_t        path[MAX_SIM_PATH_LENGTH];
488         uint16_t        file;
489         int             (*func)(struct osmocom_ms *ms, uint8_t *data,
490                                 uint8_t length);
491 } subscr_sim_files[] = {
492         { 1, { 0 },         0x2fe2, subscr_sim_iccid },
493         { 1, { 0x7f20, 0 }, 0x6f07, subscr_sim_imsi },
494         { 1, { 0x7f20, 0 }, 0x6f7e, subscr_sim_loci },
495         { 0, { 0x7f10, 0 }, 0x6f40, subscr_sim_msisdn },
496         { 0, { 0x7f20, 0 }, 0x6f20, subscr_sim_kc },
497         { 0, { 0x7f20, 0 }, 0x6f30, subscr_sim_plmnsel },
498         { 0, { 0x7f20, 0 }, 0x6f31, subscr_sim_hpplmn },
499         { 0, { 0x7f20, 0 }, 0x6f46, subscr_sim_spn },
500         { 0, { 0x7f20, 0 }, 0x6f78, subscr_sim_acc },
501         { 0, { 0x7f20, 0 }, 0x6f7b, subscr_sim_fplmn },
502         { 0, { 0 },         0,      NULL }
503 };
504
505 /* request file from SIM */
506 static int subscr_sim_request(struct osmocom_ms *ms)
507 {
508         struct gsm_subscriber *subscr = &ms->subscr;
509         struct subscr_sim_file *sf = &subscr_sim_files[subscr->sim_file_index];
510         struct msgb *nmsg;
511         struct sim_hdr *nsh;
512         int i;
513
514         /* we are done, fire up PLMN and cell selection process */
515         if (!sf->func) {
516                 LOGP(DMM, LOGL_INFO, "(ms %s) Done reading SIM card "
517                         "(IMSI=%s %s, %s)\n", ms->name, subscr->imsi,
518                         gsm_imsi_mcc(subscr->imsi), gsm_imsi_mnc(subscr->imsi));
519
520                 /* if LAI is valid, set RPLMN */
521                 if (subscr->lac > 0x0000 && subscr->lac < 0xfffe) {
522                         subscr->plmn_valid = 1;
523                         subscr->plmn_mcc = subscr->mcc;
524                         subscr->plmn_mnc = subscr->mnc;
525                         LOGP(DMM, LOGL_INFO, "-> SIM card registered to %s %s "
526                                 "(%s, %s)\n", gsm_print_mcc(subscr->plmn_mcc),
527                                 gsm_print_mnc(subscr->plmn_mnc),
528                                 gsm_get_mcc(subscr->plmn_mcc),
529                                 gsm_get_mnc(subscr->plmn_mcc,
530                                         subscr->plmn_mnc));
531                 } else
532                         LOGP(DMM, LOGL_INFO, "-> SIM card not registered\n");
533
534                 /* insert card */
535                 nmsg = gsm48_mmr_msgb_alloc(GSM48_MMR_REG_REQ);
536                 if (!nmsg)
537                         return -ENOMEM;
538                 gsm48_mmr_downmsg(ms, nmsg);
539
540                 return 0;
541         }
542
543         /* trigger SIM reading */
544         nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_query,
545                 SIM_JOB_READ_BINARY);
546         if (!nmsg)
547                 return -ENOMEM;
548         nsh = (struct sim_hdr *) nmsg->data;
549         i = 0;
550         while (sf->path[i]) {
551                 nsh->path[i] = sf->path[i];
552                 i++;
553         }
554         nsh->path[i] = 0; /* end of path */
555         nsh->file = sf->file;
556         LOGP(DMM, LOGL_INFO, "Requesting SIM file 0x%04x\n", nsh->file);
557         sim_job(ms, nmsg);
558
559         return 0;
560 }
561
562 static void subscr_sim_query_cb(struct osmocom_ms *ms, struct msgb *msg)
563 {
564         struct gsm_subscriber *subscr = &ms->subscr;
565         struct sim_hdr *sh = (struct sim_hdr *) msg->data;
566         uint8_t *payload = msg->data + sizeof(*sh);
567         uint16_t payload_len = msg->len - sizeof(*sh);
568         int rc;
569         struct subscr_sim_file *sf = &subscr_sim_files[subscr->sim_file_index];
570         struct msgb *nmsg;
571
572         /* error handling */
573         if (sh->job_type == SIM_JOB_ERROR) {
574                 uint8_t cause = payload[0];
575
576                 switch (cause) {
577                         /* unlocking required */
578                 case SIM_CAUSE_PIN1_REQUIRED:
579                         LOGP(DMM, LOGL_INFO, "PIN is required, %d tries left\n",
580                                 payload[1]);
581
582                         vty_notify(ms, NULL);
583                         vty_notify(ms, "Please give PIN for ICCID %s (you have "
584                                 "%d tries left)\n", subscr->iccid, payload[1]);
585                         subscr->sim_pin_required = 1;
586                         break;
587                 case SIM_CAUSE_PIN1_BLOCKED:
588                         LOGP(DMM, LOGL_NOTICE, "PIN is blocked\n");
589
590                         vty_notify(ms, NULL);
591                         vty_notify(ms, "PIN is blocked\n");
592                         if (payload[1]) {
593                                 vty_notify(ms, "Please give PUC for ICCID %s "
594                                         "(you have %d tries left)\n",
595                                         subscr->iccid, payload[1]);
596                         }
597                         subscr->sim_pin_required = 1;
598                         break;
599                 case SIM_CAUSE_PUC_BLOCKED:
600                         LOGP(DMM, LOGL_NOTICE, "PUC is blocked\n");
601
602                         vty_notify(ms, NULL);
603                         vty_notify(ms, "PUC is blocked\n");
604                         subscr->sim_pin_required = 1;
605                         break;
606                 default:
607                         if (sf->func && !sf->mandatory) {
608                                 LOGP(DMM, LOGL_NOTICE, "SIM reading failed, "
609                                         "ignoring!\n");
610                                 goto ignore;
611                         }
612                         LOGP(DMM, LOGL_NOTICE, "SIM reading failed\n");
613
614                         vty_notify(ms, NULL);
615                         vty_notify(ms, "SIM failed, replace SIM!\n");
616
617                         /* detach simcard */
618                         subscr->sim_valid = 0;
619                         nmsg = gsm48_mmr_msgb_alloc(GSM48_MMR_NREG_REQ);
620                         if (!nmsg)
621                                 return;
622                         gsm48_mmr_downmsg(ms, nmsg);
623                 }
624                 msgb_free(msg);
625
626                 return;
627         }
628
629         /* if pin was successfully unlocked, then resend request */
630         if (subscr->sim_pin_required) {
631                 subscr->sim_pin_required = 0;
632                 subscr_sim_request(ms);
633                 return;
634         }
635
636         /* done when nothing more to read. this happens on PIN requests */
637         if (!sf->func)
638                 return;
639
640         /* call function do decode SIM reply */
641         rc = sf->func(ms, payload, payload_len);
642         if (rc) {
643                 LOGP(DMM, LOGL_NOTICE, "SIM reading failed, file invalid\n");
644                 if (subscr_sim_files[subscr->sim_file_index].mandatory) {
645                         vty_notify(ms, NULL);
646                         vty_notify(ms, "SIM failed, data invalid, replace "
647                                 "SIM!\n");
648                         msgb_free(msg);
649
650                         return;
651                 }
652         }
653
654 ignore:
655         msgb_free(msg);
656
657         /* trigger next file */
658         subscr->sim_file_index++;
659         subscr_sim_request(ms);
660 }
661
662 /* enter PIN */
663 void gsm_subscr_sim_pin(struct osmocom_ms *ms, char *pin1, char *pin2,
664         int8_t mode)
665 {
666         struct gsm_subscriber *subscr = &ms->subscr;
667         struct msgb *nmsg;
668         uint8_t job;
669
670         /* skip, if no real valid SIM */
671         if (subscr->sim_type != GSM_SIM_TYPE_READER)
672                 return;
673
674         switch (mode) {
675         case -1:
676                 job = SIM_JOB_PIN1_DISABLE;
677                 LOGP(DMM, LOGL_INFO, "disabling PIN %s\n", pin1);
678                 break;
679         case 1:
680                 job = SIM_JOB_PIN1_ENABLE;
681                 LOGP(DMM, LOGL_INFO, "enabling PIN %s\n", pin1);
682                 break;
683         case 2:
684                 job = SIM_JOB_PIN1_CHANGE;
685                 LOGP(DMM, LOGL_INFO, "changing PIN %s to %s\n", pin1, pin2);
686                 break;
687         case 99:
688                 job = SIM_JOB_PIN1_UNBLOCK;
689                 LOGP(DMM, LOGL_INFO, "unblocking PIN %s with PUC %s\n", pin1,
690                         pin2);
691                 break;
692         default:
693                 if (!subscr->sim_pin_required) {
694                         LOGP(DMM, LOGL_ERROR, "No PIN required now\n");
695                         return;
696                 }
697                 LOGP(DMM, LOGL_INFO, "entering PIN %s\n", pin1);
698                 job = SIM_JOB_PIN1_UNLOCK;
699         }
700
701         nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_query, job);
702         if (!nmsg)
703                 return;
704         memcpy(msgb_put(nmsg, strlen(pin1) + 1), pin1, strlen(pin1) + 1);
705         memcpy(msgb_put(nmsg, strlen(pin2) + 1), pin2, strlen(pin2) + 1);
706         sim_job(ms, nmsg);
707 }
708
709 /* Attach SIM reader, no SIM must be currently attached */
710 int gsm_subscr_simcard(struct osmocom_ms *ms)
711 {
712         struct gsm_subscriber *subscr = &ms->subscr;
713
714         if (subscr->sim_valid) {
715                 LOGP(DMM, LOGL_ERROR, "Cannot attach card, until current card "
716                         "is detached.\n");
717                 return -EBUSY;
718         }
719
720         /* reset subscriber */
721         gsm_subscr_exit(ms);
722         gsm_subscr_init(ms);
723
724         subscr->sim_type = GSM_SIM_TYPE_READER;
725         sprintf(subscr->sim_name, "sim");
726         subscr->sim_valid = 1;
727         subscr->ustate = GSM_SIM_U2_NOT_UPDATED;
728
729         /* start with first index */
730         subscr->sim_file_index = 0;
731         return subscr_sim_request(ms);
732 }
733
734 /* update plmn not allowed list on SIM */
735 static int subscr_write_plmn_na(struct osmocom_ms *ms)
736 {
737         struct gsm_subscriber *subscr = &ms->subscr;
738         struct msgb *nmsg;
739         struct sim_hdr *nsh;
740         struct gsm_sub_plmn_na *na, *nas[4] = { NULL, NULL, NULL, NULL };
741         int count = 0, i;
742         uint8_t *data;
743         uint8_t lai[5];
744
745         /* skip, if no real valid SIM */
746         if (subscr->sim_type != GSM_SIM_TYPE_READER || !subscr->sim_valid)
747                 return 0;
748
749         /* get tail list from "PLMN not allowed" */
750         llist_for_each_entry(na, &subscr->plmn_na, entry) {
751                 if (count < 4)
752                         nas[count] = na;
753                 else {
754                         nas[0] = nas[1];
755                         nas[1] = nas[2];
756                         nas[2] = nas[3];
757                         nas[3] = na;
758                 }
759                 count++;
760         }
761
762         /* write to SIM */
763         LOGP(DMM, LOGL_INFO, "Updating FPLMN on SIM\n");
764         nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_update,
765                 SIM_JOB_UPDATE_BINARY);
766         if (!nmsg)
767                 return -ENOMEM;
768         nsh = (struct sim_hdr *) nmsg->data;
769         data = msgb_put(nmsg, 12);
770         nsh->path[0] = 0x7f20;
771         nsh->path[1] = 0;
772         nsh->file = 0x6f7b;
773         for (i = 0; i < 4; i++) {
774                 if (nas[i]) {
775                         gsm48_encode_lai((struct gsm48_loc_area_id *)lai,
776                         nas[i]->mcc, nas[i]->mnc, 0);
777                         *data++ = lai[0];
778                         *data++ = lai[1];
779                         *data++ = lai[2];
780                 } else {
781                         *data++ = 0xff;
782                         *data++ = 0xff;
783                         *data++ = 0xff;
784                 }
785         }
786         sim_job(ms, nmsg);
787
788         return 0;
789 }
790
791 /* update LOCI on SIM */
792 int gsm_subscr_write_loci(struct osmocom_ms *ms)
793 {
794         struct gsm_subscriber *subscr = &ms->subscr;
795         struct msgb *nmsg;
796         struct sim_hdr *nsh;
797         struct gsm1111_ef_loci *loci;
798
799         /* skip, if no real valid SIM */
800         if (subscr->sim_type != GSM_SIM_TYPE_READER || !subscr->sim_valid)
801                 return 0;
802
803         LOGP(DMM, LOGL_INFO, "Updating LOCI on SIM\n");
804
805         /* write to SIM */
806         nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_update,
807                 SIM_JOB_UPDATE_BINARY);
808         if (!nmsg)
809                 return -ENOMEM;
810         nsh = (struct sim_hdr *) nmsg->data;
811         nsh->path[0] = 0x7f20;
812         nsh->path[1] = 0;
813         nsh->file = 0x6f7e;
814         loci = (struct gsm1111_ef_loci *)msgb_put(nmsg, sizeof(*loci));
815
816         /* TMSI */
817         loci->tmsi = htonl(subscr->tmsi);
818
819         /* LAI */
820         gsm48_encode_lai(&loci->lai, subscr->mcc, subscr->mnc, subscr->lac);
821
822         /* TMSI time */
823         loci->tmsi_time = 0xff;
824
825         /* location update status */
826         switch (subscr->ustate) {
827         case GSM_SIM_U1_UPDATED:
828                 loci->lupd_status = 0x00;
829                 break;
830         case GSM_SIM_U3_ROAMING_NA:
831                 loci->lupd_status = 0x03;
832                 break;
833         default:
834                 loci->lupd_status = 0x01;
835         }
836
837         sim_job(ms, nmsg);
838
839         return 0;
840 }
841
842 static void subscr_sim_update_cb(struct osmocom_ms *ms, struct msgb *msg)
843 {
844         struct sim_hdr *sh = (struct sim_hdr *) msg->data;
845         uint8_t *payload = msg->data + sizeof(*sh);
846
847         /* error handling */
848         if (sh->job_type == SIM_JOB_ERROR)
849                 LOGP(DMM, LOGL_NOTICE, "SIM update failed (cause %d)\n",
850                         *payload);
851
852         msgb_free(msg);
853 }
854
855 int gsm_subscr_generate_kc(struct osmocom_ms *ms, uint8_t key_seq,
856         uint8_t *rand, uint8_t no_sim)
857 {
858         struct gsm_subscriber *subscr = &ms->subscr;
859         struct msgb *nmsg;
860         struct sim_hdr *nsh;
861
862         /* not a SIM */
863         if ((subscr->sim_type != GSM_SIM_TYPE_READER
864           && subscr->sim_type != GSM_SIM_TYPE_TEST)
865          || !subscr->sim_valid || no_sim) {
866                 struct gsm48_mm_event *nmme;
867
868                 LOGP(DMM, LOGL_INFO, "Sending dummy authentication response\n");
869                 nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_AUTH_RESPONSE);
870                 if (!nmsg)
871                         return -ENOMEM;
872                 nmme = (struct gsm48_mm_event *) nmsg->data;
873                 nmme->sres[0] = 0x12;
874                 nmme->sres[1] = 0x34;
875                 nmme->sres[2] = 0x56;
876                 nmme->sres[3] = 0x78;
877                 gsm48_mmevent_msg(ms, nmsg);
878
879                 return 0;
880         }
881
882         /* test SIM */
883         if (subscr->sim_type == GSM_SIM_TYPE_TEST) {
884                 struct gsm48_mm_event *nmme;
885                 uint8_t sres[4];
886                 struct gsm_settings *set = &ms->settings;
887
888                 if (set->test_ki_type == GSM_SIM_KEY_COMP128)
889                         comp128(set->test_ki, rand, sres, subscr->key);
890                 else
891                         xor96(set->test_ki, rand, sres, subscr->key);
892                 /* store sequence */
893                 subscr->key_seq = key_seq;
894
895                 LOGP(DMM, LOGL_INFO, "Sending authentication response\n");
896                 nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_AUTH_RESPONSE);
897                 if (!nmsg)
898                         return -ENOMEM;
899                 nmme = (struct gsm48_mm_event *) nmsg->data;
900                 memcpy(nmme->sres, sres, 4);
901                 gsm48_mmevent_msg(ms, nmsg);
902
903                 return 0;
904         }
905
906         LOGP(DMM, LOGL_INFO, "Generating KEY at SIM\n");
907
908         /* command to SIM */
909         nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_key, SIM_JOB_RUN_GSM_ALGO);
910         if (!nmsg)
911                 return -ENOMEM;
912         nsh = (struct sim_hdr *) nmsg->data;
913         nsh->path[0] = 0x7f20;
914         nsh->path[1] = 0;
915
916         /* random */
917         memcpy(msgb_put(nmsg, 16), rand, 16);
918
919         /* store sequence */
920         subscr->key_seq = key_seq;
921
922         sim_job(ms, nmsg);
923
924         return 0;
925 }
926
927 static void subscr_sim_key_cb(struct osmocom_ms *ms, struct msgb *msg)
928 {
929         struct gsm_subscriber *subscr = &ms->subscr;
930         struct sim_hdr *sh = (struct sim_hdr *) msg->data;
931         uint8_t *payload = msg->data + sizeof(*sh);
932         uint16_t payload_len = msg->len - sizeof(*sh);
933         struct msgb *nmsg;
934         struct sim_hdr *nsh;
935         struct gsm48_mm_event *nmme;
936         uint8_t *data;
937
938         /* error handling */
939         if (sh->job_type == SIM_JOB_ERROR) {
940                 LOGP(DMM, LOGL_NOTICE, "key generation on SIM failed "
941                         "(cause %d)\n", *payload);
942
943                 msgb_free(msg);
944
945                 return;
946         }
947
948         if (payload_len < 12) {
949                 LOGP(DMM, LOGL_NOTICE, "response from SIM too short\n");
950                 return;
951         }
952
953         /* store key */
954         memcpy(subscr->key, payload + 4, 8);
955
956         /* write to SIM */
957         LOGP(DMM, LOGL_INFO, "Updating KC on SIM\n");
958         nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_update,
959                 SIM_JOB_UPDATE_BINARY);
960         if (!nmsg)
961                 return;
962         nsh = (struct sim_hdr *) nmsg->data;
963         nsh->path[0] = 0x7f20;
964         nsh->path[1] = 0;
965         nsh->file = 0x6f20;
966         data = msgb_put(nmsg, 9);
967         memcpy(data, subscr->key, 8);
968         data[8] = subscr->key_seq;
969         sim_job(ms, nmsg);
970
971         /* return signed response */
972         nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_AUTH_RESPONSE);
973         if (!nmsg)
974                 return;
975         nmme = (struct gsm48_mm_event *) nmsg->data;
976         memcpy(nmme->sres, payload, 4);
977         gsm48_mmevent_msg(ms, nmsg);
978
979         msgb_free(msg);
980 }
981
982 /*
983  * detach
984  */
985
986 /* Detach card */
987 int gsm_subscr_remove(struct osmocom_ms *ms)
988 {
989         struct gsm_subscriber *subscr = &ms->subscr;
990         struct msgb *nmsg;
991
992         if (!subscr->sim_valid) {
993                 LOGP(DMM, LOGL_ERROR, "Cannot remove card, no card present\n");
994                 return -EINVAL;
995         }
996
997         /* remove card */
998         nmsg = gsm48_mmr_msgb_alloc(GSM48_MMR_NREG_REQ);
999         if (!nmsg)
1000                 return -ENOMEM;
1001         gsm48_mmr_downmsg(ms, nmsg);
1002
1003         return 0;
1004 }
1005
1006 /*
1007  * state and lists
1008  */
1009
1010 static const char *subscr_ustate_names[] = {
1011         "U0_NULL",
1012         "U1_UPDATED",
1013         "U2_NOT_UPDATED",
1014         "U3_ROAMING_NA"
1015 };
1016
1017 /* change to new U state */
1018 void new_sim_ustate(struct gsm_subscriber *subscr, int state)
1019 {
1020         LOGP(DMM, LOGL_INFO, "(ms %s) new state %s -> %s\n", subscr->ms->name,
1021                 subscr_ustate_names[subscr->ustate],
1022                 subscr_ustate_names[state]);
1023
1024         subscr->ustate = state;
1025 }
1026
1027 /* del forbidden PLMN */
1028 int gsm_subscr_del_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc,
1029         uint16_t mnc)
1030 {
1031         struct gsm_sub_plmn_na *na;
1032
1033         llist_for_each_entry(na, &subscr->plmn_na, entry) {
1034                 if (na->mcc == mcc && na->mnc == mnc) {
1035                         LOGP(DPLMN, LOGL_INFO, "Delete from list of forbidden "
1036                                 "PLMNs (mcc=%s, mnc=%s)\n",
1037                                 gsm_print_mcc(mcc), gsm_print_mnc(mnc));
1038                         llist_del(&na->entry);
1039                         talloc_free(na);
1040                         /* update plmn not allowed list on SIM */
1041                         subscr_write_plmn_na(subscr->ms);
1042                         return 0;
1043                 }
1044         }
1045
1046         return -EINVAL;
1047 }
1048
1049 /* add forbidden PLMN */
1050 int gsm_subscr_add_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc,
1051                                         uint16_t mnc, uint8_t cause)
1052 {
1053         struct gsm_sub_plmn_na *na;
1054
1055         /* if already in the list, remove and add to tail */
1056         gsm_subscr_del_forbidden_plmn(subscr, mcc, mnc);
1057
1058         LOGP(DPLMN, LOGL_INFO, "Add to list of forbidden PLMNs "
1059                 "(mcc=%s, mnc=%s)\n", gsm_print_mcc(mcc), gsm_print_mnc(mnc));
1060         na = talloc_zero(l23_ctx, struct gsm_sub_plmn_na);
1061         if (!na)
1062                 return -ENOMEM;
1063         na->mcc = mcc;
1064         na->mnc = mnc;
1065         na->cause = cause;
1066         llist_add_tail(&na->entry, &subscr->plmn_na);
1067
1068         /* don't add Home PLMN to SIM */
1069         if (subscr->sim_valid && gsm_match_mnc(mcc, mnc, subscr->imsi))
1070                 return -EINVAL;
1071
1072         /* update plmn not allowed list on SIM */
1073         subscr_write_plmn_na(subscr->ms);
1074
1075         return 0;
1076 }
1077
1078 /* search forbidden PLMN */
1079 int gsm_subscr_is_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc,
1080                                         uint16_t mnc)
1081 {
1082         struct gsm_sub_plmn_na *na;
1083
1084         llist_for_each_entry(na, &subscr->plmn_na, entry) {
1085                 if (na->mcc == mcc && na->mnc == mnc)
1086                         return 1;
1087         }
1088
1089         return 0;
1090 }
1091
1092 int gsm_subscr_dump_forbidden_plmn(struct osmocom_ms *ms,
1093                         void (*print)(void *, const char *, ...), void *priv)
1094 {
1095         struct gsm_subscriber *subscr = &ms->subscr;
1096         struct gsm_sub_plmn_na *temp;
1097
1098         print(priv, "MCC    |MNC    |cause\n");
1099         print(priv, "-------+-------+-------\n");
1100         llist_for_each_entry(temp, &subscr->plmn_na, entry)
1101                 print(priv, "%s    |%s%s    |#%d\n",
1102                         gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc),
1103                         ((temp->mnc & 0x00f) == 0x00f) ? " ":"", temp->cause);
1104
1105         return 0;
1106 }
1107
1108 /* dump subscriber */
1109 void gsm_subscr_dump(struct gsm_subscriber *subscr,
1110                         void (*print)(void *, const char *, ...), void *priv)
1111 {
1112         int i;
1113         struct gsm_sub_plmn_list *plmn_list;
1114         struct gsm_sub_plmn_na *plmn_na;
1115
1116         print(priv, "Mobile Subscriber of MS '%s':\n", subscr->ms->name);
1117
1118         if (!subscr->sim_valid) {
1119                 print(priv, " No SIM present.\n");
1120                 return;
1121         }
1122
1123         print(priv, " IMSI: %s\n", subscr->imsi);
1124         if (subscr->iccid[0])
1125                 print(priv, " ICCID: %s\n", subscr->iccid);
1126         if (subscr->sim_spn[0])
1127                 print(priv, " Service Provider Name: %s\n", subscr->sim_spn);
1128         if (subscr->msisdn[0])
1129                 print(priv, " MSISDN: %s\n", subscr->msisdn);
1130         print(priv, " Status: %s  IMSI %s", subscr_ustate_names[subscr->ustate],
1131                 (subscr->imsi_attached) ? "attached" : "detached");
1132         if (subscr->tmsi != 0xffffffff)
1133                 print(priv, "  TSMI 0x%08x", subscr->tmsi);
1134         if (subscr->lac > 0x0000 && subscr->lac < 0xfffe) {
1135                 print(priv, "\n");
1136                 print(priv, "         LAI: MCC %s  MNC %s  LAC 0x%04x  "
1137                         "(%s, %s)\n", gsm_print_mcc(subscr->mcc),
1138                         gsm_print_mnc(subscr->mnc), subscr->lac,
1139                         gsm_get_mcc(subscr->mcc),
1140                         gsm_get_mnc(subscr->mcc, subscr->mnc));
1141         } else
1142                 print(priv, "  LAI: invalid\n");
1143         if (subscr->key_seq != 7) {
1144                 print(priv, " Key: sequence %d ", subscr->key_seq);
1145                 for (i = 0; i < sizeof(subscr->key); i++)
1146                         print(priv, " %02x", subscr->key[i]);
1147                 print(priv, "\n");
1148         }
1149         if (subscr->plmn_valid)
1150                 print(priv, " Registered PLMN: MCC %s  MNC %s  (%s, %s)\n",
1151                         gsm_print_mcc(subscr->plmn_mcc),
1152                         gsm_print_mnc(subscr->plmn_mnc),
1153                         gsm_get_mcc(subscr->plmn_mcc),
1154                         gsm_get_mnc(subscr->plmn_mcc, subscr->plmn_mnc));
1155         print(priv, " Access barred cells: %s\n",
1156                 (subscr->acc_barr) ? "yes" : "no");
1157         print(priv, " Access classes:");
1158         for (i = 0; i < 16; i++)
1159                 if ((subscr->acc_class & (1 << i)))
1160                         print(priv, " C%d", i);
1161         print(priv, "\n");
1162         if (!llist_empty(&subscr->plmn_list)) {
1163                 print(priv, " List of preferred PLMNs:\n");
1164                 print(priv, "        MCC    |MNC\n");
1165                 print(priv, "        -------+-------\n");
1166                 llist_for_each_entry(plmn_list, &subscr->plmn_list, entry)
1167                         print(priv, "        %s    |%s        (%s, %s)\n",
1168                         gsm_print_mcc(plmn_list->mcc),
1169                         gsm_print_mnc(plmn_list->mnc),
1170                         gsm_get_mcc(plmn_list->mcc),
1171                         gsm_get_mnc(plmn_list->mcc, plmn_list->mnc));
1172         }
1173         if (!llist_empty(&subscr->plmn_na)) {
1174                 print(priv, " List of forbidden PLMNs:\n");
1175                 print(priv, "        MCC    |MNC    |cause\n");
1176                 print(priv, "        -------+-------+-------\n");
1177                 llist_for_each_entry(plmn_na, &subscr->plmn_na, entry)
1178                         print(priv, "        %s    |%s%s    |#%d        "
1179                                 "(%s, %s)\n", gsm_print_mcc(plmn_na->mcc),
1180                                 gsm_print_mnc(plmn_na->mnc),
1181                                 ((plmn_na->mnc & 0x00f) == 0x00f) ? " ":"",
1182                                 plmn_na->cause, gsm_get_mcc(plmn_na->mcc),
1183                                 gsm_get_mnc(plmn_na->mcc, plmn_na->mnc));
1184         }
1185 }
1186