From f7886fc8fbcdbeac9afaa6cdc5e87a6db6bb5a03 Mon Sep 17 00:00:00 2001 From: John Baublitz Date: Wed, 22 Jan 2025 09:56:35 -0500 Subject: [PATCH] Follow up fixes for reencryption API This commit contains two changes: * Allow CRYPT_ANY_SLOT for keyslot_new for the decryption case. * Extend ability to specify no cipher to reencrypt_init_by_keyring. --- src/luks2/reencrypt.rs | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/luks2/reencrypt.rs b/src/luks2/reencrypt.rs index 79818414..60c5a5eb 100644 --- a/src/luks2/reencrypt.rs +++ b/src/luks2/reencrypt.rs @@ -111,7 +111,7 @@ impl<'a> CryptLuks2ReencryptHandle<'a> { name: Option<&str>, passphrase: &[u8], keyslot_old: Option, - keyslot_new: c_uint, + keyslot_new: Option, cipher_and_mode: Option<(&str, &str)>, params: CryptParamsReencrypt, ) -> Result { @@ -141,7 +141,7 @@ impl<'a> CryptLuks2ReencryptHandle<'a> { to_byte_ptr!(passphrase), passphrase.len(), keyslot_old.map(|k| k as c_int).unwrap_or(CRYPT_ANY_SLOT), - keyslot_new as c_int, + keyslot_new.map(|k| k as c_int).unwrap_or(CRYPT_ANY_SLOT), // NOTE: Must keep as_ref to avoid use after free error. cipher_cstring .as_ref() @@ -163,20 +163,27 @@ impl<'a> CryptLuks2ReencryptHandle<'a> { name: Option<&str>, key_description: &str, keyslot_old: Option, - keyslot_new: c_uint, - cipher_and_mode: (&str, &str), + keyslot_new: Option, + cipher_and_mode: Option<(&str, &str)>, params: CryptParamsReencrypt, ) -> Result { let name_cstring = match name { Some(n) => Some(to_cstring!(n)?), None => None, }; - let (cipher, cipher_mode) = cipher_and_mode; + let (cipher_cstring_err, cipher_mode_cstring_err) = cipher_and_mode + .map(|(c, cm)| { + ( + Some(to_cstring!(c)).transpose(), + Some(to_cstring!(cm)).transpose(), + ) + }) + .unwrap_or_else(|| (Ok(None), Ok(None))); + let cipher_cstring = cipher_cstring_err?; + let cipher_mode_cstring = cipher_mode_cstring_err?; let params_reencrypt: CryptParamsReencryptRef<'_> = (¶ms).try_into()?; let description_cstring = to_cstring!(key_description)?; - let cipher_cstring = to_cstring!(cipher)?; - let cipher_mode_cstring = to_cstring!(cipher_mode)?; errno_int_success!(mutex!( libcryptsetup_rs_sys::crypt_reencrypt_init_by_keyring( self.reference.as_ptr(), @@ -186,9 +193,17 @@ impl<'a> CryptLuks2ReencryptHandle<'a> { .unwrap_or(ptr::null()), description_cstring.as_ptr(), keyslot_old.map(|k| k as c_int).unwrap_or(CRYPT_ANY_SLOT), - keyslot_new as c_int, - cipher_cstring.as_ptr(), - cipher_mode_cstring.as_ptr(), + keyslot_new.map(|k| k as c_int).unwrap_or(CRYPT_ANY_SLOT), + // NOTE: Must keep as_ref to avoid use after free error. + cipher_cstring + .as_ref() + .map(|s| s.as_ptr()) + .unwrap_or_else(ptr::null), + // NOTE: Must keep as_ref to avoid use after free error. + cipher_mode_cstring + .as_ref() + .map(|s| s.as_ptr()) + .unwrap_or_else(ptr::null), params_reencrypt.as_ptr(), ) ))