mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
rust/pv: Use a SecretId struct instead of an array
This streamlines and unifies the use and (de)serialization of structs using a secret id. As a bonus, the hidden `for_pv` module is not longer needed. Signed-off-by: Steffen Eiden <seiden@linux.ibm.com> Reviewed-by: Julian Ruess <julianr@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
81a1e13f3b
commit
c53dfa9754
+1
-5
@@ -35,11 +35,7 @@ const PAGESIZE: usize = 0x1000;
|
||||
|
||||
/// Definitions and functions for interacting with the Ultravisor
|
||||
pub mod uv {
|
||||
pub use pv_core::uv::{
|
||||
uv_ioctl, ConfigUid, UvCmd, UvDevice, UvDeviceInfo, UvFlags, UvcSuccess,
|
||||
};
|
||||
pub use pv_core::uv::{AddCmd, ListCmd, LockCmd};
|
||||
pub use pv_core::uv::{ListableSecretType, SecretEntry, SecretList};
|
||||
pub use pv_core::uv::*;
|
||||
}
|
||||
|
||||
/// Miscellaneous functions and definitions
|
||||
|
||||
@@ -23,7 +23,7 @@ use pv_core::request::RequestVersion;
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
/// Internal wrapper for Guest Secret, so that we can dump it in the form the UV wants it to be
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug)]
|
||||
struct BinGuestSecret(GuestSecret);
|
||||
impl BinGuestSecret {
|
||||
/// Reference to the confidential data
|
||||
@@ -40,7 +40,7 @@ impl BinGuestSecret {
|
||||
let mut buf = vec![0; 48];
|
||||
buf[3] = 2;
|
||||
buf[7] = 0x20;
|
||||
buf[16..48].copy_from_slice(id.as_slice());
|
||||
buf[16..48].copy_from_slice(id.as_ref());
|
||||
buf
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ impl ReqAuthData {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug)]
|
||||
struct ReqConfData {
|
||||
secret: BinGuestSecret,
|
||||
extension_secret: Secret<[u8; 32]>,
|
||||
@@ -164,7 +164,7 @@ impl From<AddSecretVersion> for RequestVersion {
|
||||
/// | AES GCM Tag (16) |
|
||||
/// |_____________________________________________________________|
|
||||
///```
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Debug)]
|
||||
pub struct AddSecretRequest {
|
||||
version: AddSecretVersion,
|
||||
aad: ReqAuthData,
|
||||
@@ -348,7 +348,7 @@ mod test {
|
||||
fn guest_secret_bin_ap() {
|
||||
let gs: BinGuestSecret = GuestSecret::Association {
|
||||
name: "test".to_string(),
|
||||
id: [1; 32],
|
||||
id: [1; 32].into(),
|
||||
secret: [2; 32].into(),
|
||||
}
|
||||
.into();
|
||||
|
||||
@@ -8,13 +8,14 @@ use crate::{
|
||||
request::{hash, openssl::MessageDigest, random_array, Secret},
|
||||
Result,
|
||||
};
|
||||
use pv_core::for_pv::{ser_gsid, SECRET_ID_SIZE};
|
||||
use pv_core::uv::SecretId;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::convert::TryInto;
|
||||
|
||||
const SECRET_SIZE: usize = 32;
|
||||
|
||||
/// A Secret to be added in [`AddSecretRequest`]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub enum GuestSecret {
|
||||
/// No guest secret
|
||||
Null,
|
||||
@@ -24,10 +25,9 @@ pub enum GuestSecret {
|
||||
Association {
|
||||
/// Name of the secret
|
||||
name: String,
|
||||
#[serde(serialize_with = "ser_gsid", deserialize_with = "de_gsid")]
|
||||
/// SHA256 hash of [`GuestSecret::Association::name`]
|
||||
id: [u8; SECRET_ID_SIZE],
|
||||
/// Confidential actual assocuiation secret (32 bytes)
|
||||
id: SecretId,
|
||||
/// Confidential actual association secret (32 bytes)
|
||||
#[serde(skip)]
|
||||
secret: Secret<[u8; SECRET_SIZE]>,
|
||||
},
|
||||
@@ -46,7 +46,10 @@ impl GuestSecret {
|
||||
where
|
||||
O: Into<Option<[u8; SECRET_SIZE]>>,
|
||||
{
|
||||
let id = hash(MessageDigest::sha256(), name.as_bytes())?.to_vec();
|
||||
let id: [u8; SecretId::ID_SIZE] = hash(MessageDigest::sha256(), name.as_bytes())?
|
||||
.to_vec()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
let secret = match secret.into() {
|
||||
Some(s) => s,
|
||||
None => random_array()?,
|
||||
@@ -54,39 +57,11 @@ impl GuestSecret {
|
||||
|
||||
Ok(GuestSecret::Association {
|
||||
name: name.to_string(),
|
||||
id: id.try_into().unwrap(),
|
||||
id: id.into(),
|
||||
secret: secret.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
fn de_gsid<'de, D>(de: D) -> Result<[u8; 32], D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
struct FieldVisitor;
|
||||
|
||||
impl<'de> serde::de::Visitor<'de> for FieldVisitor {
|
||||
type Value = [u8; SECRET_ID_SIZE];
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("a `32 bytes long hexstring` prepended with 0x")
|
||||
}
|
||||
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
if s.len() != SECRET_ID_SIZE * 2 + 2 {
|
||||
return Err(serde::de::Error::invalid_length(s.len(), &self));
|
||||
}
|
||||
let nb = s.strip_prefix("0x").ok_or_else(|| {
|
||||
serde::de::Error::invalid_value(serde::de::Unexpected::Str(s), &self)
|
||||
})?;
|
||||
crate::misc::parse_hex(nb)
|
||||
.try_into()
|
||||
.map_err(|_| serde::de::Error::invalid_value(serde::de::Unexpected::Str(s), &self))
|
||||
}
|
||||
}
|
||||
de.deserialize_identifier(FieldVisitor)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
@@ -106,7 +81,7 @@ mod test {
|
||||
let secret = GuestSecret::association("association secret", secret_value).unwrap();
|
||||
let exp = GuestSecret::Association {
|
||||
name,
|
||||
id: exp_id,
|
||||
id: exp_id.into(),
|
||||
secret: secret_value.into(),
|
||||
};
|
||||
assert_eq!(secret, exp);
|
||||
@@ -121,7 +96,7 @@ mod test {
|
||||
];
|
||||
let asc = GuestSecret::Association {
|
||||
name: "test123".to_string(),
|
||||
id,
|
||||
id: id.into(),
|
||||
secret: [0; 32].into(),
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user