@@ -23,6 +23,7 @@ pub use igvm_attest::ak_cert::parse_response as parse_ak_cert_response;
23
23
use :: vmgs:: EncryptionAlgorithm ;
24
24
use :: vmgs:: Vmgs ;
25
25
use cvm_tracing:: CVM_ALLOWED ;
26
+ use get_protocol:: dps_json:: GuestStateEncryptionPolicy ;
26
27
use guest_emulation_transport:: GuestEmulationTransportClient ;
27
28
use guest_emulation_transport:: api:: GspExtendedStatusFlags ;
28
29
use guest_emulation_transport:: api:: GuestStateProtection ;
@@ -100,6 +101,8 @@ enum GetDerivedKeysError {
100
101
GetIngressKeyFromKGspByIdFailed ,
101
102
#[ error( "Encryption cannot be disabled if VMGS was previously encrypted" ) ]
102
103
DisableVmgsEncryptionFailed ,
104
+ #[ error( "VMGS encryption is required, but no encryption sources were found" ) ]
105
+ EncryptionRequiredButNotFound ,
103
106
#[ error( "failed to seal the egress key using hardware derived keys" ) ]
104
107
SealEgressKeyUsingHardwareDerivedKeys ( #[ source] hardware_key_sealing:: HardwareKeySealingError ) ,
105
108
#[ error( "failed to write to `FileId::HW_KEY_PROTECTOR` in vmgs" ) ]
@@ -237,6 +240,8 @@ pub async fn initialize_platform_security(
237
240
attestation_type : AttestationType ,
238
241
suppress_attestation : bool ,
239
242
driver : LocalDriver ,
243
+ guest_state_encryption_policy : GuestStateEncryptionPolicy ,
244
+ strict_encryption_policy : bool ,
240
245
) -> Result < PlatformAttestationData , Error > {
241
246
tracing:: info!( CVM_ALLOWED ,
242
247
attestation_type=?attestation_type,
@@ -357,6 +362,8 @@ pub async fn initialize_platform_security(
357
362
ingress_rsa_kek. as_ref ( ) ,
358
363
wrapped_des_key. as_deref ( ) ,
359
364
tcb_version,
365
+ guest_state_encryption_policy,
366
+ strict_encryption_policy,
360
367
)
361
368
. await
362
369
. map_err ( AttestationErrorInner :: GetDerivedKeys ) ?;
@@ -562,7 +569,24 @@ async fn get_derived_keys(
562
569
ingress_rsa_kek : Option < & Rsa < Private > > ,
563
570
wrapped_des_key : Option < & [ u8 ] > ,
564
571
tcb_version : Option < u64 > ,
572
+ guest_state_encryption_policy : GuestStateEncryptionPolicy ,
573
+ strict_encryption_policy : bool ,
565
574
) -> Result < DerivedKeyResult , GetDerivedKeysError > {
575
+ tracing:: info!(
576
+ CVM_ALLOWED ,
577
+ ?guest_state_encryption_policy,
578
+ strict_encryption_policy,
579
+ "encryption policy"
580
+ ) ;
581
+
582
+ // TODO: implement hardware sealing only
583
+ if matches ! (
584
+ guest_state_encryption_policy,
585
+ GuestStateEncryptionPolicy :: HardwareSealing
586
+ ) {
587
+ todo ! ( "hardware sealing" )
588
+ }
589
+
566
590
let mut key_protector_settings = KeyProtectorSettings {
567
591
should_write_kp : true ,
568
592
use_gsp_by_id : false ,
@@ -626,13 +650,20 @@ async fn get_derived_keys(
626
650
} ;
627
651
628
652
// Handle various sources of Guest State Protection
629
- let mut requires_gsp_by_id =
630
- key_protector_by_id. found_id && key_protector_by_id. inner . ported != 1 ;
653
+ let is_gsp_by_id = key_protector_by_id. found_id && key_protector_by_id. inner . ported != 1 ;
654
+ let is_gsp = key_protector. gsp [ ingress_idx] . gsp_length != 0 ;
655
+ tracing:: info!(
656
+ CVM_ALLOWED ,
657
+ is_encrypted,
658
+ is_gsp_by_id,
659
+ is_gsp,
660
+ found_dek,
661
+ "initial vmgs encryption state"
662
+ ) ;
663
+ let mut requires_gsp_by_id = is_gsp_by_id;
631
664
632
665
// Attempt GSP
633
666
let ( gsp_response, no_gsp, requires_gsp) = {
634
- let found_kp = key_protector. gsp [ ingress_idx] . gsp_length != 0 ;
635
-
636
667
let response = get_gsp_data ( get, key_protector) . await ;
637
668
638
669
tracing:: info!(
@@ -644,10 +675,19 @@ async fn get_derived_keys(
644
675
"GSP response"
645
676
) ;
646
677
647
- let no_gsp =
648
- response. extended_status_flags . no_rpc_server ( ) || response. encrypted_gsp . length == 0 ;
649
-
650
- let requires_gsp = found_kp || response. extended_status_flags . requires_rpc_server ( ) ;
678
+ let no_gsp = response. extended_status_flags . no_rpc_server ( )
679
+ || response. encrypted_gsp . length == 0
680
+ || ( matches ! (
681
+ guest_state_encryption_policy,
682
+ GuestStateEncryptionPolicy :: GspById | GuestStateEncryptionPolicy :: None
683
+ ) && ( !is_gsp || strict_encryption_policy) ) ;
684
+
685
+ let requires_gsp = is_gsp
686
+ || response. extended_status_flags . requires_rpc_server ( )
687
+ || matches ! (
688
+ guest_state_encryption_policy,
689
+ GuestStateEncryptionPolicy :: GspKey
690
+ ) ;
651
691
652
692
// If the VMGS is encrypted, but no key protection data is found,
653
693
// assume GspById encryption is enabled, but no ID file was written.
@@ -658,14 +698,19 @@ async fn get_derived_keys(
658
698
( response, no_gsp, requires_gsp)
659
699
} ;
660
700
661
- // Attempt GSP By Id protection if GSP is not available, or when changing schemes.
701
+ // Attempt GSP By Id protection if GSP is not available, when changing
702
+ // schemes, or as requested
662
703
let ( gsp_response_by_id, no_gsp_by_id) = if no_gsp || requires_gsp_by_id {
663
704
let gsp_response_by_id = get
664
705
. guest_state_protection_data_by_id ( )
665
706
. await
666
707
. map_err ( GetDerivedKeysError :: FetchGuestStateProtectionById ) ?;
667
708
668
- let no_gsp_by_id = gsp_response_by_id. extended_status_flags . no_registry_file ( ) ;
709
+ let no_gsp_by_id = gsp_response_by_id. extended_status_flags . no_registry_file ( )
710
+ || ( matches ! (
711
+ guest_state_encryption_policy,
712
+ GuestStateEncryptionPolicy :: None
713
+ ) && ( !requires_gsp_by_id || strict_encryption_policy) ) ;
669
714
670
715
if no_gsp_by_id && requires_gsp_by_id {
671
716
Err ( GetDerivedKeysError :: GspByIdRequiredButNotFound ) ?
@@ -768,14 +813,23 @@ async fn get_derived_keys(
768
813
if is_encrypted {
769
814
Err ( GetDerivedKeysError :: DisableVmgsEncryptionFailed ) ?
770
815
}
771
-
772
- tracing:: trace!( CVM_ALLOWED , "No VMGS encryption used." ) ;
773
-
774
- return Ok ( DerivedKeyResult {
775
- derived_keys : None ,
776
- key_protector_settings,
777
- gsp_extended_status_flags : gsp_response. extended_status_flags ,
778
- } ) ;
816
+ match guest_state_encryption_policy {
817
+ // fail if some minimum level of encryption was required
818
+ GuestStateEncryptionPolicy :: GspById
819
+ | GuestStateEncryptionPolicy :: GspKey
820
+ | GuestStateEncryptionPolicy :: HardwareSealing => {
821
+ Err ( GetDerivedKeysError :: EncryptionRequiredButNotFound ) ?
822
+ }
823
+ GuestStateEncryptionPolicy :: Auto | GuestStateEncryptionPolicy :: None => {
824
+ tracing:: info!( CVM_ALLOWED , "No VMGS encryption used." ) ;
825
+
826
+ return Ok ( DerivedKeyResult {
827
+ derived_keys : None ,
828
+ key_protector_settings,
829
+ gsp_extended_status_flags : gsp_response. extended_status_flags ,
830
+ } ) ;
831
+ }
832
+ }
779
833
}
780
834
781
835
// Attempt to get hardware derived keys
@@ -803,7 +857,7 @@ async fn get_derived_keys(
803
857
804
858
// Use tenant key (KEK only)
805
859
if no_gsp && no_gsp_by_id {
806
- tracing:: trace !( CVM_ALLOWED , "No GSP used with SKR" ) ;
860
+ tracing:: info !( CVM_ALLOWED , "No GSP used with SKR" ) ;
807
861
808
862
derived_keys. ingress = ingress_key;
809
863
derived_keys. decrypt_egress = decrypt_egress_key;
@@ -837,7 +891,20 @@ async fn get_derived_keys(
837
891
. map_err ( GetDerivedKeysError :: GetDerivedKeyById ) ?;
838
892
839
893
if no_kek && no_gsp {
840
- tracing:: trace!( CVM_ALLOWED , "Using GSP with ID." ) ;
894
+ if matches ! (
895
+ guest_state_encryption_policy,
896
+ GuestStateEncryptionPolicy :: None
897
+ ) {
898
+ // Log a warning here to indicate that the VMGS state is out of
899
+ // sync with the VM's configuration.
900
+ //
901
+ // This should only happen if the VM is configured to
902
+ // have no encryption, but it already has GspById encryption
903
+ // and strict encryption policy is disabled.
904
+ tracing:: warn!( CVM_ALLOWED , "Allowing GspById" ) ;
905
+ } else {
906
+ tracing:: info!( CVM_ALLOWED , "Using GspById" ) ;
907
+ }
841
908
842
909
// Not required for Id protection
843
910
key_protector_settings. should_write_kp = false ;
@@ -852,7 +919,7 @@ async fn get_derived_keys(
852
919
853
920
derived_keys. ingress = derived_keys_by_id. ingress ;
854
921
855
- tracing:: trace !( CVM_ALLOWED , "Converting GSP method." ) ;
922
+ tracing:: info !( CVM_ALLOWED , "Converting GSP method." ) ;
856
923
}
857
924
858
925
let egress_seed;
@@ -969,6 +1036,21 @@ async fn get_derived_keys(
969
1036
}
970
1037
}
971
1038
1039
+ if matches ! (
1040
+ guest_state_encryption_policy,
1041
+ GuestStateEncryptionPolicy :: None | GuestStateEncryptionPolicy :: GspById
1042
+ ) {
1043
+ // Log a warning here to indicate that the VMGS state is out of
1044
+ // sync with the VM's configuration.
1045
+ //
1046
+ // This should only happen if the VM is configured to have no
1047
+ // encryption or GspById encryption, but it already has GspKey
1048
+ // encryption and strict encryption policy is disabled.
1049
+ tracing:: warn!( CVM_ALLOWED , "Allowing Gsp" ) ;
1050
+ } else {
1051
+ tracing:: info!( CVM_ALLOWED , "Using Gsp" ) ;
1052
+ }
1053
+
972
1054
Ok ( DerivedKeyResult {
973
1055
derived_keys : Some ( derived_keys) ,
974
1056
key_protector_settings,
0 commit comments