From 15fae98d2eb18fd27fc12de4df7a28897c9188c8 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 10 Apr 2021 10:22:27 +0200 Subject: [PATCH] pySim-shell: Authenticate (3g) support This adds support for AUTHENTICATE to the USIM and ISIM application, based on the newly-introduced 'construct' encoder/decoder support. Change-Id: Id5697463e29c3dceff98bcf80f5400f7f2bcaa6c --- docs/shell.rst | 11 +++++++++++ pySim/commands.py | 22 ++++++++++++++++++++++ pySim/ts_31_102.py | 20 ++++++++++++++++++++ pySim/ts_31_103.py | 3 +++ 4 files changed, 56 insertions(+) diff --git a/docs/shell.rst b/docs/shell.rst index 854944c2..1072ee85 100644 --- a/docs/shell.rst +++ b/docs/shell.rst @@ -300,6 +300,17 @@ to the SIM card. This allows for easy interactive modification of file contents. +USIM commands +------------- + +authenticate +~~~~~~~~~~~~ +.. argparse:: + :module: pySim.ts_31_102 + :func: ADF_USIM.AddlShellCommands.authenticate_parser + + + cmd2 settable parameters ------------------------ diff --git a/pySim/commands.py b/pySim/commands.py index 7919099c..791b9956 100644 --- a/pySim/commands.py +++ b/pySim/commands.py @@ -21,6 +21,8 @@ # along with this program. If not, see . # +from construct import * +from pySim.construct import LV from pySim.utils import rpad, b2h, sw_match from pySim.exceptions import SwMatchError @@ -274,6 +276,26 @@ class SimCardCommands(object): self.select_path(['3f00', '7f20']) return self._tp.send_apdu(self.cla_byte + '88000010' + rand) + def authenticate(self, rand:str, autn:str, context='3g'): + """Execute AUTHENTICATE (USIM/ISIM).""" + # 3GPP TS 31.102 Section 7.1.2.1 + AuthCmd3G = Struct('rand'/LV, 'autn'/Optional(LV)) + AuthResp3GSyncFail = Struct(Const(b'\xDC'), 'auts'/LV) + AuthResp3GSuccess = Struct(Const(b'\xDB'), 'res'/LV, 'ck'/LV, 'ik'/LV, 'kc'/Optional(LV)) + AuthResp3G = Select(AuthResp3GSyncFail, AuthResp3GSuccess) + # build parameters + cmd_data = {'rand': rand, 'autn': autn} + if context == '3g': + p2 = '81' + elif context == 'gsm': + p2 = '80' + (data, sw) = self._tp.send_apdu_constr(self.cla_byte, '88', '00', p2, AuthCmd3G, cmd_data, AuthResp3G) + if 'auts' in data: + ret = {'synchronisation_failure': data} + else: + ret = {'successful_3g_authentication': data} + return (ret, sw) + def reset_card(self): """Physically reset the card""" return self._tp.reset_card() diff --git a/pySim/ts_31_102.py b/pySim/ts_31_102.py index 267008de..cdb66124 100644 --- a/pySim/ts_31_102.py +++ b/pySim/ts_31_102.py @@ -268,6 +268,7 @@ EF_USIM_ADF_map = { # ADF.USIM ###################################################################### +from struct import unpack, pack from pySim.filesystem import * from pySim.ts_51_011 import EF_IMSI, EF_xPLMNwAcT, EF_SPN, EF_CBMI, EF_ACC, EF_PLMNsel, EF_AD from pySim.ts_51_011 import EF_CBMID, EF_CBMIR @@ -489,6 +490,8 @@ class ADF_USIM(CardADF): def __init__(self, aid='a0000000871002', name='ADF.USIM', fid=None, sfid=None, desc='USIM Application'): super().__init__(aid=aid, fid=fid, sfid=sfid, name=name, desc=desc) + # add those commands to the general commands of a TransparentEF + self.shell_commands += [self.AddlShellCommands()] files = [ EF_LI(sfid=0x02), @@ -520,6 +523,23 @@ class ADF_USIM(CardADF): def decode_select_response(self, data_hex): return pySim.ts_102_221.decode_select_response(data_hex) + @with_default_category('Application-Specific Commands') + class AddlShellCommands(CommandSet): + def __init__(self): + super().__init__() + + authenticate_parser = argparse.ArgumentParser() + authenticate_parser.add_argument('rand', help='Random challenge') + authenticate_parser.add_argument('autn', help='Authentication Nonce') + #authenticate_parser.add_argument('--context', help='Authentication context', default='3G') + @cmd2.with_argparser(authenticate_parser) + def do_authenticate(self, opts): + """Perform Authentication and Key Agreement (AKA).""" + (data, sw) = self._cmd.card._scc.authenticate(opts.rand, opts.autn) + self._cmd.poutput_json(data) + + + # TS 31.102 Section 7.3 sw_usim = { 'Security management': { diff --git a/pySim/ts_31_103.py b/pySim/ts_31_103.py index 82098452..effdbf76 100644 --- a/pySim/ts_31_103.py +++ b/pySim/ts_31_103.py @@ -25,6 +25,7 @@ Various constants from ETSI TS 131 103 V14.2.0 from pySim.filesystem import * from pySim.utils import * from pySim.ts_51_011 import EF_AD +from pySim.ts_31_102 import ADF_USIM import pySim.ts_102_221 # Mapping between ISIM Service Number and its description @@ -186,6 +187,8 @@ class ADF_ISIM(CardADF): EF_WebRTCURI(), ] self.add_files(files) + # add those commands to the general commands of a TransparentEF + self.shell_commands += [ADF_USIM.AddlShellCommands()] def decode_select_response(self, data_hex): return pySim.ts_102_221.decode_select_response(data_hex)