This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
laforge gerrit-no-reply at lists.osmocom.orglaforge has submitted this change. ( https://gerrit.osmocom.org/c/pysim/+/23564 ) Change subject: Add decoder/encoder for EF.SUCI_Calc_Info ...................................................................... Add decoder/encoder for EF.SUCI_Calc_Info Change-Id: I848a766e6d00be497c7db905475e0681cce197ac --- M pySim/ts_31_102.py M tests/test_utils.py 2 files changed, 171 insertions(+), 1 deletion(-) Approvals: Jenkins Builder: Verified laforge: Looks good to me, approved diff --git a/pySim/ts_31_102.py b/pySim/ts_31_102.py index 02b0aea..54fd95d 100644 --- a/pySim/ts_31_102.py +++ b/pySim/ts_31_102.py @@ -274,6 +274,126 @@ import pySim.ts_102_221 +# TS 31.102 4.4.11.8 +class EF_SUCI_Calc_Info(TransparentEF): + def __init__(self, fid="4f07", sfid=0x07, name='EF.SUCI_Calc_Info', size={2, None}, + desc='SUCI Calc Info'): + super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size) + + def _encode_prot_scheme_id_list(self, in_list): + out_bytes = [0xa0] + out_bytes.append(len(in_list)*2) # two byte per entry + + # position in list determines priority; high-priority items (low index) come first + for scheme in sorted(in_list, key=lambda item: item["priority"]): + out_bytes.append(scheme["identifier"]) + out_bytes.append(scheme["key_index"]) + + return out_bytes + + def _encode_hnet_pubkey_list(self, hnet_pubkey_list): + out_bytes = [0xa1] # pubkey list tag + out_bytes.append(0x00) # length filled later + length = 0 + + for key in hnet_pubkey_list: + out_bytes.append(0x80) # identifier tag + out_bytes.append(0x01) # TODO size, fixed to 1 byte + out_bytes.append(key["hnet_pubkey_identifier"]) + out_bytes.append(0x81) # key tag + out_bytes.append(len(key["hnet_pubkey"])//2) + length += 5+len(key["hnet_pubkey"])//2 + + pubkey_bytes = h2b(key["hnet_pubkey"]) + out_bytes += pubkey_bytes + + # fill length + out_bytes[1] = length + return out_bytes + + def _encode_hex(self, in_json): + out_bytes = self._encode_prot_scheme_id_list(in_json['prot_scheme_id_list']) + out_bytes += self._encode_hnet_pubkey_list(in_json['hnet_pubkey_list']) + return "".join(["%02X" % i for i in out_bytes]) + + def _decode_prot_scheme_id_list(self, in_bytes): + prot_scheme_id_list = [] + pos = 0 + # two bytes per entry + while pos < len(in_bytes): + prot_scheme = { + 'priority': pos//2, # first in list: high priority + 'identifier': in_bytes[pos], + 'key_index': in_bytes[pos+1] + } + pos += 2 + prot_scheme_id_list.append(prot_scheme) + return prot_scheme_id_list + + def _decode_hnet_pubkey_list(self, in_bytes): + hnet_pubkey_list = [] + pos = 0 + if in_bytes[pos] != 0xa1: + print("missing Home Network Public Key List data object") + return {} + pos += 1 + hnet_pubkey_list_len = in_bytes[pos] + pos += 1 + + while pos < hnet_pubkey_list_len: + if in_bytes[pos] != 0x80: + print("missing Home Network Public Key Identifier tag") + return {} + pos += 1 + hnet_pubkey_id_len = in_bytes[pos] # TODO might be more than 1 byte? + pos += 1 + hnet_pubkey_id = in_bytes[pos:pos+hnet_pubkey_id_len][0] + pos += hnet_pubkey_id_len + if in_bytes[pos] != 0x81: + print("missing Home Network Public Key tag") + return {} + pos += 1 + hnet_pubkey_len = in_bytes[pos] + pos += 1 + hnet_pubkey = in_bytes[pos:pos+hnet_pubkey_len] + pos += hnet_pubkey_len + + hnet_pubkey_list.append({ + 'hnet_pubkey_identifier': hnet_pubkey_id, + 'hnet_pubkey': b2h(hnet_pubkey) + }) + + return hnet_pubkey_list + + def _decode_bin(self, in_bin): + return self._decode_hex(b2h(in_hex)) + + def _decode_hex(self, in_hex): + in_bytes = h2b(in_hex) + pos = 0 + + if in_bytes[pos] != 0xa0: + print("missing Protection Scheme Identifier List data object tag") + return {} + pos += 1 + + prot_scheme_id_list_len = in_bytes[pos] # TODO maybe more than 1 byte + pos += 1 + # decode Protection Scheme Identifier List data object + prot_scheme_id_list = self._decode_prot_scheme_id_list(in_bytes[pos:pos+prot_scheme_id_list_len]) + pos += prot_scheme_id_list_len + + # remaining data holds Home Network Public Key Data Object + hnet_pubkey_list = self._decode_hnet_pubkey_list(in_bytes[pos:]) + + return { + 'prot_scheme_id_list': prot_scheme_id_list, + 'hnet_pubkey_list': hnet_pubkey_list + } + + def _encode_bin(self, in_json): + return h2b(self._encode_hex(in_json)) + class EF_LI(TransRecEF): def __init__(self, fid='6f05', sfid=None, name='EF.LI', size={2,None}, rec_len=2, desc='Language Indication'): @@ -340,6 +460,27 @@ """Deactivate a service within EF.UST""" self._cmd.card.update_ust(int(arg), 0) +class DF_USIM_5GS(CardDF): + def __init__(self, fid='5FC0', name='DF.5GS', desc='5GS related files'): + super().__init__(fid=fid, name=name, desc=desc) + files = [ + # I'm looking at 31.102 R15.9 + TransparentEF('4F01', None, 'EF.5GS3GPPLOCI', '5GS 3GPP location information', size={20,20}), + TransparentEF('4F02', None, 'EF.5GSN3GPPLOCI', '5GS non-3GPP location information', size={20,20}), + #LinFixedEF('4F03', None, 'EF.5GS3GPPNSC', '5GS 3GPP Access NAS Security Context'), + #LinFixedEF('4F04', None, 'EF.5GSN3GPPNSC', '5GS non-3GPP Access NAS Security Context'), + TransparentEF('4F05', None, 'EF.5GAUTHKEYS', '5G authentication keys', size={68, None}), + TransparentEF('4F06', None, 'EF.UAC_AIC', 'UAC Access Identities Configuration', size={4, 4}), + EF_SUCI_Calc_Info(), #TransparentEF('4F07', None, 'EF.SUCI_Calc_Info', 'SUCI Calculation Information', size={2, None}), + TransparentEF('4F08', None, 'EF.OPL5G', '5GS Operator PLMN List', size={10, None}), + # TransparentEF('4F09', None, 'EF.NSI', 'Network Specific Identifier'), # FFS + TransparentEF('4F0A', None, 'EF.Routing_Indicator', 'Routing Indicator', size={4,4}), + ] + + self.add_files(files) + + def decode_select_response(self, data_hex): + return data_hex class ADF_USIM(CardADF): def __init__(self, aid='a0000000871002', name='ADF.USIM', fid=None, sfid=None, @@ -370,6 +511,7 @@ EF_CBMID(sfid=0x0e), EF_ECC(sfid=0x01), EF_CBMIR(), + DF_USIM_5GS(), ] self.add_files(files) diff --git a/tests/test_utils.py b/tests/test_utils.py old mode 100644 new mode 100755 index bcf6140..badde55 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,9 +1,26 @@ #!/usr/bin/env python3 import unittest -import pySim.utils as utils +from pySim import utils +from pySim.ts_31_102 import EF_SUCI_Calc_Info class DecTestCase(unittest.TestCase): + # TS33.501 Annex C.4 test keys + hnet_pubkey_profile_b = "0272DA71976234CE833A6907425867B82E074D44EF907DFB4B3E21C1C2256EBCD1" # ID 27 in test file + hnet_pubkey_profile_a = "5A8D38864820197C3394B92613B20B91633CBD897119273BF8E4A6F4EEC0A650" # ID 30 in test file + + # TS31.121 4.9.4 EF_SUCI_Calc_Info test file + testfile_suci_calc_info = "A006020101020000A14B80011B8121" +hnet_pubkey_profile_b +"80011E8120" +hnet_pubkey_profile_a + + decoded_testfile_suci = { + 'prot_scheme_id_list': [ + {'priority': 0, 'identifier': 2, 'key_index': 1}, + {'priority': 1, 'identifier': 1, 'key_index': 2}, + {'priority': 2, 'identifier': 0, 'key_index': 0}], + 'hnet_pubkey_list': [ + {'hnet_pubkey_identifier': 27, 'hnet_pubkey': hnet_pubkey_profile_b.lower()}, # because h2b/b2h returns all lower-case + {'hnet_pubkey_identifier': 30, 'hnet_pubkey': hnet_pubkey_profile_a.lower()}] + } def testSplitHexStringToListOf5ByteEntries(self): input_str = "ffffff0003ffffff0002ffffff0001" @@ -81,5 +98,16 @@ expected += "\tffffff0000 # unused\n" self.assertEqual(utils.format_xplmn_w_act(input_str), expected) + + def testDecodeSuciCalcInfo(self): + suci_calc_info = EF_SUCI_Calc_Info() + decoded = suci_calc_info._decode_hex(self.testfile_suci_calc_info) + self.assertDictEqual(self.decoded_testfile_suci, decoded) + + def testEncodeSuciCalcInfo(self): + suci_calc_info = EF_SUCI_Calc_Info() + encoded = suci_calc_info._encode_hex(self.decoded_testfile_suci) + self.assertEqual(encoded.lower(), self.testfile_suci_calc_info.lower()) + if __name__ == "__main__": unittest.main() -- To view, visit https://gerrit.osmocom.org/c/pysim/+/23564 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Change-Id: I848a766e6d00be497c7db905475e0681cce197ac Gerrit-Change-Number: 23564 Gerrit-PatchSet: 3 Gerrit-Owner: merlinchlosta <merlin.chlosta at rub.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <laforge at osmocom.org> Gerrit-CC: fixeria <vyanitskiy at sysmocom.de> Gerrit-MessageType: merged -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210402/cf110d85/attachment.htm>