From 3c437d41e025b2a735e19588e937e578f17a8cd6 Mon Sep 17 00:00:00 2001 From: Eric Wild Date: Wed, 23 Sep 2026 17:51:04 +0200 Subject: [PATCH] sysmocom_sjs1: CardModel for the sysmoUSIM-SJS1 SJS1 model lifted off the the legacy SysmoUSIMSJS1.program(), ADM is ADM1 with CHV 0x0a, already used by the generic UiccCardBase default. Change-Id: I32b011c68de5f990e709718b313b6f28a31ca78b --- pySim/app.py | 7 ++-- pySim/sysmocom_sjs1.py | 61 +++++++++++++++++++++++++++++++++++ tests/unittests/test_files.py | 1 + 3 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 pySim/sysmocom_sjs1.py diff --git a/pySim/app.py b/pySim/app.py index 4e887881..b8c505f8 100644 --- a/pySim/app.py +++ b/pySim/app.py @@ -30,10 +30,11 @@ from pySim.log import PySimLogger log = PySimLogger.get(__name__) -# we need to import this module so that the SysmocomSJA2 sub-class of -# CardModel is created, which will add the ATR-based matching and -# calling of SysmocomSJA2.add_files. See CardModel.apply_matching_models +# we need to import these modules so that the SysmocomSJA2 / SysmocomSJS1 +# sub-classes of CardModel are created, which will add the ATR-based matching +# and calling of their add_files. See CardModel.apply_matching_models import pySim.sysmocom_sja2 +import pySim.sysmocom_sjs1 # we need to import these modules so that the various sub-classes of # CardProfile are created, which will be used in init_card() to iterate diff --git a/pySim/sysmocom_sjs1.py b/pySim/sysmocom_sjs1.py new file mode 100644 index 00000000..8f8c0440 --- /dev/null +++ b/pySim/sysmocom_sjs1.py @@ -0,0 +1,61 @@ +# coding=utf-8 +"""Utilities / Functions related to sysmocom sysmoUSIM-SJS1 cards + +(C) 2026 by sysmocom - s.f.m.c. GmbH +All Rights Reserved + +Author: Eric Wild + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" + +from construct import Struct, Bytes, Flag +from osmocom.utils import * +from osmocom.construct import * + +from pySim.filesystem import * +from pySim.runtime import RuntimeState + + +class EF_Ki(TransparentEF): + _test_de_encode = [ + ('000102030405060708090a0b0c0d0e0f', + {'key': h2b('000102030405060708090a0b0c0d0e0f')}), + ] + + def __init__(self, fid='00ff', name='EF.Ki'): + super().__init__(fid, name=name, desc='K/Ki authentication key', size=(16, 16)) + self._construct = Struct('key'/Bytes(16)) + + +class EF_OPc(TransparentEF): + _test_de_encode = [ + ('016ca53d7a0a804561646816d7b0c702fb', + {'use_opc_instead_of_op': True, 'op_opc': h2b('6ca53d7a0a804561646816d7b0c702fb')}), + ] + + def __init__(self, fid='00f7', name='EF.OPc'): + super().__init__(fid, name=name, desc='OP/OPc for milenage', size=(17, 17)) + self._construct = Struct('use_opc_instead_of_op'/Flag, 'op_opc'/Bytes(16)) + + +class SysmoUSIMSJS1(CardModel): + _atrs = ["3b9f96801fc78031a073be21136743200718000001a5"] + + @classmethod + def add_files(cls, rs: RuntimeState): + """Add sysmoUSIM-SJS1 specific files to given RuntimeState.""" + # the key material lives in DF.GSM shared with ADF.USIM + if '7f20' in rs.mf.children: + rs.mf.children['7f20'].add_files([EF_Ki(), EF_OPc()]) diff --git a/tests/unittests/test_files.py b/tests/unittests/test_files.py index e7c50dc7..e8a7bc0b 100755 --- a/tests/unittests/test_files.py +++ b/tests/unittests/test_files.py @@ -27,6 +27,7 @@ import pySim.ts_31_102 import pySim.ts_31_103 import pySim.ts_51_011 import pySim.sysmocom_sja2 +import pySim.sysmocom_sjs1 import pySim.gsm_r import pySim.cdma_ruim