diff --git a/Cargo.lock b/Cargo.lock index a0c1c36b7..c6f868bf3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -558,6 +558,7 @@ dependencies = [ "bitflags", "ptr_meta", "uefi-macros", + "uguid", ] [[package]] diff --git a/uefi-raw/Cargo.toml b/uefi-raw/Cargo.toml index 5af0ba9ee..3e37b8b07 100644 --- a/uefi-raw/Cargo.toml +++ b/uefi-raw/Cargo.toml @@ -15,6 +15,7 @@ rust-version = "1.68" bitflags = "1.3.1" ptr_meta = { version = "0.2.0", default-features = false } uefi-macros = "0.11.0" +uguid = "2.0.0" [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] diff --git a/uefi-raw/src/lib.rs b/uefi-raw/src/lib.rs index 4ab69dca3..fd5fdbbe4 100644 --- a/uefi-raw/src/lib.rs +++ b/uefi-raw/src/lib.rs @@ -17,6 +17,9 @@ #[macro_use] mod enums; +pub mod protocol; + mod status; pub use status::Status; +pub use uguid::{guid, Guid}; diff --git a/uefi-raw/src/protocol/mod.rs b/uefi-raw/src/protocol/mod.rs new file mode 100644 index 000000000..de20dc306 --- /dev/null +++ b/uefi-raw/src/protocol/mod.rs @@ -0,0 +1,7 @@ +//! Protocol definitions. +//! +//! Protocols are sets of related functionality identified by a unique +//! ID. They can be implemented by a UEFI driver or occasionally by a +//! UEFI application. + +pub mod rng; diff --git a/uefi-raw/src/protocol/rng.rs b/uefi-raw/src/protocol/rng.rs new file mode 100644 index 000000000..0fd8dbb6e --- /dev/null +++ b/uefi-raw/src/protocol/rng.rs @@ -0,0 +1,54 @@ +//! `Rng` protocol. + +use crate::{guid, Guid, Status}; + +newtype_enum! { + /// The algorithms listed are optional, not meant to be exhaustive + /// and may be augmented by vendors or other industry standards. + pub enum RngAlgorithmType: Guid => { + /// Indicates a empty algorithm, used to instantiate a buffer + /// for `get_info` + EMPTY_ALGORITHM = guid!("00000000-0000-0000-0000-000000000000"), + + /// The “raw” algorithm, when supported, is intended to provide + /// entropy directly from the source, without it going through + /// some deterministic random bit generator. + ALGORITHM_RAW = guid!("e43176d7-b6e8-4827-b784-7ffdc4b68561"), + + /// ALGORITHM_SP800_90_HASH_256 + ALGORITHM_SP800_90_HASH_256 = guid!("a7af67cb-603b-4d42-ba21-70bfb6293f96"), + + /// ALGORITHM_SP800_90_HMAC_256 + ALGORITHM_SP800_90_HMAC_256 = guid!("c5149b43-ae85-4f53-9982-b94335d3a9e7"), + + /// ALGORITHM_SP800_90_CTR_256 + ALGORITHM_SP800_90_CTR_256 = guid!("44f0de6e-4d8c-4045-a8c7-4dd168856b9e"), + + /// ALGORITHM_X9_31_3DES + ALGORITHM_X9_31_3DES = guid!("63c4785a-ca34-4012-a3c8-0b6a324f5546"), + + /// ALGORITHM_X9_31_AES + ALGORITHM_X9_31_AES = guid!("acd03321-777e-4d3d-b1c8-20cfd88820c9"), + } +} + +/// Rng protocol. +#[repr(C)] +pub struct RngProtocol { + pub get_info: unsafe extern "efiapi" fn( + this: *mut RngProtocol, + algorithm_list_size: *mut usize, + algorithm_list: *mut RngAlgorithmType, + ) -> Status, + + pub get_rng: unsafe extern "efiapi" fn( + this: *mut RngProtocol, + algorithm: *const RngAlgorithmType, + value_length: usize, + value: *mut u8, + ) -> Status, +} + +impl RngProtocol { + pub const GUID: Guid = guid!("3152bca5-eade-433d-862e-c01cdc291f44"); +} diff --git a/uefi/src/proto/rng.rs b/uefi/src/proto/rng.rs index 2e1d29312..0cf6e4986 100644 --- a/uefi/src/proto/rng.rs +++ b/uefi/src/proto/rng.rs @@ -1,56 +1,15 @@ //! `Rng` protocol. -use crate::data_types::Guid; use crate::proto::unsafe_protocol; -use crate::{guid, Result, Status, StatusExt}; +use crate::{Result, Status, StatusExt}; use core::{mem, ptr}; -newtype_enum! { - /// The algorithms listed are optional, not meant to be exhaustive - /// and may be augmented by vendors or other industry standards. - pub enum RngAlgorithmType: Guid => { - /// Indicates a empty algorithm, used to instantiate a buffer - /// for `get_info` - EMPTY_ALGORITHM = guid!("00000000-0000-0000-0000-000000000000"), - - /// The “raw” algorithm, when supported, is intended to provide - /// entropy directly from the source, without it going through - /// some deterministic random bit generator. - ALGORITHM_RAW = guid!("e43176d7-b6e8-4827-b784-7ffdc4b68561"), - - /// ALGORITHM_SP800_90_HASH_256 - ALGORITHM_SP800_90_HASH_256 = guid!("a7af67cb-603b-4d42-ba21-70bfb6293f96"), - - /// ALGORITHM_SP800_90_HMAC_256 - ALGORITHM_SP800_90_HMAC_256 = guid!("c5149b43-ae85-4f53-9982-b94335d3a9e7"), - - /// ALGORITHM_SP800_90_CTR_256 - ALGORITHM_SP800_90_CTR_256 = guid!("44f0de6e-4d8c-4045-a8c7-4dd168856b9e"), - - /// ALGORITHM_X9_31_3DES - ALGORITHM_X9_31_3DES = guid!("63c4785a-ca34-4012-a3c8-0b6a324f5546"), - - /// ALGORITHM_X9_31_AES - ALGORITHM_X9_31_AES = guid!("acd03321-777e-4d3d-b1c8-20cfd88820c9"), - } -} +pub use uefi_raw::protocol::rng::RngAlgorithmType; /// Rng protocol #[repr(C)] -#[unsafe_protocol("3152bca5-eade-433d-862e-c01cdc291f44")] -pub struct Rng { - get_info: unsafe extern "efiapi" fn( - this: &Rng, - algorithm_list_size: *mut usize, - algorithm_list: *mut RngAlgorithmType, - ) -> Status, - get_rng: unsafe extern "efiapi" fn( - this: &Rng, - algorithm: *const RngAlgorithmType, - value_length: usize, - value: *mut u8, - ) -> Status, -} +#[unsafe_protocol(uefi_raw::protocol::rng::RngProtocol::GUID)] +pub struct Rng(uefi_raw::protocol::rng::RngProtocol); impl Rng { /// Returns information about the random number generation implementation. @@ -61,20 +20,24 @@ impl Rng { let mut algorithm_list_size = algorithm_list.len() * mem::size_of::(); unsafe { - (self.get_info)(self, &mut algorithm_list_size, algorithm_list.as_mut_ptr()) - .to_result_with( - || { - let len = algorithm_list_size / mem::size_of::(); - &algorithm_list[..len] - }, - |status| { - if status == Status::BUFFER_TOO_SMALL { - Some(algorithm_list_size) - } else { - None - } - }, - ) + (self.0.get_info)( + &mut self.0, + &mut algorithm_list_size, + algorithm_list.as_mut_ptr(), + ) + .to_result_with( + || { + let len = algorithm_list_size / mem::size_of::(); + &algorithm_list[..len] + }, + |status| { + if status == Status::BUFFER_TOO_SMALL { + Some(algorithm_list_size) + } else { + None + } + }, + ) } } @@ -87,6 +50,8 @@ impl Rng { Some(algo) => algo as *const RngAlgorithmType, }; - unsafe { (self.get_rng)(self, algo, buffer_length, buffer.as_mut_ptr()).to_result() } + unsafe { + (self.0.get_rng)(&mut self.0, algo, buffer_length, buffer.as_mut_ptr()).to_result() + } } }