* [pbs-devel] [PATCH proxmox-backup v2] tape: skip setting encryption if we can't and don't want to
@ 2025-04-16 7:07 Dominik Csapak
2025-04-17 14:10 ` Andrew Stone
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Dominik Csapak @ 2025-04-16 7:07 UTC (permalink / raw)
To: pbs-devel
Some settings on changers prevents changing the encryption parameters
via the application, e.g. some libraries have a 'encryption disabled' or
'encryption is library managed' option. While the former situation can
be fixed by setting the library to 'application managed', the latter is
sometimes necessary for FIPS compliance (to ensure the tape data is
encrypted).
When libraries are configured this way, the code currently fails with
'drive does not support AES-GCM encryption'. Instead of failing, check
on first call to set_encryption if we could set it, and save that
result.
Only fail when encryption is to be enabled but it is not allowed, but
ignore the error when the backup should be done unencrypted.
`assert_encryption_mode` must also check if it's possible, and skip any
error if it's not possible and we wanted no encryption.
With these changes, it should be possible to use such configured libraries
when there is no encryption configured on the PBS side. (We currently
don't have a library with such capabilities to test.)
Note that in contrast to normal operation, the tape label will also be
encrypted then and will not be readable in case the encryption key is
lost or changed.
Additionally, return an error for 'drive_set_encryption' in case the
drive reports that it does not support hardware encryption, because this
is now already caught one level above in 'set_encryption'.
Also, slightly change the error message to make it clear that the drive
does not support *setting* encryption, not that it does not support
it at all.
This was reported in the community forum:
https://forum.proxmox.com/threads/107383/
https://forum.proxmox.com/threads/164941/
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
changes from v1:
* adapted error message to make it clear what is not supported
* also adapt `assert_encryption_mode`, otherwise a backup is not possible
pbs-tape/src/sg_tape.rs | 30 +++++++++++++++++++++++++++++-
pbs-tape/src/sg_tape/encryption.rs | 12 ++----------
src/tape/drive/lto/mod.rs | 4 ++++
3 files changed, 35 insertions(+), 11 deletions(-)
diff --git a/pbs-tape/src/sg_tape.rs b/pbs-tape/src/sg_tape.rs
index 39e6a2f94..9c7a254d5 100644
--- a/pbs-tape/src/sg_tape.rs
+++ b/pbs-tape/src/sg_tape.rs
@@ -136,6 +136,8 @@ pub struct SgTape {
file: File,
locate_offset: Option<i64>,
info: InquiryInfo,
+ // auto-detect if we can set the encryption mode
+ encryption_possible: Option<bool>,
}
impl SgTape {
@@ -158,6 +160,7 @@ impl SgTape {
file,
info,
locate_offset: None,
+ encryption_possible: None,
})
}
@@ -690,6 +693,14 @@ impl SgTape {
}
pub fn set_encryption(&mut self, key_data: Option<([u8; 32], Uuid)>) -> Result<(), Error> {
+ if self.encryption_possible == Some(false) {
+ if key_data.is_some() {
+ bail!("Drive does not support setting encryption mode");
+ } else {
+ // skip trying to set encryption if not supported and don't wanted
+ return Ok(());
+ }
+ }
let key = if let Some((ref key, ref uuid)) = key_data {
// derive specialized key for each media-set
@@ -710,7 +721,24 @@ impl SgTape {
None
};
- drive_set_encryption(&mut self.file, key)
+ match drive_set_encryption(&mut self.file, key) {
+ Ok(()) => self.encryption_possible = Some(true),
+ Err(err) => {
+ self.encryption_possible = Some(false);
+ if key.is_some() {
+ bail!("could not set encryption mode on drive: {err}");
+ } else {
+ log::info!("could not set encryption mode on drive: {err}, ignoring.");
+ }
+ }
+ }
+ Ok(())
+ }
+
+ /// Returns if encryption is possible. Returns [`None`] if it's unknown, because
+ /// no attempt was made to set the mode yet.
+ pub fn encryption_possible(&self) -> Option<bool> {
+ self.encryption_possible
}
// Note: use alloc_page_aligned_buffer to alloc data transfer buffer
diff --git a/pbs-tape/src/sg_tape/encryption.rs b/pbs-tape/src/sg_tape/encryption.rs
index 7247d257f..c24a6c658 100644
--- a/pbs-tape/src/sg_tape/encryption.rs
+++ b/pbs-tape/src/sg_tape/encryption.rs
@@ -12,15 +12,7 @@ use crate::sgutils2::{alloc_page_aligned_buffer, SgRaw};
///
/// We always use mixed mode,
pub fn drive_set_encryption<F: AsRawFd>(file: &mut F, key: Option<[u8; 32]>) -> Result<(), Error> {
- let data = match sg_spin_data_encryption_caps(file) {
- Ok(data) => data,
- Err(_) if key.is_none() => {
- // Assume device does not support HW encryption
- // We can simply ignore the clear key request
- return Ok(());
- }
- Err(err) => return Err(err),
- };
+ let data = sg_spin_data_encryption_caps(file)?;
let algorithm_index = decode_spin_data_encryption_caps(&data)?;
@@ -266,7 +258,7 @@ fn decode_spin_data_encryption_caps(data: &[u8]) -> Result<u8, Error> {
match aes_gcm_index {
Some(index) => Ok(index),
- None => bail!("drive does not support AES-GCM encryption"),
+ None => bail!("drive does not support setting AES-GCM encryption"),
}
})
.map_err(|err: Error| format_err!("decode data encryption caps page failed - {}", err))
diff --git a/src/tape/drive/lto/mod.rs b/src/tape/drive/lto/mod.rs
index 23e043ce6..bd5ec8ae6 100644
--- a/src/tape/drive/lto/mod.rs
+++ b/src/tape/drive/lto/mod.rs
@@ -264,6 +264,10 @@ impl TapeDriver for LtoTapeHandle {
}
fn assert_encryption_mode(&mut self, encryption_wanted: bool) -> Result<(), Error> {
+ if Some(false) == self.sg_tape.encryption_possible() && !encryption_wanted {
+ // ignore assertion for unencrypted mode, because we can't set it anyway
+ return Ok(());
+ }
let encryption_set = drive_get_encryption(self.sg_tape.file_mut())?;
if encryption_wanted != encryption_set {
bail!("Set encryption mode not what was desired (set: {encryption_set}, wanted: {encryption_wanted})");
--
2.39.5
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [pbs-devel] [PATCH proxmox-backup v2] tape: skip setting encryption if we can't and don't want to
2025-04-16 7:07 [pbs-devel] [PATCH proxmox-backup v2] tape: skip setting encryption if we can't and don't want to Dominik Csapak
@ 2025-04-17 14:10 ` Andrew Stone
2025-07-11 10:09 ` Dominik Csapak
` (2 subsequent siblings)
3 siblings, 0 replies; 8+ messages in thread
From: Andrew Stone @ 2025-04-17 14:10 UTC (permalink / raw)
To: d.csapak; +Cc: Proxmox Backup Server development discussion
Tested-by: Andrew Stone astone@tvammo.com
When tape pool is set to no encryption, backups are written to tape as expected.
When tape pool is set to use encryption, process fails as expected when PBS attempts to set the encryption mode.
See community forum link for full details:
https://forum.proxmox.com/threads/fips-mode-on-tape-library-pbs-errors-out-on-labeling.164941/
________________________________
The information contained in this e-mail and any attachments may contain confidential and/or proprietary information, and is intended only for the named recipient to whom it was originally addressed. If you are not the intended recipient, any disclosure, distribution, or copying of this e-mail or its attachments is strictly prohibited. If you have received this e-mail in error, please notify the sender immediately by return e-mail and permanently delete the e-mail and any attachments.
WARNING: The recipient of this email acknowledges and understands that certain information contained in this email or in an attachment to this email may be subject to export controls and restrictions including, but not limited to, the International Traffic in Arms Regulations (ITAR), the Export Administration Regulations (EAR) or the sanctions administered by the Office of Foreign Assets Control (OFAC). The recipient agrees not to disclose, transfer, or otherwise export or re-export any technical data or other restricted information to any Foreign Person (including any foreign national, foreign business or foreign government), whether in the United States or abroad, without fully complying with U.S. export control regulations, including obtaining any necessary license or other prior authorization required from the appropriate agencies of the U.S. Government.
Public Content
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [pbs-devel] [PATCH proxmox-backup v2] tape: skip setting encryption if we can't and don't want to
2025-04-16 7:07 [pbs-devel] [PATCH proxmox-backup v2] tape: skip setting encryption if we can't and don't want to Dominik Csapak
2025-04-17 14:10 ` Andrew Stone
@ 2025-07-11 10:09 ` Dominik Csapak
2025-07-11 11:45 ` Thomas Lamprecht
2025-07-22 17:16 ` Thomas Lamprecht
3 siblings, 0 replies; 8+ messages in thread
From: Dominik Csapak @ 2025-07-11 10:09 UTC (permalink / raw)
To: pbs-devel
ping, should still apply as is, but we got an additional user
running into this problem:
https://forum.proxmox.com/threads/fips-mode-on-tape-library-pbs-errors-out-on-labeling.164941/#post-782914
On 4/16/25 09:07, Dominik Csapak wrote:
> Some settings on changers prevents changing the encryption parameters
> via the application, e.g. some libraries have a 'encryption disabled' or
> 'encryption is library managed' option. While the former situation can
> be fixed by setting the library to 'application managed', the latter is
> sometimes necessary for FIPS compliance (to ensure the tape data is
> encrypted).
>
> When libraries are configured this way, the code currently fails with
> 'drive does not support AES-GCM encryption'. Instead of failing, check
> on first call to set_encryption if we could set it, and save that
> result.
>
> Only fail when encryption is to be enabled but it is not allowed, but
> ignore the error when the backup should be done unencrypted.
>
> `assert_encryption_mode` must also check if it's possible, and skip any
> error if it's not possible and we wanted no encryption.
>
> With these changes, it should be possible to use such configured libraries
> when there is no encryption configured on the PBS side. (We currently
> don't have a library with such capabilities to test.)
>
> Note that in contrast to normal operation, the tape label will also be
> encrypted then and will not be readable in case the encryption key is
> lost or changed.
>
> Additionally, return an error for 'drive_set_encryption' in case the
> drive reports that it does not support hardware encryption, because this
> is now already caught one level above in 'set_encryption'.
>
> Also, slightly change the error message to make it clear that the drive
> does not support *setting* encryption, not that it does not support
> it at all.
>
> This was reported in the community forum:
>
> https://forum.proxmox.com/threads/107383/
> https://forum.proxmox.com/threads/164941/
>
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
> changes from v1:
> * adapted error message to make it clear what is not supported
> * also adapt `assert_encryption_mode`, otherwise a backup is not possible
>
> pbs-tape/src/sg_tape.rs | 30 +++++++++++++++++++++++++++++-
> pbs-tape/src/sg_tape/encryption.rs | 12 ++----------
> src/tape/drive/lto/mod.rs | 4 ++++
> 3 files changed, 35 insertions(+), 11 deletions(-)
>
> diff --git a/pbs-tape/src/sg_tape.rs b/pbs-tape/src/sg_tape.rs
> index 39e6a2f94..9c7a254d5 100644
> --- a/pbs-tape/src/sg_tape.rs
> +++ b/pbs-tape/src/sg_tape.rs
> @@ -136,6 +136,8 @@ pub struct SgTape {
> file: File,
> locate_offset: Option<i64>,
> info: InquiryInfo,
> + // auto-detect if we can set the encryption mode
> + encryption_possible: Option<bool>,
> }
>
> impl SgTape {
> @@ -158,6 +160,7 @@ impl SgTape {
> file,
> info,
> locate_offset: None,
> + encryption_possible: None,
> })
> }
>
> @@ -690,6 +693,14 @@ impl SgTape {
> }
>
> pub fn set_encryption(&mut self, key_data: Option<([u8; 32], Uuid)>) -> Result<(), Error> {
> + if self.encryption_possible == Some(false) {
> + if key_data.is_some() {
> + bail!("Drive does not support setting encryption mode");
> + } else {
> + // skip trying to set encryption if not supported and don't wanted
> + return Ok(());
> + }
> + }
> let key = if let Some((ref key, ref uuid)) = key_data {
> // derive specialized key for each media-set
>
> @@ -710,7 +721,24 @@ impl SgTape {
> None
> };
>
> - drive_set_encryption(&mut self.file, key)
> + match drive_set_encryption(&mut self.file, key) {
> + Ok(()) => self.encryption_possible = Some(true),
> + Err(err) => {
> + self.encryption_possible = Some(false);
> + if key.is_some() {
> + bail!("could not set encryption mode on drive: {err}");
> + } else {
> + log::info!("could not set encryption mode on drive: {err}, ignoring.");
> + }
> + }
> + }
> + Ok(())
> + }
> +
> + /// Returns if encryption is possible. Returns [`None`] if it's unknown, because
> + /// no attempt was made to set the mode yet.
> + pub fn encryption_possible(&self) -> Option<bool> {
> + self.encryption_possible
> }
>
> // Note: use alloc_page_aligned_buffer to alloc data transfer buffer
> diff --git a/pbs-tape/src/sg_tape/encryption.rs b/pbs-tape/src/sg_tape/encryption.rs
> index 7247d257f..c24a6c658 100644
> --- a/pbs-tape/src/sg_tape/encryption.rs
> +++ b/pbs-tape/src/sg_tape/encryption.rs
> @@ -12,15 +12,7 @@ use crate::sgutils2::{alloc_page_aligned_buffer, SgRaw};
> ///
> /// We always use mixed mode,
> pub fn drive_set_encryption<F: AsRawFd>(file: &mut F, key: Option<[u8; 32]>) -> Result<(), Error> {
> - let data = match sg_spin_data_encryption_caps(file) {
> - Ok(data) => data,
> - Err(_) if key.is_none() => {
> - // Assume device does not support HW encryption
> - // We can simply ignore the clear key request
> - return Ok(());
> - }
> - Err(err) => return Err(err),
> - };
> + let data = sg_spin_data_encryption_caps(file)?;
>
> let algorithm_index = decode_spin_data_encryption_caps(&data)?;
>
> @@ -266,7 +258,7 @@ fn decode_spin_data_encryption_caps(data: &[u8]) -> Result<u8, Error> {
>
> match aes_gcm_index {
> Some(index) => Ok(index),
> - None => bail!("drive does not support AES-GCM encryption"),
> + None => bail!("drive does not support setting AES-GCM encryption"),
> }
> })
> .map_err(|err: Error| format_err!("decode data encryption caps page failed - {}", err))
> diff --git a/src/tape/drive/lto/mod.rs b/src/tape/drive/lto/mod.rs
> index 23e043ce6..bd5ec8ae6 100644
> --- a/src/tape/drive/lto/mod.rs
> +++ b/src/tape/drive/lto/mod.rs
> @@ -264,6 +264,10 @@ impl TapeDriver for LtoTapeHandle {
> }
>
> fn assert_encryption_mode(&mut self, encryption_wanted: bool) -> Result<(), Error> {
> + if Some(false) == self.sg_tape.encryption_possible() && !encryption_wanted {
> + // ignore assertion for unencrypted mode, because we can't set it anyway
> + return Ok(());
> + }
> let encryption_set = drive_get_encryption(self.sg_tape.file_mut())?;
> if encryption_wanted != encryption_set {
> bail!("Set encryption mode not what was desired (set: {encryption_set}, wanted: {encryption_wanted})");
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [pbs-devel] [PATCH proxmox-backup v2] tape: skip setting encryption if we can't and don't want to
2025-04-16 7:07 [pbs-devel] [PATCH proxmox-backup v2] tape: skip setting encryption if we can't and don't want to Dominik Csapak
2025-04-17 14:10 ` Andrew Stone
2025-07-11 10:09 ` Dominik Csapak
@ 2025-07-11 11:45 ` Thomas Lamprecht
2025-07-11 13:29 ` Dominik Csapak
2025-07-22 17:16 ` Thomas Lamprecht
3 siblings, 1 reply; 8+ messages in thread
From: Thomas Lamprecht @ 2025-07-11 11:45 UTC (permalink / raw)
To: Proxmox Backup Server development discussion, Dominik Csapak
The subject reads a bit sassy ^^
Am 16.04.25 um 09:07 schrieb Dominik Csapak:
> Some settings on changers prevents changing the encryption parameters
> via the application, e.g. some libraries have a 'encryption disabled' or
> 'encryption is library managed' option. While the former situation can
> be fixed by setting the library to 'application managed', the latter is
> sometimes necessary for FIPS compliance (to ensure the tape data is
> encrypted).
>
> When libraries are configured this way, the code currently fails with
> 'drive does not support AES-GCM encryption'. Instead of failing, check
> on first call to set_encryption if we could set it, and save that
> result.
Could that result in a transient transport/HW/... error becoming
permanent? I mean, probably not hugely likely, but with such "automagic"
behavior it might be worth about thinking of some potential exit
strategy for the user, or is the lifetime bound to only a single job
anyway – I could naturally check myself, but might be nice to mention
that here.
>
> Only fail when encryption is to be enabled but it is not allowed, but
> ignore the error when the backup should be done unencrypted.
>
> `assert_encryption_mode` must also check if it's possible, and skip any
> error if it's not possible and we wanted no encryption.
>
> With these changes, it should be possible to use such configured libraries
> when there is no encryption configured on the PBS side. (We currently
> don't have a library with such capabilities to test.)
>
> Note that in contrast to normal operation, the tape label will also be
> encrypted then and will not be readable in case the encryption key is
> lost or changed.
>
> Additionally, return an error for 'drive_set_encryption' in case the
> drive reports that it does not support hardware encryption, because this
> is now already caught one level above in 'set_encryption'.
nit: "already" implies to me that it's checked upfront or handled by a
method called, not one that calls us.
"[...] because this is now handled a level above"
is IMO a bit better fitting
>
> Also, slightly change the error message to make it clear that the drive
> does not support *setting* encryption, not that it does not support
> it at all.
>
> This was reported in the community forum:
>
> https://forum.proxmox.com/threads/107383/
> https://forum.proxmox.com/threads/164941/
>
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
> changes from v1:
> * adapted error message to make it clear what is not supported
> * also adapt `assert_encryption_mode`, otherwise a backup is not possible
>
> pbs-tape/src/sg_tape.rs | 30 +++++++++++++++++++++++++++++-
> pbs-tape/src/sg_tape/encryption.rs | 12 ++----------
> src/tape/drive/lto/mod.rs | 4 ++++
> 3 files changed, 35 insertions(+), 11 deletions(-)
>
> diff --git a/pbs-tape/src/sg_tape.rs b/pbs-tape/src/sg_tape.rs
> index 39e6a2f94..9c7a254d5 100644
> --- a/pbs-tape/src/sg_tape.rs
> +++ b/pbs-tape/src/sg_tape.rs
> @@ -136,6 +136,8 @@ pub struct SgTape {
> file: File,
> locate_offset: Option<i64>,
> info: InquiryInfo,
> + // auto-detect if we can set the encryption mode
> + encryption_possible: Option<bool>,
> }
>
> impl SgTape {
> @@ -158,6 +160,7 @@ impl SgTape {
> file,
> info,
> locate_offset: None,
> + encryption_possible: None,
> })
> }
>
> @@ -690,6 +693,14 @@ impl SgTape {
> }
>
> pub fn set_encryption(&mut self, key_data: Option<([u8; 32], Uuid)>) -> Result<(), Error> {
> + if self.encryption_possible == Some(false) {
> + if key_data.is_some() {
> + bail!("Drive does not support setting encryption mode");
> + } else {
> + // skip trying to set encryption if not supported and don't wanted
s/don't/not/ and s/set/clear/ (still not ideal but slightly better IMO).
btw. if one enabled encryption before changing the library to FIPS (or
whatever blocks this setting then) and then cleared encryption we might
then signal that it work the next time this method is called while it
did not, seems a bit odd.
Albeit, if that question even makes sense depends on the lifetime of the
encryption_possible setting.
Did you evaluate if exposing a setting the user has to explicitly enable?
Not saying that is better, but might be a bit simpler to understand and
probably also slightly safer to implement (or at least review hehe), I think.
OTOTH., not much in the tape code atm., so my questions might be bogus and
my reservation for this unfounded.
> + return Ok(());
> + }
> + }
> let key = if let Some((ref key, ref uuid)) = key_data {
> // derive specialized key for each media-set
>
> @@ -710,7 +721,24 @@ impl SgTape {
> None
> };
>
> - drive_set_encryption(&mut self.file, key)
> + match drive_set_encryption(&mut self.file, key) {
> + Ok(()) => self.encryption_possible = Some(true),
> + Err(err) => {
> + self.encryption_possible = Some(false);
> + if key.is_some() {
> + bail!("could not set encryption mode on drive: {err}");
> + } else {
> + log::info!("could not set encryption mode on drive: {err}, ignoring.");
While internally naming the function "set" might be fine, it always sets some
value after all, but I'd not leak that outside and rather do s/set/clear/ for
above log message, as otherwise the user will interpret this as we tried to
set (= enable) encryption, failed and just ignore it, which seems rather unsafe
from their POV.
> + }
> + }
> + }
> + Ok(())
> + }
> +
> + /// Returns if encryption is possible. Returns [`None`] if it's unknown, because
> + /// no attempt was made to set the mode yet.
> + pub fn encryption_possible(&self) -> Option<bool> {
> + self.encryption_possible
> }
>
> // Note: use alloc_page_aligned_buffer to alloc data transfer buffer
> diff --git a/pbs-tape/src/sg_tape/encryption.rs b/pbs-tape/src/sg_tape/encryption.rs
> index 7247d257f..c24a6c658 100644
> --- a/pbs-tape/src/sg_tape/encryption.rs
> +++ b/pbs-tape/src/sg_tape/encryption.rs
> @@ -12,15 +12,7 @@ use crate::sgutils2::{alloc_page_aligned_buffer, SgRaw};
> ///
> /// We always use mixed mode,
> pub fn drive_set_encryption<F: AsRawFd>(file: &mut F, key: Option<[u8; 32]>) -> Result<(), Error> {
> - let data = match sg_spin_data_encryption_caps(file) {
> - Ok(data) => data,
> - Err(_) if key.is_none() => {
> - // Assume device does not support HW encryption
> - // We can simply ignore the clear key request
> - return Ok(());
> - }
> - Err(err) => return Err(err),
> - };
> + let data = sg_spin_data_encryption_caps(file)?;
>
> let algorithm_index = decode_spin_data_encryption_caps(&data)?;
>
> @@ -266,7 +258,7 @@ fn decode_spin_data_encryption_caps(data: &[u8]) -> Result<u8, Error> {
>
> match aes_gcm_index {
> Some(index) => Ok(index),
> - None => bail!("drive does not support AES-GCM encryption"),
> + None => bail!("drive does not support setting AES-GCM encryption"),
> }
> })
> .map_err(|err: Error| format_err!("decode data encryption caps page failed - {}", err))
> diff --git a/src/tape/drive/lto/mod.rs b/src/tape/drive/lto/mod.rs
> index 23e043ce6..bd5ec8ae6 100644
> --- a/src/tape/drive/lto/mod.rs
> +++ b/src/tape/drive/lto/mod.rs
> @@ -264,6 +264,10 @@ impl TapeDriver for LtoTapeHandle {
> }
>
> fn assert_encryption_mode(&mut self, encryption_wanted: bool) -> Result<(), Error> {
> + if Some(false) == self.sg_tape.encryption_possible() && !encryption_wanted {
> + // ignore assertion for unencrypted mode, because we can't set it anyway
s/because/if/ ?
> + return Ok(());
> + }
> let encryption_set = drive_get_encryption(self.sg_tape.file_mut())?;
> if encryption_wanted != encryption_set {
> bail!("Set encryption mode not what was desired (set: {encryption_set}, wanted: {encryption_wanted})");
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [pbs-devel] [PATCH proxmox-backup v2] tape: skip setting encryption if we can't and don't want to
2025-07-11 11:45 ` Thomas Lamprecht
@ 2025-07-11 13:29 ` Dominik Csapak
2025-07-11 15:09 ` Thomas Lamprecht
0 siblings, 1 reply; 8+ messages in thread
From: Dominik Csapak @ 2025-07-11 13:29 UTC (permalink / raw)
To: Thomas Lamprecht, Proxmox Backup Server development discussion
On 7/11/25 13:45, Thomas Lamprecht wrote:
> The subject reads a bit sassy ^^
>
>
> Am 16.04.25 um 09:07 schrieb Dominik Csapak:
>> Some settings on changers prevents changing the encryption parameters
>> via the application, e.g. some libraries have a 'encryption disabled' or
>> 'encryption is library managed' option. While the former situation can
>> be fixed by setting the library to 'application managed', the latter is
>> sometimes necessary for FIPS compliance (to ensure the tape data is
>> encrypted).
>>
>> When libraries are configured this way, the code currently fails with
>> 'drive does not support AES-GCM encryption'. Instead of failing, check
>> on first call to set_encryption if we could set it, and save that
>> result.
>
> Could that result in a transient transport/HW/... error becoming
> permanent? I mean, probably not hugely likely, but with such "automagic"
> behavior it might be worth about thinking of some potential exit
> strategy for the user, or is the lifetime bound to only a single job
> anyway – I could naturally check myself, but might be nice to mention
> that here.
no that is just per job/action so each time we open the tape drive.
can reword that part to make it clearer
>
>>
>> Only fail when encryption is to be enabled but it is not allowed, but
>> ignore the error when the backup should be done unencrypted.
>>
>> `assert_encryption_mode` must also check if it's possible, and skip any
>> error if it's not possible and we wanted no encryption.
>>
>> With these changes, it should be possible to use such configured libraries
>> when there is no encryption configured on the PBS side. (We currently
>> don't have a library with such capabilities to test.)
>>
>> Note that in contrast to normal operation, the tape label will also be
>> encrypted then and will not be readable in case the encryption key is
>> lost or changed.
>>
>> Additionally, return an error for 'drive_set_encryption' in case the
>> drive reports that it does not support hardware encryption, because this
>> is now already caught one level above in 'set_encryption'.
>
> nit: "already" implies to me that it's checked upfront or handled by a
> method called, not one that calls us.
>
> "[...] because this is now handled a level above"
>
> is IMO a bit better fitting
>
ok
>>
>> Also, slightly change the error message to make it clear that the drive
>> does not support *setting* encryption, not that it does not support
>> it at all.
>>
>> This was reported in the community forum:
>>
>> https://forum.proxmox.com/threads/107383/
>> https://forum.proxmox.com/threads/164941/
>>
>> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
>> ---
>> changes from v1:
>> * adapted error message to make it clear what is not supported
>> * also adapt `assert_encryption_mode`, otherwise a backup is not possible
>>
>> pbs-tape/src/sg_tape.rs | 30 +++++++++++++++++++++++++++++-
>> pbs-tape/src/sg_tape/encryption.rs | 12 ++----------
>> src/tape/drive/lto/mod.rs | 4 ++++
>> 3 files changed, 35 insertions(+), 11 deletions(-)
>>
>> diff --git a/pbs-tape/src/sg_tape.rs b/pbs-tape/src/sg_tape.rs
>> index 39e6a2f94..9c7a254d5 100644
>> --- a/pbs-tape/src/sg_tape.rs
>> +++ b/pbs-tape/src/sg_tape.rs
>> @@ -136,6 +136,8 @@ pub struct SgTape {
>> file: File,
>> locate_offset: Option<i64>,
>> info: InquiryInfo,
>> + // auto-detect if we can set the encryption mode
>> + encryption_possible: Option<bool>,
>> }
>>
>> impl SgTape {
>> @@ -158,6 +160,7 @@ impl SgTape {
>> file,
>> info,
>> locate_offset: None,
>> + encryption_possible: None,
>> })
>> }
>>
>> @@ -690,6 +693,14 @@ impl SgTape {
>> }
>>
>> pub fn set_encryption(&mut self, key_data: Option<([u8; 32], Uuid)>) -> Result<(), Error> {
>> + if self.encryption_possible == Some(false) {
>> + if key_data.is_some() {
>> + bail!("Drive does not support setting encryption mode");
>> + } else {
>> + // skip trying to set encryption if not supported and don't wanted
>
> s/don't/not/ and s/set/clear/ (still not ideal but slightly better IMO).
>
> btw. if one enabled encryption before changing the library to FIPS (or
> whatever blocks this setting then) and then cleared encryption we might
> then signal that it work the next time this method is called while it
> did not, seems a bit odd.
>
> Albeit, if that question even makes sense depends on the lifetime of the
> encryption_possible setting.
>
since it's just for one job/action I don't think that's an issue, since
modifying drive/changer settings during such an operation won't work most of
the time anyway (since those things like to block during operation)
> Did you evaluate if exposing a setting the user has to explicitly enable?
> Not saying that is better, but might be a bit simpler to understand and
> probably also slightly safer to implement (or at least review hehe), I think.
> OTOTH., not much in the tape code atm., so my questions might be bogus and
> my reservation for this unfounded.
The original patch is already a few months old, so I'm not sure what exactly
i evaluated, but thinking about it now, I don't really want to expose
an option that 99% of users will never need and there is not much choice
in what to do anyway. One advantage of a user setting might be that
if the 'FIPS' mode (i'll just call it that for the moment) is enabled
by accident, we'd error out instead of just logging it.
Though I hope not that anybody could enable that mode by accident
(since one must manage e.g. the encryption keys, etc.)
>
>> + return Ok(());
>> + }
>> + }
>> let key = if let Some((ref key, ref uuid)) = key_data {
>> // derive specialized key for each media-set
>>
>> @@ -710,7 +721,24 @@ impl SgTape {
>> None
>> };
>>
>> - drive_set_encryption(&mut self.file, key)
>> + match drive_set_encryption(&mut self.file, key) {
>> + Ok(()) => self.encryption_possible = Some(true),
>> + Err(err) => {
>> + self.encryption_possible = Some(false);
>> + if key.is_some() {
>> + bail!("could not set encryption mode on drive: {err}");
>> + } else {
>> + log::info!("could not set encryption mode on drive: {err}, ignoring.");
>
> While internally naming the function "set" might be fine, it always sets some
> value after all, but I'd not leak that outside and rather do s/set/clear/ for
> above log message, as otherwise the user will interpret this as we tried to
> set (= enable) encryption, failed and just ignore it, which seems rather unsafe
> from their POV.
yes makes sense
>
>> + }
>> + }
>> + }
>> + Ok(())
>> + }
>> +
>> + /// Returns if encryption is possible. Returns [`None`] if it's unknown, because
>> + /// no attempt was made to set the mode yet.
>> + pub fn encryption_possible(&self) -> Option<bool> {
>> + self.encryption_possible
>> }
>>
>> // Note: use alloc_page_aligned_buffer to alloc data transfer buffer
>> diff --git a/pbs-tape/src/sg_tape/encryption.rs b/pbs-tape/src/sg_tape/encryption.rs
>> index 7247d257f..c24a6c658 100644
>> --- a/pbs-tape/src/sg_tape/encryption.rs
>> +++ b/pbs-tape/src/sg_tape/encryption.rs
>> @@ -12,15 +12,7 @@ use crate::sgutils2::{alloc_page_aligned_buffer, SgRaw};
>> ///
>> /// We always use mixed mode,
>> pub fn drive_set_encryption<F: AsRawFd>(file: &mut F, key: Option<[u8; 32]>) -> Result<(), Error> {
>> - let data = match sg_spin_data_encryption_caps(file) {
>> - Ok(data) => data,
>> - Err(_) if key.is_none() => {
>> - // Assume device does not support HW encryption
>> - // We can simply ignore the clear key request
>> - return Ok(());
>> - }
>> - Err(err) => return Err(err),
>> - };
>> + let data = sg_spin_data_encryption_caps(file)?;
>>
>> let algorithm_index = decode_spin_data_encryption_caps(&data)?;
>>
>> @@ -266,7 +258,7 @@ fn decode_spin_data_encryption_caps(data: &[u8]) -> Result<u8, Error> {
>>
>> match aes_gcm_index {
>> Some(index) => Ok(index),
>> - None => bail!("drive does not support AES-GCM encryption"),
>> + None => bail!("drive does not support setting AES-GCM encryption"),
>> }
>> })
>> .map_err(|err: Error| format_err!("decode data encryption caps page failed - {}", err))
>> diff --git a/src/tape/drive/lto/mod.rs b/src/tape/drive/lto/mod.rs
>> index 23e043ce6..bd5ec8ae6 100644
>> --- a/src/tape/drive/lto/mod.rs
>> +++ b/src/tape/drive/lto/mod.rs
>> @@ -264,6 +264,10 @@ impl TapeDriver for LtoTapeHandle {
>> }
>>
>> fn assert_encryption_mode(&mut self, encryption_wanted: bool) -> Result<(), Error> {
>> + if Some(false) == self.sg_tape.encryption_possible() && !encryption_wanted {
>> + // ignore assertion for unencrypted mode, because we can't set it anyway
>
> s/because/if/ ?
sure, sounds also good to me
I'll send a v3. Since the changes are only rewordings of the message and
comments, I'll include the 'tested-by' tag from Andrew Stone, alright?
>
>> + return Ok(());
>> + }
>> let encryption_set = drive_get_encryption(self.sg_tape.file_mut())?;
>> if encryption_wanted != encryption_set {
>> bail!("Set encryption mode not what was desired (set: {encryption_set}, wanted: {encryption_wanted})");
>
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [pbs-devel] [PATCH proxmox-backup v2] tape: skip setting encryption if we can't and don't want to
2025-07-11 13:29 ` Dominik Csapak
@ 2025-07-11 15:09 ` Thomas Lamprecht
2025-07-14 6:43 ` Dominik Csapak
0 siblings, 1 reply; 8+ messages in thread
From: Thomas Lamprecht @ 2025-07-11 15:09 UTC (permalink / raw)
To: Dominik Csapak, Proxmox Backup Server development discussion
Am 11.07.25 um 15:29 schrieb Dominik Csapak:
>>> @@ -690,6 +693,14 @@ impl SgTape {
>>> }
>>>
>>> pub fn set_encryption(&mut self, key_data: Option<([u8; 32], Uuid)>) -> Result<(), Error> {
>>> + if self.encryption_possible == Some(false) {
>>> + if key_data.is_some() {
>>> + bail!("Drive does not support setting encryption mode");
>>> + } else {
>>> + // skip trying to set encryption if not supported and don't wanted
>> s/don't/not/ and s/set/clear/ (still not ideal but slightly better IMO).
>>
>> btw. if one enabled encryption before changing the library to FIPS (or
>> whatever blocks this setting then) and then cleared encryption we might
>> then signal that it work the next time this method is called while it
>> did not, seems a bit odd.
>>
>> Albeit, if that question even makes sense depends on the lifetime of the
>> encryption_possible setting.
>>
> since it's just for one job/action I don't think that's an issue, since
> modifying drive/changer settings during such an operation won't work most of
> the time anyway (since those things like to block during operation)
>
>> Did you evaluate if exposing a setting the user has to explicitly enable?
>> Not saying that is better, but might be a bit simpler to understand and
>> probably also slightly safer to implement (or at least review hehe), I think.
>> OTOTH., not much in the tape code atm., so my questions might be bogus and
>> my reservation for this unfounded.
> The original patch is already a few months old, so I'm not sure what exactly
> i evaluated, but thinking about it now, I don't really want to expose
> an option that 99% of users will never need and there is not much choice
> in what to do anyway. One advantage of a user setting might be that
> if the 'FIPS' mode (i'll just call it that for the moment) is enabled
> by accident, we'd error out instead of just logging it.
IMO one really should not argue with 99% of users not requiring something,
either this auto-magic is safe to do or not, if not a option is required
in any way if the derivation of default (safe) behavior is required.
You got already a handful reports, so the problem is obviously there, and
while I certainly do not argue for adding a option for every little
behavior, this is not just some small behavioral quirk, for which I'd agree
with your assessment. But as this is relevant for data security, it means
that if done wrong, backups might be either unprotected while the admin
thinks they are, or not usable because encrypted while the admin doesn't
expect them to be.
As said, that might not be possible and your implementation might be fully
safe, but if you want to keep it as internal "auto-magic" behavior–which
_might_ be fine–then all those edge cases should be closely looked at and
explained in the commit message.
> Though I hope not that anybody could enable that mode by accident
> (since one must manage e.g. the encryption keys, etc.)
Yeah, I'd be also wary to create a generic and opaque "FIPS mode", besides
being hard to relate to for those admins that actually care about security
and don't just want to tick off some checkbox, if we cannot know/control
the external HW such that it's actually upheld it's very dangerous.
Specific simple question that map to specific behavior are much easier to
maintain and understand; if we would get more of those then one could think
about adding a setting that turns them all on at once.
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [pbs-devel] [PATCH proxmox-backup v2] tape: skip setting encryption if we can't and don't want to
2025-07-11 15:09 ` Thomas Lamprecht
@ 2025-07-14 6:43 ` Dominik Csapak
0 siblings, 0 replies; 8+ messages in thread
From: Dominik Csapak @ 2025-07-14 6:43 UTC (permalink / raw)
To: Thomas Lamprecht, Proxmox Backup Server development discussion
On 7/11/25 17:09, Thomas Lamprecht wrote:
> Am 11.07.25 um 15:29 schrieb Dominik Csapak:
>>>> @@ -690,6 +693,14 @@ impl SgTape {
>>>> }
>>>>
>>>> pub fn set_encryption(&mut self, key_data: Option<([u8; 32], Uuid)>) -> Result<(), Error> {
>>>> + if self.encryption_possible == Some(false) {
>>>> + if key_data.is_some() {
>>>> + bail!("Drive does not support setting encryption mode");
>>>> + } else {
>>>> + // skip trying to set encryption if not supported and don't wanted
>>> s/don't/not/ and s/set/clear/ (still not ideal but slightly better IMO).
>>>
>>> btw. if one enabled encryption before changing the library to FIPS (or
>>> whatever blocks this setting then) and then cleared encryption we might
>>> then signal that it work the next time this method is called while it
>>> did not, seems a bit odd.
>>>
>>> Albeit, if that question even makes sense depends on the lifetime of the
>>> encryption_possible setting.
>>>
>> since it's just for one job/action I don't think that's an issue, since
>> modifying drive/changer settings during such an operation won't work most of
>> the time anyway (since those things like to block during operation)
>>
>>> Did you evaluate if exposing a setting the user has to explicitly enable?
>>> Not saying that is better, but might be a bit simpler to understand and
>>> probably also slightly safer to implement (or at least review hehe), I think.
>>> OTOTH., not much in the tape code atm., so my questions might be bogus and
>>> my reservation for this unfounded.
>> The original patch is already a few months old, so I'm not sure what exactly
>> i evaluated, but thinking about it now, I don't really want to expose
>> an option that 99% of users will never need and there is not much choice
>> in what to do anyway. One advantage of a user setting might be that
>> if the 'FIPS' mode (i'll just call it that for the moment) is enabled
>> by accident, we'd error out instead of just logging it.
>
> IMO one really should not argue with 99% of users not requiring something,
> either this auto-magic is safe to do or not, if not a option is required
> in any way if the derivation of default (safe) behavior is required.
> You got already a handful reports, so the problem is obviously there, and
> while I certainly do not argue for adding a option for every little
> behavior, this is not just some small behavioral quirk, for which I'd agree
> with your assessment. But as this is relevant for data security, it means
> that if done wrong, backups might be either unprotected while the admin
> thinks they are, or not usable because encrypted while the admin doesn't
> expect them to be.
>
> As said, that might not be possible and your implementation might be fully
> safe, but if you want to keep it as internal "auto-magic" behavior–which
> _might_ be fine–then all those edge cases should be closely looked at and
> explained in the commit message.
>
I understand what you mean, and I think this implementation is ok the
way it is, maybe a short summary of situations that helps understand
it better:
* Enabling/Disabling encryption on the changer side must be done
explicitly, since the encryption keys must be managed from there.
So the Changer side mode is intentional by the admin.
* We have a very particular way to set encryption: The initial block
is written unencrypted, while the remaining blocks are encrypted.
* If the encryption is forced (or forced off) changer side, we cannot
modify the key or mode. Also the reads/writes are completely transparent to us.
This patch now ignores the following "errors":
* we try to write unencrypted but the changer forces encryption
When trying to set encryption from our side, but the changer/drive
does not let us, we bail with an error.
Note we only ever check the encryption mode when starting a new
tape (for performance reasons, if we'd check/set for every block/write
we'd be too slow for high tape throughput)
so if a user would/can change the encryption mode mid-backup, this
would impact current backups too, since it's only detected on
the start of a new tape.
(And while I don't exactly how these tape libs behave since we don't have
one, AFAIK you can't change the mode mid-backup, since our jobs
constantly use the drive, which makes it not available for such requests
from the changer/lib)
So in opinion, a setting is overkill, since if the admin sets
such a particular mode, it'll not be by accident, and the only
way forward then would be to set the option. While with my changes
it's used automatically. If the user wanted encryption on pbs side
he'll get an error when that does not happen. Only the other way around
(unencrypted on pbs side and encrypted on drive/changer side) is allowed
with this patch.
>> Though I hope not that anybody could enable that mode by accident
>> (since one must manage e.g. the encryption keys, etc.)
>
> Yeah, I'd be also wary to create a generic and opaque "FIPS mode", besides
> being hard to relate to for those admins that actually care about security
> and don't just want to tick off some checkbox, if we cannot know/control
> the external HW such that it's actually upheld it's very dangerous.
> Specific simple question that map to specific behavior are much easier to
> maintain and understand; if we would get more of those then one could think
> about adding a setting that turns them all on at once.
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [pbs-devel] [PATCH proxmox-backup v2] tape: skip setting encryption if we can't and don't want to
2025-04-16 7:07 [pbs-devel] [PATCH proxmox-backup v2] tape: skip setting encryption if we can't and don't want to Dominik Csapak
` (2 preceding siblings ...)
2025-07-11 11:45 ` Thomas Lamprecht
@ 2025-07-22 17:16 ` Thomas Lamprecht
3 siblings, 0 replies; 8+ messages in thread
From: Thomas Lamprecht @ 2025-07-22 17:16 UTC (permalink / raw)
To: pve-devel, pbs-devel, Dominik Csapak
On Wed, 16 Apr 2025 09:07:03 +0200, Dominik Csapak wrote:
> Some settings on changers prevents changing the encryption parameters
> via the application, e.g. some libraries have a 'encryption disabled' or
> 'encryption is library managed' option. While the former situation can
> be fixed by setting the library to 'application managed', the latter is
> sometimes necessary for FIPS compliance (to ensure the tape data is
> encrypted).
>
> [...]
Than you for your very thorough follow-up adding much more rationale for me.
With that I can see your point and agree with it.
Applied for PBS 4, we can still backport this though on user demand, thanks!
[1/1] tape: skip setting encryption if we can't and don't want to
commit: 096505eaf7b16aedb5ee75ae874275c95e7b8d0e
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-07-22 17:17 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-04-16 7:07 [pbs-devel] [PATCH proxmox-backup v2] tape: skip setting encryption if we can't and don't want to Dominik Csapak
2025-04-17 14:10 ` Andrew Stone
2025-07-11 10:09 ` Dominik Csapak
2025-07-11 11:45 ` Thomas Lamprecht
2025-07-11 13:29 ` Dominik Csapak
2025-07-11 15:09 ` Thomas Lamprecht
2025-07-14 6:43 ` Dominik Csapak
2025-07-22 17:16 ` Thomas Lamprecht
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox