blob: 9105418ef5dbdf061333abf20ee75dbcb96050fc [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
Harald Weltec91085e2022-02-10 18:05:45 +010030import pySim.ts_102_221
31from pySim.ts_51_011 import EF_ACMmax, EF_AAeM, EF_eMLPP, EF_CMI, EF_PNN
32from pySim.ts_51_011 import EF_MMSN, EF_MMSICP, EF_MMSUP, EF_MMSUCP, EF_VGCS, EF_VGCSS, EF_NIA
33from pySim.ts_51_011 import EF_SMSR, EF_DCK, EF_EXT, EF_CNL, EF_OPL, EF_MBI, EF_MWIS
34from pySim.ts_51_011 import EF_CBMID, EF_CBMIR, EF_ADN, EF_SMS, EF_MSISDN, EF_SMSP, EF_SMSS
35from pySim.ts_51_011 import EF_IMSI, EF_xPLMNwAcT, EF_SPN, EF_CBMI, EF_ACC, EF_PLMNsel
36from pySim.ts_102_221 import EF_ARR
37from pySim.tlv import *
38from pySim.filesystem import *
39from pySim.construct import *
40from construct import Optional as COptional
41from construct import *
42from typing import Tuple
43from struct import unpack, pack
44import enum
Supreeth Herle475dcaa2020-03-20 18:57:39 +010045EF_UST_map = {
Harald Weltec91085e2022-02-10 18:05:45 +010046 1: 'Local Phone Book',
47 2: 'Fixed Dialling Numbers (FDN)',
48 3: 'Extension 2',
49 4: 'Service Dialling Numbers (SDN)',
50 5: 'Extension3',
51 6: 'Barred Dialling Numbers (BDN)',
52 7: 'Extension4',
53 8: 'Outgoing Call Information (OCI and OCT)',
54 9: 'Incoming Call Information (ICI and ICT)',
55 10: 'Short Message Storage (SMS)',
56 11: 'Short Message Status Reports (SMSR)',
57 12: 'Short Message Service Parameters (SMSP)',
58 13: 'Advice of Charge (AoC)',
59 14: 'Capability Configuration Parameters 2 (CCP2)',
60 15: 'Cell Broadcast Message Identifier',
61 16: 'Cell Broadcast Message Identifier Ranges',
62 17: 'Group Identifier Level 1',
63 18: 'Group Identifier Level 2',
64 19: 'Service Provider Name',
65 20: 'User controlled PLMN selector with Access Technology',
66 21: 'MSISDN',
67 22: 'Image (IMG)',
68 23: 'Support of Localised Service Areas (SoLSA)',
69 24: 'Enhanced Multi-Level Precedence and Pre-emption Service',
70 25: 'Automatic Answer for eMLPP',
71 26: 'RFU',
72 27: 'GSM Access',
73 28: 'Data download via SMS-PP',
74 29: 'Data download via SMS-CB',
75 30: 'Call Control by USIM',
76 31: 'MO-SMS Control by USIM',
77 32: 'RUN AT COMMAND command',
78 33: 'shall be set to 1',
79 34: 'Enabled Services Table',
80 35: 'APN Control List (ACL)',
81 36: 'Depersonalisation Control Keys',
82 37: 'Co-operative Network List',
83 38: 'GSM security context',
84 39: 'CPBCCH Information',
85 40: 'Investigation Scan',
86 41: 'MexE',
87 42: 'Operator controlled PLMN selector with Access Technology',
88 43: 'HPLMN selector with Access Technology',
89 44: 'Extension 5',
90 45: 'PLMN Network Name',
91 46: 'Operator PLMN List',
92 47: 'Mailbox Dialling Numbers',
93 48: 'Message Waiting Indication Status',
94 49: 'Call Forwarding Indication Status',
95 50: 'Reserved and shall be ignored',
96 51: 'Service Provider Display Information',
97 52: 'Multimedia Messaging Service (MMS)',
98 53: 'Extension 8',
99 54: 'Call control on GPRS by USIM',
100 55: 'MMS User Connectivity Parameters',
101 56: 'Network\'s indication of alerting in the MS (NIA)',
102 57: 'VGCS Group Identifier List (EFVGCS and EFVGCSS)',
103 58: 'VBS Group Identifier List (EFVBS and EFVBSS)',
104 59: 'Pseudonym',
105 60: 'User Controlled PLMN selector for I-WLAN access',
106 61: 'Operator Controlled PLMN selector for I-WLAN access',
107 62: 'User controlled WSID list',
108 63: 'Operator controlled WSID list',
109 64: 'VGCS security',
110 65: 'VBS security',
111 66: 'WLAN Reauthentication Identity',
112 67: 'Multimedia Messages Storage',
113 68: 'Generic Bootstrapping Architecture (GBA)',
114 69: 'MBMS security',
115 70: 'Data download via USSD and USSD application mode',
116 71: 'Equivalent HPLMN',
117 72: 'Additional TERMINAL PROFILE after UICC activation',
118 73: 'Equivalent HPLMN Presentation Indication',
119 74: 'Last RPLMN Selection Indication',
120 75: 'OMA BCAST Smart Card Profile',
121 76: 'GBA-based Local Key Establishment Mechanism',
122 77: 'Terminal Applications',
123 78: 'Service Provider Name Icon',
124 79: 'PLMN Network Name Icon',
125 80: 'Connectivity Parameters for USIM IP connections',
126 81: 'Home I-WLAN Specific Identifier List',
127 82: 'I-WLAN Equivalent HPLMN Presentation Indication',
128 83: 'I-WLAN HPLMN Priority Indication',
129 84: 'I-WLAN Last Registered PLMN',
130 85: 'EPS Mobility Management Information',
131 86: 'Allowed CSG Lists and corresponding indications',
132 87: 'Call control on EPS PDN connection by USIM',
133 88: 'HPLMN Direct Access',
134 89: 'eCall Data',
135 90: 'Operator CSG Lists and corresponding indications',
136 91: 'Support for SM-over-IP',
137 92: 'Support of CSG Display Control',
138 93: 'Communication Control for IMS by USIM',
139 94: 'Extended Terminal Applications',
140 95: 'Support of UICC access to IMS',
141 96: 'Non-Access Stratum configuration by USIM',
142 97: 'PWS configuration by USIM',
143 98: 'RFU',
144 99: 'URI support by UICC',
145 100: 'Extended EARFCN support',
146 101: 'ProSe',
147 102: 'USAT Application Pairing',
148 103: 'Media Type support',
149 104: 'IMS call disconnection cause',
150 105: 'URI support for MO SHORT MESSAGE CONTROL',
151 106: 'ePDG configuration Information support',
152 107: 'ePDG configuration Information configured',
153 108: 'ACDC support',
154 109: 'MCPTT',
155 110: 'ePDG configuration Information for Emergency Service support',
156 111: 'ePDG configuration Information for Emergency Service configured',
157 112: 'eCall Data over IMS',
158 113: 'URI support for SMS-PP DOWNLOAD as defined in 3GPP TS 31.111 [12]',
159 114: 'From Preferred',
160 115: 'IMS configuration data',
161 116: 'TV configuration',
162 117: '3GPP PS Data Off',
163 118: '3GPP PS Data Off Service List',
164 119: 'V2X',
165 120: 'XCAP Configuration Data',
166 121: 'EARFCN list for MTC/NB-IOT UEs',
167 122: '5GS Mobility Management Information',
168 123: '5G Security Parameters',
169 124: 'Subscription identifier privacy support',
170 125: 'SUCI calculation by the USIM',
171 126: 'UAC Access Identities support',
172 127: 'Expect control plane-based Steering of Roaming information during initial registration in VPLMN',
173 128: 'Call control on PDU Session by USIM',
174 129: '5GS Operator PLMN List',
175 130: 'Support for SUPI of type NSI or GLI or GCI',
176 131: '3GPP PS Data Off separate Home and Roaming lists',
177 132: 'Support for URSP by USIM',
178 133: '5G Security Parameters extended',
179 134: 'MuD and MiD configuration data',
180 135: 'Support for Trusted non-3GPP access networks by USIM'
Sebastian Viviani0dc8f692020-05-29 00:14:55 +0100181}
182
Harald Weltee8947492022-02-10 10:33:20 +0100183# Mapping between USIM Enbled Service Number and its description
184EF_EST_map = {
185 1: 'Fixed Dialling Numbers (FDN)',
186 2: 'Barred Dialling Numbers (BDN)',
187 3: 'APN Control List (ACL)'
188}
189
Sebastian Vivianie61170c2020-06-03 08:57:00 +0100190LOCI_STATUS_map = {
Harald Weltec91085e2022-02-10 18:05:45 +0100191 0: 'updated',
192 1: 'not updated',
193 2: 'plmn not allowed',
194 3: 'locatation area not allowed'
Sebastian Vivianie61170c2020-06-03 08:57:00 +0100195}
herlesupreetha562ea02020-09-16 20:17:22 +0200196
Sebastian Viviani0dc8f692020-05-29 00:14:55 +0100197EF_USIM_ADF_map = {
Harald Weltec91085e2022-02-10 18:05:45 +0100198 'LI': '6F05',
199 'ARR': '6F06',
200 'IMSI': '6F07',
201 'Keys': '6F08',
202 'KeysPS': '6F09',
203 'DCK': '6F2C',
204 'HPPLMN': '6F31',
205 'CNL': '6F32',
206 'ACMmax': '6F37',
207 'UST': '6F38',
208 'ACM': '6F39',
209 'FDN': '6F3B',
210 'SMS': '6F3C',
211 'GID1': '6F3E',
212 'GID2': '6F3F',
213 'MSISDN': '6F40',
214 'PUCT': '6F41',
215 'SMSP': '6F42',
216 'SMSS': '6F42',
217 'CBMI': '6F45',
218 'SPN': '6F46',
219 'SMSR': '6F47',
220 'CBMID': '6F48',
221 'SDN': '6F49',
222 'EXT2': '6F4B',
223 'EXT3': '6F4C',
224 'BDN': '6F4D',
225 'EXT5': '6F4E',
226 'CCP2': '6F4F',
227 'CBMIR': '6F50',
228 'EXT4': '6F55',
229 'EST': '6F56',
230 'ACL': '6F57',
231 'CMI': '6F58',
232 'START-HFN': '6F5B',
233 'THRESHOLD': '6F5C',
234 'PLMNwAcT': '6F60',
235 'OPLMNwAcT': '6F61',
236 'HPLMNwAcT': '6F62',
237 'PSLOCI': '6F73',
238 'ACC': '6F78',
239 'FPLMN': '6F7B',
240 'LOCI': '6F7E',
241 'ICI': '6F80',
242 'OCI': '6F81',
243 'ICT': '6F82',
244 'OCT': '6F83',
245 'AD': '6FAD',
246 'VGCS': '6FB1',
247 'VGCSS': '6FB2',
248 'VBS': '6FB3',
249 'VBSS': '6FB4',
250 'eMLPP': '6FB5',
251 'AAeM': '6FB6',
252 'ECC': '6FB7',
253 'Hiddenkey': '6FC3',
254 'NETPAR': '6FC4',
255 'PNN': '6FC5',
256 'OPL': '6FC6',
257 'MBDN': '6FC7',
258 'EXT6': '6FC8',
259 'MBI': '6FC9',
260 'MWIS': '6FCA',
261 'CFIS': '6FCB',
262 'EXT7': '6FCC',
263 'SPDI': '6FCD',
264 'MMSN': '6FCE',
265 'EXT8': '6FCF',
266 'MMSICP': '6FD0',
267 'MMSUP': '6FD1',
268 'MMSUCP': '6FD2',
269 'NIA': '6FD3',
270 'VGCSCA': '6FD4',
271 'VBSCA': '6FD5',
272 'GBAP': '6FD6',
273 'MSK': '6FD7',
274 'MUK': '6FD8',
275 'EHPLMN': '6FD9',
276 'GBANL': '6FDA',
277 'EHPLMNPI': '6FDB',
278 'LRPLMNSI': '6FDC',
279 'NAFKCA': '6FDD',
280 'SPNI': '6FDE',
281 'PNNI': '6FDF',
282 'NCP-IP': '6FE2',
283 'EPSLOCI': '6FE3',
284 'EPSNSC': '6FE4',
285 'UFC': '6FE6',
286 'UICCIARI': '6FE7',
287 'NASCONFIG': '6FE8',
288 'PWC': '6FEC',
289 'FDNURI': '6FED',
290 'BDNURI': '6FEE',
291 'SDNURI': '6FEF',
292 'IWL': '6FF0',
293 'IPS': '6FF1',
294 'IPD': '6FF2',
295 'ePDGId': '6FF3',
296 'ePDGSelection': '6FF4',
297 'ePDGIdEm': '6FF5',
298 'ePDGSelectionEm': '6FF6',
Sebastian Viviani0dc8f692020-05-29 00:14:55 +0100299}
Harald Welteb2edd142021-01-08 23:29:35 +0100300
301######################################################################
302# ADF.USIM
303######################################################################
304
Harald Welteb2edd142021-01-08 23:29:35 +0100305
Harald Weltef12979d2021-05-29 21:47:13 +0200306# 3GPP TS 31.102 Section 4.4.11.4 (EF_5GS3GPPNSC)
307class EF_5GS3GPPNSC(LinFixedEF):
308 class NgKSI(BER_TLV_IE, tag=0x80):
309 _construct = Int8ub
310
311 class K_AMF(BER_TLV_IE, tag=0x81):
312 _construct = HexAdapter(Bytes(32))
313
314 class UplinkNASCount(BER_TLV_IE, tag=0x82):
315 _construct = Int32ub
316
317 class DownlinkNASCount(BER_TLV_IE, tag=0x83):
318 _construct = Int32ub
319
320 class IdsOfSelectedNasAlgos(BER_TLV_IE, tag=0x84):
321 # 3GPP TS 24.501 Section 9.11.3.34
322 _construct = BitStruct('ciphering'/Nibble, 'integrity'/Nibble)
323
324 class IdsOfSelectedEpsAlgos(BER_TLV_IE, tag=0x85):
325 # 3GPP TS 24.301 Section 9.9.3.23
326 _construct = BitStruct('ciphering'/Nibble, 'integrity'/Nibble)
327
328 class FiveGSNasSecurityContext(BER_TLV_IE, tag=0xA0,
Harald Weltec91085e2022-02-10 18:05:45 +0100329 nested=[NgKSI, K_AMF, UplinkNASCount,
330 DownlinkNASCount, IdsOfSelectedNasAlgos,
331 IdsOfSelectedEpsAlgos]):
Harald Weltef12979d2021-05-29 21:47:13 +0200332 pass
333
334 def __init__(self, fid="4f03", sfid=0x03, name='EF.5GS3GPPNSC', rec_len={57, None},
Harald Weltec91085e2022-02-10 18:05:45 +0100335 desc='5GS 3GPP Access NAS Security Context'):
Harald Weltef12979d2021-05-29 21:47:13 +0200336 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
Harald Welte65516272022-02-10 17:51:05 +0100337 self._tlv = EF_5GS3GPPNSC.FiveGSNasSecurityContext
Harald Weltef12979d2021-05-29 21:47:13 +0200338
339# 3GPP TS 31.102 Section 4.4.11.6
340class EF_5GAUTHKEYS(TransparentEF):
341 class K_AUSF(BER_TLV_IE, tag=0x80):
342 _construct = HexAdapter(GreedyBytes)
343
344 class K_SEAF(BER_TLV_IE, tag=0x81):
345 _construct = HexAdapter(GreedyBytes)
346
347 class FiveGAuthKeys(TLV_IE_Collection, nested=[K_AUSF, K_SEAF]):
348 pass
349
350 def __init__(self, fid='4f05', sfid=0x05, name='EF.5GAUTHKEYS', size={68, None},
Harald Weltec91085e2022-02-10 18:05:45 +0100351 desc='5G authentication keys'):
Harald Weltef12979d2021-05-29 21:47:13 +0200352 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Welte65516272022-02-10 17:51:05 +0100353 self._tlv = EF_5GAUTHKEYS.FiveGAuthKeys
Harald Weltef12979d2021-05-29 21:47:13 +0200354
355# 3GPP TS 31.102 Section 4.4.11.8
356class ProtSchemeIdList(BER_TLV_IE, tag=0xa0):
357 # FIXME: 3GPP TS 24.501 Protection Scheme Identifier
358 # repeated sequence of (id, index) tuples
Harald Weltec91085e2022-02-10 18:05:45 +0100359 _construct = GreedyRange(
360 Struct('id'/Enum(Byte, null=0, A=1, B=2), 'index'/Int8ub))
361
Harald Weltef12979d2021-05-29 21:47:13 +0200362
363class HomeNetPubKeyId(BER_TLV_IE, tag=0x80):
364 # 3GPP TS 24.501 / 3GPP TS 23.003
365 _construct = Int8ub
366
Harald Weltec91085e2022-02-10 18:05:45 +0100367
Harald Weltef12979d2021-05-29 21:47:13 +0200368class HomeNetPubKey(BER_TLV_IE, tag=0x81):
369 # FIXME: RFC 5480
370 _construct = HexAdapter(GreedyBytes)
371
Harald Weltec91085e2022-02-10 18:05:45 +0100372
Harald Weltef12979d2021-05-29 21:47:13 +0200373class HomeNetPubKeyList(BER_TLV_IE, tag=0xa1,
Harald Weltec91085e2022-02-10 18:05:45 +0100374 nested=[HomeNetPubKeyId, HomeNetPubKey]):
Harald Weltef12979d2021-05-29 21:47:13 +0200375 pass
376
377# 3GPP TS 31.102 Section 4.4.11.6
Harald Weltec91085e2022-02-10 18:05:45 +0100378class SUCI_CalcInfo(TLV_IE_Collection, nested=[ProtSchemeIdList, HomeNetPubKeyList]):
Harald Weltef12979d2021-05-29 21:47:13 +0200379 pass
380
381
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200382# TS 31.102 4.4.11.8
383class EF_SUCI_Calc_Info(TransparentEF):
384 def __init__(self, fid="4f07", sfid=0x07, name='EF.SUCI_Calc_Info', size={2, None},
Harald Weltec91085e2022-02-10 18:05:45 +0100385 desc='SUCI Calc Info'):
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200386 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
387
388 def _encode_prot_scheme_id_list(self, in_list):
389 out_bytes = [0xa0]
Harald Weltec91085e2022-02-10 18:05:45 +0100390 out_bytes.append(len(in_list)*2) # two byte per entry
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200391
392 # position in list determines priority; high-priority items (low index) come first
393 for scheme in sorted(in_list, key=lambda item: item["priority"]):
394 out_bytes.append(scheme["identifier"])
395 out_bytes.append(scheme["key_index"])
396
397 return out_bytes
398
399 def _encode_hnet_pubkey_list(self, hnet_pubkey_list):
Harald Weltec91085e2022-02-10 18:05:45 +0100400 out_bytes = [0xa1] # pubkey list tag
401 out_bytes.append(0x00) # length filled later
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200402 length = 0
403
404 for key in hnet_pubkey_list:
Harald Weltec91085e2022-02-10 18:05:45 +0100405 out_bytes.append(0x80) # identifier tag
406 out_bytes.append(0x01) # TODO size, fixed to 1 byte
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200407 out_bytes.append(key["hnet_pubkey_identifier"])
Harald Weltec91085e2022-02-10 18:05:45 +0100408 out_bytes.append(0x81) # key tag
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200409 out_bytes.append(len(key["hnet_pubkey"])//2)
410 length += 5+len(key["hnet_pubkey"])//2
411
412 pubkey_bytes = h2b(key["hnet_pubkey"])
413 out_bytes += pubkey_bytes
414
415 # fill length
416 out_bytes[1] = length
417 return out_bytes
418
419 def _encode_hex(self, in_json):
Harald Weltec91085e2022-02-10 18:05:45 +0100420 out_bytes = self._encode_prot_scheme_id_list(
421 in_json['prot_scheme_id_list'])
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200422 out_bytes += self._encode_hnet_pubkey_list(in_json['hnet_pubkey_list'])
423 return "".join(["%02X" % i for i in out_bytes])
424
425 def _decode_prot_scheme_id_list(self, in_bytes):
426 prot_scheme_id_list = []
427 pos = 0
428 # two bytes per entry
429 while pos < len(in_bytes):
430 prot_scheme = {
Harald Weltec91085e2022-02-10 18:05:45 +0100431 'priority': pos//2, # first in list: high priority
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200432 'identifier': in_bytes[pos],
433 'key_index': in_bytes[pos+1]
434 }
435 pos += 2
436 prot_scheme_id_list.append(prot_scheme)
437 return prot_scheme_id_list
438
439 def _decode_hnet_pubkey_list(self, in_bytes):
440 hnet_pubkey_list = []
441 pos = 0
442 if in_bytes[pos] != 0xa1:
443 print("missing Home Network Public Key List data object")
444 return {}
445 pos += 1
446 hnet_pubkey_list_len = in_bytes[pos]
447 pos += 1
448
449 while pos < hnet_pubkey_list_len:
450 if in_bytes[pos] != 0x80:
451 print("missing Home Network Public Key Identifier tag")
452 return {}
453 pos += 1
Harald Weltec91085e2022-02-10 18:05:45 +0100454 # TODO might be more than 1 byte?
455 hnet_pubkey_id_len = in_bytes[pos]
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200456 pos += 1
457 hnet_pubkey_id = in_bytes[pos:pos+hnet_pubkey_id_len][0]
458 pos += hnet_pubkey_id_len
459 if in_bytes[pos] != 0x81:
460 print("missing Home Network Public Key tag")
461 return {}
462 pos += 1
463 hnet_pubkey_len = in_bytes[pos]
464 pos += 1
465 hnet_pubkey = in_bytes[pos:pos+hnet_pubkey_len]
466 pos += hnet_pubkey_len
467
468 hnet_pubkey_list.append({
469 'hnet_pubkey_identifier': hnet_pubkey_id,
470 'hnet_pubkey': b2h(hnet_pubkey)
471 })
472
473 return hnet_pubkey_list
474
475 def _decode_bin(self, in_bin):
Vadim Yanitskiy5e41eeb2021-05-02 02:20:33 +0200476 return self._decode_hex(b2h(in_bin))
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200477
478 def _decode_hex(self, in_hex):
479 in_bytes = h2b(in_hex)
480 pos = 0
481
482 if in_bytes[pos] != 0xa0:
483 print("missing Protection Scheme Identifier List data object tag")
484 return {}
485 pos += 1
486
Harald Weltec91085e2022-02-10 18:05:45 +0100487 prot_scheme_id_list_len = in_bytes[pos] # TODO maybe more than 1 byte
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200488 pos += 1
489 # decode Protection Scheme Identifier List data object
Harald Weltec91085e2022-02-10 18:05:45 +0100490 prot_scheme_id_list = self._decode_prot_scheme_id_list(
491 in_bytes[pos:pos+prot_scheme_id_list_len])
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200492 pos += prot_scheme_id_list_len
493
494 # remaining data holds Home Network Public Key Data Object
495 hnet_pubkey_list = self._decode_hnet_pubkey_list(in_bytes[pos:])
496
497 return {
498 'prot_scheme_id_list': prot_scheme_id_list,
499 'hnet_pubkey_list': hnet_pubkey_list
500 }
501
502 def _encode_bin(self, in_json):
503 return h2b(self._encode_hex(in_json))
504
Harald Weltec91085e2022-02-10 18:05:45 +0100505
Harald Welteb2edd142021-01-08 23:29:35 +0100506class EF_LI(TransRecEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100507 def __init__(self, fid='6f05', sfid=None, name='EF.LI', size={2, None}, rec_len=2,
Harald Welteb2edd142021-01-08 23:29:35 +0100508 desc='Language Indication'):
509 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, rec_len=rec_len)
Harald Weltec91085e2022-02-10 18:05:45 +0100510
Harald Welteb2edd142021-01-08 23:29:35 +0100511 def _decode_record_bin(self, in_bin):
512 if in_bin == b'\xff\xff':
513 return None
514 else:
515 # officially this is 7-bit GSM alphabet with one padding bit in each byte
516 return in_bin.decode('ascii')
Harald Weltec91085e2022-02-10 18:05:45 +0100517
Harald Welteb2edd142021-01-08 23:29:35 +0100518 def _encode_record_bin(self, in_json):
519 if in_json == None:
520 return b'\xff\xff'
521 else:
522 # officially this is 7-bit GSM alphabet with one padding bit in each byte
523 return in_json.encode('ascii')
524
Harald Weltec91085e2022-02-10 18:05:45 +0100525
Harald Welteb2edd142021-01-08 23:29:35 +0100526class EF_Keys(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100527 def __init__(self, fid='6f08', sfid=0x08, name='EF.Keys', size={33, 33},
Harald Welteb2edd142021-01-08 23:29:35 +0100528 desc='Ciphering and Integrity Keys'):
529 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Weltec91085e2022-02-10 18:05:45 +0100530 self._construct = Struct(
531 'ksi'/Int8ub, 'ck'/HexAdapter(Bytes(16)), 'ik'/HexAdapter(Bytes(16)))
Harald Welteb2edd142021-01-08 23:29:35 +0100532
Harald Welte14105dc2021-05-31 08:48:51 +0200533# TS 31.102 Section 4.2.6
534class EF_HPPLMN(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100535 def __init__(self, fid='6f31', sfid=0x12, name='EF.HPPLMN', size={1, 1},
Harald Welte14105dc2021-05-31 08:48:51 +0200536 desc='Higher Priority PLMN search period'):
537 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
538 self._construct = Int8ub
539
540# TS 31.102 Section 4.2.8
Harald Weltee8947492022-02-10 10:33:20 +0100541class EF_UServiceTable(TransparentEF):
Harald Welte6169c722022-02-12 09:05:15 +0100542 def __init__(self, fid, sfid, name, desc, size, table, **kwargs):
543 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Weltee8947492022-02-10 10:33:20 +0100544 self.table = table
Harald Welteb2edd142021-01-08 23:29:35 +0100545 # add those commands to the general commands of a TransparentEF
546 self.shell_commands += [self.AddlShellCommands()]
Harald Weltec91085e2022-02-10 18:05:45 +0100547
Harald Weltee8947492022-02-10 10:33:20 +0100548 @staticmethod
Harald Weltec91085e2022-02-10 18:05:45 +0100549 def _bit_byte_offset_for_service(service: int) -> Tuple[int, int]:
Harald Weltee8947492022-02-10 10:33:20 +0100550 i = service - 1
551 byte_offset = i//8
552 bit_offset = (i % 8)
553 return (byte_offset, bit_offset)
Harald Weltec91085e2022-02-10 18:05:45 +0100554
Harald Welteb2edd142021-01-08 23:29:35 +0100555 def _decode_bin(self, in_bin):
Harald Weltee8947492022-02-10 10:33:20 +0100556 ret = {}
Harald Weltec91085e2022-02-10 18:05:45 +0100557 for i in range(0, len(in_bin)):
Harald Welteb2edd142021-01-08 23:29:35 +0100558 byte = in_bin[i]
Harald Weltec91085e2022-02-10 18:05:45 +0100559 for bitno in range(0, 7):
Harald Weltee8947492022-02-10 10:33:20 +0100560 service_nr = i * 8 + bitno + 1
561 ret[service_nr] = {
Harald Weltec91085e2022-02-10 18:05:45 +0100562 'activated': True if byte & (1 << bitno) else False
Harald Weltee8947492022-02-10 10:33:20 +0100563 }
564 if service_nr in self.table:
565 ret[service_nr]['description'] = self.table[service_nr]
Harald Welteb2edd142021-01-08 23:29:35 +0100566 return ret
Harald Weltec91085e2022-02-10 18:05:45 +0100567
Harald Welteb2edd142021-01-08 23:29:35 +0100568 def _encode_bin(self, in_json):
Harald Weltee8947492022-02-10 10:33:20 +0100569 # compute the required binary size
570 bin_len = 0
571 for srv in in_json.keys():
572 service_nr = int(srv)
Harald Weltec91085e2022-02-10 18:05:45 +0100573 (byte_offset, bit_offset) = EF_UServiceTable._bit_byte_offset_for_service(
574 service_nr)
Harald Weltee8947492022-02-10 10:33:20 +0100575 if byte_offset >= bin_len:
576 bin_len = byte_offset+1
577 # encode the actual data
578 out = bytearray(b'\x00' * bin_len)
579 for srv in in_json.keys():
580 service_nr = int(srv)
Harald Weltec91085e2022-02-10 18:05:45 +0100581 (byte_offset, bit_offset) = EF_UServiceTable._bit_byte_offset_for_service(
582 service_nr)
Harald Weltee8947492022-02-10 10:33:20 +0100583 if in_json[srv]['activated'] == True:
584 bit = 1
585 else:
586 bit = 0
587 out[byte_offset] |= (bit) << bit_offset
588 return out
Harald Weltec91085e2022-02-10 18:05:45 +0100589
Harald Welteb2edd142021-01-08 23:29:35 +0100590 @with_default_category('File-Specific Commands')
591 class AddlShellCommands(CommandSet):
592 def __init__(self):
593 super().__init__()
594
595 def do_ust_service_activate(self, arg):
596 """Activate a service within EF.UST"""
597 self._cmd.card.update_ust(int(arg), 1)
598
599 def do_ust_service_deactivate(self, arg):
600 """Deactivate a service within EF.UST"""
601 self._cmd.card.update_ust(int(arg), 0)
602
Harald Welte4c5e2312022-02-12 14:37:48 +0100603 def do_ust_service_check(self, arg):
604 """Check consistency between services of this file and files present/activated"""
605 # obtain list of currently active services
606 (service_data, sw) = self._cmd.rs.read_binary_dec()
607 for s in service_data.keys():
608 if service_data[s]['activated']:
609 active_services.append(s)
610 # iterate over all the service-constraints we know of
611 selected_file = self._cmd.rs.selected_file
612 files_by_service = selected_file.parent.files_by_service
613 try:
614 for s in sorted(files_by_service.keys()):
615 active_str = 'active' if s in active_services else 'inactive'
616 self._cmd.poutput("Checking service No %u (%s)" % (s, active_str))
617 for f in files_by_service[s]:
618 should_exist = f.should_exist_for_services(active_services)
619 try:
620 (data, sw) = self._cmd.card._scc.select_file(f.fid)
621 exists = True
622 fcp = f.decode_select_response(data)
623 # if we just selected a directory, go back
624 if fcp['file_descriptor']['file_type'] == 'df':
625 self._cmd.card._scc.select_parent_df()
626 except SwMatchError as e:
627 sw = e.sw_actual
628 exists = False
629 if exists != should_exist:
630 if exists:
631 self._cmd.poutput(" ERROR: File %s is selectable but should not!" % f)
632 else:
633 self._cmd.poutput(" ERROR: File %s is not selectable (SW=%s) but should!" % (f, sw))
634 finally:
635 # re-select the EF.UST
636 self._cmd.card._scc.select_file(selected_file.fid)
637
638
Harald Welte89e59542021-04-02 21:33:13 +0200639# TS 31.103 Section 4.2.7 - *not* the same as DF.GSM/EF.ECC!
640class EF_ECC(LinFixedEF):
Harald Welteff2d86d2022-01-21 15:19:47 +0100641 cc_construct = Rpad(BcdAdapter(Rpad(Bytes(3))), pattern='f')
642 category_construct = FlagsEnum(Byte, police=1, ambulance=2, fire_brigade=3, marine_guard=4,
643 mountain_rescue=5, manual_ecall=6, automatic_ecall=7)
644 alpha_construct = GsmStringAdapter(Rpad(GreedyBytes))
Harald Weltec91085e2022-02-10 18:05:45 +0100645
Harald Welte89e59542021-04-02 21:33:13 +0200646 def __init__(self, fid='6fb7', sfid=0x01, name='EF.ECC',
647 desc='Emergency Call Codes'):
Harald Weltec91085e2022-02-10 18:05:45 +0100648 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len={4, 20})
649
Harald Welteff2d86d2022-01-21 15:19:47 +0100650 def _decode_record_bin(self, in_bin):
651 # mandatory parts
652 code = in_bin[:3]
653 if code == b'\xff\xff\xff':
654 return None
655 svc_category = in_bin[-1:]
656 ret = {'call_code': parse_construct(EF_ECC.cc_construct, code),
Harald Weltec91085e2022-02-10 18:05:45 +0100657 'service_category': parse_construct(EF_ECC.category_construct, svc_category)}
Harald Welteff2d86d2022-01-21 15:19:47 +0100658 # optional alpha identifier
659 if len(in_bin) > 4:
660 alpha_id = in_bin[3:-1]
661 ret['alpha_id'] = parse_construct(EF_ECC.alpha_construct, alpha_id)
662 return ret
Harald Weltec91085e2022-02-10 18:05:45 +0100663
Harald Welteff2d86d2022-01-21 15:19:47 +0100664 def _encode_record_bin(self, in_json):
665 if in_json is None:
666 return b'\xff\xff\xff\xff'
667 code = EF_ECC.cc_construct.build(in_json['call_code'])
668 svc_category = EF_ECC.category_construct.build(in_json['category'])
669 alpha_id = EF_ECC.alpha_construct.build(in_json['alpha_id'])
670 # FIXME: alpha_id needs padding up to 'record_length - 4'
671 return code + alpha_id + svc_category
672
Harald Welte89e59542021-04-02 21:33:13 +0200673
Harald Welte790b2702021-04-11 00:01:35 +0200674# TS 31.102 Section 4.2.17
675class EF_LOCI(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100676 def __init__(self, fid='6f7e', sfid=0x0b, name='EF.LOCI', desc='Location information', size={11, 11}):
Harald Welte790b2702021-04-11 00:01:35 +0200677 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
678 self._construct = Struct('tmsi'/HexAdapter(Bytes(4)), 'lai'/HexAdapter(Bytes(5)), 'rfu'/Int8ub,
679 'lu_status'/Int8ub)
Harald Welte592b32e2021-06-05 11:26:36 +0200680# TS 31.102 Section 4.2.18
681class EF_AD(TransparentEF):
682 class OP_MODE(enum.IntEnum):
Harald Weltec91085e2022-02-10 18:05:45 +0100683 normal = 0x00
684 type_approval = 0x80
685 normal_and_specific_facilities = 0x01
686 type_approval_and_specific_facilities = 0x81
687 maintenance_off_line = 0x02
688 cell_test = 0x04
Harald Welte592b32e2021-06-05 11:26:36 +0200689
Harald Weltec91085e2022-02-10 18:05:45 +0100690 def __init__(self, fid='6fad', sfid=0x03, name='EF.AD', desc='Administrative Data', size={4, 6}):
Harald Welte592b32e2021-06-05 11:26:36 +0200691 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
692 self._construct = BitStruct(
693 # Byte 1
694 'ms_operation_mode'/Bytewise(Enum(Byte, EF_AD.OP_MODE)),
695 # Byte 2 + 3
696 'additional_info'/Bytewise(FlagsEnum(Int16ub, ciphering_indicator=1, csg_display_control=2,
697 prose_services=4, extended_drx=8)),
698 'rfu'/BitsRFU(4),
699 'mnc_len'/BitsInteger(4),
700 'extensions'/COptional(Bytewise(GreedyBytesRFU))
701 )
Harald Welte790b2702021-04-11 00:01:35 +0200702
703# TS 31.102 Section 4.2.23
704class EF_PSLOCI(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100705 def __init__(self, fid='6f73', sfid=0x0c, name='EF.PSLOCI', desc='PS Location information', size={14, 14}):
Harald Welte790b2702021-04-11 00:01:35 +0200706 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
707 self._construct = Struct('ptmsi'/HexAdapter(Bytes(4)), 'ptmsi_sig'/HexAdapter(Bytes(3)),
708 'rai'/HexAdapter(Bytes(6)), 'rau_status'/Int8ub)
709
710# TS 31.102 Section 4.2.33
711class EF_ICI(CyclicEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100712 def __init__(self, fid='6f80', sfid=0x14, name='EF.ICI', rec_len={28, 48},
Harald Welte6169c722022-02-12 09:05:15 +0100713 desc='Incoming Call Information', **kwargs):
714 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200715 self._construct = Struct('alpha_id'/Bytes(this._.total_len-28),
716 'len_of_bcd_contents'/Int8ub,
717 'ton_npi'/Int8ub,
718 'call_number'/BcdAdapter(Bytes(10)),
719 'cap_cfg2_record_id'/Int8ub,
720 'ext5_record_id'/Int8ub,
721 'date_and_time'/BcdAdapter(Bytes(7)),
722 'duration'/Int24ub,
723 'status'/Byte,
724 'link_to_phonebook'/Bytes(3))
725
726# TS 31.102 Section 4.2.34
727class EF_OCI(CyclicEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100728 def __init__(self, fid='6f81', sfid=0x15, name='EF.OCI', rec_len={27, 47},
Harald Welte6169c722022-02-12 09:05:15 +0100729 desc='Outgoing Call Information', **kwargs):
730 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200731 self._construct = Struct('alpha_id'/Bytes(this._.total_len-27),
732 'len_of_bcd_contents'/Int8ub,
733 'ton_npi'/Int8ub,
734 'call_number'/BcdAdapter(Bytes(10)),
735 'cap_cfg2_record_id'/Int8ub,
736 'ext5_record_id'/Int8ub,
737 'date_and_time'/BcdAdapter(Bytes(7)),
738 'duration'/Int24ub,
739 'link_to_phonebook'/Bytes(3))
740
741# TS 31.102 Section 4.2.35
742class EF_ICT(CyclicEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100743 def __init__(self, fid='6f82', sfid=None, name='EF.ICT', rec_len={3, 3},
Harald Welte6169c722022-02-12 09:05:15 +0100744 desc='Incoming Call Timer', **kwargs):
745 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200746 self._construct = Struct('accumulated_call_timer'/Int24ub)
747
748# TS 31.102 Section 4.2.38
749class EF_CCP2(LinFixedEF):
Harald Welte6169c722022-02-12 09:05:15 +0100750 def __init__(self, fid='6f4f', sfid=0x16, name='EF.CCP2', desc='Capability Configuration Parameters 2', **kwargs):
751 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len={15, None}, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200752
753# TS 31.102 Section 4.2.48
754class EF_ACL(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100755 def __init__(self, fid='6f57', sfid=None, name='EF.ACL', size={32, None},
Harald Welte6169c722022-02-12 09:05:15 +0100756 desc='Access Point Name Control List', **kwargs):
757 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200758 self._construct = Struct('num_of_apns'/Int8ub, 'tlvs'/GreedyBytes)
759
760# TS 31.102 Section 4.2.51
761class EF_START_HFN(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100762 def __init__(self, fid='6f5b', sfid=0x0f, name='EF.START-HFN', size={6, 6},
Harald Welte6169c722022-02-12 09:05:15 +0100763 desc='Initialisation values for Hyperframe number', **kwargs):
764 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200765 self._construct = Struct('start_cs'/Int24ub, 'start_ps'/Int24ub)
766
767# TS 31.102 Section 4.2.52
768class EF_THRESHOLD(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100769 def __init__(self, fid='6f5c', sfid=0x10, name='EF.THRESHOLD', size={3, 3},
Harald Welte6169c722022-02-12 09:05:15 +0100770 desc='Maximum value of START', **kwargs):
771 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200772 self._construct = Struct('max_start'/Int24ub)
773
774# TS 31.102 Section 4.2.77
775class EF_VGCSCA(TransRecEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100776 def __init__(self, fid='6fd4', sfid=None, name='EF.VGCSCA', size={2, 100}, rec_len=2,
Harald Welte6169c722022-02-12 09:05:15 +0100777 desc='Voice Group Call Service Ciphering Algorithm', **kwargs):
778 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, rec_len=rec_len, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200779 self._construct = Struct('alg_v_ki_1'/Int8ub, 'alg_v_ki_2'/Int8ub)
780
781# TS 31.102 Section 4.2.79
782class EF_GBABP(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100783 def __init__(self, fid='6fd6', sfid=None, name='EF.GBABP', size={3, 50},
Harald Welte6169c722022-02-12 09:05:15 +0100784 desc='GBA Bootstrapping parameters', **kwargs):
785 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200786 self._construct = Struct('rand'/LV, 'b_tid'/LV, 'key_lifetime'/LV)
787
788# TS 31.102 Section 4.2.80
789class EF_MSK(LinFixedEF):
Harald Welte6169c722022-02-12 09:05:15 +0100790 def __init__(self, fid='6fd7', sfid=None, name='EF.MSK', desc='MBMS Service Key List', **kwargs):
791 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len={20, None}, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200792 msk_ts_constr = Struct('msk_id'/Int32ub, 'timestamp_counter'/Int32ub)
793 self._construct = Struct('key_domain_id'/Bytes(3),
794 'num_msk_id'/Int8ub,
795 'msk_ids'/msk_ts_constr[this.num_msk_id])
Harald Welte14105dc2021-05-31 08:48:51 +0200796# TS 31.102 Section 4.2.81
797class EF_MUK(LinFixedEF):
798 class MUK_Idr(BER_TLV_IE, tag=0x80):
799 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100800
Harald Welte14105dc2021-05-31 08:48:51 +0200801 class MUK_Idi(BER_TLV_IE, tag=0x82):
802 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100803
Harald Welte14105dc2021-05-31 08:48:51 +0200804 class MUK_ID(BER_TLV_IE, tag=0xA0, nested=[MUK_Idr, MUK_Idi]):
805 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100806
Harald Welte14105dc2021-05-31 08:48:51 +0200807 class TimeStampCounter(BER_TLV_IE, tag=0x81):
808 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100809
Harald Welte14105dc2021-05-31 08:48:51 +0200810 class EF_MUK_Collection(TLV_IE_Collection, nested=[MUK_ID, TimeStampCounter]):
811 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100812
Harald Welte6169c722022-02-12 09:05:15 +0100813 def __init__(self, fid='6fd8', sfid=None, name='EF.MUK', desc='MBMS User Key', **kwargs):
814 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len={None, None}, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200815 self._tlv = EF_MUK.EF_MUK_Collection
816
817# TS 31.102 Section 4.2.83
818class EF_GBANL(LinFixedEF):
819 class NAF_ID(BER_TLV_IE, tag=0x80):
820 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100821
Harald Welte14105dc2021-05-31 08:48:51 +0200822 class B_TID(BER_TLV_IE, tag=0x81):
823 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100824
Harald Welte14105dc2021-05-31 08:48:51 +0200825 class EF_GBANL_Collection(BER_TLV_IE, nested=[NAF_ID, B_TID]):
826 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100827
Harald Welte6169c722022-02-12 09:05:15 +0100828 def __init__(self, fid='6fda', sfid=None, name='EF.GBANL', desc='GBA NAF List', **kwargs):
829 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len={None, None}, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200830 self._tlv = EF_GBANL.EF_GBANL_Collection
Harald Welte790b2702021-04-11 00:01:35 +0200831
832# TS 31.102 Section 4.2.85
833class EF_EHPLMNPI(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100834 def __init__(self, fid='6fdb', sfid=None, name='EF.EHPLMNPI', size={1, 1},
Harald Welte6169c722022-02-12 09:05:15 +0100835 desc='Equivalent HPLMN Presentation Indication', **kwargs):
836 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Weltec91085e2022-02-10 18:05:45 +0100837 self._construct = Struct('presentation_ind' /
Harald Welte790b2702021-04-11 00:01:35 +0200838 Enum(Byte, no_preference=0, display_highest_prio_only=1, display_all=2))
Harald Welte14105dc2021-05-31 08:48:51 +0200839
840# TS 31.102 Section 4.2.87
841class EF_NAFKCA(LinFixedEF):
842 class NAF_KeyCentreAddress(BER_TLV_IE, tag=0x80):
843 _construct = HexAdapter(GreedyBytes)
844 def __init__(self, fid='6fdd', sfid=None, name='EF.NAFKCA', rec_len={None, None},
Harald Welte6169c722022-02-12 09:05:15 +0100845 desc='NAF Key Centre Address', **kwargs):
846 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200847 self._tlv = EF_NAFKCA.NAF_KeyCentreAddress
848
849# TS 31.102 Section 4.2.90
850class EF_NCP_IP(LinFixedEF):
851 class DataDestAddrRange(TLV_IE, tag=0x83):
852 _construct = Struct('type_of_address'/Enum(Byte, IPv4=0x21, IPv6=0x56),
853 'prefix_length'/Int8ub,
854 'prefix'/HexAdapter(GreedyBytes))
Harald Weltec91085e2022-02-10 18:05:45 +0100855
Harald Welte14105dc2021-05-31 08:48:51 +0200856 class AccessPointName(TLV_IE, tag=0x80):
857 # coded as per TS 23.003
858 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100859
Harald Welte14105dc2021-05-31 08:48:51 +0200860 class Login(TLV_IE, tag=0x81):
861 # as per SMS DCS TS 23.038
862 _construct = GsmStringAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100863
Harald Welte14105dc2021-05-31 08:48:51 +0200864 class Password(TLV_IE, tag=0x82):
865 # as per SMS DCS TS 23.038
866 _construct = GsmStringAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100867
Harald Welte14105dc2021-05-31 08:48:51 +0200868 class BearerDescription(TLV_IE, tag=0x84):
869 # Bearer descriptionTLV DO as per TS 31.111
870 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100871
Harald Welte14105dc2021-05-31 08:48:51 +0200872 class EF_NCP_IP_Collection(TLV_IE_Collection,
873 nested=[AccessPointName, Login, Password, BearerDescription]):
874 pass
875 def __init__(self, fid='6fe2', sfid=None, name='EF.NCP-IP', rec_len={None, None},
Harald Welte6169c722022-02-12 09:05:15 +0100876 desc='Network Connectivity Parameters for USIM IP connections', **kwargs):
877 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200878 self._tlv = EF_NCP_IP.EF_NCP_IP_Collection
879
Harald Welte790b2702021-04-11 00:01:35 +0200880# TS 31.102 Section 4.2.91
881class EF_EPSLOCI(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100882 def __init__(self, fid='6fe3', sfid=0x1e, name='EF.EPSLOCI', size={18, 18},
Harald Welte6169c722022-02-12 09:05:15 +0100883 desc='EPS Location Information', **kwargs):
884 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Weltec91085e2022-02-10 18:05:45 +0100885 upd_status_constr = Enum(
886 Byte, updated=0, not_updated=1, roaming_not_allowed=2)
Harald Welte790b2702021-04-11 00:01:35 +0200887 self._construct = Struct('guti'/Bytes(12), 'last_visited_registered_tai'/Bytes(5),
888 'eps_update_status'/upd_status_constr)
889
Harald Welte14105dc2021-05-31 08:48:51 +0200890# TS 31.102 Section 4.2.92
891class EF_EPSNSC(LinFixedEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100892 class KSI_ASME(BER_TLV_IE, tag=0x80):
Harald Welte14105dc2021-05-31 08:48:51 +0200893 _construct = Int8ub
Harald Weltec91085e2022-02-10 18:05:45 +0100894
895 class K_ASME(BER_TLV_IE, tag=0x81):
Harald Welte14105dc2021-05-31 08:48:51 +0200896 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100897
Harald Welte14105dc2021-05-31 08:48:51 +0200898 class UplinkNASCount(BER_TLV_IE, tag=0x82):
899 _construct = Int32ub
Harald Weltec91085e2022-02-10 18:05:45 +0100900
Harald Welte14105dc2021-05-31 08:48:51 +0200901 class DownlinkNASCount(BER_TLV_IE, tag=0x83):
902 _construct = Int32ub
Harald Weltec91085e2022-02-10 18:05:45 +0100903
Harald Welte14105dc2021-05-31 08:48:51 +0200904 class IDofNASAlgorithms(BER_TLV_IE, tag=0x84):
905 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100906
Harald Welte14105dc2021-05-31 08:48:51 +0200907 class EPS_NAS_Security_Context(BER_TLV_IE, tag=0xa0,
Harald Weltec91085e2022-02-10 18:05:45 +0100908 nested=[KSI_ASME, K_ASME, UplinkNASCount, DownlinkNASCount,
909 IDofNASAlgorithms]):
Harald Welte14105dc2021-05-31 08:48:51 +0200910 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100911 def __init__(self, fid='6fe4', sfid=0x18, name='EF.EPSNSC', rec_len={54, 128},
Harald Welte6169c722022-02-12 09:05:15 +0100912 desc='EPS NAS Security Context', **kwargs):
913 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200914 self._tlv = EF_EPSNSC.EPS_NAS_Security_Context
915
Harald Welte790b2702021-04-11 00:01:35 +0200916# TS 31.102 Section 4.2.96
917class EF_PWS(TransparentEF):
Harald Welte6169c722022-02-12 09:05:15 +0100918 def __init__(self, fid='6fec', sfid=None, name='EF.PWS', desc='Public Warning System', size={1, 1}, **kwargs):
919 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Weltec91085e2022-02-10 18:05:45 +0100920 pws_config = FlagsEnum(
921 Byte, ignore_pws_in_hplmn_and_equivalent=1, ignore_pws_in_vplmn=2)
Harald Welte790b2702021-04-11 00:01:35 +0200922 self._construct = Struct('pws_configuration'/pws_config)
923
924# TS 31.102 Section 4.2.101
925class EF_IPS(CyclicEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100926 def __init__(self, fid='6ff1', sfid=None, name='EF.IPS', rec_len={4, 4},
Harald Welte6169c722022-02-12 09:05:15 +0100927 desc='IMEI(SV) Pairing Status', **kwargs):
928 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200929 self._construct = Struct('status'/PaddedString(2, 'ascii'),
930 'link_to_ef_ipd'/Int8ub, 'rfu'/Byte)
931
Harald Welte14105dc2021-05-31 08:48:51 +0200932# TS 31.102 Section 4.2.103
933class EF_ePDGId(TransparentEF):
934 class ePDGId(BER_TLV_IE, tag=0x80, nested=[]):
935 _construct = Struct('type_of_ePDG_address'/Enum(Byte, FQDN=0, IPv4=1, IPv6=2),
936 'ePDG_address'/Switch(this.type_of_address,
Harald Weltec91085e2022-02-10 18:05:45 +0100937 {'FQDN': GreedyString("utf8"),
938 'IPv4': HexAdapter(GreedyBytes),
939 'IPv6': HexAdapter(GreedyBytes)}))
940
Harald Welte6169c722022-02-12 09:05:15 +0100941 def __init__(self, fid='6ff3', sfid=None, name='EF.eDPDGId', desc='Home ePDG Identifier', **kwargs):
942 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200943 self._tlv = EF_ePDGId.ePDGId
944
Harald Welte71290072021-04-21 10:58:24 +0200945# TS 31.102 Section 4.2.106
946class EF_FromPreferred(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100947 def __init__(self, fid='6ff7', sfid=None, name='EF.FromPreferred', size={1, 1},
Harald Welte6169c722022-02-12 09:05:15 +0100948 desc='From Preferred', **kwargs):
949 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte71290072021-04-21 10:58:24 +0200950 self._construct = BitStruct('rfu'/BitsRFU(7), 'from_preferred'/Bit)
951
Harald Welte790b2702021-04-11 00:01:35 +0200952######################################################################
953# DF.5GS
954######################################################################
955
956# TS 31.102 Section 4.4.11.2
957class EF_5GS3GPPLOCI(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100958 def __init__(self, fid='4f01', sfid=0x01, name='EF.5GS3GPPLOCI', size={20, 20},
Harald Welte790b2702021-04-11 00:01:35 +0200959 desc='5S 3GP location information'):
960 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Weltec91085e2022-02-10 18:05:45 +0100961 upd_status_constr = Enum(
962 Byte, updated=0, not_updated=1, roaming_not_allowed=2)
Harald Welte790b2702021-04-11 00:01:35 +0200963 self._construct = Struct('5g_guti'/Bytes(13), 'last_visited_registered_tai_in_5gs'/Bytes(6),
964 '5gs_update_status'/upd_status_constr)
965
966# TS 31.102 Section 4.4.11.7
967class EF_UAC_AIC(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100968 def __init__(self, fid='4f06', sfid=0x06, name='EF.UAC_AIC', size={4, 4},
Harald Welte790b2702021-04-11 00:01:35 +0200969 desc='UAC Access Identities Configuration'):
970 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
971 cfg_constr = FlagsEnum(Byte, multimedia_priority_service=1,
Harald Weltec91085e2022-02-10 18:05:45 +0100972 mission_critical_service=2)
Harald Welte790b2702021-04-11 00:01:35 +0200973 self._construct = Struct('uac_access_id_config'/cfg_constr)
974
Harald Welte14105dc2021-05-31 08:48:51 +0200975# TS 31.102 Section 4.4.11.9
Harald Welte790b2702021-04-11 00:01:35 +0200976class EF_OPL5G(LinFixedEF):
977 def __init__(self, fid='6f08', sfid=0x08, name='EF.OPL5G', desc='5GS Operator PLMN List'):
Harald Weltec91085e2022-02-10 18:05:45 +0100978 super().__init__(fid=fid, sfid=sfid,
979 name=name, desc=desc, rec_len={10, None})
Harald Welte790b2702021-04-11 00:01:35 +0200980 self._construct = Struct('tai'/Bytes(9), 'pnn_record_id'/Int8ub)
981
Harald Welte14105dc2021-05-31 08:48:51 +0200982# TS 31.102 Section 4.4.11.10
983class EF_SUPI_NAI(TransparentEF):
984 class NetworkSpecificIdentifier(TLV_IE, tag=0x80):
985 # RFC 7542 encoded as UTF-8 string
986 _construct = GreedyString("utf8")
Harald Weltec91085e2022-02-10 18:05:45 +0100987
Harald Welte14105dc2021-05-31 08:48:51 +0200988 class GlobalLineIdentifier(TLV_IE, tag=0x81):
989 # TS 23.003 clause 28.16.2
990 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100991
Harald Welte14105dc2021-05-31 08:48:51 +0200992 class GlobalCableIdentifier(TLV_IE, tag=0x82):
993 # TS 23.003 clause 28.15.2
994 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100995
Harald Welte14105dc2021-05-31 08:48:51 +0200996 class NAI_TLV_Collection(TLV_IE_Collection,
Harald Weltec91085e2022-02-10 18:05:45 +0100997 nested=[NetworkSpecificIdentifier, GlobalLineIdentifier, GlobalCableIdentifier]):
Harald Welte14105dc2021-05-31 08:48:51 +0200998 pass
999 def __init__(self, fid='4f09', sfid=0x09, name='EF.SUPI_NAI',
Harald Weltec91085e2022-02-10 18:05:45 +01001000 desc='SUPI as Network Access Identifier'):
Harald Welte14105dc2021-05-31 08:48:51 +02001001 super().__init__(fid, sfid=sfid, name=name, desc=desc)
1002 self._tlv = EF_SUPI_NAI.NAI_TLV_Collection
1003
Harald Weltec91085e2022-02-10 18:05:45 +01001004
Harald Welte14105dc2021-05-31 08:48:51 +02001005class EF_TN3GPPSNN(TransparentEF):
1006 class ServingNetworkName(BER_TLV_IE, tag=0x80):
1007 _construct = GreedyString("utf8")
1008 def __init__(self, fid='4f0c', sfid=0x0c, name='EF.TN3GPPSNN',
Harald Weltec91085e2022-02-10 18:05:45 +01001009 desc='Trusted non-3GPP Serving network names list'):
Harald Welte14105dc2021-05-31 08:48:51 +02001010 super().__init__(fid, sfid=sfid, name=name, desc=desc)
1011 self._tlv = EF_TN3GPPSNN.ServingNetworkName
1012
Harald Welte3990ebb2021-04-20 23:55:14 +02001013# TS 31.102 Section 4.4.5
1014class DF_WLAN(CardDF):
Harald Welte6169c722022-02-12 09:05:15 +01001015 def __init__(self, fid='5f40', name='DF.WLAN', desc='Files for WLAN purpose', **kwargs):
1016 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
Harald Welte3990ebb2021-04-20 23:55:14 +02001017 files = [
1018 TransparentEF('4f41', 0x01, 'EF.Pseudo', 'Pseudonym'),
Harald Weltec91085e2022-02-10 18:05:45 +01001019 TransparentEF('4f42', 0x02, 'EF.UPLMNWLAN',
1020 'User controlled PLMN selector for I-WLAN Access'),
1021 TransparentEF('4f43', 0x03, 'EF.OPLMNWLAN',
1022 'Operator controlled PLMN selector for I-WLAN Access'),
1023 LinFixedEF('4f44', 0x04, 'EF.UWSIDL',
1024 'User controlled WLAN Specific Identifier List'),
1025 LinFixedEF('4f45', 0x05, 'EF.OWSIDL',
1026 'Operator controlled WLAN Specific Identifier List'),
1027 TransparentEF('4f46', 0x06, 'EF.WRI',
1028 'WLAN Reauthentication Identity'),
1029 LinFixedEF('4f47', 0x07, 'EF.HWSIDL',
1030 'Home I-WLAN Specific Identifier List'),
1031 TransparentEF('4f48', 0x08, 'EF.WEHPLMNPI',
1032 'I-WLAN Equivalent HPLMN Presentation Indication'),
1033 TransparentEF('4f49', 0x09, 'EF.WHPI',
1034 'I-WLAN HPLMN Priority Indication'),
1035 TransparentEF('4f4a', 0x0a, 'EF.WLRPLMN',
1036 'I-WLAN Last Registered PLMN'),
1037 TransparentEF('4f4b', 0x0b, 'EF.HPLMNDAI',
1038 'HPLMN Direct Access Indicator'),
1039 ]
Harald Welte3990ebb2021-04-20 23:55:14 +02001040 self.add_files(files)
1041
1042# TS 31.102 Section 4.4.6
1043class DF_HNB(CardDF):
Harald Welte6169c722022-02-12 09:05:15 +01001044 def __init__(self, fid='5f50', name='DF.HNB', desc='Files for HomeNodeB purpose', **kwargs):
1045 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
Harald Welte3990ebb2021-04-20 23:55:14 +02001046 files = [
1047 LinFixedEF('4f01', 0x01, 'EF.ACSGL', 'Allowed CSG Lists'),
1048 LinFixedEF('4f02', 0x02, 'EF.CSGTL', 'CSG Types'),
1049 LinFixedEF('4f03', 0x03, 'EF.HNBN', 'Home NodeB Name'),
1050 LinFixedEF('4f04', 0x04, 'EF.OCSGL', 'Operator CSG Lists'),
1051 LinFixedEF('4f05', 0x05, 'EF.OCSGT', 'Operator CSG Type'),
1052 LinFixedEF('4f06', 0x06, 'EF.OHNBN', 'Operator Home NodeB Name'),
Harald Weltec91085e2022-02-10 18:05:45 +01001053 ]
Harald Welte3990ebb2021-04-20 23:55:14 +02001054 self.add_files(files)
1055
1056# TS 31.102 Section 4.4.8
1057class DF_ProSe(CardDF):
Harald Welte6169c722022-02-12 09:05:15 +01001058 def __init__(self, fid='5f90', name='DF.ProSe', desc='Files for ProSe purpose', **kwargs):
1059 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
Harald Welte3990ebb2021-04-20 23:55:14 +02001060 files = [
Harald Weltec91085e2022-02-10 18:05:45 +01001061 LinFixedEF('4f01', 0x01, 'EF.PROSE_MON',
1062 'ProSe Monitoring Parameters'),
1063 LinFixedEF('4f02', 0x02, 'EF.PROSE_ANN',
1064 'ProSe Announcing Parameters'),
Harald Welte3990ebb2021-04-20 23:55:14 +02001065 LinFixedEF('4f03', 0x03, 'EF.PROSEFUNC', 'HPLMN ProSe Function'),
Harald Weltec91085e2022-02-10 18:05:45 +01001066 TransparentEF('4f04', 0x04, 'EF.PROSE_RADIO_COM',
1067 'ProSe Direct Communication Radio Parameters'),
1068 TransparentEF('4f05', 0x05, 'EF.PROSE_RADIO_MON',
1069 'ProSe Direct Discovery Monitoring Radio Parameters'),
1070 TransparentEF('4f06', 0x06, 'EF.PROSE_RADIO_ANN',
1071 'ProSe Direct Discovery Announcing Radio Parameters'),
1072 LinFixedEF('4f07', 0x07, 'EF.PROSE_POLICY',
1073 'ProSe Policy Parameters'),
Harald Welte3990ebb2021-04-20 23:55:14 +02001074 LinFixedEF('4f08', 0x08, 'EF.PROSE_PLMN', 'ProSe PLMN Parameters'),
1075 TransparentEF('4f09', 0x09, 'EF.PROSE_GC', 'ProSe Group Counter'),
1076 TransparentEF('4f10', 0x10, 'EF.PST', 'ProSe Service Table'),
Harald Weltec91085e2022-02-10 18:05:45 +01001077 TransparentEF('4f11', 0x11, 'EF.UIRC',
1078 'ProSe UsageInformationReportingConfiguration'),
1079 LinFixedEF('4f12', 0x12, 'EF.PROSE_GM_DISCOVERY',
1080 'ProSe Group Member Discovery Parameters'),
1081 LinFixedEF('4f13', 0x13, 'EF.PROSE_RELAY',
1082 'ProSe Relay Parameters'),
1083 TransparentEF('4f14', 0x14, 'EF.PROSE_RELAY_DISCOVERY',
1084 'ProSe Relay Discovery Parameters'),
1085 ]
Harald Welte3990ebb2021-04-20 23:55:14 +02001086 self.add_files(files)
1087
Harald Weltec91085e2022-02-10 18:05:45 +01001088
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001089class DF_USIM_5GS(CardDF):
Harald Welte6169c722022-02-12 09:05:15 +01001090 def __init__(self, fid='5FC0', name='DF.5GS', desc='5GS related files', **kwargs):
1091 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001092 files = [
Harald Weltec91085e2022-02-10 18:05:45 +01001093 # I'm looking at 31.102 R16.6
1094 EF_5GS3GPPLOCI(),
1095 EF_5GS3GPPLOCI('4f02', 0x02, 'EF.5GSN3GPPLOCI',
1096 '5GS non-3GPP location information'),
1097 EF_5GS3GPPNSC(),
1098 EF_5GS3GPPNSC('4f04', 0x04, 'EF.5GSN3GPPNSC',
1099 '5GS non-3GPP Access NAS Security Context'),
1100 EF_5GAUTHKEYS(),
1101 EF_UAC_AIC(),
1102 EF_SUCI_Calc_Info(),
1103 EF_OPL5G(),
1104 EF_SUPI_NAI(),
1105 TransparentEF('4F0A', 0x0a, 'EF.Routing_Indicator',
1106 'Routing Indicator', size={4, 4}),
1107 TransparentEF('4F0B', 0x0b, 'EF.URSP',
1108 'UE Route Selector Policies per PLMN'),
1109 EF_TN3GPPSNN(),
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001110 ]
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001111 self.add_files(files)
1112
Harald Weltec91085e2022-02-10 18:05:45 +01001113
Harald Welteb2edd142021-01-08 23:29:35 +01001114class ADF_USIM(CardADF):
1115 def __init__(self, aid='a0000000871002', name='ADF.USIM', fid=None, sfid=None,
1116 desc='USIM Application'):
1117 super().__init__(aid=aid, fid=fid, sfid=sfid, name=name, desc=desc)
Harald Welte15fae982021-04-10 10:22:27 +02001118 # add those commands to the general commands of a TransparentEF
1119 self.shell_commands += [self.AddlShellCommands()]
Harald Welteb2edd142021-01-08 23:29:35 +01001120
1121 files = [
Harald Weltec91085e2022-02-10 18:05:45 +01001122 EF_LI(sfid=0x02),
1123 EF_IMSI(sfid=0x07),
1124 EF_Keys(),
1125 EF_Keys('6f09', 0x09, 'EF.KeysPS',
1126 desc='Ciphering and Integrity Keys for PS domain'),
1127 EF_xPLMNwAcT('6f60', 0x0a, 'EF.PLMNwAcT',
Harald Welte6169c722022-02-12 09:05:15 +01001128 'User controlled PLMN Selector with Access Technology', service=20),
Harald Weltec91085e2022-02-10 18:05:45 +01001129 EF_HPPLMN(),
Harald Welte6169c722022-02-12 09:05:15 +01001130 EF_ACMmax(service=13),
Harald Weltec91085e2022-02-10 18:05:45 +01001131 EF_UServiceTable('6f38', 0x04, 'EF.UST', 'USIM Service Table', size={
1132 1, 17}, table=EF_UST_map),
1133 CyclicEF('6f39', None, 'EF.ACM',
Harald Welte6169c722022-02-12 09:05:15 +01001134 'Accumulated call meter', rec_len={3, 3}, service=13),
1135 TransparentEF('6f3e', None, 'EF.GID1', 'Group Identifier Level 1', service=17),
1136 TransparentEF('6f3f', None, 'EF.GID2', 'Group Identifier Level 2', service=18),
1137 EF_SPN(service=19),
Harald Weltec91085e2022-02-10 18:05:45 +01001138 TransparentEF('6f41', None, 'EF.PUCT',
Harald Welte6169c722022-02-12 09:05:15 +01001139 'Price per unit and currency table', size={5, 5}, service=13),
1140 EF_CBMI(service=15),
Harald Weltec91085e2022-02-10 18:05:45 +01001141 EF_ACC(sfid=0x06),
1142 EF_PLMNsel('6f7b', 0x0d, 'EF.FPLMN',
1143 'Forbidden PLMNs', size={12, None}),
1144 EF_LOCI(),
1145 EF_AD(),
Harald Welte6169c722022-02-12 09:05:15 +01001146 EF_CBMID(sfid=0x0e, service=29),
Harald Weltec91085e2022-02-10 18:05:45 +01001147 EF_ECC(),
Harald Welte6169c722022-02-12 09:05:15 +01001148 EF_CBMIR(service=16),
Harald Weltec91085e2022-02-10 18:05:45 +01001149 EF_PSLOCI(),
Harald Welte6169c722022-02-12 09:05:15 +01001150 EF_ADN('6f3b', None, 'EF.FDN', 'Fixed Dialling Numbers', service=[2, 89]),
1151 EF_SMS('6f3c', None, service=10),
1152 EF_MSISDN(service=21),
1153 EF_SMSP(service=12),
1154 EF_SMSS(service=10),
1155 EF_ADN('6f49', None, 'EF.SDN', 'Service Dialling Numbers', service=[4, 89]),
1156 EF_EXT('6f4b', None, 'EF.EXT2', 'Extension2 (FDN)', service=3),
1157 EF_EXT('6f4c', None, 'EF.EXT3', 'Extension2 (SDN)', service=5),
1158 EF_SMSR(service=11),
1159 EF_ICI(service=9),
1160 EF_OCI(service=8),
1161 EF_ICT(service=9),
1162 EF_ICT('6f83', None, 'EF.OCT', 'Outgoing Call Timer', service=8),
1163 EF_EXT('6f4e', None, 'EF.EXT5', 'Extension5 (ICI/OCI/MSISDN)', service=44),
1164 EF_CCP2(service=14),
1165 EF_eMLPP(service=24),
1166 EF_AAeM(service=25),
Harald Weltec91085e2022-02-10 18:05:45 +01001167 # EF_Hiddenkey
Harald Welte6169c722022-02-12 09:05:15 +01001168 EF_ADN('6f4d', None, 'EF.BDN', 'Barred Dialling Numbers', service=6),
1169 EF_EXT('6f55', None, 'EF.EXT4', 'Extension4 (BDN/SSC)', service=7),
1170 EF_CMI(service=6),
Harald Weltec91085e2022-02-10 18:05:45 +01001171 EF_UServiceTable('6f56', 0x05, 'EF.EST', 'Enabled Services Table', size={
Harald Welte6169c722022-02-12 09:05:15 +01001172 1, None}, table=EF_EST_map, service=[2, 6, 34, 35]),
1173 EF_ACL(service=35),
1174 EF_DCK(service=36),
1175 EF_CNL(service=37),
Harald Weltec91085e2022-02-10 18:05:45 +01001176 EF_START_HFN(),
1177 EF_THRESHOLD(),
Harald Welte6169c722022-02-12 09:05:15 +01001178 EF_xPLMNwAcT('6f61', 0x11, 'EF.OPLMNwAcT', 'User controlled PLMN Selector with Access Technology', service=42),
1179 EF_xPLMNwAcT('6f62', 0x13, 'EF.HPLMNwAcT', 'HPLMN Selector with Access Technology', service=43),
Harald Weltec91085e2022-02-10 18:05:45 +01001180 EF_ARR('6f06', 0x17),
1181 TransparentEF('6fc4', None, 'EF.NETPAR', 'Network Parameters'),
Harald Welte6169c722022-02-12 09:05:15 +01001182 EF_PNN('6fc5', 0x19, service=45),
1183 EF_OPL(service=46),
1184 EF_ADN('6fc7', None, 'EF.MBDN', 'Mailbox Dialling Numbers', service=47),
1185 EF_EXT('6fc8', None, 'EF.EXT6', 'Extension6 (MBDN)'),
1186 EF_MBI(service=47),
1187 EF_MWIS(service=48),
1188 EF_ADN('6fcb', None, 'EF.CFIS', 'Call Forwarding Indication Status', service=49),
Harald Weltec91085e2022-02-10 18:05:45 +01001189 EF_EXT('6fcc', None, 'EF.EXT7', 'Extension7 (CFIS)'),
Harald Welte6169c722022-02-12 09:05:15 +01001190 TransparentEF('6fcd', None, 'EF.SPDI', 'Service Provider Display Information', service=51),
1191 EF_MMSN(service=52),
1192 EF_EXT('6fcf', None, 'EF.EXT8', 'Extension8 (MMSN)', service=53),
1193 EF_MMSICP(service=52),
1194 EF_MMSUP(service=52),
1195 EF_MMSUCP(service=(52, 55)),
1196 EF_NIA(service=56),
1197 EF_VGCS(service=57),
1198 EF_VGCSS(service=57),
1199 EF_VGCS('6fb3', None, 'EF.VBS', 'Voice Broadcast Service', service=58),
1200 EF_VGCSS('6fb4', None, 'EF.VBSS', 'Voice Broadcast Service Status', service=58),
1201 EF_VGCSCA(service=64),
1202 EF_VGCSCA('6fd5', None, 'EF.VBCSCA', 'Voice Broadcast Service Ciphering Algorithm', service=65),
1203 EF_GBABP(service=68),
1204 EF_MSK(service=69),
1205 EF_MUK(service=69),
1206 EF_GBANL(service=68),
1207 EF_PLMNsel('6fd9', 0x1d, 'EF.EHPLMN', 'Equivalent HPLMN', size={12, None}, service=71),
1208 EF_EHPLMNPI(service=(71, 73)),
1209 # EF_LRPLMNSI ('6fdc', service=74)
1210 EF_NAFKCA(service=(68, 76)),
1211 TransparentEF('6fde', None, 'EF.SPNI', 'Service Provider Name Icon', service=78),
1212 LinFixedEF('6fdf', None, 'EF.PNNI', 'PLMN Network Name Icon', service=79),
1213 EF_NCP_IP(service=80),
1214 EF_EPSLOCI('6fe3', 0x1e, 'EF.EPSLOCI', 'EPS location information', service=85),
1215 EF_EPSNSC(service=85),
1216 TransparentEF('6fe6', None, 'EF.UFC', 'USAT Facility Control', size={1, 16}),
1217 TransparentEF('6fe8', None, 'EF.NASCONFIG', 'Non Access Stratum Configuration', service=96),
1218 # UICC IARI (only in cards that have no ISIM) service=95
1219 EF_PWS(service=97),
1220 LinFixedEF('6fed', None, 'EF.FDNURI', 'Fixed Dialling Numbers URI', service=(2, 99)),
1221 LinFixedEF('6fee', None, 'EF.BDNURI', 'Barred Dialling Numbers URI', service=(6, 99)),
1222 LinFixedEF('6fef', None, 'EF.SDNURI', 'Service Dialling Numbers URI', service=(4, 99)),
1223 # EF_IWL (IMEI(SV) White List)
Harald Weltec91085e2022-02-10 18:05:45 +01001224 EF_IPS(),
Harald Welte6169c722022-02-12 09:05:15 +01001225 EF_ePDGId(service=(106, 107)),
Harald Weltec91085e2022-02-10 18:05:45 +01001226 # FIXME: from EF_ePDGSelection onwards
Harald Welte6169c722022-02-12 09:05:15 +01001227 EF_FromPreferred(service=114),
1228 # FIXME: DF_SoLSA service=23
Harald Weltec91085e2022-02-10 18:05:45 +01001229 # FIXME: DF_PHONEBOOK
Harald Welte6169c722022-02-12 09:05:15 +01001230 # FIXME: DF_GSM_ACCESS service=27
1231 DF_WLAN(service=[59, 60, 61, 62, 63, 66, 81, 82, 83, 84, 88]),
1232 DF_HNB(service=[86, 90]),
1233 DF_ProSe(service=101),
1234 # FIXME: DF_ACDC service=108
1235 # FIXME: DF_TV service=116
1236 DF_USIM_5GS(service=[122, 123, 124, 125, 126, 127, 129, 130]),
Harald Weltec91085e2022-02-10 18:05:45 +01001237 ]
Harald Welteb2edd142021-01-08 23:29:35 +01001238 self.add_files(files)
1239
1240 def decode_select_response(self, data_hex):
Philipp Maier5998a3a2021-11-16 15:16:39 +01001241 return pySim.ts_102_221.CardProfileUICC.decode_select_response(data_hex)
Harald Welteb2edd142021-01-08 23:29:35 +01001242
Harald Welte15fae982021-04-10 10:22:27 +02001243 @with_default_category('Application-Specific Commands')
1244 class AddlShellCommands(CommandSet):
1245 def __init__(self):
1246 super().__init__()
1247
1248 authenticate_parser = argparse.ArgumentParser()
1249 authenticate_parser.add_argument('rand', help='Random challenge')
1250 authenticate_parser.add_argument('autn', help='Authentication Nonce')
1251 #authenticate_parser.add_argument('--context', help='Authentication context', default='3G')
Harald Weltec91085e2022-02-10 18:05:45 +01001252
Harald Welte15fae982021-04-10 10:22:27 +02001253 @cmd2.with_argparser(authenticate_parser)
1254 def do_authenticate(self, opts):
1255 """Perform Authentication and Key Agreement (AKA)."""
1256 (data, sw) = self._cmd.card._scc.authenticate(opts.rand, opts.autn)
1257 self._cmd.poutput_json(data)
1258
Harald Welte846a8982021-10-08 15:47:16 +02001259 def do_terminal_profile(self, arg):
1260 """Send a TERMINAL PROFILE command to the card."""
1261 (data, sw) = self._cmd.card._scc.terminal_profile(arg)
1262 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
Harald Welte15fae982021-04-10 10:22:27 +02001263
Harald Welte7cb94e42021-10-08 15:47:57 +02001264 def do_envelope(self, arg):
1265 """Send an ENVELOPE command to the card."""
1266 (data, sw) = self._cmd.card._scc.envelope(arg)
1267 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
1268
1269 def do_envelope_sms(self, arg):
1270 """Send an ENVELOPE command to the card."""
1271 tpdu_ie = SMS_TPDU()
1272 tpdu_ie.from_bytes(h2b(arg))
Harald Weltec91085e2022-02-10 18:05:45 +01001273 dev_ids = DeviceIdentities(
1274 decoded={'source_dev_id': 'network', 'dest_dev_id': 'uicc'})
Harald Welte7cb94e42021-10-08 15:47:57 +02001275 sms_dl = SMSPPDownload(children=[dev_ids, tpdu_ie])
1276 (data, sw) = self._cmd.card._scc.envelope(b2h(sms_dl.to_tlv()))
1277 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
1278
Harald Welte15fae982021-04-10 10:22:27 +02001279
Harald Welteb2edd142021-01-08 23:29:35 +01001280# TS 31.102 Section 7.3
1281sw_usim = {
1282 'Security management': {
1283 '9862': 'Authentication error, incorrect MAC',
1284 '9864': 'Authentication error, security context not supported',
1285 '9865': 'Key freshness failure',
1286 '9866': 'Authentication error, no memory space available',
1287 '9867': 'Authentication error, no memory space available in EF MUK',
1288 }
1289}
1290
Harald Weltec91085e2022-02-10 18:05:45 +01001291
Philipp Maier57f65ee2021-10-18 14:09:02 +02001292class CardApplicationUSIM(CardApplication):
1293 def __init__(self):
Harald Weltec91085e2022-02-10 18:05:45 +01001294 super().__init__('USIM', adf=ADF_USIM(), sw=sw_usim)