fix: SCP80 RC/CPL parity, file-life-cycle labels, EF.ARR and PS template decoders (v3.5.1)
Three fixes found while filling the ETSI/3GPP registry gaps against the SIMalliance Stepping Stones R7: - SCP80 builder/verification parity (TS 31.115 Table 1 NOTE / 4.2 / 4.3): the CPL is now transmitted whenever the packet is ciphered or carries RC/CC/DS - it is part of their input - and whenever the packet needs SMS concatenation; a single unprotected SM keeps pySim's CHL-first form. Before, the JS dropped the CPL for every unciphered packet while the server reference re-added it, so "Verify vs pySim" reported a false MISMATCH for every unciphered RC/CC packet (SPI1 01/02/0A/12/1A...). All ten offered SPI1 values now match the server reference byte-for-byte. - RC (SPI1 b2b1 = 01) was offered but not built: the JS now computes CRC-32 (TS 102 225 5.1.3.2, pySim zlib.crc32 parity) over the same CPL frame as the CC; the packet no longer silently omits the 4-byte RC field. - Server: _build_secured_packet/_ota_reference add the CPL to a concatenated unprotected packet too (Table 1 NOTE / 4.3). - fcpLifeCycle: unlisted values with b8 clear are RFU, b8 set is proprietary (Table 11.7b); previously all unmatched values were labelled proprietary. - EF.ARR decoder now decodes the expanded format (AM_DO/SC_DO per ISO 7816-4 5.4.3.2 + TS 102 221 9.2.7): operation bit masks, INCREASE/RESIZE AM_DO 0x84, OR/AND/NOT templates, PIN key references with usage qualifiers. - FCP 'C6' PS template DO decoded (PS_DO bitmap + key references + usage qualifiers, TS 102 221 11.1.1.4.10/9.5.2) with a shared key-reference map. Tests: sp.test.js (CPL/RC vectors + crc32 known answer), ef_decode.test.js (expanded-format ARR vectors), profiler.test.js (LCSI RFU/proprietary, C6), test_ota_helpers.py (RC reference, unprotected single-SM vs concatenated). Help EN/RU and READMEs: CPL size 2 (SMS), RC/CC/DS 4-8, RC bullet, CPL rule. 547 frontend / 397 Python green; version 3.5.1; sw cache simple-v253.
This commit is contained in:
@@ -29,7 +29,7 @@ from osmocom.tlv import BER_TLV_IE
|
||||
from osmocom.utils import rpad
|
||||
|
||||
|
||||
VERSION = '3.5.0'
|
||||
VERSION = '3.5.1'
|
||||
|
||||
MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE
|
||||
|
||||
@@ -937,9 +937,12 @@ def _ota_reference(spi1, spi2, kic, kid, tar_hex, cntr_hex, apdu_hex, kic_key_he
|
||||
otak = _ota_keyset(spi1, spi2, kic, kid, cntr_hex, kic_key_hex, kid_key_hex)
|
||||
spi = _spi_from_bytes(int(spi1, 16), int(spi2, 16))
|
||||
out = OtaDialectSms().encode_cmd(otak, h2b(tar_hex), spi, h2b(apdu_hex))
|
||||
if not spi['ciphering'] and spi['rc_cc_ds'] != 'no_rc_cc_ds':
|
||||
if not spi['ciphering'] and (spi['rc_cc_ds'] != 'no_rc_cc_ds'
|
||||
or len(out) > SCP80_SINGLE_BYTES):
|
||||
# pySim drops the CPL octets from its unciphered output; re-add them
|
||||
# (they are included in the RC/CC/DS calculation) per TS 31.115 4.2.
|
||||
# per TS 31.115 4.2 (they are part of the RC/CC/DS input) and per
|
||||
# Table 1 NOTE / 4.3 (required for concatenation - the CHL-to-end
|
||||
# range exceeds one SM).
|
||||
# CPL counts octets from the CHL octet to the last octet of the
|
||||
# Secured Data (incl. padding); pySim's unciphered output is exactly
|
||||
# that range, so the CPL value equals its length.
|
||||
@@ -1031,10 +1034,12 @@ def _build_secured_packet(spi1, spi2, kic, kid, tar_hex, cntr_hex, apdu_hex,
|
||||
otak = _ota_keyset(spi1, spi2, kic, kid, cntr_hex, kic_key_hex, kid_key_hex)
|
||||
spi = _spi_from_bytes(int(spi1, 16), int(spi2, 16))
|
||||
out = _encode_cmd_unlimited(otak, spi, h2b(tar_hex), h2b(apdu_hex))
|
||||
if not spi['ciphering'] and spi['rc_cc_ds'] != 'no_rc_cc_ds':
|
||||
if not spi['ciphering'] and (spi['rc_cc_ds'] != 'no_rc_cc_ds'
|
||||
or len(out) > SCP80_SINGLE_BYTES):
|
||||
# CPL counts octets from the CHL octet to the last octet of the
|
||||
# Secured Data (incl. padding) - exactly the length of the
|
||||
# unciphered range.
|
||||
# unciphered range. Added for the RC/CC/DS input and for
|
||||
# concatenation (TS 31.115 Table 1 NOTE / 4.3).
|
||||
cpl = len(out)
|
||||
out = cpl.to_bytes(2, 'big') + out
|
||||
return b2h(out), spi
|
||||
|
||||
Reference in New Issue
Block a user