laforge has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/pysim/+/36931?usp=email )


Change subject: global_platform/euicc: Implement obtaining SCP keys from 
CardKeyProvider
......................................................................

global_platform/euicc: Implement obtaining SCP keys from CardKeyProvider

Now that CardKeyProvider is capable of storing key materials
transport-key-encrypted, we can use this functionality to look up the
SCP02 / SCP03 key material for a given security domain.

This patch implements this for the ISD-R and ECASD using a look-up by
EID inside the CSV.

Change-Id: I2a21f031ab8af88019af1b8390612678b9b35880
---
M pySim/euicc.py
M pySim/global_platform/__init__.py
2 files changed, 53 insertions(+), 8 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/31/36931/1

diff --git a/pySim/euicc.py b/pySim/euicc.py
index a771a22..ddfe939 100644
--- a/pySim/euicc.py
+++ b/pySim/euicc.py
@@ -315,6 +315,8 @@
                          desc='ISD-R (Issuer Security Domain Root) 
Application')
         self.adf.decode_select_response = self.decode_select_response
         self.adf.shell_commands += [self.AddlShellCommands()]
+        # we attempt to retrieve ISD-R key material from CardKeyProvider 
identified by EID
+        self.adf.scp_key_identity = 'EID'

     @staticmethod
     def store_data(scc: SimCardCommands, tx_do: Hexstr, exp_sw: SwMatchstr 
="9000") -> Tuple[Hexstr, SwHexstr]:
@@ -539,6 +541,8 @@
                          desc='ECASD (eUICC Controlling Authority Security 
Domain) Application')
         self.adf.decode_select_response = self.decode_select_response
         self.adf.shell_commands += [self.AddlShellCommands()]
+        # we attempt to retrieve ECASD key material from CardKeyProvider 
identified by EID
+        self.adf.scp_key_identity = 'EID'

     @with_default_category('Application-Specific Commands')
     class AddlShellCommands(CommandSet):
diff --git a/pySim/global_platform/__init__.py 
b/pySim/global_platform/__init__.py
index f440fd0..0be316b 100644
--- a/pySim/global_platform/__init__.py
+++ b/pySim/global_platform/__init__.py
@@ -23,6 +23,7 @@
 from construct import Struct, GreedyRange, FlagsEnum, Int16ub, Int24ub, 
Padding, Bit, Const
 from Cryptodome.Random import get_random_bytes
 from Cryptodome.Cipher import DES, DES3, AES
+from pySim.card_key_provider import card_key_provider_get_field
 from pySim.global_platform.scp import SCP02, SCP03
 from pySim.construct import *
 from pySim.utils import *
@@ -719,23 +720,33 @@
             return self._cmd.lchan.scc.send_apdu_checksw(cmd_hex)

         est_scp02_parser = argparse.ArgumentParser()
-        est_scp02_parser.add_argument('--key-ver', type=auto_uint8, 
required=True,
-                                      help='Key Version Number (KVN)')
-        est_scp02_parser.add_argument('--key-enc', type=is_hexstr, 
required=True,
-                                      help='Secure Channel Encryption Key')
-        est_scp02_parser.add_argument('--key-mac', type=is_hexstr, 
required=True,
-                                      help='Secure Channel MAC Key')
-        est_scp02_parser.add_argument('--key-dek', type=is_hexstr, 
required=True,
-                                      help='Data Encryption Key')
+        est_scp02_parser.add_argument('--key-ver', type=auto_uint8, 
required=True, help='Key Version Number (KVN)')
         est_scp02_parser.add_argument('--host-challenge', type=is_hexstr,
                                       help='Hard-code the host challenge; 
default: random')
         est_scp02_parser.add_argument('--security-level', type=auto_uint8, 
default=0x01,
                                       help='Security Level. Default: 0x01 
(C-MAC only)')
+        est_scp02_p_k = est_scp02_parser.add_argument_group('Manual key 
specification')
+        est_scp02_p_k.add_argument('--key-enc', type=is_hexstr, help='Secure 
Channel Encryption Key')
+        est_scp02_p_k.add_argument('--key-mac', type=is_hexstr, help='Secure 
Channel MAC Key')
+        est_scp02_p_k.add_argument('--key-dek', type=is_hexstr, help='Data 
Encryption Key')
+        est_scp02_p_csv = est_scp02_parser.add_argument_group('Obtain keys 
from CardKeyProvider (e.g. CSV')
+        est_scp02_p_csv.add_argument('--key-provider-suffix', help='Suffix for 
key names in CardKeyProvider')

         @cmd2.with_argparser(est_scp02_parser)
         def do_establish_scp02(self, opts):
             """Establish a secure channel using the GlobalPlatform SCP02 
protocol.  It can be released
             again by using `release_scp`."""
+            if opts.key_provider_suffix:
+                suffix = opts.key_provider_suffix
+                id_field_name = self._cmd.lchan.selected_adf.scp_key_identity
+                identity = self._cmd.rs.identity.get(id_field_name)
+                opts.key_enc = card_key_provider_get_field('SCP02_ENC_' + 
suffix, key=id_field_name, value=identity)
+                opts.key_mac = card_key_provider_get_field('SCP02_MAC_' + 
suffix, key=id_field_name, value=identity)
+                opts.key_dek = card_key_provider_get_field('SCP02_DEK_' + 
suffix, key=id_field_name, value=identity)
+            else:
+                if not opts.key_enc or not opts.key_mac:
+                    self._cmd.poutput("Cannot establish SCP02 without at least 
ENC and MAC keys given!")
+                    return
             if self._cmd.lchan.scc.scp:
                 self._cmd.poutput("Cannot establish SCP02 as this lchan 
already has a SCP instance!")
                 return
@@ -751,6 +762,17 @@
         def do_establish_scp03(self, opts):
             """Establish a secure channel using the GlobalPlatform SCP03 
protocol.  It can be released
             again by using `release_scp`."""
+            if opts.key_provider_suffix:
+                suffix = opts.key_provider_suffix
+                id_field_name = self._cmd.lchan.selected_adf.scp_key_identity
+                identity = self._cmd.rs.identity.get(id_field_name)
+                opts.key_enc = card_key_provider_get_field('SCP03_ENC_' + 
suffix, key=id_field_name, value=identity)
+                opts.key_mac = card_key_provider_get_field('SCP03_MAC_' + 
suffix, key=id_field_name, value=identity)
+                opts.key_dek = card_key_provider_get_field('SCP03_DEK_' + 
suffix, key=id_field_name, value=identity)
+            else:
+                if not opts.key_enc or not opts.key_mac:
+                    self._cmd.poutput("Cannot establish SCP03 without at least 
ENC and MAC keys given!")
+                    return
             if self._cmd.lchan.scc.scp:
                 self._cmd.poutput("Cannot establish SCP03 as this lchan 
already has a SCP instance!")
                 return
@@ -787,6 +809,9 @@
     __intermediate = True
     def __init__(self, aid: str, name: str, desc: str):
         super().__init__(name, adf=ADF_SD(aid, name, desc), sw=sw_table)
+        # the identity (e.g. 'ICCID', 'EID') that should be used as a look-up 
key to attempt to retrieve
+        # the key material for the security domain from the CardKeyProvider
+        self.adf.scp_key_identity = None

 # Card Application of Issuer Security Domain
 class CardApplicationISD(CardApplicationSD):

--
To view, visit https://gerrit.osmocom.org/c/pysim/+/36931?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I2a21f031ab8af88019af1b8390612678b9b35880
Gerrit-Change-Number: 36931
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <lafo...@osmocom.org>
Gerrit-MessageType: newchange

Reply via email to