Files
DeDRM_tools/tests/test_alfcrypto.py
T
JMR-devandClaude Opus 4.8 d6418996dd Harden tests flagged in code review
Strengthen weak-assertion / false-confidence tests:

  - test_alfcrypto: replace the tautological ctx_init determinism check
    with an independent golden vector, and add a golden Topaz decrypt
    vector that does not rely on the test's own inverse helper (so a
    systematic cipher bug is caught, not just round-trip symmetry). Pin
    the PC1 bad-key assertion to match="Bad key length", and load
    alfcrypto via the dedrm package so the test exercises the same module
    object that topazextract/mobidedrm import.
  - test_mobidedrm: pin the PC1 bad-key assertion to the guard message.
  - test_topazextract: make the path-traversal regression rely on the
    depth-independent positive oracle (the sanitised file must land inside
    outdir, which fails against the pre-fix code) plus an exact-contents
    check, instead of brittle parent-path negatives.
  - test_erdr2pml: narrow the import skip to only the missing-cgi case so
    a genuinely broken module fails loudly instead of silently skipping.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 20:35:21 -05:00

69 lines
2.5 KiB
Python

"""Tests for the DeDRM crypto primitives (alfcrypto)."""
import hashlib
import pytest
import dedrm_test_utils as U
# Load via the `dedrm` package so we exercise the same module object that
# topazextract/mobidedrm import through `from .alfcrypto import ...`, rather
# than a second top-level copy.
alf = U.load("alfcrypto", package="dedrm")
def test_pc1_roundtrip():
key = bytes(range(16))
plaintext = b"Hello, Topaz DRM world! 12345678"
encrypted = alf.Pukall_Cipher().PC1(key, plaintext, decryption=False)
assert encrypted != plaintext
assert alf.Pukall_Cipher().PC1(key, encrypted, decryption=True) == plaintext
def test_pc1_rejects_bad_key_length():
# Pin the specific guard, not just "some exception".
with pytest.raises(Exception, match="Bad key length"):
alf.Pukall_Cipher().PC1(b"\x00" * 8, b"data............", decryption=False)
def _topaz_encrypt(data, ctx):
"""Inverse of Topaz_Cipher.decrypt, used to drive a round-trip test."""
ctx1, ctx2 = ctx
out = bytearray()
for plain in data:
out.append((plain ^ ((ctx1 >> 3) & 0xFF) ^ ((ctx2 << 3) & 0xFF)) & 0xFF)
ctx2 = ctx1
ctx1 = (((ctx1 >> 2) * (ctx1 >> 7)) & 0xFFFFFFFF) ^ ((plain * plain * 0x0F902007) & 0xFFFFFFFF)
return bytes(out)
def test_topaz_cipher_roundtrip():
plaintext = b"topaz plaintext bytes"
cipher = alf.Topaz_Cipher()
ctx = cipher.ctx_init(b"mykey123")
ciphertext = _topaz_encrypt(plaintext, list(ctx))
recovered = cipher.decrypt(ciphertext, list(ctx)).encode("latin-1")
assert recovered == plaintext
def test_topaz_ctx_init_golden():
# Independent golden vector pins the key-schedule math; a bare determinism
# check (ctx_init(x) == ctx_init(x)) would pass for any implementation.
assert alf.Topaz_Cipher().ctx_init(b"abc") == [426181496, 3966955212]
def test_topaz_decrypt_golden():
# Golden oracle independent of the test's own inverse helper: a fixed
# ciphertext + key must always decrypt to exactly these bytes. This catches
# a systematic state-update bug that the round-trip test cannot.
ctx = alf.Topaz_Cipher().ctx_init(b"topaz-key")
out = alf.Topaz_Cipher().decrypt(bytes(range(32)), list(ctx)).encode("latin-1")
assert out == bytes.fromhex(
"e64653fbb4c4ad06981b51a0e53cd17ad9c7bc72932626ed35b935791f4fd769"
)
def test_pbkdf2_matches_hashlib():
out = alf.KeyIVGen().pbkdf2(b"password", b"salt", 100, 32)
assert out == hashlib.pbkdf2_hmac("sha1", b"password", b"salt", 100, 32)