Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
fido2-storage
FIDO2 largeBlob storage with Argon2id + XChaCha20-Poly1305 encryption.
A pure storage + crypto crate for reading and writing encrypted blobs on FIDO2 hardware (e.g. YubiKey largeBlob). The crate has no knowledge of what is stored — framing, serialization, and application-specific types are the caller's responsibility.
Install
[]
= "0.1"
To use the interactive device-prompt helpers (stdin/stderr I/O), enable the
cli feature:
[]
= { = "0.1", = ["cli"] }
Native dependencies
This crate wraps libfido2 via fido2-rs. The build requires:
- A C compiler and CMake (for building libfido2 from source)
pkg-config(Linux), orFIDO2_LIB_DIR/FIDO2_USE_PKG_CONFIGenv vars- On macOS with Homebrew: OpenSSL headers are keg-only; export
BINDGEN_EXTRA_CLANG_ARGS="-I$(brew --prefix openssl@3)/include"so bindgen can find them
Quick start
use fido2_storage::{Fido2DeviceStore, RelyingParty, CredentialUser};
let rp = RelyingParty {
id: "my-app.local".to_string(),
name: "My App".to_string(),
};
let mut store = Fido2DeviceStore::open("hid:///dev/hidraw0", rp)?;
let user = CredentialUser {
id: &[0x01, 0x02, 0x03, 0x04],
name: "user1",
display_name: Some("User One"),
};
let cred_id = store.write_blob(&user, b"raw blob bytes", "1234")?;
let raw = store.read_blob(&cred_id, Some("1234"))?;
# Ok::<(), anyhow::Error>(())
See examples/crypto_roundtrip.rs for a runnable example of the crypto
layer (no hardware required):
cargo run --example crypto_roundtrip
Architecture
crypto— Argon2id key derivation and XChaCha20-Poly1305 AEAD.KdfParamsbundles salt, nonce, and cost parameters in a 68-byte wire format:salt(32) + nonce(24) + memory_cost(4 BE) + iterations(4 BE) + parallelism(4 BE).store—Fido2DeviceStorefor raw byte I/O on FIDO2 devices. Talks to a connected authenticator (e.g. YubiKey) with thelargeBlobKeyextension to write, read, list, and delete blobs.
derive_key and encrypt/decrypt are separate functions so the caller
controls how many times Argon2id runs. Derive the key once from the user's
password, then pass the 32-byte key to encrypt or decrypt. This avoids
the double-derivation anti-pattern.
Security notes
- Argon2id parameters follow OWASP recommendations:
19 MiB memory cost, 2 iterations, 1 lane. Parameter bounds are enforced by
KdfParams::validate(). - Key zeroization — derived keys and decrypted plaintexts are wrapped in
Zeroizing, which wipes memory on drop. - AAD binding —
encrypt/decryptaccept additional authenticated data. Use the blob header as AAD to bind ciphertext to metadata and prevent tampering. - PIN policy — write and delete operations require a PIN per the CTAP2 spec. PIN/UV errors are never retried (to avoid device lockout).
License
Dual-licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option.