Skip to content

Commit

Permalink
changing type of encryption header + test on PKE Aes256
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Khayam authored and Adam Khayam committed May 6, 2024
1 parent 5671366 commit 62f11dd
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 153 deletions.
4 changes: 2 additions & 2 deletions examples/decrypt.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cosmian_cover_crypt::api::EncryptedHeaderAes256;
use cosmian_cover_crypt::api::EncryptedHeader;

const USK: &str = "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";

Expand All @@ -20,7 +20,7 @@ fn main() {
let cc = Covercrypt::default();
let usk = UserSecretKey::deserialize(&transcoder.decode(USK.as_bytes()).unwrap()).unwrap();
let encrypted_header =
EncryptedHeaderAes256::deserialize(&transcoder.decode(HEADER.as_bytes()).unwrap()).unwrap();
EncryptedHeader::deserialize(&transcoder.decode(HEADER.as_bytes()).unwrap()).unwrap();
for _ in 0..100 {
encrypted_header
.decrypt(&cc, &usk, None)
Expand Down
6 changes: 3 additions & 3 deletions examples/encrypt.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use cosmian_cover_crypt::{
abe_policy::{AccessPolicy, Policy},
api::{Covercrypt, EncryptedHeaderAes256},
api::{Covercrypt, EncryptedHeader},
test_utils::policy,
MasterPublicKey, MasterSecretKey,
};
Expand All @@ -15,7 +15,7 @@ fn generate_new(
let access_policy =
AccessPolicy::parse("Department::FIN && Security Level::Top Secret").unwrap();

let (_, _header) = EncryptedHeaderAes256::generate(cc, policy, mpk, &access_policy, None, None)
let (_, _header) = EncryptedHeader::generate(cc, policy, mpk, &access_policy, None, None)
.expect("cannot encrypt header");

#[cfg(feature = "serialization")]
Expand Down Expand Up @@ -59,7 +59,7 @@ fn main() {

// Encrypt header, use loop to increase its wight in the flame graph.
for _ in 0..100 {
EncryptedHeaderAes256::generate(&cc, &policy, &mpk, &ap, None, None)
EncryptedHeader::generate(&cc, &policy, &mpk, &ap, None, None)
.expect("cannot encrypt header");
}
}
7 changes: 3 additions & 4 deletions examples/runme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use cosmian_cover_crypt::{
abe_policy::{AccessPolicy, DimensionBuilder, EncryptionHint, Policy},
api::{Covercrypt, EncryptedHeaderAes256},
api::{Covercrypt, EncryptedHeader},
};

fn main() {
Expand Down Expand Up @@ -54,7 +54,7 @@ fn main() {
.unwrap();

// Encrypt
let (_, encrypted_header) = EncryptedHeaderAes256::generate(
let (_, encrypted_header) = EncryptedHeader::generate(
&cover_crypt,
&policy,
&mpk,
Expand All @@ -79,8 +79,7 @@ fn main() {
let enc_policy = AccessPolicy::parse("Security Level::Top Secret").unwrap();
// Encrypt with rotated attribute
let (_, new_encrypted_header) =
EncryptedHeaderAes256::generate(&cover_crypt, &policy, &mpk, &enc_policy, None, None)
.unwrap();
EncryptedHeader::generate(&cover_crypt, &policy, &mpk, &enc_policy, None, None).unwrap();

// user cannot decrypt the newly encrypted header
assert!(new_encrypted_header
Expand Down
116 changes: 28 additions & 88 deletions src/core/api.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::HashMap, marker::PhantomData, sync::Mutex};
use std::{collections::HashMap, sync::Mutex};

use cosmian_crypto_core::{
kdf256,
Expand Down Expand Up @@ -174,85 +174,55 @@ impl Covercrypt {
}

/// Authenticated Encryption trait
pub trait AE<const KEY_LENGTH: usize, const NONCE_LENGTH: usize, const MAC_LENGTH: usize> {
const KEY_LENGTH: usize;
const NONCE_LENGTH: usize;
const MAC_LENGTH: usize;

/// Encrypts the given plaintext `ptx` using the given `key` and the associated data `ad`.
pub trait AE<const KEY_LENGTH: usize> {
/// Encrypts the given plaintext `ptx` using the given `key`.
fn encrypt(
key: &SymmetricKey<KEY_LENGTH>,
ptx: &[u8],
ad: Option<&[u8]>,
rng: &mut impl CryptoRngCore,
) -> Result<Vec<u8>, Error>;

/// Decrypts the given ciphertext `ctx` using the given `key` and associated data `ad`.
/// Decrypts the given ciphertext `ctx` using the given `key`.
///
/// # Error
///
/// Returns an error if the integrity of the ciphertext could not be verified.
fn decrypt(
key: &SymmetricKey<KEY_LENGTH>,
ctx: &[u8],
ad: Option<&[u8]>,
) -> Result<Vec<u8>, Error>;
fn decrypt(key: &SymmetricKey<KEY_LENGTH>, ctx: &[u8]) -> Result<Vec<u8>, Error>;
}

impl AE<{ Self::KEY_LENGTH }, { Self::NONCE_LENGTH }, { Self::MAC_LENGTH }> for Aes256Gcm {
const KEY_LENGTH: usize = Aes256Gcm::KEY_LENGTH;
const MAC_LENGTH: usize = Aes256Gcm::MAC_LENGTH;
const NONCE_LENGTH: usize = Aes256Gcm::NONCE_LENGTH;

impl AE<{ Self::KEY_LENGTH }> for Aes256Gcm {
fn encrypt(
key: &SymmetricKey<{ Self::KEY_LENGTH }>,
ptx: &[u8],
ad: Option<&[u8]>,
rng: &mut impl CryptoRngCore,
) -> Result<Vec<u8>, Error> {
let nonce = Nonce::<{ Self::NONCE_LENGTH }>::new(&mut *rng);
let ciphertext = Self::new(key).encrypt(&nonce, ptx, ad)?;
let ciphertext = Self::new(key).encrypt(&nonce, ptx, None)?;
Ok([nonce.as_bytes(), &ciphertext].concat())
}

fn decrypt(
key: &SymmetricKey<{ Self::KEY_LENGTH }>,
ctx: &[u8],
ad: Option<&[u8]>,
) -> Result<Vec<u8>, Error> {
fn decrypt(key: &SymmetricKey<{ Self::KEY_LENGTH }>, ctx: &[u8]) -> Result<Vec<u8>, Error> {
if ctx.len() < Self::NONCE_LENGTH {
return Err(Error::CryptoCoreError(
cosmian_crypto_core::CryptoCoreError::DecryptionError,
));
}
let nonce = Nonce::try_from_slice(&ctx[..Self::NONCE_LENGTH])?;
Self::new(key)
.decrypt(&nonce, &ctx[Self::NONCE_LENGTH..], ad)
.decrypt(&nonce, &ctx[Self::NONCE_LENGTH..], None)
.map_err(Error::CryptoCoreError)
}
}

/// Encrypted header holding a `Covercrypt` encapsulation of a `SEED_LENGTH`-byte seed, and metadata
/// encrypted under the scheme `E` using a key derived from the encapsulated seed.
/// Encrypted header holding a `Covercrypt` encapsulation of a 256-byte seed, and metadata
/// encrypted under the scheme AES256Gcm using a key derived from the encapsulated seed.
#[derive(Debug, PartialEq, Eq)]
pub struct EncryptedHeader<
E: AE<KEY_LENGTH, NONCE_LENGTH, MAC_LENGTH>,
const KEY_LENGTH: usize,
const NONCE_LENGTH: usize,
const MAC_LENGTH: usize,
> {
pub struct EncryptedHeader {
pub encapsulation: Encapsulation,
pub encrypted_metadata: Option<Vec<u8>>,
pub phantom: PhantomData<E>,
}

impl<
const KEY_LENGTH: usize,
const NONCE_LENGTH: usize,
const MAC_LENGTH: usize,
E: AE<KEY_LENGTH, NONCE_LENGTH, MAC_LENGTH>,
> EncryptedHeader<E, KEY_LENGTH, NONCE_LENGTH, MAC_LENGTH>
{
impl EncryptedHeader {
/// Generates an encrypted header for a random seed and the given metadata.
/// Returns the encrypted header along with the encapsulated seed.
///
Expand All @@ -275,10 +245,12 @@ impl<

let encrypted_metadata = metadata
.map(|bytes| {
let mut key = SymmetricKey::<KEY_LENGTH>::default();
let mut key = SymmetricKey::<{ Aes256Gcm::KEY_LENGTH }>::default();
kdf256!(&mut key, &seed, &[0u8]);
let mut rng = cover_crypt.rng.lock().expect("poisoned lock");
E::encrypt(&key, bytes, authentication_data, &mut *rng)
let nonce = Nonce::<{ Aes256Gcm::NONCE_LENGTH }>::new(&mut *rng);
let aes = Aes256Gcm::new(&key);
aes.encrypt(&nonce, bytes, authentication_data)
})
.transpose()?;

Expand All @@ -292,12 +264,10 @@ impl<
Self {
encapsulation,
encrypted_metadata,
phantom: PhantomData,
},
))
}


/// Decrypts the header with the given user secret key.
///
/// - `cover_crypt` : `Covercrypt` object
Expand All @@ -316,9 +286,12 @@ impl<
.encrypted_metadata
.as_ref()
.map(|ctx| {
let mut key = SymmetricKey::<KEY_LENGTH>::default();
let mut key = SymmetricKey::<{ Aes256Gcm::KEY_LENGTH }>::default();
kdf256!(&mut key, &seed, &[0u8]);
E::decrypt(&key, ctx, authentication_data)
let mut rng = cover_crypt.rng.lock().expect("poisoned lock");
let nonce = Nonce::<{ Aes256Gcm::NONCE_LENGTH }>::new(&mut *rng);
let aes = Aes256Gcm::new(&key);
aes.decrypt(&nonce, ctx, authentication_data)
})
.transpose()?;

Expand Down Expand Up @@ -393,13 +366,7 @@ impl CovercryptKEM for Covercrypt {
}
}

pub trait CovercryptPKE<
Aead,
const KEY_LENGTH: usize,
const NONCE_LENGTH: usize,
const MAC_LENGTH: usize,
>
{
pub trait CovercryptPKE<Aead, const KEY_LENGTH: usize> {
/// Encrypts the given plaintext using Covercrypt and the given DEM.
///
/// Creates a Covercrypt encapsulation of a 256-bit seed, and use it with
Expand All @@ -413,7 +380,6 @@ pub trait CovercryptPKE<
mpk: &MasterPublicKey,
policy: &Policy,
ap: &AccessPolicy,
ad: Option<&[u8]>,
plaintext: &[u8],
) -> Result<(Encapsulation, Vec<u8>), Error>;

Expand All @@ -429,77 +395,51 @@ pub trait CovercryptPKE<
fn decrypt(
&self,
usk: &UserSecretKey,
ad: Option<&[u8]>,
ciphertext: &[u8],
enc: &Encapsulation,
) -> Result<Option<Vec<u8>>, Error>;
}

impl<
const KEY_LENGTH: usize,
const NONCE_LENGTH: usize,
const MAC_LENGTH: usize,
E: AE<KEY_LENGTH, NONCE_LENGTH, MAC_LENGTH>,
> CovercryptPKE<E, KEY_LENGTH, NONCE_LENGTH, MAC_LENGTH> for Covercrypt
{
impl<const KEY_LENGTH: usize, E: AE<KEY_LENGTH>> CovercryptPKE<E, KEY_LENGTH> for Covercrypt {
fn encrypt(
&self,
mpk: &MasterPublicKey,
policy: &Policy,
ap: &AccessPolicy,
ad: Option<&[u8]>,
plaintext: &[u8],
) -> Result<(Encapsulation, Vec<u8>), Error> {
if SEED_LENGTH < KEY_LENGTH {
return Err(Error::ConversionFailed(format!(
"inssufficient entropy to generate a {}-byte key from a {}-byte seed",
"insufficient entropy to generate a {}-byte key from a {}-byte seed",
KEY_LENGTH, SEED_LENGTH
)));
}
let (seed, enc) = self.encaps(mpk, policy, ap)?;
let mut sym_key = SymmetricKey::default();
kdf256!(&mut sym_key, &seed);
let mut rng = self.rng.lock().expect("poisoned lock");
let res = E::encrypt(&sym_key, plaintext, ad, &mut *rng)?;
let res = E::encrypt(&sym_key, plaintext, &mut *rng)?;
Ok((enc, res))
}

fn decrypt(
&self,
usk: &UserSecretKey,
ad: Option<&[u8]>,
ciphertext: &[u8],
enc: &Encapsulation,
) -> Result<Option<Vec<u8>>, Error> {
if SEED_LENGTH < KEY_LENGTH {
return Err(Error::ConversionFailed(format!(
"inssufficient entropy to generate a {}-byte key from a {}-byte seed",
"insufficient entropy to generate a {}-byte key from a {}-byte seed",
KEY_LENGTH, SEED_LENGTH
)));
}
let seed = self.decaps(usk, enc)?;
seed.map(|seed| {
let mut sym_key = SymmetricKey::<KEY_LENGTH>::default();
kdf256!(&mut sym_key, &seed);
E::decrypt(&sym_key, ciphertext, ad)
E::decrypt(&sym_key, ciphertext)
})
.transpose()
}
}

pub type EncryptedHeaderAes256 = EncryptedHeader<
Aes256Gcm,
{ Aes256Gcm::KEY_LENGTH },
{ Aes256Gcm::NONCE_LENGTH },
{ Aes256Gcm::MAC_LENGTH },
>;

pub trait CovercryptPkeAes256:
CovercryptPKE<
Aes256Gcm,
{ Aes256Gcm::KEY_LENGTH },
{ Aes256Gcm::NONCE_LENGTH },
{ Aes256Gcm::MAC_LENGTH },
>
{
}
11 changes: 1 addition & 10 deletions src/core/serialization/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ use crate::{

use crate::api::CleartextHeader;
use crate::api::EncryptedHeader;
use crate::api::AE;
use core::marker::PhantomData;

impl Serializable for TracingPublicKey {
type Error = Error;
Expand Down Expand Up @@ -534,13 +532,7 @@ impl Serializable for Encapsulation {
}
}

impl<
E: AE<KEY_LENGTH, NONCE_LENGTH, MAC_LENGTH>,
const KEY_LENGTH: usize,
const NONCE_LENGTH: usize,
const MAC_LENGTH: usize,
> Serializable for EncryptedHeader<E, KEY_LENGTH, NONCE_LENGTH, MAC_LENGTH>
{
impl Serializable for EncryptedHeader {
type Error = Error;

fn length(&self) -> usize {
Expand Down Expand Up @@ -574,7 +566,6 @@ impl<
Ok(Self {
encapsulation,
encrypted_metadata,
phantom: PhantomData,
})
}
}
Expand Down
Loading

0 comments on commit 62f11dd

Please sign in to comment.