Skip to content

Commit f3a8b3c

Browse files
Ruteribakhtin
andauthored
Azure v6 tcbinfo patch (#42)
Co-authored-by: bakhtin <a@bakhtin.net>
1 parent 4e175a4 commit f3a8b3c

File tree

9 files changed

+111
-7
lines changed

9 files changed

+111
-7
lines changed

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ RUN make build-${BINARY}
77

88
FROM gcr.io/distroless/cc-debian12:nonroot-6755e21ccd99ddead6edc8106ba03888cbeed41a
99
ARG BINARY
10-
COPY --from=builder /app/build/${BINARY} /app
11-
ENTRYPOINT [ "/app" ]
10+
COPY --from=builder /app/build/${BINARY} /proxy
11+
ENTRYPOINT [ "/proxy" ]

azure-tcbinfo-override/override.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package azure_tcbinfo_override
2+
3+
import (
4+
"log/slog"
5+
6+
"github.com/flashbots/cvm-reverse-proxy/internal/atls"
7+
azure_tdx "github.com/flashbots/cvm-reverse-proxy/internal/attestation/azure/tdx"
8+
"github.com/flashbots/cvm-reverse-proxy/proxy"
9+
10+
"github.com/google/go-tdx-guest/pcs"
11+
)
12+
13+
func OverrideV6InstanceOutdatedSEAMLoader(log *slog.Logger, tcbInfo pcs.TcbInfo) pcs.TcbInfo {
14+
if tcbInfo.Fmspc == azure_tdx.AZURE_V6_BAD_FMSPC {
15+
for l, tcbLevel := range tcbInfo.TcbLevels {
16+
if tcbLevel.TcbStatus == pcs.TcbComponentStatusUpToDate {
17+
if tcbLevel.Tcb.SgxTcbcomponents[7].Svn > 3 {
18+
log.Debug("overriding tcb info to allow outdated Azure v6 SEAM loader")
19+
tcbInfo.TcbLevels[l].Tcb.SgxTcbcomponents[7].Svn = 3
20+
}
21+
}
22+
}
23+
}
24+
25+
return tcbInfo
26+
}
27+
28+
func OverrideAzureValidatorsForV6SEAMLoader(log *slog.Logger, validators []atls.Validator) {
29+
for _, validator := range validators {
30+
if multiValidator, ok := validator.(*proxy.MultiValidator); ok {
31+
OverrideAzureValidatorsForV6SEAMLoader(log, multiValidator.Validators())
32+
}
33+
if azureTdxValidator, ok := validator.(*azure_tdx.Validator); ok {
34+
log.Info("set tcb overide for Azure TDX validator")
35+
azureTdxValidator.SetTcbOverride(func(tcbInfo pcs.TcbInfo) pcs.TcbInfo { return OverrideV6InstanceOutdatedSEAMLoader(log, tcbInfo) })
36+
}
37+
}
38+
}

cmd/attested-get/main.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141
"os"
4242
"strings"
4343

44+
azure_tcbinfo_override "github.com/flashbots/cvm-reverse-proxy/azure-tcbinfo-override"
4445
"github.com/flashbots/cvm-reverse-proxy/common"
4546
"github.com/flashbots/cvm-reverse-proxy/internal/atls"
4647
azure_tdx "github.com/flashbots/cvm-reverse-proxy/internal/attestation/azure/tdx"
@@ -78,6 +79,12 @@ var flags []cli.Flag = []cli.Flag{
7879
Value: "",
7980
Usage: "File or URL with known measurements (to compare against)",
8081
},
82+
&cli.BoolFlag{
83+
Name: "override-azurev6-tcbinfo",
84+
Value: false,
85+
EnvVars: []string{"OVERRIDE_AZUREV6_TCBINFO"},
86+
Usage: "Allows Azure's V6 instance outdated SEAM Loader",
87+
},
8188
&cli.BoolFlag{
8289
Name: "log-debug",
8390
Value: false,
@@ -105,6 +112,7 @@ func runClient(cCtx *cli.Context) (err error) {
105112
outResponse := cCtx.String("out-response")
106113
attestationTypeStr := cCtx.String("attestation-type")
107114
expectedMeasurementsPath := cCtx.String("expected-measurements")
115+
overrideAzurev6Tcbinfo := cCtx.Bool("override-azurev6-tcbinfo")
108116

109117
// Setup logging
110118
log := common.SetupLogger(&common.LoggingOpts{
@@ -133,6 +141,9 @@ func runClient(cCtx *cli.Context) (err error) {
133141
attConfig := config.DefaultForAzureTDX()
134142
attConfig.SetMeasurements(measurements.M{})
135143
validator := azure_tdx.NewValidator(attConfig, proxy.AttestationLogger{Log: log})
144+
if overrideAzurev6Tcbinfo {
145+
azure_tcbinfo_override.OverrideAzureValidatorsForV6SEAMLoader(log, []atls.Validator{validator})
146+
}
136147
validators = append(validators, validator)
137148
default:
138149
log.Error("currently only azure-tdx attestation is supported")

cmd/proxy-client/main.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"net/http"
88
"os"
99

10+
azure_tcbinfo_override "github.com/flashbots/cvm-reverse-proxy/azure-tcbinfo-override"
1011
"github.com/flashbots/cvm-reverse-proxy/common"
1112
"github.com/flashbots/cvm-reverse-proxy/internal/atls"
1213
"github.com/flashbots/cvm-reverse-proxy/proxy"
@@ -47,6 +48,12 @@ var flags []cli.Flag = []cli.Flag{
4748
Value: string(proxy.AttestationNone),
4849
Usage: "type of attestation to present (" + proxy.AvailableAttestationTypes + "). Set to " + string(proxy.AttestationDummy) + " to use remote quote provider.",
4950
},
51+
&cli.BoolFlag{
52+
Name: "override-azurev6-tcbinfo",
53+
Value: false,
54+
EnvVars: []string{"OVERRIDE_AZUREV6_TCBINFO"},
55+
Usage: "Allows Azure's V6 instance outdated SEAM Loader",
56+
},
5057
&cli.BoolFlag{
5158
Name: "log-json",
5259
Value: false,
@@ -87,6 +94,7 @@ func runClient(cCtx *cli.Context) error {
8794
listenAddr := cCtx.String("listen-addr")
8895
targetAddr := cCtx.String("target-addr")
8996
serverMeasurements := cCtx.String("server-measurements")
97+
overrideAzurev6Tcbinfo := cCtx.Bool("override-azurev6-tcbinfo")
9098
logJSON := cCtx.Bool("log-json")
9199
logDebug := cCtx.Bool("log-debug")
92100
tdx.SetLogDcapQuote(cCtx.Bool("log-dcap-quote"))
@@ -143,6 +151,10 @@ func runClient(cCtx *cli.Context) error {
143151
return err
144152
}
145153

154+
if overrideAzurev6Tcbinfo {
155+
azure_tcbinfo_override.OverrideAzureValidatorsForV6SEAMLoader(log, validators)
156+
}
157+
146158
tlsConfig, err := atls.CreateAttestationClientTLSConfig(issuer, validators)
147159
if err != nil {
148160
log.Error("could not create atls config", "err", err)

cmd/proxy-server/main.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"syscall"
1212
"time"
1313

14+
azure_tcbinfo_override "github.com/flashbots/cvm-reverse-proxy/azure-tcbinfo-override"
1415
"github.com/flashbots/cvm-reverse-proxy/common"
1516
"github.com/flashbots/cvm-reverse-proxy/internal/atls"
1617
"github.com/flashbots/cvm-reverse-proxy/proxy"
@@ -62,6 +63,12 @@ var flags []cli.Flag = []cli.Flag{
6263
EnvVars: []string{"CLIENT_MEASUREMENTS"},
6364
Usage: "optional path to JSON measurements enforced on the client",
6465
},
66+
&cli.BoolFlag{
67+
Name: "override-azurev6-tcbinfo",
68+
Value: false,
69+
EnvVars: []string{"OVERRIDE_AZUREV6_TCBINFO"},
70+
Usage: "Allows Azure's V6 instance outdated SEAM Loader",
71+
},
6572
&cli.BoolFlag{
6673
Name: "log-json",
6774
EnvVars: []string{"LOG_JSON"},
@@ -110,6 +117,7 @@ func runServer(cCtx *cli.Context) error {
110117
listenAddr := cCtx.String("listen-addr")
111118
targetAddr := cCtx.String("target-addr")
112119
clientMeasurements := cCtx.String("client-measurements")
120+
overrideAzurev6Tcbinfo := cCtx.Bool("override-azurev6-tcbinfo")
113121
logJSON := cCtx.Bool("log-json")
114122
logDebug := cCtx.Bool("log-debug")
115123
tdx.SetLogDcapQuote(cCtx.Bool("log-dcap-quote"))
@@ -146,6 +154,10 @@ func runServer(cCtx *cli.Context) error {
146154
return err
147155
}
148156

157+
if overrideAzurev6Tcbinfo {
158+
azure_tcbinfo_override.OverrideAzureValidatorsForV6SEAMLoader(log, validators)
159+
}
160+
149161
var issuer atls.Issuer
150162

151163
isDummyAttestationType := serverAttestationTypeFlag == string(proxy.AttestationDummy)

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.22.4
55
replace github.com/martinjungblut/go-cryptsetup => github.com/daniel-weisse/go-cryptsetup v0.0.0-20230705150314-d8c07bd1723c
66

77
replace (
8+
github.com/google/go-tdx-guest => github.com/flashbots/go-tdx-guest v0.0.0-20250812101008-c4de93fd5a34
89
k8s.io/cloud-provider => k8s.io/cloud-provider v0.30.2
910
k8s.io/controller-manager => k8s.io/controller-manager v0.30.2
1011
k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.30.2
@@ -158,7 +159,7 @@ require (
158159
github.com/google/certificate-transparency-go v1.1.8 // indirect
159160
github.com/google/gnostic-models v0.6.8 // indirect
160161
github.com/google/go-attestation v0.5.1 // indirect
161-
github.com/google/go-configfs-tsm v0.2.2 // indirect
162+
github.com/google/go-configfs-tsm v0.3.2 // indirect
162163
github.com/google/go-containerregistry v0.19.2 // indirect
163164
github.com/google/go-tspi v0.3.0 // indirect
164165
github.com/google/gofuzz v1.2.0 // indirect

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
167167
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
168168
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
169169
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
170+
github.com/flashbots/go-tdx-guest v0.0.0-20250812101008-c4de93fd5a34 h1:rqyx3e+CwPtKBbopWz0amKweDkiuSb9fB/rF9y3RlBw=
171+
github.com/flashbots/go-tdx-guest v0.0.0-20250812101008-c4de93fd5a34/go.mod h1:uHy3VaNXNXhl0fiPxKqTxieeouqQmW6A0EfLcaeCYBk=
170172
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
171173
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
172174
github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec=
@@ -258,14 +260,12 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
258260
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
259261
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
260262
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
261-
github.com/google/go-configfs-tsm v0.2.2 h1:YnJ9rXIOj5BYD7/0DNnzs8AOp7UcvjfTvt215EWcs98=
262-
github.com/google/go-configfs-tsm v0.2.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo=
263+
github.com/google/go-configfs-tsm v0.3.2 h1:ZYmHkdQavfsvVGDtX7RRda0gamelUNUhu0A9fbiuLmE=
264+
github.com/google/go-configfs-tsm v0.3.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo=
263265
github.com/google/go-containerregistry v0.19.2 h1:TannFKE1QSajsP6hPWb5oJNgKe1IKjHukIKDUmvsV6w=
264266
github.com/google/go-containerregistry v0.19.2/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI=
265267
github.com/google/go-sev-guest v0.11.1 h1:gnww4U8fHV5DCPz4gykr1s8SEX1fFNcxCBy+vvXN24k=
266268
github.com/google/go-sev-guest v0.11.1/go.mod h1:qBOfb+JmgsUI3aUyzQoGC13Kpp9zwLeWvuyXmA9q77w=
267-
github.com/google/go-tdx-guest v0.3.1 h1:gl0KvjdsD4RrJzyLefDOvFOUH3NAJri/3qvaL5m83Iw=
268-
github.com/google/go-tdx-guest v0.3.1/go.mod h1:/rc3d7rnPykOPuY8U9saMyEps0PZDThLk/RygXm04nE=
269269
github.com/google/go-tpm v0.9.1 h1:0pGc4X//bAlmZzMKf8iz6IsDo1nYTbYJ6FZN/rg4zdM=
270270
github.com/google/go-tpm v0.9.1/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY=
271271
github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98=

internal/attestation/azure/tdx/validator.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/flashbots/cvm-reverse-proxy/internal/config"
2121

2222
"github.com/google/go-tdx-guest/abi"
23+
"github.com/google/go-tdx-guest/pcs"
2324
"github.com/google/go-tdx-guest/proto/tdx"
2425
"github.com/google/go-tdx-guest/validate"
2526
"github.com/google/go-tdx-guest/verify"
@@ -28,6 +29,8 @@ import (
2829
"github.com/google/go-tpm/legacy/tpm2"
2930
)
3031

32+
const AZURE_V6_BAD_FMSPC = "90c06f000000"
33+
3134
// Validator for Azure confidential VM attestation using TDX.
3235
type Validator struct {
3336
variant.AzureTDX
@@ -36,6 +39,9 @@ type Validator struct {
3639

3740
getter trust.HTTPSGetter
3841
hclValidator hclAkValidator
42+
43+
tcbOverride func(pcs.TcbInfo) pcs.TcbInfo
44+
log attestation.Logger
3945
}
4046

4147
// NewValidator returns a new Validator for Azure confidential VM attestation using TDX.
@@ -44,6 +50,7 @@ func NewValidator(cfg *config.AzureTDX, log attestation.Logger) *Validator {
4450
cfg: cfg,
4551
getter: trust.DefaultHTTPSGetter(),
4652
hclValidator: &azure.HCLAkValidator{},
53+
log: log,
4754
}
4855

4956
v.Validator = vtpm.NewValidator(
@@ -58,6 +65,11 @@ func NewValidator(cfg *config.AzureTDX, log attestation.Logger) *Validator {
5865
return v
5966
}
6067

68+
func (v *Validator) SetTcbOverride(overrideFn func(pcs.TcbInfo) pcs.TcbInfo) *Validator {
69+
v.tcbOverride = overrideFn
70+
return v
71+
}
72+
6173
func (v *Validator) getTrustedTPMKey(_ context.Context, attDoc vtpm.AttestationDocument, _ []byte) (crypto.PublicKey, error) {
6274
var instanceInfo InstanceInfo
6375
if err := json.Unmarshal(attDoc.InstanceInfo, &instanceInfo); err != nil {
@@ -96,12 +108,26 @@ func (v *Validator) validateQuote(tdxQuote *tdx.QuoteV4) error {
96108
if err := verify.TdxQuote(tdxQuote, &verify.Options{
97109
CheckRevocations: true,
98110
GetCollateral: true,
111+
PatchTCBInfo: v.tcbOverride,
99112
TrustedRoots: roots,
100113
Getter: v.getter,
101114
}); err != nil {
102115
return err
103116
}
104117

118+
// Hacky way to log every time we validate the outdated v6 tcb
119+
if v.tcbOverride != nil {
120+
if chain, err := verify.ExtractChainFromQuote(tdxQuote); err == nil {
121+
if exts, err := pcs.PckCertificateExtensions(chain.PCKCertificate); err == nil {
122+
if exts.FMSPC == AZURE_V6_BAD_FMSPC {
123+
if tdxQuote.TdQuoteBody.TeeTcbSvn[7] == 3 {
124+
v.log.Warn("allowing azure's outdated SEAM loader")
125+
}
126+
}
127+
}
128+
}
129+
}
130+
105131
if err := validate.TdxQuote(tdxQuote, &validate.Options{
106132
HeaderOptions: validate.HeaderOptions{
107133
MinimumQeSvn: v.cfg.QESVN.Value,

proxy/mutli_validator.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ func NewMultiValidator(validators []atls.Validator) *MultiValidator {
2727
}
2828
}
2929

30+
func (v *MultiValidator) Validators() []atls.Validator {
31+
return v.validators
32+
}
33+
3034
func (v *MultiValidator) OID() asn1.ObjectIdentifier {
3135
return v.oid
3236
}

0 commit comments

Comments
 (0)