@@ -129,16 +129,20 @@ var (
129129 }
130130)
131131
132- // TCBVersion represents the SEV-SNP TCB_VERSION
133- type TCBVersion struct {
132+ // TCBVersion is a 64-bit bitfield of different security patch levels of AMD firmware and microcode.
133+ // Deprecated: use TCBVersionStruct instead
134+ type TCBVersion uint64
135+
136+ // TCBVersionStruct represents the SEV-SNP TCB_VERSION
137+ type TCBVersionStruct struct {
134138 // Version identifies the version of this structure as defined in V[C,L]EK x509 certificate extensions
135139 Version uint8
136140 // TCB is a 64-bit bitfield of different security patch levels of AMD firmware and microcode.
137141 TCB uint64
138142}
139143
140144// String returns the version of the TCB in string format
141- func (v TCBVersion ) String () string {
145+ func (v TCBVersionStruct ) String () string {
142146 switch v .Version {
143147 case TCBStructVersion0 :
144148 return fmt .Sprintf ("Milan or Genoa TCB: 0x%x" , v .TCB )
@@ -149,6 +153,16 @@ func (v TCBVersion) String() string {
149153 }
150154}
151155
156+ // TCBVersionStructFromTCBVersion converts an object of type TCBVersion to TCBVersionStruct
157+ func TCBVersionStructFromTCBVersion (v TCBVersion ) TCBVersionStruct {
158+ return TCBVersionStruct {Version : TCBStructVersion0 , TCB : uint64 (v )}
159+ }
160+
161+ // TCBVersionStructToTCBVersion converts an object of type TCBVersionStruct to TCBVersion
162+ func TCBVersionStructToTCBVersion (v TCBVersionStruct ) uint64 {
163+ return v .TCB
164+ }
165+
152166// Extensions represents the information stored in the KDS-specified x509 extensions of a V{C,L}EK
153167// certificate.
154168type Extensions struct {
@@ -158,9 +172,11 @@ type Extensions struct {
158172 // Primary vs secondary is irrelevant to verification. The length of this
159173 // field depends on the TCB version; 64 bytes for version 0 and
160174 // 8 bytes for version 1
161- HWID []byte
162- TCBVersion TCBVersion
163- CspID string
175+ HWID []byte
176+ // Deprecated: use TCBVersionStruct instead
177+ TCBVersion TCBVersion
178+ TCBVersionStruct TCBVersionStruct
179+ CspID string
164180}
165181
166182func oidTokdsOID (id asn1.ObjectIdentifier ) (kdsOID , error ) {
@@ -250,10 +266,8 @@ type TCBParts struct {
250266 FmcSpl uint8
251267}
252268
253- // ComposeTCBParts returns an SEV-SNP TCB_VERSION from OID mapping values. The spl4-spl7 fields are
254- // reserved, but the KDS specification designates them as 4 byte-sized fields.
255- func ComposeTCBParts (parts TCBParts ) (TCBVersion , error ) {
256- tcbVersion := TCBVersion {}
269+ func composeTCBPartsToTCBVersionStruct (parts TCBParts ) (TCBVersionStruct , error ) {
270+ tcbVersion := TCBVersionStruct {}
257271 // Only UcodeSpl may be 0-255. All others must be 0-127.
258272 check127 := func (name string , value uint8 ) error {
259273 if value > 127 {
@@ -298,9 +312,26 @@ func ComposeTCBParts(parts TCBParts) (TCBVersion, error) {
298312 return tcbVersion , nil
299313}
300314
301- // DecomposeTCBVersion interprets the byte components of the AMD representation of the
302- // platform security patch levels into a struct.
303- func DecomposeTCBVersion (tcb TCBVersion ) TCBParts {
315+ // ComposeTCBParts returns an SEV-SNP TCB_VERSION from OID mapping values. The spl4-spl7 fields are
316+ // reserved, but the KDS specification designates them as 4 byte-sized fields.
317+ // Deprecated: use ComposeTCBPartsToTCBVersionStruct instead
318+ func ComposeTCBParts (parts TCBParts ) (TCBVersion , error ) {
319+ tcb , err := composeTCBPartsToTCBVersionStruct (parts )
320+ if err != nil {
321+ return TCBVersion (0 ), err
322+ }
323+
324+ return TCBVersion (tcb .TCB ), nil
325+ }
326+
327+ // ComposeTCBPartsToTCBVersionStruct returns an SEV-SNP TCB_VERSION from OID mapping
328+ // values as a TCBVersionStruct. The spl4-spl7 fields are reserved, but the
329+ // KDS specification designates them as 4 byte-sized fields.
330+ func ComposeTCBPartsToTCBVersionStruct (parts TCBParts ) (TCBVersionStruct , error ) {
331+ return composeTCBPartsToTCBVersionStruct (parts )
332+ }
333+
334+ func decomposeTCBVersionStruct (tcb TCBVersionStruct ) TCBParts {
304335 switch tcb .Version {
305336 case TCBStructVersion1 :
306337 return TCBParts {
@@ -326,6 +357,34 @@ func DecomposeTCBVersion(tcb TCBVersion) TCBParts {
326357 }
327358}
328359
360+ // DecomposeTCBVersion interprets the byte components of the AMD representation of the
361+ // platform security patch levels into a struct.
362+ // Deprecated: use DecomposeTCBVersionStruct instead
363+ func DecomposeTCBVersion (tcb TCBVersion ) TCBParts {
364+ parts , _ := DecomposeTCBVersionStruct (tcb )
365+ return parts
366+ }
367+
368+ // DecomposeTCBVersionStruct accepts SEV-SNP TCB version as TCBVersion,
369+ // TCBVersionStruct or uint64 and decodes various security patch
370+ // levels from them.
371+ func DecomposeTCBVersionStruct (t interface {}) (TCBParts , error ) {
372+ var tcb TCBVersionStruct
373+
374+ switch v := t .(type ) {
375+ case TCBVersionStruct :
376+ tcb = v
377+ case TCBVersion :
378+ tcb = TCBVersionStructFromTCBVersion (v )
379+ case uint64 :
380+ tcb = TCBVersionStruct {Version : TCBStructVersion0 , TCB : v }
381+ default :
382+ return TCBParts {}, fmt .Errorf ("unsupported TCB type: %v" , t )
383+ }
384+
385+ return decomposeTCBVersionStruct (tcb ), nil
386+ }
387+
329388// TCBPartsLE returns true iff all TCB components of tcb0 are <= the corresponding tcb1 components.
330389func TCBPartsLE (tcb0 , tcb1 TCBParts ) bool {
331390 return (tcb0 .UcodeSpl <= tcb1 .UcodeSpl ) &&
@@ -473,7 +532,7 @@ func kdsOidMapToExtensions(exts map[kdsOID]*pkix.Extension) (*Extensions, error)
473532 }
474533 }
475534
476- tcb , err := ComposeTCBParts (TCBParts {
535+ tcb , err := ComposeTCBPartsToTCBVersionStruct (TCBParts {
477536 Version : result .StructVersion ,
478537 BlSpl : blspl ,
479538 SnpSpl : snpspl ,
@@ -488,7 +547,8 @@ func kdsOidMapToExtensions(exts map[kdsOID]*pkix.Extension) (*Extensions, error)
488547 if err != nil {
489548 return nil , err
490549 }
491- result .TCBVersion = tcb
550+ result .TCBVersion = TCBVersion (tcb .TCB )
551+ result .TCBVersionStruct = tcb
492552 return & result , nil
493553}
494554
@@ -603,10 +663,14 @@ func ProductCertChainURL(s abi.ReportSigner, productLine string) string {
603663 return fmt .Sprintf ("%s/cert_chain" , productBaseURL (s , productLine ))
604664}
605665
606- // VCEKCertURL returns the AMD KDS URL for retrieving the VCEK on a given product
666+ // VCEKCertQuery returns the AMD KDS URL for retrieving the VCEK on a given product
607667// at a given TCB version. The hwid is the CHIP_ID field in an attestation report.
608- func VCEKCertURL (productLine string , hwid []byte , tcb TCBVersion ) string {
609- parts := DecomposeTCBVersion (tcb )
668+ func VCEKCertQuery (productLine string , hwid []byte , tcb TCBVersionStruct ) (string , error ) {
669+ parts , err := DecomposeTCBVersionStruct (tcb )
670+ if err != nil {
671+ return "" , err
672+ }
673+
610674 switch parts .Version {
611675 case TCBStructVersion1 :
612676 hwidv1 := hwid [0 :TCBHwIDLenVersion1 ]
@@ -618,7 +682,7 @@ func VCEKCertURL(productLine string, hwid []byte, tcb TCBVersion) string {
618682 parts .SnpSpl ,
619683 parts .UcodeSpl ,
620684 parts .FmcSpl ,
621- )
685+ ), nil
622686 default :
623687 return fmt .Sprintf ("%s/%s?blSPL=%d&teeSPL=%d&snpSPL=%d&ucodeSPL=%d" ,
624688 productBaseURL (abi .VcekReportSigner , productLine ),
@@ -627,14 +691,26 @@ func VCEKCertURL(productLine string, hwid []byte, tcb TCBVersion) string {
627691 parts .TeeSpl ,
628692 parts .SnpSpl ,
629693 parts .UcodeSpl ,
630- )
694+ ), nil
631695 }
632696}
633697
634- // VLEKCertURL returns the GET URL for retrieving a VLEK certificate, but without the necessary
698+ // VCEKCertURL returns the AMD KDS URL for retrieving the VCEK on a given product
699+ // at a given TCB version. The hwid is the CHIP_ID field in an attestation report.
700+ // Deprecated: use VCEKCertQuery instead
701+ func VCEKCertURL (productLine string , hwid []byte , tcb TCBVersion ) string {
702+ url , _ := VCEKCertQuery (productLine , hwid , TCBVersionStructFromTCBVersion (tcb ))
703+ return url
704+ }
705+
706+ // VLEKCertQuery returns the GET URL for retrieving a VLEK certificate, but without the necessary
635707// CSP secret in the HTTP headers that makes the request validate to the KDS.
636- func VLEKCertURL (productLine string , tcb TCBVersion ) string {
637- parts := DecomposeTCBVersion (tcb )
708+ func VLEKCertQuery (productLine string , tcb TCBVersionStruct ) (string , error ) {
709+ parts , err := DecomposeTCBVersionStruct (tcb )
710+ if err != nil {
711+ return "" , err
712+ }
713+
638714 switch parts .Version {
639715 case TCBStructVersion1 :
640716 return fmt .Sprintf ("%s/cert?blSPL=%d&teeSPL=%d&snpSPL=%d&ucodeSPL=%d&fmcSPL=%d" ,
@@ -644,18 +720,26 @@ func VLEKCertURL(productLine string, tcb TCBVersion) string {
644720 parts .SnpSpl ,
645721 parts .UcodeSpl ,
646722 parts .FmcSpl ,
647- )
723+ ), nil
648724 default :
649725 return fmt .Sprintf ("%s/cert?blSPL=%d&teeSPL=%d&snpSPL=%d&ucodeSPL=%d" ,
650726 productBaseURL (abi .VlekReportSigner , productLine ),
651727 parts .BlSpl ,
652728 parts .TeeSpl ,
653729 parts .SnpSpl ,
654730 parts .UcodeSpl ,
655- )
731+ ), nil
656732 }
657733}
658734
735+ // VLEKCertURL returns the GET URL for retrieving a VLEK certificate, but without the necessary
736+ // CSP secret in the HTTP headers that makes the request validate to the KDS.
737+ // Deprecated: use VLEKCertQuery instead
738+ func VLEKCertURL (productLine string , tcb TCBVersion ) string {
739+ url , _ := VLEKCertQuery (productLine , TCBVersionStructFromTCBVersion (tcb ))
740+ return url
741+ }
742+
659743// VCEKCert represents the attestation report components represented in a KDS VCEK certificate
660744// request URL.
661745type VCEKCert struct {
@@ -788,7 +872,7 @@ func parseTCBURL(u *url.URL, tcbVersion uint8) (uint64, error) {
788872 setter (uint8 (number ))
789873 }
790874 }
791- tcb , err := ComposeTCBParts (parts )
875+ tcb , err := ComposeTCBPartsToTCBVersionStruct (parts )
792876 if err != nil {
793877 return 0 , fmt .Errorf ("invalid AMD KDS TCB arguments: %v" , err )
794878 }
0 commit comments