Skip to content

Add Ed25519 and X25519 key generation, import and use - #57

Open
FlorianFranzen wants to merge 2 commits into
trussed-dev:mainfrom
FlorianFranzen:feat/x25519
Open

FlorianFranzen wants to merge 2 commits into
trussed-dev:mainfrom
FlorianFranzen:feat/x25519

Conversation

@FlorianFranzen

Copy link
Copy Markdown
Contributor

Two commits, one per algorithm, under the identifiers Yubico firmware 5.7, piv-go and pivy agreed on (#17, #13).

Ed25519 (0xE0)

Adds Ed25519 under the non-standard algorithm identifier 0xE0 that Yubico firmware 5.7, piv-go and pivy use (#17, #13). Only this variant is appended to AsymmetricAlgorithms, so persisted key metadata keeps its variant indices.

  • GENERATE ASYMMETRIC KEY returns the raw 32 byte public key in 7F49 { 86 }, without the SEC1 04 prefix, as Yubico does.
  • IMPORT ASYMMETRIC KEY takes the 32 byte seed in 07, the DO ykman/yubikit send.
  • GENERAL AUTHENTICATE signs the message itself since there is no prehashed Ed25519. sign_len becomes sign_input_len() -> Option<usize>; None means any length up to MAX_MESSAGE_LENGTH, so an oversized request answers 6A80 instead of panicking in the syscall!.
  • SELECT advertises 0xE0. The test-side algorithm enum is corrected to the identifiers the app uses (05, 16, E0, E1).

Tests: generate + sign with length checks, an oversized message, and an import of RFC 8032 test vector 2 with a byte-exact signature. The pivy expectation is updated. Verified by hand with ykman 5.9 against the vpicc card: ykman piv keys generate -a ED25519, ykman piv keys import of an openssl key (public key matches), and signatures verified by Nix (nix store verify). ykman also needs #49 to select the application.

The generate and sign paths come from the v0.8 branch (4bd37ef) by @0x0ece, credited as co-author. The ML-DSA-44 half of that branch is left out: its mechanism implementation only exists in the solokeys trussed fork (trussed-dev/trussed#219 is still open) and the fork spells the variant MlDsa44 where released trussed-core has Mldsa44, so it only builds with a git override.

X25519 (0xE1)

The second commit adds X25519 under the Yubico/piv-go/pivy identifier 0xE1 (#17, #15), appended after Ed25519 so persisted variant indices stay put.

  • GENERATE ASYMMETRIC KEY returns the raw 32 byte public key in 7F49 { 86 }, the same encoding as Ed25519.
  • IMPORT ASYMMETRIC KEY takes the 32 byte private key in 08, the DO ykman/yubikit send for X25519.
  • GENERAL AUTHENTICATE key agreement takes the peer's raw 32 byte u-coordinate in 85, where the NIST curves take a SEC1 point. The shared secret comes back in 7C { 82 } as before. An all-zero secret (a low-order peer key, RFC 7748 section 6.1) is rejected with 6A80, since the ladder itself never fails.
  • sign_mechanism returns an Option so that signing with an X25519 key answers 6985, mirroring what key agreement already answers for a signature-only key.
  • SELECT advertises 0xE1.

Tests: generate + key agreement with length checks, a rejected sign, a rejected short peer key, a rejected order-4 peer key, and an import of RFC 7748 section 6.1 (Alice's key, Bob's public key) producing the RFC's shared secret byte for byte. The pivy expectation is updated for the X25519 entry.

Both commits conflict textually with #56 in import_asymmetric_key (each adds an arm after the RSA one) and in its scalar_len, which then needs an arm for the new variants; whichever lands second keeps all arms and the rsa-gated fallback.

FlorianFranzen added a commit to FlorianFranzen/piv-authenticator that referenced this pull request Oct 16, 2026
- ac4ac85 Add Ed25519 key generation, import and signing
- 8de994f Add X25519 key generation, import and key agreement
FlorianFranzen added a commit to FlorianFranzen/piv-authenticator that referenced this pull request Oct 16, 2026

This branch has not been deployed

No deployments
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