laforge has submitted this change. ( 
https://gerrit.osmocom.org/c/pysim/+/35684?usp=email )

Change subject: global_platform: Add shell command for PUT KEY
......................................................................

global_platform: Add shell command for PUT KEY

This command is used for installation of GlobalPlatform keys.  We only
implement the command without secure messaging at this point, as it is
used during card personalization.  Authentication will later be handled
by generic implementations of SCP02 and/or SCP03.

Change-Id: Icffe9e7743266d7262fbf440dd361b21eed7c5cf
---
M docs/shell.rst
M pySim/global_platform.py
2 files changed, 65 insertions(+), 0 deletions(-)

Approvals:
  Jenkins Builder: Verified
  fixeria: Looks good to me, but someone else must approve
  laforge: Looks good to me, approved




diff --git a/docs/shell.rst b/docs/shell.rst
index 89a0d0a..8731cfe 100644
--- a/docs/shell.rst
+++ b/docs/shell.rst
@@ -947,6 +947,12 @@
    :module: pySim.global_platform
    :func: ADF_SD.AddlShellCommands.store_data_parser

+put_key
+~~~~~~~
+.. argparse::
+   :module: pySim.global_platform
+   :func: ADF_SD.AddlShellCommands.put_key_parser
+

 eUICC ISD-R commands
 --------------------
diff --git a/pySim/global_platform.py b/pySim/global_platform.py
index f7a4f64..fe6ffb3 100644
--- a/pySim/global_platform.py
+++ b/pySim/global_platform.py
@@ -446,7 +446,52 @@
                 response += data
             return data

+        put_key_parser = argparse.ArgumentParser()
+        put_key_parser.add_argument('--old-key-version-nr', type=auto_int, 
default=0, help='Old Key Version Number')
+        put_key_parser.add_argument('--key-version-nr', type=auto_int, 
required=True, help='Key Version Number')
+        put_key_parser.add_argument('--key-id', type=auto_int, required=True, 
help='Key Identifier (base)')
+        put_key_parser.add_argument('--key-type', 
choices=KeyType.ksymapping.values(), action='append', required=True, help='Key 
Type')
+        put_key_parser.add_argument('--key-data', type=is_hexstr, 
action='append', required=True, help='Key Data Block')
+        put_key_parser.add_argument('--key-check', type=is_hexstr, 
action='append', help='Key Check Value')

+        @cmd2.with_argparser(put_key_parser)
+        def do_put_key(self, opts):
+            """Perform the GlobalPlatform PUT KEY command in order to store a 
new key on the card.
+            See GlobalPlatform CardSpecification v2.3 Section 11.8 for details.
+
+            Example (SCP80 KIC/KID/KIK):
+                put_key --key-version-nr 1 --key-id 0x81    --key-type aes 
--key-data 000102030405060708090a0b0c0d0e0f
+                                                            --key-type aes 
--key-data 101112131415161718191a1b1c1d1e1f
+                                                            --key-type aes 
--key-data 202122232425262728292a2b2c2d2e2f
+
+            Example (SCP81 TLS-PSK/KEK):
+                put_key --key-version-nr 0x40 --key-id 0x81 --key-type tls_psk 
--key-data 303132333435363738393a3b3c3d3e3f
+                                                            --key-type des 
--key-data 404142434445464748494a4b4c4d4e4f
+
+            """
+            if len(opts.key_type) != len(opts.key_data):
+                raise ValueError('There must be an equal number of key-type 
and key-data arguments')
+            kdb = []
+            for i in range(0, len(opts.key_type)):
+                if opts.key_check and len(opts.key_check) > i:
+                    kcv = opts.key_check[i]
+                else:
+                    kcv = ''
+                kdb.append({'key_type': opts.key_type[i], 'kcb': 
opts.key_data[i], 'kcv': kcv})
+            return self.put_key(opts.old_key_version_nr, opts.key_version_nr, 
opts.key_id, kdb)
+
+        # Table 11-68: Key Data Field - Format 1 (Basic Format)
+        KeyDataBasic = GreedyRange(Struct('key_type'/KeyType,
+                                          'kcb'/HexAdapter(Prefixed(Int8ub, 
GreedyBytes)),
+                                          'kcv'/HexAdapter(Prefixed(Int8ub, 
GreedyBytes))))
+
+        def put_key(self, old_kvn:int, kvn: int, kid: int, key_dict: dict) -> 
bytes:
+            """Perform the GlobalPlatform PUT KEY command in order to store a 
new key on the card.
+            See GlobalPlatform CardSpecification v2.3 Section 11.8 for 
details."""
+            key_data = kvn.to_bytes(1, 'big') + 
build_construct(ADF_SD.AddlShellCommands.KeyDataBasic, key_dict)
+            hdr = "80D8%02x%02x%02x" % (old_kvn, kid, len(key_data))
+            data, sw = self._cmd.lchan.scc._tp.send_apdu_checksw(hdr + 
b2h(key_data))
+            return data


 # Card Application of a Security Domain

--
To view, visit https://gerrit.osmocom.org/c/pysim/+/35684?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: Icffe9e7743266d7262fbf440dd361b21eed7c5cf
Gerrit-Change-Number: 35684
Gerrit-PatchSet: 2
Gerrit-Owner: laforge <lafo...@osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: dexter <pma...@sysmocom.de>
Gerrit-Reviewer: fixeria <vyanits...@sysmocom.de>
Gerrit-Reviewer: laforge <lafo...@osmocom.org>
Gerrit-MessageType: merged

Reply via email to