VYPR
High severityOSV Advisory· Published Oct 27, 2025· Updated Apr 15, 2026

CVE-2025-58356

CVE-2025-58356

Description

Constellation is the first Confidential Kubernetes. The Constellation CVM image uses LUKS2-encrypted volumes for persistent storage. When opening an encrypted storage device, the CVM uses the libcryptsetup function crypt_activate_by_passhrase. If the VM is successful in opening the partition with the disk encryption key, it treats the volume as confidential. However, due to the unsafe handling of null keyslot algorithms in the cryptsetup 2.8.1, it is possible that the opened volume is not encrypted at all. Cryptsetup prior to version 2.8.1 does not report an error when processing LUKS2-formatted disks that use the cipher_null-ecb algorithm in the keyslot encryption field. This vulnerability is fixed in 2.24.0.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/edgelesssys/constellation/v2Go
< 2.24.02.24.0

Affected products

1

Patches

2
7437fc02efbd

attestation: hardcode measurements for v2.24.0

1 file changed · +8 8
  • internal/attestation/measurements/measurements_enterprise.go+8 8 modified
    @@ -19,14 +19,14 @@ package measurements
     
     // revive:disable:var-naming
     var (
    -	aws_AWSNitroTPM          = M{0: {Expected: []byte{0x73, 0x7f, 0x76, 0x7a, 0x12, 0xf5, 0x4e, 0x70, 0xee, 0xcb, 0xc8, 0x68, 0x40, 0x11, 0x32, 0x3a, 0xe2, 0xfe, 0x2d, 0xd9, 0xf9, 0x07, 0x85, 0x57, 0x79, 0x69, 0xd7, 0xa2, 0x01, 0x3e, 0x8c, 0x12}, ValidationOpt: WarnOnly}, 2: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 3: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 4: {Expected: []byte{0x2b, 0x06, 0x8e, 0x47, 0x2c, 0x87, 0xe1, 0xdd, 0xa4, 0x12, 0x97, 0x6e, 0x32, 0x2b, 0x37, 0x47, 0x9f, 0x69, 0xce, 0xaa, 0x52, 0x76, 0x27, 0xf9, 0xca, 0x2e, 0x61, 0x3f, 0x4f, 0x8d, 0x2f, 0x45}, ValidationOpt: Enforce}, 6: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0x7c, 0x96, 0xf4, 0xb2, 0x90, 0xf2, 0xfa, 0x65, 0x79, 0xd4, 0x48, 0x56, 0x89, 0x69, 0x17, 0xf9, 0xf2, 0xd7, 0xcc, 0x4f, 0x88, 0x50, 0x6c, 0x77, 0xda, 0xd9, 0x80, 0xd0, 0x4f, 0x3d, 0x67, 0x39}, ValidationOpt: Enforce}, 11: {Expected: []byte{0x6a, 0x6c, 0xdf, 0x75, 0x90, 0x0d, 0xcd, 0x4f, 0x77, 0x01, 0x5b, 0x39, 0x47, 0xac, 0xc6, 0x46, 0x58, 0xac, 0x53, 0x50, 0x09, 0x32, 0x60, 0x1f, 0xe9, 0x1f, 0x8b, 0x11, 0xa2, 0x03, 0x51, 0x87}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
    -	aws_AWSSEVSNP            = M{0: {Expected: []byte{0xd6, 0xdf, 0x85, 0x53, 0x58, 0xf5, 0xb1, 0x0f, 0x06, 0xf0, 0xfa, 0xb3, 0xf4, 0x08, 0xad, 0x26, 0xcd, 0x16, 0x5a, 0x29, 0x49, 0xba, 0xd6, 0x9e, 0x2c, 0xc7, 0x56, 0x92, 0x52, 0x9e, 0x66, 0x2a}, ValidationOpt: WarnOnly}, 2: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 3: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 4: {Expected: []byte{0xa0, 0x32, 0xe9, 0xcd, 0x10, 0x4f, 0xc4, 0xc9, 0x9a, 0x96, 0xc1, 0x51, 0x22, 0x26, 0x7a, 0xba, 0xf0, 0x46, 0x6f, 0xf7, 0x54, 0x3d, 0x95, 0x3d, 0x59, 0xcd, 0xe5, 0xd3, 0xfd, 0x0f, 0x85, 0x5d}, ValidationOpt: Enforce}, 6: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0x5a, 0xc0, 0x1b, 0x5f, 0x24, 0xec, 0x4e, 0x69, 0xc6, 0x85, 0x65, 0x1b, 0x90, 0x8c, 0xd2, 0x90, 0x34, 0x54, 0x7d, 0x78, 0xed, 0x96, 0xfe, 0x78, 0x06, 0xc1, 0x7a, 0x30, 0xf4, 0x35, 0xcf, 0x24}, ValidationOpt: Enforce}, 11: {Expected: []byte{0x8d, 0x8e, 0x93, 0x66, 0x4b, 0xad, 0x5c, 0xcc, 0x66, 0x53, 0x0e, 0xd5, 0x4f, 0x59, 0x2f, 0x20, 0x89, 0x50, 0x46, 0x4f, 0xf3, 0x0e, 0x95, 0xbf, 0x1f, 0xb3, 0xfc, 0xb2, 0x4d, 0x85, 0x33, 0xb8}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
    -	azure_AzureSEVSNP        = M{1: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 2: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 3: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 4: {Expected: []byte{0x2d, 0xcf, 0xde, 0x7f, 0x0a, 0xe6, 0x6e, 0xfc, 0x28, 0x7a, 0xd4, 0x78, 0xdc, 0x40, 0x0e, 0xb6, 0x63, 0x88, 0xb1, 0xf3, 0x7e, 0xfc, 0xb3, 0xa7, 0x12, 0x01, 0xd3, 0x9f, 0xa4, 0x24, 0x76, 0x75}, ValidationOpt: Enforce}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0xc0, 0x3d, 0xa9, 0xb9, 0x41, 0x0f, 0x6d, 0x94, 0x93, 0x7b, 0xf0, 0xe8, 0x41, 0x4e, 0x5e, 0x08, 0x77, 0x9b, 0xc8, 0x93, 0x59, 0x77, 0xfe, 0x89, 0x0e, 0xae, 0x6a, 0x9c, 0xde, 0x6f, 0xd9, 0x23}, ValidationOpt: Enforce}, 11: {Expected: []byte{0x84, 0x4b, 0x8a, 0x7c, 0xa2, 0x5c, 0x58, 0x98, 0x98, 0x86, 0x65, 0xbd, 0x44, 0x41, 0x49, 0x64, 0xa7, 0x07, 0x91, 0x24, 0x2c, 0x2b, 0x80, 0xb7, 0x48, 0xf2, 0x96, 0x26, 0xf0, 0x5d, 0x68, 0x16}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
    -	azure_AzureTDX           = M{1: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 2: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 3: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 4: {Expected: []byte{0x06, 0xd9, 0x3f, 0xe6, 0xbe, 0x46, 0x6a, 0x2d, 0xcf, 0x0a, 0x46, 0xbe, 0xf2, 0xc9, 0xd8, 0x3c, 0x24, 0xd3, 0xcd, 0xe8, 0x80, 0x88, 0x18, 0x40, 0x43, 0x92, 0x47, 0x3a, 0x6c, 0xb8, 0xe4, 0xe2}, ValidationOpt: Enforce}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0xc5, 0x11, 0x83, 0x37, 0xa8, 0x87, 0xa1, 0x8c, 0x86, 0x25, 0x75, 0xf0, 0x64, 0xf9, 0x5b, 0x1c, 0x9a, 0x1f, 0x1f, 0x17, 0x98, 0x02, 0x16, 0x6c, 0xff, 0x8c, 0x16, 0x67, 0xf4, 0xdf, 0xc7, 0x11}, ValidationOpt: Enforce}, 11: {Expected: []byte{0x3b, 0x85, 0xb0, 0x70, 0xa4, 0xd1, 0x75, 0xab, 0xf6, 0x03, 0x25, 0x50, 0x39, 0x5d, 0x36, 0x3e, 0x01, 0x62, 0x79, 0x73, 0x09, 0x9f, 0x4b, 0xe8, 0x87, 0xdd, 0x11, 0xfd, 0xaf, 0x31, 0x41, 0xa4}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
    +	aws_AWSNitroTPM          = M{0: {Expected: []byte{0x73, 0x7f, 0x76, 0x7a, 0x12, 0xf5, 0x4e, 0x70, 0xee, 0xcb, 0xc8, 0x68, 0x40, 0x11, 0x32, 0x3a, 0xe2, 0xfe, 0x2d, 0xd9, 0xf9, 0x07, 0x85, 0x57, 0x79, 0x69, 0xd7, 0xa2, 0x01, 0x3e, 0x8c, 0x12}, ValidationOpt: WarnOnly}, 2: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 3: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 4: {Expected: []byte{0xe4, 0x1f, 0x2c, 0x4c, 0x6f, 0x44, 0xf9, 0xa0, 0xbb, 0x67, 0xdb, 0x39, 0xb9, 0xa7, 0x28, 0x29, 0x5a, 0x3d, 0x72, 0x26, 0xa8, 0xd6, 0xfd, 0xa0, 0xfe, 0xb6, 0x44, 0xc9, 0xc9, 0xcb, 0x4d, 0x26}, ValidationOpt: Enforce}, 6: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0x55, 0x70, 0x00, 0x2a, 0x66, 0xcf, 0xeb, 0x3d, 0xd9, 0xd8, 0xd7, 0x7c, 0xd3, 0x34, 0x13, 0x80, 0xfa, 0x18, 0x86, 0x2a, 0x14, 0xa0, 0xae, 0x7c, 0xa8, 0xf1, 0xb5, 0x46, 0x0f, 0x04, 0x73, 0x77}, ValidationOpt: Enforce}, 11: {Expected: []byte{0x59, 0xea, 0x7e, 0x65, 0x4a, 0x99, 0x2b, 0x74, 0x46, 0x04, 0x4c, 0x5d, 0x5d, 0xf1, 0xf2, 0x10, 0x6a, 0xa5, 0x9b, 0x2a, 0x50, 0xe0, 0xd9, 0xb4, 0x38, 0xb1, 0x82, 0x1a, 0x8a, 0xbb, 0x59, 0x79}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
    +	aws_AWSSEVSNP            = M{0: {Expected: []byte{0xd6, 0xdf, 0x85, 0x53, 0x58, 0xf5, 0xb1, 0x0f, 0x06, 0xf0, 0xfa, 0xb3, 0xf4, 0x08, 0xad, 0x26, 0xcd, 0x16, 0x5a, 0x29, 0x49, 0xba, 0xd6, 0x9e, 0x2c, 0xc7, 0x56, 0x92, 0x52, 0x9e, 0x66, 0x2a}, ValidationOpt: WarnOnly}, 2: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 3: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 4: {Expected: []byte{0x26, 0xaf, 0x34, 0xbd, 0x97, 0xda, 0x78, 0x33, 0x9c, 0x04, 0x6d, 0xdf, 0x65, 0x6f, 0xf2, 0x03, 0x03, 0xb6, 0xe5, 0x3d, 0x90, 0x2d, 0x39, 0xf7, 0xd8, 0x17, 0x29, 0x5a, 0x3f, 0x27, 0x23, 0x12}, ValidationOpt: Enforce}, 6: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0x34, 0x2e, 0x5d, 0xc0, 0x54, 0xf1, 0x6b, 0x09, 0xb5, 0xf5, 0xb5, 0xdd, 0xb6, 0xa1, 0x64, 0x45, 0xe7, 0xcf, 0xfb, 0xc1, 0xa0, 0xca, 0x9e, 0xb6, 0xf4, 0xaf, 0xeb, 0xe1, 0x8f, 0xdf, 0x05, 0xe9}, ValidationOpt: Enforce}, 11: {Expected: []byte{0x11, 0xcd, 0xf7, 0xda, 0xd7, 0x2e, 0xeb, 0xc8, 0x10, 0x37, 0xf2, 0x8d, 0xfa, 0x39, 0x8d, 0xdc, 0xf8, 0x62, 0xd4, 0xbc, 0xd3, 0xd8, 0xda, 0x09, 0x1d, 0xb2, 0x99, 0xb0, 0xb8, 0xb3, 0x70, 0xd7}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
    +	azure_AzureSEVSNP        = M{1: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 2: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 3: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 4: {Expected: []byte{0x9b, 0x92, 0x97, 0x44, 0x18, 0x83, 0xed, 0x76, 0x24, 0x48, 0x6b, 0xb0, 0x18, 0x72, 0xd0, 0xca, 0x10, 0xae, 0x3b, 0x6e, 0xbd, 0x69, 0x63, 0xb4, 0xca, 0x21, 0x34, 0x7e, 0x39, 0xcb, 0xd8, 0xb6}, ValidationOpt: Enforce}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0x05, 0x1a, 0x43, 0x49, 0x02, 0xde, 0xcb, 0xe9, 0x37, 0x1f, 0x97, 0x67, 0x4c, 0x51, 0x3f, 0x69, 0x4b, 0x11, 0x67, 0x46, 0xb4, 0x8a, 0x9f, 0xb4, 0xbe, 0x10, 0x27, 0xdc, 0x71, 0x43, 0x1c, 0xdc}, ValidationOpt: Enforce}, 11: {Expected: []byte{0x67, 0xf7, 0x60, 0x72, 0x7f, 0xe5, 0x8e, 0xce, 0xeb, 0xe4, 0x28, 0x73, 0xc0, 0xc7, 0x6a, 0xa2, 0xba, 0x76, 0x66, 0x5d, 0x95, 0x8f, 0xe8, 0x7b, 0xa5, 0xf0, 0xab, 0xc8, 0x31, 0xef, 0x8e, 0xaa}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
    +	azure_AzureTDX           = M{1: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 2: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 3: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 4: {Expected: []byte{0x66, 0x8d, 0xf9, 0x5c, 0x0a, 0x26, 0x82, 0x4b, 0x51, 0xf1, 0x0c, 0x95, 0x98, 0x00, 0xe0, 0xd6, 0xa3, 0x73, 0x2a, 0x91, 0x44, 0xdb, 0x0b, 0xbe, 0x2f, 0xa5, 0xe3, 0x25, 0x8b, 0xe8, 0x23, 0xa9}, ValidationOpt: Enforce}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0x72, 0x71, 0x45, 0xb6, 0x85, 0x4f, 0xf4, 0xfb, 0xa6, 0x75, 0x7e, 0xbb, 0xea, 0x29, 0xdf, 0xdb, 0xb4, 0xd8, 0x38, 0xad, 0xda, 0xfd, 0x0c, 0xf5, 0x85, 0x98, 0x8e, 0xd3, 0x96, 0x99, 0xf1, 0x2d}, ValidationOpt: Enforce}, 11: {Expected: []byte{0xa6, 0x8f, 0xec, 0x12, 0x06, 0x98, 0x1d, 0xfa, 0xc5, 0x63, 0xd0, 0x6b, 0x9b, 0x81, 0x78, 0x78, 0x33, 0x2d, 0xfa, 0xed, 0xf0, 0x74, 0x2a, 0x21, 0x99, 0x72, 0xa4, 0x59, 0xb4, 0xcd, 0x96, 0xd5}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
     	azure_AzureTrustedLaunch M
    -	gcp_GCPSEVES             = M{1: {Expected: []byte{0x36, 0x95, 0xdc, 0xc5, 0x5e, 0x3a, 0xa3, 0x40, 0x27, 0xc2, 0x77, 0x93, 0xc8, 0x5c, 0x72, 0x3c, 0x69, 0x7d, 0x70, 0x8c, 0x42, 0xd1, 0xf7, 0x3b, 0xd6, 0xfa, 0x4f, 0x26, 0x60, 0x8a, 0x5b, 0x24}, ValidationOpt: WarnOnly}, 2: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 3: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 4: {Expected: []byte{0x75, 0xc7, 0xf8, 0xd0, 0x87, 0x69, 0xdc, 0x52, 0x4c, 0x71, 0x07, 0x07, 0xe9, 0xf7, 0x44, 0x20, 0x5b, 0xcd, 0xda, 0x13, 0x69, 0x91, 0x41, 0x45, 0xe6, 0xa0, 0xfe, 0x21, 0x63, 0x34, 0xd1, 0xd5}, ValidationOpt: Enforce}, 6: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0x0c, 0x20, 0x6f, 0xef, 0x8f, 0xa9, 0xbf, 0x50, 0x12, 0x4d, 0x98, 0xa2, 0x30, 0xd8, 0xfa, 0x7f, 0xf2, 0xaf, 0xd0, 0xba, 0x57, 0x48, 0x66, 0xfd, 0x19, 0xde, 0xe5, 0x8b, 0xf1, 0x79, 0xe5, 0x0b}, ValidationOpt: Enforce}, 11: {Expected: []byte{0xf9, 0xcb, 0x64, 0x16, 0x07, 0x1a, 0x44, 0x09, 0x0a, 0x7a, 0xde, 0x98, 0xc2, 0x82, 0x31, 0x1d, 0x51, 0xf0, 0xc9, 0x4e, 0x55, 0x62, 0x1d, 0x23, 0x0d, 0xee, 0x20, 0x85, 0xe5, 0x2e, 0x94, 0x36}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
    -	gcp_GCPSEVSNP            = M{1: {Expected: []byte{0x36, 0x95, 0xdc, 0xc5, 0x5e, 0x3a, 0xa3, 0x40, 0x27, 0xc2, 0x77, 0x93, 0xc8, 0x5c, 0x72, 0x3c, 0x69, 0x7d, 0x70, 0x8c, 0x42, 0xd1, 0xf7, 0x3b, 0xd6, 0xfa, 0x4f, 0x26, 0x60, 0x8a, 0x5b, 0x24}, ValidationOpt: WarnOnly}, 2: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 3: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 4: {Expected: []byte{0xe2, 0xda, 0x61, 0xbe, 0xd0, 0x5c, 0x6d, 0x36, 0xf6, 0x6e, 0x92, 0xd5, 0xd9, 0x7d, 0x27, 0x91, 0x06, 0x3e, 0x1d, 0xab, 0x34, 0xc7, 0x81, 0xcf, 0xd3, 0xe2, 0xdf, 0x5b, 0x33, 0xf2, 0x6a, 0x77}, ValidationOpt: Enforce}, 6: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0x75, 0xe9, 0x7c, 0x45, 0x75, 0xbe, 0xea, 0x86, 0xb6, 0x21, 0x2d, 0x0d, 0x8f, 0x6a, 0xb1, 0x44, 0x19, 0x9a, 0x2d, 0xaa, 0xfd, 0xd1, 0x8b, 0x73, 0xa7, 0x6b, 0x02, 0xa3, 0x3d, 0x41, 0x87, 0xd4}, ValidationOpt: Enforce}, 11: {Expected: []byte{0xa0, 0x20, 0x27, 0xd4, 0x74, 0x94, 0xe6, 0xa2, 0x82, 0x3c, 0xcd, 0x16, 0x36, 0x21, 0x20, 0xd5, 0xf7, 0x88, 0x9d, 0x8a, 0x18, 0xb4, 0x80, 0xba, 0x5a, 0xbb, 0x78, 0x54, 0x7f, 0xf5, 0x28, 0x53}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
    -	openstack_QEMUVTPM       = M{4: {Expected: []byte{0x18, 0x89, 0xf9, 0x5c, 0x02, 0x64, 0x9c, 0x2e, 0x1d, 0xb7, 0xd2, 0xab, 0x45, 0xca, 0xb9, 0x09, 0x13, 0xc6, 0x44, 0xe9, 0xc8, 0x0b, 0xf2, 0xe1, 0x18, 0x08, 0x5e, 0x30, 0xbb, 0x12, 0x18, 0xab}, ValidationOpt: Enforce}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0xe2, 0x35, 0xd2, 0xbd, 0xd4, 0x5d, 0x2e, 0x63, 0x58, 0xb3, 0xca, 0xed, 0xb1, 0x48, 0x17, 0xbd, 0x0e, 0xcc, 0x7b, 0xff, 0x4b, 0x08, 0x10, 0x34, 0x3d, 0xc1, 0x83, 0x2b, 0x6f, 0xd4, 0x9c, 0x93}, ValidationOpt: Enforce}, 11: {Expected: []byte{0x42, 0xee, 0x07, 0xc6, 0xef, 0x42, 0xc1, 0xaf, 0xcc, 0xc9, 0x36, 0x26, 0xa0, 0x23, 0x4f, 0x23, 0x55, 0x84, 0x18, 0x0c, 0x6d, 0xbc, 0x39, 0xe7, 0x14, 0x65, 0x6e, 0xcb, 0xca, 0x6b, 0x24, 0xe8}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
    +	gcp_GCPSEVES             = M{1: {Expected: []byte{0x36, 0x95, 0xdc, 0xc5, 0x5e, 0x3a, 0xa3, 0x40, 0x27, 0xc2, 0x77, 0x93, 0xc8, 0x5c, 0x72, 0x3c, 0x69, 0x7d, 0x70, 0x8c, 0x42, 0xd1, 0xf7, 0x3b, 0xd6, 0xfa, 0x4f, 0x26, 0x60, 0x8a, 0x5b, 0x24}, ValidationOpt: WarnOnly}, 2: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 3: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 4: {Expected: []byte{0x78, 0xdc, 0x5d, 0x86, 0xe5, 0xbd, 0x6e, 0x61, 0x87, 0xd8, 0x19, 0xf0, 0x36, 0x4d, 0xf2, 0x25, 0x0a, 0x31, 0xed, 0x6a, 0x96, 0xad, 0x4c, 0x01, 0x52, 0xac, 0x5f, 0x85, 0x53, 0x34, 0x68, 0xff}, ValidationOpt: Enforce}, 6: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0x9b, 0x3f, 0xa1, 0x34, 0x8a, 0xec, 0x01, 0x87, 0xef, 0xd7, 0xf2, 0x06, 0xfa, 0x15, 0xbe, 0xde, 0xb9, 0xbb, 0xe3, 0x8e, 0xf7, 0x25, 0x89, 0xaa, 0x93, 0x2f, 0xb6, 0x7b, 0x28, 0x54, 0xda, 0x57}, ValidationOpt: Enforce}, 11: {Expected: []byte{0xa2, 0x8c, 0xd2, 0x8c, 0xb2, 0xf8, 0x42, 0x65, 0xe2, 0x4f, 0xb1, 0x4d, 0x1d, 0x8e, 0x4e, 0xd8, 0xef, 0x6e, 0x1e, 0x10, 0x79, 0x77, 0x88, 0x65, 0xd5, 0x8e, 0x30, 0xfa, 0x23, 0x3b, 0x9c, 0xec}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
    +	gcp_GCPSEVSNP            = M{1: {Expected: []byte{0x36, 0x95, 0xdc, 0xc5, 0x5e, 0x3a, 0xa3, 0x40, 0x27, 0xc2, 0x77, 0x93, 0xc8, 0x5c, 0x72, 0x3c, 0x69, 0x7d, 0x70, 0x8c, 0x42, 0xd1, 0xf7, 0x3b, 0xd6, 0xfa, 0x4f, 0x26, 0x60, 0x8a, 0x5b, 0x24}, ValidationOpt: WarnOnly}, 2: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 3: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 4: {Expected: []byte{0xe2, 0xb6, 0xdb, 0xbc, 0x86, 0x92, 0x67, 0x85, 0x3c, 0xeb, 0xcc, 0xed, 0xf9, 0x80, 0xe7, 0xef, 0x13, 0xaf, 0xb7, 0xd8, 0x77, 0xa1, 0xff, 0xc3, 0xc5, 0x60, 0x05, 0xcc, 0xde, 0x17, 0xfc, 0x2b}, ValidationOpt: Enforce}, 6: {Expected: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, ValidationOpt: WarnOnly}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0xea, 0x48, 0x7f, 0xe9, 0xff, 0x3a, 0x67, 0x41, 0x90, 0x51, 0xff, 0xfa, 0xb8, 0x73, 0x4b, 0x2e, 0x30, 0xf5, 0x0c, 0xe9, 0xc1, 0xa5, 0x4d, 0xa1, 0x09, 0x19, 0x63, 0xe0, 0x02, 0x6c, 0xfc, 0xb1}, ValidationOpt: Enforce}, 11: {Expected: []byte{0xb9, 0x7d, 0x64, 0x14, 0x3b, 0x38, 0x27, 0xdc, 0x0e, 0xde, 0xc3, 0xa6, 0x35, 0xc2, 0x43, 0x48, 0x59, 0x80, 0xab, 0xce, 0x7b, 0x5c, 0xbf, 0x09, 0xd2, 0xe9, 0x1b, 0x18, 0xb2, 0xc0, 0xb2, 0x8f}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
    +	openstack_QEMUVTPM       = M{4: {Expected: []byte{0x29, 0xfb, 0xf8, 0x52, 0x34, 0xcb, 0x98, 0xbc, 0xd6, 0x96, 0x53, 0xf0, 0x1a, 0x46, 0x77, 0x37, 0x1b, 0x4e, 0x64, 0xdc, 0x7a, 0xea, 0xc5, 0x05, 0x0c, 0x80, 0x1c, 0x63, 0xdf, 0x32, 0xbc, 0x68}, ValidationOpt: Enforce}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0xa0, 0xa4, 0x07, 0x6f, 0x16, 0x66, 0x5e, 0x58, 0xc1, 0xa6, 0xd4, 0xe2, 0x4a, 0x45, 0x2b, 0x11, 0xc7, 0xbb, 0x6f, 0x89, 0x00, 0x8e, 0xf0, 0xcb, 0x94, 0xee, 0xf2, 0xc7, 0xb4, 0x63, 0x9b, 0x03}, ValidationOpt: Enforce}, 11: {Expected: []byte{0xe9, 0x01, 0xd6, 0x3d, 0xf1, 0x82, 0x02, 0x0c, 0xc5, 0x67, 0x27, 0xe4, 0x57, 0x11, 0x2f, 0x9d, 0x8c, 0x7f, 0x6b, 0xa5, 0x6b, 0x2b, 0x1a, 0x73, 0x1e, 0x6b, 0x46, 0x5f, 0x47, 0x41, 0x0d, 0xd0}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 14: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: WarnOnly}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
     	qemu_QEMUTDX             M
    -	qemu_QEMUVTPM            = M{4: {Expected: []byte{0xb5, 0x9a, 0xe5, 0x6b, 0x0f, 0x22, 0x5d, 0x57, 0x3a, 0xe9, 0x5c, 0xc2, 0x18, 0xed, 0xc5, 0x61, 0xa6, 0xec, 0xbc, 0x22, 0x9d, 0x30, 0x8f, 0xd9, 0xd8, 0xe3, 0x81, 0x1f, 0xd5, 0x94, 0x7e, 0x27}, ValidationOpt: Enforce}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0x2f, 0x81, 0x07, 0x6a, 0x6f, 0x7f, 0x03, 0xf0, 0xac, 0x3d, 0xaa, 0xe7, 0x61, 0x7f, 0x27, 0x88, 0xad, 0x5b, 0xe1, 0x69, 0x19, 0x67, 0xa5, 0xf7, 0xbe, 0x4e, 0xbc, 0xa0, 0xec, 0x08, 0x1d, 0x84}, ValidationOpt: Enforce}, 11: {Expected: []byte{0xb1, 0xda, 0xb8, 0x71, 0x45, 0x1b, 0x8e, 0x53, 0x1c, 0x4c, 0xc8, 0x1e, 0xe7, 0x22, 0xcd, 0xd9, 0x4f, 0xda, 0x71, 0x5a, 0xfd, 0xdb, 0xac, 0x90, 0x45, 0xfe, 0xac, 0xc9, 0x25, 0x60, 0x8d, 0xdf}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
    +	qemu_QEMUVTPM            = M{4: {Expected: []byte{0x4e, 0x66, 0xd2, 0xbe, 0x35, 0x4e, 0x7d, 0x69, 0xbc, 0xe0, 0xea, 0x24, 0x1b, 0xd5, 0x5f, 0xb5, 0xc1, 0x97, 0xb0, 0x7e, 0x23, 0x9f, 0xba, 0xd3, 0x21, 0x31, 0x62, 0x25, 0xf5, 0x91, 0x95, 0xb6}, ValidationOpt: Enforce}, 8: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 9: {Expected: []byte{0x55, 0xf3, 0x43, 0x4a, 0x11, 0xb5, 0x0d, 0x56, 0x10, 0x9a, 0x29, 0x63, 0xd3, 0xa8, 0x53, 0xc1, 0xf9, 0x00, 0xc4, 0xe8, 0x26, 0xb8, 0xa6, 0x48, 0x89, 0xe8, 0x64, 0x10, 0xc1, 0x5d, 0xcb, 0x15}, ValidationOpt: Enforce}, 11: {Expected: []byte{0x02, 0x72, 0x5e, 0x0a, 0x5e, 0xb6, 0xb6, 0x7d, 0xc2, 0xcd, 0x1a, 0x83, 0x6e, 0x2a, 0xd7, 0x8b, 0xef, 0xc7, 0xfb, 0xf4, 0x89, 0x5f, 0xe0, 0x8f, 0x91, 0xc9, 0x71, 0xad, 0xdb, 0xc6, 0xa4, 0xba}, ValidationOpt: Enforce}, 12: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 13: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}, 15: {Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, ValidationOpt: Enforce}}
     )
    
bb8d2c8a5c0a

cryptsetup: enable detached header (#3927)

https://github.com/edgelesssys/constellationDaniel WeißeAug 28, 2025via ghsa
10 files changed · +682 100
  • csi/test/BUILD.bazel+2 0 modified
    @@ -14,6 +14,7 @@ go_test(
             "@e2fsprogs//:bin/mkfs.ext4",
             "@util-linux//:bin/blkid",
             "@util-linux//:bin/fsck",
    +        "@util-linux//:bin/losetup",
             "@util-linux//:bin/mount",
             "@util-linux//:bin/umount",
         ],
    @@ -23,6 +24,7 @@ go_test(
             "DD": "$(rlocationpath @coreutils//:bin/dd)",
             "FSCK": "$(rlocationpath @util-linux//:bin/fsck)",
             "FSCK_EXT4": "$(rlocationpath @e2fsprogs//:bin/fsck.ext4)",
    +        "LOSETUP": "$(rlocationpath @util-linux//:bin/losetup)",
             "MKFS_EXT4": "$(rlocationpath @e2fsprogs//:bin/mkfs.ext4)",
             "MOUNT": "$(rlocationpath @util-linux//:bin/mount)",
             "RM": "$(rlocationpath @coreutils//:bin/rm)",
    
  • csi/test/mount_integration_test.go+42 26 modified
    @@ -27,11 +27,11 @@ import (
     )
     
     const (
    -	devicePath string = "testDevice"
    -	deviceName string = "testDeviceName"
    +	defaultBackingImage = "testDevice"
    +	deviceName          = "testDeviceName"
     )
     
    -var toolsEnvs = []string{"CP", "DD", "RM", "FSCK_EXT4", "MKFS_EXT4", "BLKID", "FSCK", "MOUNT", "UMOUNT"}
    +var toolsEnvs = []string{"CP", "DD", "RM", "FSCK_EXT4", "MKFS_EXT4", "BLKID", "FSCK", "MOUNT", "UMOUNT", "LOSETUP"}
     
     // addToolsToPATH is used to update the PATH to contain necessary tool binaries for
     // coreutils, util-linux and ext4.
    @@ -57,20 +57,35 @@ func addToolsToPATH() error {
     	return nil
     }
     
    -func setup(devicePath string) {
    -	if err := exec.Command("dd", "if=/dev/zero", fmt.Sprintf("of=%s", devicePath), "bs=64M", "count=1").Run(); err != nil {
    +func setup(backingDisk string) string {
    +	if err := exec.Command("dd", "if=/dev/zero", fmt.Sprintf("of=%s", backingDisk), "bs=64M", "count=1").Run(); err != nil {
     		panic(err)
     	}
    +	out, err := exec.Command("losetup", "-f", "--show", backingDisk).CombinedOutput()
    +	if err != nil {
    +		panic(err)
    +	}
    +	return strings.TrimSpace(string(out))
     }
     
    -func teardown(devicePath string) {
    -	if err := exec.Command("rm", "-f", devicePath).Run(); err != nil {
    +func teardown(backingImage, devicePath string) {
    +	if err := exec.Command("losetup", "-d", devicePath).Run(); err != nil {
    +		panic(err)
    +	}
    +	if err := exec.Command("rm", "-f", backingImage).Run(); err != nil {
     		panic(err)
     	}
     }
     
    -func cp(source, target string) error {
    -	return exec.Command("cp", source, target).Run()
    +func cp(source, target string) (string, error) {
    +	if err := exec.Command("cp", source, target).Run(); err != nil {
    +		return "", err
    +	}
    +	out, err := exec.Command("losetup", "-f", "--show", target).CombinedOutput()
    +	if err != nil {
    +		return "", err
    +	}
    +	return strings.TrimSpace(string(out)), nil
     }
     
     func resize(devicePath string) {
    @@ -100,8 +115,8 @@ func TestMain(m *testing.M) {
     func TestOpenAndClose(t *testing.T) {
     	assert := assert.New(t)
     	require := require.New(t)
    -	setup(devicePath)
    -	defer teardown(devicePath)
    +	devicePath := setup(defaultBackingImage)
    +	defer teardown(defaultBackingImage, devicePath)
     
     	mapper := cryptmapper.New(&fakeKMS{})
     
    @@ -124,7 +139,7 @@ func TestOpenAndClose(t *testing.T) {
     	assert.Equal(newPath, newPath2)
     
     	// Resize the device
    -	resize(devicePath)
    +	resize(defaultBackingImage)
     
     	resizedPath, err := mapper.ResizeCryptDevice(t.Context(), deviceName)
     	require.NoError(err)
    @@ -145,8 +160,8 @@ func TestOpenAndClose(t *testing.T) {
     func TestOpenAndCloseIntegrity(t *testing.T) {
     	assert := assert.New(t)
     	require := require.New(t)
    -	setup(devicePath)
    -	defer teardown(devicePath)
    +	devicePath := setup(defaultBackingImage)
    +	defer teardown(defaultBackingImage, devicePath)
     
     	mapper := cryptmapper.New(&fakeKMS{})
     
    @@ -167,7 +182,7 @@ func TestOpenAndCloseIntegrity(t *testing.T) {
     	assert.Equal(newPath, newPath2)
     
     	// integrity devices do not support resizing
    -	resize(devicePath)
    +	resize(defaultBackingImage)
     	_, err = mapper.ResizeCryptDevice(t.Context(), deviceName)
     	assert.Error(err)
     
    @@ -182,25 +197,26 @@ func TestOpenAndCloseIntegrity(t *testing.T) {
     
     	// check if we can reopen the device
     	_, err = mapper.OpenCryptDevice(t.Context(), devicePath, deviceName, true)
    -	assert.NoError(err)
    +	assert.NoError(err, "Failed to re-open crypt device")
     	assert.NoError(mapper.CloseCryptDevice(deviceName))
     }
     
     func TestDeviceCloning(t *testing.T) {
     	assert := assert.New(t)
     	require := require.New(t)
    -	setup(devicePath)
    -	defer teardown(devicePath)
    +	devicePath := setup(defaultBackingImage)
    +	defer teardown(defaultBackingImage, devicePath)
     
     	mapper := cryptmapper.New(&dynamicKMS{})
     
     	_, err := mapper.OpenCryptDevice(t.Context(), devicePath, deviceName, false)
     	assert.NoError(err)
     
    -	require.NoError(cp(devicePath, devicePath+"-copy"))
    -	defer teardown(devicePath + "-copy")
    +	cpDevice, err := cp(defaultBackingImage, defaultBackingImage+"-copy")
    +	require.NoError(err)
    +	defer teardown(defaultBackingImage+"-copy", cpDevice)
     
    -	_, err = mapper.OpenCryptDevice(t.Context(), devicePath+"-copy", deviceName+"-copy", false)
    +	_, err = mapper.OpenCryptDevice(t.Context(), cpDevice, deviceName+"-copy", false)
     	assert.NoError(err)
     
     	assert.NoError(mapper.CloseCryptDevice(deviceName))
    @@ -209,12 +225,12 @@ func TestDeviceCloning(t *testing.T) {
     
     func TestConcurrency(t *testing.T) {
     	assert := assert.New(t)
    -	setup(devicePath)
    -	defer teardown(devicePath)
    +	devicePath := setup(defaultBackingImage)
    +	defer teardown(defaultBackingImage, devicePath)
     
    -	device2 := devicePath + "-2"
    -	setup(device2)
    -	defer teardown(device2)
    +	backingImage2 := defaultBackingImage + "-2"
    +	device2 := setup(backingImage2)
    +	defer teardown(backingImage2, device2)
     
     	mapper := cryptmapper.New(&fakeKMS{})
     
    
  • disk-mapper/internal/test/BUILD.bazel+2 0 modified
    @@ -9,9 +9,11 @@ go_test(
         data = [
             "@coreutils//:bin/dd",
             "@coreutils//:bin/rm",
    +        "@util-linux//:bin/losetup",
         ],
         env = {
             "DD": "$(rlocationpath @coreutils//:bin/dd)",
    +        "LOSETUP": "$(rlocationpath @util-linux//:bin/losetup)",
             "RM": "$(rlocationpath @coreutils//:bin/rm)",
         },
         # keep
    
  • disk-mapper/internal/test/integration_test.go+39 4 modified
    @@ -10,6 +10,7 @@ package integration
     
     import (
     	"encoding/json"
    +	"errors"
     	"flag"
     	"fmt"
     	"log/slog"
    @@ -31,13 +32,15 @@ import (
     )
     
     const (
    -	devicePath   = "testDevice"
    +	backingDisk  = "testDevice"
     	mappedDevice = "mappedDevice"
     )
     
    +var devicePath string
    +
     var diskPath = flag.String("disk", "", "Path to the disk to use for the benchmark")
     
    -var toolsEnvs = []string{"DD", "RM"}
    +var toolsEnvs = []string{"DD", "RM", "LOSETUP"}
     
     // addToolsToPATH is used to update the PATH to contain necessary tool binaries for
     // coreutils.
    @@ -64,11 +67,22 @@ func addToolsToPATH() error {
     }
     
     func setup(sizeGB int) error {
    -	return exec.Command("dd", "if=/dev/random", fmt.Sprintf("of=%s", devicePath), "bs=1G", fmt.Sprintf("count=%d", sizeGB)).Run()
    +	if err := exec.Command("dd", "if=/dev/random", fmt.Sprintf("of=%s", backingDisk), "bs=1G", fmt.Sprintf("count=%d", sizeGB)).Run(); err != nil {
    +		return err
    +	}
    +	cmd := exec.Command("losetup", "-f", "--show", backingDisk)
    +	out, err := cmd.CombinedOutput()
    +	if err != nil {
    +		return fmt.Errorf("losetup failed: %w\nOutput: %s", err, out)
    +	}
    +	devicePath = strings.TrimSpace(string(out))
    +	return nil
     }
     
     func teardown() error {
    -	return exec.Command("rm", "-f", devicePath).Run()
    +	err := exec.Command("losetup", "-d", devicePath).Run()
    +	errors.Join(err, exec.Command("rm", "-f", backingDisk).Run())
    +	return err
     }
     
     func TestMain(m *testing.M) {
    @@ -137,6 +151,27 @@ func TestMapper(t *testing.T) {
     	// Disk should still be marked as not initialized because token is set to false.
     	assert.False(mapper.IsInitialized())
     
    +	// Set disk as initialized
    +	assert.NoError(ccrypt.SetConstellationStateDiskToken(ccryptsetup.SetDiskInitialized))
    +
    +	// Set up a new client and check if the client still sees the disk as initialized
    +	ccrypt2 := ccryptsetup.New()
    +	freeDevice2, err := ccrypt2.Init(devicePath)
    +	require.NoError(err, "failed to initialize crypt device")
    +	defer freeDevice2()
    +	require.NoError(ccrypt2.LoadLUKS2(), "failed to load LUKS2")
    +
    +	tokenJSON, err = ccrypt2.TokenJSONGet(ccryptsetup.ConstellationStateDiskTokenID)
    +	require.NoError(err, "token should have been set")
    +	var token2 struct {
    +		Type              string   `json:"type"`
    +		Keyslots          []string `json:"keyslots"`
    +		DiskIsInitialized bool     `json:"diskIsInitialized"`
    +	}
    +	require.NoError(json.Unmarshal([]byte(tokenJSON), &token2))
    +	assert.True(token2.DiskIsInitialized, "disk should be marked as initialized")
    +	assert.True(ccrypt2.ConstellationStateDiskTokenIsInitialized(), "disk should be marked as initialized")
    +
     	// Try to map disk with incorrect passphrase
     	assert.Error(mapper.MapDisk(mappedDevice, "invalid-passphrase"), "was able to map disk with incorrect passphrase")
     
    
  • go.mod+1 2 modified
    @@ -2,8 +2,7 @@ module github.com/edgelesssys/constellation/v2
     
     go 1.24.6
     
    -// TODO(daniel-weisse): revert after merging https://github.com/martinjungblut/go-cryptsetup/pull/16.
    -replace github.com/martinjungblut/go-cryptsetup => github.com/daniel-weisse/go-cryptsetup v0.0.0-20230705150314-d8c07bd1723c
    +replace github.com/martinjungblut/go-cryptsetup => github.com/edgelesssys/go-cryptsetup v0.0.0-20250822075033-840d240dddf8
     
     // TODO(daniel-weisse): revert after merging https://github.com/google/go-sev-guest/pull/173.
     replace github.com/google/go-sev-guest => github.com/daniel-weisse/go-sev-guest v0.0.0-20250728114912-0c2ba277c52b
    
  • go.sum+2 2 modified
    @@ -237,8 +237,6 @@ github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7 h
     github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw=
     github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
     github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
    -github.com/daniel-weisse/go-cryptsetup v0.0.0-20230705150314-d8c07bd1723c h1:ToajP6trZoiqlZ3Z4uoG1P02/wtqSw1AcowOXOYjATk=
    -github.com/daniel-weisse/go-cryptsetup v0.0.0-20230705150314-d8c07bd1723c/go.mod h1:gZoZ0+POlM1ge/VUxWpMmZVNPzzMJ7l436CgkQ5+qzU=
     github.com/daniel-weisse/go-sev-guest v0.0.0-20250728114912-0c2ba277c52b h1:pElX9BS0PnYZS/tznradDYbo82kvG2yisWGvZGsDnVs=
     github.com/daniel-weisse/go-sev-guest v0.0.0-20250728114912-0c2ba277c52b/go.mod h1:SK9vW+uyfuzYdVN0m8BShL3OQCtXZe/JPF7ZkpD3760=
     github.com/danieljoos/wincred v1.2.1 h1:dl9cBrupW8+r5250DYkYxocLeZ1Y4vB1kxgtjxw8GQs=
    @@ -271,6 +269,8 @@ github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU
     github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
     github.com/edgelesssys/go-azguestattestation v0.0.0-20250408071817-8c4457b235ff h1:V6A5kD0+c1Qg4X72Lg+zxhCZk+par436sQdgLvMCBBc=
     github.com/edgelesssys/go-azguestattestation v0.0.0-20250408071817-8c4457b235ff/go.mod h1:Lz4QaomI4wU2YbatD4/W7vatW2Q35tnkoJezB1clscc=
    +github.com/edgelesssys/go-cryptsetup v0.0.0-20250822075033-840d240dddf8 h1:aZsuG/e0UNZSttE63TplTeTpYjpl8A2GXbNQYMRUktw=
    +github.com/edgelesssys/go-cryptsetup v0.0.0-20250822075033-840d240dddf8/go.mod h1:gZoZ0+POlM1ge/VUxWpMmZVNPzzMJ7l436CgkQ5+qzU=
     github.com/edgelesssys/go-tdx-qpl v0.0.0-20250129202750-607ac61e2377 h1:5JMJiBhvOUUR7EZ0UyeSy7a1WrqB2eM+DX3odLSHAh4=
     github.com/edgelesssys/go-tdx-qpl v0.0.0-20250129202750-607ac61e2377/go.mod h1:IC72qyykUIWl0ZmSk53L4xbLCFDBEGZVaujUmPQOEyw=
     github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
    
  • internal/cryptsetup/BUILD.bazel+4 0 modified
    @@ -16,10 +16,14 @@ go_library(
         visibility = ["//:__subpackages__"],
         deps = select({
             "@io_bazel_rules_go//go/platform:android": [
    +            "@com_github_google_uuid//:uuid",
                 "@com_github_martinjungblut_go_cryptsetup//:go-cryptsetup",
    +            "@org_golang_x_sys//unix",
             ],
             "@io_bazel_rules_go//go/platform:linux": [
    +            "@com_github_google_uuid//:uuid",
                 "@com_github_martinjungblut_go_cryptsetup//:go-cryptsetup",
    +            "@org_golang_x_sys//unix",
             ],
             "//conditions:default": [],
         }),
    
  • internal/cryptsetup/cryptsetup_cgo.go+351 4 modified
    @@ -11,9 +11,16 @@ package cryptsetup
     import "C"
     
     import (
    +	"encoding/json"
     	"errors"
    +	"fmt"
    +	"os"
    +	"path/filepath"
    +	"strings"
     
    +	"github.com/google/uuid"
     	"github.com/martinjungblut/go-cryptsetup"
    +	"golang.org/x/sys/unix"
     )
     
     const (
    @@ -56,12 +63,103 @@ func format(device cryptDevice, integrity bool) error {
     	}
     }
     
    -func initByDevicePath(devicePath string) (cryptDevice, error) {
    -	return cryptsetup.Init(devicePath)
    +// headerRestore restores the header of the given device from the header in the given file.
    +// Reloading the device is required for the changes to be reflected in the active [cryptDevice] struct.
    +func headerRestore(device cryptDevice, headerFile string) error {
    +	switch d := device.(type) {
    +	case cgoRestorer:
    +		return d.HeaderRestore(cryptsetup.LUKS2{}, headerFile)
    +	default:
    +		return errInvalidType
    +	}
     }
     
    -func initByName(name string) (cryptDevice, error) {
    -	return cryptsetup.InitByName(name)
    +// headerBackup creates a backup of the cryptDevice's header to the given file.
    +func headerBackup(device cryptDevice, headerFile string) error {
    +	switch d := device.(type) {
    +	case cgoBackuper:
    +		if err := os.Remove(headerFile); err != nil && !errors.Is(err, os.ErrNotExist) {
    +			return fmt.Errorf("removing existing header file %q: %w", headerFile, err)
    +		}
    +		if err := d.HeaderBackup(cryptsetup.LUKS2{}, headerFile); err != nil {
    +			return fmt.Errorf("creating header backup: %w", err)
    +		}
    +		return nil
    +	default:
    +		return errInvalidType
    +	}
    +}
    +
    +func initByDevicePath(devicePath string) (deviceDetachedHeader, deviceAttachedHeader cryptDevice, headerDevice string, headerFile string, err error) {
    +	tmpDevice, err := cryptsetup.Init(devicePath)
    +	if err != nil {
    +		return nil, nil, "", "", fmt.Errorf("init device by path %s: %w", devicePath, err)
    +	}
    +	// If the device is not LUKS2 formatted, this is treated as a new device,
    +	// meaning no header exists yet
    +	if err := tmpDevice.Load(cryptsetup.LUKS2{}); err != nil {
    +		return nil, tmpDevice, "", "", nil
    +	}
    +	defer tmpDevice.Free()
    +
    +	deviceAttachedHeader, err = cryptsetup.Init(devicePath)
    +	if err != nil {
    +		return nil, nil, "", "", fmt.Errorf("init device by path %s: %w", devicePath, err)
    +	}
    +	defer func() {
    +		if err != nil && deviceAttachedHeader != nil {
    +			deviceAttachedHeader.Free()
    +		}
    +	}()
    +
    +	headerDevice, headerFile, err = detachHeader(tmpDevice)
    +	if err != nil {
    +		return nil, nil, "", "", err
    +	}
    +	defer func() {
    +		if err != nil {
    +			_ = detachLoopbackDevice(headerDevice)
    +		}
    +	}()
    +
    +	cryptDevice, err := cryptsetup.InitDataDevice(headerDevice, devicePath)
    +	return cryptDevice, deviceAttachedHeader, headerDevice, headerFile, err
    +}
    +
    +func initByName(name string) (deviceDetachedHeader, deviceAttachedHeader cryptDevice, headerDevice string, headerFile string, err error) {
    +	tmpDevice, err := cryptsetup.InitByName(name)
    +	if err != nil {
    +		return nil, nil, "", "", fmt.Errorf("init device by name %s: %w", name, err)
    +	}
    +	// If the device is not LUKS2 formatted, this is treated as a new device,
    +	// meaning no header exists yet
    +	if err := tmpDevice.Load(cryptsetup.LUKS2{}); err != nil {
    +		return nil, tmpDevice, "", "", nil
    +	}
    +	defer tmpDevice.Free()
    +
    +	deviceAttachedHeader, err = cryptsetup.InitByName(name)
    +	if err != nil {
    +		return nil, nil, "", "", fmt.Errorf("init device by name %s: %w", name, err)
    +	}
    +	defer func() {
    +		if err != nil && deviceAttachedHeader != nil {
    +			deviceAttachedHeader.Free()
    +		}
    +	}()
    +
    +	headerDevice, headerFile, err = detachHeader(tmpDevice)
    +	if err != nil {
    +		return nil, nil, "", "", err
    +	}
    +	defer func() {
    +		if err != nil {
    +			_ = detachLoopbackDevice(headerDevice)
    +		}
    +	}()
    +
    +	cryptDevice, err := cryptsetup.InitByNameAndHeader(name, headerDevice)
    +	return cryptDevice, deviceAttachedHeader, headerDevice, headerFile, err
     }
     
     func loadLUKS2(device cryptDevice) error {
    @@ -73,10 +171,259 @@ func loadLUKS2(device cryptDevice) error {
     	}
     }
     
    +// detachHeader loads reads the header from the given cryptsetup device and returns a loopback device with just the header.
    +func detachHeader(device *cryptsetup.Device) (headerDevice, headerFile string, err error) {
    +	headerFile = filepath.Join(os.TempDir(), fmt.Sprintf("luks-header-%s", uuid.New().String()))
    +	if err = headerBackup(device, headerFile); err != nil {
    +		return "", "", err
    +	}
    +
    +	headerDevice, err = createLoopbackDevice(headerFile)
    +	if err != nil {
    +		return "", "", fmt.Errorf("create loopback device: %w", err)
    +	}
    +	defer func() {
    +		if err != nil {
    +			_ = detachLoopbackDevice(headerDevice)
    +		}
    +	}()
    +
    +	headerCryptDevice, err := cryptsetup.Init(headerDevice)
    +	if err != nil {
    +		return "", "", fmt.Errorf("init header device: %w", err)
    +	}
    +	defer headerCryptDevice.Free()
    +	if err := headerCryptDevice.Load(cryptsetup.LUKS2{}); err != nil {
    +		return "", "", fmt.Errorf("creating header backup: %w", err)
    +	}
    +	metadataJSON, err := headerCryptDevice.DumpJSON()
    +	if err != nil {
    +		return "", "", fmt.Errorf("dumping device metadata: %w", err)
    +	}
    +
    +	var metadata cryptsetupMetadata
    +	decoder := json.NewDecoder(strings.NewReader(metadataJSON))
    +	decoder.DisallowUnknownFields() // Ensure no unknown fields are present in the JSON data
    +	if err := decoder.Decode(&metadata); err != nil {
    +		return "", "", fmt.Errorf("decoding LUKS header JSON from %s: %w", headerFile, err)
    +	}
    +
    +	if err := verifyLUKS2Header(metadata); err != nil {
    +		return "", "", fmt.Errorf("verifying LUKS2 header: %w", err)
    +	}
    +
    +	return headerDevice, headerFile, nil
    +}
    +
    +// verifyLUKS2Header verifies a LUKS2 header contains the expected configuration for Constellation.
    +func verifyLUKS2Header(metadata cryptsetupMetadata) error {
    +	if len(metadata.KeySlots) == 0 {
    +		return errors.New("no key slots found in LUKS2 header")
    +	}
    +	for slotName, slot := range metadata.KeySlots {
    +		if slot.Type != "luks2" {
    +			return fmt.Errorf("unsupported key slot type %q for slot %q", slot.Type, slotName)
    +		}
    +		if slot.KeySize != 64 && slot.KeySize != 96 { // 64 for encryption, 96 if integrity is added
    +			return fmt.Errorf("unsupported key size %d for slot %q", slot.KeySize, slotName)
    +		}
    +		if slot.AntiForensicSplitter.Type != "luks1" {
    +			return fmt.Errorf("unsupported anti-forensic splitter type %q for slot %q", slot.AntiForensicSplitter.Type, slotName)
    +		}
    +		if slot.AntiForensicSplitter.Stripes != 4000 {
    +			return fmt.Errorf("unsupported anti-forensic splitter stripes %d for slot %q", slot.AntiForensicSplitter.Stripes, slotName)
    +		}
    +		if slot.AntiForensicSplitter.Hash != "sha256" {
    +			return fmt.Errorf("unsupported anti-forensic splitter hash %q for slot %q", slot.AntiForensicSplitter.Hash, slotName)
    +		}
    +		if slot.Area.Type != "raw" {
    +			return fmt.Errorf("unsupported area type %q for slot %q", slot.Area.Type, slotName)
    +		}
    +		if slot.Area.Encryption != "aes-xts-plain64" {
    +			return fmt.Errorf("unsupported area encryption %q for slot %q", slot.Area.Encryption, slotName)
    +		}
    +		if slot.Area.KeySize != 64 {
    +			return fmt.Errorf("unsupported area key size %d for slot %q", slot.Area.KeySize, slotName)
    +		}
    +		if slot.KDF.Type != "argon2id" {
    +			return fmt.Errorf("unsupported KDF type %q for slot %q", slot.KDF.Type, slotName)
    +		}
    +		if slot.KDF.Memory == 0 {
    +			return fmt.Errorf("unsupported KDF memory %d for slot %q", slot.KDF.Memory, slotName)
    +		}
    +		if slot.KDF.Salt == "" {
    +			return fmt.Errorf("unsupported KDF salt for slot %q", slotName)
    +		}
    +	}
    +	if len(metadata.Segments) == 0 {
    +		return errors.New("no segments found in LUKS2 header")
    +	}
    +	for segmentName, segment := range metadata.Segments {
    +		if segment.Type != "crypt" {
    +			return fmt.Errorf("unsupported segment type %q for segment %q", segment.Type, segmentName)
    +		}
    +		if segment.SectorSize != 4096 {
    +			return fmt.Errorf("unsupported segment sector size %d for segment %q", segment.SectorSize, segmentName)
    +		}
    +		if segment.IVTweak != "0" {
    +			return fmt.Errorf("unsupported segment IV tweak %q for segment %q", segment.IVTweak, segmentName)
    +		}
    +		if segment.Encryption != "aes-xts-plain64" {
    +			return fmt.Errorf("unsupported segment encryption %q for segment %q", segment.Encryption, segmentName)
    +		}
    +		switch segment.Integrity.Type {
    +		case "hmac(sha256)":
    +			if segment.Integrity.JournalEncryption != "none" {
    +				return fmt.Errorf("unsupported segment integrity journal encryption %q for segment %q", segment.Integrity.JournalEncryption, segmentName)
    +			}
    +			if segment.Integrity.JournalIntegrity != "none" {
    +				return fmt.Errorf("unsupported segment integrity journal integrity %q for segment %q", segment.Integrity.JournalIntegrity, segmentName)
    +			}
    +		case "":
    +			if segment.Integrity.JournalEncryption != "" {
    +				return fmt.Errorf("unsupported segment integrity journal encryption %q for segment %q", segment.Integrity.JournalEncryption, segmentName)
    +			}
    +			if segment.Integrity.JournalIntegrity != "" {
    +				return fmt.Errorf("unsupported segment integrity journal integrity %q for segment %q", segment.Integrity.JournalIntegrity, segmentName)
    +			}
    +		default:
    +			return fmt.Errorf("unsupported segment integrity type %q for segment %q", segment.Integrity.Type, segmentName)
    +		}
    +	}
    +	if len(metadata.Digests) == 0 {
    +		return errors.New("no digests found in LUKS2 header")
    +	}
    +	for digestName, digest := range metadata.Digests {
    +		if digest.Type != "pbkdf2" {
    +			return fmt.Errorf("unsupported digest type %q for digest %q", digest.Type, digestName)
    +		}
    +		if digest.Hash != "sha256" {
    +			return fmt.Errorf("unsupported digest hash %q for digest %q", digest.Hash, digestName)
    +		}
    +		if digest.Salt == "" {
    +			return fmt.Errorf("unsupported digest salt for digest %q", digestName)
    +		}
    +		if digest.Digest == "" {
    +			return fmt.Errorf("unsupported digest value for digest %q", digestName)
    +		}
    +	}
    +	return nil
    +}
    +
    +// createLoopbackDevice sets up a loop device for the given file and returns the loop device path (e.g., /dev/loop0).
    +func createLoopbackDevice(filePath string) (string, error) {
    +	file, err := os.OpenFile(filePath, os.O_RDWR, 0)
    +	if err != nil {
    +		return "", fmt.Errorf("open backing file: %w", err)
    +	}
    +	defer file.Close()
    +
    +	// Get a free loop device number
    +	ctrl, err := os.OpenFile("/dev/loop-control", os.O_RDWR, 0)
    +	if err != nil {
    +		return "", fmt.Errorf("open /dev/loop-control: %w", err)
    +	}
    +	defer ctrl.Close()
    +	loopNum, _, errno := unix.Syscall(unix.SYS_IOCTL, ctrl.Fd(), unix.LOOP_CTL_GET_FREE, 0)
    +	if errno != 0 {
    +		return "", fmt.Errorf("LOOP_CTL_GET_FREE: %v", errno)
    +	}
    +
    +	// Open the loop device
    +	loopDev := fmt.Sprintf("/dev/loop%d", loopNum)
    +	loop, err := os.OpenFile(loopDev, os.O_RDWR, 0)
    +	if err != nil {
    +		return "", fmt.Errorf("open loop device: %w", err)
    +	}
    +	defer loop.Close()
    +
    +	// Associate the file with the loop device
    +	if _, _, errno := unix.Syscall(unix.SYS_IOCTL, loop.Fd(), unix.LOOP_SET_FD, file.Fd()); errno != 0 {
    +		return "", fmt.Errorf("LOOP_SET_FD: %v", errno)
    +	}
    +
    +	return loopDev, nil
    +}
    +
    +// detachLoopbackDevice removes the specified loopback device.
    +func detachLoopbackDevice(loopDev string) error {
    +	loop, err := os.OpenFile(loopDev, os.O_RDWR, 0)
    +	if err != nil {
    +		return fmt.Errorf("open loop device: %w", err)
    +	}
    +	defer loop.Close()
    +
    +	if _, _, errno := unix.Syscall(unix.SYS_IOCTL, loop.Fd(), unix.LOOP_CLR_FD, 0); errno != 0 {
    +		return fmt.Errorf("LOOP_CLR_FD: %v", errno)
    +	}
    +	return nil
    +}
    +
    +type cryptsetupMetadata struct {
    +	KeySlots map[string]struct {
    +		Type                 string `json:"type"`
    +		KeySize              int    `json:"key_size"`
    +		AntiForensicSplitter struct {
    +			Type    string `json:"type"`
    +			Stripes int    `json:"stripes"`
    +			Hash    string `json:"hash"`
    +		} `json:"af"`
    +		Area struct {
    +			Type       string `json:"type"`
    +			Offset     string `json:"offset"`
    +			Size       string `json:"size"`
    +			Encryption string `json:"encryption"`
    +			KeySize    int    `json:"key_size"`
    +		} `json:"area"`
    +		KDF struct {
    +			Type   string `json:"type"`
    +			Time   int    `json:"time"`
    +			Memory int    `json:"memory"`
    +			CPUs   int    `json:"cpus"`
    +			Salt   string `json:"salt"`
    +		} `json:"kdf"`
    +	} `json:"keyslots"`
    +	Tokens   map[string]any `json:"tokens"`
    +	Segments map[string]struct {
    +		Type       string   `json:"type"`
    +		Offset     string   `json:"offset"`
    +		Size       string   `json:"size"`
    +		Flags      []string `json:"flags,omitempty"`
    +		IVTweak    string   `json:"iv_tweak"`
    +		Encryption string   `json:"encryption"`
    +		SectorSize int      `json:"sector_size"`
    +		Integrity  struct {
    +			Type              string `json:"type"`
    +			JournalEncryption string `json:"journal_encryption"`
    +			JournalIntegrity  string `json:"journal_integrity"`
    +		}
    +	} `json:"segments"`
    +	Digests map[string]struct {
    +		Type       string   `json:"type"`
    +		Keyslots   []string `json:"keyslots"`
    +		Segments   []string `json:"segments"`
    +		Hash       string   `json:"hash"`
    +		Iterations int      `json:"iterations"`
    +		Salt       string   `json:"salt"`
    +		Digest     string   `json:"digest"`
    +	} `json:"digests"`
    +	Config struct {
    +		JSONSize     string `json:"json_size"`
    +		KeyslotsSize string `json:"keyslots_size"`
    +	}
    +}
    +
     type cgoFormatter interface {
     	Format(deviceType cryptsetup.DeviceType, genericParams cryptsetup.GenericParams) error
     }
     
     type cgoLoader interface {
     	Load(deviceType cryptsetup.DeviceType) error
     }
    +
    +type cgoRestorer interface {
    +	HeaderRestore(deviceType cryptsetup.DeviceType, headerFile string) error
    +}
    +type cgoBackuper interface {
    +	HeaderBackup(deviceType cryptsetup.DeviceType, headerFile string) error
    +}
    
  • internal/cryptsetup/cryptsetup_cross.go+16 4 modified
    @@ -26,14 +26,26 @@ func format(_ cryptDevice, _ bool) error {
     	return errCGONotSupported
     }
     
    -func initByDevicePath(_ string) (cryptDevice, error) {
    -	return nil, errCGONotSupported
    +func headerRestore(_ cryptDevice, _ string) error {
    +	return errCGONotSupported
     }
     
    -func initByName(_ string) (cryptDevice, error) {
    -	return nil, errCGONotSupported
    +func headerBackup(_ cryptDevice, _ string) error {
    +	return errCGONotSupported
    +}
    +
    +func initByDevicePath(_ string) (cryptDevice, cryptDevice, string, string, error) {
    +	return nil, nil, "", "", errCGONotSupported
    +}
    +
    +func initByName(_ string) (cryptDevice, cryptDevice, string, string, error) {
    +	return nil, nil, "", "", errCGONotSupported
     }
     
     func loadLUKS2(_ cryptDevice) error {
     	return errCGONotSupported
     }
    +
    +func detachLoopbackDevice(_ string) error {
    +	return errCGONotSupported
    +}
    
  • internal/cryptsetup/cryptsetup.go+223 58 modified
    @@ -17,6 +17,7 @@ import (
     	"encoding/json"
     	"errors"
     	"fmt"
    +	"reflect"
     	"strings"
     	"sync"
     	"time"
    @@ -50,9 +51,18 @@ var (
     
     // CryptSetup manages encrypted devices.
     type CryptSetup struct {
    -	nameInit func(name string) (cryptDevice, error)
    -	pathInit func(path string) (cryptDevice, error)
    -	device   cryptDevice
    +	nameInit func(name string) (deviceDetachedHeader, deviceAttachedHeader cryptDevice, headerDevice string, headerFile string, err error)
    +	pathInit func(path string) (deviceDetachedHeader, deviceAttachedHeader cryptDevice, headerDevice string, headerFile string, err error)
    +	// deviceWithDetachedHeader is the cryptsetup device with detached header we are working on.
    +	deviceWithDetachedHeader cryptDevice
    +	// deviceWithAttachedHeader is a cryptsetup device loaded without a separate, detached header.
    +	// If this is not a fresh disk, this device is purely used to write back changes that affect the header to the original disk.
    +	deviceWithAttachedHeader cryptDevice
    +	// headerDevice is the name of the loopback device containing the detached cryptsetup header.
    +	headerDevice string
    +	// headerFile is the path to the file containing the detached cryptsetup header.
    +	// The file is mounted as a loopback device on "headerDevice".
    +	headerFile string
     }
     
     // New creates a new CryptSetup.
    @@ -68,50 +78,55 @@ func New() *CryptSetup {
     func (c *CryptSetup) Init(devicePath string) (free func(), err error) {
     	packageLock.Lock()
     	defer packageLock.Unlock()
    -	if c.device != nil {
    +	if c.hasDetachedHeaderDevice() || c.hasAttachedHeaderDevice() {
     		return nil, errDeviceAlreadyOpen
     	}
    -	device, err := c.pathInit(devicePath)
    +	deviceDetachedHeader, deviceAttachedHeader, headerDevice, headerFile, err := c.pathInit(devicePath)
     	if err != nil {
     		return nil, fmt.Errorf("init cryptsetup by device path %q: %w", devicePath, err)
     	}
    -	c.device = device
    +	c.deviceWithDetachedHeader = deviceDetachedHeader
    +	c.deviceWithAttachedHeader = deviceAttachedHeader
    +	c.headerDevice = headerDevice
    +	c.headerFile = headerFile
     	return c.Free, nil
     }
     
     // InitByName opens an active crypt device using its mapped name.
     func (c *CryptSetup) InitByName(name string) (free func(), err error) {
     	packageLock.Lock()
     	defer packageLock.Unlock()
    -	if c.device != nil {
    +	if c.hasDetachedHeaderDevice() || c.hasAttachedHeaderDevice() {
     		return nil, errDeviceAlreadyOpen
     	}
    -	device, err := c.nameInit(name)
    +	deviceDetachedHeader, deviceAttachedHeader, headerDevice, headerFile, err := c.nameInit(name)
     	if err != nil {
     		return nil, fmt.Errorf("init cryptsetup by name %q: %w", name, err)
     	}
    -	c.device = device
    +	c.deviceWithDetachedHeader = deviceDetachedHeader
    +	c.deviceWithAttachedHeader = deviceAttachedHeader
    +	c.headerDevice = headerDevice
    +	c.headerFile = headerFile
     	return c.Free, nil
     }
     
     // Free frees resources from a previously opened crypt device.
     func (c *CryptSetup) Free() {
     	packageLock.Lock()
     	defer packageLock.Unlock()
    -	if c.device != nil {
    -		c.device.Free()
    -		c.device = nil
    -	}
    +	c.free()
     }
     
     // ActivateByPassphrase actives a crypt device using a passphrase.
     func (c *CryptSetup) ActivateByPassphrase(deviceName string, keyslot int, passphrase string, flags int) error {
     	packageLock.Lock()
     	defer packageLock.Unlock()
    -	if c.device == nil {
    -		return errDeviceNotOpen
    +	if !c.hasDetachedHeaderDevice() {
    +		if err := c.reload(); err != nil {
    +			return fmt.Errorf("re-loading crypt device for activation: %w", err)
    +		}
     	}
    -	if err := c.device.ActivateByPassphrase(deviceName, keyslot, passphrase, flags); err != nil {
    +	if err := c.deviceWithDetachedHeader.ActivateByPassphrase(deviceName, keyslot, passphrase, flags); err != nil {
     		return fmt.Errorf("activating crypt device %q using passphrase: %w", deviceName, err)
     	}
     	return nil
    @@ -122,10 +137,12 @@ func (c *CryptSetup) ActivateByPassphrase(deviceName string, keyslot int, passph
     func (c *CryptSetup) ActivateByVolumeKey(deviceName, volumeKey string, volumeKeySize, flags int) error {
     	packageLock.Lock()
     	defer packageLock.Unlock()
    -	if c.device == nil {
    -		return errDeviceNotOpen
    +	if !c.hasDetachedHeaderDevice() {
    +		if err := c.reload(); err != nil {
    +			return fmt.Errorf("re-loading crypt device for activation: %w", err)
    +		}
     	}
    -	if err := c.device.ActivateByVolumeKey(deviceName, volumeKey, volumeKeySize, flags); err != nil {
    +	if err := c.deviceWithDetachedHeader.ActivateByVolumeKey(deviceName, volumeKey, volumeKeySize, flags); err != nil {
     		return fmt.Errorf("activating crypt device %q using volume key: %w", deviceName, err)
     	}
     	return nil
    @@ -135,10 +152,10 @@ func (c *CryptSetup) ActivateByVolumeKey(deviceName, volumeKey string, volumeKey
     func (c *CryptSetup) Deactivate(deviceName string) error {
     	packageLock.Lock()
     	defer packageLock.Unlock()
    -	if c.device == nil {
    +	if !c.hasDetachedHeaderDevice() {
     		return errDeviceNotOpen
     	}
    -	if err := c.device.Deactivate(deviceName); err != nil {
    +	if err := c.deviceWithDetachedHeader.Deactivate(deviceName); err != nil {
     		return fmt.Errorf("deactivating crypt device %q: %w", deviceName, err)
     	}
     	return nil
    @@ -149,31 +166,56 @@ func (c *CryptSetup) Deactivate(deviceName string) error {
     func (c *CryptSetup) Format(integrity bool) error {
     	packageLock.Lock()
     	defer packageLock.Unlock()
    -	if c.device == nil {
    +	var device cryptDevice
    +
    +	// If we are re-formatting an existing device, we start from scratch without a detached header
    +	if c.hasAttachedHeaderDevice() {
    +		if c.deviceWithDetachedHeader != nil {
    +			c.deviceWithDetachedHeader.Free()
    +			c.deviceWithDetachedHeader = nil
    +		}
    +		if c.headerDevice != "" {
    +			_ = detachLoopbackDevice(c.headerDevice)
    +			c.headerDevice = ""
    +		}
    +		c.headerFile = ""
    +		device = c.deviceWithAttachedHeader
    +	} else {
     		return errDeviceNotOpen
     	}
    -	if err := format(c.device, integrity); err != nil {
    -		return fmt.Errorf("formatting crypt device %q: %w", c.device.GetDeviceName(), err)
    +
    +	if err := format(device, integrity); err != nil {
    +		return fmt.Errorf("formatting crypt device %q: %w", device.GetDeviceName(), err)
    +	}
    +	if err := c.createHeaderBackup(); err != nil {
    +		return err
     	}
     	return nil
     }
     
     // GetDeviceName gets the path to the underlying device.
     func (c *CryptSetup) GetDeviceName() string {
    -	return c.device.GetDeviceName()
    +	packageLock.Lock()
    +	defer packageLock.Unlock()
    +	device, err := c.getActiveDevice()
    +	if err != nil {
    +		return ""
    +	}
    +	return device.GetDeviceName()
     }
     
     // GetUUID gets the device's LUKS2 UUID.
     // The UUID is returned in lowercase.
     func (c *CryptSetup) GetUUID() (string, error) {
     	packageLock.Lock()
     	defer packageLock.Unlock()
    -	if c.device == nil {
    -		return "", errDeviceNotOpen
    +	device, err := c.getActiveDevice()
    +	if err != nil {
    +		return "", err
     	}
    -	uuid := c.device.GetUUID()
    +	uuid := device.GetUUID()
     	if uuid == "" {
    -		return "", fmt.Errorf("unable to get UUID for device %q", c.device.GetDeviceName())
    +		return "", fmt.Errorf("unable to get UUID for device %q", device.GetDeviceName())
     	}
     	return strings.ToLower(uuid), nil
     }
    @@ -183,11 +225,15 @@ func (c *CryptSetup) GetUUID() (string, error) {
     func (c *CryptSetup) KeyslotAddByVolumeKey(keyslot int, volumeKey string, passphrase string) error {
     	packageLock.Lock()
     	defer packageLock.Unlock()
    -	if c.device == nil {
    -		return errDeviceNotOpen
    +	device, err := c.getActiveDevice()
    +	if err != nil {
    +		return err
    +	}
    +	if err := device.KeyslotAddByVolumeKey(keyslot, volumeKey, passphrase); err != nil {
    +		return fmt.Errorf("adding keyslot to device %q: %w", device.GetDeviceName(), err)
     	}
    -	if err := c.device.KeyslotAddByVolumeKey(keyslot, volumeKey, passphrase); err != nil {
    -		return fmt.Errorf("adding keyslot to device %q: %w", c.device.GetDeviceName(), err)
    +	if err := c.createHeaderBackup(); err != nil {
    +		return err
     	}
     	return nil
     }
    @@ -196,21 +242,30 @@ func (c *CryptSetup) KeyslotAddByVolumeKey(keyslot int, volumeKey string, passph
     func (c *CryptSetup) KeyslotChangeByPassphrase(currentKeyslot, newKeyslot int, currentPassphrase, newPassphrase string) error {
     	packageLock.Lock()
     	defer packageLock.Unlock()
    -	if c.device == nil {
    -		return errDeviceNotOpen
    +	device, err := c.getActiveDevice()
    +	if err != nil {
    +		return err
    +	}
    +	if err := device.KeyslotChangeByPassphrase(currentKeyslot, newKeyslot, currentPassphrase, newPassphrase); err != nil {
    +		return fmt.Errorf("updating passphrase for device %q: %w", device.GetDeviceName(), err)
     	}
    -	if err := c.device.KeyslotChangeByPassphrase(currentKeyslot, newKeyslot, currentPassphrase, newPassphrase); err != nil {
    -		return fmt.Errorf("updating passphrase for device %q: %w", c.device.GetDeviceName(), err)
    +	if err := c.createHeaderBackup(); err != nil {
    +		return err
     	}
     	return nil
     }
     
     // LoadLUKS2 loads the device as LUKS2 crypt device.
     func (c *CryptSetup) LoadLUKS2() error {
    -	if err := loadLUKS2(c.device); err != nil {
    -		return fmt.Errorf("loading LUKS2 crypt device %q: %w", c.device.GetDeviceName(), err)
    +	packageLock.Lock()
    +	defer packageLock.Unlock()
    +	if c.hasDetachedHeaderDevice() {
    +		if err := loadLUKS2(c.deviceWithDetachedHeader); err != nil {
    +			return fmt.Errorf("loading LUKS2 crypt device %q: %w", c.deviceWithDetachedHeader.GetDeviceName(), err)
    +		}
    +		return nil
     	}
    -	return nil
    +	return errors.New("cannot load LUKS2 on device with attached header")
     }
     
     // Resize resizes a device to the given size.
    @@ -219,11 +274,15 @@ func (c *CryptSetup) LoadLUKS2() error {
     func (c *CryptSetup) Resize(name string, newSize uint64) error {
     	packageLock.Lock()
     	defer packageLock.Unlock()
    -	if c.device == nil {
    -		return errDeviceNotOpen
    +	device, err := c.getActiveDevice()
    +	if err != nil {
    +		return err
    +	}
    +	if err := device.Resize(name, newSize); err != nil {
    +		return fmt.Errorf("resizing crypt device %q: %w", device.GetDeviceName(), err)
     	}
    -	if err := c.device.Resize(name, newSize); err != nil {
    -		return fmt.Errorf("resizing crypt device %q: %w", c.device.GetDeviceName(), err)
    +	if err := c.createHeaderBackup(); err != nil {
    +		return err
     	}
     	return nil
     }
    @@ -232,10 +291,11 @@ func (c *CryptSetup) Resize(name string, newSize uint64) error {
     func (c *CryptSetup) TokenJSONGet(token int) (string, error) {
     	packageLock.Lock()
     	defer packageLock.Unlock()
    -	if c.device == nil {
    -		return "", errDeviceNotOpen
    +	device, err := c.getActiveDevice()
    +	if err != nil {
    +		return "", err
     	}
    -	json, err := c.device.TokenJSONGet(token)
    +	json, err := device.TokenJSONGet(token)
     	if err != nil {
     		return "", fmt.Errorf("getting JSON data for token %d: %w", token, err)
     	}
    @@ -252,18 +312,25 @@ func (c *CryptSetup) TokenJSONGet(token int) (string, error) {
     func (c *CryptSetup) TokenJSONSet(token int, json string) (int, error) {
     	packageLock.Lock()
     	defer packageLock.Unlock()
    -	if c.device == nil {
    -		return -1, errDeviceNotOpen
    +	device, err := c.getActiveDevice()
    +	if err != nil {
    +		return -1, err
     	}
    -	tokenID, err := c.device.TokenJSONSet(token, json)
    +
    +	tokenID, err := device.TokenJSONSet(token, json)
     	if err != nil {
     		return -1, fmt.Errorf("setting JSON data for token %d: %w", token, err)
     	}
    +	if err := c.createHeaderBackup(); err != nil {
    +		return -1, err
    +	}
     	return tokenID, nil
     }
     
     // SetConstellationStateDiskToken sets the Constellation state disk token.
     func (c *CryptSetup) SetConstellationStateDiskToken(diskIsInitialized bool) error {
    +	packageLock.Lock()
    +	defer packageLock.Unlock()
     	token := constellationLUKS2Token{
     		Type:              "constellation-state-disk",
     		Keyslots:          []string{},
    @@ -273,15 +340,31 @@ func (c *CryptSetup) SetConstellationStateDiskToken(diskIsInitialized bool) erro
     	if err != nil {
     		return fmt.Errorf("marshaling token: %w", err)
     	}
    -	if _, err := c.device.TokenJSONSet(ConstellationStateDiskTokenID, string(json)); err != nil {
    +
    +	device, err := c.getActiveDevice()
    +	if err != nil {
    +		return err
    +	}
    +
    +	if _, err := device.TokenJSONSet(ConstellationStateDiskTokenID, string(json)); err != nil {
     		return fmt.Errorf("setting token: %w", err)
     	}
    +	if err := c.createHeaderBackup(); err != nil {
    +		return err
    +	}
     	return nil
     }
     
     // ConstellationStateDiskTokenIsInitialized returns true if the Constellation state disk token is set to initialized.
     func (c *CryptSetup) ConstellationStateDiskTokenIsInitialized() bool {
    -	stateDiskToken, err := c.device.TokenJSONGet(ConstellationStateDiskTokenID)
    +	packageLock.Lock()
    +	defer packageLock.Unlock()
    +	device, err := c.getActiveDevice()
    +	if err != nil {
    +		return false
    +	}
    +
    +	stateDiskToken, err := device.TokenJSONGet(ConstellationStateDiskTokenID)
     	if err != nil {
     		return false
     	}
    @@ -298,17 +381,18 @@ func (c *CryptSetup) Wipe(
     ) (err error) {
     	packageLock.Lock()
     	defer packageLock.Unlock()
    -	if c.device == nil {
    -		return errDeviceNotOpen
    +	device, err := c.getActiveDevice()
    +	if err != nil {
    +		return err
     	}
     
     	// Active temporary device to perform wipe on
     	tmpDevice := tmpDevicePrefix + name
    -	if err := c.device.ActivateByVolumeKey(tmpDevice, "", 0, wipeFlags); err != nil {
    +	if err := device.ActivateByVolumeKey(tmpDevice, "", 0, wipeFlags); err != nil {
     		return fmt.Errorf("trying to activate temporary dm-crypt volume: %w", err)
     	}
     	defer func() {
    -		if deactivateErr := c.device.Deactivate(tmpDevice); deactivateErr != nil {
    +		if deactivateErr := device.Deactivate(tmpDevice); deactivateErr != nil {
     			err = errors.Join(err, fmt.Errorf("deactivating temporary device %q: %w", tmpDevice, deactivateErr))
     		}
     	}()
    @@ -330,8 +414,89 @@ func (c *CryptSetup) Wipe(
     		return 0
     	}
     
    -	if err := c.device.Wipe(mappedDevicePath+tmpDevice, wipePattern, 0, 0, blockWipeSize, flags, progressCallback); err != nil {
    -		return fmt.Errorf("wiping disk of device %q: %w", c.device.GetDeviceName(), err)
    +	if err := device.Wipe(mappedDevicePath+tmpDevice, wipePattern, 0, 0, blockWipeSize, flags, progressCallback); err != nil {
    +		return fmt.Errorf("wiping disk of device %q: %w", device.GetDeviceName(), err)
    +	}
    +	if err := c.createHeaderBackup(); err != nil {
    +		return err
    +	}
    +	return nil
    +}
    +
    +func (c *CryptSetup) free() {
    +	if c.hasDetachedHeaderDevice() {
    +		c.deviceWithDetachedHeader.Free()
    +		c.deviceWithDetachedHeader = nil
    +	}
    +	if c.hasAttachedHeaderDevice() {
    +		c.deviceWithAttachedHeader.Free()
    +		c.deviceWithAttachedHeader = nil
    +	}
    +	if c.headerDevice != "" {
    +		_ = detachLoopbackDevice(c.headerDevice)
    +	}
    +	if c.headerFile != "" {
    +		c.headerFile = ""
    +	}
    +}
    +
    +func (c *CryptSetup) reload() error {
    +	if !c.hasAttachedHeaderDevice() {
    +		return errDeviceNotOpen
    +	}
    +
    +	backingDevice := c.deviceWithAttachedHeader.GetDeviceName()
    +	c.free()
    +	var err error
    +	c.deviceWithDetachedHeader, c.deviceWithAttachedHeader, c.headerDevice, c.headerFile, err = c.pathInit(backingDevice)
    +	if err != nil {
    +		return fmt.Errorf("re-loading crypt device: %w", err)
    +	}
    +
    +	if !c.hasDetachedHeaderDevice() {
    +		return errors.New("failed to reload device without detached header")
    +	}
    +
    +	if err := loadLUKS2(c.deviceWithDetachedHeader); err != nil {
    +		return err
    +	}
    +
    +	return nil
    +}
    +
    +// getActiveDevice returns a handle to the active cryptsetup device with detached header if set,
    +// or one with attached header otherwise.
    +func (c *CryptSetup) getActiveDevice() (cryptDevice, error) {
    +	if c.hasDetachedHeaderDevice() {
    +		return c.deviceWithDetachedHeader, nil
    +	}
    +	if c.hasAttachedHeaderDevice() {
    +		return c.deviceWithAttachedHeader, nil
    +	}
    +	return nil, errDeviceNotOpen
    +}
    +
    +// hasDetachedHeaderDevice checks if the value of the [CryptSetup.deviceWithDetachedHeader] interface is not nil.
    +func (c *CryptSetup) hasDetachedHeaderDevice() bool {
    +	return c.deviceWithDetachedHeader != nil && !reflect.ValueOf(c.deviceWithDetachedHeader).IsNil()
    +}
    +
    +// hasAttachedHeaderDevice checks if the value of the [CryptSetup.deviceWithAttachedHeader] interface is not nil.
    +func (c *CryptSetup) hasAttachedHeaderDevice() bool {
    +	return c.deviceWithAttachedHeader != nil && !reflect.ValueOf(c.deviceWithAttachedHeader).IsNil()
    +}
    +
    +// createHeaderBackup creates a backup of the detached header, and saves it back to the original device.
    +func (c *CryptSetup) createHeaderBackup() error {
    +	if c.hasDetachedHeaderDevice() && c.headerFile != "" {
    +		if err := headerBackup(c.deviceWithDetachedHeader, c.headerFile); err != nil {
    +			return fmt.Errorf("creating header backup for device %q: %w", c.deviceWithDetachedHeader.GetDeviceName(), err)
    +		}
    +	}
    +	if c.hasAttachedHeaderDevice() && c.headerFile != "" {
    +		if err := headerRestore(c.deviceWithAttachedHeader, c.headerFile); err != nil {
    +			return fmt.Errorf("restoring header for device %q (with attached header): %w", c.deviceWithDetachedHeader.GetDeviceName(), err)
    +		}
     	}
     	return nil
     }
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.