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

Generated by: LCOV version 2.1-1