Implement decryption
This commit is contained in:
parent
9a60461266
commit
85d0ee7e31
2 changed files with 64 additions and 8 deletions
|
@ -5,6 +5,7 @@ use crate::{storage, InputKeyMaterialList};
|
||||||
use chacha20poly1305::aead::{Aead, KeyInit, Payload};
|
use chacha20poly1305::aead::{Aead, KeyInit, Payload};
|
||||||
use chacha20poly1305::{Key, XChaCha20Poly1305, XNonce};
|
use chacha20poly1305::{Key, XChaCha20Poly1305, XNonce};
|
||||||
|
|
||||||
|
pub(crate) type DecryptionFunction = dyn Fn(&[u8], &EncryptedData, &str) -> Result<Vec<u8>>;
|
||||||
pub(crate) type EncryptionFunction = dyn Fn(&[u8], &[u8], &str) -> Result<EncryptedData>;
|
pub(crate) type EncryptionFunction = dyn Fn(&[u8], &[u8], &str) -> Result<EncryptedData>;
|
||||||
|
|
||||||
pub(crate) struct EncryptedData {
|
pub(crate) struct EncryptedData {
|
||||||
|
@ -12,6 +13,13 @@ pub(crate) struct EncryptedData {
|
||||||
pub(crate) ciphertext: Vec<u8>,
|
pub(crate) ciphertext: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn generate_aad(key_context: &[&str], data_context: &[impl AsRef<[u8]>]) -> String {
|
||||||
|
let key_context_canon = canonicalize(key_context);
|
||||||
|
let data_context_canon = canonicalize(data_context);
|
||||||
|
join_canonicalized_str(&key_context_canon, &data_context_canon)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn encrypt(
|
pub fn encrypt(
|
||||||
ikml: &InputKeyMaterialList,
|
ikml: &InputKeyMaterialList,
|
||||||
key_context: &[&str],
|
key_context: &[&str],
|
||||||
|
@ -23,9 +31,7 @@ pub fn encrypt(
|
||||||
let key = derive_key(ikm, key_context);
|
let key = derive_key(ikm, key_context);
|
||||||
|
|
||||||
// Generate the AAD
|
// Generate the AAD
|
||||||
let key_context_canon = canonicalize(key_context);
|
let aad = generate_aad(key_context, data_context);
|
||||||
let data_context_canon = canonicalize(data_context);
|
|
||||||
let aad = join_canonicalized_str(&key_context_canon, &data_context_canon);
|
|
||||||
|
|
||||||
// Encrypt
|
// Encrypt
|
||||||
let encryption_function = ikm.scheme.get_encryption();
|
let encryption_function = ikm.scheme.get_encryption();
|
||||||
|
@ -68,10 +74,42 @@ pub(crate) fn xchacha20poly1305_encrypt(
|
||||||
pub fn decrypt(
|
pub fn decrypt(
|
||||||
ikml: &InputKeyMaterialList,
|
ikml: &InputKeyMaterialList,
|
||||||
key_context: &[&str],
|
key_context: &[&str],
|
||||||
data: impl AsRef<[u8]>,
|
stored_data: &str,
|
||||||
data_context: &[impl AsRef<[u8]>],
|
data_context: &[impl AsRef<[u8]>],
|
||||||
) -> Result<Vec<u8>> {
|
) -> Result<Vec<u8>> {
|
||||||
unimplemented!("decrypt");
|
// Retreive the IKM and the encrypted data
|
||||||
|
let (ikm_id, encrypted_data) = storage::decode(stored_data)?;
|
||||||
|
let ikm = ikml.get_ikm_by_id(ikm_id)?;
|
||||||
|
|
||||||
|
// Derive the key
|
||||||
|
let key = derive_key(ikm, key_context);
|
||||||
|
|
||||||
|
// Generate the AAD
|
||||||
|
let aad = generate_aad(key_context, data_context);
|
||||||
|
|
||||||
|
// Decrypt
|
||||||
|
let decryption_function = ikm.scheme.get_decryption();
|
||||||
|
decryption_function(&key, &encrypted_data, &aad)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn xchacha20poly1305_decrypt(
|
||||||
|
key: &[u8],
|
||||||
|
encrypted_data: &EncryptedData,
|
||||||
|
aad: &str,
|
||||||
|
) -> Result<Vec<u8>> {
|
||||||
|
// Adapt the key and the nonce
|
||||||
|
let key = Key::from_slice(key);
|
||||||
|
let nonce = XNonce::from_slice(&encrypted_data.nonce);
|
||||||
|
|
||||||
|
// Prepare the payload
|
||||||
|
let payload = Payload {
|
||||||
|
msg: &encrypted_data.ciphertext,
|
||||||
|
aad: aad.as_bytes(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Decrypt the payload
|
||||||
|
let cipher = XChaCha20Poly1305::new(key);
|
||||||
|
Ok(cipher.decrypt(nonce, payload)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -92,6 +130,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn encrypt_decrypt_no_context() {
|
fn encrypt_decrypt_no_context() {
|
||||||
|
// Encrypt
|
||||||
let lst = get_ikm_lst();
|
let lst = get_ikm_lst();
|
||||||
let res = encrypt(&lst, &[], TEST_DATA, EMPTY_DATA_CTX);
|
let res = encrypt(&lst, &[], TEST_DATA, EMPTY_DATA_CTX);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
|
@ -99,11 +138,16 @@ mod tests {
|
||||||
assert!(ciphertext.starts_with("AQAAAA:"));
|
assert!(ciphertext.starts_with("AQAAAA:"));
|
||||||
assert_eq!(ciphertext.len(), 98);
|
assert_eq!(ciphertext.len(), 98);
|
||||||
|
|
||||||
// TODO: decrypt
|
// Decrypt
|
||||||
|
let res = decrypt(&lst, &[], &ciphertext, EMPTY_DATA_CTX);
|
||||||
|
assert!(res.is_ok());
|
||||||
|
let plaintext = res.unwrap();
|
||||||
|
assert_eq!(plaintext, TEST_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn encrypt_decrypt_with_context() {
|
fn encrypt_decrypt_with_context() {
|
||||||
|
// Encrypt
|
||||||
let lst = get_ikm_lst();
|
let lst = get_ikm_lst();
|
||||||
let res = encrypt(&lst, TEST_KEY_CTX, TEST_DATA, TEST_DATA_CTX);
|
let res = encrypt(&lst, TEST_KEY_CTX, TEST_DATA, TEST_DATA_CTX);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
|
@ -111,6 +155,10 @@ mod tests {
|
||||||
assert!(ciphertext.starts_with("AQAAAA:"));
|
assert!(ciphertext.starts_with("AQAAAA:"));
|
||||||
assert_eq!(ciphertext.len(), 98);
|
assert_eq!(ciphertext.len(), 98);
|
||||||
|
|
||||||
// TODO: decrypt
|
// Decrypt
|
||||||
|
let res = decrypt(&lst, TEST_KEY_CTX, &ciphertext, TEST_DATA_CTX);
|
||||||
|
assert!(res.is_ok());
|
||||||
|
let plaintext = res.unwrap();
|
||||||
|
assert_eq!(plaintext, TEST_DATA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::encryption::EncryptionFunction;
|
use crate::encryption::{DecryptionFunction, EncryptionFunction};
|
||||||
use crate::kdf::KdfFunction;
|
use crate::kdf::KdfFunction;
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
|
||||||
|
@ -16,6 +16,14 @@ impl Scheme {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_decryption(&self) -> Box<DecryptionFunction> {
|
||||||
|
match self {
|
||||||
|
Scheme::XChaCha20Poly1305WithBlake3 => {
|
||||||
|
Box::new(crate::encryption::xchacha20poly1305_decrypt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn get_encryption(&self) -> Box<EncryptionFunction> {
|
pub(crate) fn get_encryption(&self) -> Box<EncryptionFunction> {
|
||||||
match self {
|
match self {
|
||||||
Scheme::XChaCha20Poly1305WithBlake3 => {
|
Scheme::XChaCha20Poly1305WithBlake3 => {
|
||||||
|
|
Loading…
Reference in a new issue