LCOV - code coverage report
Current view: top level - src/pe - enclave_configuration.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 94.0 % 133 125
Test Date: 2025-02-23:00:00:00 Functions: 93.9 % 33 31

            Line data    Source code
       1              : //! PE enclave configuration
       2              : use std::marker::PhantomData;
       3              : 
       4              : use crate::{common::FromFFI, declare_iterator, to_slice};
       5              : use lief_ffi as ffi;
       6              : 
       7              : /// Defines an entry in the array of images that an enclave can import.
       8              : pub struct EnclaveConfiguration<'a> {
       9              :     ptr: cxx::UniquePtr<ffi::PE_EnclaveConfiguration>,
      10              :     _owner: PhantomData<&'a ffi::PE_LoadConfiguration>,
      11              : }
      12              : 
      13              : impl EnclaveConfiguration<'_> {
      14              :     /// The size of the `IMAGE_ENCLAVE_CONFIG64/IMAGE_ENCLAVE_CONFIG32` structure, in bytes.
      15           10 :     pub fn size(&self) -> u32 {
      16           10 :         self.ptr.size()
      17           10 :     }
      18              : 
      19              :     /// The minimum size of the `IMAGE_ENCLAVE_CONFIG(32,64)` structure that the
      20              :     /// image loader must be able to process in order for the enclave to be usable.
      21              :     ///
      22              :     /// This member allows an enclave to inform an earlier version of the image
      23              :     /// loader that the image loader can safely load the enclave and ignore
      24              :     /// optional members added to `IMAGE_ENCLAVE_CONFIG(32,64)` for later versions
      25              :     /// of the enclave. If the size of `IMAGE_ENCLAVE_CONFIG(32,64)` that the image
      26              :     /// loader can process is less than `MinimumRequiredConfigSize`, the enclave
      27              :     /// cannot be run securely.
      28              :     ///
      29              :     /// If `MinimumRequiredConfigSize` is zero, the minimum size of the
      30              :     /// `IMAGE_ENCLAVE_CONFIG(32,64)` structure that the image loader must be able
      31              :     /// to process in order for the enclave to be usable is assumed to be the size
      32              :     /// of the structure through and including the `MinimumRequiredConfigSize` member.
      33           10 :     pub fn min_required_config_size(&self) -> u32 {
      34           10 :         self.ptr.min_required_config_size()
      35           10 :     }
      36              : 
      37              :     /// A flag that indicates whether the enclave permits debugging.
      38           10 :     pub fn policy_flags(&self) -> u32 {
      39           10 :         self.ptr.policy_flags()
      40           10 :     }
      41              : 
      42              :     /// Whether this enclave can be debugged
      43           10 :     pub fn is_debuggable(&self) -> bool {
      44           10 :         self.ptr.is_debuggable()
      45           10 :     }
      46              : 
      47              :     /// The RVA of the array of images that the enclave image may import, with identity information
      48              :     /// for each image.
      49           10 :     pub fn import_list_rva(&self) -> u32 {
      50           10 :         self.ptr.import_list_rva()
      51           10 :     }
      52              : 
      53              :     /// The size of each image in the array of images that the [`EnclaveConfiguration::import_list_rva`]
      54              :     /// member points to.
      55           10 :     pub fn import_entry_size(&self) -> u32 {
      56           10 :         self.ptr.import_entry_size()
      57           10 :     }
      58              : 
      59              :     /// The number of images in the array of images that the [`EnclaveConfiguration::import_list_rva`]
      60              :     /// member points to.
      61           10 :     pub fn nb_imports(&self) -> u32 {
      62           10 :         self.ptr.nb_imports()
      63           10 :     }
      64              : 
      65              :     /// Return an iterator over the enclave's imports
      66           10 :     pub fn imports(&self) -> Imports {
      67           10 :         Imports::new(self.ptr.imports())
      68           10 :     }
      69              : 
      70              :     /// The family identifier that the author of the enclave assigned to the enclave.
      71           10 :     pub fn family_id(&self) -> &[u8] {
      72           10 :         to_slice!(self.ptr.family_id());
      73           10 :     }
      74              : 
      75              :     /// The image identifier that the author of the enclave assigned to the enclave.
      76            0 :     pub fn image_id(&self) -> &[u8] {
      77            0 :         to_slice!(self.ptr.image_id());
      78            0 :     }
      79              : 
      80              :     /// The version number that the author of the enclave assigned to the enclave.
      81           10 :     pub fn image_version(&self) -> u32 {
      82           10 :         self.ptr.image_version()
      83           10 :     }
      84              : 
      85              :     /// The security version number that the author of the enclave assigned to the enclave.
      86           10 :     pub fn security_version(&self) -> u32 {
      87           10 :         self.ptr.security_version()
      88           10 :     }
      89              : 
      90              :     /// The expected virtual size of the private address range for the enclave, in bytes.
      91           10 :     pub fn enclave_size(&self) -> u64 {
      92           10 :         self.ptr.enclave_size()
      93           10 :     }
      94              : 
      95              :     /// The maximum number of threads that can be created within the enclave.
      96           10 :     pub fn nb_threads(&self) -> u32 {
      97           10 :         self.ptr.nb_threads()
      98           10 :     }
      99              : 
     100              :     /// A flag that indicates whether the image is suitable for use as the primary image in the
     101              :     /// enclave.
     102           10 :     pub fn enclave_flags(&self) -> u32 {
     103           10 :         self.ptr.enclave_flags()
     104           10 :     }
     105              : }
     106              : 
     107              : impl std::fmt::Debug for EnclaveConfiguration<'_> {
     108           10 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     109           10 :         f.debug_struct("EnclaveConfiguration")
     110           10 :             .field("size", &self.size())
     111           10 :             .field("min_required_config_size", &self.min_required_config_size())
     112           10 :             .field("policy_flags", &self.policy_flags())
     113           10 :             .field("is_debuggable", &self.is_debuggable())
     114           10 :             .field("import_list_rva", &self.import_list_rva())
     115           10 :             .field("import_entry_size", &self.import_entry_size())
     116           10 :             .field("nb_imports", &self.nb_imports())
     117           10 :             .field("family_id", &self.family_id())
     118           10 :             .field("image_version", &self.image_version())
     119           10 :             .field("security_version", &self.security_version())
     120           10 :             .field("enclave_size", &self.enclave_size())
     121           10 :             .field("nb_threads", &self.nb_threads())
     122           10 :             .field("enclave_flags", &self.enclave_flags())
     123           10 :             .finish()
     124           10 :     }
     125              : }
     126              : 
     127              : impl std::fmt::Display for EnclaveConfiguration<'_> {
     128           10 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     129           10 :         write!(f, "{}", self.ptr.to_string())
     130           10 :     }
     131              : }
     132              : 
     133              : impl<'a> FromFFI<ffi::PE_EnclaveConfiguration> for EnclaveConfiguration<'a> {
     134           10 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_EnclaveConfiguration>) -> Self {
     135           10 :         Self {
     136           10 :             ptr,
     137           10 :             _owner: PhantomData,
     138           10 :         }
     139           10 :     }
     140              : }
     141              : 
     142              : 
     143              : /// This structure represents an entry in the array of images that an enclave can import.
     144              : pub struct EnclaveImport<'a> {
     145              :     ptr: cxx::UniquePtr<ffi::PE_EnclaveImport>,
     146              :     _owner: PhantomData<&'a ffi::PE_EnclaveConfiguration>,
     147              : }
     148              : 
     149              : impl EnclaveImport<'_> {
     150              :     /// The type of identifier of the image that must match the value in the import record.
     151           30 :     pub fn get_type(&self) -> Type {
     152           30 :         Type::from(self.ptr.get_type())
     153           30 :     }
     154              : 
     155              :     /// The minimum enclave security version that each image must have for the
     156              :     /// image to be imported successfully. The image is rejected unless its enclave
     157              :     /// security version is equal to or greater than the minimum value in the
     158              :     /// import record. Set the value in the import record to zero to turn off the
     159              :     /// security version check.
     160           30 :     pub fn min_security_version(&self) -> u32 {
     161           30 :         self.ptr.min_security_version()
     162           30 :     }
     163              : 
     164              :     /// The relative virtual address of a NULL-terminated string that contains the
     165              :     /// same value found in the import directory for the image.
     166           30 :     pub fn import_name_rva(&self) -> u32 {
     167           30 :         self.ptr.import_name_rva()
     168           30 :     }
     169              : 
     170              :     /// Resolved import name
     171           30 :     pub fn import_name(&self) -> String {
     172           30 :         self.ptr.import_name().to_string()
     173           30 :     }
     174              : 
     175              :     /// Reserved. Should be 0
     176           30 :     pub fn reserved(&self) -> u32 {
     177           30 :         self.ptr.reserved()
     178           30 :     }
     179              : 
     180              :     /// The unique identifier of the primary module for the enclave, if the
     181              :     /// [`EnclaveImport::get_type`] is [`Type::UNIQUE_ID`]. Otherwise, the author identifier of the
     182              :     /// primary module for the enclave.
     183           30 :     pub fn id(&self) -> &[u8] {
     184           30 :         to_slice!(self.ptr.id());
     185           30 :     }
     186              : 
     187              :     /// The family identifier of the primary module for the enclave.
     188           30 :     pub fn family_id(&self) -> &[u8] {
     189           30 :         to_slice!(self.ptr.family_id());
     190           30 :     }
     191              : 
     192              :     /// The image identifier of the primary module for the enclave.
     193           30 :     pub fn image_id(&self) -> &[u8] {
     194           30 :         to_slice!(self.ptr.image_id());
     195           30 :     }
     196              : }
     197              : 
     198              : impl std::fmt::Debug for EnclaveImport<'_> {
     199           30 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     200           30 :         f.debug_struct("EnclaveImport")
     201           30 :             .field("type", &self.get_type())
     202           30 :             .field("min_security_version", &self.min_security_version())
     203           30 :             .field("import_name_rva", &self.import_name_rva())
     204           30 :             .field("import_name", &self.import_name())
     205           30 :             .field("reserved", &self.reserved())
     206           30 :             .field("id", &self.id())
     207           30 :             .field("family_id", &self.family_id())
     208           30 :             .field("image_id", &self.image_id())
     209           30 :             .finish()
     210           30 :     }
     211              : }
     212              : 
     213              : impl std::fmt::Display for EnclaveImport<'_> {
     214           30 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     215           30 :         write!(f, "{}", self.ptr.to_string())
     216           30 :     }
     217              : }
     218              : 
     219              : impl<'a> FromFFI<ffi::PE_EnclaveImport> for EnclaveImport<'a> {
     220           30 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_EnclaveImport>) -> Self {
     221           30 :         Self {
     222           30 :             ptr,
     223           30 :             _owner: PhantomData,
     224           30 :         }
     225           30 :     }
     226              : }
     227              : 
     228              : #[allow(non_camel_case_types)]
     229           30 : #[derive(Debug, Copy, Clone)]
     230              : pub enum Type {
     231              :     /// None of the identifiers of the image need to match the value in the
     232              :     /// import record.
     233              :     NONE,
     234              : 
     235              :     /// The value of the enclave unique identifier of the image must match the
     236              :     /// value in the import record. Otherwise, loading of the image fails.
     237              :     UNIQUE_ID,
     238              : 
     239              :     /// The value of the enclave author identifier of the image must match the
     240              :     /// value in the import record. Otherwise, loading of the image fails. If
     241              :     /// this flag is set and the import record indicates an author identifier
     242              :     /// of all zeros, the imported image must be part of the Windows installation.
     243              :     AUTHOR_ID,
     244              : 
     245              :           /// The value of the enclave family identifier of the image must match the
     246              :     /// value in the import record. Otherwise, loading of the image fails.
     247              :     FAMILY_ID,
     248              : 
     249              :     /// The value of the enclave image identifier of the image must match the
     250              :     /// value in the import record. Otherwise, loading of the image fails.
     251              :     IMAGE_ID,
     252              :     UNKNOWN(u32),
     253              : }
     254              : 
     255              : impl From<u32> for Type {
     256           30 :     fn from(value: u32) -> Self {
     257           30 :         match value {
     258            0 :             0x00000000 => Type::NONE,
     259            0 :             0x00000001 => Type::UNIQUE_ID,
     260            0 :             0x00000002 => Type::AUTHOR_ID,
     261            0 :             0x00000003 => Type::FAMILY_ID,
     262           30 :             0x00000004 => Type::IMAGE_ID,
     263            0 :             _ => Type::UNKNOWN(value),
     264              :         }
     265           30 :     }
     266              : }
     267              : 
     268           30 : declare_iterator!(
     269           30 :     Imports,
     270           30 :     EnclaveImport<'a>,
     271           30 :     ffi::PE_EnclaveImport,
     272           30 :     ffi::PE_EnclaveConfiguration,
     273           30 :     ffi::PE_EnclaveConfiguration_it_imports
     274           30 : );
     275              : 
     276              : 
        

Generated by: LCOV version 2.1-1