Skip to main content

veil_core/
context.rs

1use crate::{
2    backend::{TeeBackend, WrappedKey},
3    error::Result,
4    recovery::{BackupBundle, RecoveryStrategy},
5};
6use serde::{Deserialize, Serialize};
7
8/// Main entry point for veil operations.
9pub struct VeilContext {
10    backend: Box<dyn TeeBackend>,
11}
12
13#[derive(Debug, Clone)]
14pub enum FallbackPolicy {
15    /// Error if no TEE hardware is available.
16    Deny,
17    /// Warn and fall back to software backend.
18    Warn,
19    /// Silently fall back to software backend.
20    Software,
21}
22
23impl VeilContext {
24    /// Create a VeilContext with a specific backend (for testing or advanced use).
25    /// Calls `initialize_primary_key()` on the backend.
26    pub fn with_backend(mut backend: Box<dyn TeeBackend>) -> Result<Self> {
27        backend.initialize_primary_key()?;
28        Ok(Self { backend })
29    }
30
31    /// Protect data by generating a Data Key, encrypting, and wrapping.
32    /// The returned `ProtectedData` can be serialized and stored anywhere.
33    pub fn protect(&mut self, data: &[u8]) -> Result<ProtectedData> {
34        let key = self.backend.generate_data_key()?;
35        let ciphertext = self.backend.seal(&key, data)?;
36        Ok(ProtectedData {
37            key,
38            ciphertext,
39            version: 1,
40        })
41    }
42
43    /// Decrypt protected data. Requires the same TEE that produced it.
44    pub fn unprotect(&mut self, protected: &ProtectedData) -> Result<Vec<u8>> {
45        self.backend.unseal(&protected.key, &protected.ciphertext)
46    }
47
48    /// Backup protected data using a chosen recovery strategy.
49    ///
50    /// `secret` is strategy-specific (e.g., passphrase bytes for `PassphraseRecovery`).
51    pub fn backup(
52        &self,
53        protected: &ProtectedData,
54        strategy: &dyn RecoveryStrategy,
55        secret: Option<&[u8]>,
56    ) -> Result<BackupBundle> {
57        strategy.backup(&protected.key, secret)
58    }
59
60    /// Restore protected data from a backup using the matching recovery strategy.
61    pub fn restore(
62        &self,
63        bundle: &BackupBundle,
64        ciphertext: &[u8],
65        strategy: &dyn RecoveryStrategy,
66        secret: &[u8],
67    ) -> Result<ProtectedData> {
68        let key = strategy.restore(bundle, secret)?;
69        Ok(ProtectedData {
70            key,
71            ciphertext: ciphertext.to_vec(),
72            version: 1,
73        })
74    }
75}
76
77/// TEE-protected data. Serializable for persistence.
78/// Cannot be decrypted without the corresponding TEE (or recovery).
79#[derive(Debug, Clone, Serialize, Deserialize)]
80pub struct ProtectedData {
81    key: WrappedKey,
82    pub ciphertext: Vec<u8>,
83    version: u8,
84}