'use strict'; const assert = require('node:assert/strict'); const test = require('node:test'); const { classifyPs5FpkgSyslogEvidence, createPs5FpkgContentAuthTrace, parseKstuffSemanticSnapshot, } = require('../../src/services/ps5-fpkg-content-auth-trace'); const OPERATION_ID = '123e4567-e89b-42d3-a456-426614174000'; const REVISION = '3b2ab4a16ba43c8ab38daf7ec83cc297014e0e47'; const PAYLOAD_SHA256 = '1'.repeat(64); const LOADER_SHA256 = '9'.repeat(64); const FINGERPRINT = 'a'.repeat(64); function runtime(overrides = {}) { return { product: 'EchoStretch/kstuff-lite', version: '1.10', revision: REVISION, payloadSha256: PAYLOAD_SHA256, loaderSha256: LOADER_SHA256, observabilityProfile: 'KSTUFF_OBS-v1.10-semantic-counters', identityStatus: 'exact', traceEligible: true, firmware: '9.60', fingerprint: FINGERPRINT, ...overrides, }; } function snapshot(sequence, metrics, overrides = {}) { return { sequence, sampledAt: 1000 + sequence, runtimeFingerprint: FINGERPRINT, metrics, ...overrides }; } function zeroMetrics() { return { nmountArmed: 0, nmountTrap: 0, nmountEmulated: 0, mailboxFpkg: 0, verifySuperBlockMailbox: 0, verifySuperBlockEmulated: 0, fakeKeyDerivationCalls: 0, fakeKeyDerivationSuccesses: 0, fakeKeyDerivationFailures: 0, fakeKeyRegisters: 0, cryptoRequests: 0, cryptoRequestsEmulated: 0, cryptoRequestsFallback: 0, cryptoRequestsFailed: 0, cryptoHmacMessages: 0, cryptoXtsMessages: 0, cryptoOtherMessages: 0, cryptoEmulatedMessages: 0, rejectXtsNonFake: 0, rejectHmacNonFake: 0, rejectHmacBadShape: 0, rejectOtherMessage: 0, requestNoEmulation: 0, requestFpuEnterFail: 0, }; } test('A6 network 0x8041013d stays separate from content authentication', () => { const evidence = classifyPs5FpkgSyslogEvidence([ '[SceShellUI] ResourceArbitrator returned 0x8041013d', 'ERROR: verifyImage(989) ret -1', 'verify error=0xffffffff -> EICV', 'PfsMountGameData_PPR() ret = 0x80020060', ].join('\n'), 'FAKE00000'); assert.equal(evidence.events[0].subsystem, 'network'); assert.equal(evidence.events[0].category, 'connection_refused'); assert.equal(evidence.events[0].causalStatus, 'unknown'); assert.equal(evidence.firstContentAuthFailure.stage, 'verifyImage'); assert.equal(evidence.firstContentAuthFailure.code, 'PS5_FPKG_VERIFY_IMAGE_FAILED'); assert.notEqual(evidence.firstContentAuthFailure.code, 'PS5_FPKG_CONTENT_AUTH_AND_PFS_MOUNT_FAILED'); }); test('A6 parser accepts only the strict semantic-reader schema', () => { const parsed = parseKstuffSemanticSnapshot([ 'schema=chimera.p15-a6-semantic-metrics.v1', 'status=attached', 'sample=7', 'core mailbox_fpkg=4', 'fakekeys reg=2 derive=1 derive_ok=1 derive_fail=0', 'crypto req=3 emu=2 fallback=1 fail=0 xts_msg=1 hmac_msg=1 other_msg=1 emu_msg=2', 'fpkg verify=1 verify_emu=1', 'fpkg_rejects xts_non_fake=0 hmac_non_fake=0 hmac_shape=0 other=1 no_emu=1 fpu_fail=0', 'syscall[nmount] armed=5 trap=1 emu=1', ].join('\n'), { sequence: 7, sampledAt: 1007, runtimeFingerprint: FINGERPRINT }); assert.equal(parsed.metrics.nmountArmed, 5); assert.equal(parsed.metrics.verifySuperBlockMailbox, 1); assert.equal(parsed.metrics.cryptoHmacMessages, 1); assert.equal(parsed.metrics.cryptoXtsMessages, 1); assert.equal(parsed.metrics.rejectOtherMessage, 1); }); test('A6 parser rejects unknown lines and extra fields before normalization', () => { const base = [ 'schema=chimera.p15-a6-semantic-metrics.v1', 'status=attached', 'sample=7', 'core mailbox_fpkg=4', ]; for (const unsafe of [ 'log-word[0]=0xffff800012345678', 'mailbox-capture[0] request=0x1234 req0=0xdeadbeef', 'core mailbox_fpkg=4 mailbox_unhandled=9', 'fakekeys reg=2 derive=1 derive_ok=1 derive_fail=0 key=forbidden', 'crypto req=3 emu=2 fallback=1 fail=0 xts_msg=1 hmac_msg=1 other_msg=1 emu_msg=2 raw_key=forbidden', ]) { assert.throws( () => parseKstuffSemanticSnapshot([...base, unsafe].join('\n'), { sequence: 7, sampledAt: 1007, runtimeFingerprint: FINGERPRINT }), error => error.code === 'PS5_FPKG_CONTENT_AUTH_TRACE_UNSAFE_LINE', ); } }); test('A6 launch delta excludes stale counters and preserves zero versus nonzero', () => { const pre = snapshot(10, { nmountArmed: 32, nmountTrap: 4, nmountEmulated: 4, mailboxFpkg: 8, verifySuperBlockMailbox: 5, verifySuperBlockEmulated: 5, fakeKeyDerivationCalls: 5, fakeKeyDerivationSuccesses: 5, fakeKeyDerivationFailures: 0, fakeKeyRegisters: 10, cryptoRequests: 20, cryptoRequestsEmulated: 20, cryptoRequestsFallback: 0, cryptoRequestsFailed: 0, cryptoHmacMessages: 10, cryptoXtsMessages: 10, cryptoOtherMessages: 0, cryptoEmulatedMessages: 20, rejectXtsNonFake: 0, rejectHmacNonFake: 0, rejectHmacBadShape: 0, rejectOtherMessage: 0, requestNoEmulation: 0, requestFpuEnterFail: 0, }); const post = snapshot(11, { ...pre.metrics, nmountArmed: 33 }); const trace = createPs5FpkgContentAuthTrace({ operationId: OPERATION_ID, titleId: 'FAKE00000', runtime: runtime(), pre, post, syslog: 'verifyImage ret -1\nEICV\nPfsMountGameData_PPR() ret = 0x80020060', }); assert.equal(trace.delta.nmountArmed, 1); assert.equal(trace.delta.verifySuperBlockMailbox, 0); assert.equal(trace.verifySuperBlock.reached, false); assert.equal(trace.fakeKey.derivationAttempted, false); assert.equal(trace.crypto.requests, 0); assert.equal(trace.firstFailedStage, 'verify_superblock_mailbox_not_reached'); assert.equal(trace.decisionCase, 'A'); assert.equal(trace.productionRestorable, false); }); test('A6 trace retains unknown values as null and rejects counter reset', () => { const pre = snapshot(10, { nmountArmed: 4, nmountTrap: null }); const post = snapshot(11, { nmountArmed: 3, nmountTrap: null }); const trace = createPs5FpkgContentAuthTrace({ operationId: OPERATION_ID, titleId: 'FAKE00000', runtime: runtime(), pre, post, syslog: '' }); assert.equal(trace.delta.nmountArmed, null); assert.equal(trace.delta.nmountTrap, null); assert.equal(trace.metricContinuity, 'counter-reset-or-drift'); assert.equal(trace.status, 'outcome_unknown'); assert.equal(trace.verifyImage.reached, null); assert.equal(trace.firstFailedStage, 'unknown'); }); test('A6 fake-key and crypto outcomes are semantic only', () => { const pre = snapshot(1, zeroMetrics()); const post = snapshot(2, { nmountArmed: 1, nmountTrap: 1, nmountEmulated: 1, mailboxFpkg: 1, verifySuperBlockMailbox: 1, verifySuperBlockEmulated: 1, fakeKeyDerivationCalls: 1, fakeKeyDerivationSuccesses: 1, fakeKeyDerivationFailures: 0, fakeKeyRegisters: 2, cryptoRequests: 2, cryptoRequestsEmulated: 1, cryptoRequestsFallback: 1, cryptoRequestsFailed: 0, cryptoHmacMessages: 1, cryptoXtsMessages: 1, cryptoOtherMessages: 0, cryptoEmulatedMessages: 1, rejectXtsNonFake: 1, rejectHmacNonFake: 0, rejectHmacBadShape: 0, rejectOtherMessage: 0, requestNoEmulation: 1, requestFpuEnterFail: 0, }); const trace = createPs5FpkgContentAuthTrace({ operationId: OPERATION_ID, titleId: 'FAKE00000', runtime: runtime(), pre, post, syslog: 'verifyImage ret -1\nEICV\nPFS mount 0x80020060' }); assert.equal(trace.fakeKey.derivationSucceeded, true); assert.equal(trace.fakeKey.encryptionHandleValid, true); assert.equal(trace.fakeKey.signingHandleValid, true); assert.equal(trace.crypto.hmac, 1); assert.equal(trace.crypto.xts, 1); assert.equal(trace.crypto.fallback, 1); assert.equal(trace.crypto.rejections.xtsNonFake, 1); assert.equal(trace.firstFailedStage, 'crypto_request_rejected_or_not_emulated'); const serialized = JSON.stringify(trace); for (const forbidden of ['keyBytes', 'eekpfs', 'ekpfs', 'dmem', 'mailboxBuffer']) assert.doesNotMatch(serialized, new RegExp(forbidden, 'i')); }); test('A6 runtime revision and hashes are mandatory and snapshots bind to it', () => { const pre = snapshot(1, {}); const post = snapshot(2, {}); assert.throws( () => createPs5FpkgContentAuthTrace({ operationId: OPERATION_ID, titleId: 'FAKE00000', runtime: runtime({ identityStatus: 'unproven' }), pre, post, syslog: '' }), error => error.code === 'PS5_FPKG_KSTUFF_RUNTIME_IDENTITY_UNPROVEN', ); assert.throws( () => createPs5FpkgContentAuthTrace({ operationId: OPERATION_ID, titleId: 'FAKE00000', runtime: runtime({ traceEligible: false }), pre, post, syslog: '' }), error => error.code === 'PS5_FPKG_KSTUFF_RUNTIME_IDENTITY_UNPROVEN', ); assert.throws( () => createPs5FpkgContentAuthTrace({ operationId: OPERATION_ID, titleId: 'FAKE00000', runtime: runtime(), pre, post: { ...post, runtimeFingerprint: 'b'.repeat(64) }, syslog: '' }), error => error.code === 'PS5_FPKG_CONTENT_AUTH_TRACE_RUNTIME_DRIFT', ); }); test('A6 diagnostic profile remains distinct and interrupted result is outcome_unknown', () => { const trace = createPs5FpkgContentAuthTrace({ operationId: OPERATION_ID, titleId: 'FAKE00000', runtime: runtime({ observabilityProfile: 'chimera-p15-fpkg-observe-v1' }), pre: snapshot(1, {}), post: null, syslog: '', interrupted: true, }); assert.equal(trace.status, 'outcome_unknown'); assert.equal(trace.runtime.observabilityProfile, 'chimera-p15-fpkg-observe-v1'); assert.equal(trace.launchRequests, 1); assert.equal(trace.productionRestorable, false); });