Files
LisherSong--ps5-web-file-ma…/tests
Songlx516 4da345a6e8 feat(7z): decrypt 7zAES packed streams
7-Zip wraps the packed stream of a password protected archive in a 7zAES
coder (method 0x06F10701).  The bundled LZMA SDK has no C implementation of
it, so add one to the folder chain:

  * aes_props_layout() splits the property bytes into numCyclesPower, salt
    and IV exactly as CDecoder::SetDecoderProperties2() does, and rejects a
    block whose declared lengths do not match its size;
  * aes_derive_key() runs the 7-Zip KDF: SHA-256 over
    (salt || password_utf16le || counter_le64) repeated 1 << numCyclesPower
    times, with the 0x3F power meaning "no derivation", the key being the
    salt and password copied into 32 bytes;
  * utf8_to_utf16le() converts the caller's password, since that is the
    encoding 7-Zip hashes;
  * the SZ_N_AES node decrypts one block at a time with Aes_SetKey_Dec() /
    AesCbc_Init() / g_AesCbc_Decode(), keeping the trailing partial block in
    the node so the declared (unpadded) unpack size is what gets delivered.

sz_chain_decode() gains a `password` argument, and sz_chain_needs_password()
lets a caller ask for one before it touches the filesystem.  A folder that
needs a password and did not get one fails as SZ_CHAIN_ERR_PASSWORD with a
message naming 7zAES, rather than as a generic corrupt archive.

Because a wrong password decrypts to plausible looking rubbish, a failure
from a folder that carried a 7zAES coder gets "(a wrong password looks like
this)" appended, so the UI can offer a retry instead of calling the file
damaged.

numCyclesPower comes from the archive and drives 2^n SHA-256 passes, so it is
capped by the limits profile (max_aes_cycles, 2^24 for both the default and
the large profile).

An encrypted *header* (-mhe=on) is a different problem: the archive header is
encrypted with the same coder and has to be decrypted before any folder
exists.  That stays out of scope and is reported as such.

tests/run-sevenz-tests.sh: aes leaves KNOWN_GAPS and passes; aeshe stays
there with the reason spelled out.
2026-09-13 09:13:04 +08:00
..