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:
@@ -28,6 +28,7 @@ const FNS = [
|
||||
'efDecSpn', 'efDecLoci', 'efDecPsLoci', 'efDecEpsLoci', 'efDecEpsNsc', 'efDecKc', 'efDecAcc',
|
||||
'efDecPhase', 'efDecCbmi', 'efDecCbmir', 'efDecEcc', 'efDecOpl', 'efDecAd', 'efDecAcl',
|
||||
'efDecSmsp', 'efDecSpdi', 'efDecNai', 'efDecDir', 'efDecArr', 'efDecPnn', 'efDecAdn',
|
||||
'pinKeyRefName', 'efArrAmLabel', 'efArrSc', 'efArrAmDo',
|
||||
'efDecExt1', 'efDecSms', 'efDecSume', 'efFindDecoder', 'efFidFromPath', 'efDecodeBytes',
|
||||
'efDecodeFile', 'efDecodeHex', 'efIsRawOnly', 'efFieldLabel', 'efPrimitive', 'efFlatten',
|
||||
'efDiffData', 'efDataSummary', 'efContentDiff', 'gsm7Decode', 'efRenderFieldsHtml',
|
||||
@@ -152,8 +153,22 @@ test('EF record decoders: SMS, OPL, DIR, ARR, IMPI/SMSP', () => {
|
||||
assert.strictEqual(dir.applications.length, 1);
|
||||
assert.strictEqual(dir.applications[0].aid, 'A0000000871002FFFFFFFF8907090000');
|
||||
assert.strictEqual(dir.applications[0].label, 'USim1');
|
||||
// EF.ARR: AM_DO 01 (read) guarded by ADM1 (TS 102 221 9.2.7 / ISO 7816-4 5.4.3.2)
|
||||
const arr = efDecArr(efBytes('800101a40683010a950108'));
|
||||
assert.deepStrictEqual(arr.rules, [{ tag: '0x80', hex: '01' }, { tag: '0xA4', hex: '83010A950108' }]);
|
||||
assert.deepStrictEqual(arr.rules, ['AM 0x01 (READ/SEARCH (EF) / DELETE FILE child (DF)): ADM1 (verify)']);
|
||||
// Two rules: update needs PIN app1 or app2, read is always
|
||||
assert.deepStrictEqual(
|
||||
efDecArr(efBytes('800102a010a406830101950108a4068301029501088001019000')).rules,
|
||||
['AM 0x02 (UPDATE/ERASE (EF) / CREATE FILE EF (DF)): (PIN app1 (verify) OR PIN app2 (verify))',
|
||||
'AM 0x01 (READ/SEARCH (EF) / DELETE FILE child (DF)): always']);
|
||||
// INCREASE / RESIZE ride AM_DO 0x84 with the command INS as value
|
||||
assert.deepStrictEqual(efDecArr(efBytes('8401329000')).rules,
|
||||
['INCREASE (AM_DO 0x84, INS 0x32): always']);
|
||||
assert.deepStrictEqual(efDecArr(efBytes('8401D49000')).rules,
|
||||
['RESIZE FILE (AM_DO 0x84, INS 0xD4): always']);
|
||||
// b8=1: bits 7-4 are proprietary
|
||||
assert.deepStrictEqual(efDecArr(efBytes('8001819000')).rules,
|
||||
['AM 0x81 (bits 7-4 proprietary + READ/SEARCH (EF) / DELETE FILE child (DF)): always']);
|
||||
const impi = efDecNai(efBytes('803137333830303630303030303031303140696d732e6d6e633030302e6d63633733382e336770706e6574776f726b2e6f7267'));
|
||||
assert.strictEqual(impi.text, '738006000000101@ims.mnc000.mcc738.3gppnetwork.org');
|
||||
const smsp = efDecSmsp(efBytes('534d5343ffffffffffffffffffffffffe1ffffffffffffffffffffffff0891945197109099f9ffffff0000a9'));
|
||||
|
||||
Reference in New Issue
Block a user