blob: ce32b2040f61d2997e9969ce2264ae4acb091b6b [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 Weltec91085e2022-02-10 18:05:45 +0100545
Harald Weltee8947492022-02-10 10:33:20 +0100546 @staticmethod
Harald Weltec91085e2022-02-10 18:05:45 +0100547 def _bit_byte_offset_for_service(service: int) -> Tuple[int, int]:
Harald Weltee8947492022-02-10 10:33:20 +0100548 i = service - 1
549 byte_offset = i//8
550 bit_offset = (i % 8)
551 return (byte_offset, bit_offset)
Harald Weltec91085e2022-02-10 18:05:45 +0100552
Harald Welteb2edd142021-01-08 23:29:35 +0100553 def _decode_bin(self, in_bin):
Harald Weltee8947492022-02-10 10:33:20 +0100554 ret = {}
Harald Weltec91085e2022-02-10 18:05:45 +0100555 for i in range(0, len(in_bin)):
Harald Welteb2edd142021-01-08 23:29:35 +0100556 byte = in_bin[i]
Harald Weltec91085e2022-02-10 18:05:45 +0100557 for bitno in range(0, 7):
Harald Weltee8947492022-02-10 10:33:20 +0100558 service_nr = i * 8 + bitno + 1
559 ret[service_nr] = {
Harald Weltec91085e2022-02-10 18:05:45 +0100560 'activated': True if byte & (1 << bitno) else False
Harald Weltee8947492022-02-10 10:33:20 +0100561 }
562 if service_nr in self.table:
563 ret[service_nr]['description'] = self.table[service_nr]
Harald Welteb2edd142021-01-08 23:29:35 +0100564 return ret
Harald Weltec91085e2022-02-10 18:05:45 +0100565
Harald Welteb2edd142021-01-08 23:29:35 +0100566 def _encode_bin(self, in_json):
Harald Weltee8947492022-02-10 10:33:20 +0100567 # compute the required binary size
568 bin_len = 0
569 for srv in in_json.keys():
570 service_nr = int(srv)
Harald Weltec91085e2022-02-10 18:05:45 +0100571 (byte_offset, bit_offset) = EF_UServiceTable._bit_byte_offset_for_service(
572 service_nr)
Harald Weltee8947492022-02-10 10:33:20 +0100573 if byte_offset >= bin_len:
574 bin_len = byte_offset+1
575 # encode the actual data
576 out = bytearray(b'\x00' * bin_len)
577 for srv in in_json.keys():
578 service_nr = int(srv)
Harald Weltec91085e2022-02-10 18:05:45 +0100579 (byte_offset, bit_offset) = EF_UServiceTable._bit_byte_offset_for_service(
580 service_nr)
Harald Weltee8947492022-02-10 10:33:20 +0100581 if in_json[srv]['activated'] == True:
582 bit = 1
583 else:
584 bit = 0
585 out[byte_offset] |= (bit) << bit_offset
586 return out
Harald Weltec91085e2022-02-10 18:05:45 +0100587
Harald Welte82f75c22022-02-12 18:22:28 +0100588 def get_active_services(self, cmd):
Harald Welte6ca2fa72022-02-12 16:29:31 +0100589 # obtain list of currently active services
590 (service_data, sw) = cmd.rs.read_binary_dec()
591 active_services = []
592 for s in service_data.keys():
593 if service_data[s]['activated']:
594 active_services.append(s)
Harald Welte82f75c22022-02-12 18:22:28 +0100595 return active_services
596
597 def ust_service_check(self, cmd):
598 """Check consistency between services of this file and files present/activated"""
599 num_problems = 0
600 # obtain list of currently active services
601 active_services = self.get_active_services(cmd)
Harald Welte6ca2fa72022-02-12 16:29:31 +0100602 # iterate over all the service-constraints we know of
603 files_by_service = self.parent.files_by_service
604 try:
605 for s in sorted(files_by_service.keys()):
606 active_str = 'active' if s in active_services else 'inactive'
607 cmd.poutput("Checking service No %u (%s)" % (s, active_str))
608 for f in files_by_service[s]:
609 should_exist = f.should_exist_for_services(active_services)
610 try:
611 (data, sw) = cmd.card._scc.select_file(f.fid)
612 exists = True
613 fcp = f.decode_select_response(data)
614 # if we just selected a directory, go back
615 if fcp['file_descriptor']['file_type'] == 'df':
616 cmd.card._scc.select_parent_df()
617 except SwMatchError as e:
618 sw = str(e)
619 exists = False
620 if exists != should_exist:
Harald Welte82f75c22022-02-12 18:22:28 +0100621 num_problems += 1
Harald Welte6ca2fa72022-02-12 16:29:31 +0100622 if exists:
623 cmd.poutput(" ERROR: File %s is selectable but should not!" % f)
624 else:
625 cmd.poutput(" ERROR: File %s is not selectable (%s) but should!" % (f, sw))
626 finally:
627 # re-select the EF.UST
628 cmd.card._scc.select_file(self.fid)
Harald Welte82f75c22022-02-12 18:22:28 +0100629 return num_problems
Harald Welte6ca2fa72022-02-12 16:29:31 +0100630
631class EF_UST(EF_UServiceTable):
632 def __init__(self, **kwargs):
633 super().__init__(fid='6f38', sfid=0x04, name='EF.UST', desc='USIM Service Table', size={1,17}, table=EF_UST_map, **kwargs)
634 # add those commands to the general commands of a TransparentEF
635 self.shell_commands += [self.AddlShellCommands()]
636
Harald Welteb2edd142021-01-08 23:29:35 +0100637 @with_default_category('File-Specific Commands')
638 class AddlShellCommands(CommandSet):
639 def __init__(self):
640 super().__init__()
641
642 def do_ust_service_activate(self, arg):
643 """Activate a service within EF.UST"""
644 self._cmd.card.update_ust(int(arg), 1)
645
646 def do_ust_service_deactivate(self, arg):
647 """Deactivate a service within EF.UST"""
648 self._cmd.card.update_ust(int(arg), 0)
649
Harald Welte4c5e2312022-02-12 14:37:48 +0100650 def do_ust_service_check(self, arg):
651 """Check consistency between services of this file and files present/activated"""
Harald Welte4c5e2312022-02-12 14:37:48 +0100652 selected_file = self._cmd.rs.selected_file
Harald Welte82f75c22022-02-12 18:22:28 +0100653 num_problems = selected_file.ust_service_check(self._cmd)
654 # obtain list of currently active services
655 active_services = selected_file.get_active_services(self._cmd)
656 # Service n°46 can only be declared "available" if service n°45 is declared "available"
657 if 46 in active_services and not 45 in active_services:
658 self._cmd.poutput("ERROR: Service 46 available, but it requires Service 45")
659 num_problems += 1
660 # Service n°125 shall only be taken into account if Service n°124 is declared "available"
661 if 125 in active_services and not 124 in active_services:
662 self._cmd.poutput("ERROR: Service 125 is ignored as Service 124 not available")
663 num_problems += 1
664 # Service n°95, n°99 and n°115 shall not be declared "available" if an ISIM application is present on the UICC
665 non_isim_services = [95, 99, 115]
666 app_names = selected_file.get_mf().get_app_names()
667 if 'ADF.ISIM' in app_names:
668 for s in non_isim_services:
669 if s in active_services:
670 self._cmd.poutput("ERROR: Service %u shall not be available as ISIM application is present" % s)
671 num_problems += 1
672 self._cmd.poutput("===> %u service / file inconsistencies detected" % num_problems)
Harald Welte4c5e2312022-02-12 14:37:48 +0100673
674
Harald Welte89e59542021-04-02 21:33:13 +0200675# TS 31.103 Section 4.2.7 - *not* the same as DF.GSM/EF.ECC!
676class EF_ECC(LinFixedEF):
Harald Welteff2d86d2022-01-21 15:19:47 +0100677 cc_construct = Rpad(BcdAdapter(Rpad(Bytes(3))), pattern='f')
678 category_construct = FlagsEnum(Byte, police=1, ambulance=2, fire_brigade=3, marine_guard=4,
679 mountain_rescue=5, manual_ecall=6, automatic_ecall=7)
680 alpha_construct = GsmStringAdapter(Rpad(GreedyBytes))
Harald Weltec91085e2022-02-10 18:05:45 +0100681
Harald Welte89e59542021-04-02 21:33:13 +0200682 def __init__(self, fid='6fb7', sfid=0x01, name='EF.ECC',
683 desc='Emergency Call Codes'):
Harald Weltec91085e2022-02-10 18:05:45 +0100684 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len={4, 20})
685
Harald Welteff2d86d2022-01-21 15:19:47 +0100686 def _decode_record_bin(self, in_bin):
687 # mandatory parts
688 code = in_bin[:3]
689 if code == b'\xff\xff\xff':
690 return None
691 svc_category = in_bin[-1:]
692 ret = {'call_code': parse_construct(EF_ECC.cc_construct, code),
Harald Weltec91085e2022-02-10 18:05:45 +0100693 'service_category': parse_construct(EF_ECC.category_construct, svc_category)}
Harald Welteff2d86d2022-01-21 15:19:47 +0100694 # optional alpha identifier
695 if len(in_bin) > 4:
696 alpha_id = in_bin[3:-1]
697 ret['alpha_id'] = parse_construct(EF_ECC.alpha_construct, alpha_id)
698 return ret
Harald Weltec91085e2022-02-10 18:05:45 +0100699
Harald Welteff2d86d2022-01-21 15:19:47 +0100700 def _encode_record_bin(self, in_json):
701 if in_json is None:
702 return b'\xff\xff\xff\xff'
703 code = EF_ECC.cc_construct.build(in_json['call_code'])
704 svc_category = EF_ECC.category_construct.build(in_json['category'])
705 alpha_id = EF_ECC.alpha_construct.build(in_json['alpha_id'])
706 # FIXME: alpha_id needs padding up to 'record_length - 4'
707 return code + alpha_id + svc_category
708
Harald Welte89e59542021-04-02 21:33:13 +0200709
Harald Welte790b2702021-04-11 00:01:35 +0200710# TS 31.102 Section 4.2.17
711class EF_LOCI(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100712 def __init__(self, fid='6f7e', sfid=0x0b, name='EF.LOCI', desc='Location information', size={11, 11}):
Harald Welte790b2702021-04-11 00:01:35 +0200713 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
714 self._construct = Struct('tmsi'/HexAdapter(Bytes(4)), 'lai'/HexAdapter(Bytes(5)), 'rfu'/Int8ub,
715 'lu_status'/Int8ub)
Harald Welte592b32e2021-06-05 11:26:36 +0200716# TS 31.102 Section 4.2.18
717class EF_AD(TransparentEF):
718 class OP_MODE(enum.IntEnum):
Harald Weltec91085e2022-02-10 18:05:45 +0100719 normal = 0x00
720 type_approval = 0x80
721 normal_and_specific_facilities = 0x01
722 type_approval_and_specific_facilities = 0x81
723 maintenance_off_line = 0x02
724 cell_test = 0x04
Harald Welte592b32e2021-06-05 11:26:36 +0200725
Harald Weltec91085e2022-02-10 18:05:45 +0100726 def __init__(self, fid='6fad', sfid=0x03, name='EF.AD', desc='Administrative Data', size={4, 6}):
Harald Welte592b32e2021-06-05 11:26:36 +0200727 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
728 self._construct = BitStruct(
729 # Byte 1
730 'ms_operation_mode'/Bytewise(Enum(Byte, EF_AD.OP_MODE)),
731 # Byte 2 + 3
732 'additional_info'/Bytewise(FlagsEnum(Int16ub, ciphering_indicator=1, csg_display_control=2,
733 prose_services=4, extended_drx=8)),
734 'rfu'/BitsRFU(4),
735 'mnc_len'/BitsInteger(4),
736 'extensions'/COptional(Bytewise(GreedyBytesRFU))
737 )
Harald Welte790b2702021-04-11 00:01:35 +0200738
739# TS 31.102 Section 4.2.23
740class EF_PSLOCI(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100741 def __init__(self, fid='6f73', sfid=0x0c, name='EF.PSLOCI', desc='PS Location information', size={14, 14}):
Harald Welte790b2702021-04-11 00:01:35 +0200742 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
743 self._construct = Struct('ptmsi'/HexAdapter(Bytes(4)), 'ptmsi_sig'/HexAdapter(Bytes(3)),
744 'rai'/HexAdapter(Bytes(6)), 'rau_status'/Int8ub)
745
746# TS 31.102 Section 4.2.33
747class EF_ICI(CyclicEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100748 def __init__(self, fid='6f80', sfid=0x14, name='EF.ICI', rec_len={28, 48},
Harald Welte6169c722022-02-12 09:05:15 +0100749 desc='Incoming Call Information', **kwargs):
750 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200751 self._construct = Struct('alpha_id'/Bytes(this._.total_len-28),
752 'len_of_bcd_contents'/Int8ub,
753 'ton_npi'/Int8ub,
754 'call_number'/BcdAdapter(Bytes(10)),
755 'cap_cfg2_record_id'/Int8ub,
756 'ext5_record_id'/Int8ub,
757 'date_and_time'/BcdAdapter(Bytes(7)),
758 'duration'/Int24ub,
759 'status'/Byte,
760 'link_to_phonebook'/Bytes(3))
761
762# TS 31.102 Section 4.2.34
763class EF_OCI(CyclicEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100764 def __init__(self, fid='6f81', sfid=0x15, name='EF.OCI', rec_len={27, 47},
Harald Welte6169c722022-02-12 09:05:15 +0100765 desc='Outgoing Call Information', **kwargs):
766 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200767 self._construct = Struct('alpha_id'/Bytes(this._.total_len-27),
768 'len_of_bcd_contents'/Int8ub,
769 'ton_npi'/Int8ub,
770 'call_number'/BcdAdapter(Bytes(10)),
771 'cap_cfg2_record_id'/Int8ub,
772 'ext5_record_id'/Int8ub,
773 'date_and_time'/BcdAdapter(Bytes(7)),
774 'duration'/Int24ub,
775 'link_to_phonebook'/Bytes(3))
776
777# TS 31.102 Section 4.2.35
778class EF_ICT(CyclicEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100779 def __init__(self, fid='6f82', sfid=None, name='EF.ICT', rec_len={3, 3},
Harald Welte6169c722022-02-12 09:05:15 +0100780 desc='Incoming Call Timer', **kwargs):
781 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200782 self._construct = Struct('accumulated_call_timer'/Int24ub)
783
784# TS 31.102 Section 4.2.38
785class EF_CCP2(LinFixedEF):
Harald Welte6169c722022-02-12 09:05:15 +0100786 def __init__(self, fid='6f4f', sfid=0x16, name='EF.CCP2', desc='Capability Configuration Parameters 2', **kwargs):
787 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len={15, None}, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200788
Harald Welte6ca2fa72022-02-12 16:29:31 +0100789# TS 31.102 Section 4.2.47
790class EF_EST(EF_UServiceTable):
791 def __init__(self, **kwargs):
792 super().__init__(fid='6f56', sfid=0x05, name='EF.EST', desc='Enabled Services Table', size={1,None}, table=EF_EST_map, **kwargs)
793 # add those commands to the general commands of a TransparentEF
794 self.shell_commands += [self.AddlShellCommands()]
795
796 @with_default_category('File-Specific Commands')
797 class AddlShellCommands(CommandSet):
798 def __init__(self):
799 super().__init__()
800
801 def do_est_service_activate(self, arg):
802 """Activate a service within EF.UST"""
803 self._cmd.card.update_est(int(arg), 1)
804
805 def do_est_service_deactivate(self, arg):
806 """Deactivate a service within EF.UST"""
807 self._cmd.card.update_est(int(arg), 0)
808
809 def do_est_service_check(self, arg):
810 """Check consistency between services of this file and files present/activated"""
811 # obtain list of currently active services
812 (service_data, sw) = self._cmd.rs.read_binary_dec()
813 active_services = service_data.keys()
814
815
Harald Welte790b2702021-04-11 00:01:35 +0200816# TS 31.102 Section 4.2.48
817class EF_ACL(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100818 def __init__(self, fid='6f57', sfid=None, name='EF.ACL', size={32, None},
Harald Welte6169c722022-02-12 09:05:15 +0100819 desc='Access Point Name Control List', **kwargs):
820 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200821 self._construct = Struct('num_of_apns'/Int8ub, 'tlvs'/GreedyBytes)
822
823# TS 31.102 Section 4.2.51
824class EF_START_HFN(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100825 def __init__(self, fid='6f5b', sfid=0x0f, name='EF.START-HFN', size={6, 6},
Harald Welte6169c722022-02-12 09:05:15 +0100826 desc='Initialisation values for Hyperframe number', **kwargs):
827 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200828 self._construct = Struct('start_cs'/Int24ub, 'start_ps'/Int24ub)
829
830# TS 31.102 Section 4.2.52
831class EF_THRESHOLD(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100832 def __init__(self, fid='6f5c', sfid=0x10, name='EF.THRESHOLD', size={3, 3},
Harald Welte6169c722022-02-12 09:05:15 +0100833 desc='Maximum value of START', **kwargs):
834 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200835 self._construct = Struct('max_start'/Int24ub)
836
837# TS 31.102 Section 4.2.77
838class EF_VGCSCA(TransRecEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100839 def __init__(self, fid='6fd4', sfid=None, name='EF.VGCSCA', size={2, 100}, rec_len=2,
Harald Welte6169c722022-02-12 09:05:15 +0100840 desc='Voice Group Call Service Ciphering Algorithm', **kwargs):
841 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, rec_len=rec_len, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200842 self._construct = Struct('alg_v_ki_1'/Int8ub, 'alg_v_ki_2'/Int8ub)
843
844# TS 31.102 Section 4.2.79
845class EF_GBABP(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100846 def __init__(self, fid='6fd6', sfid=None, name='EF.GBABP', size={3, 50},
Harald Welte6169c722022-02-12 09:05:15 +0100847 desc='GBA Bootstrapping parameters', **kwargs):
848 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200849 self._construct = Struct('rand'/LV, 'b_tid'/LV, 'key_lifetime'/LV)
850
851# TS 31.102 Section 4.2.80
852class EF_MSK(LinFixedEF):
Harald Welte6169c722022-02-12 09:05:15 +0100853 def __init__(self, fid='6fd7', sfid=None, name='EF.MSK', desc='MBMS Service Key List', **kwargs):
854 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len={20, None}, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200855 msk_ts_constr = Struct('msk_id'/Int32ub, 'timestamp_counter'/Int32ub)
856 self._construct = Struct('key_domain_id'/Bytes(3),
857 'num_msk_id'/Int8ub,
858 'msk_ids'/msk_ts_constr[this.num_msk_id])
Harald Welte14105dc2021-05-31 08:48:51 +0200859# TS 31.102 Section 4.2.81
860class EF_MUK(LinFixedEF):
861 class MUK_Idr(BER_TLV_IE, tag=0x80):
862 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100863
Harald Welte14105dc2021-05-31 08:48:51 +0200864 class MUK_Idi(BER_TLV_IE, tag=0x82):
865 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100866
Harald Welte14105dc2021-05-31 08:48:51 +0200867 class MUK_ID(BER_TLV_IE, tag=0xA0, nested=[MUK_Idr, MUK_Idi]):
868 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100869
Harald Welte14105dc2021-05-31 08:48:51 +0200870 class TimeStampCounter(BER_TLV_IE, tag=0x81):
871 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100872
Harald Welte14105dc2021-05-31 08:48:51 +0200873 class EF_MUK_Collection(TLV_IE_Collection, nested=[MUK_ID, TimeStampCounter]):
874 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100875
Harald Welte6169c722022-02-12 09:05:15 +0100876 def __init__(self, fid='6fd8', sfid=None, name='EF.MUK', desc='MBMS User Key', **kwargs):
877 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len={None, None}, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200878 self._tlv = EF_MUK.EF_MUK_Collection
879
880# TS 31.102 Section 4.2.83
881class EF_GBANL(LinFixedEF):
882 class NAF_ID(BER_TLV_IE, tag=0x80):
883 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100884
Harald Welte14105dc2021-05-31 08:48:51 +0200885 class B_TID(BER_TLV_IE, tag=0x81):
886 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100887
Harald Welte14105dc2021-05-31 08:48:51 +0200888 class EF_GBANL_Collection(BER_TLV_IE, nested=[NAF_ID, B_TID]):
889 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100890
Harald Welte6169c722022-02-12 09:05:15 +0100891 def __init__(self, fid='6fda', sfid=None, name='EF.GBANL', desc='GBA NAF List', **kwargs):
892 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len={None, None}, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200893 self._tlv = EF_GBANL.EF_GBANL_Collection
Harald Welte790b2702021-04-11 00:01:35 +0200894
895# TS 31.102 Section 4.2.85
896class EF_EHPLMNPI(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100897 def __init__(self, fid='6fdb', sfid=None, name='EF.EHPLMNPI', size={1, 1},
Harald Welte6169c722022-02-12 09:05:15 +0100898 desc='Equivalent HPLMN Presentation Indication', **kwargs):
899 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Weltec91085e2022-02-10 18:05:45 +0100900 self._construct = Struct('presentation_ind' /
Harald Welte790b2702021-04-11 00:01:35 +0200901 Enum(Byte, no_preference=0, display_highest_prio_only=1, display_all=2))
Harald Welte14105dc2021-05-31 08:48:51 +0200902
903# TS 31.102 Section 4.2.87
904class EF_NAFKCA(LinFixedEF):
905 class NAF_KeyCentreAddress(BER_TLV_IE, tag=0x80):
906 _construct = HexAdapter(GreedyBytes)
907 def __init__(self, fid='6fdd', sfid=None, name='EF.NAFKCA', rec_len={None, None},
Harald Welte6169c722022-02-12 09:05:15 +0100908 desc='NAF Key Centre Address', **kwargs):
909 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200910 self._tlv = EF_NAFKCA.NAF_KeyCentreAddress
911
912# TS 31.102 Section 4.2.90
913class EF_NCP_IP(LinFixedEF):
914 class DataDestAddrRange(TLV_IE, tag=0x83):
915 _construct = Struct('type_of_address'/Enum(Byte, IPv4=0x21, IPv6=0x56),
916 'prefix_length'/Int8ub,
917 'prefix'/HexAdapter(GreedyBytes))
Harald Weltec91085e2022-02-10 18:05:45 +0100918
Harald Welte14105dc2021-05-31 08:48:51 +0200919 class AccessPointName(TLV_IE, tag=0x80):
920 # coded as per TS 23.003
921 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100922
Harald Welte14105dc2021-05-31 08:48:51 +0200923 class Login(TLV_IE, tag=0x81):
924 # as per SMS DCS TS 23.038
925 _construct = GsmStringAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100926
Harald Welte14105dc2021-05-31 08:48:51 +0200927 class Password(TLV_IE, tag=0x82):
928 # as per SMS DCS TS 23.038
929 _construct = GsmStringAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100930
Harald Welte14105dc2021-05-31 08:48:51 +0200931 class BearerDescription(TLV_IE, tag=0x84):
932 # Bearer descriptionTLV DO as per TS 31.111
933 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100934
Harald Welte14105dc2021-05-31 08:48:51 +0200935 class EF_NCP_IP_Collection(TLV_IE_Collection,
936 nested=[AccessPointName, Login, Password, BearerDescription]):
937 pass
938 def __init__(self, fid='6fe2', sfid=None, name='EF.NCP-IP', rec_len={None, None},
Harald Welte6169c722022-02-12 09:05:15 +0100939 desc='Network Connectivity Parameters for USIM IP connections', **kwargs):
940 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200941 self._tlv = EF_NCP_IP.EF_NCP_IP_Collection
942
Harald Welte790b2702021-04-11 00:01:35 +0200943# TS 31.102 Section 4.2.91
944class EF_EPSLOCI(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100945 def __init__(self, fid='6fe3', sfid=0x1e, name='EF.EPSLOCI', size={18, 18},
Harald Welte6169c722022-02-12 09:05:15 +0100946 desc='EPS Location Information', **kwargs):
947 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Weltec91085e2022-02-10 18:05:45 +0100948 upd_status_constr = Enum(
949 Byte, updated=0, not_updated=1, roaming_not_allowed=2)
Harald Welte790b2702021-04-11 00:01:35 +0200950 self._construct = Struct('guti'/Bytes(12), 'last_visited_registered_tai'/Bytes(5),
951 'eps_update_status'/upd_status_constr)
952
Harald Welte14105dc2021-05-31 08:48:51 +0200953# TS 31.102 Section 4.2.92
954class EF_EPSNSC(LinFixedEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100955 class KSI_ASME(BER_TLV_IE, tag=0x80):
Harald Welte14105dc2021-05-31 08:48:51 +0200956 _construct = Int8ub
Harald Weltec91085e2022-02-10 18:05:45 +0100957
958 class K_ASME(BER_TLV_IE, tag=0x81):
Harald Welte14105dc2021-05-31 08:48:51 +0200959 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100960
Harald Welte14105dc2021-05-31 08:48:51 +0200961 class UplinkNASCount(BER_TLV_IE, tag=0x82):
962 _construct = Int32ub
Harald Weltec91085e2022-02-10 18:05:45 +0100963
Harald Welte14105dc2021-05-31 08:48:51 +0200964 class DownlinkNASCount(BER_TLV_IE, tag=0x83):
965 _construct = Int32ub
Harald Weltec91085e2022-02-10 18:05:45 +0100966
Harald Welte14105dc2021-05-31 08:48:51 +0200967 class IDofNASAlgorithms(BER_TLV_IE, tag=0x84):
968 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100969
Harald Welte14105dc2021-05-31 08:48:51 +0200970 class EPS_NAS_Security_Context(BER_TLV_IE, tag=0xa0,
Harald Weltec91085e2022-02-10 18:05:45 +0100971 nested=[KSI_ASME, K_ASME, UplinkNASCount, DownlinkNASCount,
972 IDofNASAlgorithms]):
Harald Welte14105dc2021-05-31 08:48:51 +0200973 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100974 def __init__(self, fid='6fe4', sfid=0x18, name='EF.EPSNSC', rec_len={54, 128},
Harald Welte6169c722022-02-12 09:05:15 +0100975 desc='EPS NAS Security Context', **kwargs):
976 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200977 self._tlv = EF_EPSNSC.EPS_NAS_Security_Context
978
Harald Welte790b2702021-04-11 00:01:35 +0200979# TS 31.102 Section 4.2.96
980class EF_PWS(TransparentEF):
Harald Welte6169c722022-02-12 09:05:15 +0100981 def __init__(self, fid='6fec', sfid=None, name='EF.PWS', desc='Public Warning System', size={1, 1}, **kwargs):
982 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Weltec91085e2022-02-10 18:05:45 +0100983 pws_config = FlagsEnum(
984 Byte, ignore_pws_in_hplmn_and_equivalent=1, ignore_pws_in_vplmn=2)
Harald Welte790b2702021-04-11 00:01:35 +0200985 self._construct = Struct('pws_configuration'/pws_config)
986
987# TS 31.102 Section 4.2.101
988class EF_IPS(CyclicEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100989 def __init__(self, fid='6ff1', sfid=None, name='EF.IPS', rec_len={4, 4},
Harald Welte6169c722022-02-12 09:05:15 +0100990 desc='IMEI(SV) Pairing Status', **kwargs):
991 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200992 self._construct = Struct('status'/PaddedString(2, 'ascii'),
993 'link_to_ef_ipd'/Int8ub, 'rfu'/Byte)
994
Harald Welte14105dc2021-05-31 08:48:51 +0200995# TS 31.102 Section 4.2.103
996class EF_ePDGId(TransparentEF):
997 class ePDGId(BER_TLV_IE, tag=0x80, nested=[]):
998 _construct = Struct('type_of_ePDG_address'/Enum(Byte, FQDN=0, IPv4=1, IPv6=2),
999 'ePDG_address'/Switch(this.type_of_address,
Harald Weltec91085e2022-02-10 18:05:45 +01001000 {'FQDN': GreedyString("utf8"),
1001 'IPv4': HexAdapter(GreedyBytes),
1002 'IPv6': HexAdapter(GreedyBytes)}))
1003
Harald Welte6169c722022-02-12 09:05:15 +01001004 def __init__(self, fid='6ff3', sfid=None, name='EF.eDPDGId', desc='Home ePDG Identifier', **kwargs):
1005 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +02001006 self._tlv = EF_ePDGId.ePDGId
1007
Harald Welte71290072021-04-21 10:58:24 +02001008# TS 31.102 Section 4.2.106
1009class EF_FromPreferred(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +01001010 def __init__(self, fid='6ff7', sfid=None, name='EF.FromPreferred', size={1, 1},
Harald Welte6169c722022-02-12 09:05:15 +01001011 desc='From Preferred', **kwargs):
1012 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte71290072021-04-21 10:58:24 +02001013 self._construct = BitStruct('rfu'/BitsRFU(7), 'from_preferred'/Bit)
1014
Harald Welte790b2702021-04-11 00:01:35 +02001015######################################################################
1016# DF.5GS
1017######################################################################
1018
1019# TS 31.102 Section 4.4.11.2
1020class EF_5GS3GPPLOCI(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +01001021 def __init__(self, fid='4f01', sfid=0x01, name='EF.5GS3GPPLOCI', size={20, 20},
Harald Welte790b2702021-04-11 00:01:35 +02001022 desc='5S 3GP location information'):
1023 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Weltec91085e2022-02-10 18:05:45 +01001024 upd_status_constr = Enum(
1025 Byte, updated=0, not_updated=1, roaming_not_allowed=2)
Harald Welte790b2702021-04-11 00:01:35 +02001026 self._construct = Struct('5g_guti'/Bytes(13), 'last_visited_registered_tai_in_5gs'/Bytes(6),
1027 '5gs_update_status'/upd_status_constr)
1028
1029# TS 31.102 Section 4.4.11.7
1030class EF_UAC_AIC(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +01001031 def __init__(self, fid='4f06', sfid=0x06, name='EF.UAC_AIC', size={4, 4},
Harald Welte790b2702021-04-11 00:01:35 +02001032 desc='UAC Access Identities Configuration'):
1033 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
1034 cfg_constr = FlagsEnum(Byte, multimedia_priority_service=1,
Harald Weltec91085e2022-02-10 18:05:45 +01001035 mission_critical_service=2)
Harald Welte790b2702021-04-11 00:01:35 +02001036 self._construct = Struct('uac_access_id_config'/cfg_constr)
1037
Harald Welte14105dc2021-05-31 08:48:51 +02001038# TS 31.102 Section 4.4.11.9
Harald Welte790b2702021-04-11 00:01:35 +02001039class EF_OPL5G(LinFixedEF):
1040 def __init__(self, fid='6f08', sfid=0x08, name='EF.OPL5G', desc='5GS Operator PLMN List'):
Harald Weltec91085e2022-02-10 18:05:45 +01001041 super().__init__(fid=fid, sfid=sfid,
1042 name=name, desc=desc, rec_len={10, None})
Harald Welte790b2702021-04-11 00:01:35 +02001043 self._construct = Struct('tai'/Bytes(9), 'pnn_record_id'/Int8ub)
1044
Harald Welte14105dc2021-05-31 08:48:51 +02001045# TS 31.102 Section 4.4.11.10
1046class EF_SUPI_NAI(TransparentEF):
1047 class NetworkSpecificIdentifier(TLV_IE, tag=0x80):
1048 # RFC 7542 encoded as UTF-8 string
1049 _construct = GreedyString("utf8")
Harald Weltec91085e2022-02-10 18:05:45 +01001050
Harald Welte14105dc2021-05-31 08:48:51 +02001051 class GlobalLineIdentifier(TLV_IE, tag=0x81):
1052 # TS 23.003 clause 28.16.2
1053 pass
Harald Weltec91085e2022-02-10 18:05:45 +01001054
Harald Welte14105dc2021-05-31 08:48:51 +02001055 class GlobalCableIdentifier(TLV_IE, tag=0x82):
1056 # TS 23.003 clause 28.15.2
1057 pass
Harald Weltec91085e2022-02-10 18:05:45 +01001058
Harald Welte14105dc2021-05-31 08:48:51 +02001059 class NAI_TLV_Collection(TLV_IE_Collection,
Harald Weltec91085e2022-02-10 18:05:45 +01001060 nested=[NetworkSpecificIdentifier, GlobalLineIdentifier, GlobalCableIdentifier]):
Harald Welte14105dc2021-05-31 08:48:51 +02001061 pass
1062 def __init__(self, fid='4f09', sfid=0x09, name='EF.SUPI_NAI',
Harald Weltec91085e2022-02-10 18:05:45 +01001063 desc='SUPI as Network Access Identifier'):
Harald Welte14105dc2021-05-31 08:48:51 +02001064 super().__init__(fid, sfid=sfid, name=name, desc=desc)
1065 self._tlv = EF_SUPI_NAI.NAI_TLV_Collection
1066
Harald Weltec91085e2022-02-10 18:05:45 +01001067
Harald Welte14105dc2021-05-31 08:48:51 +02001068class EF_TN3GPPSNN(TransparentEF):
1069 class ServingNetworkName(BER_TLV_IE, tag=0x80):
1070 _construct = GreedyString("utf8")
1071 def __init__(self, fid='4f0c', sfid=0x0c, name='EF.TN3GPPSNN',
Harald Weltec91085e2022-02-10 18:05:45 +01001072 desc='Trusted non-3GPP Serving network names list'):
Harald Welte14105dc2021-05-31 08:48:51 +02001073 super().__init__(fid, sfid=sfid, name=name, desc=desc)
1074 self._tlv = EF_TN3GPPSNN.ServingNetworkName
1075
Harald Welte3990ebb2021-04-20 23:55:14 +02001076# TS 31.102 Section 4.4.5
1077class DF_WLAN(CardDF):
Harald Welte6169c722022-02-12 09:05:15 +01001078 def __init__(self, fid='5f40', name='DF.WLAN', desc='Files for WLAN purpose', **kwargs):
1079 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
Harald Welte3990ebb2021-04-20 23:55:14 +02001080 files = [
1081 TransparentEF('4f41', 0x01, 'EF.Pseudo', 'Pseudonym'),
Harald Weltec91085e2022-02-10 18:05:45 +01001082 TransparentEF('4f42', 0x02, 'EF.UPLMNWLAN',
1083 'User controlled PLMN selector for I-WLAN Access'),
1084 TransparentEF('4f43', 0x03, 'EF.OPLMNWLAN',
1085 'Operator controlled PLMN selector for I-WLAN Access'),
1086 LinFixedEF('4f44', 0x04, 'EF.UWSIDL',
1087 'User controlled WLAN Specific Identifier List'),
1088 LinFixedEF('4f45', 0x05, 'EF.OWSIDL',
1089 'Operator controlled WLAN Specific Identifier List'),
1090 TransparentEF('4f46', 0x06, 'EF.WRI',
1091 'WLAN Reauthentication Identity'),
1092 LinFixedEF('4f47', 0x07, 'EF.HWSIDL',
1093 'Home I-WLAN Specific Identifier List'),
1094 TransparentEF('4f48', 0x08, 'EF.WEHPLMNPI',
1095 'I-WLAN Equivalent HPLMN Presentation Indication'),
1096 TransparentEF('4f49', 0x09, 'EF.WHPI',
1097 'I-WLAN HPLMN Priority Indication'),
1098 TransparentEF('4f4a', 0x0a, 'EF.WLRPLMN',
1099 'I-WLAN Last Registered PLMN'),
1100 TransparentEF('4f4b', 0x0b, 'EF.HPLMNDAI',
1101 'HPLMN Direct Access Indicator'),
1102 ]
Harald Welte3990ebb2021-04-20 23:55:14 +02001103 self.add_files(files)
1104
1105# TS 31.102 Section 4.4.6
1106class DF_HNB(CardDF):
Harald Welte6169c722022-02-12 09:05:15 +01001107 def __init__(self, fid='5f50', name='DF.HNB', desc='Files for HomeNodeB purpose', **kwargs):
1108 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
Harald Welte3990ebb2021-04-20 23:55:14 +02001109 files = [
1110 LinFixedEF('4f01', 0x01, 'EF.ACSGL', 'Allowed CSG Lists'),
1111 LinFixedEF('4f02', 0x02, 'EF.CSGTL', 'CSG Types'),
1112 LinFixedEF('4f03', 0x03, 'EF.HNBN', 'Home NodeB Name'),
1113 LinFixedEF('4f04', 0x04, 'EF.OCSGL', 'Operator CSG Lists'),
1114 LinFixedEF('4f05', 0x05, 'EF.OCSGT', 'Operator CSG Type'),
1115 LinFixedEF('4f06', 0x06, 'EF.OHNBN', 'Operator Home NodeB Name'),
Harald Weltec91085e2022-02-10 18:05:45 +01001116 ]
Harald Welte3990ebb2021-04-20 23:55:14 +02001117 self.add_files(files)
1118
1119# TS 31.102 Section 4.4.8
1120class DF_ProSe(CardDF):
Harald Welte6169c722022-02-12 09:05:15 +01001121 def __init__(self, fid='5f90', name='DF.ProSe', desc='Files for ProSe purpose', **kwargs):
1122 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
Harald Welte3990ebb2021-04-20 23:55:14 +02001123 files = [
Harald Weltec91085e2022-02-10 18:05:45 +01001124 LinFixedEF('4f01', 0x01, 'EF.PROSE_MON',
1125 'ProSe Monitoring Parameters'),
1126 LinFixedEF('4f02', 0x02, 'EF.PROSE_ANN',
1127 'ProSe Announcing Parameters'),
Harald Welte3990ebb2021-04-20 23:55:14 +02001128 LinFixedEF('4f03', 0x03, 'EF.PROSEFUNC', 'HPLMN ProSe Function'),
Harald Weltec91085e2022-02-10 18:05:45 +01001129 TransparentEF('4f04', 0x04, 'EF.PROSE_RADIO_COM',
1130 'ProSe Direct Communication Radio Parameters'),
1131 TransparentEF('4f05', 0x05, 'EF.PROSE_RADIO_MON',
1132 'ProSe Direct Discovery Monitoring Radio Parameters'),
1133 TransparentEF('4f06', 0x06, 'EF.PROSE_RADIO_ANN',
1134 'ProSe Direct Discovery Announcing Radio Parameters'),
1135 LinFixedEF('4f07', 0x07, 'EF.PROSE_POLICY',
1136 'ProSe Policy Parameters'),
Harald Welte3990ebb2021-04-20 23:55:14 +02001137 LinFixedEF('4f08', 0x08, 'EF.PROSE_PLMN', 'ProSe PLMN Parameters'),
1138 TransparentEF('4f09', 0x09, 'EF.PROSE_GC', 'ProSe Group Counter'),
1139 TransparentEF('4f10', 0x10, 'EF.PST', 'ProSe Service Table'),
Harald Weltec91085e2022-02-10 18:05:45 +01001140 TransparentEF('4f11', 0x11, 'EF.UIRC',
1141 'ProSe UsageInformationReportingConfiguration'),
1142 LinFixedEF('4f12', 0x12, 'EF.PROSE_GM_DISCOVERY',
1143 'ProSe Group Member Discovery Parameters'),
1144 LinFixedEF('4f13', 0x13, 'EF.PROSE_RELAY',
1145 'ProSe Relay Parameters'),
1146 TransparentEF('4f14', 0x14, 'EF.PROSE_RELAY_DISCOVERY',
1147 'ProSe Relay Discovery Parameters'),
1148 ]
Harald Welte3990ebb2021-04-20 23:55:14 +02001149 self.add_files(files)
1150
Harald Weltec91085e2022-02-10 18:05:45 +01001151
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001152class DF_USIM_5GS(CardDF):
Harald Welte6169c722022-02-12 09:05:15 +01001153 def __init__(self, fid='5FC0', name='DF.5GS', desc='5GS related files', **kwargs):
1154 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001155 files = [
Harald Weltec91085e2022-02-10 18:05:45 +01001156 # I'm looking at 31.102 R16.6
1157 EF_5GS3GPPLOCI(),
1158 EF_5GS3GPPLOCI('4f02', 0x02, 'EF.5GSN3GPPLOCI',
1159 '5GS non-3GPP location information'),
1160 EF_5GS3GPPNSC(),
1161 EF_5GS3GPPNSC('4f04', 0x04, 'EF.5GSN3GPPNSC',
1162 '5GS non-3GPP Access NAS Security Context'),
1163 EF_5GAUTHKEYS(),
1164 EF_UAC_AIC(),
1165 EF_SUCI_Calc_Info(),
1166 EF_OPL5G(),
1167 EF_SUPI_NAI(),
1168 TransparentEF('4F0A', 0x0a, 'EF.Routing_Indicator',
1169 'Routing Indicator', size={4, 4}),
1170 TransparentEF('4F0B', 0x0b, 'EF.URSP',
1171 'UE Route Selector Policies per PLMN'),
1172 EF_TN3GPPSNN(),
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001173 ]
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001174 self.add_files(files)
1175
Harald Weltec91085e2022-02-10 18:05:45 +01001176
Harald Welteb2edd142021-01-08 23:29:35 +01001177class ADF_USIM(CardADF):
1178 def __init__(self, aid='a0000000871002', name='ADF.USIM', fid=None, sfid=None,
1179 desc='USIM Application'):
1180 super().__init__(aid=aid, fid=fid, sfid=sfid, name=name, desc=desc)
Harald Welte15fae982021-04-10 10:22:27 +02001181 # add those commands to the general commands of a TransparentEF
1182 self.shell_commands += [self.AddlShellCommands()]
Harald Welteb2edd142021-01-08 23:29:35 +01001183
1184 files = [
Harald Weltec91085e2022-02-10 18:05:45 +01001185 EF_LI(sfid=0x02),
1186 EF_IMSI(sfid=0x07),
1187 EF_Keys(),
1188 EF_Keys('6f09', 0x09, 'EF.KeysPS',
1189 desc='Ciphering and Integrity Keys for PS domain'),
1190 EF_xPLMNwAcT('6f60', 0x0a, 'EF.PLMNwAcT',
Harald Welte6169c722022-02-12 09:05:15 +01001191 'User controlled PLMN Selector with Access Technology', service=20),
Harald Weltec91085e2022-02-10 18:05:45 +01001192 EF_HPPLMN(),
Harald Welte6169c722022-02-12 09:05:15 +01001193 EF_ACMmax(service=13),
Harald Welte6ca2fa72022-02-12 16:29:31 +01001194 EF_UST(),
Harald Weltec91085e2022-02-10 18:05:45 +01001195 CyclicEF('6f39', None, 'EF.ACM',
Harald Welte6169c722022-02-12 09:05:15 +01001196 'Accumulated call meter', rec_len={3, 3}, service=13),
1197 TransparentEF('6f3e', None, 'EF.GID1', 'Group Identifier Level 1', service=17),
1198 TransparentEF('6f3f', None, 'EF.GID2', 'Group Identifier Level 2', service=18),
1199 EF_SPN(service=19),
Harald Weltec91085e2022-02-10 18:05:45 +01001200 TransparentEF('6f41', None, 'EF.PUCT',
Harald Welte6169c722022-02-12 09:05:15 +01001201 'Price per unit and currency table', size={5, 5}, service=13),
1202 EF_CBMI(service=15),
Harald Weltec91085e2022-02-10 18:05:45 +01001203 EF_ACC(sfid=0x06),
1204 EF_PLMNsel('6f7b', 0x0d, 'EF.FPLMN',
1205 'Forbidden PLMNs', size={12, None}),
1206 EF_LOCI(),
1207 EF_AD(),
Harald Welte6169c722022-02-12 09:05:15 +01001208 EF_CBMID(sfid=0x0e, service=29),
Harald Weltec91085e2022-02-10 18:05:45 +01001209 EF_ECC(),
Harald Welte6169c722022-02-12 09:05:15 +01001210 EF_CBMIR(service=16),
Harald Weltec91085e2022-02-10 18:05:45 +01001211 EF_PSLOCI(),
Harald Welte6169c722022-02-12 09:05:15 +01001212 EF_ADN('6f3b', None, 'EF.FDN', 'Fixed Dialling Numbers', service=[2, 89]),
1213 EF_SMS('6f3c', None, service=10),
1214 EF_MSISDN(service=21),
1215 EF_SMSP(service=12),
1216 EF_SMSS(service=10),
1217 EF_ADN('6f49', None, 'EF.SDN', 'Service Dialling Numbers', service=[4, 89]),
1218 EF_EXT('6f4b', None, 'EF.EXT2', 'Extension2 (FDN)', service=3),
1219 EF_EXT('6f4c', None, 'EF.EXT3', 'Extension2 (SDN)', service=5),
1220 EF_SMSR(service=11),
1221 EF_ICI(service=9),
1222 EF_OCI(service=8),
1223 EF_ICT(service=9),
1224 EF_ICT('6f83', None, 'EF.OCT', 'Outgoing Call Timer', service=8),
1225 EF_EXT('6f4e', None, 'EF.EXT5', 'Extension5 (ICI/OCI/MSISDN)', service=44),
1226 EF_CCP2(service=14),
1227 EF_eMLPP(service=24),
1228 EF_AAeM(service=25),
Harald Weltec91085e2022-02-10 18:05:45 +01001229 # EF_Hiddenkey
Harald Welte6169c722022-02-12 09:05:15 +01001230 EF_ADN('6f4d', None, 'EF.BDN', 'Barred Dialling Numbers', service=6),
1231 EF_EXT('6f55', None, 'EF.EXT4', 'Extension4 (BDN/SSC)', service=7),
1232 EF_CMI(service=6),
Harald Welte6ca2fa72022-02-12 16:29:31 +01001233 EF_EST(service=[2, 6, 34, 35]),
Harald Welte6169c722022-02-12 09:05:15 +01001234 EF_ACL(service=35),
1235 EF_DCK(service=36),
1236 EF_CNL(service=37),
Harald Weltec91085e2022-02-10 18:05:45 +01001237 EF_START_HFN(),
1238 EF_THRESHOLD(),
Harald Welte6169c722022-02-12 09:05:15 +01001239 EF_xPLMNwAcT('6f61', 0x11, 'EF.OPLMNwAcT', 'User controlled PLMN Selector with Access Technology', service=42),
1240 EF_xPLMNwAcT('6f62', 0x13, 'EF.HPLMNwAcT', 'HPLMN Selector with Access Technology', service=43),
Harald Weltec91085e2022-02-10 18:05:45 +01001241 EF_ARR('6f06', 0x17),
1242 TransparentEF('6fc4', None, 'EF.NETPAR', 'Network Parameters'),
Harald Welte6169c722022-02-12 09:05:15 +01001243 EF_PNN('6fc5', 0x19, service=45),
1244 EF_OPL(service=46),
1245 EF_ADN('6fc7', None, 'EF.MBDN', 'Mailbox Dialling Numbers', service=47),
1246 EF_EXT('6fc8', None, 'EF.EXT6', 'Extension6 (MBDN)'),
1247 EF_MBI(service=47),
1248 EF_MWIS(service=48),
1249 EF_ADN('6fcb', None, 'EF.CFIS', 'Call Forwarding Indication Status', service=49),
Harald Weltec91085e2022-02-10 18:05:45 +01001250 EF_EXT('6fcc', None, 'EF.EXT7', 'Extension7 (CFIS)'),
Harald Welte6169c722022-02-12 09:05:15 +01001251 TransparentEF('6fcd', None, 'EF.SPDI', 'Service Provider Display Information', service=51),
1252 EF_MMSN(service=52),
1253 EF_EXT('6fcf', None, 'EF.EXT8', 'Extension8 (MMSN)', service=53),
1254 EF_MMSICP(service=52),
1255 EF_MMSUP(service=52),
1256 EF_MMSUCP(service=(52, 55)),
1257 EF_NIA(service=56),
1258 EF_VGCS(service=57),
1259 EF_VGCSS(service=57),
1260 EF_VGCS('6fb3', None, 'EF.VBS', 'Voice Broadcast Service', service=58),
1261 EF_VGCSS('6fb4', None, 'EF.VBSS', 'Voice Broadcast Service Status', service=58),
1262 EF_VGCSCA(service=64),
1263 EF_VGCSCA('6fd5', None, 'EF.VBCSCA', 'Voice Broadcast Service Ciphering Algorithm', service=65),
1264 EF_GBABP(service=68),
1265 EF_MSK(service=69),
1266 EF_MUK(service=69),
1267 EF_GBANL(service=68),
1268 EF_PLMNsel('6fd9', 0x1d, 'EF.EHPLMN', 'Equivalent HPLMN', size={12, None}, service=71),
1269 EF_EHPLMNPI(service=(71, 73)),
1270 # EF_LRPLMNSI ('6fdc', service=74)
1271 EF_NAFKCA(service=(68, 76)),
1272 TransparentEF('6fde', None, 'EF.SPNI', 'Service Provider Name Icon', service=78),
1273 LinFixedEF('6fdf', None, 'EF.PNNI', 'PLMN Network Name Icon', service=79),
1274 EF_NCP_IP(service=80),
1275 EF_EPSLOCI('6fe3', 0x1e, 'EF.EPSLOCI', 'EPS location information', service=85),
1276 EF_EPSNSC(service=85),
1277 TransparentEF('6fe6', None, 'EF.UFC', 'USAT Facility Control', size={1, 16}),
1278 TransparentEF('6fe8', None, 'EF.NASCONFIG', 'Non Access Stratum Configuration', service=96),
1279 # UICC IARI (only in cards that have no ISIM) service=95
1280 EF_PWS(service=97),
1281 LinFixedEF('6fed', None, 'EF.FDNURI', 'Fixed Dialling Numbers URI', service=(2, 99)),
1282 LinFixedEF('6fee', None, 'EF.BDNURI', 'Barred Dialling Numbers URI', service=(6, 99)),
1283 LinFixedEF('6fef', None, 'EF.SDNURI', 'Service Dialling Numbers URI', service=(4, 99)),
1284 # EF_IWL (IMEI(SV) White List)
Harald Weltec91085e2022-02-10 18:05:45 +01001285 EF_IPS(),
Harald Welte6169c722022-02-12 09:05:15 +01001286 EF_ePDGId(service=(106, 107)),
Harald Weltec91085e2022-02-10 18:05:45 +01001287 # FIXME: from EF_ePDGSelection onwards
Harald Welte6169c722022-02-12 09:05:15 +01001288 EF_FromPreferred(service=114),
1289 # FIXME: DF_SoLSA service=23
Harald Weltec91085e2022-02-10 18:05:45 +01001290 # FIXME: DF_PHONEBOOK
Harald Welte6169c722022-02-12 09:05:15 +01001291 # FIXME: DF_GSM_ACCESS service=27
1292 DF_WLAN(service=[59, 60, 61, 62, 63, 66, 81, 82, 83, 84, 88]),
1293 DF_HNB(service=[86, 90]),
1294 DF_ProSe(service=101),
1295 # FIXME: DF_ACDC service=108
1296 # FIXME: DF_TV service=116
1297 DF_USIM_5GS(service=[122, 123, 124, 125, 126, 127, 129, 130]),
Harald Weltec91085e2022-02-10 18:05:45 +01001298 ]
Harald Welteb2edd142021-01-08 23:29:35 +01001299 self.add_files(files)
1300
1301 def decode_select_response(self, data_hex):
Philipp Maier5998a3a2021-11-16 15:16:39 +01001302 return pySim.ts_102_221.CardProfileUICC.decode_select_response(data_hex)
Harald Welteb2edd142021-01-08 23:29:35 +01001303
Harald Welte15fae982021-04-10 10:22:27 +02001304 @with_default_category('Application-Specific Commands')
1305 class AddlShellCommands(CommandSet):
1306 def __init__(self):
1307 super().__init__()
1308
1309 authenticate_parser = argparse.ArgumentParser()
1310 authenticate_parser.add_argument('rand', help='Random challenge')
1311 authenticate_parser.add_argument('autn', help='Authentication Nonce')
1312 #authenticate_parser.add_argument('--context', help='Authentication context', default='3G')
Harald Weltec91085e2022-02-10 18:05:45 +01001313
Harald Welte15fae982021-04-10 10:22:27 +02001314 @cmd2.with_argparser(authenticate_parser)
1315 def do_authenticate(self, opts):
1316 """Perform Authentication and Key Agreement (AKA)."""
1317 (data, sw) = self._cmd.card._scc.authenticate(opts.rand, opts.autn)
1318 self._cmd.poutput_json(data)
1319
Harald Welte846a8982021-10-08 15:47:16 +02001320 def do_terminal_profile(self, arg):
1321 """Send a TERMINAL PROFILE command to the card."""
1322 (data, sw) = self._cmd.card._scc.terminal_profile(arg)
1323 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
Harald Welte15fae982021-04-10 10:22:27 +02001324
Harald Welte7cb94e42021-10-08 15:47:57 +02001325 def do_envelope(self, arg):
1326 """Send an ENVELOPE command to the card."""
1327 (data, sw) = self._cmd.card._scc.envelope(arg)
1328 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
1329
1330 def do_envelope_sms(self, arg):
1331 """Send an ENVELOPE command to the card."""
1332 tpdu_ie = SMS_TPDU()
1333 tpdu_ie.from_bytes(h2b(arg))
Harald Weltec91085e2022-02-10 18:05:45 +01001334 dev_ids = DeviceIdentities(
1335 decoded={'source_dev_id': 'network', 'dest_dev_id': 'uicc'})
Harald Welte7cb94e42021-10-08 15:47:57 +02001336 sms_dl = SMSPPDownload(children=[dev_ids, tpdu_ie])
1337 (data, sw) = self._cmd.card._scc.envelope(b2h(sms_dl.to_tlv()))
1338 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
1339
Harald Welte15fae982021-04-10 10:22:27 +02001340
Harald Welteb2edd142021-01-08 23:29:35 +01001341# TS 31.102 Section 7.3
1342sw_usim = {
1343 'Security management': {
1344 '9862': 'Authentication error, incorrect MAC',
1345 '9864': 'Authentication error, security context not supported',
1346 '9865': 'Key freshness failure',
1347 '9866': 'Authentication error, no memory space available',
1348 '9867': 'Authentication error, no memory space available in EF MUK',
1349 }
1350}
1351
Harald Weltec91085e2022-02-10 18:05:45 +01001352
Philipp Maier57f65ee2021-10-18 14:09:02 +02001353class CardApplicationUSIM(CardApplication):
1354 def __init__(self):
Harald Weltec91085e2022-02-10 18:05:45 +01001355 super().__init__('USIM', adf=ADF_USIM(), sw=sw_usim)