Add support for ADF_USIM/EF_EHPLMN

If the EF.EHPLMN exists, it contains the "Equivalent Home PLMN List".
The odd part of that list is that it is not just a list of additional
PLMN identities, but if the first digits of the IMSI are *not* listed
in EF.EHPLMN, then the MCC/MNC of the IMSI prefix is suddently no
longer considered the home network, but the subscriber is roaming.

See TS 23.122: "If the HPLMN code derived from the IMSI is not present
in the EHPLMN list, then it shall be treated as a Visited PLMN for PLMN
selection purposes."

Change-Id: I22d96ab4a424ec5bc1fb02f5e80165c646a748d3
This commit is contained in:
Harald Welte
2020-06-03 15:19:40 +02:00
committed by laforge
parent 3c0bd7a41e
commit ca6739458e
5 changed files with 83 additions and 4 deletions

View File

@@ -24,6 +24,7 @@
#
from pySim.ts_51_011 import EF, DF
from pySim.ts_31_102 import EF_USIM_ADF_map
from pySim.utils import *
from smartcard.util import toBytes
@@ -41,6 +42,13 @@ class Card(object):
print("warning: erasing is not supported for specified card type!")
return
def file_exists(self, fid):
res_arr = self._scc.try_select_file(fid)
for res in res_arr:
if res[1] != '9000':
return False
return True
def verify_adm(self, key):
'''
Authenticate with ADM key
@@ -262,6 +270,25 @@ class Card(object):
len = self._scc.record_size(ef)
self._scc.update_record(ef, rec_no, "ff" * len, force_len=False, verify=True)
class UsimCard(Card):
def __init__(self, ssc):
super(UsimCard, self).__init__(ssc)
def read_ehplmn(self):
(res, sw) = self._scc.read_binary(EF_USIM_ADF_map['EHPLMN'])
if sw == '9000':
return (format_xplmn(res), sw)
else:
return (None, sw)
def update_ehplmn(self, mcc, mnc):
data = self._scc.read_binary(EF_USIM_ADF_map['EHPLMN'], length=None, offset=0)
size = len(data[0]) // 2
ehplmn = enc_plmn(mcc, mnc)
data, sw = self._scc.update_binary(EF_USIM_ADF_map['EHPLMN'], ehplmn)
return sw
class _MagicSimBase(Card):
"""
@@ -552,7 +579,7 @@ class SysmoSIMgr1(GrcardSim):
return None
return None
class SysmoUSIMgr1(Card):
class SysmoUSIMgr1(UsimCard):
"""
sysmocom sysmoUSIM-GR1
"""
@@ -653,7 +680,7 @@ class SysmoSIMgr2(Card):
data, sw = self._scc.update_record('6f42', 1, lpad(p['smsp'], 80))
class SysmoUSIMSJS1(Card):
class SysmoUSIMSJS1(UsimCard):
"""
sysmocom sysmoUSIM-SJS1
"""
@@ -1037,7 +1064,7 @@ class WavemobileSim(Card):
return None
class SysmoISIMSJA2(Card):
class SysmoISIMSJA2(UsimCard):
"""
sysmocom sysmoISIM-SJA2
"""
@@ -1144,16 +1171,22 @@ class SysmoISIMSJA2(Card):
if p.get('opc'):
self._scc.update_binary('af20', p['opc'], 17)
# update EF-USIM_AUTH_KEY in ADF.USIM
self._scc.select_file(['3f00'])
aid = self.read_aid()
if (aid):
# update EF-USIM_AUTH_KEY in ADF.USIM
self._scc.select_adf(aid)
if p.get('ki'):
self._scc.update_binary('af20', p['ki'], 1)
if p.get('opc'):
self._scc.update_binary('af20', p['opc'], 17)
# update EF.EHPLMN in ADF.USIM
if self.file_exists(EF_USIM_ADF_map['EHPLMN']):
if p.get('mcc') and p.get('mnc'):
sw = self.update_ehplmn(p['mcc'], p['mnc'])
if sw != '9000':
print("Programming EHPLMN failed with code %s"%sw)
return