diff --git a/abi/abi.go b/abi/abi.go new file mode 100644 index 0000000..e505e6f --- /dev/null +++ b/abi/abi.go @@ -0,0 +1,888 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package abi provides Go representations and conversions for TDX attestation +// data structures +package abi + +import ( + "encoding/binary" + "errors" + "fmt" + "math/big" + + pb "github.com/google/go-tdx-guest/proto/tdx" + "golang.org/x/crypto/cryptobyte" + "golang.org/x/crypto/cryptobyte/asn1" +) + +const ( + // QuoteMinSize is the minimum specified size of TDX generated quote + QuoteMinSize = 0x3FC + // QuoteVersion currently in support + QuoteVersion = 4 + // AttestationKeyType supported value + AttestationKeyType = 2 // (ECDSA-256-with-P-256 curve) + // TeeTDX for Attestation + TeeTDX = 0x00000081 + + userDataSize = 0x14 + reportDataSize = 0x40 + qeReportCertificationDataType = 0x6 + pckReportCertificationDataType = 0x5 + qeReportSize = 0x180 + headerSize = 0x30 + tdQuoteBodySize = 0x248 + qeSvnSize = 0x2 + pceSvnSize = 0x2 + qeVendorIDSize = 0x10 + teeTcbSvnSize = 0x10 + mrSeamSize = 0x30 + mrSignerSeamSize = 0x30 + seamAttributesSize = 0x08 + tdAttributesSize = 0x08 + xfamSize = 0x08 + mrTdSize = 0x30 + mrConfigIDSize = 0x30 + mrOwnerSize = 0x30 + mrOwnerConfigSize = 0x30 + rtMr0Size = 0x30 + rtMr1Size = 0x30 + rtMr2Size = 0x30 + rtMr3Size = 0x30 + cpuSvnSize = 0x10 + reserved1Size = 0x1C + attributesSize = 0x10 + mrEnclaveSize = 0x20 + reserved2Size = 0x20 + mrSignerSize = 0x20 + reserved3Size = 0x60 + reserved4Size = 0x3C + signatureSize = 0x40 + attestationKeySize = 0x40 + pckCertificateChainKnownSize = 0x06 + qeAuthDataKnownSize = 0x02 + certificationDataKnownSize = 0x06 + quoteV4AuthDataKnownSize = 0x80 + quoteHeaderStart = 0x00 + quoteHeaderEnd = 0x30 + quoteBodyStart = 0x30 + quoteBodyEnd = 0x278 + quoteSignedDataSizeStart = 0x278 + quoteSignedDataSizeEnd = 0x27C + quoteSignedDataStart = quoteSignedDataSizeEnd + headerVersionStart = 0x00 + headerVersionEnd = 0x02 + headerAttestationKeyTypeStart = headerVersionEnd + headerAttestationKeyTypeEnd = 0x04 + headerTeeTypeStart = headerAttestationKeyTypeEnd + headerTeeTypeEnd = 0x08 + headerPceSvnStart = headerTeeTypeEnd + headerPceSvnEnd = 0xA + headerQeSvnStart = headerPceSvnEnd + headerQeSvnEnd = 0xC + headerQeVendorIDStart = headerQeSvnEnd + headerQeVendorIDEnd = 0x1C + headerUserDataStart = headerQeVendorIDEnd + headerUserDataEnd = 0x30 + tdTeeTcbSvnStart = 0x00 + tdTeeTcbSvnEnd = 0x10 + tdMrSeamStart = tdTeeTcbSvnEnd + tdMrSeamEnd = 0x40 + tdMrSignerSeamStart = tdMrSeamEnd + tdMrSignerSeamEnd = 0x70 + tdSeamAttributesStart = tdMrSignerSeamEnd + tdSeamAttributesEnd = 0x78 + tdAttributesStart = tdSeamAttributesEnd + tdAttributesEnd = 0x80 + tdXfamStart = tdAttributesEnd + tdXfamEnd = 0x88 + tdMrTdStart = tdXfamEnd + tdMrTdEnd = 0xB8 + tdMrConfigIDStart = tdMrTdEnd + tdMrConfigIDEnd = 0xE8 + tdMrOwnerStart = tdMrConfigIDEnd + tdMrOwnerEnd = 0x118 + tdMrOwnerConfigStart = tdMrOwnerEnd + tdMrOwnerConfigEnd = 0x148 + tdRtMr0Start = tdMrOwnerConfigEnd + tdRtMr0End = 0x178 + tdRtMr1Start = tdRtMr0End + tdRtMr1End = 0x1A8 + tdRtMr2Start = tdRtMr1End + tdRtMr2End = 0x1D8 + tdRtMr3Start = tdRtMr2End + tdRtMr3End = 0x208 + tdReportDataStart = tdRtMr3End + tdReportDataEnd = 0x248 + signedDataSignatureStart = 0x00 + signedDataSignatureEnd = 0x40 + signedDataAttestationKeyStart = signedDataSignatureEnd + signedDataAttestationKeyEnd = 0x80 + signedDataCertificationDataStart = signedDataAttestationKeyEnd + certificateDataTypeStart = 0x00 + certificateDataTypeEnd = 0x02 + certificateSizeStart = certificateDataTypeEnd + certificateSizeEnd = 0x06 + certificateDataStart = certificateSizeEnd + enclaveReportStart = 0x00 + enclaveReportEnd = 0x180 + qeReportCertificationDataSignatureStart = enclaveReportEnd + qeReportCertificationDataSignatureEnd = 0x1C0 + qeReportCertificationDataAuthDataStart = qeReportCertificationDataSignatureEnd + qeCPUSvnStart = 0x00 + qeCPUSvnEnd = 0x10 + qeMiscSelectStart = qeCPUSvnEnd + qeMiscSelectEnd = 0x14 + qeReserved1Start = qeMiscSelectEnd + qeReserved1End = 0x30 + qeAttributesStart = qeReserved1End + qeAttributesEnd = 0x40 + qeMrEnclaveStart = qeAttributesEnd + qeMrEnclaveEnd = 0x60 + qeReserved2Start = qeMrEnclaveEnd + qeReserved2End = 0x80 + qeMrSignerStart = qeReserved2End + qeMrSignerEnd = 0xA0 + qeReserved3Start = qeMrSignerEnd + qeReserved3End = 0x100 + qeIsvProdIDStart = qeReserved3End + qeIsvProdIDEnd = 0x102 + qeIsvSvnStart = qeIsvProdIDEnd + qeIsvSvnEnd = 0x104 + qeReserved4Start = qeIsvSvnEnd + qeReserved4End = 0x140 + qeReportDataStart = qeReserved4End + qeReportDataEnd = 0x180 + authDataParsedDataSizeStart = 0x00 + authDataParsedDataSizeEnd = 0x02 + authDataStart = authDataParsedDataSizeEnd + pckCertChainCertificationDataTypeStart = 0x00 + pckCertChainCertificationDataTypeEnd = 0x02 + pckCertChainSizeStart = pckCertChainCertificationDataTypeEnd + pckCertChainSizeEnd = 0x06 + pckCertChainDataStart = pckCertChainSizeEnd +) + +var ( + // ErrQuoteV4Nil error returned when QuoteV4 is empty + ErrQuoteV4Nil = errors.New("QuoteV4 is empty") + + // ErrQuoteV4AuthDataNil error returned when QuoteV4 Auth Data is empty + ErrQuoteV4AuthDataNil = errors.New("QuoteV4 authData is empty") + + // ErrCertificationDataNil error returned when Certification Data is empty + ErrCertificationDataNil = errors.New("certification data is empty") + + // ErrQeReportCertificationDataNil error returned when QE report certification data is empty + ErrQeReportCertificationDataNil = errors.New("QE Report certification data is empty") + + // ErrQeAuthDataNil error returned when QE Auth Data is empty + ErrQeAuthDataNil = errors.New("QE AuthData is empty") + + // ErrQeReportNil error returned when QE Report is empty + ErrQeReportNil = errors.New("QE Report is empty") + + // ErrPckCertChainNil error returned when PCK Certificate Chain is empty + ErrPckCertChainNil = errors.New("PCK certificate chain is empty") + + // ErrTDQuoteBodyNil error returned when TD quote body is empty + ErrTDQuoteBodyNil = errors.New("TD quote body is empty") + + // ErrTeeType error returned when TEE type is not TDX + ErrTeeType = errors.New("TEE type is not TDX") + + // ErrAttestationKeyType error returned when attestation key is not of expected type + ErrAttestationKeyType = errors.New("attestation key type not supported") + + // ErrHeaderNil error returned when header is empty + ErrHeaderNil = errors.New("header is empty") +) + +func clone(b []byte) []byte { + result := make([]byte, len(b)) + copy(result, b) + return result +} + +// QuoteToProto creates a pb.QuoteV4 from the Intel's attestation quote byte array in Intel's ABI format. +func QuoteToProto(b []uint8) (*pb.QuoteV4, error) { + data := clone(b) // Created an independent copy to make the interface less error-prone + if len(data) < QuoteMinSize { + return nil, fmt.Errorf("raw quote size is 0x%x, a TDX quote should have size a minimum size of 0x%x", len(data), QuoteMinSize) + } + quote := &pb.QuoteV4{} + header, err := headerToProto(data[quoteHeaderStart:quoteHeaderEnd]) + if err != nil { + return nil, err + } + + tdQuoteBody, err := tdQuoteBodyToProto(data[quoteBodyStart:quoteBodyEnd]) + if err != nil { + return nil, err + } + + quote.SignedDataSize = binary.LittleEndian.Uint32(data[quoteSignedDataSizeStart:quoteSignedDataSizeEnd]) + + additionalData := data[quoteSignedDataStart:] + if uint32(len(additionalData)) < quote.GetSignedDataSize() { + return nil, fmt.Errorf("size of signed data is 0x%x. Expected minimum size of 0x%x", len(additionalData), quote.GetSignedDataSize()) + } + quoteSignedDataEnd := quoteSignedDataStart + quote.GetSignedDataSize() + rawSignedData := data[quoteSignedDataStart:quoteSignedDataEnd] + extraBytes := data[quoteSignedDataEnd:] + signedData, err := signedDataToProto(rawSignedData) + if err != nil { + return nil, err + } + + quote.Header = header + quote.TdQuoteBody = tdQuoteBody + quote.SignedData = signedData + if len(extraBytes) > 0 { + quote.ExtraBytes = extraBytes + } + + if err := CheckQuoteV4(quote); err != nil { + return nil, fmt.Errorf("parsing QuoteV4 failed: %v", err) + } + return quote, nil +} + +func headerToProto(b []uint8) (*pb.Header, error) { + data := clone(b) // Created an independent copy to make the interface less error-prone + header := &pb.Header{} + + header.Version = uint32(binary.LittleEndian.Uint16(data[headerVersionStart:headerVersionEnd])) + header.AttestationKeyType = uint32(binary.LittleEndian.Uint16(data[headerAttestationKeyTypeStart:headerAttestationKeyTypeEnd])) + header.TeeType = binary.LittleEndian.Uint32(data[headerTeeTypeStart:headerTeeTypeEnd]) + header.PceSvn = data[headerPceSvnStart:headerPceSvnEnd] + header.QeSvn = data[headerQeSvnStart:headerQeSvnEnd] + header.QeVendorId = data[headerQeVendorIDStart:headerQeVendorIDEnd] + header.UserData = data[headerUserDataStart:headerUserDataEnd] + + if err := checkHeader(header); err != nil { + return nil, fmt.Errorf("parsing header failed: %v", err) + } + return header, nil +} + +func tdQuoteBodyToProto(b []uint8) (*pb.TDQuoteBody, error) { + data := clone(b) // Created an independent copy to make the interface less error-prone + report := &pb.TDQuoteBody{} + report.TeeTcbSvn = data[tdTeeTcbSvnStart:tdTeeTcbSvnEnd] + report.MrSeam = data[tdMrSeamStart:tdMrSeamEnd] + report.MrSignerSeam = data[tdMrSignerSeamStart:tdMrSignerSeamEnd] + report.SeamAttributes = data[tdSeamAttributesStart:tdSeamAttributesEnd] + report.TdAttributes = data[tdAttributesStart:tdAttributesEnd] + report.Xfam = data[tdXfamStart:tdXfamEnd] + report.MrTd = data[tdMrTdStart:tdMrTdEnd] + report.MrConfigId = data[tdMrConfigIDStart:tdMrConfigIDEnd] + report.MrOwner = data[tdMrOwnerStart:tdMrOwnerEnd] + report.MrOwnerConfig = data[tdMrOwnerConfigStart:tdMrOwnerConfigEnd] + report.RtMr0 = data[tdRtMr0Start:tdRtMr0End] + report.RtMr1 = data[tdRtMr1Start:tdRtMr1End] + report.RtMr2 = data[tdRtMr2Start:tdRtMr2End] + report.RtMr3 = data[tdRtMr3Start:tdRtMr3End] + report.ReportData = data[tdReportDataStart:tdReportDataEnd] + + if err := checkTDQuoteBody(report); err != nil { + return nil, fmt.Errorf("parsing TD Quote Body failed: %v", err) + } + + return report, nil +} + +func signedDataToProto(b []uint8) (*pb.Ecdsa256BitQuoteV4AuthData, error) { + data := clone(b) // Created an independent copy to make the interface less error-prone + signedData := &pb.Ecdsa256BitQuoteV4AuthData{} + signedData.Signature = data[signedDataSignatureStart:signedDataSignatureEnd] + signedData.EcdsaAttestationKey = data[signedDataAttestationKeyStart:signedDataAttestationKeyEnd] + + certificationData, err := certificationDataToProto(data[signedDataCertificationDataStart:]) + if err != nil { + return nil, err + } + + signedData.CertificationData = certificationData + + if err := checkEcdsa256BitQuoteV4AuthData(signedData); err != nil { + return nil, fmt.Errorf("parsing QuoteV4 AuthData failed: %v", err) + } + return signedData, nil +} + +func certificationDataToProto(b []uint8) (*pb.CertificationData, error) { + data := clone(b) // Created an independent copy to make the interface less error-prone + certification := &pb.CertificationData{} + + certification.CertificateDataType = uint32(binary.LittleEndian.Uint16(data[certificateDataTypeStart:certificateDataTypeEnd])) + certification.Size = binary.LittleEndian.Uint32(data[certificateSizeStart:certificateSizeEnd]) + rawCertificateData := data[certificateDataStart:] + if uint32(len(rawCertificateData)) != certification.GetSize() { + return nil, fmt.Errorf("size of certificate data is 0x%x. Expected size 0x%x", len(rawCertificateData), certification.GetSize()) + } + + qeReportCertificationData, err := qeReportCertificationDataToProto(rawCertificateData) + if err != nil { + return nil, err + } + + certification.QeReportCertificationData = qeReportCertificationData + + if err := checkCertificationData(certification); err != nil { + return nil, fmt.Errorf("parsing certification data failed: %v", err) + } + return certification, nil +} + +func qeReportCertificationDataToProto(b []uint8) (*pb.QEReportCertificationData, error) { + data := clone(b) // Created an independent copy to make the interface less error-prone + qeReportCertificationData := &pb.QEReportCertificationData{} + + enclaveReport, err := enclaveReportToProto(data[enclaveReportStart:enclaveReportEnd]) + if err != nil { + return nil, err + } + + qeReportCertificationData.QeReport = enclaveReport + qeReportCertificationData.QeReportSignature = data[qeReportCertificationDataSignatureStart:qeReportCertificationDataSignatureEnd] + + authData, authDataSize, err := qeAuthDataToProto(data[qeReportCertificationDataAuthDataStart:]) + if err != nil { + return nil, err + } + + qeReportCertificationData.QeAuthData = authData + + pckCertificateStart := qeReportCertificationDataAuthDataStart + authDataSize + + pckCertificateChain, err := pckCertificateChainToProto(data[pckCertificateStart:]) + if err != nil { + return nil, err + } + + qeReportCertificationData.PckCertificateChainData = pckCertificateChain + + if err := checkQeReportCertificationData(qeReportCertificationData); err != nil { + return nil, fmt.Errorf("parsing QE Report Certification Data failed: %v", err) + } + return qeReportCertificationData, nil +} + +func enclaveReportToProto(b []uint8) (*pb.EnclaveReport, error) { + data := clone(b) // Created an independent copy to make the interface less error-prone + enclaveReport := &pb.EnclaveReport{} + + enclaveReport.CpuSvn = data[qeCPUSvnStart:qeCPUSvnEnd] + enclaveReport.MiscSelect = binary.LittleEndian.Uint32(data[qeMiscSelectStart:qeMiscSelectEnd]) + enclaveReport.Reserved1 = data[qeReserved1Start:qeReserved1End] + enclaveReport.Attributes = data[qeAttributesStart:qeAttributesEnd] + enclaveReport.MrEnclave = data[qeMrEnclaveStart:qeMrEnclaveEnd] + enclaveReport.Reserved2 = data[qeReserved2Start:qeReserved2End] + enclaveReport.MrSigner = data[qeMrSignerStart:qeMrSignerEnd] + enclaveReport.Reserved3 = data[qeReserved3Start:qeReserved3End] + enclaveReport.IsvProdId = uint32(binary.LittleEndian.Uint16(data[qeIsvProdIDStart:qeIsvProdIDEnd])) + enclaveReport.IsvSvn = uint32(binary.LittleEndian.Uint16(data[qeIsvSvnStart:qeIsvSvnEnd])) + enclaveReport.Reserved4 = data[qeReserved4Start:qeReserved4End] + enclaveReport.ReportData = data[qeReportDataStart:qeReportDataEnd] + + if err := checkQeReport(enclaveReport); err != nil { + return nil, fmt.Errorf("parsing QE Report failed: %v", err) + } + return enclaveReport, nil +} + +func qeAuthDataToProto(b []uint8) (*pb.QeAuthData, uint32, error) { + data := clone(b) // Created an independent copy to make the interface less error-prone + authData := &pb.QeAuthData{} + + authData.ParsedDataSize = uint32(binary.LittleEndian.Uint16(data[authDataParsedDataSizeStart:authDataParsedDataSizeEnd])) + authDataEnd := authDataParsedDataSizeEnd + authData.GetParsedDataSize() + authData.Data = data[authDataStart:authDataEnd] + if err := checkQeAuthData(authData); err != nil { + return nil, 0, fmt.Errorf("parsing QE AuthData failed: %v", err) + } + return authData, authDataEnd, nil +} + +func pckCertificateChainToProto(b []uint8) (*pb.PCKCertificateChainData, error) { + data := clone(b) // Created an independent copy to make the interface less error-prone + pckCertificateChain := &pb.PCKCertificateChainData{} + + pckCertificateChain.CertificateDataType = uint32(binary.LittleEndian.Uint16(data[pckCertChainCertificationDataTypeStart:pckCertChainCertificationDataTypeEnd])) + pckCertificateChain.Size = binary.LittleEndian.Uint32(data[pckCertChainSizeStart:pckCertChainSizeEnd]) + pckCertificateChain.PckCertChain = data[pckCertChainDataStart:] + + if err := checkPCKCertificateChain(pckCertificateChain); err != nil { + return nil, fmt.Errorf("parsing PCK certification chain failed: %v", err) + } + return pckCertificateChain, nil +} + +func checkHeader(header *pb.Header) error { + if header == nil { + return ErrHeaderNil + } + if header.GetVersion() >= (1 << 16) { + return fmt.Errorf("version field size must fit in 2 bytes , got %d", header.GetVersion()) + } + if header.GetVersion() != QuoteVersion { + return fmt.Errorf("version %d not supported", header.GetVersion()) + } + if header.GetAttestationKeyType() >= (1 << 16) { + return fmt.Errorf("attestation key type field size must fit in 2 bytes , got %d", header.GetAttestationKeyType()) + } + if header.GetAttestationKeyType() != AttestationKeyType { + return ErrAttestationKeyType + } + if header.GetTeeType() != TeeTDX { + return ErrTeeType + } + + if len(header.GetQeSvn()) != qeSvnSize { + return fmt.Errorf("qeSvn size is %d bytes. Expected %d bytes", len(header.GetQeSvn()), qeSvnSize) + } + if len(header.GetPceSvn()) != pceSvnSize { + return fmt.Errorf("pceSvn size is %d bytes. Expected %d bytes", len(header.GetPceSvn()), pceSvnSize) + } + if len(header.GetQeVendorId()) != qeVendorIDSize { + return fmt.Errorf("qeVendorId size is %d bytes. Expected %d bytes", len(header.GetQeVendorId()), qeVendorIDSize) + } + if len(header.GetUserData()) != userDataSize { + return fmt.Errorf("user data size is %d bytes. Expected %d bytes", len(header.GetUserData()), userDataSize) + } + + return nil + +} + +func checkTDQuoteBody(tdQuoteBody *pb.TDQuoteBody) error { + if tdQuoteBody == nil { + return ErrTDQuoteBodyNil + } + if len(tdQuoteBody.GetTeeTcbSvn()) != teeTcbSvnSize { + return fmt.Errorf("teeTcbSvn size is %d bytes. Expected %d bytes", len(tdQuoteBody.GetTeeTcbSvn()), teeTcbSvnSize) + } + if len(tdQuoteBody.GetMrSeam()) != mrSeamSize { + return fmt.Errorf("mrSeam size is %d bytes. Expected %d bytes", len(tdQuoteBody.GetMrSeam()), mrSeamSize) + } + if len(tdQuoteBody.GetMrSignerSeam()) != mrSignerSeamSize { + return fmt.Errorf("mrSignerSeam size is %d bytes. Expected %d bytes", len(tdQuoteBody.GetMrSignerSeam()), mrSignerSeamSize) + } + if len(tdQuoteBody.GetSeamAttributes()) != seamAttributesSize { + return fmt.Errorf("seamAttributes size is %d bytes. Expected %d bytes", len(tdQuoteBody.GetSeamAttributes()), seamAttributesSize) + } + if len(tdQuoteBody.GetTdAttributes()) != tdAttributesSize { + return fmt.Errorf("tdAttributes size is %d bytes. Expected %d bytes", len(tdQuoteBody.GetTdAttributes()), tdAttributesSize) + } + if len(tdQuoteBody.GetXfam()) != xfamSize { + return fmt.Errorf("xfam size is %d bytes. Expected %d bytes", len(tdQuoteBody.GetXfam()), xfamSize) + } + if len(tdQuoteBody.GetMrTd()) != mrTdSize { + return fmt.Errorf("mrTd size is %d bytes. Expected %d bytes", len(tdQuoteBody.GetMrTd()), mrTdSize) + } + if len(tdQuoteBody.GetMrConfigId()) != mrConfigIDSize { + return fmt.Errorf("mrConfigId size is %d bytes. Expected %d bytes", len(tdQuoteBody.GetMrConfigId()), mrConfigIDSize) + } + if len(tdQuoteBody.GetMrOwner()) != mrOwnerSize { + return fmt.Errorf("mrOwner size is %d bytes. Expected %d bytes", len(tdQuoteBody.GetMrOwner()), mrOwnerSize) + } + if len(tdQuoteBody.GetMrOwnerConfig()) != mrOwnerConfigSize { + return fmt.Errorf("mrOwnerConfig size is %d bytes. Expected %d bytes", len(tdQuoteBody.GetMrOwnerConfig()), mrOwnerConfigSize) + } + if len(tdQuoteBody.GetRtMr0()) != rtMr0Size { + return fmt.Errorf("rtMr0 size is %d bytes. Expected %d bytes", len(tdQuoteBody.GetRtMr0()), rtMr0Size) + } + if len(tdQuoteBody.GetRtMr1()) != rtMr1Size { + return fmt.Errorf("rtMr1 size is %d bytes. Expected %d bytes", len(tdQuoteBody.GetRtMr1()), rtMr1Size) + } + if len(tdQuoteBody.GetRtMr2()) != rtMr2Size { + return fmt.Errorf("rtMr2 size is %d bytes. Expected %d bytes", len(tdQuoteBody.GetRtMr2()), rtMr2Size) + } + if len(tdQuoteBody.GetRtMr3()) != rtMr3Size { + return fmt.Errorf("rtMr3 size is %d bytes. Expected %d bytes", len(tdQuoteBody.GetRtMr3()), rtMr3Size) + } + if len(tdQuoteBody.GetReportData()) != reportDataSize { + return fmt.Errorf("reportData size is %d bytes. Expected %d bytes", len(tdQuoteBody.GetReportData()), reportDataSize) + } + return nil +} + +func checkPCKCertificateChain(chain *pb.PCKCertificateChainData) error { + if chain == nil { + return ErrPckCertChainNil + } + if chain.GetCertificateDataType() >= (1 << 16) { + return fmt.Errorf("certification data type expected to be of 2 bytes, got %d", chain.GetCertificateDataType()) + } + if chain.GetCertificateDataType() != pckReportCertificationDataType { + return fmt.Errorf("PCK certificate chain data type invalid, got %d, expected %d", chain.GetCertificateDataType(), pckReportCertificationDataType) + } + if chain.GetSize() != uint32(len(chain.GetPckCertChain())) { + return fmt.Errorf("PCK certificate chain size is %d. Expected size %d", len(chain.GetPckCertChain()), chain.GetSize()) + } + return nil +} + +func checkQeReport(report *pb.EnclaveReport) error { + if report == nil { + return ErrQeReportNil + } + if len(report.GetCpuSvn()) != cpuSvnSize { + return fmt.Errorf("cpuSvn size is %d bytes. Expected %d bytes", len(report.GetCpuSvn()), rtMr3Size) + } + if len(report.GetReserved1()) != reserved1Size { + return fmt.Errorf("reserved1 size is %d bytes. Expected %d bytes", len(report.GetReserved1()), reserved1Size) + } + if len(report.GetAttributes()) != attributesSize { + return fmt.Errorf("attributes size is %d bytes. Expected %d bytes", len(report.GetAttributes()), attributesSize) + } + if len(report.GetMrEnclave()) != mrEnclaveSize { + return fmt.Errorf("mrEnclave size is %d bytes. Expected %d bytes", len(report.GetMrEnclave()), mrEnclaveSize) + } + if len(report.GetReserved2()) != reserved2Size { + return fmt.Errorf("reserved2 size is %d bytes. Expected %d bytes", len(report.GetReserved2()), reserved2Size) + } + if len(report.GetMrSigner()) != mrSignerSize { + return fmt.Errorf("mrSigner size is %d bytes. Expected %d bytes", len(report.GetMrSigner()), mrSignerSize) + } + if len(report.GetReserved3()) != reserved3Size { + return fmt.Errorf("reserved3 size is %d bytes. Expected %d bytes", len(report.GetReserved3()), reserved3Size) + } + if report.GetIsvProdId() >= (1 << 16) { + return fmt.Errorf("isVProdId field size must fit in 2 bytes , got %d", report.GetIsvProdId()) + } + if report.GetIsvSvn() >= (1 << 16) { + return fmt.Errorf("isVSvn field size must fit in 2 bytes , got %d", report.GetIsvSvn()) + } + if len(report.GetReserved4()) != reserved4Size { + return fmt.Errorf("reserved4 size is %d bytes. Expected %d bytes", len(report.GetReserved4()), reserved4Size) + } + if len(report.GetReportData()) != reportDataSize { + return fmt.Errorf("report data size is %d bytes. Expected %d bytes", len(report.GetReportData()), reportDataSize) + } + return nil +} + +func checkQeAuthData(authData *pb.QeAuthData) error { + if authData == nil { + return ErrQeAuthDataNil + } + if authData.GetParsedDataSize() >= (1 << 16) { + return fmt.Errorf("parsed data size field size must fit in 2 bytes , got %d", authData.GetParsedDataSize()) + } + if authData.GetParsedDataSize() != uint32(len(authData.GetData())) { + return fmt.Errorf("parsed data size is %d bytes. Expected %d bytes", len(authData.GetData()), authData.GetParsedDataSize()) + } + return nil +} + +func checkQeReportCertificationData(qeReport *pb.QEReportCertificationData) error { + if qeReport == nil { + return ErrQeReportCertificationDataNil + } + if err := checkQeReport(qeReport.GetQeReport()); err != nil { + return fmt.Errorf("QE Report error: %v", err) + } + if len(qeReport.GetQeReportSignature()) != signatureSize { + return fmt.Errorf("signature size is %d bytes. Expected %d bytes", len(qeReport.GetQeReportSignature()), signatureSize) + } + if err := checkQeAuthData(qeReport.GetQeAuthData()); err != nil { + return fmt.Errorf("QE AuthData error: %v", err) + } + if err := checkPCKCertificateChain(qeReport.GetPckCertificateChainData()); err != nil { + return fmt.Errorf("PCK certificate chain error: %v", err) + } + return nil +} + +func checkCertificationData(certification *pb.CertificationData) error { + if certification == nil { + return ErrCertificationDataNil + } + if certification.GetCertificateDataType() >= (1 << 16) { + return fmt.Errorf("certification data type field size must fit in 2 bytes , got %d", certification.GetCertificateDataType()) + } + if certification.GetCertificateDataType() != qeReportCertificationDataType { + return fmt.Errorf("certification data type invalid, got %d, expected %d", certification.GetCertificateDataType(), qeReportCertificationDataType) + } + if err := checkQeReportCertificationData(certification.GetQeReportCertificationData()); err != nil { + return fmt.Errorf("QE Report certification data error: %v", err) + } + return nil +} + +func checkEcdsa256BitQuoteV4AuthData(signedData *pb.Ecdsa256BitQuoteV4AuthData) error { + if signedData == nil { + return ErrQuoteV4AuthDataNil + } + if len(signedData.GetSignature()) != signatureSize { + return fmt.Errorf("signature size is %d bytes. Expected %d bytes", len(signedData.GetSignature()), signatureSize) + } + if len(signedData.GetEcdsaAttestationKey()) != attestationKeySize { + return fmt.Errorf("ecdsa attestation key size is %d bytes. Expected %d bytes", len(signedData.GetEcdsaAttestationKey()), attestationKeySize) + } + if err := checkCertificationData(signedData.GetCertificationData()); err != nil { + return fmt.Errorf("certification data error: %v", err) + } + + return nil +} + +// CheckQuoteV4 validates a quote protobuf by ensuring all parameters meet their required size +func CheckQuoteV4(quote *pb.QuoteV4) error { + if quote == nil { + return ErrQuoteV4Nil + } + if err := checkHeader(quote.GetHeader()); err != nil { + return fmt.Errorf("QuoteV4 Header error: %v", err) + } + if err := checkTDQuoteBody(quote.GetTdQuoteBody()); err != nil { + return fmt.Errorf("QuoteV4 TD Quote Body error: %v", err) + } + + if err := checkEcdsa256BitQuoteV4AuthData(quote.GetSignedData()); err != nil { + return fmt.Errorf("QuoteV4 AuthData error: %v", err) + } + return nil +} + +// EnclaveReportToAbiBytes translates the EnclaveReport back into its little-endian ABI format +func EnclaveReportToAbiBytes(report *pb.EnclaveReport) ([]byte, error) { + if report == nil { + return nil, ErrQeReportNil + } + if err := checkQeReport(report); err != nil { + return nil, fmt.Errorf("QE Report invalid: %v", err) + } + + data := make([]byte, qeReportSize) + copy(data[qeCPUSvnStart:qeCPUSvnEnd], report.GetCpuSvn()) + binary.LittleEndian.PutUint32(data[qeMiscSelectStart:qeMiscSelectEnd], report.GetMiscSelect()) + copy(data[qeReserved1Start:qeReserved1End], report.GetReserved1()) + copy(data[qeAttributesStart:qeAttributesEnd], report.GetAttributes()) + copy(data[qeMrEnclaveStart:qeMrEnclaveEnd], report.GetMrEnclave()) + copy(data[qeReserved2Start:qeReserved2End], report.GetReserved2()) + copy(data[qeMrSignerStart:qeMrSignerEnd], report.GetMrSigner()) + copy(data[qeReserved3Start:qeReserved3End], report.GetReserved3()) + binary.LittleEndian.PutUint16(data[qeIsvProdIDStart:qeIsvProdIDEnd], uint16(report.GetIsvProdId())) + binary.LittleEndian.PutUint16(data[qeIsvSvnStart:qeIsvSvnEnd], uint16(report.GetIsvSvn())) + copy(data[qeReserved4Start:qeReserved4End], report.GetReserved4()) + copy(data[qeReportDataStart:qeReportDataEnd], report.GetReportData()) + return data, nil +} + +// HeaderToAbiBytes translates the Header back into its little-endian ABI format +func HeaderToAbiBytes(header *pb.Header) ([]byte, error) { + if header == nil { + return nil, ErrHeaderNil + } + if err := checkHeader(header); err != nil { + return nil, fmt.Errorf("header invalid: %v", err) + } + + data := make([]byte, headerSize) + binary.LittleEndian.PutUint16(data[headerVersionStart:headerVersionEnd], uint16(header.GetVersion())) + binary.LittleEndian.PutUint16(data[headerAttestationKeyTypeStart:headerAttestationKeyTypeEnd], uint16(header.GetAttestationKeyType())) + binary.LittleEndian.PutUint32(data[headerTeeTypeStart:headerTeeTypeEnd], (header.GetTeeType())) + copy(data[headerPceSvnStart:headerPceSvnEnd], header.GetPceSvn()) + copy(data[headerQeSvnStart:headerQeSvnEnd], header.GetQeSvn()) + copy(data[headerQeVendorIDStart:headerQeVendorIDEnd], header.GetQeVendorId()) + copy(data[headerUserDataStart:headerUserDataEnd], header.GetUserData()) + + return data, nil + +} + +// TdQuoteBodyToAbiBytes translates the TDQuoteBody back into its little-endian ABI format +func TdQuoteBodyToAbiBytes(tdQuoteBody *pb.TDQuoteBody) ([]byte, error) { + + if tdQuoteBody == nil { + return nil, ErrTDQuoteBodyNil + } + if err := checkTDQuoteBody(tdQuoteBody); err != nil { + return nil, fmt.Errorf("TD quote body invalid: %v", err) + } + + data := make([]byte, tdQuoteBodySize) + copy(data[tdTeeTcbSvnStart:tdTeeTcbSvnEnd], tdQuoteBody.GetTeeTcbSvn()) + copy(data[tdMrSeamStart:tdMrSeamEnd], tdQuoteBody.GetMrSeam()) + copy(data[tdMrSignerSeamStart:tdMrSignerSeamEnd], tdQuoteBody.GetMrSignerSeam()) + copy(data[tdSeamAttributesStart:tdSeamAttributesEnd], tdQuoteBody.GetSeamAttributes()) + copy(data[tdAttributesStart:tdAttributesEnd], tdQuoteBody.GetTdAttributes()) + copy(data[tdXfamStart:tdXfamEnd], tdQuoteBody.GetXfam()) + copy(data[tdMrTdStart:tdMrTdEnd], tdQuoteBody.GetMrTd()) + copy(data[tdMrConfigIDStart:tdMrConfigIDEnd], tdQuoteBody.GetMrConfigId()) + copy(data[tdMrOwnerStart:tdMrOwnerEnd], tdQuoteBody.GetMrOwner()) + copy(data[tdMrOwnerConfigStart:tdMrOwnerConfigEnd], tdQuoteBody.GetMrOwnerConfig()) + copy(data[tdRtMr0Start:tdRtMr0End], tdQuoteBody.GetRtMr0()) + copy(data[tdRtMr1Start:tdRtMr1End], tdQuoteBody.GetRtMr1()) + copy(data[tdRtMr2Start:tdRtMr2End], tdQuoteBody.GetRtMr2()) + copy(data[tdRtMr3Start:tdRtMr3End], tdQuoteBody.GetRtMr3()) + copy(data[tdReportDataStart:tdReportDataEnd], tdQuoteBody.GetReportData()) + return data, nil +} + +func pckCertificateChainToAbiBytes(pckCertificateChain *pb.PCKCertificateChainData) ([]byte, error) { + if pckCertificateChain == nil { + return nil, ErrPckCertChainNil + } + if err := checkPCKCertificateChain(pckCertificateChain); err != nil { + return nil, fmt.Errorf("PCK certificate chain data invalid: %v", err) + } + + data := make([]byte, pckCertificateChainKnownSize+pckCertificateChain.GetSize()) + binary.LittleEndian.PutUint16(data[pckCertChainCertificationDataTypeStart:pckCertChainCertificationDataTypeEnd], uint16(pckCertificateChain.GetCertificateDataType())) + binary.LittleEndian.PutUint32(data[pckCertChainSizeStart:pckCertChainSizeEnd], pckCertificateChain.GetSize()) + copy(data[pckCertChainDataStart:], pckCertificateChain.GetPckCertChain()) + return data, nil +} + +func qeAuthDataToAbiBytes(authData *pb.QeAuthData) ([]byte, error) { + if authData == nil { + return nil, ErrQeAuthDataNil + } + if err := checkQeAuthData(authData); err != nil { + return nil, fmt.Errorf("QE AuthData invalid: %v", err) + } + + data := make([]byte, qeAuthDataKnownSize+authData.GetParsedDataSize()) + binary.LittleEndian.PutUint16(data[authDataParsedDataSizeStart:authDataParsedDataSizeEnd], uint16(authData.GetParsedDataSize())) + copy(data[authDataStart:], authData.GetData()) + return data, nil +} + +func qeReportCertificationDataToAbiBytes(qeReport *pb.QEReportCertificationData) ([]byte, error) { + if qeReport == nil { + return nil, ErrQeReportCertificationDataNil + } + if err := checkQeReportCertificationData(qeReport); err != nil { + return nil, fmt.Errorf("QE Report certification data invalid: %v", err) + } + + data, err := EnclaveReportToAbiBytes(qeReport.GetQeReport()) + if err != nil { + return nil, fmt.Errorf("enclave report to abi bytes conversion failed: %v", err) + } + qeReportSignatureData := clone(qeReport.GetQeReportSignature()) + data = append(data, qeReportSignatureData...) + qeAuthData, err := qeAuthDataToAbiBytes(qeReport.GetQeAuthData()) + if err != nil { + return nil, fmt.Errorf("QE AuthData to abi bytes conversion failed: %v", err) + } + data = append(data, qeAuthData...) + + pckCertificateChainData, err := pckCertificateChainToAbiBytes(qeReport.GetPckCertificateChainData()) + if err != nil { + return nil, fmt.Errorf("PCK certificate chain to abi bytes conversion failed: %v", err) + } + data = append(data, pckCertificateChainData...) + return data, nil +} + +func certificationDataToAbiBytes(certification *pb.CertificationData) ([]byte, error) { + if certification == nil { + return nil, ErrCertificationDataNil + } + if err := checkCertificationData(certification); err != nil { + return nil, fmt.Errorf("certification data invalid: %v", err) + } + data := make([]byte, certificationDataKnownSize) + binary.LittleEndian.PutUint16(data[certificateDataTypeStart:certificateDataTypeEnd], uint16(certification.GetCertificateDataType())) + binary.LittleEndian.PutUint32(data[certificateSizeStart:certificateSizeEnd], certification.GetSize()) + + certificationData, err := qeReportCertificationDataToAbiBytes(certification.GetQeReportCertificationData()) + if err != nil { + return nil, fmt.Errorf("QE Report certification data to abi bytes conversion failed: %v", err) + } + data = append(data, certificationData...) + return data, nil +} + +func signedDataToAbiBytes(signedData *pb.Ecdsa256BitQuoteV4AuthData) ([]byte, error) { + if signedData == nil { + return nil, ErrQuoteV4AuthDataNil + } + if err := checkEcdsa256BitQuoteV4AuthData(signedData); err != nil { + return nil, fmt.Errorf("QuoteV4 AuthData invalid: %v", err) + } + data := make([]byte, quoteV4AuthDataKnownSize) + copy(data[signedDataSignatureStart:signedDataSignatureEnd], signedData.GetSignature()) + copy(data[signedDataAttestationKeyStart:signedDataAttestationKeyEnd], signedData.GetEcdsaAttestationKey()) + + certificationData, err := certificationDataToAbiBytes(signedData.GetCertificationData()) + if err != nil { + return nil, fmt.Errorf("signed data certification data to abi bytes conversion failed: %v", err) + } + data = append(data, certificationData...) + return data, nil +} + +// QuoteToAbiBytes translates the QuoteV4 back into its little-endian ABI format +func QuoteToAbiBytes(quote *pb.QuoteV4) ([]byte, error) { + if quote == nil { + return nil, ErrQuoteV4Nil + } + if err := CheckQuoteV4(quote); err != nil { + return nil, fmt.Errorf("QuoteV4 invalid: %v", err) + } + var data []byte + + headerData, err := HeaderToAbiBytes(quote.GetHeader()) + if err != nil { + return nil, fmt.Errorf("header to abi bytes conversion failed: %v", err) + } + data = append(data, headerData...) + + tdReportData, err := TdQuoteBodyToAbiBytes(quote.GetTdQuoteBody()) + if err != nil { + return nil, fmt.Errorf("TD quote body to abi bytes conversion failed: %v", err) + } + data = append(data, tdReportData...) + + signedDataSizeBytes := make([]byte, 0x04) + binary.LittleEndian.PutUint32(signedDataSizeBytes[0x00:0x04], quote.GetSignedDataSize()) + data = append(data, signedDataSizeBytes...) + + signedData, err := signedDataToAbiBytes(quote.GetSignedData()) + if err != nil { + return nil, fmt.Errorf("signed data to abi bytes conversion failed: %v", err) + } + data = append(data, signedData...) + + if quote.GetExtraBytes() != nil { + data = append(data, quote.GetExtraBytes()...) + } + return data, nil +} + +// SignatureToDER converts the signature to DER format +func SignatureToDER(x []byte) ([]byte, error) { + if len(x) != signatureSize { + return nil, fmt.Errorf("signature size is %d bytes. Expected %d bytes", len(x), signatureSize) + } + var b cryptobyte.Builder + b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) { + b.AddASN1BigInt(new(big.Int).SetBytes(ecdsaGetR(x))) + b.AddASN1BigInt(new(big.Int).SetBytes(ecdsaGetS(x))) + }) + return b.Bytes() +} +func ecdsaGetR(signature []byte) []byte { + return signature[0x0:0x20] +} +func ecdsaGetS(signature []byte) []byte { + return signature[0x20:0x40] +} diff --git a/abi/abi_test.go b/abi/abi_test.go new file mode 100644 index 0000000..f567c51 --- /dev/null +++ b/abi/abi_test.go @@ -0,0 +1,145 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package abi + +import ( + "bytes" + "testing" + + pb "github.com/google/go-tdx-guest/proto/tdx" + test "github.com/google/go-tdx-guest/testing/testdata" +) + +func TestQuoteToProto(t *testing.T) { + _, err := QuoteToProto(test.RawQuote) + if err != nil { + t.Fatal(err) + } +} + +func TestQuoteToAbiBytes(t *testing.T) { + quote, err := QuoteToProto(test.RawQuote) + if err != nil { + t.Fatal(err) + } + rawQuote, err := QuoteToAbiBytes(quote) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(test.RawQuote, rawQuote) { + t.Errorf("raw quote bytes got %v. Expected %v", rawQuote, test.RawQuote) + } +} + +func TestNilToAbiBytesConversions(t *testing.T) { + + if _, err := QuoteToAbiBytes(nil); err != ErrQuoteV4Nil { + t.Error(err) + } + if _, err := signedDataToAbiBytes(nil); err != ErrQuoteV4AuthDataNil { + t.Error(err) + } + if _, err := certificationDataToAbiBytes(nil); err != ErrCertificationDataNil { + t.Error(err) + } + if _, err := qeReportCertificationDataToAbiBytes(nil); err != ErrQeReportCertificationDataNil { + t.Error(err) + } + if _, err := qeAuthDataToAbiBytes(nil); err != ErrQeAuthDataNil { + t.Error(err) + } + if _, err := pckCertificateChainToAbiBytes(nil); err != ErrPckCertChainNil { + t.Error(err) + } + if _, err := TdQuoteBodyToAbiBytes(nil); err != ErrTDQuoteBodyNil { + t.Error(err) + } + if _, err := HeaderToAbiBytes(nil); err != ErrHeaderNil { + t.Error(err) + } + if _, err := EnclaveReportToAbiBytes(nil); err != ErrQeReportNil { + t.Error(err) + } +} + +func TestInvalidConversionsToAbiBytes(t *testing.T) { + expectedErrors := []string{ + "QuoteV4 invalid: QuoteV4 Header error: header is empty", + "QuoteV4 AuthData invalid: signature size is 0 bytes. Expected 64 bytes", + "certification data invalid: certification data type invalid, got 0, expected 6", + "certification data invalid: certification data type invalid, got 7, expected 6", + "certification data invalid: QE Report certification data error: QE Report certification data is empty", + "QE Report certification data invalid: QE Report error: QE Report is empty", + "QE AuthData invalid: parsed data size is 0 bytes. Expected 1 bytes", + "PCK certificate chain data invalid: PCK certificate chain data type invalid, got 0, expected 5", + "PCK certificate chain data invalid: PCK certificate chain data type invalid, got 7, expected 5", + "PCK certificate chain data invalid: PCK certificate chain size is 0. Expected size 2", + "TD quote body invalid: teeTcbSvn size is 0 bytes. Expected 16 bytes", + "header invalid: version 0 not supported", + "header invalid: version 1 not supported", + "header invalid: attestation key type not supported", + "header invalid: TEE type is not TDX", + "QE Report invalid: cpuSvn size is 0 bytes. Expected 48 bytes", + } + if _, err := QuoteToAbiBytes(&pb.QuoteV4{}); err == nil || err.Error() != expectedErrors[0] { + t.Errorf("error found: %v, want error: %s", err, expectedErrors[0]) + } + if _, err := signedDataToAbiBytes(&pb.Ecdsa256BitQuoteV4AuthData{}); err == nil || err.Error() != expectedErrors[1] { + t.Errorf("error found: %v, want error: %s", err, expectedErrors[1]) + } + if _, err := certificationDataToAbiBytes(&pb.CertificationData{}); err == nil || err.Error() != expectedErrors[2] { + t.Errorf("error found: %v, want error: %s", err, expectedErrors[2]) + } + if _, err := certificationDataToAbiBytes(&pb.CertificationData{CertificateDataType: 7}); err == nil || err.Error() != expectedErrors[3] { + t.Errorf("error found: %v, want error: %s", err, expectedErrors[3]) + } + if _, err := certificationDataToAbiBytes(&pb.CertificationData{CertificateDataType: qeReportCertificationDataType, Size: 2}); err == nil || err.Error() != expectedErrors[4] { + t.Errorf("error found: %v, want error: %s", err, expectedErrors[4]) + } + if _, err := qeReportCertificationDataToAbiBytes(&pb.QEReportCertificationData{}); err == nil || err.Error() != expectedErrors[5] { + t.Errorf("error found: %v, want error: %s", err, expectedErrors[5]) + } + if _, err := qeAuthDataToAbiBytes(&pb.QeAuthData{ParsedDataSize: 1}); err == nil || err.Error() != expectedErrors[6] { + + t.Errorf("error found: %v, want error: %s", err, expectedErrors[6]) + } + if _, err := pckCertificateChainToAbiBytes(&pb.PCKCertificateChainData{}); err == nil || err.Error() != expectedErrors[7] { + t.Errorf("error found: %v, want error: %s", err, expectedErrors[7]) + } + if _, err := pckCertificateChainToAbiBytes(&pb.PCKCertificateChainData{CertificateDataType: 7}); err == nil || err.Error() != expectedErrors[8] { + t.Errorf("error found: %v, want error: %s", err, expectedErrors[8]) + } + if _, err := pckCertificateChainToAbiBytes(&pb.PCKCertificateChainData{CertificateDataType: pckReportCertificationDataType, Size: 2}); err == nil || err.Error() != expectedErrors[9] { + t.Errorf("error found: %v, want error: %s", err, expectedErrors[9]) + } + if _, err := TdQuoteBodyToAbiBytes(&pb.TDQuoteBody{}); err == nil || err.Error() != expectedErrors[10] { + t.Errorf("error found: %v, want error: %s", err, expectedErrors[10]) + } + if _, err := HeaderToAbiBytes(&pb.Header{}); err == nil || err.Error() != expectedErrors[11] { + t.Errorf("error found: %v, want error: %s", err, expectedErrors[11]) + } + if _, err := HeaderToAbiBytes(&pb.Header{Version: 1}); err == nil || err.Error() != expectedErrors[12] { + t.Errorf("error found: %v, want error: %s", err, expectedErrors[12]) + } + if _, err := HeaderToAbiBytes(&pb.Header{Version: QuoteVersion, AttestationKeyType: 1}); err == nil || err.Error() != expectedErrors[13] { + t.Errorf("error found: %v, want error: %s", err, expectedErrors[13]) + } + if _, err := HeaderToAbiBytes(&pb.Header{Version: QuoteVersion, AttestationKeyType: AttestationKeyType, TeeType: 0x01}); err == nil || err.Error() != expectedErrors[14] { + t.Errorf("error found: %v, want error: %s", err, expectedErrors[14]) + } + if _, err := EnclaveReportToAbiBytes(&pb.EnclaveReport{}); err == nil || err.Error() != expectedErrors[15] { + t.Errorf("error found: %v, want error: %s", err, expectedErrors[15]) + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5c833d9 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/google/go-tdx-guest + +go 1.21 + +require ( + golang.org/x/crypto v0.10.0 + google.golang.org/protobuf v1.31.0 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..6f08b18 --- /dev/null +++ b/go.sum @@ -0,0 +1,10 @@ +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/proto/doc.go b/proto/doc.go new file mode 100644 index 0000000..2833001 --- /dev/null +++ b/proto/doc.go @@ -0,0 +1,49 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package proto contains protocol buffers that are exchanged between the client +// and server, as well as convenience configuration definitions for tools. +// +// # Generating Protocol Buffer Code +// +// Anytime the Protocol Buffer definitions change, the generated Go code must be +// regenerated. This can be done with "go generate". Just run: +// +// go generate ./... +// +// Upstream documentation: +// https://developers.google.com/protocol-buffers/docs/reference/go-generated +// +// # Code Generation Dependencies +// +// To generate the Go code, your system must have "protoc" installed. See: +// https://github.com/protocolbuffers/protobuf#protocol-compiler-installation +// +// The "protoc-gen-go" tool must also be installed. To install it, run: +// +// go install google.golang.org/protobuf/cmd/protoc-gen-go +// +// If you see a 'protoc-gen-go: program not found or is not executable' error +// for the 'go generate' command, run the following: +// +// echo 'export PATH=$PATH:$GOPATH/bin' >> $HOME/.bashrc +// source $HOME/.bashrc +// +// If you see 'google/protobuf/wrappers.proto not found', then you need to +// similarly set your PROTOC_INSTALL_DIR environment variable to the protoc +// installation directory which should have the "well-known types" in the +// include subdirectory. +package proto + +//go:generate protoc -I$PROTOC_INSTALL_DIR/include -I=. --go_out=. --go_opt=module=github.com/google/go-tdx-guest/proto tdx.proto diff --git a/proto/tdx.proto b/proto/tdx.proto new file mode 100644 index 0000000..418603e --- /dev/null +++ b/proto/tdx.proto @@ -0,0 +1,165 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +// Package tdx represents a TDX attestation quote. +package tdx; + +option go_package = "github.com/google/go-tdx-guest/proto/tdx"; + +message QuoteV4 { + // Header of quote structure + Header header = 1; // should be 48 bytes + + // TD report by which quote is generated + TDQuoteBody td_quote_body = 2; // should be 584 bytes + + // Size of the Quote Signature Data structure + uint32 signed_data_size = 3; + + // Quote Signature Data structure. + Ecdsa256BitQuoteV4AuthData signed_data = + 4; // The size should be same as signed_data_size + + // Extra bytes included to fill the quote buffer + bytes extra_bytes = 5; // These trailing bytes can be ignored +} + +message Header { + // Version 4 supported + uint32 version = 1; + + // Type of attestation key used by quoting enclave + // Values : + // 2 (ECDSA-256-with-P-256 curve) + // 3 (ECDSA-384-with-P-384 curve) (Currently not supported) + uint32 attestation_key_type = 2; + + // TEE for this attestation + // TDX : 0x00000081 + uint32 tee_type = 3; + + bytes qe_svn = 4; // should be 2 bytes + bytes pce_svn = 5; // should be 2 bytes + + // Unique vendor id of QE vendor + bytes qe_vendor_id = 6; // should be 16 bytes + + // Custom user defined data + bytes user_data = 7; // should be 20 bytes +} + +message TDQuoteBody { + bytes tee_tcb_svn = 1; // should be 16 bytes + bytes mr_seam = 2; // should be 48 bytes + bytes mr_signer_seam = 3; // should be 48 bytes + bytes seam_attributes = 4; // should be 8 bytes + bytes td_attributes = 5; // should be 8 bytes + bytes xfam = 6; // should be 8 bytes + bytes mr_td = 7; // should be 48 bytes + bytes mr_config_id = 8; // should be 48 bytes + bytes mr_owner = 9; // should be 48 bytes + bytes mr_owner_config = 10; // should be 48 bytes + bytes rt_mr0 = 11; // should be 48 bytes + bytes rt_mr1 = 12; // should be 48 bytes + bytes rt_mr2 = 13; // should be 48 bytes + bytes rt_mr3 = 14; // should be 48 bytes + bytes report_data = 15; // should be 64 bytes +} + +message Ecdsa256BitQuoteV4AuthData { + // The ECDSA 256-bit signature. + bytes signature = 1; // should be 64 bytes + + // The ECDSA 256-bit public key of the attestation key. + bytes ecdsa_attestation_key = 2; // should be 64 bytes + + // The certification data. + CertificationData certification_data = 3; +} + +message CertificationData { + // Supported values: + // - 1 (PCK identifier: PPID in plain text, CPUSVN and PCESVN) + // - 2 (PCK identifier: PPID encrypted using RSA-2048-OAEP, CPUSVN and PCESVN) + // - 3 (PCK identifier: PPID encrypted using RSA-3072-OAEP, CPUSVN and PCESVN) + // - 4 (PCK Leaf Certificate in plain text, currently not supported) + // - 5 (Concatenated PCK Cert Chain) + // - 6 (QE Report Certification Data) + // - 7 (PLATFORM_MANIFEST, currently not supported) + uint32 certificate_data_type = 1; + + // Size of Certification Data field + uint32 size = 2; + + // Certification Data Type: + // - 1: Byte array that contains concatenation of PPID, CPUSVN,PCESVN (LE), + // PCEID (LE). + // - 2: Byte array that contains concatenation of PPID encrypted using + // RSA-2048-OAEP, CPUSVN, PCESVN (LE), PCEID (LE). + // - 3: Byte array that contains concatenation of PPID encrypted using + // RSA-3072-OAEP, CPUSVN, PCESVN (LE), PCEID (LE). + // - 4: PCK Leaf Certificate + // - 5: Concatenated PCK Cert Chain (PEM formatted). PCK LeafCert|| + // Intermediate CA Cert|| Root CA Cert + //- 6: QE Report Certification Data + //- 7: PLATFORM_MANIFEST (currently not supported) + + QEReportCertificationData qe_report_certification_data = 3; +} + +message QEReportCertificationData { + EnclaveReport qe_report = 1; + bytes qe_report_signature = 2; // should be 64 bytes + QeAuthData qe_auth_data = 3; + PCKCertificateChainData pck_certificate_chain_data = 4; +} +message PCKCertificateChainData { + // Supported values: + // - 1 (PCK identifier: PPID in plain text, CPUSVN and PCESVN) + // - 2 (PCK identifier: PPID encrypted using RSA-2048-OAEP, CPUSVN and PCESVN) + // - 3 (PCK identifier: PPID encrypted using RSA-3072-OAEP, CPUSVN and PCESVN) + // - 4 (PCK Leaf Certificate in plain text, currently not supported) + // - 5 (Concatenated PCK Cert Chain) + // - 6 (QE Report Certification Data) + // - 7 (PLATFORM_MANIFEST, currently not supported) + uint32 certificate_data_type = 1; + + // Size of Certification Data field + uint32 size = 2; + bytes pck_cert_chain = 3; +} + +message QeAuthData { + // The parsed data size. + uint32 parsed_data_size = 1; // should be 2 bytes + // The data. + bytes data = 2; +} + +message EnclaveReport { + bytes cpu_svn = 1; // should be 16 bytes + uint32 misc_select = 2; // should be 4 bytes + bytes reserved1 = 3; // should be 28 bytes + bytes attributes = 4; // should be 16 bytes + bytes mr_enclave = 5; // should be 32 bytes + bytes reserved2 = 6; // should be 32 bytes + bytes mr_signer = 7; // should be 32 bytes + bytes reserved3 = 8; // should be 96 bytes + uint32 isv_prod_id = 9; // should be 2 bytes + uint32 isv_svn = 10; // should be 2 bytes + bytes reserved4 = 11; // should be 60 bytes + bytes report_data = 12; // should be 64 bytes +} diff --git a/proto/tdx/tdx.pb.go b/proto/tdx/tdx.pb.go new file mode 100644 index 0000000..181eac5 --- /dev/null +++ b/proto/tdx/tdx.pb.go @@ -0,0 +1,1179 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v3.21.12 +// source: tdx.proto + +// Package tdx represents a TDX attestation quote. + +package tdx + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type QuoteV4 struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Header of quote structure + Header *Header `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` // should be 48 bytes + // TD report by which quote is generated + TdQuoteBody *TDQuoteBody `protobuf:"bytes,2,opt,name=td_quote_body,json=tdQuoteBody,proto3" json:"td_quote_body,omitempty"` // should be 584 bytes + // Size of the Quote Signature Data structure + SignedDataSize uint32 `protobuf:"varint,3,opt,name=signed_data_size,json=signedDataSize,proto3" json:"signed_data_size,omitempty"` + // Quote Signature Data structure. + SignedData *Ecdsa256BitQuoteV4AuthData `protobuf:"bytes,4,opt,name=signed_data,json=signedData,proto3" json:"signed_data,omitempty"` // The size should be same as signed_data_size + // Extra bytes included to fill the quote buffer + ExtraBytes []byte `protobuf:"bytes,5,opt,name=extra_bytes,json=extraBytes,proto3" json:"extra_bytes,omitempty"` // These trailing bytes can be ignored +} + +func (x *QuoteV4) Reset() { + *x = QuoteV4{} + if protoimpl.UnsafeEnabled { + mi := &file_tdx_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QuoteV4) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QuoteV4) ProtoMessage() {} + +func (x *QuoteV4) ProtoReflect() protoreflect.Message { + mi := &file_tdx_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QuoteV4.ProtoReflect.Descriptor instead. +func (*QuoteV4) Descriptor() ([]byte, []int) { + return file_tdx_proto_rawDescGZIP(), []int{0} +} + +func (x *QuoteV4) GetHeader() *Header { + if x != nil { + return x.Header + } + return nil +} + +func (x *QuoteV4) GetTdQuoteBody() *TDQuoteBody { + if x != nil { + return x.TdQuoteBody + } + return nil +} + +func (x *QuoteV4) GetSignedDataSize() uint32 { + if x != nil { + return x.SignedDataSize + } + return 0 +} + +func (x *QuoteV4) GetSignedData() *Ecdsa256BitQuoteV4AuthData { + if x != nil { + return x.SignedData + } + return nil +} + +func (x *QuoteV4) GetExtraBytes() []byte { + if x != nil { + return x.ExtraBytes + } + return nil +} + +type Header struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Version 4 supported + Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + // Type of attestation key used by quoting enclave + // Values : + // 2 (ECDSA-256-with-P-256 curve) + // 3 (ECDSA-384-with-P-384 curve) (Currently not supported) + AttestationKeyType uint32 `protobuf:"varint,2,opt,name=attestation_key_type,json=attestationKeyType,proto3" json:"attestation_key_type,omitempty"` + // TEE for this attestation + // TDX : 0x00000081 + TeeType uint32 `protobuf:"varint,3,opt,name=tee_type,json=teeType,proto3" json:"tee_type,omitempty"` + QeSvn []byte `protobuf:"bytes,4,opt,name=qe_svn,json=qeSvn,proto3" json:"qe_svn,omitempty"` // should be 2 bytes + PceSvn []byte `protobuf:"bytes,5,opt,name=pce_svn,json=pceSvn,proto3" json:"pce_svn,omitempty"` // should be 2 bytes + // Unique vendor id of QE vendor + QeVendorId []byte `protobuf:"bytes,6,opt,name=qe_vendor_id,json=qeVendorId,proto3" json:"qe_vendor_id,omitempty"` // should be 16 bytes + // Custom user defined data + UserData []byte `protobuf:"bytes,7,opt,name=user_data,json=userData,proto3" json:"user_data,omitempty"` // should be 20 bytes +} + +func (x *Header) Reset() { + *x = Header{} + if protoimpl.UnsafeEnabled { + mi := &file_tdx_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Header) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Header) ProtoMessage() {} + +func (x *Header) ProtoReflect() protoreflect.Message { + mi := &file_tdx_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Header.ProtoReflect.Descriptor instead. +func (*Header) Descriptor() ([]byte, []int) { + return file_tdx_proto_rawDescGZIP(), []int{1} +} + +func (x *Header) GetVersion() uint32 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *Header) GetAttestationKeyType() uint32 { + if x != nil { + return x.AttestationKeyType + } + return 0 +} + +func (x *Header) GetTeeType() uint32 { + if x != nil { + return x.TeeType + } + return 0 +} + +func (x *Header) GetQeSvn() []byte { + if x != nil { + return x.QeSvn + } + return nil +} + +func (x *Header) GetPceSvn() []byte { + if x != nil { + return x.PceSvn + } + return nil +} + +func (x *Header) GetQeVendorId() []byte { + if x != nil { + return x.QeVendorId + } + return nil +} + +func (x *Header) GetUserData() []byte { + if x != nil { + return x.UserData + } + return nil +} + +type TDQuoteBody struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TeeTcbSvn []byte `protobuf:"bytes,1,opt,name=tee_tcb_svn,json=teeTcbSvn,proto3" json:"tee_tcb_svn,omitempty"` // should be 16 bytes + MrSeam []byte `protobuf:"bytes,2,opt,name=mr_seam,json=mrSeam,proto3" json:"mr_seam,omitempty"` // should be 48 bytes + MrSignerSeam []byte `protobuf:"bytes,3,opt,name=mr_signer_seam,json=mrSignerSeam,proto3" json:"mr_signer_seam,omitempty"` // should be 48 bytes + SeamAttributes []byte `protobuf:"bytes,4,opt,name=seam_attributes,json=seamAttributes,proto3" json:"seam_attributes,omitempty"` // should be 8 bytes + TdAttributes []byte `protobuf:"bytes,5,opt,name=td_attributes,json=tdAttributes,proto3" json:"td_attributes,omitempty"` // should be 8 bytes + Xfam []byte `protobuf:"bytes,6,opt,name=xfam,proto3" json:"xfam,omitempty"` // should be 8 bytes + MrTd []byte `protobuf:"bytes,7,opt,name=mr_td,json=mrTd,proto3" json:"mr_td,omitempty"` // should be 48 bytes + MrConfigId []byte `protobuf:"bytes,8,opt,name=mr_config_id,json=mrConfigId,proto3" json:"mr_config_id,omitempty"` // should be 48 bytes + MrOwner []byte `protobuf:"bytes,9,opt,name=mr_owner,json=mrOwner,proto3" json:"mr_owner,omitempty"` // should be 48 bytes + MrOwnerConfig []byte `protobuf:"bytes,10,opt,name=mr_owner_config,json=mrOwnerConfig,proto3" json:"mr_owner_config,omitempty"` // should be 48 bytes + RtMr0 []byte `protobuf:"bytes,11,opt,name=rt_mr0,json=rtMr0,proto3" json:"rt_mr0,omitempty"` // should be 48 bytes + RtMr1 []byte `protobuf:"bytes,12,opt,name=rt_mr1,json=rtMr1,proto3" json:"rt_mr1,omitempty"` // should be 48 bytes + RtMr2 []byte `protobuf:"bytes,13,opt,name=rt_mr2,json=rtMr2,proto3" json:"rt_mr2,omitempty"` // should be 48 bytes + RtMr3 []byte `protobuf:"bytes,14,opt,name=rt_mr3,json=rtMr3,proto3" json:"rt_mr3,omitempty"` // should be 48 bytes + ReportData []byte `protobuf:"bytes,15,opt,name=report_data,json=reportData,proto3" json:"report_data,omitempty"` // should be 64 bytes +} + +func (x *TDQuoteBody) Reset() { + *x = TDQuoteBody{} + if protoimpl.UnsafeEnabled { + mi := &file_tdx_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TDQuoteBody) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TDQuoteBody) ProtoMessage() {} + +func (x *TDQuoteBody) ProtoReflect() protoreflect.Message { + mi := &file_tdx_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TDQuoteBody.ProtoReflect.Descriptor instead. +func (*TDQuoteBody) Descriptor() ([]byte, []int) { + return file_tdx_proto_rawDescGZIP(), []int{2} +} + +func (x *TDQuoteBody) GetTeeTcbSvn() []byte { + if x != nil { + return x.TeeTcbSvn + } + return nil +} + +func (x *TDQuoteBody) GetMrSeam() []byte { + if x != nil { + return x.MrSeam + } + return nil +} + +func (x *TDQuoteBody) GetMrSignerSeam() []byte { + if x != nil { + return x.MrSignerSeam + } + return nil +} + +func (x *TDQuoteBody) GetSeamAttributes() []byte { + if x != nil { + return x.SeamAttributes + } + return nil +} + +func (x *TDQuoteBody) GetTdAttributes() []byte { + if x != nil { + return x.TdAttributes + } + return nil +} + +func (x *TDQuoteBody) GetXfam() []byte { + if x != nil { + return x.Xfam + } + return nil +} + +func (x *TDQuoteBody) GetMrTd() []byte { + if x != nil { + return x.MrTd + } + return nil +} + +func (x *TDQuoteBody) GetMrConfigId() []byte { + if x != nil { + return x.MrConfigId + } + return nil +} + +func (x *TDQuoteBody) GetMrOwner() []byte { + if x != nil { + return x.MrOwner + } + return nil +} + +func (x *TDQuoteBody) GetMrOwnerConfig() []byte { + if x != nil { + return x.MrOwnerConfig + } + return nil +} + +func (x *TDQuoteBody) GetRtMr0() []byte { + if x != nil { + return x.RtMr0 + } + return nil +} + +func (x *TDQuoteBody) GetRtMr1() []byte { + if x != nil { + return x.RtMr1 + } + return nil +} + +func (x *TDQuoteBody) GetRtMr2() []byte { + if x != nil { + return x.RtMr2 + } + return nil +} + +func (x *TDQuoteBody) GetRtMr3() []byte { + if x != nil { + return x.RtMr3 + } + return nil +} + +func (x *TDQuoteBody) GetReportData() []byte { + if x != nil { + return x.ReportData + } + return nil +} + +type Ecdsa256BitQuoteV4AuthData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The ECDSA 256-bit signature. + Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` // should be 64 bytes + // The ECDSA 256-bit public key of the attestation key. + EcdsaAttestationKey []byte `protobuf:"bytes,2,opt,name=ecdsa_attestation_key,json=ecdsaAttestationKey,proto3" json:"ecdsa_attestation_key,omitempty"` // should be 64 bytes + // The certification data. + CertificationData *CertificationData `protobuf:"bytes,3,opt,name=certification_data,json=certificationData,proto3" json:"certification_data,omitempty"` +} + +func (x *Ecdsa256BitQuoteV4AuthData) Reset() { + *x = Ecdsa256BitQuoteV4AuthData{} + if protoimpl.UnsafeEnabled { + mi := &file_tdx_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Ecdsa256BitQuoteV4AuthData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Ecdsa256BitQuoteV4AuthData) ProtoMessage() {} + +func (x *Ecdsa256BitQuoteV4AuthData) ProtoReflect() protoreflect.Message { + mi := &file_tdx_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Ecdsa256BitQuoteV4AuthData.ProtoReflect.Descriptor instead. +func (*Ecdsa256BitQuoteV4AuthData) Descriptor() ([]byte, []int) { + return file_tdx_proto_rawDescGZIP(), []int{3} +} + +func (x *Ecdsa256BitQuoteV4AuthData) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + +func (x *Ecdsa256BitQuoteV4AuthData) GetEcdsaAttestationKey() []byte { + if x != nil { + return x.EcdsaAttestationKey + } + return nil +} + +func (x *Ecdsa256BitQuoteV4AuthData) GetCertificationData() *CertificationData { + if x != nil { + return x.CertificationData + } + return nil +} + +type CertificationData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Supported values: + // + // - 1 (PCK identifier: PPID in plain text, CPUSVN and PCESVN) + // - 2 (PCK identifier: PPID encrypted using RSA-2048-OAEP, CPUSVN and PCESVN) + // - 3 (PCK identifier: PPID encrypted using RSA-3072-OAEP, CPUSVN and PCESVN) + // - 4 (PCK Leaf Certificate in plain text, currently not supported) + // - 5 (Concatenated PCK Cert Chain) + // - 6 (QE Report Certification Data) + // - 7 (PLATFORM_MANIFEST, currently not supported) + CertificateDataType uint32 `protobuf:"varint,1,opt,name=certificate_data_type,json=certificateDataType,proto3" json:"certificate_data_type,omitempty"` + // Size of Certification Data field + Size uint32 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"` + QeReportCertificationData *QEReportCertificationData `protobuf:"bytes,3,opt,name=qe_report_certification_data,json=qeReportCertificationData,proto3" json:"qe_report_certification_data,omitempty"` +} + +func (x *CertificationData) Reset() { + *x = CertificationData{} + if protoimpl.UnsafeEnabled { + mi := &file_tdx_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CertificationData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CertificationData) ProtoMessage() {} + +func (x *CertificationData) ProtoReflect() protoreflect.Message { + mi := &file_tdx_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CertificationData.ProtoReflect.Descriptor instead. +func (*CertificationData) Descriptor() ([]byte, []int) { + return file_tdx_proto_rawDescGZIP(), []int{4} +} + +func (x *CertificationData) GetCertificateDataType() uint32 { + if x != nil { + return x.CertificateDataType + } + return 0 +} + +func (x *CertificationData) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *CertificationData) GetQeReportCertificationData() *QEReportCertificationData { + if x != nil { + return x.QeReportCertificationData + } + return nil +} + +type QEReportCertificationData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + QeReport *EnclaveReport `protobuf:"bytes,1,opt,name=qe_report,json=qeReport,proto3" json:"qe_report,omitempty"` + QeReportSignature []byte `protobuf:"bytes,2,opt,name=qe_report_signature,json=qeReportSignature,proto3" json:"qe_report_signature,omitempty"` // should be 64 bytes + QeAuthData *QeAuthData `protobuf:"bytes,3,opt,name=qe_auth_data,json=qeAuthData,proto3" json:"qe_auth_data,omitempty"` + PckCertificateChainData *PCKCertificateChainData `protobuf:"bytes,4,opt,name=pck_certificate_chain_data,json=pckCertificateChainData,proto3" json:"pck_certificate_chain_data,omitempty"` +} + +func (x *QEReportCertificationData) Reset() { + *x = QEReportCertificationData{} + if protoimpl.UnsafeEnabled { + mi := &file_tdx_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QEReportCertificationData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QEReportCertificationData) ProtoMessage() {} + +func (x *QEReportCertificationData) ProtoReflect() protoreflect.Message { + mi := &file_tdx_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QEReportCertificationData.ProtoReflect.Descriptor instead. +func (*QEReportCertificationData) Descriptor() ([]byte, []int) { + return file_tdx_proto_rawDescGZIP(), []int{5} +} + +func (x *QEReportCertificationData) GetQeReport() *EnclaveReport { + if x != nil { + return x.QeReport + } + return nil +} + +func (x *QEReportCertificationData) GetQeReportSignature() []byte { + if x != nil { + return x.QeReportSignature + } + return nil +} + +func (x *QEReportCertificationData) GetQeAuthData() *QeAuthData { + if x != nil { + return x.QeAuthData + } + return nil +} + +func (x *QEReportCertificationData) GetPckCertificateChainData() *PCKCertificateChainData { + if x != nil { + return x.PckCertificateChainData + } + return nil +} + +type PCKCertificateChainData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Supported values: + // + // - 1 (PCK identifier: PPID in plain text, CPUSVN and PCESVN) + // - 2 (PCK identifier: PPID encrypted using RSA-2048-OAEP, CPUSVN and PCESVN) + // - 3 (PCK identifier: PPID encrypted using RSA-3072-OAEP, CPUSVN and PCESVN) + // - 4 (PCK Leaf Certificate in plain text, currently not supported) + // - 5 (Concatenated PCK Cert Chain) + // - 6 (QE Report Certification Data) + // - 7 (PLATFORM_MANIFEST, currently not supported) + CertificateDataType uint32 `protobuf:"varint,1,opt,name=certificate_data_type,json=certificateDataType,proto3" json:"certificate_data_type,omitempty"` + // Size of Certification Data field + Size uint32 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"` + PckCertChain []byte `protobuf:"bytes,3,opt,name=pck_cert_chain,json=pckCertChain,proto3" json:"pck_cert_chain,omitempty"` +} + +func (x *PCKCertificateChainData) Reset() { + *x = PCKCertificateChainData{} + if protoimpl.UnsafeEnabled { + mi := &file_tdx_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PCKCertificateChainData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PCKCertificateChainData) ProtoMessage() {} + +func (x *PCKCertificateChainData) ProtoReflect() protoreflect.Message { + mi := &file_tdx_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PCKCertificateChainData.ProtoReflect.Descriptor instead. +func (*PCKCertificateChainData) Descriptor() ([]byte, []int) { + return file_tdx_proto_rawDescGZIP(), []int{6} +} + +func (x *PCKCertificateChainData) GetCertificateDataType() uint32 { + if x != nil { + return x.CertificateDataType + } + return 0 +} + +func (x *PCKCertificateChainData) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *PCKCertificateChainData) GetPckCertChain() []byte { + if x != nil { + return x.PckCertChain + } + return nil +} + +type QeAuthData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The parsed data size. + ParsedDataSize uint32 `protobuf:"varint,1,opt,name=parsed_data_size,json=parsedDataSize,proto3" json:"parsed_data_size,omitempty"` // should be 2 bytes + // The data. + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *QeAuthData) Reset() { + *x = QeAuthData{} + if protoimpl.UnsafeEnabled { + mi := &file_tdx_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QeAuthData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QeAuthData) ProtoMessage() {} + +func (x *QeAuthData) ProtoReflect() protoreflect.Message { + mi := &file_tdx_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QeAuthData.ProtoReflect.Descriptor instead. +func (*QeAuthData) Descriptor() ([]byte, []int) { + return file_tdx_proto_rawDescGZIP(), []int{7} +} + +func (x *QeAuthData) GetParsedDataSize() uint32 { + if x != nil { + return x.ParsedDataSize + } + return 0 +} + +func (x *QeAuthData) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +type EnclaveReport struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CpuSvn []byte `protobuf:"bytes,1,opt,name=cpu_svn,json=cpuSvn,proto3" json:"cpu_svn,omitempty"` // should be 16 bytes + MiscSelect uint32 `protobuf:"varint,2,opt,name=misc_select,json=miscSelect,proto3" json:"misc_select,omitempty"` // should be 4 bytes + Reserved1 []byte `protobuf:"bytes,3,opt,name=reserved1,proto3" json:"reserved1,omitempty"` // should be 28 bytes + Attributes []byte `protobuf:"bytes,4,opt,name=attributes,proto3" json:"attributes,omitempty"` // should be 16 bytes + MrEnclave []byte `protobuf:"bytes,5,opt,name=mr_enclave,json=mrEnclave,proto3" json:"mr_enclave,omitempty"` // should be 32 bytes + Reserved2 []byte `protobuf:"bytes,6,opt,name=reserved2,proto3" json:"reserved2,omitempty"` // should be 32 bytes + MrSigner []byte `protobuf:"bytes,7,opt,name=mr_signer,json=mrSigner,proto3" json:"mr_signer,omitempty"` // should be 32 bytes + Reserved3 []byte `protobuf:"bytes,8,opt,name=reserved3,proto3" json:"reserved3,omitempty"` // should be 96 bytes + IsvProdId uint32 `protobuf:"varint,9,opt,name=isv_prod_id,json=isvProdId,proto3" json:"isv_prod_id,omitempty"` // should be 2 bytes + IsvSvn uint32 `protobuf:"varint,10,opt,name=isv_svn,json=isvSvn,proto3" json:"isv_svn,omitempty"` // should be 2 bytes + Reserved4 []byte `protobuf:"bytes,11,opt,name=reserved4,proto3" json:"reserved4,omitempty"` // should be 60 bytes + ReportData []byte `protobuf:"bytes,12,opt,name=report_data,json=reportData,proto3" json:"report_data,omitempty"` // should be 64 bytes +} + +func (x *EnclaveReport) Reset() { + *x = EnclaveReport{} + if protoimpl.UnsafeEnabled { + mi := &file_tdx_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EnclaveReport) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EnclaveReport) ProtoMessage() {} + +func (x *EnclaveReport) ProtoReflect() protoreflect.Message { + mi := &file_tdx_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EnclaveReport.ProtoReflect.Descriptor instead. +func (*EnclaveReport) Descriptor() ([]byte, []int) { + return file_tdx_proto_rawDescGZIP(), []int{8} +} + +func (x *EnclaveReport) GetCpuSvn() []byte { + if x != nil { + return x.CpuSvn + } + return nil +} + +func (x *EnclaveReport) GetMiscSelect() uint32 { + if x != nil { + return x.MiscSelect + } + return 0 +} + +func (x *EnclaveReport) GetReserved1() []byte { + if x != nil { + return x.Reserved1 + } + return nil +} + +func (x *EnclaveReport) GetAttributes() []byte { + if x != nil { + return x.Attributes + } + return nil +} + +func (x *EnclaveReport) GetMrEnclave() []byte { + if x != nil { + return x.MrEnclave + } + return nil +} + +func (x *EnclaveReport) GetReserved2() []byte { + if x != nil { + return x.Reserved2 + } + return nil +} + +func (x *EnclaveReport) GetMrSigner() []byte { + if x != nil { + return x.MrSigner + } + return nil +} + +func (x *EnclaveReport) GetReserved3() []byte { + if x != nil { + return x.Reserved3 + } + return nil +} + +func (x *EnclaveReport) GetIsvProdId() uint32 { + if x != nil { + return x.IsvProdId + } + return 0 +} + +func (x *EnclaveReport) GetIsvSvn() uint32 { + if x != nil { + return x.IsvSvn + } + return 0 +} + +func (x *EnclaveReport) GetReserved4() []byte { + if x != nil { + return x.Reserved4 + } + return nil +} + +func (x *EnclaveReport) GetReportData() []byte { + if x != nil { + return x.ReportData + } + return nil +} + +var File_tdx_proto protoreflect.FileDescriptor + +var file_tdx_proto_rawDesc = []byte{ + 0x0a, 0x09, 0x74, 0x64, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x74, 0x64, 0x78, + 0x22, 0xf1, 0x01, 0x0a, 0x07, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x56, 0x34, 0x12, 0x23, 0x0a, 0x06, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x74, + 0x64, 0x78, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x12, 0x34, 0x0a, 0x0d, 0x74, 0x64, 0x5f, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x5f, 0x62, 0x6f, + 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x64, 0x78, 0x2e, 0x54, + 0x44, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x0b, 0x74, 0x64, 0x51, 0x75, + 0x6f, 0x74, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x69, 0x67, 0x6e, 0x65, + 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x0e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x69, 0x7a, + 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x64, 0x78, 0x2e, 0x45, 0x63, 0x64, + 0x73, 0x61, 0x32, 0x35, 0x36, 0x42, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x56, 0x34, 0x41, + 0x75, 0x74, 0x68, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x44, + 0x61, 0x74, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x72, 0x61, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x22, 0xde, 0x01, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, + 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x14, 0x61, 0x74, 0x74, + 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, + 0x65, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x74, + 0x65, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x71, 0x65, 0x5f, 0x73, 0x76, 0x6e, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x71, 0x65, 0x53, 0x76, 0x6e, 0x12, 0x17, 0x0a, + 0x07, 0x70, 0x63, 0x65, 0x5f, 0x73, 0x76, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, + 0x70, 0x63, 0x65, 0x53, 0x76, 0x6e, 0x12, 0x20, 0x0a, 0x0c, 0x71, 0x65, 0x5f, 0x76, 0x65, 0x6e, + 0x64, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x71, 0x65, + 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x44, 0x61, 0x74, 0x61, 0x22, 0xc5, 0x03, 0x0a, 0x0b, 0x54, 0x44, 0x51, 0x75, 0x6f, 0x74, + 0x65, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x1e, 0x0a, 0x0b, 0x74, 0x65, 0x65, 0x5f, 0x74, 0x63, 0x62, + 0x5f, 0x73, 0x76, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x74, 0x65, 0x65, 0x54, + 0x63, 0x62, 0x53, 0x76, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x72, 0x5f, 0x73, 0x65, 0x61, 0x6d, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6d, 0x72, 0x53, 0x65, 0x61, 0x6d, 0x12, 0x24, + 0x0a, 0x0e, 0x6d, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x61, 0x6d, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6d, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, + 0x53, 0x65, 0x61, 0x6d, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65, 0x61, 0x6d, 0x5f, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x73, + 0x65, 0x61, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x23, 0x0a, + 0x0d, 0x74, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x74, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x78, 0x66, 0x61, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x78, 0x66, 0x61, 0x6d, 0x12, 0x13, 0x0a, 0x05, 0x6d, 0x72, 0x5f, 0x74, 0x64, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6d, 0x72, 0x54, 0x64, 0x12, 0x20, 0x0a, 0x0c, 0x6d, + 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0a, 0x6d, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x64, 0x12, 0x19, 0x0a, + 0x08, 0x6d, 0x72, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x6d, 0x72, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x72, 0x5f, 0x6f, + 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0d, 0x6d, 0x72, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x15, 0x0a, 0x06, 0x72, 0x74, 0x5f, 0x6d, 0x72, 0x30, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x05, 0x72, 0x74, 0x4d, 0x72, 0x30, 0x12, 0x15, 0x0a, 0x06, 0x72, 0x74, 0x5f, 0x6d, 0x72, + 0x31, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x72, 0x74, 0x4d, 0x72, 0x31, 0x12, 0x15, + 0x0a, 0x06, 0x72, 0x74, 0x5f, 0x6d, 0x72, 0x32, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x72, 0x74, 0x4d, 0x72, 0x32, 0x12, 0x15, 0x0a, 0x06, 0x72, 0x74, 0x5f, 0x6d, 0x72, 0x33, 0x18, + 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x72, 0x74, 0x4d, 0x72, 0x33, 0x12, 0x1f, 0x0a, 0x0b, + 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x22, 0xb5, 0x01, + 0x0a, 0x1a, 0x45, 0x63, 0x64, 0x73, 0x61, 0x32, 0x35, 0x36, 0x42, 0x69, 0x74, 0x51, 0x75, 0x6f, + 0x74, 0x65, 0x56, 0x34, 0x41, 0x75, 0x74, 0x68, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x09, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x65, 0x63, + 0x64, 0x73, 0x61, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x65, 0x63, 0x64, 0x73, 0x61, + 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x45, + 0x0a, 0x12, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x74, 0x64, 0x78, + 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, + 0x74, 0x61, 0x52, 0x11, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x44, 0x61, 0x74, 0x61, 0x22, 0xbc, 0x01, 0x0a, 0x11, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x32, 0x0a, 0x15, 0x63, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x63, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, + 0x69, 0x7a, 0x65, 0x12, 0x5f, 0x0a, 0x1c, 0x71, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x64, 0x78, 0x2e, + 0x51, 0x45, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x19, 0x71, 0x65, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x44, 0x61, 0x74, 0x61, 0x22, 0x8a, 0x02, 0x0a, 0x19, 0x51, 0x45, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, + 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x09, 0x71, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x64, 0x78, 0x2e, 0x45, 0x6e, 0x63, 0x6c, + 0x61, 0x76, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x08, 0x71, 0x65, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x71, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x11, 0x71, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x12, 0x31, 0x0a, 0x0c, 0x71, 0x65, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x64, 0x78, 0x2e, + 0x51, 0x65, 0x41, 0x75, 0x74, 0x68, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x71, 0x65, 0x41, 0x75, + 0x74, 0x68, 0x44, 0x61, 0x74, 0x61, 0x12, 0x59, 0x0a, 0x1a, 0x70, 0x63, 0x6b, 0x5f, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x64, 0x78, + 0x2e, 0x50, 0x43, 0x4b, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, + 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x17, 0x70, 0x63, 0x6b, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, + 0x61, 0x22, 0x87, 0x01, 0x0a, 0x17, 0x50, 0x43, 0x4b, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x32, 0x0a, + 0x15, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x61, 0x74, + 0x61, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x63, 0x6b, 0x5f, 0x63, 0x65, 0x72, + 0x74, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, + 0x63, 0x6b, 0x43, 0x65, 0x72, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x22, 0x4a, 0x0a, 0x0a, 0x51, + 0x65, 0x41, 0x75, 0x74, 0x68, 0x44, 0x61, 0x74, 0x61, 0x12, 0x28, 0x0a, 0x10, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, + 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xf7, 0x02, 0x0a, 0x0d, 0x45, 0x6e, 0x63, 0x6c, + 0x61, 0x76, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x63, 0x70, 0x75, + 0x5f, 0x73, 0x76, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x63, 0x70, 0x75, 0x53, + 0x76, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x69, 0x73, 0x63, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6d, 0x69, 0x73, 0x63, 0x53, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x31, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, + 0x31, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x72, 0x5f, 0x65, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6d, 0x72, 0x45, 0x6e, 0x63, 0x6c, 0x61, 0x76, 0x65, + 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x32, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x32, 0x12, 0x1b, + 0x0a, 0x09, 0x6d, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x08, 0x6d, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x72, + 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x33, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, + 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x33, 0x12, 0x1e, 0x0a, 0x0b, 0x69, 0x73, 0x76, + 0x5f, 0x70, 0x72, 0x6f, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, + 0x69, 0x73, 0x76, 0x50, 0x72, 0x6f, 0x64, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x76, + 0x5f, 0x73, 0x76, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x73, 0x76, 0x53, + 0x76, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x34, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x34, + 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x44, 0x61, 0x74, + 0x61, 0x42, 0x2a, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x67, 0x6f, 0x2d, 0x74, 0x64, 0x78, 0x2d, 0x67, 0x75, + 0x65, 0x73, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x64, 0x78, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_tdx_proto_rawDescOnce sync.Once + file_tdx_proto_rawDescData = file_tdx_proto_rawDesc +) + +func file_tdx_proto_rawDescGZIP() []byte { + file_tdx_proto_rawDescOnce.Do(func() { + file_tdx_proto_rawDescData = protoimpl.X.CompressGZIP(file_tdx_proto_rawDescData) + }) + return file_tdx_proto_rawDescData +} + +var file_tdx_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_tdx_proto_goTypes = []interface{}{ + (*QuoteV4)(nil), // 0: tdx.QuoteV4 + (*Header)(nil), // 1: tdx.Header + (*TDQuoteBody)(nil), // 2: tdx.TDQuoteBody + (*Ecdsa256BitQuoteV4AuthData)(nil), // 3: tdx.Ecdsa256BitQuoteV4AuthData + (*CertificationData)(nil), // 4: tdx.CertificationData + (*QEReportCertificationData)(nil), // 5: tdx.QEReportCertificationData + (*PCKCertificateChainData)(nil), // 6: tdx.PCKCertificateChainData + (*QeAuthData)(nil), // 7: tdx.QeAuthData + (*EnclaveReport)(nil), // 8: tdx.EnclaveReport +} +var file_tdx_proto_depIdxs = []int32{ + 1, // 0: tdx.QuoteV4.header:type_name -> tdx.Header + 2, // 1: tdx.QuoteV4.td_quote_body:type_name -> tdx.TDQuoteBody + 3, // 2: tdx.QuoteV4.signed_data:type_name -> tdx.Ecdsa256BitQuoteV4AuthData + 4, // 3: tdx.Ecdsa256BitQuoteV4AuthData.certification_data:type_name -> tdx.CertificationData + 5, // 4: tdx.CertificationData.qe_report_certification_data:type_name -> tdx.QEReportCertificationData + 8, // 5: tdx.QEReportCertificationData.qe_report:type_name -> tdx.EnclaveReport + 7, // 6: tdx.QEReportCertificationData.qe_auth_data:type_name -> tdx.QeAuthData + 6, // 7: tdx.QEReportCertificationData.pck_certificate_chain_data:type_name -> tdx.PCKCertificateChainData + 8, // [8:8] is the sub-list for method output_type + 8, // [8:8] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name +} + +func init() { file_tdx_proto_init() } +func file_tdx_proto_init() { + if File_tdx_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_tdx_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QuoteV4); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tdx_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Header); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tdx_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TDQuoteBody); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tdx_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Ecdsa256BitQuoteV4AuthData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tdx_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CertificationData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tdx_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QEReportCertificationData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tdx_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PCKCertificateChainData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tdx_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QeAuthData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tdx_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EnclaveReport); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_tdx_proto_rawDesc, + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_tdx_proto_goTypes, + DependencyIndexes: file_tdx_proto_depIdxs, + MessageInfos: file_tdx_proto_msgTypes, + }.Build() + File_tdx_proto = out.File + file_tdx_proto_rawDesc = nil + file_tdx_proto_goTypes = nil + file_tdx_proto_depIdxs = nil +} diff --git a/testing/testdata/README.md b/testing/testdata/README.md new file mode 100644 index 0000000..3b24e2f --- /dev/null +++ b/testing/testdata/README.md @@ -0,0 +1,115 @@ +# `testdata` +This folder contains embedded files that serve as sample API responses, +intended for testing purposes. These responses can be used to stimulate the +behavior of Intel PCS APIs without actually making network access. + + +## Files + +### `pckcrl` + +This file serves as sample for Intel PCS API response for PCK certificate +Revocation List. This response is specifically designed to check whether a PCK +certificate is revoked or not. +This sample API follows a structure similar to +`https://api.trustedservices.intel.com/sgx/certification/v4/pckcrl?ca=platform&encoding=der` + + +### `sample_tcbInfo_response` + +This file serves as sample for Intel PCS API response to retrieve TDX TCB +information for given FMSPC. This response helps in determining the status of a +TDX TCB level for a given platform needs to be done using TDX TCB information +according to the following algorithm: + +1. Retrieve FMSPC value from SGX PCK Certificate assigned to a given platform. + +2. Retrieve TDX TCB Info matching the FMSPC value. + +3. Go over the sorted collection of TCB Levels retrieved from TCB Info starting + from the first item on the list: + + a. Compare all of the SGX TCB Comp SVNs retrieved from the SGX PCK Certificate + (from 01 to 16) with the corresponding values of SVNs in sgxtcbcomponents + array of TCB Level. If all SGX TCB Comp SVNs in the certificate are greater + or equal to the corresponding values in TCB Level, go to 3.b, otherwise move + to the next item on TCB Levels list. + + b. Compare PCESVN value retrieved from the SGX PCK certificate with the + corresponding value in the TCB Level. If it is greater or equal to the + value in TCB Level, go to 3.c, otherwise move to the next item on TCB + Levels list. + + c. Compare all of the SVNs in TEE TCB SVN array retrieved from TD Report in + Quote (from index 0 to 15) with the corresponding values of SVNs in + tdxtcbcomponents array of TCB Level. If all TEE TCB SVNs in the TD Report + are greater or equal to the corresponding values in TCB Level, read status + assigned to this TCB level. Otherwise, move to the next item on TCB Levels + list. + +4. For the selected TCB level verify that SVN at index 1 in tdxtcbcomponents + array matches the value of SVN at index 1 in TEE TCB SVNs array (from TD Report + in Quote). In case of a mismatch the selected TCB level should be rejected as + TCB Info that was used for the comparison is not supported for this platform + configuration. + +5. If no TCB level matches the SGX PCK Certificate and TD Report, then the TCB + level is not supported. + +This sample API follows a structure similar to +`https://api.trustedservices.intel.com/tdx/certification/v4/tcb?fmspc=50806f000000` + + +### `sample_qeIdentity_response` + +This file serves as sample for Intel PCS API response to retrieve QE identity +response. This response helps in determining if the identity of a SGX Enclave +(represented by SGX Enclave Report) matches a valid, up-to-date Enclave Identity +issued by Intel requires following steps: + +1. Retrieve Enclave Identity(TDX QE) from PCS and verify that it is a valid + structure issued by Intel. + +2. Perform the following comparison of SGX Enclave Report against the retrieved + Enclave Identity: + + a. Verify if MRSIGNER field retrieved from SGX Enclave Report is equal to the + value of mrsigner field in Enclave Identity. + + b. Verify if ISVPRODID field retrieved from SGX Enclave Report is equal to the + value of isvprodid field in Enclave Identity. + + c. Apply miscselectMask (binary mask) from Enclave Identity to MISCSELECT + field retrieved from SGX Enclave Report. Verify if the outcome + (miscselectMask & MISCSELECT) is equal to the value of miscselect field in + Enclave Identity. + + d. Apply attributesMask (binary mask) from Enclave Identity to ATTRIBUTES + field retrieved from SGX Enclave Report. Verify if the outcome (attributesMask + & ATTRIBUTES) is equal to the value of attributes field in Enclave Identity. + +3. If any of the checks above fail, the identity of the enclave does not match + Enclave Identity published by Intel. + +4. Determine a TCB status of the Enclave: + + a. Retrieve a collection of TCB Levels (sorted by ISVSVNs) from tcbLevels field + in Enclave Identity structure. + + b. Go over the list of TCB Levels (descending order) and find the one that has + ISVSVN that is lower or equal to the ISVSVN value from SGX Enclave Report. + + c. If a TCB level is found, read its status from tcbStatus field, otherwise + the TCB Level is not supported. + +This sample API follows a structure similar to +`https://api.trustedservices.intel.com/tdx/certification/v4/qe/identity` + + +### `rootcrl.der` + +This file serves as sample for Intel PCS API response for Root certificate +Revocation List. This response is specifically designed to check whether a Root +certificate is revoked or not. +This sample API follows a structure similar to +`https://certificates.trustedservices.intel.com/IntelSGXRootCA.der` diff --git a/testing/testdata/pckcrl b/testing/testdata/pckcrl new file mode 100644 index 0000000..7482727 Binary files /dev/null and b/testing/testdata/pckcrl differ diff --git a/testing/testdata/report.dat b/testing/testdata/report.dat new file mode 100644 index 0000000..6a726be Binary files /dev/null and b/testing/testdata/report.dat differ diff --git a/testing/testdata/rootcrl.der b/testing/testdata/rootcrl.der new file mode 100644 index 0000000..4716247 Binary files /dev/null and b/testing/testdata/rootcrl.der differ diff --git a/testing/testdata/sample_qeIdentity_response b/testing/testdata/sample_qeIdentity_response new file mode 100644 index 0000000..38bd6da --- /dev/null +++ b/testing/testdata/sample_qeIdentity_response @@ -0,0 +1 @@ +{"enclaveIdentity":{"id":"TD_QE","version":2,"issueDate":"2023-06-08T07:24:59Z","nextUpdate":"2023-07-08T07:24:59Z","tcbEvaluationDataNumber":15,"miscselect":"00000000","miscselectMask":"FFFFFFFF","attributes":"11000000000000000000000000000000","attributesMask":"FBFFFFFFFFFFFFFF0000000000000000","mrsigner":"DC9E2A7C6F948F17474E34A7FC43ED030F7C1563F1BABDDF6340C82E0E54A8C5","isvprodid":2,"tcbLevels":[{"tcb":{"isvsvn":4},"tcbDate":"2023-02-15T00:00:00Z","tcbStatus":"UpToDate"}]},"signature":"b6a601f05de27f2ca5105eec24bdd4bf7dd1b8bbfffc76dffe4f4d16b8a395843e4b92d430fd6744b0648bf44302c528412fcb9cbf3cc9ce6922a3057932b6a6"} \ No newline at end of file diff --git a/testing/testdata/sample_tcbInfo_response b/testing/testdata/sample_tcbInfo_response new file mode 100644 index 0000000..ea9302d --- /dev/null +++ b/testing/testdata/sample_tcbInfo_response @@ -0,0 +1 @@ +{"tcbInfo":{"id":"TDX","version":3,"issueDate":"2023-06-18T08:42:58Z","nextUpdate":"2023-07-18T08:42:58Z","fmspc":"50806f000000","pceId":"0000","tcbType":0,"tcbEvaluationDataNumber":15,"tdxModule":{"mrsigner":"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","attributes":"0000000000000000","attributesMask":"FFFFFFFFFFFFFFFF"},"tcbLevels":[{"tcb":{"sgxtcbcomponents":[{"svn":5,"category":"BIOS","type":"Early Microcode Update"},{"svn":5,"category":"OS/VMM","type":"SGX Late Microcode Update"},{"svn":2,"category":"OS/VMM","type":"TXT SINIT"},{"svn":2,"category":"BIOS"},{"svn":3,"category":"BIOS"},{"svn":1,"category":"BIOS"},{"svn":0},{"svn":3,"category":"OS/VMM","type":"SEAMLDR ACM"},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}],"pcesvn":11,"tdxtcbcomponents":[{"svn":3,"category":"OS/VMM","type":"TDX Module"},{"svn":0,"category":"OS/VMM","type":"TDX Module"},{"svn":5,"category":"OS/VMM","type":"TDX Late Microcode Update"},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}]},"tcbDate":"2023-02-15T00:00:00Z","tcbStatus":"UpToDate"},{"tcb":{"sgxtcbcomponents":[{"svn":5,"category":"BIOS","type":"Early Microcode Update"},{"svn":5,"category":"OS/VMM","type":"SGX Late Microcode Update"},{"svn":2,"category":"OS/VMM","type":"TXT SINIT"},{"svn":2,"category":"BIOS"},{"svn":3,"category":"BIOS"},{"svn":1,"category":"BIOS"},{"svn":0},{"svn":3,"category":"OS/VMM","type":"SEAMLDR ACM"},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}],"pcesvn":5,"tdxtcbcomponents":[{"svn":3,"category":"OS/VMM","type":"TDX Module"},{"svn":0,"category":"OS/VMM","type":"TDX Module"},{"svn":5,"category":"OS/VMM","type":"TDX Late Microcode Update"},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}]},"tcbDate":"2018-01-04T00:00:00Z","tcbStatus":"OutOfDate","advisoryIDs":["INTEL-SA-00106","INTEL-SA-00115","INTEL-SA-00135","INTEL-SA-00203","INTEL-SA-00220","INTEL-SA-00233","INTEL-SA-00270","INTEL-SA-00293","INTEL-SA-00320","INTEL-SA-00329","INTEL-SA-00381","INTEL-SA-00389","INTEL-SA-00477"]}]},"signature":"f6502d6fad1e3b7281df2b7eddc773d5b5281187346c12c5647b4f243cea49212be96a7a1a6b5d83e36323fe3fa9dacd61ebfbc38e631ff0fe29ef14ae0db0b4"} diff --git a/testing/testdata/tdx_prod_quote_SPR_E4.dat b/testing/testdata/tdx_prod_quote_SPR_E4.dat new file mode 100644 index 0000000..67fddf2 Binary files /dev/null and b/testing/testdata/tdx_prod_quote_SPR_E4.dat differ diff --git a/testing/testdata/testdata.go b/testing/testdata/testdata.go new file mode 100644 index 0000000..70f9782 --- /dev/null +++ b/testing/testdata/testdata.go @@ -0,0 +1,50 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package testdata defines sample responses of the collaterals +package testdata + +import ( + _ "embed" +) + +// RawQuote contains raw bytes of quote. To be used only for testing +// +//go:embed "tdx_prod_quote_SPR_E4.dat" +var RawQuote []byte + +// RawReport contains raw bytes of report. To be used only for testing +// +//go:embed "report.dat" +var RawReport []byte + +// PckCrlBody contains sample PCK CRL. To be used only for testing +// +//go:embed "pckcrl" +var PckCrlBody []byte + +// RootCrlBody contains sample Root CA CRL. To be used only for testing +// +//go:embed "rootcrl.der" +var RootCrlBody []byte + +// TcbInfoBody contains sample TCBInfo response. To be used only for testing +// +//go:embed "sample_tcbInfo_response" +var TcbInfoBody []byte + +// QeIdentityBody contains sample QeIdentity response. To be used only for testing +// +//go:embed "sample_qeIdentity_response" +var QeIdentityBody []byte