use openmls_traits::types::HpkeCiphertext;
use crate::ciphersuite::*;
#[openmls_test::openmls_test]
fn test_hpke_seal_open() {
let provider = &Provider::default();
let plaintext = &[1, 2, 3];
let kp = provider
.crypto()
.derive_hpke_keypair(
ciphersuite.hpke_config(),
Secret::random(ciphersuite, provider.rand())
.expect("Not enough randomness.")
.as_slice(),
)
.expect("error deriving hpke key pair");
let ciphertext = hpke::encrypt_with_label(
&kp.public,
"label",
&[1, 2, 3],
plaintext,
ciphersuite,
provider.crypto(),
)
.unwrap();
let decrypted_payload = hpke::decrypt_with_label(
&kp.private,
"label",
&[1, 2, 3],
&ciphertext,
ciphersuite,
provider.crypto(),
)
.expect("Unexpected error while decrypting a valid ciphertext.");
assert_eq!(decrypted_payload, plaintext);
let mut broken_kem_output = ciphertext.kem_output.clone();
broken_kem_output.pop();
let mut broken_ciphertext = ciphertext.ciphertext.clone();
broken_ciphertext.pop();
let broken_ciphertext1 = HpkeCiphertext {
kem_output: broken_kem_output,
ciphertext: ciphertext.ciphertext.clone(),
};
let broken_ciphertext2 = HpkeCiphertext {
kem_output: ciphertext.kem_output,
ciphertext: broken_ciphertext,
};
assert_eq!(
hpke::decrypt_with_label(
&kp.private,
"label",
&[1, 2, 3],
&broken_ciphertext1,
ciphersuite,
provider.crypto(),
)
.map_err(|_| CryptoError::HpkeDecryptionError)
.expect_err("Erroneously correct ciphertext decryption of broken ciphertext."),
CryptoError::HpkeDecryptionError
);
assert_eq!(
hpke::decrypt_with_label(
&kp.private,
"label",
&[1, 2, 3],
&broken_ciphertext2,
ciphersuite,
provider.crypto(),
)
.map_err(|_| CryptoError::HpkeDecryptionError)
.expect_err("Erroneously correct ciphertext decryption of broken ciphertext."),
CryptoError::HpkeDecryptionError
);
}
#[cfg(feature = "extensions-draft")]
#[openmls_test::openmls_test]
fn test_safe_hpke_seal_open() {
use crate::component::ComponentId;
let provider = &Provider::default();
const CONTEXT: &[u8] = &[1, 2, 3];
const LABEL: &str = "label";
let plaintext = &[1, 2, 3];
let kp = provider
.crypto()
.derive_hpke_keypair(
ciphersuite.hpke_config(),
Secret::random(ciphersuite, provider.rand())
.expect("Not enough randomness.")
.as_slice(),
)
.expect("error deriving hpke key pair");
const COMPONENT_ID: ComponentId = 1;
let ciphertext = hpke::safe_encrypt_with_label(
&kp.public,
plaintext,
ciphersuite,
SafeEncryptionContext {
component_id: COMPONENT_ID,
label: LABEL,
context: CONTEXT,
},
provider.crypto(),
)
.unwrap();
let decrypted_payload = hpke::safe_decrypt_with_label(
&kp.private,
&ciphertext,
ciphersuite,
SafeEncryptionContext {
component_id: COMPONENT_ID,
label: LABEL,
context: CONTEXT,
},
provider.crypto(),
)
.expect("Unexpected error while decrypting a valid ciphertext.");
assert_eq!(decrypted_payload, plaintext);
let mut broken_kem_output: Vec<u8> = ciphertext.kem_output.clone().into();
broken_kem_output[0] ^= 0xff;
let mut broken_ciphertext: Vec<u8> = ciphertext.ciphertext.clone().into();
broken_ciphertext[1] ^= 0xff;
let broken_ciphertext1 = HpkeCiphertext {
kem_output: broken_kem_output.into(),
ciphertext: ciphertext.ciphertext.clone(),
};
let broken_ciphertext2 = HpkeCiphertext {
kem_output: ciphertext.kem_output,
ciphertext: broken_ciphertext.into(),
};
assert_eq!(
hpke::safe_decrypt_with_label(
&kp.private,
&broken_ciphertext1,
ciphersuite,
SafeEncryptionContext {
component_id: COMPONENT_ID,
label: LABEL,
context: CONTEXT,
},
provider.crypto(),
)
.map_err(|_| CryptoError::HpkeDecryptionError)
.expect_err("Erroneously correct ciphertext decryption of broken ciphertext."),
CryptoError::HpkeDecryptionError
);
assert_eq!(
hpke::safe_decrypt_with_label(
&kp.private,
&broken_ciphertext2,
ciphersuite,
SafeEncryptionContext {
component_id: COMPONENT_ID,
label: LABEL,
context: CONTEXT,
},
provider.crypto(),
)
.map_err(|_| CryptoError::HpkeDecryptionError)
.expect_err("Erroneously correct ciphertext decryption of broken ciphertext."),
CryptoError::HpkeDecryptionError
);
}