blob: 9e6ea78a6a9f9af5b5790dc3596f746421f90652 [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)
Harald Weltec91085e2022-02-10 18:05:45 +0100307
Harald Weltef12979d2021-05-29 21:47:13 +0200308class EF_5GS3GPPNSC(LinFixedEF):
309 class NgKSI(BER_TLV_IE, tag=0x80):
310 _construct = Int8ub
311
312 class K_AMF(BER_TLV_IE, tag=0x81):
313 _construct = HexAdapter(Bytes(32))
314
315 class UplinkNASCount(BER_TLV_IE, tag=0x82):
316 _construct = Int32ub
317
318 class DownlinkNASCount(BER_TLV_IE, tag=0x83):
319 _construct = Int32ub
320
321 class IdsOfSelectedNasAlgos(BER_TLV_IE, tag=0x84):
322 # 3GPP TS 24.501 Section 9.11.3.34
323 _construct = BitStruct('ciphering'/Nibble, 'integrity'/Nibble)
324
325 class IdsOfSelectedEpsAlgos(BER_TLV_IE, tag=0x85):
326 # 3GPP TS 24.301 Section 9.9.3.23
327 _construct = BitStruct('ciphering'/Nibble, 'integrity'/Nibble)
328
329 class FiveGSNasSecurityContext(BER_TLV_IE, tag=0xA0,
Harald Weltec91085e2022-02-10 18:05:45 +0100330 nested=[NgKSI, K_AMF, UplinkNASCount,
331 DownlinkNASCount, IdsOfSelectedNasAlgos,
332 IdsOfSelectedEpsAlgos]):
Harald Weltef12979d2021-05-29 21:47:13 +0200333 pass
334
335 def __init__(self, fid="4f03", sfid=0x03, name='EF.5GS3GPPNSC', rec_len={57, None},
Harald Weltec91085e2022-02-10 18:05:45 +0100336 desc='5GS 3GPP Access NAS Security Context'):
Harald Weltef12979d2021-05-29 21:47:13 +0200337 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
Harald Welte65516272022-02-10 17:51:05 +0100338 self._tlv = EF_5GS3GPPNSC.FiveGSNasSecurityContext
Harald Weltef12979d2021-05-29 21:47:13 +0200339
340# 3GPP TS 31.102 Section 4.4.11.6
Harald Weltec91085e2022-02-10 18:05:45 +0100341
342
Harald Weltef12979d2021-05-29 21:47:13 +0200343class EF_5GAUTHKEYS(TransparentEF):
344 class K_AUSF(BER_TLV_IE, tag=0x80):
345 _construct = HexAdapter(GreedyBytes)
346
347 class K_SEAF(BER_TLV_IE, tag=0x81):
348 _construct = HexAdapter(GreedyBytes)
349
350 class FiveGAuthKeys(TLV_IE_Collection, nested=[K_AUSF, K_SEAF]):
351 pass
352
353 def __init__(self, fid='4f05', sfid=0x05, name='EF.5GAUTHKEYS', size={68, None},
Harald Weltec91085e2022-02-10 18:05:45 +0100354 desc='5G authentication keys'):
Harald Weltef12979d2021-05-29 21:47:13 +0200355 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Welte65516272022-02-10 17:51:05 +0100356 self._tlv = EF_5GAUTHKEYS.FiveGAuthKeys
Harald Weltef12979d2021-05-29 21:47:13 +0200357
358# 3GPP TS 31.102 Section 4.4.11.8
Harald Weltec91085e2022-02-10 18:05:45 +0100359
360
Harald Weltef12979d2021-05-29 21:47:13 +0200361class ProtSchemeIdList(BER_TLV_IE, tag=0xa0):
362 # FIXME: 3GPP TS 24.501 Protection Scheme Identifier
363 # repeated sequence of (id, index) tuples
Harald Weltec91085e2022-02-10 18:05:45 +0100364 _construct = GreedyRange(
365 Struct('id'/Enum(Byte, null=0, A=1, B=2), 'index'/Int8ub))
366
Harald Weltef12979d2021-05-29 21:47:13 +0200367
368class HomeNetPubKeyId(BER_TLV_IE, tag=0x80):
369 # 3GPP TS 24.501 / 3GPP TS 23.003
370 _construct = Int8ub
371
Harald Weltec91085e2022-02-10 18:05:45 +0100372
Harald Weltef12979d2021-05-29 21:47:13 +0200373class HomeNetPubKey(BER_TLV_IE, tag=0x81):
374 # FIXME: RFC 5480
375 _construct = HexAdapter(GreedyBytes)
376
Harald Weltec91085e2022-02-10 18:05:45 +0100377
Harald Weltef12979d2021-05-29 21:47:13 +0200378class HomeNetPubKeyList(BER_TLV_IE, tag=0xa1,
Harald Weltec91085e2022-02-10 18:05:45 +0100379 nested=[HomeNetPubKeyId, HomeNetPubKey]):
Harald Weltef12979d2021-05-29 21:47:13 +0200380 pass
381
382# 3GPP TS 31.102 Section 4.4.11.6
Harald Weltec91085e2022-02-10 18:05:45 +0100383
384
385class SUCI_CalcInfo(TLV_IE_Collection, nested=[ProtSchemeIdList, HomeNetPubKeyList]):
Harald Weltef12979d2021-05-29 21:47:13 +0200386 pass
387
388
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200389# TS 31.102 4.4.11.8
390class EF_SUCI_Calc_Info(TransparentEF):
391 def __init__(self, fid="4f07", sfid=0x07, name='EF.SUCI_Calc_Info', size={2, None},
Harald Weltec91085e2022-02-10 18:05:45 +0100392 desc='SUCI Calc Info'):
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200393 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
394
395 def _encode_prot_scheme_id_list(self, in_list):
396 out_bytes = [0xa0]
Harald Weltec91085e2022-02-10 18:05:45 +0100397 out_bytes.append(len(in_list)*2) # two byte per entry
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200398
399 # position in list determines priority; high-priority items (low index) come first
400 for scheme in sorted(in_list, key=lambda item: item["priority"]):
401 out_bytes.append(scheme["identifier"])
402 out_bytes.append(scheme["key_index"])
403
404 return out_bytes
405
406 def _encode_hnet_pubkey_list(self, hnet_pubkey_list):
Harald Weltec91085e2022-02-10 18:05:45 +0100407 out_bytes = [0xa1] # pubkey list tag
408 out_bytes.append(0x00) # length filled later
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200409 length = 0
410
411 for key in hnet_pubkey_list:
Harald Weltec91085e2022-02-10 18:05:45 +0100412 out_bytes.append(0x80) # identifier tag
413 out_bytes.append(0x01) # TODO size, fixed to 1 byte
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200414 out_bytes.append(key["hnet_pubkey_identifier"])
Harald Weltec91085e2022-02-10 18:05:45 +0100415 out_bytes.append(0x81) # key tag
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200416 out_bytes.append(len(key["hnet_pubkey"])//2)
417 length += 5+len(key["hnet_pubkey"])//2
418
419 pubkey_bytes = h2b(key["hnet_pubkey"])
420 out_bytes += pubkey_bytes
421
422 # fill length
423 out_bytes[1] = length
424 return out_bytes
425
426 def _encode_hex(self, in_json):
Harald Weltec91085e2022-02-10 18:05:45 +0100427 out_bytes = self._encode_prot_scheme_id_list(
428 in_json['prot_scheme_id_list'])
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200429 out_bytes += self._encode_hnet_pubkey_list(in_json['hnet_pubkey_list'])
430 return "".join(["%02X" % i for i in out_bytes])
431
432 def _decode_prot_scheme_id_list(self, in_bytes):
433 prot_scheme_id_list = []
434 pos = 0
435 # two bytes per entry
436 while pos < len(in_bytes):
437 prot_scheme = {
Harald Weltec91085e2022-02-10 18:05:45 +0100438 'priority': pos//2, # first in list: high priority
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200439 'identifier': in_bytes[pos],
440 'key_index': in_bytes[pos+1]
441 }
442 pos += 2
443 prot_scheme_id_list.append(prot_scheme)
444 return prot_scheme_id_list
445
446 def _decode_hnet_pubkey_list(self, in_bytes):
447 hnet_pubkey_list = []
448 pos = 0
449 if in_bytes[pos] != 0xa1:
450 print("missing Home Network Public Key List data object")
451 return {}
452 pos += 1
453 hnet_pubkey_list_len = in_bytes[pos]
454 pos += 1
455
456 while pos < hnet_pubkey_list_len:
457 if in_bytes[pos] != 0x80:
458 print("missing Home Network Public Key Identifier tag")
459 return {}
460 pos += 1
Harald Weltec91085e2022-02-10 18:05:45 +0100461 # TODO might be more than 1 byte?
462 hnet_pubkey_id_len = in_bytes[pos]
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200463 pos += 1
464 hnet_pubkey_id = in_bytes[pos:pos+hnet_pubkey_id_len][0]
465 pos += hnet_pubkey_id_len
466 if in_bytes[pos] != 0x81:
467 print("missing Home Network Public Key tag")
468 return {}
469 pos += 1
470 hnet_pubkey_len = in_bytes[pos]
471 pos += 1
472 hnet_pubkey = in_bytes[pos:pos+hnet_pubkey_len]
473 pos += hnet_pubkey_len
474
475 hnet_pubkey_list.append({
476 'hnet_pubkey_identifier': hnet_pubkey_id,
477 'hnet_pubkey': b2h(hnet_pubkey)
478 })
479
480 return hnet_pubkey_list
481
482 def _decode_bin(self, in_bin):
Vadim Yanitskiy5e41eeb2021-05-02 02:20:33 +0200483 return self._decode_hex(b2h(in_bin))
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200484
485 def _decode_hex(self, in_hex):
486 in_bytes = h2b(in_hex)
487 pos = 0
488
489 if in_bytes[pos] != 0xa0:
490 print("missing Protection Scheme Identifier List data object tag")
491 return {}
492 pos += 1
493
Harald Weltec91085e2022-02-10 18:05:45 +0100494 prot_scheme_id_list_len = in_bytes[pos] # TODO maybe more than 1 byte
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200495 pos += 1
496 # decode Protection Scheme Identifier List data object
Harald Weltec91085e2022-02-10 18:05:45 +0100497 prot_scheme_id_list = self._decode_prot_scheme_id_list(
498 in_bytes[pos:pos+prot_scheme_id_list_len])
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200499 pos += prot_scheme_id_list_len
500
501 # remaining data holds Home Network Public Key Data Object
502 hnet_pubkey_list = self._decode_hnet_pubkey_list(in_bytes[pos:])
503
504 return {
505 'prot_scheme_id_list': prot_scheme_id_list,
506 'hnet_pubkey_list': hnet_pubkey_list
507 }
508
509 def _encode_bin(self, in_json):
510 return h2b(self._encode_hex(in_json))
511
Harald Weltec91085e2022-02-10 18:05:45 +0100512
Harald Welteb2edd142021-01-08 23:29:35 +0100513class EF_LI(TransRecEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100514 def __init__(self, fid='6f05', sfid=None, name='EF.LI', size={2, None}, rec_len=2,
Harald Welteb2edd142021-01-08 23:29:35 +0100515 desc='Language Indication'):
516 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, rec_len=rec_len)
Harald Weltec91085e2022-02-10 18:05:45 +0100517
Harald Welteb2edd142021-01-08 23:29:35 +0100518 def _decode_record_bin(self, in_bin):
519 if in_bin == b'\xff\xff':
520 return None
521 else:
522 # officially this is 7-bit GSM alphabet with one padding bit in each byte
523 return in_bin.decode('ascii')
Harald Weltec91085e2022-02-10 18:05:45 +0100524
Harald Welteb2edd142021-01-08 23:29:35 +0100525 def _encode_record_bin(self, in_json):
526 if in_json == None:
527 return b'\xff\xff'
528 else:
529 # officially this is 7-bit GSM alphabet with one padding bit in each byte
530 return in_json.encode('ascii')
531
Harald Weltec91085e2022-02-10 18:05:45 +0100532
Harald Welteb2edd142021-01-08 23:29:35 +0100533class EF_Keys(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100534 def __init__(self, fid='6f08', sfid=0x08, name='EF.Keys', size={33, 33},
Harald Welteb2edd142021-01-08 23:29:35 +0100535 desc='Ciphering and Integrity Keys'):
536 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Weltec91085e2022-02-10 18:05:45 +0100537 self._construct = Struct(
538 'ksi'/Int8ub, 'ck'/HexAdapter(Bytes(16)), 'ik'/HexAdapter(Bytes(16)))
Harald Welteb2edd142021-01-08 23:29:35 +0100539
Harald Welte14105dc2021-05-31 08:48:51 +0200540# TS 31.102 Section 4.2.6
Harald Weltec91085e2022-02-10 18:05:45 +0100541
542
Harald Welte14105dc2021-05-31 08:48:51 +0200543class EF_HPPLMN(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100544 def __init__(self, fid='6f31', sfid=0x12, name='EF.HPPLMN', size={1, 1},
Harald Welte14105dc2021-05-31 08:48:51 +0200545 desc='Higher Priority PLMN search period'):
546 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
547 self._construct = Int8ub
548
549# TS 31.102 Section 4.2.8
Harald Weltec91085e2022-02-10 18:05:45 +0100550
551
Harald Weltee8947492022-02-10 10:33:20 +0100552class EF_UServiceTable(TransparentEF):
553 def __init__(self, fid, sfid, name, desc, size, table):
Harald Welte790b2702021-04-11 00:01:35 +0200554 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Weltee8947492022-02-10 10:33:20 +0100555 self.table = table
Harald Welteb2edd142021-01-08 23:29:35 +0100556 # add those commands to the general commands of a TransparentEF
557 self.shell_commands += [self.AddlShellCommands()]
Harald Weltec91085e2022-02-10 18:05:45 +0100558
Harald Weltee8947492022-02-10 10:33:20 +0100559 @staticmethod
Harald Weltec91085e2022-02-10 18:05:45 +0100560 def _bit_byte_offset_for_service(service: int) -> Tuple[int, int]:
Harald Weltee8947492022-02-10 10:33:20 +0100561 i = service - 1
562 byte_offset = i//8
563 bit_offset = (i % 8)
564 return (byte_offset, bit_offset)
Harald Weltec91085e2022-02-10 18:05:45 +0100565
Harald Welteb2edd142021-01-08 23:29:35 +0100566 def _decode_bin(self, in_bin):
Harald Weltee8947492022-02-10 10:33:20 +0100567 ret = {}
Harald Weltec91085e2022-02-10 18:05:45 +0100568 for i in range(0, len(in_bin)):
Harald Welteb2edd142021-01-08 23:29:35 +0100569 byte = in_bin[i]
Harald Weltec91085e2022-02-10 18:05:45 +0100570 for bitno in range(0, 7):
Harald Weltee8947492022-02-10 10:33:20 +0100571 service_nr = i * 8 + bitno + 1
572 ret[service_nr] = {
Harald Weltec91085e2022-02-10 18:05:45 +0100573 'activated': True if byte & (1 << bitno) else False
Harald Weltee8947492022-02-10 10:33:20 +0100574 }
575 if service_nr in self.table:
576 ret[service_nr]['description'] = self.table[service_nr]
Harald Welteb2edd142021-01-08 23:29:35 +0100577 return ret
Harald Weltec91085e2022-02-10 18:05:45 +0100578
Harald Welteb2edd142021-01-08 23:29:35 +0100579 def _encode_bin(self, in_json):
Harald Weltee8947492022-02-10 10:33:20 +0100580 # compute the required binary size
581 bin_len = 0
582 for srv in in_json.keys():
583 service_nr = int(srv)
Harald Weltec91085e2022-02-10 18:05:45 +0100584 (byte_offset, bit_offset) = EF_UServiceTable._bit_byte_offset_for_service(
585 service_nr)
Harald Weltee8947492022-02-10 10:33:20 +0100586 if byte_offset >= bin_len:
587 bin_len = byte_offset+1
588 # encode the actual data
589 out = bytearray(b'\x00' * bin_len)
590 for srv in in_json.keys():
591 service_nr = int(srv)
Harald Weltec91085e2022-02-10 18:05:45 +0100592 (byte_offset, bit_offset) = EF_UServiceTable._bit_byte_offset_for_service(
593 service_nr)
Harald Weltee8947492022-02-10 10:33:20 +0100594 if in_json[srv]['activated'] == True:
595 bit = 1
596 else:
597 bit = 0
598 out[byte_offset] |= (bit) << bit_offset
599 return out
Harald Weltec91085e2022-02-10 18:05:45 +0100600
Harald Welteb2edd142021-01-08 23:29:35 +0100601 @with_default_category('File-Specific Commands')
602 class AddlShellCommands(CommandSet):
603 def __init__(self):
604 super().__init__()
605
606 def do_ust_service_activate(self, arg):
607 """Activate a service within EF.UST"""
608 self._cmd.card.update_ust(int(arg), 1)
609
610 def do_ust_service_deactivate(self, arg):
611 """Deactivate a service within EF.UST"""
612 self._cmd.card.update_ust(int(arg), 0)
613
Harald Welte89e59542021-04-02 21:33:13 +0200614# TS 31.103 Section 4.2.7 - *not* the same as DF.GSM/EF.ECC!
Harald Weltec91085e2022-02-10 18:05:45 +0100615
616
Harald Welte89e59542021-04-02 21:33:13 +0200617class EF_ECC(LinFixedEF):
Harald Welteff2d86d2022-01-21 15:19:47 +0100618 cc_construct = Rpad(BcdAdapter(Rpad(Bytes(3))), pattern='f')
619 category_construct = FlagsEnum(Byte, police=1, ambulance=2, fire_brigade=3, marine_guard=4,
620 mountain_rescue=5, manual_ecall=6, automatic_ecall=7)
621 alpha_construct = GsmStringAdapter(Rpad(GreedyBytes))
Harald Weltec91085e2022-02-10 18:05:45 +0100622
Harald Welte89e59542021-04-02 21:33:13 +0200623 def __init__(self, fid='6fb7', sfid=0x01, name='EF.ECC',
624 desc='Emergency Call Codes'):
Harald Weltec91085e2022-02-10 18:05:45 +0100625 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len={4, 20})
626
Harald Welteff2d86d2022-01-21 15:19:47 +0100627 def _decode_record_bin(self, in_bin):
628 # mandatory parts
629 code = in_bin[:3]
630 if code == b'\xff\xff\xff':
631 return None
632 svc_category = in_bin[-1:]
633 ret = {'call_code': parse_construct(EF_ECC.cc_construct, code),
Harald Weltec91085e2022-02-10 18:05:45 +0100634 'service_category': parse_construct(EF_ECC.category_construct, svc_category)}
Harald Welteff2d86d2022-01-21 15:19:47 +0100635 # optional alpha identifier
636 if len(in_bin) > 4:
637 alpha_id = in_bin[3:-1]
638 ret['alpha_id'] = parse_construct(EF_ECC.alpha_construct, alpha_id)
639 return ret
Harald Weltec91085e2022-02-10 18:05:45 +0100640
Harald Welteff2d86d2022-01-21 15:19:47 +0100641 def _encode_record_bin(self, in_json):
642 if in_json is None:
643 return b'\xff\xff\xff\xff'
644 code = EF_ECC.cc_construct.build(in_json['call_code'])
645 svc_category = EF_ECC.category_construct.build(in_json['category'])
646 alpha_id = EF_ECC.alpha_construct.build(in_json['alpha_id'])
647 # FIXME: alpha_id needs padding up to 'record_length - 4'
648 return code + alpha_id + svc_category
649
Harald Welte89e59542021-04-02 21:33:13 +0200650
Harald Welte790b2702021-04-11 00:01:35 +0200651# TS 31.102 Section 4.2.17
652class EF_LOCI(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100653 def __init__(self, fid='6f7e', sfid=0x0b, name='EF.LOCI', desc='Location information', size={11, 11}):
Harald Welte790b2702021-04-11 00:01:35 +0200654 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
655 self._construct = Struct('tmsi'/HexAdapter(Bytes(4)), 'lai'/HexAdapter(Bytes(5)), 'rfu'/Int8ub,
656 'lu_status'/Int8ub)
Harald Welte592b32e2021-06-05 11:26:36 +0200657# TS 31.102 Section 4.2.18
Harald Weltec91085e2022-02-10 18:05:45 +0100658
659
Harald Welte592b32e2021-06-05 11:26:36 +0200660class EF_AD(TransparentEF):
661 class OP_MODE(enum.IntEnum):
Harald Weltec91085e2022-02-10 18:05:45 +0100662 normal = 0x00
663 type_approval = 0x80
664 normal_and_specific_facilities = 0x01
665 type_approval_and_specific_facilities = 0x81
666 maintenance_off_line = 0x02
667 cell_test = 0x04
Harald Welte592b32e2021-06-05 11:26:36 +0200668
Harald Weltec91085e2022-02-10 18:05:45 +0100669 def __init__(self, fid='6fad', sfid=0x03, name='EF.AD', desc='Administrative Data', size={4, 6}):
Harald Welte592b32e2021-06-05 11:26:36 +0200670 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
671 self._construct = BitStruct(
672 # Byte 1
673 'ms_operation_mode'/Bytewise(Enum(Byte, EF_AD.OP_MODE)),
674 # Byte 2 + 3
675 'additional_info'/Bytewise(FlagsEnum(Int16ub, ciphering_indicator=1, csg_display_control=2,
676 prose_services=4, extended_drx=8)),
677 'rfu'/BitsRFU(4),
678 'mnc_len'/BitsInteger(4),
679 'extensions'/COptional(Bytewise(GreedyBytesRFU))
680 )
Harald Welte790b2702021-04-11 00:01:35 +0200681
682# TS 31.102 Section 4.2.23
Harald Weltec91085e2022-02-10 18:05:45 +0100683
684
Harald Welte790b2702021-04-11 00:01:35 +0200685class EF_PSLOCI(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100686 def __init__(self, fid='6f73', sfid=0x0c, name='EF.PSLOCI', desc='PS Location information', size={14, 14}):
Harald Welte790b2702021-04-11 00:01:35 +0200687 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
688 self._construct = Struct('ptmsi'/HexAdapter(Bytes(4)), 'ptmsi_sig'/HexAdapter(Bytes(3)),
689 'rai'/HexAdapter(Bytes(6)), 'rau_status'/Int8ub)
690
691# TS 31.102 Section 4.2.33
Harald Weltec91085e2022-02-10 18:05:45 +0100692
693
Harald Welte790b2702021-04-11 00:01:35 +0200694class EF_ICI(CyclicEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100695 def __init__(self, fid='6f80', sfid=0x14, name='EF.ICI', rec_len={28, 48},
Harald Welte790b2702021-04-11 00:01:35 +0200696 desc='Incoming Call Information'):
697 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
698 self._construct = Struct('alpha_id'/Bytes(this._.total_len-28),
699 'len_of_bcd_contents'/Int8ub,
700 'ton_npi'/Int8ub,
701 'call_number'/BcdAdapter(Bytes(10)),
702 'cap_cfg2_record_id'/Int8ub,
703 'ext5_record_id'/Int8ub,
704 'date_and_time'/BcdAdapter(Bytes(7)),
705 'duration'/Int24ub,
706 'status'/Byte,
707 'link_to_phonebook'/Bytes(3))
708
709# TS 31.102 Section 4.2.34
Harald Weltec91085e2022-02-10 18:05:45 +0100710
711
Harald Welte790b2702021-04-11 00:01:35 +0200712class EF_OCI(CyclicEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100713 def __init__(self, fid='6f81', sfid=0x15, name='EF.OCI', rec_len={27, 47},
Harald Welte790b2702021-04-11 00:01:35 +0200714 desc='Outgoing Call Information'):
715 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
716 self._construct = Struct('alpha_id'/Bytes(this._.total_len-27),
717 'len_of_bcd_contents'/Int8ub,
718 'ton_npi'/Int8ub,
719 'call_number'/BcdAdapter(Bytes(10)),
720 'cap_cfg2_record_id'/Int8ub,
721 'ext5_record_id'/Int8ub,
722 'date_and_time'/BcdAdapter(Bytes(7)),
723 'duration'/Int24ub,
724 'link_to_phonebook'/Bytes(3))
725
726# TS 31.102 Section 4.2.35
Harald Weltec91085e2022-02-10 18:05:45 +0100727
728
Harald Welte790b2702021-04-11 00:01:35 +0200729class EF_ICT(CyclicEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100730 def __init__(self, fid='6f82', sfid=None, name='EF.ICT', rec_len={3, 3},
Harald Welte790b2702021-04-11 00:01:35 +0200731 desc='Incoming Call Timer'):
732 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
733 self._construct = Struct('accumulated_call_timer'/Int24ub)
734
735# TS 31.102 Section 4.2.38
Harald Weltec91085e2022-02-10 18:05:45 +0100736
737
Harald Welte790b2702021-04-11 00:01:35 +0200738class EF_CCP2(LinFixedEF):
739 def __init__(self, fid='6f4f', sfid=0x16, name='EF.CCP2', desc='Capability Configuration Parameters 2'):
Harald Weltec91085e2022-02-10 18:05:45 +0100740 super().__init__(fid=fid, sfid=sfid,
741 name=name, desc=desc, rec_len={15, None})
Harald Welte790b2702021-04-11 00:01:35 +0200742
743# TS 31.102 Section 4.2.48
Harald Weltec91085e2022-02-10 18:05:45 +0100744
745
Harald Welte790b2702021-04-11 00:01:35 +0200746class EF_ACL(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100747 def __init__(self, fid='6f57', sfid=None, name='EF.ACL', size={32, None},
Harald Welte790b2702021-04-11 00:01:35 +0200748 desc='Access Point Name Control List'):
749 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
750 self._construct = Struct('num_of_apns'/Int8ub, 'tlvs'/GreedyBytes)
751
752# TS 31.102 Section 4.2.51
Harald Weltec91085e2022-02-10 18:05:45 +0100753
754
Harald Welte790b2702021-04-11 00:01:35 +0200755class EF_START_HFN(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100756 def __init__(self, fid='6f5b', sfid=0x0f, name='EF.START-HFN', size={6, 6},
Harald Welte790b2702021-04-11 00:01:35 +0200757 desc='Initialisation values for Hyperframe number'):
758 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
759 self._construct = Struct('start_cs'/Int24ub, 'start_ps'/Int24ub)
760
761# TS 31.102 Section 4.2.52
Harald Weltec91085e2022-02-10 18:05:45 +0100762
763
Harald Welte790b2702021-04-11 00:01:35 +0200764class EF_THRESHOLD(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100765 def __init__(self, fid='6f5c', sfid=0x10, name='EF.THRESHOLD', size={3, 3},
Harald Welte790b2702021-04-11 00:01:35 +0200766 desc='Maximum value of START'):
767 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
768 self._construct = Struct('max_start'/Int24ub)
769
770# TS 31.102 Section 4.2.77
Harald Weltec91085e2022-02-10 18:05:45 +0100771
772
Harald Welte790b2702021-04-11 00:01:35 +0200773class EF_VGCSCA(TransRecEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100774 def __init__(self, fid='6fd4', sfid=None, name='EF.VGCSCA', size={2, 100}, rec_len=2,
Harald Welte790b2702021-04-11 00:01:35 +0200775 desc='Voice Group Call Service Ciphering Algorithm'):
776 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, rec_len=rec_len)
777 self._construct = Struct('alg_v_ki_1'/Int8ub, 'alg_v_ki_2'/Int8ub)
778
779# TS 31.102 Section 4.2.79
Harald Weltec91085e2022-02-10 18:05:45 +0100780
781
Harald Welte790b2702021-04-11 00:01:35 +0200782class 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 Welte790b2702021-04-11 00:01:35 +0200784 desc='GBA Bootstrapping parameters'):
785 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
786 self._construct = Struct('rand'/LV, 'b_tid'/LV, 'key_lifetime'/LV)
787
788# TS 31.102 Section 4.2.80
Harald Weltec91085e2022-02-10 18:05:45 +0100789
790
Harald Welte790b2702021-04-11 00:01:35 +0200791class EF_MSK(LinFixedEF):
792 def __init__(self, fid='6fd7', sfid=None, name='EF.MSK', desc='MBMS Service Key List'):
Harald Weltec91085e2022-02-10 18:05:45 +0100793 super().__init__(fid=fid, sfid=sfid,
794 name=name, desc=desc, rec_len={20, None})
Harald Welte790b2702021-04-11 00:01:35 +0200795 msk_ts_constr = Struct('msk_id'/Int32ub, 'timestamp_counter'/Int32ub)
796 self._construct = Struct('key_domain_id'/Bytes(3),
797 'num_msk_id'/Int8ub,
798 'msk_ids'/msk_ts_constr[this.num_msk_id])
Harald Welte14105dc2021-05-31 08:48:51 +0200799# TS 31.102 Section 4.2.81
Harald Weltec91085e2022-02-10 18:05:45 +0100800
801
Harald Welte14105dc2021-05-31 08:48:51 +0200802class EF_MUK(LinFixedEF):
803 class MUK_Idr(BER_TLV_IE, tag=0x80):
804 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100805
Harald Welte14105dc2021-05-31 08:48:51 +0200806 class MUK_Idi(BER_TLV_IE, tag=0x82):
807 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100808
Harald Welte14105dc2021-05-31 08:48:51 +0200809 class MUK_ID(BER_TLV_IE, tag=0xA0, nested=[MUK_Idr, MUK_Idi]):
810 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100811
Harald Welte14105dc2021-05-31 08:48:51 +0200812 class TimeStampCounter(BER_TLV_IE, tag=0x81):
813 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100814
Harald Welte14105dc2021-05-31 08:48:51 +0200815 class EF_MUK_Collection(TLV_IE_Collection, nested=[MUK_ID, TimeStampCounter]):
816 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100817
Harald Welte14105dc2021-05-31 08:48:51 +0200818 def __init__(self, fid='6fd8', sfid=None, name='EF.MUK', desc='MBMS User Key'):
Harald Weltec91085e2022-02-10 18:05:45 +0100819 super().__init__(fid=fid, sfid=sfid, name=name,
820 desc=desc, rec_len={None, None})
Harald Welte14105dc2021-05-31 08:48:51 +0200821 self._tlv = EF_MUK.EF_MUK_Collection
822
823# TS 31.102 Section 4.2.83
Harald Weltec91085e2022-02-10 18:05:45 +0100824
825
Harald Welte14105dc2021-05-31 08:48:51 +0200826class EF_GBANL(LinFixedEF):
827 class NAF_ID(BER_TLV_IE, tag=0x80):
828 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100829
Harald Welte14105dc2021-05-31 08:48:51 +0200830 class B_TID(BER_TLV_IE, tag=0x81):
831 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100832
Harald Welte14105dc2021-05-31 08:48:51 +0200833 class EF_GBANL_Collection(BER_TLV_IE, nested=[NAF_ID, B_TID]):
834 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100835
Harald Welte14105dc2021-05-31 08:48:51 +0200836 def __init__(self, fid='6fda', sfid=None, name='EF.GBANL', desc='GBA NAF List'):
Harald Weltec91085e2022-02-10 18:05:45 +0100837 super().__init__(fid=fid, sfid=sfid, name=name,
838 desc=desc, rec_len={None, None})
Harald Welte14105dc2021-05-31 08:48:51 +0200839 self._tlv = EF_GBANL.EF_GBANL_Collection
Harald Welte790b2702021-04-11 00:01:35 +0200840
841# TS 31.102 Section 4.2.85
Harald Weltec91085e2022-02-10 18:05:45 +0100842
843
Harald Welte790b2702021-04-11 00:01:35 +0200844class EF_EHPLMNPI(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100845 def __init__(self, fid='6fdb', sfid=None, name='EF.EHPLMNPI', size={1, 1},
Harald Welte790b2702021-04-11 00:01:35 +0200846 desc='Equivalent HPLMN Presentation Indication'):
847 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Weltec91085e2022-02-10 18:05:45 +0100848 self._construct = Struct('presentation_ind' /
Harald Welte790b2702021-04-11 00:01:35 +0200849 Enum(Byte, no_preference=0, display_highest_prio_only=1, display_all=2))
Harald Welte14105dc2021-05-31 08:48:51 +0200850
851# TS 31.102 Section 4.2.87
Harald Weltec91085e2022-02-10 18:05:45 +0100852
853
Harald Welte14105dc2021-05-31 08:48:51 +0200854class EF_NAFKCA(LinFixedEF):
855 class NAF_KeyCentreAddress(BER_TLV_IE, tag=0x80):
856 _construct = HexAdapter(GreedyBytes)
857 def __init__(self, fid='6fdd', sfid=None, name='EF.NAFKCA', rec_len={None, None},
Harald Weltec91085e2022-02-10 18:05:45 +0100858 desc='NAF Key Centre Address'):
Harald Welte14105dc2021-05-31 08:48:51 +0200859 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
860 self._tlv = EF_NAFKCA.NAF_KeyCentreAddress
861
862# TS 31.102 Section 4.2.90
Harald Weltec91085e2022-02-10 18:05:45 +0100863
864
Harald Welte14105dc2021-05-31 08:48:51 +0200865class EF_NCP_IP(LinFixedEF):
866 class DataDestAddrRange(TLV_IE, tag=0x83):
867 _construct = Struct('type_of_address'/Enum(Byte, IPv4=0x21, IPv6=0x56),
868 'prefix_length'/Int8ub,
869 'prefix'/HexAdapter(GreedyBytes))
Harald Weltec91085e2022-02-10 18:05:45 +0100870
Harald Welte14105dc2021-05-31 08:48:51 +0200871 class AccessPointName(TLV_IE, tag=0x80):
872 # coded as per TS 23.003
873 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100874
Harald Welte14105dc2021-05-31 08:48:51 +0200875 class Login(TLV_IE, tag=0x81):
876 # as per SMS DCS TS 23.038
877 _construct = GsmStringAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100878
Harald Welte14105dc2021-05-31 08:48:51 +0200879 class Password(TLV_IE, tag=0x82):
880 # as per SMS DCS TS 23.038
881 _construct = GsmStringAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100882
Harald Welte14105dc2021-05-31 08:48:51 +0200883 class BearerDescription(TLV_IE, tag=0x84):
884 # Bearer descriptionTLV DO as per TS 31.111
885 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100886
Harald Welte14105dc2021-05-31 08:48:51 +0200887 class EF_NCP_IP_Collection(TLV_IE_Collection,
888 nested=[AccessPointName, Login, Password, BearerDescription]):
889 pass
890 def __init__(self, fid='6fe2', sfid=None, name='EF.NCP-IP', rec_len={None, None},
Harald Weltec91085e2022-02-10 18:05:45 +0100891 desc='Network Connectivity Parameters for USIM IP connections'):
Harald Welte14105dc2021-05-31 08:48:51 +0200892 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
893 self._tlv = EF_NCP_IP.EF_NCP_IP_Collection
894
Harald Welte790b2702021-04-11 00:01:35 +0200895# TS 31.102 Section 4.2.91
Harald Weltec91085e2022-02-10 18:05:45 +0100896
897
Harald Welte790b2702021-04-11 00:01:35 +0200898class EF_EPSLOCI(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100899 def __init__(self, fid='6fe3', sfid=0x1e, name='EF.EPSLOCI', size={18, 18},
Harald Welte790b2702021-04-11 00:01:35 +0200900 desc='EPS Location Information'):
901 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Weltec91085e2022-02-10 18:05:45 +0100902 upd_status_constr = Enum(
903 Byte, updated=0, not_updated=1, roaming_not_allowed=2)
Harald Welte790b2702021-04-11 00:01:35 +0200904 self._construct = Struct('guti'/Bytes(12), 'last_visited_registered_tai'/Bytes(5),
905 'eps_update_status'/upd_status_constr)
906
Harald Welte14105dc2021-05-31 08:48:51 +0200907# TS 31.102 Section 4.2.92
Harald Weltec91085e2022-02-10 18:05:45 +0100908
909
Harald Welte14105dc2021-05-31 08:48:51 +0200910class EF_EPSNSC(LinFixedEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100911 class KSI_ASME(BER_TLV_IE, tag=0x80):
Harald Welte14105dc2021-05-31 08:48:51 +0200912 _construct = Int8ub
Harald Weltec91085e2022-02-10 18:05:45 +0100913
914 class K_ASME(BER_TLV_IE, tag=0x81):
Harald Welte14105dc2021-05-31 08:48:51 +0200915 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100916
Harald Welte14105dc2021-05-31 08:48:51 +0200917 class UplinkNASCount(BER_TLV_IE, tag=0x82):
918 _construct = Int32ub
Harald Weltec91085e2022-02-10 18:05:45 +0100919
Harald Welte14105dc2021-05-31 08:48:51 +0200920 class DownlinkNASCount(BER_TLV_IE, tag=0x83):
921 _construct = Int32ub
Harald Weltec91085e2022-02-10 18:05:45 +0100922
Harald Welte14105dc2021-05-31 08:48:51 +0200923 class IDofNASAlgorithms(BER_TLV_IE, tag=0x84):
924 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100925
Harald Welte14105dc2021-05-31 08:48:51 +0200926 class EPS_NAS_Security_Context(BER_TLV_IE, tag=0xa0,
Harald Weltec91085e2022-02-10 18:05:45 +0100927 nested=[KSI_ASME, K_ASME, UplinkNASCount, DownlinkNASCount,
928 IDofNASAlgorithms]):
Harald Welte14105dc2021-05-31 08:48:51 +0200929 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100930 def __init__(self, fid='6fe4', sfid=0x18, name='EF.EPSNSC', rec_len={54, 128},
931 desc='EPS NAS Security Context'):
Harald Welte14105dc2021-05-31 08:48:51 +0200932 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
933 self._tlv = EF_EPSNSC.EPS_NAS_Security_Context
934
Harald Welte790b2702021-04-11 00:01:35 +0200935# TS 31.102 Section 4.2.96
Harald Weltec91085e2022-02-10 18:05:45 +0100936
937
Harald Welte790b2702021-04-11 00:01:35 +0200938class EF_PWS(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100939 def __init__(self, fid='6fec', sfid=None, name='EF.PWS', desc='Public Warning System', size={1, 1}):
Harald Welte790b2702021-04-11 00:01:35 +0200940 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Weltec91085e2022-02-10 18:05:45 +0100941 pws_config = FlagsEnum(
942 Byte, ignore_pws_in_hplmn_and_equivalent=1, ignore_pws_in_vplmn=2)
Harald Welte790b2702021-04-11 00:01:35 +0200943 self._construct = Struct('pws_configuration'/pws_config)
944
945# TS 31.102 Section 4.2.101
Harald Weltec91085e2022-02-10 18:05:45 +0100946
947
Harald Welte790b2702021-04-11 00:01:35 +0200948class EF_IPS(CyclicEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100949 def __init__(self, fid='6ff1', sfid=None, name='EF.IPS', rec_len={4, 4},
Harald Welte790b2702021-04-11 00:01:35 +0200950 desc='IMEI(SV) Pairing Status'):
951 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len)
952 self._construct = Struct('status'/PaddedString(2, 'ascii'),
953 'link_to_ef_ipd'/Int8ub, 'rfu'/Byte)
954
Harald Welte14105dc2021-05-31 08:48:51 +0200955# TS 31.102 Section 4.2.103
Harald Weltec91085e2022-02-10 18:05:45 +0100956
957
Harald Welte14105dc2021-05-31 08:48:51 +0200958class EF_ePDGId(TransparentEF):
959 class ePDGId(BER_TLV_IE, tag=0x80, nested=[]):
960 _construct = Struct('type_of_ePDG_address'/Enum(Byte, FQDN=0, IPv4=1, IPv6=2),
961 'ePDG_address'/Switch(this.type_of_address,
Harald Weltec91085e2022-02-10 18:05:45 +0100962 {'FQDN': GreedyString("utf8"),
963 'IPv4': HexAdapter(GreedyBytes),
964 'IPv6': HexAdapter(GreedyBytes)}))
965
Harald Welte14105dc2021-05-31 08:48:51 +0200966 def __init__(self, fid='6ff3', sfid=None, name='EF.eDPDGId', desc='Home ePDG Identifier'):
967 super().__init__(fid, sfid=sfid, name=name, desc=desc)
968 self._tlv = EF_ePDGId.ePDGId
969
Harald Welte71290072021-04-21 10:58:24 +0200970# TS 31.102 Section 4.2.106
Harald Weltec91085e2022-02-10 18:05:45 +0100971
972
Harald Welte71290072021-04-21 10:58:24 +0200973class EF_FromPreferred(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100974 def __init__(self, fid='6ff7', sfid=None, name='EF.FromPreferred', size={1, 1},
Harald Welte71290072021-04-21 10:58:24 +0200975 desc='From Preferred'):
976 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
977 self._construct = BitStruct('rfu'/BitsRFU(7), 'from_preferred'/Bit)
978
Harald Welte790b2702021-04-11 00:01:35 +0200979######################################################################
980# DF.5GS
981######################################################################
982
983# TS 31.102 Section 4.4.11.2
Harald Weltec91085e2022-02-10 18:05:45 +0100984
985
Harald Welte790b2702021-04-11 00:01:35 +0200986class EF_5GS3GPPLOCI(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100987 def __init__(self, fid='4f01', sfid=0x01, name='EF.5GS3GPPLOCI', size={20, 20},
Harald Welte790b2702021-04-11 00:01:35 +0200988 desc='5S 3GP location information'):
989 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Weltec91085e2022-02-10 18:05:45 +0100990 upd_status_constr = Enum(
991 Byte, updated=0, not_updated=1, roaming_not_allowed=2)
Harald Welte790b2702021-04-11 00:01:35 +0200992 self._construct = Struct('5g_guti'/Bytes(13), 'last_visited_registered_tai_in_5gs'/Bytes(6),
993 '5gs_update_status'/upd_status_constr)
994
995# TS 31.102 Section 4.4.11.7
Harald Weltec91085e2022-02-10 18:05:45 +0100996
997
Harald Welte790b2702021-04-11 00:01:35 +0200998class EF_UAC_AIC(TransparentEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100999 def __init__(self, fid='4f06', sfid=0x06, name='EF.UAC_AIC', size={4, 4},
Harald Welte790b2702021-04-11 00:01:35 +02001000 desc='UAC Access Identities Configuration'):
1001 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
1002 cfg_constr = FlagsEnum(Byte, multimedia_priority_service=1,
Harald Weltec91085e2022-02-10 18:05:45 +01001003 mission_critical_service=2)
Harald Welte790b2702021-04-11 00:01:35 +02001004 self._construct = Struct('uac_access_id_config'/cfg_constr)
1005
Harald Welte14105dc2021-05-31 08:48:51 +02001006# TS 31.102 Section 4.4.11.9
Harald Weltec91085e2022-02-10 18:05:45 +01001007
1008
Harald Welte790b2702021-04-11 00:01:35 +02001009class EF_OPL5G(LinFixedEF):
1010 def __init__(self, fid='6f08', sfid=0x08, name='EF.OPL5G', desc='5GS Operator PLMN List'):
Harald Weltec91085e2022-02-10 18:05:45 +01001011 super().__init__(fid=fid, sfid=sfid,
1012 name=name, desc=desc, rec_len={10, None})
Harald Welte790b2702021-04-11 00:01:35 +02001013 self._construct = Struct('tai'/Bytes(9), 'pnn_record_id'/Int8ub)
1014
Harald Welte14105dc2021-05-31 08:48:51 +02001015# TS 31.102 Section 4.4.11.10
Harald Weltec91085e2022-02-10 18:05:45 +01001016
1017
Harald Welte14105dc2021-05-31 08:48:51 +02001018class EF_SUPI_NAI(TransparentEF):
1019 class NetworkSpecificIdentifier(TLV_IE, tag=0x80):
1020 # RFC 7542 encoded as UTF-8 string
1021 _construct = GreedyString("utf8")
Harald Weltec91085e2022-02-10 18:05:45 +01001022
Harald Welte14105dc2021-05-31 08:48:51 +02001023 class GlobalLineIdentifier(TLV_IE, tag=0x81):
1024 # TS 23.003 clause 28.16.2
1025 pass
Harald Weltec91085e2022-02-10 18:05:45 +01001026
Harald Welte14105dc2021-05-31 08:48:51 +02001027 class GlobalCableIdentifier(TLV_IE, tag=0x82):
1028 # TS 23.003 clause 28.15.2
1029 pass
Harald Weltec91085e2022-02-10 18:05:45 +01001030
Harald Welte14105dc2021-05-31 08:48:51 +02001031 class NAI_TLV_Collection(TLV_IE_Collection,
Harald Weltec91085e2022-02-10 18:05:45 +01001032 nested=[NetworkSpecificIdentifier, GlobalLineIdentifier, GlobalCableIdentifier]):
Harald Welte14105dc2021-05-31 08:48:51 +02001033 pass
1034 def __init__(self, fid='4f09', sfid=0x09, name='EF.SUPI_NAI',
Harald Weltec91085e2022-02-10 18:05:45 +01001035 desc='SUPI as Network Access Identifier'):
Harald Welte14105dc2021-05-31 08:48:51 +02001036 super().__init__(fid, sfid=sfid, name=name, desc=desc)
1037 self._tlv = EF_SUPI_NAI.NAI_TLV_Collection
1038
Harald Weltec91085e2022-02-10 18:05:45 +01001039
Harald Welte14105dc2021-05-31 08:48:51 +02001040class EF_TN3GPPSNN(TransparentEF):
1041 class ServingNetworkName(BER_TLV_IE, tag=0x80):
1042 _construct = GreedyString("utf8")
1043 def __init__(self, fid='4f0c', sfid=0x0c, name='EF.TN3GPPSNN',
Harald Weltec91085e2022-02-10 18:05:45 +01001044 desc='Trusted non-3GPP Serving network names list'):
Harald Welte14105dc2021-05-31 08:48:51 +02001045 super().__init__(fid, sfid=sfid, name=name, desc=desc)
1046 self._tlv = EF_TN3GPPSNN.ServingNetworkName
1047
Harald Welte3990ebb2021-04-20 23:55:14 +02001048# TS 31.102 Section 4.4.5
Harald Weltec91085e2022-02-10 18:05:45 +01001049
1050
Harald Welte3990ebb2021-04-20 23:55:14 +02001051class DF_WLAN(CardDF):
1052 def __init__(self, fid='5f40', name='DF.WLAN', desc='Files for WLAN purpose'):
1053 super().__init__(fid=fid, name=name, desc=desc)
1054 files = [
1055 TransparentEF('4f41', 0x01, 'EF.Pseudo', 'Pseudonym'),
Harald Weltec91085e2022-02-10 18:05:45 +01001056 TransparentEF('4f42', 0x02, 'EF.UPLMNWLAN',
1057 'User controlled PLMN selector for I-WLAN Access'),
1058 TransparentEF('4f43', 0x03, 'EF.OPLMNWLAN',
1059 'Operator controlled PLMN selector for I-WLAN Access'),
1060 LinFixedEF('4f44', 0x04, 'EF.UWSIDL',
1061 'User controlled WLAN Specific Identifier List'),
1062 LinFixedEF('4f45', 0x05, 'EF.OWSIDL',
1063 'Operator controlled WLAN Specific Identifier List'),
1064 TransparentEF('4f46', 0x06, 'EF.WRI',
1065 'WLAN Reauthentication Identity'),
1066 LinFixedEF('4f47', 0x07, 'EF.HWSIDL',
1067 'Home I-WLAN Specific Identifier List'),
1068 TransparentEF('4f48', 0x08, 'EF.WEHPLMNPI',
1069 'I-WLAN Equivalent HPLMN Presentation Indication'),
1070 TransparentEF('4f49', 0x09, 'EF.WHPI',
1071 'I-WLAN HPLMN Priority Indication'),
1072 TransparentEF('4f4a', 0x0a, 'EF.WLRPLMN',
1073 'I-WLAN Last Registered PLMN'),
1074 TransparentEF('4f4b', 0x0b, 'EF.HPLMNDAI',
1075 'HPLMN Direct Access Indicator'),
1076 ]
Harald Welte3990ebb2021-04-20 23:55:14 +02001077 self.add_files(files)
1078
1079# TS 31.102 Section 4.4.6
Harald Weltec91085e2022-02-10 18:05:45 +01001080
1081
Harald Welte3990ebb2021-04-20 23:55:14 +02001082class DF_HNB(CardDF):
1083 def __init__(self, fid='5f50', name='DF.HNB', desc='Files for HomeNodeB purpose'):
1084 super().__init__(fid=fid, name=name, desc=desc)
1085 files = [
1086 LinFixedEF('4f01', 0x01, 'EF.ACSGL', 'Allowed CSG Lists'),
1087 LinFixedEF('4f02', 0x02, 'EF.CSGTL', 'CSG Types'),
1088 LinFixedEF('4f03', 0x03, 'EF.HNBN', 'Home NodeB Name'),
1089 LinFixedEF('4f04', 0x04, 'EF.OCSGL', 'Operator CSG Lists'),
1090 LinFixedEF('4f05', 0x05, 'EF.OCSGT', 'Operator CSG Type'),
1091 LinFixedEF('4f06', 0x06, 'EF.OHNBN', 'Operator Home NodeB Name'),
Harald Weltec91085e2022-02-10 18:05:45 +01001092 ]
Harald Welte3990ebb2021-04-20 23:55:14 +02001093 self.add_files(files)
1094
1095# TS 31.102 Section 4.4.8
Harald Weltec91085e2022-02-10 18:05:45 +01001096
1097
Harald Welte3990ebb2021-04-20 23:55:14 +02001098class DF_ProSe(CardDF):
1099 def __init__(self, fid='5f90', name='DF.ProSe', desc='Files for ProSe purpose'):
1100 super().__init__(fid=fid, name=name, desc=desc)
1101 files = [
Harald Weltec91085e2022-02-10 18:05:45 +01001102 LinFixedEF('4f01', 0x01, 'EF.PROSE_MON',
1103 'ProSe Monitoring Parameters'),
1104 LinFixedEF('4f02', 0x02, 'EF.PROSE_ANN',
1105 'ProSe Announcing Parameters'),
Harald Welte3990ebb2021-04-20 23:55:14 +02001106 LinFixedEF('4f03', 0x03, 'EF.PROSEFUNC', 'HPLMN ProSe Function'),
Harald Weltec91085e2022-02-10 18:05:45 +01001107 TransparentEF('4f04', 0x04, 'EF.PROSE_RADIO_COM',
1108 'ProSe Direct Communication Radio Parameters'),
1109 TransparentEF('4f05', 0x05, 'EF.PROSE_RADIO_MON',
1110 'ProSe Direct Discovery Monitoring Radio Parameters'),
1111 TransparentEF('4f06', 0x06, 'EF.PROSE_RADIO_ANN',
1112 'ProSe Direct Discovery Announcing Radio Parameters'),
1113 LinFixedEF('4f07', 0x07, 'EF.PROSE_POLICY',
1114 'ProSe Policy Parameters'),
Harald Welte3990ebb2021-04-20 23:55:14 +02001115 LinFixedEF('4f08', 0x08, 'EF.PROSE_PLMN', 'ProSe PLMN Parameters'),
1116 TransparentEF('4f09', 0x09, 'EF.PROSE_GC', 'ProSe Group Counter'),
1117 TransparentEF('4f10', 0x10, 'EF.PST', 'ProSe Service Table'),
Harald Weltec91085e2022-02-10 18:05:45 +01001118 TransparentEF('4f11', 0x11, 'EF.UIRC',
1119 'ProSe UsageInformationReportingConfiguration'),
1120 LinFixedEF('4f12', 0x12, 'EF.PROSE_GM_DISCOVERY',
1121 'ProSe Group Member Discovery Parameters'),
1122 LinFixedEF('4f13', 0x13, 'EF.PROSE_RELAY',
1123 'ProSe Relay Parameters'),
1124 TransparentEF('4f14', 0x14, 'EF.PROSE_RELAY_DISCOVERY',
1125 'ProSe Relay Discovery Parameters'),
1126 ]
Harald Welte3990ebb2021-04-20 23:55:14 +02001127 self.add_files(files)
1128
Harald Weltec91085e2022-02-10 18:05:45 +01001129
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001130class DF_USIM_5GS(CardDF):
1131 def __init__(self, fid='5FC0', name='DF.5GS', desc='5GS related files'):
1132 super().__init__(fid=fid, name=name, desc=desc)
1133 files = [
Harald Weltec91085e2022-02-10 18:05:45 +01001134 # I'm looking at 31.102 R16.6
1135 EF_5GS3GPPLOCI(),
1136 EF_5GS3GPPLOCI('4f02', 0x02, 'EF.5GSN3GPPLOCI',
1137 '5GS non-3GPP location information'),
1138 EF_5GS3GPPNSC(),
1139 EF_5GS3GPPNSC('4f04', 0x04, 'EF.5GSN3GPPNSC',
1140 '5GS non-3GPP Access NAS Security Context'),
1141 EF_5GAUTHKEYS(),
1142 EF_UAC_AIC(),
1143 EF_SUCI_Calc_Info(),
1144 EF_OPL5G(),
1145 EF_SUPI_NAI(),
1146 TransparentEF('4F0A', 0x0a, 'EF.Routing_Indicator',
1147 'Routing Indicator', size={4, 4}),
1148 TransparentEF('4F0B', 0x0b, 'EF.URSP',
1149 'UE Route Selector Policies per PLMN'),
1150 EF_TN3GPPSNN(),
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001151 ]
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001152 self.add_files(files)
1153
Harald Weltec91085e2022-02-10 18:05:45 +01001154
Harald Welteb2edd142021-01-08 23:29:35 +01001155class ADF_USIM(CardADF):
1156 def __init__(self, aid='a0000000871002', name='ADF.USIM', fid=None, sfid=None,
1157 desc='USIM Application'):
1158 super().__init__(aid=aid, fid=fid, sfid=sfid, name=name, desc=desc)
Harald Welte15fae982021-04-10 10:22:27 +02001159 # add those commands to the general commands of a TransparentEF
1160 self.shell_commands += [self.AddlShellCommands()]
Harald Welteb2edd142021-01-08 23:29:35 +01001161
1162 files = [
Harald Weltec91085e2022-02-10 18:05:45 +01001163 EF_LI(sfid=0x02),
1164 EF_IMSI(sfid=0x07),
1165 EF_Keys(),
1166 EF_Keys('6f09', 0x09, 'EF.KeysPS',
1167 desc='Ciphering and Integrity Keys for PS domain'),
1168 EF_xPLMNwAcT('6f60', 0x0a, 'EF.PLMNwAcT',
1169 'User controlled PLMN Selector with Access Technology'),
1170 EF_HPPLMN(),
1171 EF_ACMmax(),
1172 EF_UServiceTable('6f38', 0x04, 'EF.UST', 'USIM Service Table', size={
1173 1, 17}, table=EF_UST_map),
1174 CyclicEF('6f39', None, 'EF.ACM',
1175 'Accumulated call meter', rec_len={3, 3}),
1176 TransparentEF('6f3e', None, 'EF.GID1', 'Group Identifier Level 1'),
1177 TransparentEF('6f3f', None, 'EF.GID2', 'Group Identifier Level 2'),
1178 EF_SPN(),
1179 TransparentEF('6f41', None, 'EF.PUCT',
1180 'Price per unit and currency table', size={5, 5}),
1181 EF_CBMI(),
1182 EF_ACC(sfid=0x06),
1183 EF_PLMNsel('6f7b', 0x0d, 'EF.FPLMN',
1184 'Forbidden PLMNs', size={12, None}),
1185 EF_LOCI(),
1186 EF_AD(),
1187 EF_CBMID(sfid=0x0e),
1188 EF_ECC(),
1189 EF_CBMIR(),
1190 EF_PSLOCI(),
1191 EF_ADN('6f3b', None, 'EF.FDN', 'Fixed Dialling Numbers'),
1192 EF_SMS('6f3c', None),
1193 EF_MSISDN(),
1194 EF_SMSP(),
1195 EF_SMSS(),
1196 EF_ADN('6f49', None, 'EF.SDN', 'Service Dialling Numbers'),
1197 EF_EXT('6f4b', None, 'EF.EXT2', 'Extension2 (FDN)'),
1198 EF_EXT('6f4c', None, 'EF.EXT3', 'Extension2 (SDN)'),
1199 EF_SMSR(),
1200 EF_ICI(),
1201 EF_OCI(),
1202 EF_ICT(),
1203 EF_ICT('6f83', None, 'EF.OCT', 'Outgoing Call Timer'),
1204 EF_EXT('6f4e', None, 'EF.EXT5', 'Extension5 (ICI/OCI/MSISDN)'),
1205 EF_CCP2(),
1206 EF_eMLPP(),
1207 EF_AAeM(),
1208 # EF_Hiddenkey
1209 EF_ADN('6f4d', None, 'EF.BDN', 'Barred Dialling Numbers'),
1210 EF_EXT('6f55', None, 'EF.EXT4', 'Extension4 (BDN/SSC)'),
1211 EF_CMI(),
1212 EF_UServiceTable('6f56', 0x05, 'EF.EST', 'Enabled Services Table', size={
1213 1, None}, table=EF_EST_map),
1214 EF_ACL(),
1215 EF_DCK(),
1216 EF_CNL(),
1217 EF_START_HFN(),
1218 EF_THRESHOLD(),
1219 EF_xPLMNwAcT('6f61', 0x11, 'EF.OPLMNwAcT',
1220 'User controlled PLMN Selector with Access Technology'),
1221 EF_ARR('6f06', 0x17),
1222 TransparentEF('6fc4', None, 'EF.NETPAR', 'Network Parameters'),
1223 EF_PNN('6fc5', 0x19),
1224 EF_OPL(),
1225 EF_ADN('6fc7', None, 'EF.MBDN', 'Mailbox Dialling Numbers'),
1226 EF_MBI(),
1227 EF_MWIS(),
1228 EF_ADN('6fcb', None, 'EF.CFIS',
1229 'Call Forwarding Indication Status'),
1230 EF_EXT('6fcc', None, 'EF.EXT7', 'Extension7 (CFIS)'),
1231 TransparentEF('6fcd', None, 'EF.SPDI',
1232 'Service Provider Display Information'),
1233 EF_MMSN(),
1234 EF_EXT('6fcf', None, 'EF.EXT8', 'Extension8 (MMSN)'),
1235 EF_MMSICP(),
1236 EF_MMSUP(),
1237 EF_MMSUCP(),
1238 EF_NIA(),
1239 EF_VGCS(),
1240 EF_VGCSS(),
1241 EF_VGCS('6fb3', None, 'EF.VBS', 'Voice Broadcast Service'),
1242 EF_VGCSS('6fb4', None, 'EF.VBSS',
1243 'Voice Broadcast Service Status'),
1244 EF_VGCSCA(),
1245 EF_VGCSCA('6fd5', None, 'EF.VBCSCA',
1246 'Voice Broadcast Service Ciphering Algorithm'),
1247 EF_GBABP(),
1248 EF_MSK(),
1249 EF_MUK(),
1250 EF_GBANL(),
1251 EF_PLMNsel('6fd9', 0x1d, 'EF.EHPLMN',
1252 'Equivalent HPLMN', size={12, None}),
1253 EF_EHPLMNPI(),
1254 EF_NAFKCA(),
1255 TransparentEF('6fde', None, 'EF.SPNI',
1256 'Service Provider Name Icon'),
1257 LinFixedEF('6fdf', None, 'EF.PNNI', 'PLMN Network Name Icon'),
1258 EF_NCP_IP(),
1259 EF_EPSLOCI('6fe3', 0x1e, 'EF.EPSLOCI', 'EPS location information'),
1260 EF_EPSNSC(),
1261 TransparentEF('6fe6', None, 'EF.UFC',
1262 'USAT Facility Control', size={1, 16}),
1263 TransparentEF('6fe8', None, 'EF.NASCONFIG',
1264 'Non Access Stratum Configuration'),
1265 # UICC IARI (only in cards that have no ISIM)
1266 EF_PWS(),
1267 LinFixedEF('6fed', None, 'EF.FDNURI',
1268 'Fixed Dialling Numbers URI'),
1269 LinFixedEF('6fee', None, 'EF.BDNURI',
1270 'Barred Dialling Numbers URI'),
1271 LinFixedEF('6fef', None, 'EF.SDNURI',
1272 'Service Dialling Numbers URI'),
1273 EF_IPS(),
1274 EF_ePDGId(),
1275 # FIXME: from EF_ePDGSelection onwards
1276 EF_FromPreferred(),
1277 # FIXME: DF_SoLSA
1278 # FIXME: DF_PHONEBOOK
1279 # FIXME: DF_GSM_ACCESS
1280 DF_WLAN(),
1281 DF_HNB(),
1282 DF_ProSe(),
1283 # FIXME: DF_ACDC
1284 # FIXME: DF_TV
1285 DF_USIM_5GS(),
1286 ]
Harald Welteb2edd142021-01-08 23:29:35 +01001287 self.add_files(files)
1288
1289 def decode_select_response(self, data_hex):
Philipp Maier5998a3a2021-11-16 15:16:39 +01001290 return pySim.ts_102_221.CardProfileUICC.decode_select_response(data_hex)
Harald Welteb2edd142021-01-08 23:29:35 +01001291
Harald Welte15fae982021-04-10 10:22:27 +02001292 @with_default_category('Application-Specific Commands')
1293 class AddlShellCommands(CommandSet):
1294 def __init__(self):
1295 super().__init__()
1296
1297 authenticate_parser = argparse.ArgumentParser()
1298 authenticate_parser.add_argument('rand', help='Random challenge')
1299 authenticate_parser.add_argument('autn', help='Authentication Nonce')
1300 #authenticate_parser.add_argument('--context', help='Authentication context', default='3G')
Harald Weltec91085e2022-02-10 18:05:45 +01001301
Harald Welte15fae982021-04-10 10:22:27 +02001302 @cmd2.with_argparser(authenticate_parser)
1303 def do_authenticate(self, opts):
1304 """Perform Authentication and Key Agreement (AKA)."""
1305 (data, sw) = self._cmd.card._scc.authenticate(opts.rand, opts.autn)
1306 self._cmd.poutput_json(data)
1307
Harald Welte846a8982021-10-08 15:47:16 +02001308 def do_terminal_profile(self, arg):
1309 """Send a TERMINAL PROFILE command to the card."""
1310 (data, sw) = self._cmd.card._scc.terminal_profile(arg)
1311 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
Harald Welte15fae982021-04-10 10:22:27 +02001312
Harald Welte7cb94e42021-10-08 15:47:57 +02001313 def do_envelope(self, arg):
1314 """Send an ENVELOPE command to the card."""
1315 (data, sw) = self._cmd.card._scc.envelope(arg)
1316 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
1317
1318 def do_envelope_sms(self, arg):
1319 """Send an ENVELOPE command to the card."""
1320 tpdu_ie = SMS_TPDU()
1321 tpdu_ie.from_bytes(h2b(arg))
Harald Weltec91085e2022-02-10 18:05:45 +01001322 dev_ids = DeviceIdentities(
1323 decoded={'source_dev_id': 'network', 'dest_dev_id': 'uicc'})
Harald Welte7cb94e42021-10-08 15:47:57 +02001324 sms_dl = SMSPPDownload(children=[dev_ids, tpdu_ie])
1325 (data, sw) = self._cmd.card._scc.envelope(b2h(sms_dl.to_tlv()))
1326 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
1327
Harald Welte15fae982021-04-10 10:22:27 +02001328
Harald Welteb2edd142021-01-08 23:29:35 +01001329# TS 31.102 Section 7.3
1330sw_usim = {
1331 'Security management': {
1332 '9862': 'Authentication error, incorrect MAC',
1333 '9864': 'Authentication error, security context not supported',
1334 '9865': 'Key freshness failure',
1335 '9866': 'Authentication error, no memory space available',
1336 '9867': 'Authentication error, no memory space available in EF MUK',
1337 }
1338}
1339
Harald Weltec91085e2022-02-10 18:05:45 +01001340
Philipp Maier57f65ee2021-10-18 14:09:02 +02001341class CardApplicationUSIM(CardApplication):
1342 def __init__(self):
Harald Weltec91085e2022-02-10 18:05:45 +01001343 super().__init__('USIM', adf=ADF_USIM(), sw=sw_usim)