diff --git a/comid/tdx-profile/example_qe_refval_test.go b/comid/tdx-profile/example_qe_refval_test.go index 7f8119b..5dfc129 100644 --- a/comid/tdx-profile/example_qe_refval_test.go +++ b/comid/tdx-profile/example_qe_refval_test.go @@ -8,53 +8,146 @@ import ( "github.com/veraison/corim/comid" "github.com/veraison/corim/corim" - "github.com/veraison/corim/extensions" "github.com/veraison/eat" ) -func Example_tdx_qe_refval() { - coMID := &comid.Comid{} +// Example_decode_JSON decodes the TDX Measurement Extensions from the given JSON Template +func Example_decode_QE_JSON() { profileID, err := eat.NewProfile("http://intel.com/tdx-profile") if err != nil { panic(err) // will not error, as the hard-coded string above is valid } + profile, found := corim.GetProfile(profileID) + if !found { + fmt.Printf("CoRIM Profile NOT FOUND") + return + } - extMap := extensions.NewMap(). - Add(comid.ExtMval, &MvalExtensions{}) + coMID := profile.GetComid() + if err := coMID.FromJSON([]byte(TDXQERefValTemplate)); err != nil { + panic(err) + } - if err := corim.RegisterProfile(profileID, extMap); err != nil { - // will not error, assuming our profile ID is unique, and we've - // correctly set up the extensions Map above + if err := coMID.Valid(); err != nil { panic(err) } - if err := coMID.FromJSON([]byte(TDXQERefValTemplate)); err != nil { - fmt.Printf("From JSON Failed %s", err.Error()) - } else { - fmt.Printf("From JSON Passed \n") + + if err := extractQERefVals(coMID); err != nil { + panic(err) + } + + // output + // OID: 2.16.840.1.113741.1.2.3.4.1 + // Vendor: Intel Corporation + // Model: TDX QE TCB + // miscselect: c0000000fbff0000 + // tcbEvalNum: 11 + // IsvProdID: 0303 + // Digest Alg: 1 + // Digest Value: 87428fc522803d31065e7bce3cf03fe475096631e5e07bbd7a0fde60c4cf25c7 + // Digest Alg: 8 + // Digest Value: a314fc2dc663ae7a6b6bc6787594057396e6b3f569cd50fd5ddb4d1bbafd2b6aa314fc2dc663ae7a6b6bc6787594057396e6b3f569cd50fd5ddb4d1bbafd2b6a + // CryptoKey Type: pkix-base64-key + // CryptoKey Value: -----BEGIN PUBLIC KEY----- + // MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFn0taoAwR3PmrKkYLtAsD9o05KSM6mbgfNCgpuL0g6VpTHkZl73wk5BDxoV7n+Oeee0iIqkW3HMZT3ETiniJdg== + // -----END PUBLIC KEY----- +} + +func extractQERefVals(c *comid.Comid) error { + if c.Triples.ReferenceValues == nil { + return fmt.Errorf("no reference values triples") } - mVal := coMID.Triples.ReferenceValues.Values[0].Measurements.Values[0].Val - val, err := mVal.Extensions.Get("tcbevalnum") + + for i, rv := range c.Triples.ReferenceValues.Values { + if err := extractQERefVal(rv); err != nil { + return fmt.Errorf("bad PSA reference value at index %d: %w", i, err) + } + } + + return nil +} + +func extractQERefVal(rv comid.ValueTriple) error { + class := rv.Environment.Class + + if err := extractClassElements(class); err != nil { + return fmt.Errorf("extracting class: %w", err) + } + + measurements := rv.Measurements + if err := extractQEMeasurements(measurements); err != nil { + return fmt.Errorf("extracting measurements: %w", err) + } + + return nil +} + +func extractQEMeasurements(m comid.Measurements) error { + if len(m.Values) == 0 { + return fmt.Errorf("no measurements") + } + for i, m := range m.Values { + if err := decodeQEMValExtensions(m); err != nil { + return fmt.Errorf("extracting measurement at index %d: %w", i, err) + } + + if m.AuthorizedBy != nil { + err := decodeAuthorisedBy(m) + if err != nil { + return fmt.Errorf("extracting measurement at index %d: %w", i, err) + } + } + } + return nil +} + +func decodeQEMValExtensions(m comid.Measurement) error { + val, err := m.Val.Extensions.Get("miscselect") + if err != nil { + return fmt.Errorf("failed to decode miscselect from measurement extensions") + } + f, ok := val.(*teeMiscSelect) + if !ok { + fmt.Printf("val was not pointer to teeMiscSelect") + } + miscselect := *f + fmt.Printf("\nmiscselect: %x", miscselect) + + val, err = m.Val.Extensions.Get("tcbevalnum") if err != nil { - fmt.Printf(" \n tcbEvalNum NOT Set: %s \n", err.Error()) - } else { - fmt.Printf(" \n tcbEvalNum is Set %d", val) + return fmt.Errorf("failed to decode tcbevalnum from measurement extensions") } - f, ok := val.(*teeTcbEvalNum) + t, ok := val.(*teeTcbEvalNum) if !ok { fmt.Printf("val was not pointer to teeTcbEvalNum") } - tcbValNum := *f + tcbValNum := *t + fmt.Printf("\ntcbEvalNum: %d", tcbValNum) + + val, err = m.Val.Extensions.Get("isvprodid") if err != nil { - fmt.Printf(" \n tcbEvalNum NOT Set: %s \n", err.Error()) - } else { - fmt.Printf(" \n tcbEvalNum is Set %d", tcbValNum) + return fmt.Errorf("failed to decode isvprodid from measurement extensions") + } + tS, ok := val.(*teeIsvProdID) + if !ok { + fmt.Printf("val was not pointer to teeIsvProdID") } - if err := coMID.Valid(); err != nil { - panic(err) + fmt.Printf("\nIsvProdID: %x", *tS) + + val, err = m.Val.Extensions.Get("mrsigner") + if err != nil { + return fmt.Errorf("failed to decode mrsigner from measurement extensions") } - // Output: - //a301a1005043bbe37f2e614b33aed353cff1428b200281a30065494e54454c01d8207168747470733a2f2f696e74656c2e636f6d028301000204a1008182a100a300d86f4c6086480186f84d01020304050171496e74656c20436f72706f726174696f6e02675444585345414d81a101a100a20065312e322e330101 + tD, ok := val.(*teeDigest) + if !ok { + fmt.Printf("val was not pointer to teeDigest") + } + err = extractTEEDigest(tD) + if err != nil { + return fmt.Errorf("unable to extract TEE Digest: %w", err) + } + return nil } diff --git a/comid/tdx-profile/example_seam_refval_test.go b/comid/tdx-profile/example_seam_refval_test.go index e19dd37..bdf25c8 100644 --- a/comid/tdx-profile/example_seam_refval_test.go +++ b/comid/tdx-profile/example_seam_refval_test.go @@ -262,7 +262,7 @@ func decodeMValExtensions(m comid.Measurement) error { fmt.Printf("val was not pointer to teeTcbEvalNum") } tcbValNum := *f - fmt.Printf("tcbEvalNum: %d", tcbValNum) + fmt.Printf("\ntcbEvalNum: %d", tcbValNum) val, err = m.Val.Extensions.Get("isvprodid") if err != nil { @@ -296,7 +296,7 @@ func decodeMValExtensions(m comid.Measurement) error { fmt.Printf("val was not pointer to teeAttributes") } - fmt.Printf("\nAttributes: %x\n", *tA) + fmt.Printf("\nAttributes: %x", *tA) val, err = m.Val.Extensions.Get("mrsigner") if err != nil { @@ -319,8 +319,8 @@ func decodeAuthorisedBy(m comid.Measurement) error { if err := m.AuthorizedBy.Valid(); err != nil { return fmt.Errorf("invalid cryptokey: %w", err) } - fmt.Printf("CryptoKey Type: %s\n", m.AuthorizedBy.Type()) - fmt.Printf("CryptoKey Value: %s", m.AuthorizedBy.String()) + fmt.Printf("\nCryptoKey Type: %s", m.AuthorizedBy.Type()) + fmt.Printf("\nCryptoKey Value: %s", m.AuthorizedBy.String()) return nil } @@ -380,7 +380,7 @@ func extractRefVals(c *comid.Comid) error { } for i, rv := range c.Triples.ReferenceValues.Values { - if err := extractTDXRefVal(rv); err != nil { + if err := extractSeamRefVal(rv); err != nil { return fmt.Errorf("bad PSA reference value at index %d: %w", i, err) } } @@ -388,7 +388,7 @@ func extractRefVals(c *comid.Comid) error { return nil } -func extractTDXRefVal(rv comid.ValueTriple) error { +func extractSeamRefVal(rv comid.ValueTriple) error { class := rv.Environment.Class if err := extractClassElements(class); err != nil { @@ -437,17 +437,17 @@ func extractClassElements(c *comid.Class) error { return fmt.Errorf("class id is not an oid") } - fmt.Printf("OID: %s\n", classID.Value.String()) + fmt.Printf("OID: %s", classID.Value.String()) if c.Vendor == nil { return fmt.Errorf("no Vendor") } - fmt.Printf("Vendor: %s\n", *c.Vendor) + fmt.Printf("\nVendor: %s", *c.Vendor) if c.Model == nil { return fmt.Errorf("no Model") } - fmt.Printf("Model: %s\n", *c.Model) + fmt.Printf("\nModel: %s", *c.Model) return nil } @@ -462,8 +462,8 @@ func extractTEEDigest(d *teeDigest) error { } for _, digest := range *d { - fmt.Printf("Digest Alg: %d\n", digest.HashAlgID) - fmt.Printf("Digest Value: %x\n", digest.HashValue) + fmt.Printf("\nDigest Alg: %d", digest.HashAlgID) + fmt.Printf("\nDigest Value: %x", digest.HashValue) } return nil