From 8929d21948cebf5ee43a24e27742e0b39949f818 Mon Sep 17 00:00:00 2001 From: Steffen Eiden Date: Mon, 28 Apr 2025 10:04:03 +0200 Subject: [PATCH] rust: Upgrade zerocopy dependency to 0.8.X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This enables some const constructors, Dataful Enums, Dynamically Sized Types and much more. v0.8 introduces breaking changes including, but not limited to: - Rename AsBytes to IntoBytes - Fine-grain (derive) Traits that need to be implemented on top. - Rename FromZeroes to FromZeros for which this patch takes care of as well. Also a direct FromZeros derive is no longer necessary. As it is touched anyways, remove it where appropriate. See: https://github.com/google/zerocopy/discussions/1680 Signed-off-by: Steffen Eiden Signed-off-by: Jan Höppner --- rust/Cargo.lock | 122 +++++++++++++++++------ rust/cpacfinfo/Cargo.toml | 2 +- rust/cpacfinfo/src/query.rs | 5 +- rust/pv/Cargo.toml | 2 +- rust/pv/src/brcb.rs | 22 ++-- rust/pv/src/req.rs | 12 +-- rust/pv/src/uvattest/arcb.rs | 8 +- rust/pv/src/uvattest/attest.rs | 2 +- rust/pv/src/uvsecret/asrcb.rs | 4 +- rust/pv/src/uvsecret/guest_secret.rs | 6 +- rust/pv/src/uvsecret/retr_secret.rs | 3 +- rust/pv/src/uvsecret/user_data.rs | 23 +++-- rust/pv_core/Cargo.toml | 2 +- rust/pv_core/src/utils.rs | 6 +- rust/pv_core/src/uvattest.rs | 2 +- rust/pv_core/src/uvdevice/attest.rs | 4 +- rust/pv_core/src/uvdevice/ffi.rs | 6 +- rust/pv_core/src/uvdevice/info.rs | 4 +- rust/pv_core/src/uvdevice/secret.rs | 2 +- rust/pv_core/src/uvdevice/secret_list.rs | 26 +++-- rust/pv_core/src/uvsecret.rs | 8 +- rust/pvapconfig/Cargo.toml | 2 +- rust/pvattest/Cargo.toml | 2 +- rust/pvattest/src/exchange.rs | 16 +-- 24 files changed, 182 insertions(+), 109 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 609fa631..911868d7 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -356,13 +356,25 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] @@ -429,9 +441,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.169" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libz-sys" @@ -539,9 +551,9 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "ppv-lite86" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ "zerocopy", ] @@ -557,9 +569,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -575,8 +587,8 @@ dependencies = [ "bitflags", "lazy_static", "num-traits", - "rand", - "rand_chacha", + "rand 0.8.5", + "rand_chacha 0.3.1", "rand_xorshift", "regex-syntax", "rusty-fork", @@ -592,7 +604,7 @@ dependencies = [ "clap_complete", "lazy_static", "openssl", - "rand", + "rand 0.9.1", "regex", "s390_pv_core", "serde", @@ -661,13 +673,19 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "radium" version = "0.7.0" @@ -681,8 +699,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", ] [[package]] @@ -692,7 +720,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -701,7 +739,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.2", ] [[package]] @@ -710,7 +757,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" dependencies = [ - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -898,9 +945,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.96" +version = "2.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" dependencies = [ "proc-macro2", "quote", @@ -921,7 +968,7 @@ checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" dependencies = [ "cfg-if", "fastrand", - "getrandom", + "getrandom 0.2.16", "once_cell", "rustix", "windows-sys 0.59.0", @@ -982,9 +1029,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unsafe-libyaml" @@ -1030,6 +1077,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -1121,6 +1177,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + [[package]] name = "wyz" version = "0.5.1" @@ -1132,19 +1197,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" dependencies = [ - "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" dependencies = [ "proc-macro2", "quote", diff --git a/rust/cpacfinfo/Cargo.toml b/rust/cpacfinfo/Cargo.toml index 9f117cdf..838f7385 100644 --- a/rust/cpacfinfo/Cargo.toml +++ b/rust/cpacfinfo/Cargo.toml @@ -12,7 +12,7 @@ libc = "0.2" serde = { version = "1.0.217", features = ["derive"] } serde_json = "1.0" utils = { path = "../utils" } -zerocopy = { version="0.7", features = ["derive"] } +zerocopy = { version="0.8", features = ["derive"] } [build-dependencies] cc = "1.2" diff --git a/rust/cpacfinfo/src/query.rs b/rust/cpacfinfo/src/query.rs index a92fba40..40b67d61 100644 --- a/rust/cpacfinfo/src/query.rs +++ b/rust/cpacfinfo/src/query.rs @@ -9,7 +9,6 @@ use std::ops::Index; use std::result::Result; use zerocopy::FromBytes; -use zerocopy::FromZeroes; use crate::msa::InstructionKind; use crate::msa::QueryAuthInfo; @@ -33,7 +32,7 @@ pub const QAI_PARAM_SIZE_IN_BYTES: usize = 256; /// Query authentication information format identifier const FORMAT_0: u8 = 0; -#[derive(FromBytes, FromZeroes)] +#[derive(FromBytes)] #[repr(C)] struct QaiFmt0 { res00: [u8; 6], @@ -175,7 +174,7 @@ pub fn check_sysfs() -> bool { /// ----------------------------------------------------------------- fn parse_qai_format_0(qai: &mut QueryAuthInfo, param: &[u8]) { // parse param to temporary struct to ease further conversion - let tmp = QaiFmt0::read_from_prefix(param).expect("programming error"); + let (tmp, _) = QaiFmt0::read_from_prefix(param).expect("programming error"); // parse from temporary struct qai.hash_len = tmp.hash_length; diff --git a/rust/pv/Cargo.toml b/rust/pv/Cargo.toml index d5c26042..7aa671d1 100644 --- a/rust/pv/Cargo.toml +++ b/rust/pv/Cargo.toml @@ -23,7 +23,7 @@ openssl = "0.10.70" openssl-sys = "0.9.105" serde = { version = "1.0.217", features = ["derive"] } thiserror = "2.0.11" -zerocopy = { version="0.7", features = ["derive"] } +zerocopy = { version="0.8", features = ["derive"] } pv_core = { path = "../pv_core", package = "s390_pv_core", version = "0.11.0" } diff --git a/rust/pv/src/brcb.rs b/rust/pv/src/brcb.rs index 0afda41b..e69e4c82 100644 --- a/rust/pv/src/brcb.rs +++ b/rust/pv/src/brcb.rs @@ -8,7 +8,7 @@ use std::{ }; use log::{debug, warn}; -use zerocopy::{AsBytes, BigEndian, FromBytes, FromZeroes, U32, U64}; +use zerocopy::{BigEndian, FromBytes, Immutable, IntoBytes, KnownLayout, U32, U64}; // (SE) boot request control block aka SE header use crate::{assert_size, request::MagicValue, static_assert, Error, Result, PAGESIZE}; @@ -21,7 +21,7 @@ use crate::{assert_size, request::MagicValue, static_assert, Error, Result, PAGE /// Tweak List Digest (tld) /// SE-Header Tag (tag) #[repr(C)] -#[derive(Debug, Clone, Copy, AsBytes, PartialEq, Eq, FromBytes, FromZeroes)] +#[derive(Debug, Clone, Copy, IntoBytes, PartialEq, Eq, FromBytes, Immutable, KnownLayout)] pub struct BootHdrTags { pld: [u8; BootHdrHead::DIGEST_SIZE], ald: [u8; BootHdrHead::DIGEST_SIZE], @@ -40,8 +40,8 @@ impl TryFrom> for BootHdrTags { type Error = Error; fn try_from(value: Vec) -> Result { - Self::ref_from(&value) - .ok_or(Error::InvBootHdrSize(value.len())) + Self::ref_from_bytes(&value) + .map_err(|_| Error::InvBootHdrSize(value.len())) .copied() } } @@ -49,7 +49,7 @@ impl TryFrom> for BootHdrTags { /// Struct representing the Secure Execution boot image metadata #[allow(unused)] #[repr(packed)] -#[derive(Debug, Clone, FromBytes, FromZeroes, AsBytes, PartialEq, Eq)] +#[derive(Debug, Clone, FromBytes, IntoBytes, PartialEq, Eq, Immutable, KnownLayout)] pub struct SeImgMetaData { /// Magic value magic: [u8; 8], @@ -106,7 +106,7 @@ impl SeImgMetaData { /// Gets the bytes of this value. #[inline(always)] pub fn as_bytes(&self) -> &[u8] { - ::as_bytes(self) + ::as_bytes(self) } /// Returns the version of this [`SeImgMetaData`]. @@ -154,7 +154,7 @@ where // read in the header img.read_exact(&mut img_metadata_bytes)?; // Cannot fail because the buffer has the same size as SeImgMetaData. - let img_metadata = SeImgMetaData::ref_from(&img_metadata_bytes).unwrap(); + let img_metadata = SeImgMetaData::ref_from_bytes(&img_metadata_bytes).unwrap(); let img_metadata_version = img_metadata.version(); if img_metadata_version != SeImgMetaData::V1 { warn!("Unknown Secure Execution boot image version {img_metadata_version}"); @@ -226,8 +226,8 @@ impl BootHdrTags { } let hdr_head = match BootHdrHead::read_from_prefix(hdr.as_mut_slice()) { - Some(hdr) => hdr, - None => { + Ok((hdr, _)) => hdr, + Err(_) => { debug!("Boot hdr is too small"); return Err(Error::InvBootHdr); } @@ -260,7 +260,7 @@ impl BootHdrTags { } #[repr(C)] -#[derive(Debug, Clone, FromBytes, FromZeroes)] +#[derive(Debug, Clone, FromBytes)] struct BootHdrHead { magic: U64, version: U32, @@ -388,7 +388,7 @@ mod tests { 0, 1, 96, 0, ]; assert_eq!(metadata.as_bytes(), &data); - assert_eq!(SeImgMetaData::ref_from(&data), Some(&metadata)); + assert_eq!(SeImgMetaData::ref_from_bytes(&data), Ok(&metadata)); assert_eq!(metadata.version(), SeImgMetaData::V1); } diff --git a/rust/pv/src/req.rs b/rust/pv/src/req.rs index d4c8dfb6..d132ecc2 100644 --- a/rust/pv/src/req.rs +++ b/rust/pv/src/req.rs @@ -12,7 +12,7 @@ use openssl::{ pkey::{PKey, PKeyRef, Private, Public}, }; use pv_core::request::{RequestMagic, RequestVersion}; -use zerocopy::{AsBytes, BigEndian, FromBytes, FromZeroes, U32}; +use zerocopy::{BigEndian, FromBytes, Immutable, IntoBytes, KnownLayout, U32}; use crate::{ assert_size, @@ -358,7 +358,7 @@ ecdh_from!(Public); /// Representation of the shared parts of the request header. /// Used by [`ReqEncrCtx`] #[repr(C)] -#[derive(Debug, Copy, Clone, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, Copy, Clone, IntoBytes, FromBytes, Immutable)] struct RequestHdr { magic: [u8; 8], rqvn: U32, @@ -449,7 +449,7 @@ impl<'a> BinReqValues<'a> { /// Does minimal sanity test, just tests to prevent panics. /// `req` may be larger than the actual request. pub(crate) fn get(req: &'a [u8]) -> Result { - let hdr = RequestHdr::read_from_prefix(req).ok_or(Error::BinRequestSmall)?; + let (hdr, _) = RequestHdr::read_from_prefix(req).map_err(|_| Error::BinRequestSmall)?; let rql = hdr.rql.get() as usize; let sea = hdr.sea.get() as usize; @@ -506,9 +506,9 @@ impl<'a> BinReqValues<'a> { /// [`FromBytes::ref_from_prefix`] pub(crate) fn req_dep_aad(&self) -> Option<&T> where - T: FromBytes + Sized, + T: FromBytes + Sized + Immutable + KnownLayout, { - T::ref_from_prefix(self.req_dep_aad) + T::ref_from_prefix(self.req_dep_aad).map(|s| s.0).ok() } /// Returns a reference to the tag of this [`BinReqValues`]. @@ -615,7 +615,7 @@ mod tests { #[test] fn req_hdr2() { let mut hdr = RequestHdr::new(0x200, 0x1234, [0x11; 12], 15, 44, Some(TEST_MAGIC)); - let hdr_bin = hdr.as_bytes_mut(); + let hdr_bin = hdr.as_mut_bytes(); let hdr_bin_exp = [ 0x12, 0x34, 0x56, 0x89, 0xab, 0xcd, 0xef, 0, // magic 0, 0, 2, 0, // vers diff --git a/rust/pv/src/uvattest/arcb.rs b/rust/pv/src/uvattest/arcb.rs index aae8917a..37db0e53 100644 --- a/rust/pv/src/uvattest/arcb.rs +++ b/rust/pv/src/uvattest/arcb.rs @@ -4,7 +4,7 @@ use openssl::pkey::{PKey, Public}; use std::mem::size_of; -use zerocopy::{AsBytes, BigEndian, FromBytes, FromZeroes, U32}; +use zerocopy::{BigEndian, FromBytes, Immutable, IntoBytes, KnownLayout, U32}; use crate::{ assert_size, @@ -276,7 +276,7 @@ impl From for RequestVersion { /// Authenticated additional Data of an [`AttestationRequest`] #[repr(C)] -#[derive(Debug, AsBytes, FromZeroes, FromBytes, Clone, Copy)] +#[derive(Debug, IntoBytes, FromBytes, Clone, Copy, Immutable, KnownLayout)] pub struct AttestationAuthenticated { flags: AttestationFlags, mai: U32, @@ -310,7 +310,7 @@ impl AttestationAuthenticated { /// Attestation flags #[repr(C)] -#[derive(Default, Debug, AsBytes, FromZeroes, FromBytes, Clone, Copy)] +#[derive(Default, Debug, IntoBytes, FromBytes, Clone, Copy, Immutable)] pub struct AttestationFlags(UvFlags); static_assert!(AttestationFlags::FLAG_TO_ADD_SIZE.len() < 64); @@ -393,7 +393,7 @@ impl AttestationFlags { } #[repr(C)] -#[derive(Debug, AsBytes)] +#[derive(Debug, IntoBytes, Immutable)] struct ReqConfData { meas_key: [u8; 64], nonce: AttNonce, diff --git a/rust/pv/src/uvattest/attest.rs b/rust/pv/src/uvattest/attest.rs index 40ead782..52160794 100644 --- a/rust/pv/src/uvattest/attest.rs +++ b/rust/pv/src/uvattest/attest.rs @@ -12,7 +12,7 @@ use openssl::{ pkey::{PKeyRef, Private}, }; use std::mem::size_of; -use zerocopy::{AsBytes, BigEndian, U16, U32}; +use zerocopy::{BigEndian, IntoBytes, U16, U32}; #[cfg(doc)] use crate::attest::AttestationRequest; diff --git a/rust/pv/src/uvsecret/asrcb.rs b/rust/pv/src/uvsecret/asrcb.rs index 9e16e5d2..c7d4ce6d 100644 --- a/rust/pv/src/uvsecret/asrcb.rs +++ b/rust/pv/src/uvsecret/asrcb.rs @@ -18,11 +18,11 @@ use openssl::{ pkey::{PKey, Private, Public}, }; use pv_core::{request::RequestVersion, secret::AddSecretMagic, uv::SecretId}; -use zerocopy::AsBytes; +use zerocopy::{Immutable, IntoBytes}; /// Authenticated data w/o user data #[repr(C)] -#[derive(Debug, Clone, Copy, AsBytes)] +#[derive(Debug, Clone, Copy, IntoBytes, Immutable)] struct ReqAuthData { flags: UvFlags, boot_tags: BootHdrTags, diff --git a/rust/pv/src/uvsecret/guest_secret.rs b/rust/pv/src/uvsecret/guest_secret.rs index 93b96583..087a1ad3 100644 --- a/rust/pv/src/uvsecret/guest_secret.rs +++ b/rust/pv/src/uvsecret/guest_secret.rs @@ -17,7 +17,6 @@ use crate::{ }, Error, Result, }; -use byteorder::BigEndian; use openssl::{ hash::MessageDigest, nid::Nid, @@ -26,7 +25,8 @@ use openssl::{ use pv_core::static_assert; use serde::{Deserialize, Serialize}; use std::fmt::Display; -use zerocopy::{AsBytes, FromBytes, FromZeroes, U16, U32}; +use zerocopy::{BigEndian, KnownLayout}; +use zerocopy::{FromBytes, Immutable, IntoBytes, U16, U32}; const ASSOC_SECRET_SIZE: usize = 32; /// Maximum size of a plain-text secret payload (8190) @@ -380,7 +380,7 @@ impl SecretAuth { } #[repr(C)] -#[derive(Debug, AsBytes, FromZeroes, FromBytes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] pub(crate) struct ListableSecretHdr { res0: u16, kind: U16, diff --git a/rust/pv/src/uvsecret/retr_secret.rs b/rust/pv/src/uvsecret/retr_secret.rs index 5fad016f..ec07be79 100644 --- a/rust/pv/src/uvsecret/retr_secret.rs +++ b/rust/pv/src/uvsecret/retr_secret.rs @@ -4,12 +4,12 @@ use crate::{pem::Pem, uvsecret::guest_secret::MAX_SIZE_PLAIN_PAYLOAD, Result}; -use byteorder::BigEndian; use log::warn; use pv_core::{ request::Confidential, uv::{ListableSecretType, RetrievableSecret, RetrieveCmd}, }; +use zerocopy::BigEndian; use zerocopy::{FromBytes, U16}; /// An IBM Protected Key @@ -76,6 +76,7 @@ impl From for RetrievedSecret { // minimum size let len = U16::::read_from_prefix(key.value()) .unwrap_or_default() + .0 .get() as usize; // Test if the plain text secret has a size: diff --git a/rust/pv/src/uvsecret/user_data.rs b/rust/pv/src/uvsecret/user_data.rs index e9cd2a84..2f6c2ccd 100644 --- a/rust/pv/src/uvsecret/user_data.rs +++ b/rust/pv/src/uvsecret/user_data.rs @@ -15,7 +15,7 @@ use crate::{ }; use openssl::hash::MessageDigest; use openssl::nid::Nid; -use zerocopy::{AsBytes, BigEndian, FromBytes, FromZeroes, U16}; +use zerocopy::{BigEndian, FromBytes, IntoBytes, KnownLayout, U16}; /// User data. /// @@ -59,7 +59,7 @@ pub(super) enum UserData { } #[repr(C)] -#[derive(Debug, AsBytes, FromBytes, FromZeroes)] +#[derive(Debug, IntoBytes, FromBytes, KnownLayout)] struct EcUserData { data: [u8; 256], signature: [u8; EC_SIGN_MAX_SIZE], @@ -175,7 +175,7 @@ impl UserData { // insert signature if let UserDataType::SgnEcSECP521R1 = self.data_type() { // Panic: will not panic buffer is 512+ bytes long - let buf_ec = EcUserData::mut_from_prefix(&mut buf[user_data_offset..]).unwrap(); + let (buf_ec, _) = EcUserData::mut_from_prefix(&mut buf[user_data_offset..]).unwrap(); buf_ec.set_signature(&sgn); } else { // Panic: will not panic buffer is 512+ bytes long @@ -328,12 +328,15 @@ impl VerifiedUserData { let (ret, sgn) = match kind { UserDataType::SgnEcSECP521R1 => { - let EcUserData { - data, - signature, - sgn_size, - .. - } = EcUserData::mut_from_prefix(buf).unwrap(); + let ( + EcUserData { + data, + signature, + sgn_size, + .. + }, + _, + ) = EcUserData::mut_from_prefix(buf).unwrap(); let data_len: usize = data.len(); let data = data.to_vec(); let mut signature = signature.to_vec(); @@ -480,7 +483,7 @@ mod test { buf[..0x80].copy_from_slice(data); user_data.sign(&mut buf, 0).unwrap(); - let buf_ec = EcUserData::mut_from(&mut buf).unwrap(); + let buf_ec = EcUserData::mut_from_bytes(&mut buf).unwrap(); let EcUserData { data, signature, diff --git a/rust/pv_core/Cargo.toml b/rust/pv_core/Cargo.toml index e9c0d103..e68e87ac 100644 --- a/rust/pv_core/Cargo.toml +++ b/rust/pv_core/Cargo.toml @@ -19,7 +19,7 @@ workspace = true libc = "0.2.169" log = { version = "0.4.25", features = ["std", "release_max_level_debug"] } thiserror = "2.0.11" -zerocopy = {version = "0.7", features = ["derive"]} +zerocopy = {version = "0.8", features = ["derive"]} serde = { version = "1.0.217", features = ["derive"]} byteorder = "1.5" regex = "1.10" diff --git a/rust/pv_core/src/utils.rs b/rust/pv_core/src/utils.rs index 099106ac..b1bf08fb 100644 --- a/rust/pv_core/src/utils.rs +++ b/rust/pv_core/src/utils.rs @@ -7,7 +7,7 @@ use std::{ path::Path, }; -use zerocopy::{AsBytes, BigEndian, FromBytes, FromZeroes, U64}; +use zerocopy::{BigEndian, FromBytes, Immutable, IntoBytes, U64}; use crate::{ macros::{bail_spec, file_error}, @@ -34,7 +34,7 @@ pub trait Flags: From + for<'a> From<&'a T> { /// /// Wraps an u64 to set/get individual bits #[repr(C)] -#[derive(Debug, Clone, Copy, Default, AsBytes, FromZeroes, FromBytes, Eq, PartialEq)] +#[derive(Debug, Clone, Copy, Default, IntoBytes, FromBytes, Eq, PartialEq, Immutable)] pub struct Msb0Flags64(U64); impl Flags for Msb0Flags64 { #[track_caller] @@ -82,7 +82,7 @@ impl From for u64 { /// /// Wraps an u64 to set/get individual bits #[repr(C)] -#[derive(Debug, Clone, Copy, Default, AsBytes, FromZeroes, FromBytes)] +#[derive(Debug, Clone, Copy, Default, IntoBytes, FromBytes, Immutable)] pub struct Lsb0Flags64(U64); impl Flags for Lsb0Flags64 { #[track_caller] diff --git a/rust/pv_core/src/uvattest.rs b/rust/pv_core/src/uvattest.rs index e9315bd3..dc93d5f6 100644 --- a/rust/pv_core/src/uvattest.rs +++ b/rust/pv_core/src/uvattest.rs @@ -3,8 +3,8 @@ // Copyright IBM Corp. 2024 use crate::{request::MagicValue, Error}; -use byteorder::{BigEndian, ByteOrder}; use zerocopy::U32; +use zerocopy::{BigEndian, ByteOrder}; /// The magic value used to identify an attestation request /// diff --git a/rust/pv_core/src/uvdevice/attest.rs b/rust/pv_core/src/uvdevice/attest.rs index 3614928a..10e2cbb8 100644 --- a/rust/pv_core/src/uvdevice/attest.rs +++ b/rust/pv_core/src/uvdevice/attest.rs @@ -4,7 +4,7 @@ use super::{ffi, AttestationUserData, ConfigUid, UvCmd}; use crate::{Error, Result}; use std::ptr; -use zerocopy::{AsBytes, FromZeroes}; +use zerocopy::{FromZeros, IntoBytes}; /// _Retrieve Attestation Measurement_ UVC /// @@ -222,7 +222,7 @@ impl UvCmd for AttestationCmd { } fn data(&mut self) -> Option<&mut [u8]> { - Some(self.uvio_attest.as_bytes_mut()) + Some(self.uvio_attest.as_mut_bytes()) } } diff --git a/rust/pv_core/src/uvdevice/ffi.rs b/rust/pv_core/src/uvdevice/ffi.rs index 3d9998db..b14b842e 100644 --- a/rust/pv_core/src/uvdevice/ffi.rs +++ b/rust/pv_core/src/uvdevice/ffi.rs @@ -12,7 +12,7 @@ use std::mem::size_of; use crate::{assert_size, static_assert}; -use zerocopy::{AsBytes, FromBytes, FromZeroes}; +use zerocopy::{FromBytes, IntoBytes}; pub const UVIO_ATT_ARCB_MAX_LEN: usize = 0x100000; pub const UVIO_ATT_MEASUREMENT_MAX_LEN: usize = 0x8000; @@ -65,7 +65,7 @@ assert_size!(uvio_ioctl_cb, 0x40); /// 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, FromZeroes, FromBytes)] +#[derive(Debug, Copy, Clone, IntoBytes, FromBytes)] pub struct uvio_uvdev_info { pub supp_uvio_cmds: u64, pub supp_uv_cmds: u64, @@ -95,7 +95,7 @@ pub const UVIO_ATT_UID_LEN: usize = 0x10; /// /// All numbers are in big-endian! #[repr(C)] -#[derive(Debug, AsBytes, FromZeroes, FromBytes)] +#[derive(Debug, IntoBytes, FromBytes)] pub struct uvio_attest { pub arcb_addr: u64, // in pub meas_addr: u64, // out diff --git a/rust/pv_core/src/uvdevice/info.rs b/rust/pv_core/src/uvdevice/info.rs index b6851fa4..64c0685b 100644 --- a/rust/pv_core/src/uvdevice/info.rs +++ b/rust/pv_core/src/uvdevice/info.rs @@ -9,7 +9,7 @@ use crate::{ Result, }; use std::fmt::Display; -use zerocopy::{AsBytes, FromZeroes}; +use zerocopy::{FromZeros, IntoBytes}; /// Information of supported functions by the uvdevice /// @@ -74,7 +74,7 @@ impl UvCmd for uvio_uvdev_info { const UV_IOCTL_NR: u8 = ffi::UVIO_IOCTL_UVDEV_INFO_NR; fn data(&mut self) -> Option<&mut [u8]> { - Some(self.as_bytes_mut()) + Some(self.as_mut_bytes()) } fn rc_fmt(&self, _: u16, _: u16) -> Option<&'static str> { diff --git a/rust/pv_core/src/uvdevice/secret.rs b/rust/pv_core/src/uvdevice/secret.rs index cb5b7233..932ae68d 100644 --- a/rust/pv_core/src/uvdevice/secret.rs +++ b/rust/pv_core/src/uvdevice/secret.rs @@ -11,7 +11,7 @@ use crate::{ }; use log::debug; use std::{io::Read, mem::size_of_val}; -use zerocopy::AsBytes; +use zerocopy::IntoBytes; /// _List Secrets_ Ultravisor command. /// diff --git a/rust/pv_core/src/uvdevice/secret_list.rs b/rust/pv_core/src/uvdevice/secret_list.rs index 7c7e63b5..9fb3d585 100644 --- a/rust/pv_core/src/uvdevice/secret_list.rs +++ b/rust/pv_core/src/uvdevice/secret_list.rs @@ -8,7 +8,6 @@ use crate::{ uvdevice::UvCmd, Error, Result, }; -use byteorder::{BigEndian, ByteOrder}; use serde::{Deserialize, Serialize, Serializer}; use std::{ cmp::min, @@ -19,13 +18,14 @@ use std::{ slice::Iter, vec::IntoIter, }; -use zerocopy::{AsBytes, FromBytes, FromZeroes, U16, U32}; +use zerocopy::{BigEndian, ByteOrder}; +use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, U16, U32}; /// The 32 byte long ID of an UV secret /// /// (de)serializes itself in/from a hex-string #[repr(C)] -#[derive(PartialEq, Eq, AsBytes, FromZeroes, FromBytes, Debug, Clone, Default)] +#[derive(PartialEq, Eq, IntoBytes, FromBytes, Debug, Clone, Default, Immutable, KnownLayout)] pub struct SecretId([u8; Self::ID_SIZE]); assert_size!(SecretId, SecretId::ID_SIZE); @@ -132,7 +132,7 @@ impl AsRef<[u8]> for SecretId { /// A secret in a [`SecretList`] #[repr(C)] -#[derive(Debug, Clone, PartialEq, Eq, AsBytes, FromZeroes, FromBytes, Serialize)] +#[derive(Debug, Clone, PartialEq, Eq, IntoBytes, FromBytes, Serialize, Immutable)] pub struct SecretEntry { #[serde(serialize_with = "ser_u16")] index: U16, @@ -183,7 +183,7 @@ impl SecretEntry { /// The slice is guaranteed to be 32 bytes long. /// ```rust /// # use s390_pv_core::uv::SecretEntry; - /// # use zerocopy::FromZeroes; + /// # use zerocopy::FromZeros; /// # let secr = SecretEntry::new_zeroed(); /// # assert_eq!(secr.id().len(), 32); /// ``` @@ -211,7 +211,9 @@ impl Display for SecretEntry { } #[repr(C)] -#[derive(Debug, FromBytes, AsBytes, FromZeroes, Clone, PartialEq, Eq, Default, Serialize)] +#[derive( + Debug, FromBytes, IntoBytes, Clone, PartialEq, Eq, Default, Serialize, Immutable, KnownLayout, +)] struct SecretListHdr { #[serde(skip)] num_secrets_stored: U16, @@ -325,7 +327,8 @@ impl SecretList { /// Encodes the list in the same binary format the UV would do pub fn encode(&self, w: &mut T) -> Result<()> { - w.write_all(self.hdr.as_bytes())?; + let hdr = self.hdr.as_bytes(); + w.write_all(hdr)?; for secret in &self.secrets { w.write_all(secret.as_bytes())?; } @@ -336,14 +339,14 @@ impl SecretList { pub fn decode(r: &mut R) -> std::io::Result { let mut buf = [0u8; size_of::()]; r.read_exact(&mut buf)?; - let hdr = SecretListHdr::ref_from(&buf).unwrap(); + let hdr = SecretListHdr::ref_from_bytes(&buf).unwrap(); let mut buf = [0u8; SecretEntry::STRUCT_SIZE]; let mut v = Vec::with_capacity(hdr.num_secrets_stored.get() as usize); for _ in 0..hdr.num_secrets_stored.get() { r.read_exact(&mut buf)?; // cannot fail. buffer has the same size as the secret entry - let secr = SecretEntry::read_from(buf.as_slice()).unwrap(); + let secr = SecretEntry::read_from_bytes(buf.as_slice()).unwrap(); v.push(secr); } Ok(Self { @@ -538,10 +541,13 @@ where #[cfg(test)] mod test { + use std::io::{BufReader, BufWriter, Cursor}; + use serde_test::{assert_ser_tokens, assert_tokens, Token}; + use zerocopy::FromZeros; use super::*; - use std::io::{BufReader, BufWriter, Cursor}; + #[test] fn dump_secret_entry() { const EXP: &[u8] = &[ diff --git a/rust/pv_core/src/uvsecret.rs b/rust/pv_core/src/uvsecret.rs index 41b6eebe..4fab87ff 100644 --- a/rust/pv_core/src/uvsecret.rs +++ b/rust/pv_core/src/uvsecret.rs @@ -7,9 +7,9 @@ use crate::{ request::{MagicValue, RequestMagic}, Error, Result, }; -use byteorder::{BigEndian, ByteOrder}; +use byteorder::ByteOrder; use std::{fmt::Display, mem::size_of}; -use zerocopy::{AsBytes, U16}; +use zerocopy::{BigEndian, Immutable, IntoBytes, U16}; /// The magic value used to identify an `AddSecretRequest`. /// @@ -25,7 +25,7 @@ use zerocopy::{AsBytes, U16}; /// # } /// ``` #[repr(C)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, AsBytes)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, IntoBytes, Immutable)] pub struct AddSecretMagic { magic: [u8; 6], // [0x61, 0x73, 0x72, 0x63, 0x62, 0x4D] kind: U16, @@ -56,7 +56,7 @@ impl AddSecretMagic { } // Panic: Will not panic, bytes is at least 8 elements long - let kind = BigEndian::read_u16(&bytes[6..8]); + let kind = byteorder::BigEndian::read_u16(&bytes[6..8]); let kind = UserDataType::try_from(kind)?; Ok(Self::from(kind)) } diff --git a/rust/pvapconfig/Cargo.toml b/rust/pvapconfig/Cargo.toml index 3a7fcc8c..711ec085 100644 --- a/rust/pvapconfig/Cargo.toml +++ b/rust/pvapconfig/Cargo.toml @@ -12,7 +12,7 @@ clap = { version ="4.5", features = ["derive", "wrap_help"]} lazy_static = "1.5" openssl = { version = "0.10.70" } pv_core = { path = "../pv_core", package = "s390_pv_core"} -rand = "0.8" +rand = "0.9" regex = "1.11" serde = { version = "1.0.217", features = ["derive"] } serde_yaml = "0.9" diff --git a/rust/pvattest/Cargo.toml b/rust/pvattest/Cargo.toml index bc2239a2..89de18af 100644 --- a/rust/pvattest/Cargo.toml +++ b/rust/pvattest/Cargo.toml @@ -19,7 +19,7 @@ openssl = "0.10.70" serde = { version = "1.0.217", features = ["derive"]} serde_json = "1.0" serde_yaml = "0.9" -zerocopy = { version="0.7", features = ["derive"] } +zerocopy = { version="0.8", features = ["derive"] } pv = { path = "../pv", package = "s390_pv" } utils = { path = "../utils" } diff --git a/rust/pvattest/src/exchange.rs b/rust/pvattest/src/exchange.rs index c6f9823c..a061d338 100644 --- a/rust/pvattest/src/exchange.rs +++ b/rust/pvattest/src/exchange.rs @@ -2,18 +2,18 @@ // // Copyright IBM Corp. 2024 use anyhow::{anyhow, bail, Error, Result}; -use byteorder::ByteOrder; use pv::{assert_size, request::MagicValue, uv::AttestationCmd, uv::ConfigUid}; use std::{ io::{ErrorKind, Read, Seek, SeekFrom, Write}, mem::size_of, }; -use zerocopy::{AsBytes, BigEndian, FromBytes, FromZeroes, U32, U64}; +use zerocopy::ByteOrder; +use zerocopy::{BigEndian, FromBytes, Immutable, IntoBytes, KnownLayout, U32, U64}; const INV_EXCHANGE_FMT_ERROR_TEXT: &str = "The input has not the correct format:"; #[repr(C)] -#[derive(Debug, AsBytes, PartialEq, Eq, Default, FromZeroes, FromBytes)] +#[derive(Debug, IntoBytes, PartialEq, Eq, Default, FromBytes, Immutable, KnownLayout)] struct Entry { size: U32, offset: U32, @@ -76,7 +76,7 @@ impl Entry { } #[repr(C)] -#[derive(Debug, AsBytes, FromZeroes, FromBytes)] +#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)] struct ExchangeFormatV1Hdr { magic: U64, version: U32, @@ -352,8 +352,8 @@ impl ExchangeFormatRequest { bail!("{INV_EXCHANGE_FMT_ERROR_TEXT} Does not start with the magic value.",); } - let hdr = ExchangeFormatV1Hdr::ref_from(buf.as_slice()) - .ok_or(anyhow!("{INV_EXCHANGE_FMT_ERROR_TEXT} Invalid Header."))?; + let hdr = ExchangeFormatV1Hdr::ref_from_bytes(buf.as_slice()) + .map_err(|_| anyhow!("{INV_EXCHANGE_FMT_ERROR_TEXT} Invalid Header."))?; match TryInto::::try_into(hdr.version)? { ExchangeFormatVersion::One => (), @@ -515,8 +515,8 @@ impl ExchangeFormatResponse { bail!("{INV_EXCHANGE_FMT_ERROR_TEXT} Does not start with the magic value."); } - let hdr = ExchangeFormatV1Hdr::ref_from(buf.as_slice()) - .ok_or(anyhow!("{INV_EXCHANGE_FMT_ERROR_TEXT} Invalid Header."))?; + let hdr = ExchangeFormatV1Hdr::ref_from_bytes(buf.as_slice()) + .map_err(|_| anyhow!("{INV_EXCHANGE_FMT_ERROR_TEXT} Invalid Header."))?; match TryInto::::try_into(hdr.version)? { ExchangeFormatVersion::One => (),