laforge has submitted this change. ( https://gerrit.osmocom.org/c/pysim/+/36956?usp=email )
Change subject: add globalplatform.uicc ......................................................................
add globalplatform.uicc
GlobalPlatform has a [non-public] "UICC Configuration" spec, which defines some specific aspects of implementing GlobalPlatform in the context of an UICC. Let's add some python definitions about it.
Change-Id: If4cb110a9bc5f873b0e097c006bef59264ee48fa --- A pySim/global_platform/uicc.py 1 file changed, 120 insertions(+), 0 deletions(-)
Approvals: Jenkins Builder: Verified laforge: Looks good to me, approved
diff --git a/pySim/global_platform/uicc.py b/pySim/global_platform/uicc.py new file mode 100644 index 0000000..2cf5e96 --- /dev/null +++ b/pySim/global_platform/uicc.py @@ -0,0 +1,107 @@ +# coding=utf-8 +"""GlobalPLatform UICC Configuration 1.0 parameters + +(C) 2024 by Harald Welte laforge@osmocom.org + +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 http://www.gnu.org/licenses/. +""" + +from construct import Optional as COptional +from construct import Struct, GreedyRange, FlagsEnum, Int16ub, Int24ub, Padding, Bit, Const +from pySim.construct import * +from pySim.utils import * +from pySim.tlv import * + +# Section 11.6.2.3 / Table 11-58 +class SecurityDomainAid(BER_TLV_IE, tag=0x4f): + _construct = GreedyBytes +class LoadFileDataBlockSignature(BER_TLV_IE, tag=0xc3): + _construct = GreedyBytes +class DapBlock(BER_TLV_IE, tag=0xe2, nested=[SecurityDomainAid, LoadFileDataBlockSignature]): + pass +class LoadFileDataBlock(BER_TLV_IE, tag=0xc4): + _construct = GreedyBytes +class Icv(BER_TLV_IE, tag=0xd3): + _construct = GreedyBytes +class CipheredLoadFileDataBlock(BER_TLV_IE, tag=0xd4): + _construct = GreedyBytes +class LoadFile(TLV_IE_Collection, nested=[DapBlock, LoadFileDataBlock, Icv, CipheredLoadFileDataBlock]): + pass + +# UICC Configuration v1.0.1 / Section 4.3.2 +class UiccScp(BER_TLV_IE, tag=0x81): + _construct = Struct('scp'/Int8ub, 'i'/Int8ub) + +class AcceptExtradAppsAndElfToSd(BER_TLV_IE, tag=0x82): + _construct = GreedyBytes + +class AcceptDelOfAssocSd(BER_TLV_IE, tag=0x83): + _construct = GreedyBytes + +class LifeCycleTransitionToPersonalized(BER_TLV_IE, tag=0x84): + _construct = GreedyBytes + +class CasdCapabilityInformation(BER_TLV_IE, tag=0x86): + _construct = GreedyBytes + +class AcceptExtradAssocAppsAndElf(BER_TLV_IE, tag=0x87): + _construct = GreedyBytes + +# Security Domain Install Parameters (inside C9 during INSTALL [for install]) +class UiccSdInstallParams(TLV_IE_Collection, nested=[UiccScp, AcceptExtradAppsAndElfToSd, AcceptDelOfAssocSd, + LifeCycleTransitionToPersonalized, + CasdCapabilityInformation, AcceptExtradAssocAppsAndElf]): + def has_scp(self, scp: int) -> bool: + """Determine if SD Installation parameters already specify given SCP.""" + for c in self.children: + if not isinstance(c, UiccScp): + continue + if c.decoded['scp'] == scp: + return True + return False + + def add_scp(self, scp: int, i: int): + """Add given SCP (and i parameter) to list of SCP of the Security Domain Install Params. + Example: add_scp(0x03, 0x70) for SCP03, or add_scp(0x02, 0x55) for SCP02.""" + if self.has_scp(scp): + raise ValueError('SCP%02x already present' % scp) + self.children.append(UiccScp(decoded={'scp': scp, 'i': i})) + + def remove_scp(self, scp: int): + """Remove given SCP from list of SCP of the Security Domain Install Params.""" + for c in self.children: + if not isinstance(c, UiccScp): + continue + if c.decoded['scp'] == scp: + self.children.remove(c) + return + raise ValueError("SCP%02x not present" % scp) + + +# Key Usage: +# KVN 0x01 .. 0x0F reserved for SCP80 +# KVN 0x11 reserved for DAP specified in ETSI TS 102 226 +# KVN 0x20 .. 0x2F reserved for SCP02 +# KID 0x01 = ENC; 0x02 = MAC; 0x03 = DEK +# KVN 0x30 .. 0x3F reserved for SCP03 +# KID 0x01 = ENC; 0x02 = MAC; 0x03 = DEK +# KVN 0x70 KID 0x01: Token key (RSA public or DES) +# KVN 0x71 KID 0x01: Receipt key (DES) +# KVN 0x73 KID 0x01: DAP verifiation key (RS public or DES) +# KVN 0x74 reserved for CASD +# KID 0x01: PK.CA.AUT +# KID 0x02: SK.CASD.AUT (PK) and KS.CASD.AUT (Non-PK) +# KID 0x03: SK.CASD.CT (P) and KS.CASD.CT (Non-PK) +# KVN 0x75 KID 0x01: 16-byte DES key for Ciphered Load File Data Block +# KVN 0xFF reserved for ISD with SCP02 without SCP80 s upport