keyfork-shard: use hkdf for remote shard keys
This commit is contained in:
parent
488e9f48da
commit
3df3caa235
|
@ -906,6 +906,15 @@ version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5491a308e0214554f07a81d8944abe45f552871c12e3c3c6e7e5d354039a6c4c"
|
checksum = "5491a308e0214554f07a81d8944abe45f552871c12e3c3c6e7e5d354039a6c4c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hkdf"
|
||||||
|
version = "0.12.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
|
||||||
|
dependencies = [
|
||||||
|
"hmac",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hmac"
|
name = "hmac"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
|
@ -1152,12 +1161,14 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"card-backend",
|
"card-backend",
|
||||||
"card-backend-pcsc",
|
"card-backend-pcsc",
|
||||||
|
"hkdf",
|
||||||
"keyfork-derive-openpgp",
|
"keyfork-derive-openpgp",
|
||||||
"keyfork-mnemonic-util",
|
"keyfork-mnemonic-util",
|
||||||
"keyfork-prompt",
|
"keyfork-prompt",
|
||||||
"openpgp-card",
|
"openpgp-card",
|
||||||
"openpgp-card-sequoia",
|
"openpgp-card-sequoia",
|
||||||
"sequoia-openpgp",
|
"sequoia-openpgp",
|
||||||
|
"sha2",
|
||||||
"sharks",
|
"sharks",
|
||||||
"smex",
|
"smex",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
|
|
@ -31,3 +31,5 @@ openpgp-card-sequoia = { version = "0.2.0", optional = true }
|
||||||
openpgp-card = { version = "0.4.0", optional = true }
|
openpgp-card = { version = "0.4.0", optional = true }
|
||||||
sequoia-openpgp = { version = "1.16.1", optional = true }
|
sequoia-openpgp = { version = "1.16.1", optional = true }
|
||||||
keyfork-prompt = { version = "0.1.0", path = "../keyfork-prompt", optional = true }
|
keyfork-prompt = { version = "0.1.0", path = "../keyfork-prompt", optional = true }
|
||||||
|
hkdf = { version = "0.12.4", features = ["std"] }
|
||||||
|
sha2 = "0.10.8"
|
||||||
|
|
|
@ -7,6 +7,8 @@ use aes_gcm::{
|
||||||
aead::{Aead, AeadCore, OsRng},
|
aead::{Aead, AeadCore, OsRng},
|
||||||
Aes256Gcm, KeyInit,
|
Aes256Gcm, KeyInit,
|
||||||
};
|
};
|
||||||
|
use hkdf::Hkdf;
|
||||||
|
use sha2::Sha256;
|
||||||
use keyfork_mnemonic_util::{Mnemonic, Wordlist};
|
use keyfork_mnemonic_util::{Mnemonic, Wordlist};
|
||||||
use keyfork_prompt::{qrencode, Message as PromptMessage, PromptManager};
|
use keyfork_prompt::{qrencode, Message as PromptMessage, PromptManager};
|
||||||
use sharks::{Share, Sharks};
|
use sharks::{Share, Sharks};
|
||||||
|
@ -89,8 +91,11 @@ pub fn remote_decrypt(w: &mut impl Write) -> Result<(), Box<dyn std::error::Erro
|
||||||
let shared_secret = our_key
|
let shared_secret = our_key
|
||||||
.diffie_hellman(&PublicKey::from(their_key))
|
.diffie_hellman(&PublicKey::from(their_key))
|
||||||
.to_bytes();
|
.to_bytes();
|
||||||
|
let hkdf = Hkdf::<Sha256>::new(None, &shared_secret);
|
||||||
|
let mut hkdf_output = [0u8; 256 / 8];
|
||||||
|
hkdf.expand(&[], &mut hkdf_output)?;
|
||||||
let shared_key =
|
let shared_key =
|
||||||
Aes256Gcm::new_from_slice(&shared_secret)?;
|
Aes256Gcm::new_from_slice(&hkdf_output)?;
|
||||||
|
|
||||||
let payload = Mnemonic::from_str(&payload_mnemonic)?.entropy();
|
let payload = Mnemonic::from_str(&payload_mnemonic)?.entropy();
|
||||||
let payload =
|
let payload =
|
||||||
|
|
|
@ -10,6 +10,8 @@ use aes_gcm::{
|
||||||
aes::cipher::InvalidLength,
|
aes::cipher::InvalidLength,
|
||||||
Aes256Gcm, Error as AesError, KeyInit, Nonce,
|
Aes256Gcm, Error as AesError, KeyInit, Nonce,
|
||||||
};
|
};
|
||||||
|
use hkdf::{Hkdf, InvalidLength as HkdfInvalidLength};
|
||||||
|
use sha2::Sha256;
|
||||||
use keyfork_derive_openpgp::derive_util::{
|
use keyfork_derive_openpgp::derive_util::{
|
||||||
request::{DerivationAlgorithm, DerivationRequest},
|
request::{DerivationAlgorithm, DerivationRequest},
|
||||||
DerivationPath,
|
DerivationPath,
|
||||||
|
@ -65,6 +67,9 @@ pub enum Error {
|
||||||
#[error("Invalid length of AES key: {0}")]
|
#[error("Invalid length of AES key: {0}")]
|
||||||
AesLength(#[from] InvalidLength),
|
AesLength(#[from] InvalidLength),
|
||||||
|
|
||||||
|
#[error("Invalid KDF length: {0}")]
|
||||||
|
HkdfLength(#[from] HkdfInvalidLength),
|
||||||
|
|
||||||
#[error("Derived secret hash {0} != expected {1}")]
|
#[error("Derived secret hash {0} != expected {1}")]
|
||||||
InvalidSecret(Fingerprint, Fingerprint),
|
InvalidSecret(Fingerprint, Fingerprint),
|
||||||
|
|
||||||
|
@ -442,7 +447,12 @@ pub fn decrypt(
|
||||||
"invalid share length (too long, max {ENC_LEN} bytes)"
|
"invalid share length (too long, max {ENC_LEN} bytes)"
|
||||||
);
|
);
|
||||||
|
|
||||||
let shared_key = Aes256Gcm::new_from_slice(&shared_secret)?;
|
let hkdf = Hkdf::<Sha256>::new(None, &shared_secret);
|
||||||
|
let mut hkdf_output = [0u8; 256 / 8];
|
||||||
|
hkdf.expand(&[], &mut hkdf_output)?;
|
||||||
|
let shared_key =
|
||||||
|
Aes256Gcm::new_from_slice(&hkdf_output)?;
|
||||||
|
|
||||||
let bytes = shared_key.encrypt(their_nonce, share.as_slice())?;
|
let bytes = shared_key.encrypt(their_nonce, share.as_slice())?;
|
||||||
shared_key.decrypt(their_nonce, &bytes[..])?;
|
shared_key.decrypt(their_nonce, &bytes[..])?;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue