SL2 Analyzer
Read a FromSoftware .sl2 save and report what is in it
Loading...
Searching...
No Matches
sl2.crypto Namespace Reference

Functions

 _aes_cbc (key, iv, ct)
 AES-128-CBC decrypt, truncated to a whole number of blocks.
 
 decrypt_ds2 (blob, key=DS2_KEY)
 Decrypt a DS2 entry: [16B MD5][16B IV][ciphertext], plaintext prefixed by a uint32 length.
 
 decrypt_iv_prefixed (blob, key)
 Decrypt a DSR or DS3 entry.
 
 decrypt_none (blob)
 "Decrypt" an unencrypted entry (PtDE, Elden Ring).
 
 decrypt_nr (blob, key=NR_KEY)
 Decrypt an Elden Ring Nightreign entry: [16B IV][ciphertext].
 
 nr_checksum_ok (pt)
 Does a decrypted Nightreign entry hash to the digest it carries?
 

Variables

 NR_MD5_FROM_END
 Where the MD5 sits, counting back from the end of a Nightreign plaintext, and how much of the plaintext it covers.
 
 NR_MD5_SKIP
 Where the MD5 sits, counting back from the end of a Nightreign plaintext, and how much of the plaintext it covers.
 

Detailed Description

Per-game entry decryption. Each returns the plaintext game data for one entry,
or None on a bad read.

Function Documentation

◆ _aes_cbc()

sl2.crypto._aes_cbc (   key,
  iv,
  ct 
)
protected

AES-128-CBC decrypt, truncated to a whole number of blocks.

Parameters
keyThe 16-byte key.
ivThe 16-byte initialisation vector.
ctThe ciphertext.
Returns
The decrypted bytes.

Definition at line 19 of file crypto.py.

◆ decrypt_ds2()

sl2.crypto.decrypt_ds2 (   blob,
  key = DS2_KEY 
)

Decrypt a DS2 entry: [16B MD5][16B IV][ciphertext], plaintext prefixed by a uint32 length.

Parameters
blobThe raw entry bytes.
keyDS2_KEY (Scholar) or DS2_VANILLA_KEY (the DX9 original). The two variants share this layout exactly; only the key differs.
Returns
The game data, or None if the length prefix is unreadable.

Definition at line 31 of file crypto.py.

◆ decrypt_iv_prefixed()

sl2.crypto.decrypt_iv_prefixed (   blob,
  key 
)

Decrypt a DSR or DS3 entry.

The IV doubles as the first ciphertext block, so the first 16 decrypted bytes are discarded; the length sits at offset 16 and the data starts at 20.

Parameters
blobThe raw entry bytes.
keyDSR or DS3 key.
Returns
The game data, or None if the length is unreadable.

Definition at line 50 of file crypto.py.

◆ decrypt_none()

sl2.crypto.decrypt_none (   blob)

"Decrypt" an unencrypted entry (PtDE, Elden Ring).

Only the MD5+IV header is stripped; the rest is already plaintext.

Parameters
blobThe raw entry bytes.
Returns
The game data.

Definition at line 61 of file crypto.py.

◆ decrypt_nr()

sl2.crypto.decrypt_nr (   blob,
  key = NR_KEY 
)

Decrypt an Elden Ring Nightreign entry: [16B IV][ciphertext].

Close to DS3's layout and NOT the same, which is the trap. DS3 and DSR put a 16-byte checksum FIRST and the IV second, so their reader takes blob[16:32] as the IV; Nightreign leads with the IV and keeps its MD5 at the end of the plaintext, 28 bytes back. Reading it the DS3 way decrypts to noise that still looks like a buffer.

There is no length prefix either, so nothing here truncates: the whole plaintext is the payload. Use nr_checksum_ok to tell a good decrypt from a bad one.

Parameters
blobThe raw entry bytes.
keyNR_KEY.
Returns
The plaintext, or None if the entry is too short to hold an IV.

Definition at line 78 of file crypto.py.

◆ nr_checksum_ok()

sl2.crypto.nr_checksum_ok (   pt)

Does a decrypted Nightreign entry hash to the digest it carries?

This is the game's own integrity check, and it doubles as the key check — which is why the key above is stated as measured rather than trusted.

Parameters
ptThe decrypted entry.
Returns
True if the stored MD5 matches the data it covers.

Definition at line 96 of file crypto.py.

Variable Documentation

◆ NR_MD5_FROM_END

sl2.crypto.NR_MD5_FROM_END

Where the MD5 sits, counting back from the end of a Nightreign plaintext, and how much of the plaintext it covers.

The hash runs from offset 4 to the start of the digest, so the first four bytes and the twelve trailing ones are outside it.

Definition at line 87 of file crypto.py.

◆ NR_MD5_SKIP

sl2.crypto.NR_MD5_SKIP

Where the MD5 sits, counting back from the end of a Nightreign plaintext, and how much of the plaintext it covers.

The hash runs from offset 4 to the start of the digest, so the first four bytes and the twelve trailing ones are outside it.

Definition at line 87 of file crypto.py.