Skip to content

Marvin Attack against PKCS#1 v1.5 RSA decryption #26

Description

@curious-rabbit

trussed-rsa uses the rsa = 0.9.8 crate. All versions of this crate
through at least 0.9.x are affected by the documented timing side-
channel in PKCS#1 v1.5 decryption. Reachability is via opcard
PSO-DECIPHER and PIV decrypt operations, into src/lib.rs:333:

  .decrypt(Pkcs1v15Encrypt, &request.message)

The Marvin Attack (Hubert Kario, 2023) exploits timing variability
in PKCS#1 v1.5 unpadding: the time to find the 0x00 padding marker
correlates with plaintext content. With many chosen ciphertexts and
high-resolution timing, the adversary recovers the RSA private key.

Attack reachability on the Nitrokey 3 family:

  • The standard threat model for OpenPGP smartcards assumes the host
    is partially trusted: the user issues authentic operations with
    their PIN, but a malicious application on the same host post-
    authentication can issue arbitrary additional decryption requests.
    This matches the Marvin attack precondition exactly.
  • On a USB-connected token, RSA decryption takes several hundred
    milliseconds (modexp dominates); the PKCS#1 v1.5 unpadding timing
    delta is microseconds; USB transport jitter is also microseconds.
    Signal-to-noise is poor compared to network attacks but not
    infeasible — published Marvin research demonstrates the attack
    against constrained-time signals.
  • The default configuration since firmware 1.7.0 routes opcard
    through the SE050. In that configuration this attack path is
    not reachable. The attack is reachable only when the SE050
    backend has been disabled by the user (for opcard) or where
    PIV uses RSA on a software backend (not the case in current
    NK3 firmware).

Impact.

  • Recovery of the RSA private key by a host-side adversary.
  • For OpenPGP, this means full PGP private key compromise.
  • For PIV, RSA key-management keys are at risk if ever routed
    through software RSA.

Recommended remediation.

  • Track the upstream rsa-crate constant-time effort
    (modpow implementation is not constant-time RustCrypto/RSA#19) and update once available.
  • Until then, consider deliberate response-time randomization in
    the trussed-rsa decrypt path. A random delay drawn from a
    distribution with sufficient variance (e.g., uniform over
    100ms) decorrelates timing observation from internal padding-
    check timing.
  • Document the limitation prominently in the README so downstream
    users know not to disable SE050 routing for opcard.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions