Dynamically determine maximum CMD data length depending on SCP

If we're using a Secure Channel Protocol, this will add overhead
in terms of the C-MAC appended to the C-APDU.  This means in turn that
the useable length of the data field shrinks by a certain number of
bytes.

Let's make sure the SCP instances expose an 'overhead' property
of how much overhead they add - and that other commands use this to
determine the maximum command data field length.

Change-Id: I0a081a23efe20c77557600e62b52ba90a401058d
diff --git a/pySim/commands.py b/pySim/commands.py
index 4e439e6..9a49124 100644
--- a/pySim/commands.py
+++ b/pySim/commands.py
@@ -84,6 +84,14 @@
         """Return the (cached) patched default CLA byte for this card."""
         return self._cla4lchan
 
+    @property
+    def max_cmd_len(self) -> int:
+        """Maximum length of the command apdu data section. Depends on secure channel protocol used."""
+        if self.scp:
+            return 255 - self.scp.overhead
+        else:
+            return 255
+
     @cla_byte.setter
     def cla_byte(self, new_val: Hexstr):
         """Set the (raw, without lchan) default CLA value for this card."""
@@ -318,7 +326,7 @@
         total_data = ''
         chunk_offset = 0
         while chunk_offset < length:
-            chunk_len = min(255, length-chunk_offset)
+            chunk_len = min(self.max_cmd_len, length-chunk_offset)
             pdu = self.cla_byte + \
                 'b0%04x%02x' % (offset + chunk_offset, chunk_len)
             try:
@@ -376,7 +384,7 @@
         total_data = ''
         chunk_offset = 0
         while chunk_offset < data_length:
-            chunk_len = min(255, data_length - chunk_offset)
+            chunk_len = min(self.max_cmd_len, data_length - chunk_offset)
             # chunk_offset is bytes, but data slicing is hex chars, so we need to multiply by 2
             pdu = self.cla_byte + \
                 'd6%04x%02x' % (offset + chunk_offset, chunk_len) + \
@@ -560,10 +568,10 @@
         total_len = len(tlv_bin)
         remaining = tlv_bin
         while len(remaining) > 0:
-            fragment = remaining[:255]
+            fragment = remaining[:self.max_cmd_len]
             rdata, sw = self._set_data(fragment, first=first)
             first = False
-            remaining = remaining[255:]
+            remaining = remaining[self.max_cmd_len:]
         return rdata, sw
 
     def run_gsm(self, rand: Hexstr) -> ResTuple:
diff --git a/pySim/global_platform/__init__.py b/pySim/global_platform/__init__.py
index 4d553a7..9960560 100644
--- a/pySim/global_platform/__init__.py
+++ b/pySim/global_platform/__init__.py
@@ -492,13 +492,14 @@
         def store_data(self, data: bytes, structure:str = 'none', encryption:str = 'none', response_permitted: bool = False) -> bytes:
             """Perform the GlobalPlatform GET DATA command in order to store some card-specific data.
             See GlobalPlatform CardSpecification v2.3Section 11.11 for details."""
+            max_cmd_len = self._cmd.lchan.scc.max_cmd_len
             # Table 11-89 of GP Card Specification v2.3
             remainder = data
             block_nr = 0
             response = ''
             while len(remainder):
-                chunk = remainder[:255]
-                remainder = remainder[255:]
+                chunk = remainder[:max_cmd_len]
+                remainder = remainder[max_cmd_len:]
                 p1b = build_construct(ADF_SD.StoreData,
                                       {'last_block': len(remainder) == 0, 'encryption': encryption,
                                        'structure': structure, 'response': response_permitted})
diff --git a/pySim/global_platform/scp.py b/pySim/global_platform/scp.py
index 0804492..967a582 100644
--- a/pySim/global_platform/scp.py
+++ b/pySim/global_platform/scp.py
@@ -218,6 +218,10 @@
                         'seq_counter'/Int16ub, 'card_challenge'/Bytes(6), 'card_cryptogram'/Bytes(8))
     kvn_range = [0x20, 0x2f]
 
+    def __init__(self, *args, **kwargs):
+        self.overhead = 8
+        super().__init__(*args, **kwargs)
+
     def dek_encrypt(self, plaintext:bytes) -> bytes:
         cipher = DES.new(self.card_keys.dek, DES.MODE_ECB)
         return cipher.encrypt(plaintext)
@@ -410,6 +414,7 @@
 
     def __init__(self, *args, **kwargs):
         self.s_mode = kwargs.pop('s_mode', 8)
+        self.overhead = self.s_mode
         super().__init__(*args, **kwargs)
 
     def dek_encrypt(self, plaintext:bytes) -> bytes: