mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Add a `pv` crate that bundles useful functions and structs for creating requests like `Attestation`, `Add Secret`, or even `Boot` a.k.a. Secure Execution Image. Note pv includes a subcrate `openssl_extensions` that (temporarily) bundles some needed `openssl-rust` functionalities that are not upstream yet. The plan is to remove these, when they become upstream. The pv crate has multiple features: * request - code to generate requests * uvsecret - code to access the UV-secret api with request enabled also generating requests is possible Signed-off-by: Steffen Eiden <seiden@linux.ibm.com> Acked-by: Jan Höppner <hoeppner@linux.ibm.com> Acked-by: Marc Hartmayer <mhartmay@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
129 lines
4.5 KiB
Rust
129 lines
4.5 KiB
Rust
// SPDX-License-Identifier: MIT
|
|
//
|
|
// Copyright IBM Corp. 2023
|
|
|
|
use crate::{assert_size, static_assert};
|
|
use zerocopy::{AsBytes, FromBytes};
|
|
|
|
pub const UVIO_ATT_ARCB_MAX_LEN: usize = 0x100000;
|
|
pub const UVIO_ATT_MEASUREMENT_MAX_LEN: usize = 0x8000;
|
|
pub const UVIO_ATT_ADDITIONAL_MAX_LEN: usize = 0x8000;
|
|
pub const UVIO_ADD_SECRET_MAX_LEN: usize = 0x100000;
|
|
pub const UVIO_LIST_SECRETS_LEN: usize = 0x1000;
|
|
|
|
// equal to ascii 'u'
|
|
pub const UVIO_TYPE_UVC: u8 = 117u8;
|
|
|
|
pub const UVIO_IOCTL_UVDEV_INFO_NR: u8 = 0;
|
|
pub const UVIO_IOCTL_ATT_NR: u8 = 1;
|
|
pub const UVIO_IOCTL_ADD_SECRET_NR: u8 = 2;
|
|
pub const UVIO_IOCTL_LIST_SECRETS_NR: u8 = 3;
|
|
pub const UVIO_IOCTL_LOCK_SECRETS_NR: u8 = 4;
|
|
|
|
/// Uvdevice IOCTL control block
|
|
/// Programs can use this struct to communicate with the uvdevice via IOCTLs
|
|
/// `argument_{addr,len}` specifies in/out data depending on the request
|
|
///
|
|
/// 'uv_rc' and `uv_rrc` are the response and reason response codes from the
|
|
/// Ultravisor.
|
|
///
|
|
/// `flags` is currently unused and to be set zero
|
|
///
|
|
#[repr(C)]
|
|
#[derive(Debug)]
|
|
pub struct uvio_ioctl_cb {
|
|
pub flags: u32,
|
|
pub uv_rc: u16,
|
|
pub uv_rrc: u16,
|
|
pub argument_addr: u64,
|
|
pub argument_len: u32,
|
|
pub reserved14: [u8; 44usize],
|
|
}
|
|
assert_size!(uvio_ioctl_cb, 0x40);
|
|
|
|
/// Information of supported functions by the uvdevice
|
|
///
|
|
/// * `supp_uvio_cmds` - supported IOCTLs by this device
|
|
/// * `supp_uv_cmds` - supported UVCs corresponding to the IOCTL
|
|
///
|
|
/// UVIO request to get information about supported request types by this
|
|
/// uvdevice and the Ultravisor.
|
|
/// Everything is output. Bits are in LSB0 ordering.
|
|
/// If the bit is set in both, `supp_uvio_cmds` and `supp_uv_cmds`,
|
|
/// the uvdevice and the Ultravisor support that call.
|
|
///
|
|
/// Note that bit 0 (UVIO_IOCTL_UVDEV_INFO_NR) is always zero for `supp_uv_cmds`
|
|
/// as there is no corresponding UV-call.
|
|
#[repr(C)]
|
|
#[derive(Debug, Copy, Clone, AsBytes, FromBytes)]
|
|
pub struct uvio_uvdev_info {
|
|
pub supp_uvio_cmds: u64,
|
|
pub supp_uv_cmds: u64,
|
|
}
|
|
assert_size!(uvio_uvdev_info, 0x10);
|
|
|
|
pub const UVIO_ATT_USER_DATA_LEN: usize = 0x100;
|
|
pub const UVIO_ATT_UID_LEN: usize = 0x10;
|
|
|
|
/// Request Attestation Measurement control block
|
|
///
|
|
/// The Attestation Request has two input and two outputs.
|
|
/// ARCB and User Data are inputs for the UV.
|
|
/// Measurement and Additional Data are outputs generated by UV.
|
|
///
|
|
/// The Attestation Request Control Block (ARCB) is a cryptographically verified
|
|
/// and secured request to UV and User Data is some plaintext data which is
|
|
/// going to be included in the Attestation Measurement calculation.
|
|
///
|
|
/// Measurement is a cryptographic measurement of the callers properties,
|
|
/// optional data configured by the ARCB and the user data. If specified by the
|
|
/// ARCB, UV will add some Additional Data to the measurement calculation.
|
|
/// This Additional Data is then returned as well.
|
|
///
|
|
/// If the Retrieve Attestation Measurement UV facility is not present,
|
|
/// UV will return invalid command rc.
|
|
/// Obviously all numbers are in BIG-endian!
|
|
#[repr(C)]
|
|
#[derive(Debug, AsBytes, FromBytes)]
|
|
pub struct uvio_attest {
|
|
pub arcb_addr: u64, //in
|
|
pub meas_addr: u64, //out
|
|
pub add_data_addr: u64, //out
|
|
pub user_data: [u8; UVIO_ATT_USER_DATA_LEN], //in
|
|
pub config_uid: [u8; UVIO_ATT_UID_LEN], //out
|
|
pub arcb_len: u32,
|
|
pub meas_len: u32,
|
|
pub add_data_len: u32,
|
|
pub user_data_len: u16,
|
|
pub reserved136: u16,
|
|
}
|
|
assert_size!(uvio_attest, 0x138);
|
|
|
|
#[allow(dead_code)] //TODO rm when pv learns attestation
|
|
impl uvio_attest {
|
|
pub const ARCB_MAX_LEN: usize = UVIO_ATT_ARCB_MAX_LEN;
|
|
pub const MEASUREMENT_MAX_LEN: usize = UVIO_ATT_MEASUREMENT_MAX_LEN;
|
|
pub const ADDITIONAL_MAX_LEN: usize = UVIO_ATT_ADDITIONAL_MAX_LEN;
|
|
}
|
|
|
|
/// corresponds to the UV_IOCTL macro
|
|
pub const fn uv_ioctl(nr: u8) -> u64 {
|
|
iowr(UVIO_TYPE_UVC, nr, std::mem::size_of::<uvio_ioctl_cb>())
|
|
}
|
|
static_assert!(uv_ioctl(UVIO_IOCTL_ATT_NR) == 0xc0407501);
|
|
|
|
/// corresponds to the __IOWR macro
|
|
const fn iowr(ty: u8, nr: u8, size: usize) -> u64 {
|
|
// constants and calculation from linux: asm-generic/ioctl.h
|
|
const _IOC_WRITE: u32 = 1;
|
|
const _IOC_READ: u32 = 2;
|
|
const _IOC_NRSHIFT: u32 = 0;
|
|
const _IOC_TYPESHIFT: u32 = 8;
|
|
const _IOC_SIZESHIFT: u32 = 16;
|
|
const _IOC_DIRSHIFT: u32 = 30;
|
|
((_IOC_READ | _IOC_WRITE) as u64) << _IOC_DIRSHIFT
|
|
| ((ty as u64) << _IOC_TYPESHIFT)
|
|
| ((nr as u64) << _IOC_NRSHIFT)
|
|
| ((size as u64) << _IOC_SIZESHIFT)
|
|
}
|