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
This commit is contained in:
Harald Welte
2024-02-15 20:32:41 +01:00
parent 1432af5150
commit 979c837286
3 changed files with 20 additions and 6 deletions

View File

@@ -492,13 +492,14 @@ class ADF_SD(CardADF):
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})

View File

@@ -218,6 +218,10 @@ class SCP02(SCP):
'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 @@ class SCP03(SCP):
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: