rust/pv: Move confidential.rs to pv_core

Migrate Confidential to pv_core crate. This has no impact on the public
API of pv as the migrated symbols are reexported.
This enables pv_core to manage confidential data as well.

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
This commit is contained in:
Steffen Eiden
2024-06-26 14:07:24 +02:00
parent d1b5f80fe5
commit 516bd8c2cf
4 changed files with 6 additions and 4 deletions
-118
View File
@@ -1,118 +0,0 @@
// SPDX-License-Identifier: MIT
//
// Copyright IBM Corp. 2023, 2024
use std::fmt::Debug;
/// Trait for securely zeroizing memory.
///
/// To be used with [`Confidential`]
pub trait Zeroize {
/// Reliably overwrites the given buffer with zeros,
fn zeroize(&mut self);
}
// Automatically impl Zeroize for u8 arrays
impl<const COUNT: usize> Zeroize for [u8; COUNT] {
/// Reliably overwrites the given buffer with zeros,
/// by performing a volatile write followed by a memory barrier
fn zeroize(&mut self) {
// SAFETY: given buffer(self) has the correct (compile time) size
unsafe { std::ptr::write_volatile(self, [0u8; COUNT]) };
std::sync::atomic::compiler_fence(std::sync::atomic::Ordering::SeqCst);
}
}
impl Zeroize for Vec<u8> {
/// Reliably overwrites the given buffer with zeros,
/// by overwriting the whole vector's capacity with zeros.
fn zeroize(&mut self) {
// TODO use `volatile_set_memory` when stabilized
let mut dst = self.as_mut_ptr();
for _ in 0..self.capacity() {
// SAFETY:
// * Vec allocated at least capacity elements continuously
// * dst points always to a valid location
unsafe {
std::ptr::write_volatile(dst, 0);
dst = dst.add(1);
}
}
std::sync::atomic::compiler_fence(std::sync::atomic::Ordering::SeqCst);
}
}
/// Thin wrapper around an type implementing Zeroize.
///
/// A `Confidential` represents a confidential value that must be securely overwritten during drop.
/// Will never leak its wrapped value during [`Debug`]
///
/// ```rust
/// use s390_pv::request::Confidential;
/// fn foo(value: Confidential<[u8; 2]>) {
/// println!("value: {value:?}");
/// }
/// # fn main() {
/// foo([1, 2].into());
/// // prints:
/// // in debug builds:
/// // value: Confidential([1, 2])
/// // in release builds:
/// // value: Confidential(***)
/// # }
/// ```
#[derive(Clone, PartialEq, Eq, Default)]
pub struct Confidential<C: Zeroize>(C);
impl<C: Zeroize> Confidential<C> {
/// Convert a type into a self overwriting one.
///
/// Prefer using [`Into`]
pub fn new(v: C) -> Self {
Self(v)
}
/// Get a reference to the contained value
pub fn value(&self) -> &C {
&self.0
}
/// Get an immutable reference to the contained value
///
/// NOTE that modifications to a mutable reference can trigger reallocation.
/// e.g. a [`Vec`] might expand if more space needed. -> preallocate enough space
/// or operate on slices. The old locations can and will **NOT** be zeroized.
pub fn value_mut(&mut self) -> &mut C {
&mut self.0
}
}
impl<C: Zeroize + Debug> Debug for Confidential<C> {
#[allow(unreachable_code)]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// do NOT leak secrets in production builds
#[cfg(not(debug_assertions))]
return write!(f, "Confidential(***)");
let mut b = f.debug_tuple("Confidential");
b.field(&self.0);
b.finish()
}
}
impl<C: Zeroize> From<C> for Confidential<C> {
fn from(v: C) -> Self {
Self(v)
}
}
impl<C: Zeroize> Zeroize for Confidential<C> {
fn zeroize(&mut self) {
self.0.zeroize();
}
}
impl<C: Zeroize> Drop for Confidential<C> {
fn drop(&mut self) {
self.0.zeroize();
}
}
+3 -1
View File
@@ -2,7 +2,6 @@
//
// Copyright IBM Corp. 2023, 2024
use crate::{confidential::Confidential, error::Result, Error};
use openssl::{
derive::Deriver,
ec::{EcGroup, EcKey},
@@ -16,8 +15,11 @@ use openssl::{
sign::{Signer, Verifier},
symm::{decrypt_aead, encrypt_aead, Cipher},
};
use pv_core::request::Confidential;
use std::{convert::TryInto, ops::Range};
use crate::{error::Result, Error};
/// An AES256-GCM key that will purge itself out of the memory when going out of scope
pub type Aes256Key = Confidential<[u8; 32]>;
pub(crate) const AES_256_GCM_TAG_SIZE: usize = 16;
-2
View File
@@ -42,7 +42,6 @@
//! # Verify
//! [`attest::AttestationItems`], [`attest::AttestationMeasurement`]
mod brcb;
mod confidential;
mod crypto;
mod error;
mod openssl_extensions;
@@ -93,7 +92,6 @@ pub use pv_core::{FileAccessErrorType, FileIoErrorType};
/// Functionalities to build UV requests
pub mod request {
pub use crate::brcb::BootHdrTags;
pub use crate::confidential::{Confidential, Zeroize};
pub use crate::crypto::{SymKey, SymKeyType};
pub use crate::req::{Keyslot, ReqEncrCtx, Request};
pub use crate::verify::{CertVerifier, HkdVerifier, NoVerifyHkd};