Skip to content

feat(tbor): implement RSA mod exp#586

Open
vsonims wants to merge 1 commit into
tbor/unwrap-keyfrom
tbor/rsa-crypto
Open

feat(tbor): implement RSA mod exp#586
vsonims wants to merge 1 commit into
tbor/unwrap-keyfrom
tbor/rsa-crypto

Conversation

@vsonims

@vsonims vsonims commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds the TBOR RsaModExp command (opcode 0x1A) — the RSA private-key primitive x = y^d mod n using a caller-held masked RSA private key (imported via UnwrapKey with the RSA / RSA-CRT key class). It is the raw primitive underlying RSA decrypt / sign; the host applies and removes any padding. There is no TBOR RSA key generation — RSA keys enter the device only through UnwrapKey.

Opcode Command Handler
0x1A RsaModExp unmask masked RSA key in place → y^d mod n → reserved x slot

Design (mirrors the sibling TBOR crypto handlers)

  • Unmask-in-place: decode_mut the masked key in the request buffer (no scratch copy); recover modulus size / CRT form from the blob's key kind via a strict from_pal::rsa_key (non-RSA-private kinds → InvalidKeyType).
  • Permission gate: RsaOp::Decrypt requires the decrypt attribute, RsaOp::Sign requires sign (checked post-unmask).
  • Exact-length y validated against the key's modulus length; result written straight into the reserved response x slot.
  • Secret hygiene: the recovered plaintext key is scrubbed from the request buffer on every path.
  • Endianness: y/x are PKA-native wire little-endian; the device flips internally for OpenSSL.

Changes

  • Handler fw/core/lib/src/ddi/tbor/rsa_mod_exp.rs; from_pal::rsa_key mapping; dispatch + 3 classifiers in mod.rs; op.rs from_tbor_opcode.
  • Wire schemas (fw + host mirror) with a 1-byte RsaOp selector + lib.rs registration.
  • Emu tests: host-verified raw RSA sign/decrypt roundtrips for 2K / 3K / 4K / 4K-CRT through the full UnwrapKey(Rsa) → RsaModExp path, plus wrong-y-length and wrong-key-class rejects.
  • Docs: rsa_mod_exp.md + README row.

Testing

  • cargo check fw core (host + Uno no_std) ✅
  • clippy (fw + host) ✅ · nightly fmt ✅ · copyright ✅
  • Full TBOR emu suite: 127 passed.

Notes

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

Add the TBOR RsaModExp command (opcode 0x1A): the RSA private-key
primitive x = y^d mod n using a caller-held masked RSA private key
(imported via UnwrapKey with the RSA / RSA-CRT key class). The device
unmasks the key in place (recovering its modulus size and CRT form from
the blob's key kind), checks the op's usage attribute (Decrypt -> decrypt,
Sign -> sign), computes the modular exponentiation into the reserved
response slot, and scrubs the recovered key on every path. The raw
primitive underlying RSA decrypt / sign — the host applies and removes any
padding. TBOR analogue of MBOR RsaModExp; there is no TBOR RSA key
generation, so RSA keys enter only through UnwrapKey.

Wire schemas (fw + host mirror) with a 1-byte RsaOp selector; dispatch /
classifier / op.rs wiring; a strict from_pal::rsa_key mapping (rejects
non-RSA-private kinds as InvalidKeyType). Emu tests cover host-verified
RSA sign/decrypt roundtrips for 2K/3K/4K and 4K-CRT through the full
UnwrapKey(Rsa) -> RsaModExp path, plus wrong-y-length and wrong-key-class
rejects. Per-command docs added.

Based on tbor/unwrap-key (#583), which provides the DMA-budget-efficient
UnwrapKey that lets RSA-3072/4096 keys be imported within 8 KB.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 0b09e50a-a9be-4bae-b347-d42dc775a258
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.

1 participant