Repository: google/go-tpm
Pull request #329 (2023-05-22 15:33:11)

fix reflection on cmd structs not to use elem
In d68ba3356cd92210724c141baab40ccbea95e822, commands were updated to implement `Command` by value and not by pointer. A little bit of reflection code remained that still called `Elem()` in certain situations, which panics (since `cmd` is not a pointer anymore).


Patch:
diff --git a/tpm2/reflect.go b/tpm2/reflect.go
index e948e46..ea9b172 100644
--- a/tpm2/reflect.go
+++ b/tpm2/reflect.go
@@ -754,7 +754,7 @@ func cmdAuths[R any](cmd Command[R, *R]) ([]Session, error) {
 		if h, ok := authHandle.Interface().(AuthHandle); ok {
 			if h.Auth == nil {
 				return nil, fmt.Errorf("missing auth for '%v' parameter",
-					reflect.ValueOf(cmd).Elem().Type().Field(i).Name)
+					reflect.ValueOf(cmd).Type().Field(i).Name)
 			}
 			result = append(result, h.Auth)
 		} else {
@@ -781,7 +781,7 @@ func cmdHandles[R any](cmd Command[R, *R]) ([]byte, error) {
 
 		// Special behavior: nullable handles have an effective zero-value of
 		// TPM_RH_NULL.
-		if h.HandleValue() == 0 && hasTag(reflect.TypeOf(cmd).Elem().Field(i), "nullable") {
+		if h.HandleValue() == 0 && hasTag(reflect.TypeOf(cmd).Field(i), "nullable") {
 			h = TPMRHNull
 		}
 
@@ -804,14 +804,14 @@ func cmdNames[R any](cmd Command[R, *R]) ([]TPM2BName, error) {
 
 		// Special behavior: nullable handles have an effective zero-value of
 		// TPM_RH_NULL.
-		if h.HandleValue() == 0 && hasTag(reflect.TypeOf(cmd).Elem().Field(i), "nullable") {
+		if h.HandleValue() == 0 && hasTag(reflect.TypeOf(cmd).Field(i), "nullable") {
 			h = TPMRHNull
 		}
 
 		name := h.KnownName()
 		if name == nil {
 			return nil, fmt.Errorf("missing Name for '%v' parameter",
-				reflect.ValueOf(cmd).Elem().Type().Field(i).Name)
+				reflect.ValueOf(cmd).Type().Field(i).Name)
 		}
 		result = append(result, *name)
 	}


Test patch:
diff --git a/tpm2/test/pcr_test.go b/tpm2/test/pcr_test.go
index bb13ba4..6421213 100644
--- a/tpm2/test/pcr_test.go
+++ b/tpm2/test/pcr_test.go
@@ -5,6 +5,7 @@ import (
 	"crypto/sha1"
 	"crypto/sha256"
 	"crypto/sha512"
+	"fmt"
 	"testing"
 
 	. "github.com/google/go-tpm/tpm2"
@@ -123,3 +124,62 @@ func TestPCRReset(t *testing.T) {
 		})
 	}
 }
+
+func TestPCREvent(t *testing.T) {
+	thetpm, err := simulator.OpenSimulator()
+	if err != nil {
+		t.Fatalf("could not connect to TPM simulator: %v", err)
+	}
+	defer thetpm.Close()
+
+	cases := []struct {
+		name    string
+		hashalg TPMAlgID
+	}{
+		{"SHA1", TPMAlgSHA1},
+		{"SHA256", TPMAlgSHA256},
+		{"SHA384", TPMAlgSHA384},
+	}
+
+	// Extend every SRTM PCR with TPM2_PCR_Event
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			for i := 0; i < 17; i++ {
+				t.Run(fmt.Sprintf("PCR%02d", i), func(t *testing.T) {
+					PCRs, err := CreatePCRSelection([]int{i})
+					if err != nil {
+						t.Fatalf("Failed to create PCRSelection")
+					}
+
+					pcrRead := PCRRead{
+						PCRSelectionIn: TPMLPCRSelection{
+							PCRSelections: []TPMSPCRSelection{
+								{
+									Hash:      c.hashalg,
+									PCRSelect: PCRs,
+								},
+							},
+						},
+					}
+
+					pcrEvent := PCREvent{
+						PCRHandle: TPMHandle(i),
+						EventData: TPM2BEvent{Buffer: []byte("hello")},
+					}
+					if _, err := pcrEvent.Execute(thetpm); err != nil {
+						t.Fatalf("failed to extend pcr for test %v", err)
+					}
+
+					pcrReadRsp, err := pcrRead.Execute(thetpm)
+					if err != nil {
+						t.Fatalf("failed to read PCRs")
+					}
+					postExtendPCR16 := pcrReadRsp.PCRValues.Digests[0].Buffer
+					if allZero(postExtendPCR16) {
+						t.Errorf("postExtendPCR16 not expected to be all Zero: %v", postExtendPCR16)
+					}
+				})
+			}
+		})
+	}
+}