]> git.proxmox.com Git - proxmox-backup.git/commitdiff
tape: move key deriving into SgTape
authorDominik Csapak <d.csapak@proxmox.com>
Mon, 22 Jan 2024 11:50:28 +0000 (12:50 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Mon, 22 Jan 2024 12:07:13 +0000 (13:07 +0100)
makes the boundary a bit clearer, introduce 'load_key' to load a single
key from the key config

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
pbs-tape/Cargo.toml
pbs-tape/src/sg_tape.rs
src/tape/drive/lto/mod.rs
src/tape/encryption_keys.rs

index 2b826abd09eb64bfe6858e2d174fafd962c44895..970315b7a80f213f8c2f1783c183f60d20652662 100644 (file)
@@ -14,6 +14,7 @@ lazy_static.workspace = true
 libc.workspace = true
 log.workspace = true
 nix.workspace = true
+openssl.workspace = true
 regex.workspace = true
 serde.workspace = true
 serde_json.workspace = true
index dcf53b725cd70f821df576925687836e4ca5f785..3a1cd026dfe53c68bcc59cef7e6b279ac444ed1d 100644 (file)
@@ -12,6 +12,7 @@ mod encryption;
 pub use encryption::{drive_set_encryption, has_encryption};
 
 mod volume_statistics;
+use proxmox_uuid::Uuid;
 pub use volume_statistics::*;
 
 mod tape_alert_flags;
@@ -652,7 +653,26 @@ impl SgTape {
         read_volume_statistics(&mut self.file)
     }
 
-    pub fn set_encryption(&mut self, key: Option<[u8; 32]>) -> Result<(), Error> {
+    pub fn set_encryption(&mut self, key_data: Option<([u8; 32], Uuid)>) -> Result<(), Error> {
+        let key = if let Some((ref key, ref uuid)) = key_data {
+            // derive specialized key for each media-set
+
+            let mut tape_key = [0u8; 32];
+
+            let uuid_bytes: [u8; 16] = *uuid.as_bytes();
+
+            openssl::pkcs5::pbkdf2_hmac(
+                key,
+                &uuid_bytes,
+                10,
+                openssl::hash::MessageDigest::sha256(),
+                &mut tape_key,
+            )?;
+
+            Some(tape_key)
+        } else {
+            None
+        };
         self.encryption_key_loaded = key.is_some();
 
         drive_set_encryption(&mut self.file, key)
index 3ff989bb4290ad7fb70fcf99a92c0ab97aa90c0b..2a8699c0be297622aae16444ffc73bb98b862ba7 100644 (file)
@@ -272,31 +272,13 @@ impl TapeDriver for LtoTapeHandle {
         key_fingerprint: Option<(Fingerprint, Uuid)>,
     ) -> Result<(), Error> {
         if nix::unistd::Uid::effective().is_root() {
-            if let Some((ref key_fingerprint, ref uuid)) = key_fingerprint {
-                let (key_map, _digest) = crate::tape::encryption_keys::load_keys()?;
-                match key_map.get(key_fingerprint) {
-                    Some(item) => {
-                        // derive specialized key for each media-set
-
-                        let mut tape_key = [0u8; 32];
-
-                        let uuid_bytes: [u8; 16] = *uuid.as_bytes();
-
-                        openssl::pkcs5::pbkdf2_hmac(
-                            &item.key,
-                            &uuid_bytes,
-                            10,
-                            openssl::hash::MessageDigest::sha256(),
-                            &mut tape_key,
-                        )?;
-
-                        return self.sg_tape.set_encryption(Some(tape_key));
-                    }
-                    None => bail!("unknown tape encryption key '{}'", key_fingerprint),
-                }
+            let key_data = if let Some((ref key_fingerprint, ref uuid)) = key_fingerprint {
+                let key = crate::tape::encryption_keys::load_key(key_fingerprint)?;
+                Some((key, uuid.clone()))
             } else {
-                return self.sg_tape.set_encryption(None);
-            }
+                None
+            };
+            return self.sg_tape.set_encryption(key_data);
         }
 
         let output = if let Some((fingerprint, uuid)) = key_fingerprint {
index bc6dee3b26604215e472724431e75d6eef8684a6..1f60c1c6eca475eeecdd4a2754fd757ed424e3e6 100644 (file)
@@ -12,7 +12,7 @@
 
 use std::collections::HashMap;
 
-use anyhow::{bail, Error};
+use anyhow::{bail, format_err, Error};
 use serde::{Deserialize, Serialize};
 
 use proxmox_sys::fs::file_read_optional_string;
@@ -92,6 +92,14 @@ pub fn load_keys() -> Result<(HashMap<Fingerprint, EncryptionKeyInfo>, [u8; 32])
     Ok((map, digest))
 }
 
+pub fn load_key(fingerprint: &Fingerprint) -> Result<[u8; 32], Error> {
+    let (key_map, _digest) = crate::tape::encryption_keys::load_keys()?;
+    key_map
+        .get(fingerprint)
+        .map(|data| data.key)
+        .ok_or_else(|| format_err!("unknown tape encryption key '{fingerprint}'"))
+}
+
 /// Load tape encryption key configurations (password protected keys)
 pub fn load_key_configs() -> Result<(HashMap<Fingerprint, KeyConfig>, [u8; 32]), Error> {
     let content = file_read_optional_string(TAPE_KEY_CONFIG_FILENAME)?;