scp80: advance the counter after every send and persist it to the preset (v2.1.9)

The counter only advanced when a PoR came back with status por_ok, so
PoR-less sends kept reusing the same counter (the card rejects a repeated
counter for replay protection). It now advances on every successful send
(and shows "CNTR -> ..." in the result line), and the new value is written
into the selected card preset via spCntrSyncPreset(). Manually edited
counters are persisted too (the field's onchange). New spNextCntr() helper
with carry tests; service worker v146.
This commit is contained in:
2026-09-16 07:30:21 +03:00
parent 3463a68292
commit 4dd09740b7
5 changed files with 46 additions and 21 deletions
+13 -1
View File
@@ -28,7 +28,7 @@ function extractFunc(src, name) {
const FNS = ['hexToBytes', 'bytesToHex', 'des3Keys', 'des3EncryptBlock', 'des3CbcEncrypt',
'xorBytes', 'zeroPad', 'cbcMac', 'aesCbcEncrypt', 'aesShiftLeft1', 'aesCmacSubkeys',
'aesCmac', 'genSp'];
'aesCmac', 'genSp', 'spNextCntr'];
let code = '';
for (const f of FNS) code += extractFunc(html, f) + '\n';
@@ -217,3 +217,15 @@ test('AES rejects 8-byte key', () => {
});
assert.strictEqual(err, 'Error: AES KIc key must be 16, 24, or 32 bytes');
});
test('spNextCntr increments with carry', () => {
assert.strictEqual(spNextCntr('0000000001'), '0000000002');
assert.strictEqual(spNextCntr('00000000FF'), '0000000100');
assert.strictEqual(spNextCntr('000000FFFF'), '0000010000');
assert.strictEqual(spNextCntr('0000ABCDEF'), '0000ABCDF0');
});
test('spNextCntr tolerates lower case and separators', () => {
assert.strictEqual(spNextCntr('00000000 0a'), '000000000B');
assert.strictEqual(spNextCntr(''), '0000000001');
});