blob: 5bec44626b2d1a96687d3598945f51c9c77f5cc2 [file] [log] [blame]
Harald Weltef44256c2021-10-14 15:53:39 +02001# coding=utf-8
Harald Welte0489ae62023-05-24 10:28:34 +02002"""Utilities / Functions related to sysmocom SJA2/SJA5 cards
Harald Weltef44256c2021-10-14 15:53:39 +02003
Harald Welte0489ae62023-05-24 10:28:34 +02004(C) 2021-2023 by Harald Welte <laforge@osmocom.org>
Harald Weltef44256c2021-10-14 15:53:39 +02005
6This program is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program. If not, see <http://www.gnu.org/licenses/>.
18"""
19
20from pytlv.TLV import *
21from struct import pack, unpack
22from pySim.utils import *
23from pySim.filesystem import *
Harald Welte531894d2023-07-11 19:11:11 +020024from pySim.runtime import RuntimeState
Harald Weltef44256c2021-10-14 15:53:39 +020025from pySim.ts_102_221 import CardProfileUICC
26from pySim.construct import *
27from construct import *
28import pySim
29
30key_type2str = {
31 0: 'kic',
32 1: 'kid',
33 2: 'kik',
34 3: 'any',
35}
36
37key_algo2str = {
38 0: 'des',
39 1: 'aes'
40}
41
42mac_length = {
43 0: 8,
44 1: 4
45}
46
Harald Weltec91085e2022-02-10 18:05:45 +010047
Harald Weltef44256c2021-10-14 15:53:39 +020048class EF_PIN(TransparentEF):
Harald Weltedb1684d2023-12-28 15:06:11 +010049 _test_de_encode = [
50 ( 'f1030331323334ffffffff0a0a3132333435363738',
51 { 'state': { 'valid': True, 'change_able': True, 'unblock_able': True, 'disable_able': True,
52 'not_initialized': False, 'disabled': True },
53 'attempts_remaining': 3, 'maximum_attempts': 3, 'pin': '31323334',
54 'puk': { 'attempts_remaining': 10, 'maximum_attempts': 10, 'puk': '3132333435363738' }
55 } ),
56 ( 'f003039999999999999999',
57 { 'state': { 'valid': True, 'change_able': True, 'unblock_able': True, 'disable_able': True,
58 'not_initialized': False, 'disabled': False },
59 'attempts_remaining': 3, 'maximum_attempts': 3, 'pin': '9999999999999999',
60 'puk': None } ),
61 ]
62 def __init__(self, fid='6f01', name='EF.CHV1'):
Harald Weltef44256c2021-10-14 15:53:39 +020063 super().__init__(fid, name=name, desc='%s PIN file' % name)
Harald Weltedb1684d2023-12-28 15:06:11 +010064 StateByte = FlagsEnum(Byte, disabled=1, not_initialized=2, disable_able=0x10, unblock_able=0x20,
65 change_able=0x40, valid=0x80)
66 PukStruct = Struct('attempts_remaining'/Int8ub,
67 'maximum_attempts'/Int8ub,
68 'puk'/HexAdapter(Rpad(Bytes(8))))
69 self._construct = Struct('state'/StateByte,
70 'attempts_remaining'/Int8ub,
71 'maximum_attempts'/Int8ub,
72 'pin'/HexAdapter(Rpad(Bytes(8))),
73 'puk'/Optional(PukStruct))
Harald Weltef44256c2021-10-14 15:53:39 +020074
Harald Weltec91085e2022-02-10 18:05:45 +010075
Harald Weltef44256c2021-10-14 15:53:39 +020076class EF_MILENAGE_CFG(TransparentEF):
Harald Welte7be68b22023-11-02 00:19:53 +010077 _test_de_encode = [
78 ( '40002040600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000020000000000000000000000000000000400000000000000000000000000000008',
79 {"r1": 64, "r2": 0, "r3": 32, "r4": 64, "r5": 96, "c1": "00000000000000000000000000000000", "c2":
80 "00000000000000000000000000000001", "c3": "00000000000000000000000000000002", "c4":
81 "00000000000000000000000000000004", "c5": "00000000000000000000000000000008"} ),
82 ]
Harald Weltef44256c2021-10-14 15:53:39 +020083 def __init__(self, fid='6f21', name='EF.MILENAGE_CFG', desc='Milenage connfiguration'):
84 super().__init__(fid, name=name, desc=desc)
Harald Welte7be68b22023-11-02 00:19:53 +010085 self._construct = Struct('r1'/Int8ub, 'r2'/Int8ub, 'r3'/Int8ub, 'r4'/Int8ub, 'r5'/Int8ub,
86 'c1'/HexAdapter(Bytes(16)),
87 'c2'/HexAdapter(Bytes(16)),
88 'c3'/HexAdapter(Bytes(16)),
89 'c4'/HexAdapter(Bytes(16)),
90 'c5'/HexAdapter(Bytes(16)))
Harald Weltec91085e2022-02-10 18:05:45 +010091
Harald Weltef44256c2021-10-14 15:53:39 +020092
93class EF_0348_KEY(LinFixedEF):
94 def __init__(self, fid='6f22', name='EF.0348_KEY', desc='TS 03.48 OTA Keys'):
Harald Welte99e4cc02022-07-21 15:25:47 +020095 super().__init__(fid, name=name, desc=desc, rec_len=(27, 35))
Harald Welte954ce952023-05-27 20:08:09 +020096 KeyLenAndType = BitStruct('mac_length'/Mapping(Bit, {8:0, 4:1}),
97 'algorithm'/Enum(Bit, des=0, aes=1),
98 'key_length'/MultiplyAdapter(BitsInteger(3), 8),
99 '_rfu'/BitsRFU(1),
100 'key_type'/Enum(BitsInteger(2), kic=0, kid=1, kik=2, any=3))
101 self._construct = Struct('security_domain'/Int8ub,
102 'key_set_version'/Int8ub,
103 'key_len_and_type'/KeyLenAndType,
104 'key'/HexAdapter(Bytes(this.key_len_and_type.key_length)))
Harald Weltec91085e2022-02-10 18:05:45 +0100105
Harald Weltef44256c2021-10-14 15:53:39 +0200106
107class EF_0348_COUNT(LinFixedEF):
Harald Welte7be68b22023-11-02 00:19:53 +0100108 _test_de_encode = [
109 ( 'fe010000000000', {"sec_domain": 254, "key_set_version": 1, "counter": "0000000000"} ),
110 ]
Harald Weltef44256c2021-10-14 15:53:39 +0200111 def __init__(self, fid='6f23', name='EF.0348_COUNT', desc='TS 03.48 OTA Counters'):
Harald Welte99e4cc02022-07-21 15:25:47 +0200112 super().__init__(fid, name=name, desc=desc, rec_len=(7, 7))
Harald Welte7be68b22023-11-02 00:19:53 +0100113 self._construct = Struct('sec_domain'/Int8ub,
114 'key_set_version'/Int8ub,
115 'counter'/HexAdapter(Bytes(5)))
Harald Weltef44256c2021-10-14 15:53:39 +0200116
Harald Weltec91085e2022-02-10 18:05:45 +0100117
Harald Weltef44256c2021-10-14 15:53:39 +0200118class EF_SIM_AUTH_COUNTER(TransparentEF):
119 def __init__(self, fid='af24', name='EF.SIM_AUTH_COUNTER'):
120 super().__init__(fid, name=name, desc='Number of remaining RUN GSM ALGORITHM executions')
121 self._construct = Struct('num_run_gsm_algo_remain'/Int32ub)
122
Harald Weltec91085e2022-02-10 18:05:45 +0100123
Harald Weltef44256c2021-10-14 15:53:39 +0200124class EF_GP_COUNT(LinFixedEF):
Harald Welte7be68b22023-11-02 00:19:53 +0100125 _test_de_encode = [
126 ( '0070000000', {"sec_domain": 0, "key_set_version": 112, "counter": 0, "rfu": 0} ),
127 ]
Harald Weltef44256c2021-10-14 15:53:39 +0200128 def __init__(self, fid='6f26', name='EF.GP_COUNT', desc='GP SCP02 Counters'):
Harald Welte99e4cc02022-07-21 15:25:47 +0200129 super().__init__(fid, name=name, desc=desc, rec_len=(5, 5))
Harald Welte7be68b22023-11-02 00:19:53 +0100130 self._construct = Struct('sec_domain'/Int8ub,
131 'key_set_version'/Int8ub,
132 'counter'/Int16ub,
133 'rfu'/Int8ub)
Harald Weltec91085e2022-02-10 18:05:45 +0100134
Harald Weltef44256c2021-10-14 15:53:39 +0200135class EF_GP_DIV_DATA(LinFixedEF):
136 def __init__(self, fid='6f27', name='EF.GP_DIV_DATA', desc='GP SCP02 key diversification data'):
Harald Welte99e4cc02022-07-21 15:25:47 +0200137 super().__init__(fid, name=name, desc=desc, rec_len=(12, 12))
Harald Weltec91085e2022-02-10 18:05:45 +0100138
Harald Weltef6b37af2023-01-24 15:42:26 +0100139 def _decode_record_bin(self, raw_bin_data, **kwargs):
Harald Weltef44256c2021-10-14 15:53:39 +0200140 u = unpack('!BB8s', raw_bin_data)
141 return {'sec_domain': u[0], 'key_set_version': u[1], 'key_div_data': u[2].hex()}
142
Harald Weltec91085e2022-02-10 18:05:45 +0100143
Harald Weltef44256c2021-10-14 15:53:39 +0200144class EF_SIM_AUTH_KEY(TransparentEF):
Harald Welte7be68b22023-11-02 00:19:53 +0100145 _test_de_encode = [
146 ( '14000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f',
Harald Welte45477a72023-11-03 01:33:06 +0100147 {"cfg": {"sres_deriv_func": 1, "use_opc_instead_of_op": True, "algorithm": "milenage"}, "key":
Harald Welte7be68b22023-11-02 00:19:53 +0100148 "000102030405060708090a0b0c0d0e0f", "op_opc": "101112131415161718191a1b1c1d1e1f"} ),
149 ]
Harald Weltef44256c2021-10-14 15:53:39 +0200150 def __init__(self, fid='6f20', name='EF.SIM_AUTH_KEY'):
151 super().__init__(fid, name=name, desc='USIM authentication key')
Harald Weltecfa30152022-07-22 17:12:27 +0200152 CfgByte = BitStruct(Padding(2),
Harald Welte45477a72023-11-03 01:33:06 +0100153 'sres_deriv_func'/Mapping(Bit, {1:0, 2:1}),
154 'use_opc_instead_of_op'/Flag,
Harald Weltef44256c2021-10-14 15:53:39 +0200155 'algorithm'/Enum(Nibble, milenage=4, comp128v1=1, comp128v2=2, comp128v3=3))
156 self._construct = Struct('cfg'/CfgByte,
Harald Welte3c98d5e2022-07-20 07:40:05 +0200157 'key'/HexAdapter(Bytes(16)),
Philipp Maier4f888a02022-12-02 12:30:12 +0100158 'op_opc' /HexAdapter(Bytes(16)))
Harald Weltef44256c2021-10-14 15:53:39 +0200159
Harald Weltec91085e2022-02-10 18:05:45 +0100160
Harald Weltef44256c2021-10-14 15:53:39 +0200161class DF_SYSTEM(CardDF):
162 def __init__(self):
163 super().__init__(fid='a515', name='DF.SYSTEM', desc='CardOS specifics')
164 files = [
165 EF_PIN('6f01', 'EF.CHV1'),
166 EF_PIN('6f81', 'EF.CHV2'),
167 EF_PIN('6f0a', 'EF.ADM1'),
168 EF_PIN('6f0b', 'EF.ADM2'),
169 EF_PIN('6f0c', 'EF.ADM3'),
170 EF_PIN('6f0d', 'EF.ADM4'),
171 EF_MILENAGE_CFG(),
172 EF_0348_KEY(),
173 EF_SIM_AUTH_COUNTER(),
174 EF_SIM_AUTH_KEY(),
175 EF_0348_COUNT(),
176 EF_GP_COUNT(),
177 EF_GP_DIV_DATA(),
Harald Weltec91085e2022-02-10 18:05:45 +0100178 ]
Harald Weltef44256c2021-10-14 15:53:39 +0200179 self.add_files(files)
180
181 def decode_select_response(self, resp_hex):
Philipp Maier5998a3a2021-11-16 15:16:39 +0100182 return pySim.ts_102_221.CardProfileUICC.decode_select_response(resp_hex)
Harald Weltef44256c2021-10-14 15:53:39 +0200183
Harald Weltec91085e2022-02-10 18:05:45 +0100184
Harald Weltef44256c2021-10-14 15:53:39 +0200185class EF_USIM_SQN(TransparentEF):
Harald Welte7be68b22023-11-02 00:19:53 +0100186 _test_de_encode = [
187 ( 'd503000200000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
Harald Welte45477a72023-11-03 01:33:06 +0100188 {"flag1": {"skip_next_sqn_check": True, "delta_max_check": True, "age_limit_check": False, "sqn_check": True,
189 "ind_len": 5}, "flag2": {"rfu": 0, "dont_clear_amf_for_macs": False, "aus_concealed": True,
190 "autn_concealed": True}, "delta_max": 8589934592, "age_limit":
Harald Welte7be68b22023-11-02 00:19:53 +0100191 8589934592, "freshness": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
192 0, 0, 0, 0, 0, 0, 0, 0]} ),
193 ]
Harald Weltef44256c2021-10-14 15:53:39 +0200194 def __init__(self, fid='af30', name='EF.USIM_SQN'):
195 super().__init__(fid, name=name, desc='SQN parameters for AKA')
Harald Welte45477a72023-11-03 01:33:06 +0100196 Flag1 = BitStruct('skip_next_sqn_check'/Flag, 'delta_max_check'/Flag,
197 'age_limit_check'/Flag, 'sqn_check'/Flag,
Harald Weltef44256c2021-10-14 15:53:39 +0200198 'ind_len'/BitsInteger(4))
Harald Welte45477a72023-11-03 01:33:06 +0100199 Flag2 = BitStruct('rfu'/BitsRFU(5), 'dont_clear_amf_for_macs'/Flag,
200 'aus_concealed'/Flag, 'autn_concealed'/Flag)
Harald Weltef44256c2021-10-14 15:53:39 +0200201 self._construct = Struct('flag1'/Flag1, 'flag2'/Flag2,
Harald Weltec91085e2022-02-10 18:05:45 +0100202 'delta_max' /
203 BytesInteger(6), 'age_limit'/BytesInteger(6),
Harald Welteeb458382021-10-16 10:44:23 +0200204 'freshness'/GreedyRange(BytesInteger(6)))
Harald Weltef44256c2021-10-14 15:53:39 +0200205
Harald Weltec91085e2022-02-10 18:05:45 +0100206
Harald Weltef44256c2021-10-14 15:53:39 +0200207class EF_USIM_AUTH_KEY(TransparentEF):
208 def __init__(self, fid='af20', name='EF.USIM_AUTH_KEY'):
209 super().__init__(fid, name=name, desc='USIM authentication key')
Harald Welte03650582023-05-29 21:07:24 +0200210 Algorithm = Enum(Nibble, milenage=4, sha1_aka=5, tuak=6, xor=15)
Harald Welte45477a72023-11-03 01:33:06 +0100211 CfgByte = BitStruct(Padding(1), 'only_4bytes_res_in_3g'/Flag,
212 'sres_deriv_func_in_2g'/Mapping(Bit, {1:0, 2:1}),
Harald Welte03650582023-05-29 21:07:24 +0200213 'use_opc_instead_of_op'/Mapping(Bit, {False:0, True:1}),
214 'algorithm'/Algorithm)
Harald Weltef44256c2021-10-14 15:53:39 +0200215 self._construct = Struct('cfg'/CfgByte,
Harald Welte3c98d5e2022-07-20 07:40:05 +0200216 'key'/HexAdapter(Bytes(16)),
Philipp Maier4f888a02022-12-02 12:30:12 +0100217 'op_opc' /HexAdapter(Bytes(16)))
Harald Welte03650582023-05-29 21:07:24 +0200218 # TUAK has a rather different layout for the data, so we define a different
219 # construct below and use explicit _{decode,encode}_bin() methods for separating
220 # the TUAK and non-TUAK situation
221 CfgByteTuak = BitStruct(Padding(1),
222 'key_length'/Mapping(Bit, {128:0, 256:1}),
Harald Welte45477a72023-11-03 01:33:06 +0100223 'sres_deriv_func_in_2g'/Mapping(Bit, {1:0, 2:1}),
Harald Welte03650582023-05-29 21:07:24 +0200224 'use_opc_instead_of_op'/Mapping(Bit, {False:0, True:1}),
225 'algorithm'/Algorithm)
226 TuakCfgByte = BitStruct(Padding(1),
227 'ck_and_ik_size'/Mapping(Bit, {128:0, 256:1}),
228 'mac_size'/Mapping(BitsInteger(3), {64:0, 128:1, 256:2}),
229 'res_size'/Mapping(BitsInteger(3), {32:0, 64:1, 128:2, 256:3}))
230 self._constr_tuak = Struct('cfg'/CfgByteTuak,
231 'tuak_cfg'/TuakCfgByte,
232 'num_of_keccak_iterations'/Int8ub,
233 'op_opc'/HexAdapter(Bytes(32)),
Harald Welte19b4a972023-06-08 17:18:31 +0200234 'k'/HexAdapter(Bytes(this.cfg.key_length//8)))
Harald Welte03650582023-05-29 21:07:24 +0200235
236 def _decode_bin(self, raw_bin_data: bytearray) -> dict:
237 if raw_bin_data[0] & 0x0F == 0x06:
238 return parse_construct(self._constr_tuak, raw_bin_data)
239 else:
240 return parse_construct(self._construct, raw_bin_data)
241
242 def _encode_bin(self, abstract_data: dict) -> bytearray:
243 if abstract_data['cfg']['algorithm'] == 'tuak':
Harald Weltea5eb9242023-12-23 10:20:20 +0100244 return build_construct(self._constr_tuak, abstract_data)
Harald Welte03650582023-05-29 21:07:24 +0200245 else:
Harald Weltea5eb9242023-12-23 10:20:20 +0100246 return build_construct(self._construct, abstract_data)
Harald Weltec91085e2022-02-10 18:05:45 +0100247
248
Harald Weltef44256c2021-10-14 15:53:39 +0200249class EF_USIM_AUTH_KEY_2G(TransparentEF):
Harald Welte7be68b22023-11-02 00:19:53 +0100250 _test_de_encode = [
251 ( '14000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f',
Harald Welte45477a72023-11-03 01:33:06 +0100252 {"cfg": {"only_4bytes_res_in_3g": False, "sres_deriv_func_in_2g": 1, "use_opc_instead_of_op": True,
Harald Welte7be68b22023-11-02 00:19:53 +0100253 "algorithm": "milenage"}, "key": "000102030405060708090a0b0c0d0e0f", "op_opc":
254 "101112131415161718191a1b1c1d1e1f"} ),
255 ]
Harald Weltef44256c2021-10-14 15:53:39 +0200256 def __init__(self, fid='af22', name='EF.USIM_AUTH_KEY_2G'):
257 super().__init__(fid, name=name, desc='USIM authentication key in 2G context')
Harald Welte45477a72023-11-03 01:33:06 +0100258 CfgByte = BitStruct(Padding(1), 'only_4bytes_res_in_3g'/Flag,
259 'sres_deriv_func_in_2g'/Mapping(Bit, {1:0, 2:1}),
260 'use_opc_instead_of_op'/Flag,
Harald Welte557c1362023-05-29 15:26:22 +0200261 'algorithm'/Enum(Nibble, milenage=4, comp128v1=1, comp128v2=2, comp128v3=3, xor=14))
Harald Weltef44256c2021-10-14 15:53:39 +0200262 self._construct = Struct('cfg'/CfgByte,
Harald Welte3c98d5e2022-07-20 07:40:05 +0200263 'key'/HexAdapter(Bytes(16)),
Philipp Maier4f888a02022-12-02 12:30:12 +0100264 'op_opc' /HexAdapter(Bytes(16)))
Harald Weltec91085e2022-02-10 18:05:45 +0100265
266
Harald Weltef44256c2021-10-14 15:53:39 +0200267class EF_GBA_SK(TransparentEF):
268 def __init__(self, fid='af31', name='EF.GBA_SK'):
269 super().__init__(fid, name=name, desc='Secret key for GBA key derivation')
270 self._construct = GreedyBytes
271
Harald Weltec91085e2022-02-10 18:05:45 +0100272
Harald Weltef44256c2021-10-14 15:53:39 +0200273class EF_GBA_REC_LIST(TransparentEF):
274 def __init__(self, fid='af32', name='EF.GBA_REC_LIST'):
275 super().__init__(fid, name=name, desc='Secret key for GBA key derivation')
276 # integers representing record numbers in EF-GBANL
277 self._construct = GreedyRange(Int8ub)
278
Harald Weltec91085e2022-02-10 18:05:45 +0100279
Harald Weltef44256c2021-10-14 15:53:39 +0200280class EF_GBA_INT_KEY(LinFixedEF):
281 def __init__(self, fid='af33', name='EF.GBA_INT_KEY'):
Harald Weltec91085e2022-02-10 18:05:45 +0100282 super().__init__(fid, name=name,
Harald Welte99e4cc02022-07-21 15:25:47 +0200283 desc='Secret key for GBA key derivation', rec_len=(32, 32))
Harald Weltef44256c2021-10-14 15:53:39 +0200284 self._construct = GreedyBytes
285
286
Harald Weltef44256c2021-10-14 15:53:39 +0200287class SysmocomSJA2(CardModel):
Harald Weltec91085e2022-02-10 18:05:45 +0100288 _atrs = ["3B 9F 96 80 1F 87 80 31 E0 73 FE 21 1B 67 4A 4C 75 30 34 05 4B A9",
289 "3B 9F 96 80 1F 87 80 31 E0 73 FE 21 1B 67 4A 4C 75 31 33 02 51 B2",
290 "3B 9F 96 80 1F 87 80 31 E0 73 FE 21 1B 67 4A 4C 52 75 31 04 51 D5"]
291
Harald Weltef44256c2021-10-14 15:53:39 +0200292 @classmethod
Harald Weltec91085e2022-02-10 18:05:45 +0100293 def add_files(cls, rs: RuntimeState):
Harald Weltef44256c2021-10-14 15:53:39 +0200294 """Add sysmocom SJA2 specific files to given RuntimeState."""
295 rs.mf.add_file(DF_SYSTEM())
296 # optional USIM application
297 if 'a0000000871002' in rs.mf.applications:
298 usim_adf = rs.mf.applications['a0000000871002']
299 files_adf_usim = [
300 EF_USIM_AUTH_KEY(),
301 EF_USIM_AUTH_KEY_2G(),
302 EF_GBA_SK(),
303 EF_GBA_REC_LIST(),
304 EF_GBA_INT_KEY(),
305 EF_USIM_SQN(),
Harald Weltec91085e2022-02-10 18:05:45 +0100306 ]
Harald Weltef44256c2021-10-14 15:53:39 +0200307 usim_adf.add_files(files_adf_usim)
308 # optional ISIM application
309 if 'a0000000871004' in rs.mf.applications:
310 isim_adf = rs.mf.applications['a0000000871004']
311 files_adf_isim = [
312 EF_USIM_AUTH_KEY(name='EF.ISIM_AUTH_KEY'),
313 EF_USIM_AUTH_KEY_2G(name='EF.ISIM_AUTH_KEY_2G'),
314 EF_USIM_SQN(name='EF.ISIM_SQN'),
Harald Weltec91085e2022-02-10 18:05:45 +0100315 ]
Harald Weltef44256c2021-10-14 15:53:39 +0200316 isim_adf.add_files(files_adf_isim)
Harald Welte0489ae62023-05-24 10:28:34 +0200317
318class SysmocomSJA5(CardModel):
319 _atrs = ["3B 9F 96 80 1F 87 80 31 E0 73 FE 21 1B 67 4A 35 75 30 35 02 51 CC",
320 "3B 9F 96 80 1F 87 80 31 E0 73 FE 21 1B 67 4A 35 75 30 35 02 65 F8",
321 "3B 9F 96 80 1F 87 80 31 E0 73 FE 21 1B 67 4A 35 75 30 35 02 59 C4"]
322
323 @classmethod
324 def add_files(cls, rs: RuntimeState):
325 """Add sysmocom SJA2 specific files to given RuntimeState."""
326 rs.mf.add_file(DF_SYSTEM())
327 # optional USIM application
328 if 'a0000000871002' in rs.mf.applications:
329 usim_adf = rs.mf.applications['a0000000871002']
330 files_adf_usim = [
331 EF_USIM_AUTH_KEY(),
332 EF_USIM_AUTH_KEY_2G(),
333 EF_GBA_SK(),
334 EF_GBA_REC_LIST(),
335 EF_GBA_INT_KEY(),
336 EF_USIM_SQN(),
337 ]
338 usim_adf.add_files(files_adf_usim)
339 # optional ISIM application
340 if 'a0000000871004' in rs.mf.applications:
341 isim_adf = rs.mf.applications['a0000000871004']
342 files_adf_isim = [
343 EF_USIM_AUTH_KEY(name='EF.ISIM_AUTH_KEY'),
344 EF_USIM_AUTH_KEY_2G(name='EF.ISIM_AUTH_KEY_2G'),
345 EF_USIM_SQN(name='EF.ISIM_SQN'),
346 ]
347 isim_adf.add_files(files_adf_isim)