trelent-hyok 0.1.12

A Rust library implementing Hold Your Own Key (HYOK) encryption patterns with support for multiple cloud providers
Documentation
//! Custom encryption strategy implementation.
//!
//! This module enables integration with any encryption algorithm by allowing
//! users to provide their own encryption and decryption functions. It supports:
//!
//! - Custom encryption algorithms
//! - Flexible metadata handling
//! - Error handling
//! - Thread-safe operations

use crate::dek::DEK;
use crate::error::encryption::EncryptionError;
use crate::held_data::encryption::EncryptionStrategy;
use async_trait::async_trait;
use std::sync::Arc;

/// A customizable encryption strategy that accepts user-defined functions.
///
/// This strategy allows integration with any encryption algorithm by accepting
/// closures for encryption and decryption. Features include:
///
/// - Flexible algorithm choice
/// - Custom metadata handling
/// - Error handling
/// - Thread-safe operations
///
/// # Security
///
/// When implementing custom operations, ensure:
/// - Strong encryption algorithms
/// - Proper key handling
/// - Secure metadata management
/// - Authentication where needed
///
/// # Example
/// ```no_run
/// use hyokashi::{CustomStrategy, EncryptionError, DEK};
///
/// // Define custom encryption/decryption functions
/// let encrypt = |dek: DEK, data: Vec<u8>, metadata: Vec<u8>| {
///     Box::pin(async move {
///         // Implement secure encryption...
///         Ok(data)
///     })
/// };
///
/// let decrypt = |dek: DEK, data: Vec<u8>, metadata: Vec<u8>| {
///     Box::pin(async move {
///         // Implement secure decryption...
///         Ok(data)
///     })
/// };
///
/// // Create the custom strategy
/// let strategy = CustomStrategy::new(encrypt, decrypt);
///
/// // Use the strategy
///     let dek = DEK::new(vec![1, 2, 3]);
///     let data = vec![4, 5, 6];
///     let metadata = vec![7, 8, 9];
///
///     let encrypted = strategy.encrypt(dek.clone(), data.clone(), metadata.clone()).await?;
///     let decrypted = strategy.decrypt(dek, encrypted, metadata).await?;
///     assert_eq!(data, decrypted);
///
/// ```
pub struct CustomStrategy<ED: Send> {
    encrypt_fn: Arc<
        dyn (Fn(
            DEK,
            Vec<u8>,
            ED
        ) -> futures::future::BoxFuture<'static, Result<Vec<u8>, EncryptionError>>) +
        Send +
        Sync
    >,
    decrypt_fn: Arc<
        dyn (Fn(
            DEK,
            Vec<u8>,
            ED
        ) -> futures::future::BoxFuture<'static, Result<Vec<u8>, EncryptionError>>) +
        Send +
        Sync
    >,
}

impl<ED: Send> CustomStrategy<ED> {
    /// Creates a new custom strategy with provided encryption and decryption functions
    ///
    /// # Arguments
    /// * `encrypt_fn` - Async function for encryption
    /// * `decrypt_fn` - Async function for decryption
    ///
    /// # Returns
    /// * `Self` - New instance of CustomStrategy
    pub fn new<E, D>(encrypt_fn: E, decrypt_fn: D) -> Self
    where
        E: Fn(
            DEK,
                Vec<u8>,
            ED
        ) -> futures::future::BoxFuture<'static, Result<Vec<u8>, EncryptionError>> +
        Send +
        Sync +
        'static,
        D: Fn(
            DEK,
                Vec<u8>,
            ED
        ) -> futures::future::BoxFuture<'static, Result<Vec<u8>, EncryptionError>> +
        Send +
        Sync +
        'static
    {
        CustomStrategy {
            encrypt_fn: Arc::new(encrypt_fn),
            decrypt_fn: Arc::new(decrypt_fn),
        }
    }
}

/// Container for custom encryption metadata
#[derive(Debug, Clone)]
pub struct CustomEncryptionData {
    /// Custom metadata for encryption/decryption operations
    pub metadata: Vec<u8>,
}

#[async_trait]
impl<ED: Send> EncryptionStrategy for CustomStrategy<ED> {
    type EncryptionData = ED;

    /// Encrypts data using the custom encryption function
    ///
    /// # Arguments
    /// * `dek` - Data Encryption Key
    /// * `plaintext` - Data to encrypt
    /// * `encryption_data` - Custom encryption metadata
    ///
    /// # Returns
    /// * `Result<Vec<u8>, EncryptionError>` - Encrypted data or error
    async fn encrypt(
        &self,
        dek: DEK,
        plaintext: Vec<u8>,
        encryption_data: Self::EncryptionData
    ) -> Result<Vec<u8>, EncryptionError> {
        (self.encrypt_fn)(dek, plaintext, encryption_data).await
    }

    /// Decrypts data using the custom decryption function
    ///
    /// # Arguments
    /// * `dek` - Data Encryption Key
    /// * `ciphertext` - Encrypted data
    /// * `encryption_data` - Custom encryption metadata
    ///
    /// # Returns
    /// * `Result<Vec<u8>, EncryptionError>` - Decrypted data or error
    async fn decrypt(
        &self,
        dek: DEK,
        ciphertext: Vec<u8>,
        encryption_data: Self::EncryptionData
    ) -> Result<Vec<u8>, EncryptionError> {
        (self.decrypt_fn)(dek, ciphertext, encryption_data).await
    }
}