@@ -8,7 +8,7 @@ use enumflags2::BitFlags;
88use log:: { debug, info, trace} ;
99
1010use osutils:: {
11- encryption as osutils_encryption, files, path,
11+ container , efivar , encryption as osutils_encryption, files, path,
1212 pcrlock:: { self , PCRLOCK_POLICY_JSON_PATH } ,
1313} ;
1414use sysdefs:: tpm2:: Pcr ;
@@ -89,53 +89,43 @@ pub(super) fn validate_host_config(ctx: &EngineContext) -> Result<(), TridentErr
8989 }
9090
9191 // We've already validated that only supported PCRs, i.e. 4, 7, and/or 11, are specified;
92- // but we also need to ensure that only valid PCRs are specified for each image type .
93- if !encryption . pcrs . is_empty ( ) {
94- if ctx . is_uki ( ) ? {
95- // TODO: Currently, we cannot seal to PCR 7 for grub MOS -> UKI ROS scenario b/c
96- // not all measurements are recognized by the .pcrlock file generation logic. Once
97- // that is resolved, we include PCR 7 into the valid list. For now, only PCRs 4 and
98- // 11 are valid. Related ADO tasks:
99- // https://dev.azure.com/mariner-org/polar/_workitems/edit/14523/ and
100- // https://dev.azure.com/mariner-org/polar/_workitems/edit/14455/.
101- let invalid_pcrs: Vec < _ > = encryption
102- . pcrs
92+ // but we also need to ensure that only PCR 7 is specified for grub images .
93+ if !ctx . is_uki ( ) ? {
94+ let invalid_pcrs : Vec < _ > = encryption
95+ . pcrs
96+ . iter ( )
97+ . filter ( | & & pcr| pcr != Pcr :: Pcr7 )
98+ . cloned ( )
99+ . collect ( ) ;
100+
101+ if ! invalid_pcrs. is_empty ( ) {
102+ let pcrs_string = invalid_pcrs
103103 . iter ( )
104- . filter ( |& & pcr| pcr != Pcr :: Pcr4 && pcr != Pcr :: Pcr11 )
105- . cloned ( )
106- . collect ( ) ;
107-
108- if !invalid_pcrs. is_empty ( ) {
109- let pcrs_string = invalid_pcrs
110- . iter ( )
111- . map ( |pcr| pcr. to_num ( ) . to_string ( ) )
112- . collect :: < Vec < _ > > ( )
113- . join ( ", " ) ;
104+ . map ( |pcr| pcr. to_num ( ) . to_string ( ) )
105+ . collect :: < Vec < _ > > ( )
106+ . join ( ", " ) ;
107+ return Err ( TridentError :: new ( InvalidInputError :: from (
108+ HostConfigurationDynamicValidationError :: InvalidEncryptionPcrsForGrubImage {
109+ pcrs : pcrs_string,
110+ } ,
111+ ) ) ) ;
112+ }
113+ } else {
114+ // For UKI images, if PCR 7 is requested, we need to ensure that:
115+ // 1. Secure Boot is enabled,
116+ // 2. Trident is NOT running inside a container,
117+ // due to the limitations of `systemd-pcrlock`.
118+ if encryption. pcrs . contains ( & Pcr :: Pcr7 ) {
119+ if !efivar:: secure_boot_is_enabled ( ) {
114120 return Err ( TridentError :: new ( InvalidInputError :: from (
115- HostConfigurationDynamicValidationError :: InvalidEncryptionPcrsForUkiImage {
116- pcrs : pcrs_string,
117- } ,
121+ HostConfigurationDynamicValidationError :: Pcr7EncryptionForUkiWhenSecureBootDisabled ,
118122 ) ) ) ;
119123 }
120- } else {
121- let invalid_pcrs: Vec < _ > = encryption
122- . pcrs
123- . iter ( )
124- . filter ( |& & pcr| pcr != Pcr :: Pcr7 )
125- . cloned ( )
126- . collect ( ) ;
127124
128- if !invalid_pcrs. is_empty ( ) {
129- let pcrs_string = invalid_pcrs
130- . iter ( )
131- . map ( |pcr| pcr. to_num ( ) . to_string ( ) )
132- . collect :: < Vec < _ > > ( )
133- . join ( ", " ) ;
125+ if container:: is_running_in_container ( ) ? {
134126 return Err ( TridentError :: new ( InvalidInputError :: from (
135- HostConfigurationDynamicValidationError :: InvalidEncryptionPcrsForGrubImage {
136- pcrs : pcrs_string,
137- } ,
138- ) ) ) ;
127+ HostConfigurationDynamicValidationError :: Pcr7EncryptionForUkiWhenRunningInContainer ,
128+ ) ) ) ;
139129 }
140130 }
141131 }
@@ -148,15 +138,15 @@ pub(super) fn validate_host_config(ctx: &EngineContext) -> Result<(), TridentErr
148138/// persists the pcrlock policy to the update volume.
149139///
150140/// On clean install:
151- /// 1. TODO: UKI MOS + UKI ROS -> re-generate pcrlock policy to include PCRs 4,7,11 as selected by
152- /// the user; not implemented for now. Related ADO task:
141+ /// 1. TODO: UKI MOS + UKI target OS -> re-generate pcrlock policy to include PCRs 4,7,11 as
142+ /// selected by the user; not implemented for now. Related ADO task:
153143/// https://dev.azure.com/mariner-org/polar/_workitems/edit/13059/.
154- /// 2. Grub MOS + UKI ROS -> N/A, i.e. keep previous pcrlock policy that includes PCR 0 only,
155- /// 3. Grub MOS + grub ROS -> N/A, i.e. still sealed to the value of PCR 7.
144+ /// 2. Grub MOS + UKI target OS -> N/A, i.e. keep previous pcrlock policy that includes PCR 0 only,
145+ /// 3. Grub MOS + grub target OS -> N/A, i.e. still sealed to the value of PCR 7.
156146///
157147/// On A/B update:
158- /// 1. UKI ROS -> re-generate pcrlock policy to include PCRs 4,7,11 as selected by the user,
159- /// 2. Grub ROS -> N/A, i.e. keep previous pcrlock policy that includes PCR 7 only.
148+ /// 1. UKI target OS -> re-generate pcrlock policy to include PCRs 4,7,11 as selected by the user,
149+ /// 2. Grub target OS -> N/A, i.e. keep previous pcrlock policy that includes PCR 7 only.
160150#[ tracing:: instrument( name = "encryption_provision" , skip_all) ]
161151pub fn provision ( ctx : & EngineContext , mount_path : & Path ) -> Result < ( ) , TridentError > {
162152 if let Some ( encryption) = & ctx. spec . storage . encryption {
@@ -168,23 +158,10 @@ pub fn provision(ctx: &EngineContext, mount_path: &Path) -> Result<(), TridentEr
168158 // On A/B update, use PCRs selected by the user through the API
169159 ServicingType :: AbUpdate => {
170160 if ctx. is_uki ( ) ? {
171- let bitflags = if !encryption. pcrs . is_empty ( ) {
172- encryption
173- . pcrs
174- . iter ( )
175- . fold ( BitFlags :: empty ( ) , |acc, & pcr| acc | BitFlags :: from ( pcr) )
176- } else {
177- // TODO: Currently, we cannot seal to PCR 7 b/c not all measurements are
178- // recognized by the .pcrlock file generation logic. Once that is resolved,
179- // we want to have PCR 7 as the default. For now, we use PCRs 4 and 11. Related
180- // ADO tasks:
181- // https://dev.azure.com/mariner-org/polar/_workitems/edit/14523/ and
182- // https://dev.azure.com/mariner-org/polar/_workitems/edit/14455/.
183- //
184- // Use default PCR if none specified.
185- //BitFlags::from(osutils_encryption::DEFAULT_PCR)
186- BitFlags :: from ( Pcr :: Pcr4 ) | BitFlags :: from ( Pcr :: Pcr11 )
187- } ;
161+ let bitflags = encryption
162+ . pcrs
163+ . iter ( )
164+ . fold ( BitFlags :: empty ( ) , |acc, & pcr| acc | BitFlags :: from ( pcr) ) ;
188165 Some ( bitflags)
189166 } else {
190167 debug ! (
@@ -552,27 +529,8 @@ mod tests {
552529 }
553530 validate_host_config ( & ctx) . unwrap ( ) ;
554531
555- // Test case #2: If OS image is a UKI image, then only PCRs 4 and 11 are allowed .
532+ // Test case #2: If OS image is a UKI image AND PCRs only include 4 and 11, then pass .
556533 ctx. is_uki = Some ( true ) ;
557- {
558- let encryption = ctx. spec . storage . encryption . as_mut ( ) . unwrap ( ) ;
559- encryption. pcrs = vec ! [ Pcr :: Pcr4 , Pcr :: Pcr7 , Pcr :: Pcr11 ] ;
560- }
561- let pcrs_str = [ Pcr :: Pcr7 ]
562- . iter ( )
563- . map ( |pcr| pcr. to_num ( ) . to_string ( ) )
564- . collect :: < Vec < _ > > ( )
565- . join ( ", " ) ;
566- assert_eq ! (
567- validate_host_config( & ctx) . unwrap_err( ) . kind( ) ,
568- & ErrorKind :: InvalidInput ( InvalidInputError :: InvalidHostConfigurationDynamic {
569- inner: HostConfigurationDynamicValidationError :: InvalidEncryptionPcrsForUkiImage {
570- pcrs: pcrs_str,
571- }
572- } )
573- ) ;
574-
575- // Test case #3: If OS image is a UKI image AND PCRs only include 4 and 11, then pass.
576534 {
577535 let encryption = ctx. spec . storage . encryption . as_mut ( ) . unwrap ( ) ;
578536 encryption. pcrs = vec ! [ Pcr :: Pcr4 , Pcr :: Pcr11 ] ;
0 commit comments