mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
rust/pv: Add-Secret: Add user-data types
Add four new user-data types an add-secret request could have: Unsigned, Signed(EcSECP521R1, Rsa(2048, 3072)) As the user-data enum was not marked as non-exaustive this might be a breaking change for users. (Not for any crate in this repo though). The addition of such user-data is provided by following patches. Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
bfd0e12d22
commit
f36c34038b
@@ -240,11 +240,7 @@ impl AddSecretRequest {
|
||||
self.keyslots.iter().for_each(|k| aad.push(Aad::Ks(k)));
|
||||
aad.push(Aad::Plain(&secr_auth));
|
||||
|
||||
ctx.build_aad(self.version.into(), &aad, conf_len, self.magic())
|
||||
}
|
||||
|
||||
fn magic(&self) -> crate::request::RequestMagic {
|
||||
self.magic.as_bytes().try_into().unwrap()
|
||||
ctx.build_aad(self.version.into(), &aad, conf_len, self.magic.get())
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
||||
@@ -63,7 +63,7 @@ impl AddCmd {
|
||||
let mut data = Vec::with_capacity(PAGESIZE);
|
||||
bin_add_secret_req.read_to_end(&mut data)?;
|
||||
|
||||
if !AddSecretMagic::starts_with_magic(&data[..6]) {
|
||||
if !AddSecretMagic::starts_with_magic(&data) {
|
||||
return Err(Error::NoAsrcb);
|
||||
}
|
||||
Ok(Self(data))
|
||||
|
||||
@@ -44,6 +44,9 @@ pub enum Error {
|
||||
#[error("Input does not contain an add-secret request")]
|
||||
NoAsrcb,
|
||||
|
||||
#[error("Input contains unsupported user-data type: {0:#06x}")]
|
||||
UnsupportedUserData(u16),
|
||||
|
||||
// errors from other crates
|
||||
#[error(transparent)]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
@@ -4,14 +4,17 @@
|
||||
|
||||
use crate::{
|
||||
misc::to_u16,
|
||||
request::MagicValue,
|
||||
request::{MagicValue, RequestMagic},
|
||||
uv::{ListCmd, UvCmd},
|
||||
Error, Result,
|
||||
};
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
use std::{
|
||||
fmt::Display,
|
||||
io::{Cursor, Read, Seek, Write},
|
||||
mem::size_of,
|
||||
};
|
||||
use utils::{assert_size, static_assert};
|
||||
use zerocopy::{AsBytes, FromBytes, U16, U32};
|
||||
|
||||
/// The magic value used to identify an add-secret request`]
|
||||
@@ -29,30 +32,156 @@ use zerocopy::{AsBytes, FromBytes, U16, U32};
|
||||
///```
|
||||
///
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, AsBytes)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, AsBytes)]
|
||||
pub struct AddSecretMagic {
|
||||
magic: [u8; 6], // [0x61, 0x73, 0x72, 0x63, 0x62, 0x4D]
|
||||
tp: UserDataType,
|
||||
kind: U16<BigEndian>,
|
||||
}
|
||||
assert_size!(AddSecretMagic, 8);
|
||||
|
||||
impl MagicValue<6> for AddSecretMagic {
|
||||
// "asrcbM"
|
||||
const MAGIC: [u8; 6] = [0x61, 0x73, 0x72, 0x63, 0x62, 0x4D];
|
||||
}
|
||||
|
||||
impl AddSecretMagic {
|
||||
/// Get the magic value.
|
||||
pub fn get(&self) -> RequestMagic {
|
||||
let mut res = RequestMagic::default();
|
||||
debug_assert!(res.len() == size_of::<AddSecretMagic>());
|
||||
// Panic: does not panic, buf is 8 bytes long
|
||||
self.write_to(&mut res).unwrap();
|
||||
res
|
||||
}
|
||||
|
||||
/// Try to convert from a byte slice.
|
||||
///
|
||||
/// Retuns [`None`] if the byte slice does not contain a valid magic value variant.
|
||||
pub fn try_from_bytes(bytes: &[u8]) -> Result<Self> {
|
||||
if !Self::starts_with_magic(bytes) || bytes.len() < size_of::<AddSecretMagic>() {
|
||||
return Err(Error::NoAsrcb);
|
||||
}
|
||||
|
||||
// Panic: Will not panic, bytes is at least 8 elements long
|
||||
let kind = BigEndian::read_u16(&bytes[6..8]);
|
||||
let kind = UserDataType::try_from(kind)?;
|
||||
Ok(Self::from(kind))
|
||||
}
|
||||
}
|
||||
|
||||
/// Types of (non architectured) user data for an add-secret request
|
||||
#[repr(u16)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, zerocopy::AsBytes)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum UserDataType {
|
||||
/// Marker that the request does not contain any user data
|
||||
Null = 0x0000,
|
||||
/// Arbitrary user data (max 512 bytes)
|
||||
Unsigned = 0x0001,
|
||||
/// User data message signed with an Ec key, (max 256 byte)
|
||||
SgnEcSECP521R1 = 0x0002,
|
||||
/// User data message signature with a Rsa key of 2048 bit size, (max 256 byte)
|
||||
SgnRsa2048 = 0x0003,
|
||||
/// User data message signature with a Rsa key of 3072 bit size, (max 128 byte)
|
||||
SgnRsa3072 = 0x0004,
|
||||
}
|
||||
|
||||
impl From<UserDataType> for AddSecretMagic {
|
||||
fn from(tp: UserDataType) -> Self {
|
||||
Self {
|
||||
magic: Self::MAGIC,
|
||||
tp,
|
||||
impl UserDataType {
|
||||
/// Returns the maximum user-data size in bytes.
|
||||
pub fn max(&self) -> usize {
|
||||
match self {
|
||||
UserDataType::Null => 0,
|
||||
UserDataType::Unsigned => 512,
|
||||
UserDataType::SgnEcSECP521R1 => 256,
|
||||
UserDataType::SgnRsa2048 => 256,
|
||||
UserDataType::SgnRsa3072 => 128,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for UserDataType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
Self::Null => "None",
|
||||
Self::Unsigned => "unsigned",
|
||||
Self::SgnEcSECP521R1 => "ECDSA signed",
|
||||
Self::SgnRsa2048 => "RSA 2048 signed",
|
||||
Self::SgnRsa3072 => "RSA 3072 signed",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u16> for UserDataType {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: u16) -> std::result::Result<Self, Self::Error> {
|
||||
if value == UserDataType::Null as u16 {
|
||||
Ok(UserDataType::Null)
|
||||
} else if value == UserDataType::Unsigned as u16 {
|
||||
Ok(UserDataType::Unsigned)
|
||||
} else if value == UserDataType::SgnEcSECP521R1 as u16 {
|
||||
Ok(UserDataType::SgnEcSECP521R1)
|
||||
} else if value == UserDataType::SgnRsa2048 as u16 {
|
||||
Ok(UserDataType::SgnRsa2048)
|
||||
} else if value == UserDataType::SgnRsa3072 as u16 {
|
||||
Ok(UserDataType::SgnRsa3072)
|
||||
} else {
|
||||
Err(Error::UnsupportedUserData(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UserDataType> for AddSecretMagic {
|
||||
fn from(kind: UserDataType) -> Self {
|
||||
Self {
|
||||
magic: Self::MAGIC,
|
||||
kind: (kind as u16).into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::{
|
||||
request::{
|
||||
uvsecret::{AddSecretMagic, UserDataType},
|
||||
MagicValue,
|
||||
},
|
||||
Error,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn convert_user_data() {
|
||||
assert!(matches!(
|
||||
UserDataType::try_from(5),
|
||||
Err(Error::UnsupportedUserData(5))
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn magic_get() {
|
||||
let user_data = AddSecretMagic::from(UserDataType::SgnEcSECP521R1);
|
||||
|
||||
assert_eq!(
|
||||
user_data.get(),
|
||||
[0x61, 0x73, 0x72, 0x63, 0x62, 0x4D, 0x00, 0x02]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn magic_try_from() {
|
||||
let bin = [0x61, 0x73, 0x72, 0x63, 0x62, 0x4D, 0x00, 0x02];
|
||||
|
||||
let magic = AddSecretMagic::try_from_bytes(&bin).unwrap();
|
||||
assert_eq!(
|
||||
magic,
|
||||
AddSecretMagic {
|
||||
magic: AddSecretMagic::MAGIC,
|
||||
kind: (UserDataType::SgnEcSECP521R1 as u16).into()
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user