Skip to content

Replace custom AES implementation with cryptography - #624

Merged
yozik04 merged 4 commits into
devfrom
yozik04-aes-with-cryptography
Oct 17, 2026
Merged

yozik04 merged 4 commits into
devfrom
yozik04-aes-with-cryptography

Conversation

@yozik04

@yozik04 yozik04 commented Oct 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Use cryptography's AES-256-ECB implementation instead of the hand-written AES rounds. This is an independent alternative to #623, based directly on dev at dc9384b; it does not include or modify that PR.

Preserve the legacy wire/API behavior:

  • Transpose each 16-byte Paradox block before and after AES; leave key byte order unchanged.
  • Pad short nonempty keys to 32 bytes with 0xEE, use the first 32 bytes of longer keys, and continue rejecting empty keys.
  • Pad only incomplete plaintext blocks with 0xEE; preserve empty/aligned plaintext behavior.
  • Decrypt only complete ciphertext blocks, ignoring partial tails and retaining plaintext padding.
  • Preserve supported byte-input types and exact serial E0 FE and IP150 framing, including checksums and IP header-length trimming.

Add the dependency to both installation manifests and update the encryption documentation. Replace the internal key-schedule test with fixed legacy ciphertext/plaintext vectors and behavioral regressions, including exact serial and IP150 wire vectors.

Compatibility and verification

  • 1,749 tests passed on Python 3.14.0 (two unrelated GSM/asyncio warnings).
  • 92 regression/parser tests passed against the original pure-Python implementation, loaded from the unchanged dc9384b source, as well as against the replacement. Expected ciphertext and serial/IP150 frames were captured from that original implementation, not generated through replacement round trips.
  • Direct differential comparison: 5,040 key/message combinations, with key lengths 1–65, 95–97, 255 and 256 bytes and message lengths 0–65, 127, 128, 255–257 and 512 bytes. Encryption, arbitrary-ciphertext decryption and legacy-ciphertext decryption were byte-for-byte identical.
  • Additional differential checks cover 720 byte-input operation cases (bytes, bytearray, memoryview, lists and tuples) and 144 empty-key rejection cases per implementation.
  • Black, isort, flake8, dependency consistency and diff-whitespace checks passed.

No encryption-mode or protocol-security redesign is included: ECB and legacy padding are retained for panel compatibility.

Preserve Paradox block transposition, padding, key handling, partial ciphertext and serial/IP150 framing. Add fixed legacy vectors and compatibility regressions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 5f934cf6-5389-4a80-b9b7-a5df44ff8929
Comment thread paradox/lib/crypto.py Fixed
Keep actual values first in crypto assertions. Explain why panel-mandated ECB and padding cannot be replaced without breaking wire compatibility; leave the security finding visible.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 5f934cf6-5389-4a80-b9b7-a5df44ff8929
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 5f934cf6-5389-4a80-b9b7-a5df44ff8929
Limit NOSONAR to the ECB mode line; retain the protocol compatibility rationale and documented security limitation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 5f934cf6-5389-4a80-b9b7-a5df44ff8929
@sonarqubecloud

Copy link
Copy Markdown

@yozik04
yozik04 merged commit 84f49fa into dev Oct 17, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants