Skip to content

age plugin: align PQ host protocol with firmware; 1.2.11 packaging/description#90

Open
0c-coder wants to merge 1 commit into
trustcrypto:tighten-age-plugin-identity-bindingfrom
0c-coder:fix/age-plugin-pq-firmware-alignment
Open

age plugin: align PQ host protocol with firmware; 1.2.11 packaging/description#90
0c-coder wants to merge 1 commit into
trustcrypto:tighten-age-plugin-identity-bindingfrom
0c-coder:fix/age-plugin-pq-firmware-alignment

Conversation

@0c-coder

Copy link
Copy Markdown

age plugin: align PQ host protocol with firmware, + 1.2.11 packaging/description

Bundles the PyPI-description/packaging fix with the post-quantum age-plugin
changes that bring the host protocol in line with the OnlyKey firmware.

Packaging / release

  • setup.py: enable long_description (from README.md, markdown) and
    long_description_content_type so the PyPI page renders a description
    (currently shows "The author of this package has not provided a project
    description"). Bump 1.2.101.2.11 (1.2.10 is already published).
  • MANIFEST.in: ship README.md in the sdist.
  • onlykey/client.py: prefer the Linux hidraw backend, fall back to hid,
    to avoid an "open failed" race when the HID interface was just used by another
    app (PR Avoid hid open failed #89).

Post-quantum age plugin ↔ firmware alignment

The ML-KEM-768 / X-Wing plugin talked to slot/opcode/transport conventions the
firmware does not implement. Corrected to match okcore.cpp / okcrypto.cpp:

  • Slots — PQ keys are a 32-byte seed stored in a user ECC slot. Use the
    real ECC range 101–116 (selectable via --slot, validated), not the
    former 133/134 which the firmware never handled. 117–132 are reserved.
  • Key type — send the firmware key-type byte (KEYTYPE_MLKEM768=5 /
    KEYTYPE_XWING=6) in buffer[6] so the device routes the request.
  • Keygen — use OKSETPRIV with the all-0xFF generate-on-device trigger
    (not the previous wrong opcode), and frame messages with the Message enum.
  • Decapsulation — stream the 1120-byte X-Wing (1088-byte ML-KEM) ciphertext
    with the multi-packet send_large_message2 protocol, exactly as the CLI sends
    RSA/ECDH ciphertext for OKDECRYPT. Previously a single 64-byte report could
    carry only ~57 bytes, so decrypt could never work. The firmware reads the key
    type from the stored key and reassembles the ciphertext. (X-Wing decaps and
    RSA decrypt share identical process_packets / CRYPTO_AUTH branches in
    firmware, so this reuses a proven path.)

Tests (hardware-free)

  • tests/test_age_pq.py — ML-KEM-768 / X-Wing / HPKE software roundtrip and
    spec-constant checks.
  • tests/test_age_wire.py — HID wire-framing: slot/key-type placement, the
    OKSETPRIV generate trigger, reserved-slot rejection, and a multi-packet
    decaps test that reassembles the 1120-byte ciphertext from the packets.

Notes for hardware verification

…scription

- setup.py: enable long_description (markdown), bump 1.2.10 -> 1.2.11
- MANIFEST.in: ship README.md
- client.py: prefer hidraw backend (trustcrypto#89)
- age_plugin: PQ seed in user ECC slot 101-116 (selectable, validated); key
  type in buffer[6]; keygen via OKSETPRIV 0xFF trigger; Message-enum framing;
  multi-packet decapsulation via send_large_message2 (mirrors RSA/ECDH decrypt)
- tests: hardware-free ML-KEM/X-Wing crypto + HID wire-framing/multipacket
@0c-coder

Copy link
Copy Markdown
Author

Firmware counterpart: trustcrypto/libraries#29 — enforces the reserved-slot restriction (host may only write user ECC slots 101–116) on-device. Should land together with #29. Companion packaging release: onlykey/lib-agent#18 (onlykey-agent 1.1.16 PyPI description).

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