blob: c96bf098d99b8ed19ed4f9d16cc85aeed76b9ea9 [file] [log] [blame]
Supreeth Herle475dcaa2020-03-20 18:57:39 +01001# -*- coding: utf-8 -*-
2
Harald Weltef12979d2021-05-29 21:47:13 +02003# without this, pylint will fail when inner classes are used
4# within the 'nested' kwarg of our TlvMeta metaclass on python 3.7 :(
5# pylint: disable=undefined-variable
6
Supreeth Herle475dcaa2020-03-20 18:57:39 +01007"""
Harald Welte2f831032021-04-20 23:54:53 +02008Various constants from 3GPP TS 31.102 V16.6.0
Supreeth Herle475dcaa2020-03-20 18:57:39 +01009"""
10
11#
12# Copyright (C) 2020 Supreeth Herle <herlesupreeth@gmail.com>
Harald Welte790b2702021-04-11 00:01:35 +020013# Copyright (C) 2021 Harald Welte <laforge@osmocom.org>
Supreeth Herle475dcaa2020-03-20 18:57:39 +010014#
15# This program is free software: you can redistribute it and/or modify
16# it under the terms of the GNU General Public License as published by
17# the Free Software Foundation, either version 2 of the License, or
18# (at your option) any later version.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program. If not, see <http://www.gnu.org/licenses/>.
27#
28
29# Mapping between USIM Service Number and its description
30EF_UST_map = {
31 1: 'Local Phone Book',
32 2: 'Fixed Dialling Numbers (FDN)',
33 3: 'Extension 2',
34 4: 'Service Dialling Numbers (SDN)',
35 5: 'Extension3',
36 6: 'Barred Dialling Numbers (BDN)',
37 7: 'Extension4',
38 8: 'Outgoing Call Information (OCI and OCT)',
39 9: 'Incoming Call Information (ICI and ICT)',
40 10: 'Short Message Storage (SMS)',
41 11: 'Short Message Status Reports (SMSR)',
42 12: 'Short Message Service Parameters (SMSP)',
43 13: 'Advice of Charge (AoC)',
44 14: 'Capability Configuration Parameters 2 (CCP2)',
45 15: 'Cell Broadcast Message Identifier',
46 16: 'Cell Broadcast Message Identifier Ranges',
47 17: 'Group Identifier Level 1',
48 18: 'Group Identifier Level 2',
49 19: 'Service Provider Name',
50 20: 'User controlled PLMN selector with Access Technology',
51 21: 'MSISDN',
52 22: 'Image (IMG)',
53 23: 'Support of Localised Service Areas (SoLSA)',
54 24: 'Enhanced Multi-Level Precedence and Pre-emption Service',
55 25: 'Automatic Answer for eMLPP',
56 26: 'RFU',
57 27: 'GSM Access',
58 28: 'Data download via SMS-PP',
59 29: 'Data download via SMS-CB',
60 30: 'Call Control by USIM',
61 31: 'MO-SMS Control by USIM',
62 32: 'RUN AT COMMAND command',
63 33: 'shall be set to 1',
64 34: 'Enabled Services Table',
65 35: 'APN Control List (ACL)',
66 36: 'Depersonalisation Control Keys',
67 37: 'Co-operative Network List',
68 38: 'GSM security context',
69 39: 'CPBCCH Information',
70 40: 'Investigation Scan',
71 41: 'MexE',
72 42: 'Operator controlled PLMN selector with Access Technology',
73 43: 'HPLMN selector with Access Technology',
74 44: 'Extension 5',
75 45: 'PLMN Network Name',
76 46: 'Operator PLMN List',
77 47: 'Mailbox Dialling Numbers',
78 48: 'Message Waiting Indication Status',
79 49: 'Call Forwarding Indication Status',
80 50: 'Reserved and shall be ignored',
81 51: 'Service Provider Display Information',
82 52: 'Multimedia Messaging Service (MMS)',
83 53: 'Extension 8',
84 54: 'Call control on GPRS by USIM',
85 55: 'MMS User Connectivity Parameters',
86 56: 'Network\'s indication of alerting in the MS (NIA)',
87 57: 'VGCS Group Identifier List (EFVGCS and EFVGCSS)',
88 58: 'VBS Group Identifier List (EFVBS and EFVBSS)',
89 59: 'Pseudonym',
90 60: 'User Controlled PLMN selector for I-WLAN access',
91 61: 'Operator Controlled PLMN selector for I-WLAN access',
92 62: 'User controlled WSID list',
93 63: 'Operator controlled WSID list',
94 64: 'VGCS security',
95 65: 'VBS security',
96 66: 'WLAN Reauthentication Identity',
97 67: 'Multimedia Messages Storage',
98 68: 'Generic Bootstrapping Architecture (GBA)',
99 69: 'MBMS security',
100 70: 'Data download via USSD and USSD application mode',
101 71: 'Equivalent HPLMN',
102 72: 'Additional TERMINAL PROFILE after UICC activation',
103 73: 'Equivalent HPLMN Presentation Indication',
104 74: 'Last RPLMN Selection Indication',
105 75: 'OMA BCAST Smart Card Profile',
106 76: 'GBA-based Local Key Establishment Mechanism',
107 77: 'Terminal Applications',
108 78: 'Service Provider Name Icon',
109 79: 'PLMN Network Name Icon',
110 80: 'Connectivity Parameters for USIM IP connections',
111 81: 'Home I-WLAN Specific Identifier List',
112 82: 'I-WLAN Equivalent HPLMN Presentation Indication',
113 83: 'I-WLAN HPLMN Priority Indication',
114 84: 'I-WLAN Last Registered PLMN',
115 85: 'EPS Mobility Management Information',
116 86: 'Allowed CSG Lists and corresponding indications',
117 87: 'Call control on EPS PDN connection by USIM',
118 88: 'HPLMN Direct Access',
119 89: 'eCall Data',
120 90: 'Operator CSG Lists and corresponding indications',
121 91: 'Support for SM-over-IP',
122 92: 'Support of CSG Display Control',
123 93: 'Communication Control for IMS by USIM',
124 94: 'Extended Terminal Applications',
125 95: 'Support of UICC access to IMS',
126 96: 'Non-Access Stratum configuration by USIM',
127 97: 'PWS configuration by USIM',
128 98: 'RFU',
129 99: 'URI support by UICC',
130 100: 'Extended EARFCN support',
131 101: 'ProSe',
132 102: 'USAT Application Pairing',
133 103: 'Media Type support',
134 104: 'IMS call disconnection cause',
135 105: 'URI support for MO SHORT MESSAGE CONTROL',
136 106: 'ePDG configuration Information support',
137 107: 'ePDG configuration Information configured',
138 108: 'ACDC support',
139 109: 'MCPTT',
140 110: 'ePDG configuration Information for Emergency Service support',
141 111: 'ePDG configuration Information for Emergency Service configured',
Supreeth Herle4d9e6be2020-03-24 12:13:45 +0100142 112: 'eCall Data over IMS',
143 113: 'URI support for SMS-PP DOWNLOAD as defined in 3GPP TS 31.111 [12]',
144 114: 'From Preferred',
145 115: 'IMS configuration data',
146 116: 'TV configuration',
147 117: '3GPP PS Data Off',
148 118: '3GPP PS Data Off Service List',
149 119: 'V2X',
150 120: 'XCAP Configuration Data',
151 121: 'EARFCN list for MTC/NB-IOT UEs',
152 122: '5GS Mobility Management Information',
153 123: '5G Security Parameters',
154 124: 'Subscription identifier privacy support',
155 125: 'SUCI calculation by the USIM',
156 126: 'UAC Access Identities support',
157 127: 'Expect control plane-based Steering of Roaming information during initial registration in VPLMN',
158 128: 'Call control on PDU Session by USIM',
Harald Welte2f831032021-04-20 23:54:53 +0200159 129: '5GS Operator PLMN List',
160 130: 'Support for SUPI of type NSI or GLI or GCI',
161 131: '3GPP PS Data Off separate Home and Roaming lists',
162 132: 'Support for URSP by USIM',
163 133: '5G Security Parameters extended',
164 134: 'MuD and MiD configuration data',
165 135: 'Support for Trusted non-3GPP access networks by USIM'
Sebastian Viviani0dc8f692020-05-29 00:14:55 +0100166}
167
Sebastian Vivianie61170c2020-06-03 08:57:00 +0100168LOCI_STATUS_map = {
169 0: 'updated',
170 1: 'not updated',
171 2: 'plmn not allowed',
172 3: 'locatation area not allowed'
173}
herlesupreetha562ea02020-09-16 20:17:22 +0200174
Sebastian Viviani0dc8f692020-05-29 00:14:55 +0100175EF_USIM_ADF_map = {
176 'LI': '6F05',
177 'ARR': '6F06',
178 'IMSI': '6F07',
179 'Keys': '6F08',
180 'KeysPS': '6F09',
181 'DCK': '6F2C',
182 'HPPLMN': '6F31',
183 'CNL': '6F32',
184 'ACMmax': '6F37',
185 'UST': '6F38',
186 'ACM': '6F39',
187 'FDN': '6F3B',
188 'SMS': '6F3C',
189 'GID1': '6F3E',
190 'GID2': '6F3F',
191 'MSISDN': '6F40',
192 'PUCT': '6F41',
193 'SMSP': '6F42',
194 'SMSS': '6F42',
195 'CBMI': '6F45',
196 'SPN': '6F46',
197 'SMSR': '6F47',
198 'CBMID': '6F48',
199 'SDN': '6F49',
200 'EXT2': '6F4B',
201 'EXT3': '6F4C',
202 'BDN': '6F4D',
203 'EXT5': '6F4E',
204 'CCP2': '6F4F',
205 'CBMIR': '6F50',
206 'EXT4': '6F55',
207 'EST': '6F56',
208 'ACL': '6F57',
209 'CMI': '6F58',
210 'START-HFN': '6F5B',
211 'THRESHOLD': '6F5C',
212 'PLMNwAcT': '6F60',
213 'OPLMNwAcT': '6F61',
214 'HPLMNwAcT': '6F62',
215 'PSLOCI': '6F73',
216 'ACC': '6F78',
217 'FPLMN': '6F7B',
218 'LOCI': '6F7E',
219 'ICI': '6F80',
220 'OCI': '6F81',
221 'ICT': '6F82',
222 'OCT': '6F83',
223 'AD': '6FAD',
224 'VGCS': '6FB1',
225 'VGCSS': '6FB2',
226 'VBS': '6FB3',
227 'VBSS': '6FB4',
228 'eMLPP': '6FB5',
229 'AAeM': '6FB6',
230 'ECC': '6FB7',
231 'Hiddenkey': '6FC3',
232 'NETPAR': '6FC4',
233 'PNN': '6FC5',
234 'OPL': '6FC6',
235 'MBDN': '6FC7',
236 'EXT6': '6FC8',
237 'MBI': '6FC9',
238 'MWIS': '6FCA',
239 'CFIS': '6FCB',
240 'EXT7': '6FCC',
241 'SPDI': '6FCD',
242 'MMSN': '6FCE',
243 'EXT8': '6FCF',
244 'MMSICP': '6FD0',
245 'MMSUP': '6FD1',
246 'MMSUCP': '6FD2',
247 'NIA': '6FD3',
248 'VGCSCA': '6FD4',
249 'VBSCA': '6FD5',
250 'GBAP': '6FD6',
251 'MSK': '6FD7',
252 'MUK': '6FD8',
253 'EHPLMN': '6FD9',
254 'GBANL': '6FDA',
255 'EHPLMNPI': '6FDB',
256 'LRPLMNSI': '6FDC',
257 'NAFKCA': '6FDD',
258 'SPNI': '6FDE',
259 'PNNI': '6FDF',
260 'NCP-IP': '6FE2',
261 'EPSLOCI': '6FE3',
262 'EPSNSC': '6FE4',
263 'UFC': '6FE6',
264 'UICCIARI': '6FE7',
265 'NASCONFIG': '6FE8',
266 'PWC': '6FEC',
267 'FDNURI': '6FED',
268 'BDNURI': '6FEE',
269 'SDNURI': '6FEF',
270 'IWL': '6FF0',
271 'IPS': '6FF1',
272 'IPD': '6FF2',
273 'ePDGId': '6FF3',
274 'ePDGSelection': '6FF4',
275 'ePDGIdEm': '6FF5',
276 'ePDGSelectionEm': '6FF6',
277}
Harald Welteb2edd142021-01-08 23:29:35 +0100278
279######################################################################
280# ADF.USIM
281######################################################################
282
Harald Welte592b32e2021-06-05 11:26:36 +0200283import enum
Harald Welte15fae982021-04-10 10:22:27 +0200284from struct import unpack, pack
Harald Welte9853e242021-04-10 19:08:25 +0200285from construct import *
Harald Welte592b32e2021-06-05 11:26:36 +0200286from construct import Optional as COptional
Harald Weltef12979d2021-05-29 21:47:13 +0200287from pySim.construct import *
Harald Welteb2edd142021-01-08 23:29:35 +0100288from pySim.filesystem import *
Harald Weltef12979d2021-05-29 21:47:13 +0200289from pySim.tlv import *
Harald Welte790b2702021-04-11 00:01:35 +0200290from pySim.ts_102_221 import EF_ARR
Harald Welte592b32e2021-06-05 11:26:36 +0200291from pySim.ts_51_011 import EF_IMSI, EF_xPLMNwAcT, EF_SPN, EF_CBMI, EF_ACC, EF_PLMNsel
Harald Welte790b2702021-04-11 00:01:35 +0200292from pySim.ts_51_011 import EF_CBMID, EF_CBMIR, EF_ADN, EF_SMS, EF_MSISDN, EF_SMSP, EF_SMSS
293from pySim.ts_51_011 import EF_SMSR, EF_DCK, EF_EXT, EF_CNL, EF_OPL, EF_MBI, EF_MWIS
294from pySim.ts_51_011 import EF_MMSN, EF_MMSICP, EF_MMSUP, EF_MMSUCP, EF_VGCS, EF_VGCSS, EF_NIA
295from pySim.ts_51_011 import EF_ACMmax, EF_AAeM, EF_eMLPP, EF_CMI
Harald Welteb2edd142021-01-08 23:29:35 +0100296
297import pySim.ts_102_221
298
Harald Weltef12979d2021-05-29 21:47:13 +0200299# 3GPP TS 31.102 Section 4.4.11.4 (EF_5GS3GPPNSC)
300class EF_5GS3GPPNSC(LinFixedEF):
301 class NgKSI(BER_TLV_IE, tag=0x80):
302 _construct = Int8ub
303
304 class K_AMF(BER_TLV_IE, tag=0x81):
305 _construct = HexAdapter(Bytes(32))
306
307 class UplinkNASCount(BER_TLV_IE, tag=0x82):
308 _construct = Int32ub
309
310 class DownlinkNASCount(BER_TLV_IE, tag=0x83):
311 _construct = Int32ub
312
313 class IdsOfSelectedNasAlgos(BER_TLV_IE, tag=0x84):
314 # 3GPP TS 24.501 Section 9.11.3.34
315 _construct = BitStruct('ciphering'/Nibble, 'integrity'/Nibble)
316
317 class IdsOfSelectedEpsAlgos(BER_TLV_IE, tag=0x85):
318 # 3GPP TS 24.301 Section 9.9.3.23
319 _construct = BitStruct('ciphering'/Nibble, 'integrity'/Nibble)
320
321 class FiveGSNasSecurityContext(BER_TLV_IE, tag=0xA0,
322 nested=[NgKSI, K_AMF, UplinkNASCount,
323 DownlinkNASCount, IdsOfSelectedNasAlgos,
324 IdsOfSelectedEpsAlgos]):
325 pass
326
327 def __init__(self, fid="4f03", sfid=0x03, name='EF.5GS3GPPNSC', rec_len={57, None},
328 desc='5GS 3GPP Access NAS Security Context'):
329 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
330 self._tlv = EF_5GS3GPPNSC.FiveGSNasSecurityContext()
331
332# 3GPP TS 31.102 Section 4.4.11.6
333class EF_5GAUTHKEYS(TransparentEF):
334 class K_AUSF(BER_TLV_IE, tag=0x80):
335 _construct = HexAdapter(GreedyBytes)
336
337 class K_SEAF(BER_TLV_IE, tag=0x81):
338 _construct = HexAdapter(GreedyBytes)
339
340 class FiveGAuthKeys(TLV_IE_Collection, nested=[K_AUSF, K_SEAF]):
341 pass
342
343 def __init__(self, fid='4f05', sfid=0x05, name='EF.5GAUTHKEYS', size={68, None},
344 desc='5G authentication keys'):
345 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
346 self._tlv = EF_5GAUTHKEYS.FiveGAuthKeys()
347
348# 3GPP TS 31.102 Section 4.4.11.8
349class ProtSchemeIdList(BER_TLV_IE, tag=0xa0):
350 # FIXME: 3GPP TS 24.501 Protection Scheme Identifier
351 # repeated sequence of (id, index) tuples
352 _construct = GreedyRange(Struct('id'/Enum(Byte, null=0, A=1, B=2), 'index'/Int8ub))
353
354class HomeNetPubKeyId(BER_TLV_IE, tag=0x80):
355 # 3GPP TS 24.501 / 3GPP TS 23.003
356 _construct = Int8ub
357
358class HomeNetPubKey(BER_TLV_IE, tag=0x81):
359 # FIXME: RFC 5480
360 _construct = HexAdapter(GreedyBytes)
361
362class HomeNetPubKeyList(BER_TLV_IE, tag=0xa1,
363 nested=[HomeNetPubKeyId, HomeNetPubKey]):
364 pass
365
366# 3GPP TS 31.102 Section 4.4.11.6
367class SUCI_CalcInfo(TLV_IE_Collection, nested=[ProtSchemeIdList,HomeNetPubKeyList]):
368 pass
369
370
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200371# TS 31.102 4.4.11.8
372class EF_SUCI_Calc_Info(TransparentEF):
373 def __init__(self, fid="4f07", sfid=0x07, name='EF.SUCI_Calc_Info', size={2, None},
374 desc='SUCI Calc Info'):
375 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
376
377 def _encode_prot_scheme_id_list(self, in_list):
378 out_bytes = [0xa0]
379 out_bytes.append(len(in_list)*2) # two byte per entry
380
381 # position in list determines priority; high-priority items (low index) come first
382 for scheme in sorted(in_list, key=lambda item: item["priority"]):
383 out_bytes.append(scheme["identifier"])
384 out_bytes.append(scheme["key_index"])
385
386 return out_bytes
387
388 def _encode_hnet_pubkey_list(self, hnet_pubkey_list):
389 out_bytes = [0xa1] # pubkey list tag
390 out_bytes.append(0x00) # length filled later
391 length = 0
392
393 for key in hnet_pubkey_list:
394 out_bytes.append(0x80) # identifier tag
395 out_bytes.append(0x01) # TODO size, fixed to 1 byte
396 out_bytes.append(key["hnet_pubkey_identifier"])
397 out_bytes.append(0x81) # key tag
398 out_bytes.append(len(key["hnet_pubkey"])//2)
399 length += 5+len(key["hnet_pubkey"])//2
400
401 pubkey_bytes = h2b(key["hnet_pubkey"])
402 out_bytes += pubkey_bytes
403
404 # fill length
405 out_bytes[1] = length
406 return out_bytes
407
408 def _encode_hex(self, in_json):
409 out_bytes = self._encode_prot_scheme_id_list(in_json['prot_scheme_id_list'])
410 out_bytes += self._encode_hnet_pubkey_list(in_json['hnet_pubkey_list'])
411 return "".join(["%02X" % i for i in out_bytes])
412
413 def _decode_prot_scheme_id_list(self, in_bytes):
414 prot_scheme_id_list = []
415 pos = 0
416 # two bytes per entry
417 while pos < len(in_bytes):
418 prot_scheme = {
419 'priority': pos//2, # first in list: high priority
420 'identifier': in_bytes[pos],
421 'key_index': in_bytes[pos+1]
422 }
423 pos += 2
424 prot_scheme_id_list.append(prot_scheme)
425 return prot_scheme_id_list
426
427 def _decode_hnet_pubkey_list(self, in_bytes):
428 hnet_pubkey_list = []
429 pos = 0
430 if in_bytes[pos] != 0xa1:
431 print("missing Home Network Public Key List data object")
432 return {}
433 pos += 1
434 hnet_pubkey_list_len = in_bytes[pos]
435 pos += 1
436
437 while pos < hnet_pubkey_list_len:
438 if in_bytes[pos] != 0x80:
439 print("missing Home Network Public Key Identifier tag")
440 return {}
441 pos += 1
442 hnet_pubkey_id_len = in_bytes[pos] # TODO might be more than 1 byte?
443 pos += 1
444 hnet_pubkey_id = in_bytes[pos:pos+hnet_pubkey_id_len][0]
445 pos += hnet_pubkey_id_len
446 if in_bytes[pos] != 0x81:
447 print("missing Home Network Public Key tag")
448 return {}
449 pos += 1
450 hnet_pubkey_len = in_bytes[pos]
451 pos += 1
452 hnet_pubkey = in_bytes[pos:pos+hnet_pubkey_len]
453 pos += hnet_pubkey_len
454
455 hnet_pubkey_list.append({
456 'hnet_pubkey_identifier': hnet_pubkey_id,
457 'hnet_pubkey': b2h(hnet_pubkey)
458 })
459
460 return hnet_pubkey_list
461
462 def _decode_bin(self, in_bin):
Vadim Yanitskiy5e41eeb2021-05-02 02:20:33 +0200463 return self._decode_hex(b2h(in_bin))
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200464
465 def _decode_hex(self, in_hex):
466 in_bytes = h2b(in_hex)
467 pos = 0
468
469 if in_bytes[pos] != 0xa0:
470 print("missing Protection Scheme Identifier List data object tag")
471 return {}
472 pos += 1
473
474 prot_scheme_id_list_len = in_bytes[pos] # TODO maybe more than 1 byte
475 pos += 1
476 # decode Protection Scheme Identifier List data object
477 prot_scheme_id_list = self._decode_prot_scheme_id_list(in_bytes[pos:pos+prot_scheme_id_list_len])
478 pos += prot_scheme_id_list_len
479
480 # remaining data holds Home Network Public Key Data Object
481 hnet_pubkey_list = self._decode_hnet_pubkey_list(in_bytes[pos:])
482
483 return {
484 'prot_scheme_id_list': prot_scheme_id_list,
485 'hnet_pubkey_list': hnet_pubkey_list
486 }
487
488 def _encode_bin(self, in_json):
489 return h2b(self._encode_hex(in_json))
490
Harald Welteb2edd142021-01-08 23:29:35 +0100491class EF_LI(TransRecEF):
492 def __init__(self, fid='6f05', sfid=None, name='EF.LI', size={2,None}, rec_len=2,
493 desc='Language Indication'):
494 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, rec_len=rec_len)
495 def _decode_record_bin(self, in_bin):
496 if in_bin == b'\xff\xff':
497 return None
498 else:
499 # officially this is 7-bit GSM alphabet with one padding bit in each byte
500 return in_bin.decode('ascii')
501 def _encode_record_bin(self, in_json):
502 if in_json == None:
503 return b'\xff\xff'
504 else:
505 # officially this is 7-bit GSM alphabet with one padding bit in each byte
506 return in_json.encode('ascii')
507
508class EF_Keys(TransparentEF):
509 def __init__(self, fid='6f08', sfid=0x08, name='EF.Keys', size={33,33},
510 desc='Ciphering and Integrity Keys'):
511 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Welte9853e242021-04-10 19:08:25 +0200512 self._construct = Struct('ksi'/Int8ub, 'ck'/HexAdapter(Bytes(16)), 'ik'/HexAdapter(Bytes(16)))
Harald Welteb2edd142021-01-08 23:29:35 +0100513
Harald Welte14105dc2021-05-31 08:48:51 +0200514# TS 31.102 Section 4.2.6
515class EF_HPPLMN(TransparentEF):
516 def __init__(self, fid='6f31', sfid=0x12, name='EF.HPPLMN', size={1,1},
517 desc='Higher Priority PLMN search period'):
518 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
519 self._construct = Int8ub
520
521# TS 31.102 Section 4.2.8
Harald Welteb2edd142021-01-08 23:29:35 +0100522class EF_UST(TransparentEF):
Harald Welte790b2702021-04-11 00:01:35 +0200523 def __init__(self, fid='6f38', sfid=0x04, name='EF.UST', desc='USIM Service Table', size={1,17}):
524 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Welteb2edd142021-01-08 23:29:35 +0100525 # add those commands to the general commands of a TransparentEF
526 self.shell_commands += [self.AddlShellCommands()]
527 def _decode_bin(self, in_bin):
528 ret = []
529 for i in range (0, len(in_bin)):
530 byte = in_bin[i]
531 for bitno in range(0,7):
532 if byte & (1 << bitno):
533 ret.append(i * 8 + bitno + 1)
534 return ret
535 def _encode_bin(self, in_json):
536 # FIXME: size this to length of file
537 ret = bytearray(20)
538 for srv in in_json:
539 print("srv=%d"%srv)
540 srv = srv-1
541 byte_nr = srv // 8
542 # FIXME: detect if service out of range was selected
543 bit_nr = srv % 8
544 ret[byte_nr] |= (1 << bit_nr)
545 return ret
546 @with_default_category('File-Specific Commands')
547 class AddlShellCommands(CommandSet):
548 def __init__(self):
549 super().__init__()
550
551 def do_ust_service_activate(self, arg):
552 """Activate a service within EF.UST"""
553 self._cmd.card.update_ust(int(arg), 1)
554
555 def do_ust_service_deactivate(self, arg):
556 """Deactivate a service within EF.UST"""
557 self._cmd.card.update_ust(int(arg), 0)
558
Harald Welte89e59542021-04-02 21:33:13 +0200559# TS 31.103 Section 4.2.7 - *not* the same as DF.GSM/EF.ECC!
560class EF_ECC(LinFixedEF):
Harald Welteff2d86d2022-01-21 15:19:47 +0100561 cc_construct = Rpad(BcdAdapter(Rpad(Bytes(3))), pattern='f')
562 category_construct = FlagsEnum(Byte, police=1, ambulance=2, fire_brigade=3, marine_guard=4,
563 mountain_rescue=5, manual_ecall=6, automatic_ecall=7)
564 alpha_construct = GsmStringAdapter(Rpad(GreedyBytes))
Harald Welte89e59542021-04-02 21:33:13 +0200565 def __init__(self, fid='6fb7', sfid=0x01, name='EF.ECC',
566 desc='Emergency Call Codes'):
567 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len={4,20})
Harald Welteff2d86d2022-01-21 15:19:47 +0100568 def _decode_record_bin(self, in_bin):
569 # mandatory parts
570 code = in_bin[:3]
571 if code == b'\xff\xff\xff':
572 return None
573 svc_category = in_bin[-1:]
574 ret = {'call_code': parse_construct(EF_ECC.cc_construct, code),
575 'service_category': parse_construct(EF_ECC.category_construct, svc_category) }
576 # optional alpha identifier
577 if len(in_bin) > 4:
578 alpha_id = in_bin[3:-1]
579 ret['alpha_id'] = parse_construct(EF_ECC.alpha_construct, alpha_id)
580 return ret
581 def _encode_record_bin(self, in_json):
582 if in_json is None:
583 return b'\xff\xff\xff\xff'
584 code = EF_ECC.cc_construct.build(in_json['call_code'])
585 svc_category = EF_ECC.category_construct.build(in_json['category'])
586 alpha_id = EF_ECC.alpha_construct.build(in_json['alpha_id'])
587 # FIXME: alpha_id needs padding up to 'record_length - 4'
588 return code + alpha_id + svc_category
589
Harald Welte89e59542021-04-02 21:33:13 +0200590
Harald Welte790b2702021-04-11 00:01:35 +0200591# TS 31.102 Section 4.2.17
592class EF_LOCI(TransparentEF):
Harald Weltec9cdce32021-04-11 10:28:28 +0200593 def __init__(self, fid='6f7e', sfid=0x0b, name='EF.LOCI', desc='Location information', size={11,11}):
Harald Welte790b2702021-04-11 00:01:35 +0200594 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
595 self._construct = Struct('tmsi'/HexAdapter(Bytes(4)), 'lai'/HexAdapter(Bytes(5)), 'rfu'/Int8ub,
596 'lu_status'/Int8ub)
Harald Welte592b32e2021-06-05 11:26:36 +0200597# TS 31.102 Section 4.2.18
598class EF_AD(TransparentEF):
599 class OP_MODE(enum.IntEnum):
600 normal = 0x00
601 type_approval = 0x80
602 normal_and_specific_facilities = 0x01
603 type_approval_and_specific_facilities = 0x81
604 maintenance_off_line = 0x02
605 cell_test = 0x04
606
607 def __init__(self, fid='6fad', sfid=0x03, name='EF.AD', desc='Administrative Data', size={4,6}):
608 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
609 self._construct = BitStruct(
610 # Byte 1
611 'ms_operation_mode'/Bytewise(Enum(Byte, EF_AD.OP_MODE)),
612 # Byte 2 + 3
613 'additional_info'/Bytewise(FlagsEnum(Int16ub, ciphering_indicator=1, csg_display_control=2,
614 prose_services=4, extended_drx=8)),
615 'rfu'/BitsRFU(4),
616 'mnc_len'/BitsInteger(4),
617 'extensions'/COptional(Bytewise(GreedyBytesRFU))
618 )
Harald Welte790b2702021-04-11 00:01:35 +0200619
620# TS 31.102 Section 4.2.23
621class EF_PSLOCI(TransparentEF):
Harald Weltec9cdce32021-04-11 10:28:28 +0200622 def __init__(self, fid='6f73', sfid=0x0c, name='EF.PSLOCI', desc='PS Location information', size={14,14}):
Harald Welte790b2702021-04-11 00:01:35 +0200623 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
624 self._construct = Struct('ptmsi'/HexAdapter(Bytes(4)), 'ptmsi_sig'/HexAdapter(Bytes(3)),
625 'rai'/HexAdapter(Bytes(6)), 'rau_status'/Int8ub)
626
627# TS 31.102 Section 4.2.33
628class EF_ICI(CyclicEF):
629 def __init__(self, fid='6f80', sfid=0x14, name='EF.ICI', rec_len={28,48},
630 desc='Incoming Call Information'):
631 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
632 self._construct = Struct('alpha_id'/Bytes(this._.total_len-28),
633 'len_of_bcd_contents'/Int8ub,
634 'ton_npi'/Int8ub,
635 'call_number'/BcdAdapter(Bytes(10)),
636 'cap_cfg2_record_id'/Int8ub,
637 'ext5_record_id'/Int8ub,
638 'date_and_time'/BcdAdapter(Bytes(7)),
639 'duration'/Int24ub,
640 'status'/Byte,
641 'link_to_phonebook'/Bytes(3))
642
643# TS 31.102 Section 4.2.34
644class EF_OCI(CyclicEF):
645 def __init__(self, fid='6f81', sfid=0x15, name='EF.OCI', rec_len={27,47},
646 desc='Outgoing Call Information'):
647 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
648 self._construct = Struct('alpha_id'/Bytes(this._.total_len-27),
649 'len_of_bcd_contents'/Int8ub,
650 'ton_npi'/Int8ub,
651 'call_number'/BcdAdapter(Bytes(10)),
652 'cap_cfg2_record_id'/Int8ub,
653 'ext5_record_id'/Int8ub,
654 'date_and_time'/BcdAdapter(Bytes(7)),
655 'duration'/Int24ub,
656 'link_to_phonebook'/Bytes(3))
657
658# TS 31.102 Section 4.2.35
659class EF_ICT(CyclicEF):
660 def __init__(self, fid='6f82', sfid=None, name='EF.ICT', rec_len={3,3},
661 desc='Incoming Call Timer'):
662 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
663 self._construct = Struct('accumulated_call_timer'/Int24ub)
664
665# TS 31.102 Section 4.2.38
666class EF_CCP2(LinFixedEF):
667 def __init__(self, fid='6f4f', sfid=0x16, name='EF.CCP2', desc='Capability Configuration Parameters 2'):
668 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len={15,None})
669
670# TS 31.102 Section 4.2.48
671class EF_ACL(TransparentEF):
672 def __init__(self, fid='6f57', sfid=None, name='EF.ACL', size={32,None},
673 desc='Access Point Name Control List'):
674 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
675 self._construct = Struct('num_of_apns'/Int8ub, 'tlvs'/GreedyBytes)
676
677# TS 31.102 Section 4.2.51
678class EF_START_HFN(TransparentEF):
679 def __init__(self, fid='6f5b', sfid=0x0f, name='EF.START-HFN', size={6,6},
680 desc='Initialisation values for Hyperframe number'):
681 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
682 self._construct = Struct('start_cs'/Int24ub, 'start_ps'/Int24ub)
683
684# TS 31.102 Section 4.2.52
685class EF_THRESHOLD(TransparentEF):
686 def __init__(self, fid='6f5c', sfid=0x10, name='EF.THRESHOLD', size={3,3},
687 desc='Maximum value of START'):
688 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
689 self._construct = Struct('max_start'/Int24ub)
690
691# TS 31.102 Section 4.2.77
692class EF_VGCSCA(TransRecEF):
693 def __init__(self, fid='6fd4', sfid=None, name='EF.VGCSCA', size={2,100}, rec_len=2,
694 desc='Voice Group Call Service Ciphering Algorithm'):
695 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, rec_len=rec_len)
696 self._construct = Struct('alg_v_ki_1'/Int8ub, 'alg_v_ki_2'/Int8ub)
697
698# TS 31.102 Section 4.2.79
699class EF_GBABP(TransparentEF):
700 def __init__(self, fid='6fd6', sfid=None, name='EF.GBABP', size={3,50},
701 desc='GBA Bootstrapping parameters'):
702 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
703 self._construct = Struct('rand'/LV, 'b_tid'/LV, 'key_lifetime'/LV)
704
705# TS 31.102 Section 4.2.80
706class EF_MSK(LinFixedEF):
707 def __init__(self, fid='6fd7', sfid=None, name='EF.MSK', desc='MBMS Service Key List'):
708 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len={20,None})
709 msk_ts_constr = Struct('msk_id'/Int32ub, 'timestamp_counter'/Int32ub)
710 self._construct = Struct('key_domain_id'/Bytes(3),
711 'num_msk_id'/Int8ub,
712 'msk_ids'/msk_ts_constr[this.num_msk_id])
Harald Welte14105dc2021-05-31 08:48:51 +0200713# TS 31.102 Section 4.2.81
714class EF_MUK(LinFixedEF):
715 class MUK_Idr(BER_TLV_IE, tag=0x80):
716 _construct = HexAdapter(GreedyBytes)
717 class MUK_Idi(BER_TLV_IE, tag=0x82):
718 _construct = HexAdapter(GreedyBytes)
719 class MUK_ID(BER_TLV_IE, tag=0xA0, nested=[MUK_Idr, MUK_Idi]):
720 pass
721 class TimeStampCounter(BER_TLV_IE, tag=0x81):
722 pass
723 class EF_MUK_Collection(TLV_IE_Collection, nested=[MUK_ID, TimeStampCounter]):
724 pass
725 def __init__(self, fid='6fd8', sfid=None, name='EF.MUK', desc='MBMS User Key'):
726 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len={None,None})
727 self._tlv = EF_MUK.EF_MUK_Collection
728
729# TS 31.102 Section 4.2.83
730class EF_GBANL(LinFixedEF):
731 class NAF_ID(BER_TLV_IE, tag=0x80):
732 _construct = HexAdapter(GreedyBytes)
733 class B_TID(BER_TLV_IE, tag=0x81):
734 _construct = HexAdapter(GreedyBytes)
735 class EF_GBANL_Collection(BER_TLV_IE, nested=[NAF_ID, B_TID]):
736 pass
737 def __init__(self, fid='6fda', sfid=None, name='EF.GBANL', desc='GBA NAF List'):
738 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len={None,None})
739 self._tlv = EF_GBANL.EF_GBANL_Collection
Harald Welte790b2702021-04-11 00:01:35 +0200740
741# TS 31.102 Section 4.2.85
742class EF_EHPLMNPI(TransparentEF):
743 def __init__(self, fid='6fdb', sfid=None, name='EF.EHPLMNPI', size={1,1},
744 desc='Equivalent HPLMN Presentation Indication'):
745 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
746 self._construct = Struct('presentation_ind'/
747 Enum(Byte, no_preference=0, display_highest_prio_only=1, display_all=2))
Harald Welte14105dc2021-05-31 08:48:51 +0200748
749# TS 31.102 Section 4.2.87
750class EF_NAFKCA(LinFixedEF):
751 class NAF_KeyCentreAddress(BER_TLV_IE, tag=0x80):
752 _construct = HexAdapter(GreedyBytes)
753 def __init__(self, fid='6fdd', sfid=None, name='EF.NAFKCA', rec_len={None, None},
754 desc='NAF Key Centre Address'):
755 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
756 self._tlv = EF_NAFKCA.NAF_KeyCentreAddress
757
758# TS 31.102 Section 4.2.90
759class EF_NCP_IP(LinFixedEF):
760 class DataDestAddrRange(TLV_IE, tag=0x83):
761 _construct = Struct('type_of_address'/Enum(Byte, IPv4=0x21, IPv6=0x56),
762 'prefix_length'/Int8ub,
763 'prefix'/HexAdapter(GreedyBytes))
764 class AccessPointName(TLV_IE, tag=0x80):
765 # coded as per TS 23.003
766 _construct = HexAdapter(GreedyBytes)
767 class Login(TLV_IE, tag=0x81):
768 # as per SMS DCS TS 23.038
769 _construct = GsmStringAdapter(GreedyBytes)
770 class Password(TLV_IE, tag=0x82):
771 # as per SMS DCS TS 23.038
772 _construct = GsmStringAdapter(GreedyBytes)
773 class BearerDescription(TLV_IE, tag=0x84):
774 # Bearer descriptionTLV DO as per TS 31.111
775 pass
776 class EF_NCP_IP_Collection(TLV_IE_Collection,
777 nested=[AccessPointName, Login, Password, BearerDescription]):
778 pass
779 def __init__(self, fid='6fe2', sfid=None, name='EF.NCP-IP', rec_len={None, None},
780 desc='Network Connectivity Parameters for USIM IP connections'):
781 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
782 self._tlv = EF_NCP_IP.EF_NCP_IP_Collection
783
Harald Welte790b2702021-04-11 00:01:35 +0200784# TS 31.102 Section 4.2.91
785class EF_EPSLOCI(TransparentEF):
786 def __init__(self, fid='6fe3', sfid=0x1e, name='EF.EPSLOCI', size={18,18},
787 desc='EPS Location Information'):
788 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
789 upd_status_constr = Enum(Byte, updated=0, not_updated=1, roaming_not_allowed=2)
790 self._construct = Struct('guti'/Bytes(12), 'last_visited_registered_tai'/Bytes(5),
791 'eps_update_status'/upd_status_constr)
792
Harald Welte14105dc2021-05-31 08:48:51 +0200793# TS 31.102 Section 4.2.92
794class EF_EPSNSC(LinFixedEF):
795 class KSI_ASME(BER_TLV_IE, tag= 0x80):
796 _construct = Int8ub
797 class K_ASME(BER_TLV_IE, tag= 0x81):
798 _construct = HexAdapter(GreedyBytes)
799 class UplinkNASCount(BER_TLV_IE, tag=0x82):
800 _construct = Int32ub
801 class DownlinkNASCount(BER_TLV_IE, tag=0x83):
802 _construct = Int32ub
803 class IDofNASAlgorithms(BER_TLV_IE, tag=0x84):
804 _construct = HexAdapter(GreedyBytes)
805 class EPS_NAS_Security_Context(BER_TLV_IE, tag=0xa0,
806 nested=[KSI_ASME, K_ASME, UplinkNASCount, DownlinkNASCount,
807 IDofNASAlgorithms]):
808 pass
809 def __init__(self,fid='6fe4', sfid=0x18, name='EF.EPSNSC', rec_len={54,128},
810 desc='EPS NAS Security Context'):
811 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
812 self._tlv = EF_EPSNSC.EPS_NAS_Security_Context
813
Harald Welte790b2702021-04-11 00:01:35 +0200814# TS 31.102 Section 4.2.96
815class EF_PWS(TransparentEF):
816 def __init__(self, fid='6fec', sfid=None, name='EF.PWS', desc='Public Warning System', size={1,1}):
817 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
818 pws_config = FlagsEnum(Byte, ignore_pws_in_hplmn_and_equivalent=1, ignore_pws_in_vplmn=2)
819 self._construct = Struct('pws_configuration'/pws_config)
820
821# TS 31.102 Section 4.2.101
822class EF_IPS(CyclicEF):
823 def __init__(self, fid='6ff1', sfid=None, name='EF.IPS', rec_len={4,4},
824 desc='IMEI(SV) Pairing Status'):
825 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
826 self._construct = Struct('status'/PaddedString(2, 'ascii'),
827 'link_to_ef_ipd'/Int8ub, 'rfu'/Byte)
828
Harald Welte14105dc2021-05-31 08:48:51 +0200829# TS 31.102 Section 4.2.103
830class EF_ePDGId(TransparentEF):
831 class ePDGId(BER_TLV_IE, tag=0x80, nested=[]):
832 _construct = Struct('type_of_ePDG_address'/Enum(Byte, FQDN=0, IPv4=1, IPv6=2),
833 'ePDG_address'/Switch(this.type_of_address,
834 { 'FQDN': GreedyString("utf8"),
835 'IPv4': HexAdapter(GreedyBytes),
836 'IPv6': HexAdapter(GreedyBytes) }))
837 def __init__(self, fid='6ff3', sfid=None, name='EF.eDPDGId', desc='Home ePDG Identifier'):
838 super().__init__(fid, sfid=sfid, name=name, desc=desc)
839 self._tlv = EF_ePDGId.ePDGId
840
Harald Welte71290072021-04-21 10:58:24 +0200841# TS 31.102 Section 4.2.106
842class EF_FromPreferred(TransparentEF):
843 def __init__(self, fid='6ff7', sfid=None, name='EF.FromPreferred', size={1,1},
844 desc='From Preferred'):
845 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
846 self._construct = BitStruct('rfu'/BitsRFU(7), 'from_preferred'/Bit)
847
Harald Welte790b2702021-04-11 00:01:35 +0200848######################################################################
849# DF.5GS
850######################################################################
851
852# TS 31.102 Section 4.4.11.2
853class EF_5GS3GPPLOCI(TransparentEF):
854 def __init__(self, fid='4f01', sfid=0x01, name='EF.5GS3GPPLOCI', size={20,20},
855 desc='5S 3GP location information'):
856 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
857 upd_status_constr = Enum(Byte, updated=0, not_updated=1, roaming_not_allowed=2)
858 self._construct = Struct('5g_guti'/Bytes(13), 'last_visited_registered_tai_in_5gs'/Bytes(6),
859 '5gs_update_status'/upd_status_constr)
860
861# TS 31.102 Section 4.4.11.7
862class EF_UAC_AIC(TransparentEF):
863 def __init__(self, fid='4f06', sfid=0x06, name='EF.UAC_AIC', size={4,4},
864 desc='UAC Access Identities Configuration'):
865 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
866 cfg_constr = FlagsEnum(Byte, multimedia_priority_service=1,
867 mission_critical_service=2)
868 self._construct = Struct('uac_access_id_config'/cfg_constr)
869
Harald Welte14105dc2021-05-31 08:48:51 +0200870# TS 31.102 Section 4.4.11.9
Harald Welte790b2702021-04-11 00:01:35 +0200871class EF_OPL5G(LinFixedEF):
872 def __init__(self, fid='6f08', sfid=0x08, name='EF.OPL5G', desc='5GS Operator PLMN List'):
873 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len={10,None})
874 self._construct = Struct('tai'/Bytes(9), 'pnn_record_id'/Int8ub)
875
Harald Welte14105dc2021-05-31 08:48:51 +0200876# TS 31.102 Section 4.4.11.10
877class EF_SUPI_NAI(TransparentEF):
878 class NetworkSpecificIdentifier(TLV_IE, tag=0x80):
879 # RFC 7542 encoded as UTF-8 string
880 _construct = GreedyString("utf8")
881 class GlobalLineIdentifier(TLV_IE, tag=0x81):
882 # TS 23.003 clause 28.16.2
883 pass
884 class GlobalCableIdentifier(TLV_IE, tag=0x82):
885 # TS 23.003 clause 28.15.2
886 pass
887 class NAI_TLV_Collection(TLV_IE_Collection,
888 nested=[NetworkSpecificIdentifier, GlobalLineIdentifier, GlobalCableIdentifier]):
889 pass
890 def __init__(self, fid='4f09', sfid=0x09, name='EF.SUPI_NAI',
891 desc='SUPI as Network Access Identifier'):
892 super().__init__(fid, sfid=sfid, name=name, desc=desc)
893 self._tlv = EF_SUPI_NAI.NAI_TLV_Collection
894
895class EF_TN3GPPSNN(TransparentEF):
896 class ServingNetworkName(BER_TLV_IE, tag=0x80):
897 _construct = GreedyString("utf8")
898 def __init__(self, fid='4f0c', sfid=0x0c, name='EF.TN3GPPSNN',
899 desc='Trusted non-3GPP Serving network names list'):
900 super().__init__(fid, sfid=sfid, name=name, desc=desc)
901 self._tlv = EF_TN3GPPSNN.ServingNetworkName
902
Harald Welte3990ebb2021-04-20 23:55:14 +0200903# TS 31.102 Section 4.4.5
904class DF_WLAN(CardDF):
905 def __init__(self, fid='5f40', name='DF.WLAN', desc='Files for WLAN purpose'):
906 super().__init__(fid=fid, name=name, desc=desc)
907 files = [
908 TransparentEF('4f41', 0x01, 'EF.Pseudo', 'Pseudonym'),
909 TransparentEF('4f42', 0x02, 'EF.UPLMNWLAN', 'User controlled PLMN selector for I-WLAN Access'),
910 TransparentEF('4f43', 0x03, 'EF.OPLMNWLAN', 'Operator controlled PLMN selector for I-WLAN Access'),
911 LinFixedEF('4f44', 0x04, 'EF.UWSIDL', 'User controlled WLAN Specific Identifier List'),
912 LinFixedEF('4f45', 0x05, 'EF.OWSIDL', 'Operator controlled WLAN Specific Identifier List'),
913 TransparentEF('4f46', 0x06, 'EF.WRI', 'WLAN Reauthentication Identity'),
914 LinFixedEF('4f47', 0x07, 'EF.HWSIDL', 'Home I-WLAN Specific Identifier List'),
915 TransparentEF('4f48', 0x08, 'EF.WEHPLMNPI', 'I-WLAN Equivalent HPLMN Presentation Indication'),
916 TransparentEF('4f49', 0x09, 'EF.WHPI', 'I-WLAN HPLMN Priority Indication'),
917 TransparentEF('4f4a', 0x0a, 'EF.WLRPLMN', 'I-WLAN Last Registered PLMN'),
918 TransparentEF('4f4b', 0x0b, 'EF.HPLMNDAI', 'HPLMN Direct Access Indicator'),
919 ]
920 self.add_files(files)
921
922# TS 31.102 Section 4.4.6
923class DF_HNB(CardDF):
924 def __init__(self, fid='5f50', name='DF.HNB', desc='Files for HomeNodeB purpose'):
925 super().__init__(fid=fid, name=name, desc=desc)
926 files = [
927 LinFixedEF('4f01', 0x01, 'EF.ACSGL', 'Allowed CSG Lists'),
928 LinFixedEF('4f02', 0x02, 'EF.CSGTL', 'CSG Types'),
929 LinFixedEF('4f03', 0x03, 'EF.HNBN', 'Home NodeB Name'),
930 LinFixedEF('4f04', 0x04, 'EF.OCSGL', 'Operator CSG Lists'),
931 LinFixedEF('4f05', 0x05, 'EF.OCSGT', 'Operator CSG Type'),
932 LinFixedEF('4f06', 0x06, 'EF.OHNBN', 'Operator Home NodeB Name'),
933 ]
934 self.add_files(files)
935
936# TS 31.102 Section 4.4.8
937class DF_ProSe(CardDF):
938 def __init__(self, fid='5f90', name='DF.ProSe', desc='Files for ProSe purpose'):
939 super().__init__(fid=fid, name=name, desc=desc)
940 files = [
941 LinFixedEF('4f01', 0x01, 'EF.PROSE_MON', 'ProSe Monitoring Parameters'),
942 LinFixedEF('4f02', 0x02, 'EF.PROSE_ANN', 'ProSe Announcing Parameters'),
943 LinFixedEF('4f03', 0x03, 'EF.PROSEFUNC', 'HPLMN ProSe Function'),
944 TransparentEF('4f04', 0x04, 'EF.PROSE_RADIO_COM', 'ProSe Direct Communication Radio Parameters'),
945 TransparentEF('4f05', 0x05, 'EF.PROSE_RADIO_MON', 'ProSe Direct Discovery Monitoring Radio Parameters'),
946 TransparentEF('4f06', 0x06, 'EF.PROSE_RADIO_ANN', 'ProSe Direct Discovery Announcing Radio Parameters'),
947 LinFixedEF('4f07', 0x07, 'EF.PROSE_POLICY', 'ProSe Policy Parameters'),
948 LinFixedEF('4f08', 0x08, 'EF.PROSE_PLMN', 'ProSe PLMN Parameters'),
949 TransparentEF('4f09', 0x09, 'EF.PROSE_GC', 'ProSe Group Counter'),
950 TransparentEF('4f10', 0x10, 'EF.PST', 'ProSe Service Table'),
951 TransparentEF('4f11', 0x11, 'EF.UIRC', 'ProSe UsageInformationReportingConfiguration'),
952 LinFixedEF('4f12', 0x12, 'EF.PROSE_GM_DISCOVERY', 'ProSe Group Member Discovery Parameters'),
953 LinFixedEF('4f13', 0x13, 'EF.PROSE_RELAY', 'ProSe Relay Parameters'),
954 TransparentEF('4f14', 0x14, 'EF.PROSE_RELAY_DISCOVERY', 'ProSe Relay Discovery Parameters'),
955 ]
956 self.add_files(files)
957
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200958class DF_USIM_5GS(CardDF):
959 def __init__(self, fid='5FC0', name='DF.5GS', desc='5GS related files'):
960 super().__init__(fid=fid, name=name, desc=desc)
961 files = [
Harald Welte2f831032021-04-20 23:54:53 +0200962 # I'm looking at 31.102 R16.6
Harald Welte790b2702021-04-11 00:01:35 +0200963 EF_5GS3GPPLOCI(),
964 EF_5GS3GPPLOCI('4f02', 0x02, 'EF.5GSN3GPPLOCI', '5GS non-3GPP location information'),
Harald Weltef12979d2021-05-29 21:47:13 +0200965 EF_5GS3GPPNSC(),
966 EF_5GS3GPPNSC('4f04', 0x04, 'EF.5GSN3GPPNSC', '5GS non-3GPP Access NAS Security Context'),
967 EF_5GAUTHKEYS(),
Harald Welte790b2702021-04-11 00:01:35 +0200968 EF_UAC_AIC(),
969 EF_SUCI_Calc_Info(),
970 EF_OPL5G(),
Harald Welte14105dc2021-05-31 08:48:51 +0200971 EF_SUPI_NAI(),
Harald Welte790b2702021-04-11 00:01:35 +0200972 TransparentEF('4F0A', 0x0a, 'EF.Routing_Indicator', 'Routing Indicator', size={4,4}),
Harald Welte2f831032021-04-20 23:54:53 +0200973 TransparentEF('4F0B', 0x0b, 'EF.URSP', 'UE Route Selector Policies per PLMN'),
Harald Welte14105dc2021-05-31 08:48:51 +0200974 EF_TN3GPPSNN(),
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200975 ]
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200976 self.add_files(files)
977
Harald Welteb2edd142021-01-08 23:29:35 +0100978class ADF_USIM(CardADF):
979 def __init__(self, aid='a0000000871002', name='ADF.USIM', fid=None, sfid=None,
980 desc='USIM Application'):
981 super().__init__(aid=aid, fid=fid, sfid=sfid, name=name, desc=desc)
Harald Welte15fae982021-04-10 10:22:27 +0200982 # add those commands to the general commands of a TransparentEF
983 self.shell_commands += [self.AddlShellCommands()]
Harald Welteb2edd142021-01-08 23:29:35 +0100984
985 files = [
986 EF_LI(sfid=0x02),
987 EF_IMSI(sfid=0x07),
988 EF_Keys(),
989 EF_Keys('6f09', 0x09, 'EF.KeysPS', desc='Ciphering and Integrity Keys for PS domain'),
990 EF_xPLMNwAcT('6f60', 0x0a, 'EF.PLMNwAcT',
991 'User controlled PLMN Selector with Access Technology'),
Harald Welte14105dc2021-05-31 08:48:51 +0200992 EF_HPPLMN(),
Harald Welte790b2702021-04-11 00:01:35 +0200993 EF_ACMmax(),
Harald Welteb2edd142021-01-08 23:29:35 +0100994 EF_UST(),
995 CyclicEF('6f39', None, 'EF.ACM', 'Accumulated call meter', rec_len={3,3}),
996 TransparentEF('6f3e', None, 'EF.GID1', 'Group Identifier Level 1'),
997 TransparentEF('6f3f', None, 'EF.GID2', 'Group Identifier Level 2'),
998 EF_SPN(),
999 TransparentEF('6f41', None, 'EF.PUCT', 'Price per unit and currency table', size={5,5}),
1000 EF_CBMI(),
1001 EF_ACC(sfid=0x06),
1002 EF_PLMNsel('6f7b', 0x0d, 'EF.FPLMN', 'Forbidden PLMNs', size={12,None}),
Harald Welte790b2702021-04-11 00:01:35 +02001003 EF_LOCI(),
Harald Welte592b32e2021-06-05 11:26:36 +02001004 EF_AD(),
Harald Welteb2edd142021-01-08 23:29:35 +01001005 EF_CBMID(sfid=0x0e),
Harald Welte89e59542021-04-02 21:33:13 +02001006 EF_ECC(),
Harald Welteb2edd142021-01-08 23:29:35 +01001007 EF_CBMIR(),
Harald Welte790b2702021-04-11 00:01:35 +02001008 EF_PSLOCI(),
1009 EF_ADN('6f3b', None, 'EF.FDN', 'Fixed Dialling Numbers'),
1010 EF_SMS('6f3c', None),
1011 EF_MSISDN(),
1012 EF_SMSP(),
1013 EF_SMSS(),
1014 EF_ADN('6f49', None, 'EF.SDN', 'Service Dialling Numbers'),
1015 EF_EXT('6f4b', None, 'EF.EXT2', 'Extension2 (FDN)'),
1016 EF_EXT('6f4c', None, 'EF.EXT3', 'Extension2 (SDN)'),
1017 EF_SMSR(),
1018 EF_ICI(),
1019 EF_OCI(),
1020 EF_ICT(),
1021 EF_ICT('6f83', None, 'EF.OCT', 'Outgoing Call Timer'),
1022 EF_EXT('6f4e', None, 'EF.EXT5', 'Extension5 (ICI/OCI/MSISDN)'),
1023 EF_CCP2(),
1024 EF_eMLPP(),
1025 EF_AAeM(),
1026 # EF_Hiddenkey
1027 EF_ADN('6f4d', None, 'EF.BDN', 'Barred Dialling Numbers'),
1028 EF_EXT('6f55', None, 'EF.EXT4', 'Extension4 (BDN/SSC)'),
1029 EF_CMI(),
1030 EF_UST('6f56', 0x05, 'EF.EST', 'Enabled Services Table', size={1,None}),
1031 EF_ACL(),
1032 EF_DCK(),
1033 EF_CNL(),
1034 EF_START_HFN(),
1035 EF_THRESHOLD(),
1036 EF_xPLMNwAcT('6f61', 0x11, 'EF.OPLMNwAcT',
1037 'User controlled PLMN Selector with Access Technology'),
1038 EF_ARR('6f06', 0x17),
1039 TransparentEF('6fc4', None, 'EF.NETPAR', 'Network Parameters'),
1040 LinFixedEF('6fc5', 0x19, 'EF.PNN', 'PLMN Network Name'),
1041 EF_OPL(),
1042 EF_ADN('6fc7', None, 'EF.MBDN', 'Mailbox Dialling Numbers'),
1043 EF_MBI(),
1044 EF_MWIS(),
1045 EF_ADN('6fcb', None, 'EF.CFIS', 'Call Forwarding Indication Status'),
1046 EF_EXT('6fcc', None, 'EF.EXT7', 'Extension7 (CFIS)'),
1047 TransparentEF('6fcd', None, 'EF.SPDI', 'Service Provider Display Information'),
1048 EF_MMSN(),
1049 EF_EXT('6fcf', None, 'EF.EXT8', 'Extension8 (MMSN)'),
1050 EF_MMSICP(),
1051 EF_MMSUP(),
1052 EF_MMSUCP(),
1053 EF_NIA(),
1054 EF_VGCS(),
1055 EF_VGCSS(),
1056 EF_VGCS('6fb3', None, 'EF.VBS', 'Voice Broadcast Service'),
1057 EF_VGCSS('6fb4', None, 'EF.VBSS', 'Voice Broadcast Service Status'),
1058 EF_VGCSCA(),
1059 EF_VGCSCA('6fd5', None, 'EF.VBCSCA', 'Voice Broadcast Service Ciphering Algorithm'),
1060 EF_GBABP(),
1061 EF_MSK(),
Harald Welte14105dc2021-05-31 08:48:51 +02001062 EF_MUK(),
1063 EF_GBANL(),
Harald Welte790b2702021-04-11 00:01:35 +02001064 EF_PLMNsel('6fd9', 0x1d, 'EF.EHPLMN', 'Equivalent HPLMN', size={12,None}),
1065 EF_EHPLMNPI(),
Harald Welte14105dc2021-05-31 08:48:51 +02001066 EF_NAFKCA(),
Harald Welte790b2702021-04-11 00:01:35 +02001067 TransparentEF('6fde', None, 'EF.SPNI', 'Service Provider Name Icon'),
1068 LinFixedEF('6fdf', None, 'EF.PNNI', 'PLMN Network Name Icon'),
Harald Welte14105dc2021-05-31 08:48:51 +02001069 EF_NCP_IP(),
Harald Welte790b2702021-04-11 00:01:35 +02001070 EF_EPSLOCI('6fe3', 0x1e, 'EF.EPSLOCI', 'EPS location information'),
Harald Welte14105dc2021-05-31 08:48:51 +02001071 EF_EPSNSC(),
Harald Welte790b2702021-04-11 00:01:35 +02001072 TransparentEF('6fe6', None, 'EF.UFC', 'USAT Facility Control', size={1,16}),
1073 TransparentEF('6fe8', None, 'EF.NASCONFIG', 'Non Access Stratum Configuration'),
1074 # UICC IARI (only in cards that have no ISIM)
1075 EF_PWS(),
1076 LinFixedEF('6fed', None, 'EF.FDNURI', 'Fixed Dialling Numbers URI'),
1077 LinFixedEF('6fee', None, 'EF.BDNURI', 'Barred Dialling Numbers URI'),
1078 LinFixedEF('6fef', None, 'EF.SDNURI', 'Service Dialling Numbers URI'),
1079 EF_IPS(),
Harald Welte14105dc2021-05-31 08:48:51 +02001080 EF_ePDGId(),
1081 # FIXME: from EF_ePDGSelection onwards
Harald Welte71290072021-04-21 10:58:24 +02001082 EF_FromPreferred(),
Harald Welte790b2702021-04-11 00:01:35 +02001083 # FIXME: DF_SoLSA
1084 # FIXME: DF_PHONEBOOK
1085 # FIXME: DF_GSM_ACCESS
Harald Welte3990ebb2021-04-20 23:55:14 +02001086 DF_WLAN(),
1087 DF_HNB(),
1088 DF_ProSe(),
Harald Welte790b2702021-04-11 00:01:35 +02001089 # FIXME: DF_ACDC
1090 # FIXME: DF_TV
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001091 DF_USIM_5GS(),
Harald Welteb2edd142021-01-08 23:29:35 +01001092 ]
1093 self.add_files(files)
1094
1095 def decode_select_response(self, data_hex):
Philipp Maier5998a3a2021-11-16 15:16:39 +01001096 return pySim.ts_102_221.CardProfileUICC.decode_select_response(data_hex)
Harald Welteb2edd142021-01-08 23:29:35 +01001097
Harald Welte15fae982021-04-10 10:22:27 +02001098 @with_default_category('Application-Specific Commands')
1099 class AddlShellCommands(CommandSet):
1100 def __init__(self):
1101 super().__init__()
1102
1103 authenticate_parser = argparse.ArgumentParser()
1104 authenticate_parser.add_argument('rand', help='Random challenge')
1105 authenticate_parser.add_argument('autn', help='Authentication Nonce')
1106 #authenticate_parser.add_argument('--context', help='Authentication context', default='3G')
1107 @cmd2.with_argparser(authenticate_parser)
1108 def do_authenticate(self, opts):
1109 """Perform Authentication and Key Agreement (AKA)."""
1110 (data, sw) = self._cmd.card._scc.authenticate(opts.rand, opts.autn)
1111 self._cmd.poutput_json(data)
1112
Harald Welte846a8982021-10-08 15:47:16 +02001113 def do_terminal_profile(self, arg):
1114 """Send a TERMINAL PROFILE command to the card."""
1115 (data, sw) = self._cmd.card._scc.terminal_profile(arg)
1116 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
Harald Welte15fae982021-04-10 10:22:27 +02001117
Harald Welte7cb94e42021-10-08 15:47:57 +02001118 def do_envelope(self, arg):
1119 """Send an ENVELOPE command to the card."""
1120 (data, sw) = self._cmd.card._scc.envelope(arg)
1121 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
1122
1123 def do_envelope_sms(self, arg):
1124 """Send an ENVELOPE command to the card."""
1125 tpdu_ie = SMS_TPDU()
1126 tpdu_ie.from_bytes(h2b(arg))
1127 dev_ids = DeviceIdentities(decoded={'source_dev_id':'network','dest_dev_id':'uicc'})
1128 sms_dl = SMSPPDownload(children=[dev_ids, tpdu_ie])
1129 (data, sw) = self._cmd.card._scc.envelope(b2h(sms_dl.to_tlv()))
1130 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
1131
Harald Welte15fae982021-04-10 10:22:27 +02001132
Harald Welteb2edd142021-01-08 23:29:35 +01001133# TS 31.102 Section 7.3
1134sw_usim = {
1135 'Security management': {
1136 '9862': 'Authentication error, incorrect MAC',
1137 '9864': 'Authentication error, security context not supported',
1138 '9865': 'Key freshness failure',
1139 '9866': 'Authentication error, no memory space available',
1140 '9867': 'Authentication error, no memory space available in EF MUK',
1141 }
1142}
1143
Philipp Maier57f65ee2021-10-18 14:09:02 +02001144class CardApplicationUSIM(CardApplication):
1145 def __init__(self):
1146 super().__init__('USIM', adf=ADF_USIM(), sw=sw_usim)