Repository: google/go-tpm
Pull request #103 (2019-05-07 10:27:50)

CapabilityPCRs
Implements GetCapability-Case for CapabilityPCRs. Extends decodeTPMLPCRSelection for multiple PCRSelections.

googlebot: 
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

:memo: **Please visit <https://cla.developers.google.com/> to sign.**

Once you've signed (or fixed any issues), please reply here (e.g. `I signed it!`) and we'll verify it.

----

#### What to do if you already signed the CLA

##### Individual signers

*   It's possible we don't have your GitHub username or you're using a different email address on your commit. Check [your existing CLA data](https://cla.developers.google.com/clas) and verify that your [email is set on your git commits](https://help.github.com/articles/setting-your-email-in-git/).

##### Corporate signers

*   Your company has a Point of Contact who decides which employees are authorized to participate. Ask your POC to be added to the group of authorized contributors. If you don't know who your Point of Contact is, direct the Google project maintainer to [go/cla#troubleshoot](http://go/cla#troubleshoot) ([Public version](https://opensource.google.com/docs/cla/#troubleshoot)).
*   The email used to register you as an authorized contributor must be the email used for the Git commit. Check [your existing CLA data](https://cla.developers.google.com/clas) and verify that your [email is set on your git commits](https://help.github.com/articles/setting-your-email-in-git/).
*   The email used to register you as an authorized contributor must also be [attached to your GitHub account](https://github.com/settings/emails).
		

ℹ️ **Googlers: [Go here](https://goto.google.com/prinfo/https%3A%2F%2Fgithub.com%2Fgoogle%2Fgo-tpm%2Fpull%2F103) for more info**.

<!-- need_sender_cla -->
ChriMarMe: I signed it !
googlebot: CLAs look good, thanks!

ℹ️ **Googlers: [Go here](https://goto.google.com/prinfo/https%3A%2F%2Fgithub.com%2Fgoogle%2Fgo-tpm%2Fpull%2F103) for more info**.

<!-- ok -->
awly: Also make sure `go test` passes. Currently there's a failing test: https://source.cloud.google.com/results/invocations/f8261f83-189d-4d43-9f00-2f1329561c07/targets/go-tpm%2Fgoogle_presubmit/log
In case you don't have access to that link:

```
?   	github.com/google/go-tpm/examples/tpm-clear	[no test files]
?   	github.com/google/go-tpm/examples/tpm-genaik	[no test files]
?   	github.com/google/go-tpm/examples/tpm-keys	[no test files]
?   	github.com/google/go-tpm/examples/tpm-sign	[no test files]
?   	github.com/google/go-tpm/examples/tpm-takeownership	[no test files]
?   	github.com/google/go-tpm/examples/tpm2-ekcert	[no test files]
?   	github.com/google/go-tpm/examples/tpm2-nvread	[no test files]
?   	github.com/google/go-tpm/examples/tpm2-seal-unseal	[no test files]
ok  	github.com/google/go-tpm/tpm	0.013s
--- FAIL: TestEncodeDecodeTPMLSelection (0.00s)
    encoding_test.go:51: after decoding: [{Hash:4 PCRs:[7]}], before encoding: {Hash:4 PCRs:[7]}
FAIL
FAIL	github.com/google/go-tpm/tpm2	0.014s
ok  	github.com/google/go-tpm/tpm2/credactivation	0.005s
ok  	github.com/google/go-tpm/tpmutil	0.003s
?   	github.com/google/go-tpm/tpmutil/mssim	[no test files]
```
ChriMarMe: Some problems pop up here. I see two possible approaches, but maybe I miss some.

Variadic encode-function: 
Argument of encode-function and return-value of decode-function differ. Which could be a problem of complexity in later use. User always needs to remember that encode- and decode-functions do not operate the same data-structures. Also test will continue to fail.

Encode-function with slice as argument: 
User needs to create a slice of PCRSelection and pass it to the function. So every time even if only one PCRSelection needs to be encoded, user have to build a slice of PCRSelection around it. This also is some kind of extra complexity for users. Test will pass in this solution (I guess)

I'm thankful for a word of advice.  


awly: Either way should work fine and won't be too hard for readers to understand.
I lean slightly towards variadic argument to encode, but up to you.

Tests must get fixed regardless.

Patch:
diff --git a/tpm2/structures.go b/tpm2/structures.go
index 8bde1a4..05ceaee 100644
--- a/tpm2/structures.go
+++ b/tpm2/structures.go
@@ -684,11 +684,12 @@ type QuoteInfo struct {
 
 func decodeQuoteInfo(in *bytes.Buffer) (*QuoteInfo, error) {
 	var out QuoteInfo
-	sel, err := decodeTPMLPCRSelection(in)
+	sel, err := decodeOneTPMLPCRSelection(in)
 	if err != nil {
 		return nil, fmt.Errorf("decoding PCRSelection: %v", err)
 	}
 	out.PCRSelection = sel
+
 	if err := tpmutil.UnpackBuf(in, &out.PCRDigest); err != nil {
 		return nil, fmt.Errorf("decoding PCRDigest: %v", err)
 	}
@@ -755,9 +756,9 @@ func DecodeCreationData(buf []byte) (*CreationData, error) {
 	in := bytes.NewBuffer(buf)
 	var out CreationData
 
-	sel, err := decodeTPMLPCRSelection(in)
+	sel, err := decodeOneTPMLPCRSelection(in)
 	if err != nil {
-		return nil, fmt.Errorf("decoding PCRSelection: %v", err)
+		return nil, fmt.Errorf("decodeOneTPMLPCRSelection returned error %v", err)
 	}
 	out.PCRSelection = sel
 
diff --git a/tpm2/tpm2.go b/tpm2/tpm2.go
index 5ae0064..b1e1807 100644
--- a/tpm2/tpm2.go
+++ b/tpm2/tpm2.go
@@ -51,8 +51,8 @@ func FlushContext(rw io.ReadWriter, handle tpmutil.Handle) error {
 	return err
 }
 
-func encodeTPMLPCRSelection(sel PCRSelection) ([]byte, error) {
-	if len(sel.PCRs) == 0 {
+func encodeTPMLPCRSelection(sel ...PCRSelection) ([]byte, error) {
+	if len(sel) == 0 {
 		return tpmutil.Pack(uint32(0))
 	}
 
@@ -64,59 +64,92 @@ func encodeTPMLPCRSelection(sel PCRSelection) ([]byte, error) {
 	// For example, selecting PCRs 3 and 9 looks like:
 	// size(3)  mask     mask     mask
 	// 00000011 00000000 00000001 00000100
-	ts := tpmsPCRSelection{
-		Hash: sel.Hash,
-		Size: sizeOfPCRSelect,
-		PCRs: make(tpmutil.RawBytes, sizeOfPCRSelect),
+	var retBytes []byte
+	for _, s := range sel {
+		if len(s.PCRs) == 0 {
+			return tpmutil.Pack(uint32(0))
+		}
+
+		ts := tpmsPCRSelection{
+			Hash: s.Hash,
+			Size: sizeOfPCRSelect,
+			PCRs: make(tpmutil.RawBytes, sizeOfPCRSelect),
+		}
+
+		// s[i].PCRs parameter is indexes of PCRs, convert that to set bits.
+		for _, n := range s.PCRs {
+			byteNum := n / 8
+			bytePos := byte(1 << byte(n%8))
+			ts.PCRs[byteNum] |= bytePos
+		}
+
+		tmpBytes, err := tpmutil.Pack(ts)
+		if err != nil {
+			return nil, err
+		}
+
+		retBytes = append(retBytes, tmpBytes...)
 	}
-	// sel.PCRs parameter is indexes of PCRs, convert that to set bits.
-	for _, n := range sel.PCRs {
-		byteNum := n / 8
-		bytePos := byte(1 << byte(n%8))
-		ts.PCRs[byteNum] |= bytePos
+	tmpSize, err := tpmutil.Pack(uint32(len(sel)))
+	if err != nil {
+		return nil, err
 	}
-	// Only encode 1 TPMS_PCR_SELECT value.
-	return tpmutil.Pack(uint32(1), ts)
+	retBytes = append(tmpSize, retBytes...)
+
+	return retBytes, nil
 }
 
-func decodeTPMLPCRSelection(buf *bytes.Buffer) (PCRSelection, error) {
+func decodeTPMLPCRSelection(buf *bytes.Buffer) ([]PCRSelection, error) {
 	var count uint32
-	var sel PCRSelection
+	var sel []PCRSelection
+
+	// This unpacks buffer which is of type TPMLPCRSelection
+	// and returns the count of TPMSPCRSelections.
 	if err := tpmutil.UnpackBuf(buf, &count); err != nil {
 		return sel, err
 	}
-	switch count {
-	case 0:
-		sel.Hash = AlgUnknown
-		return sel, nil
-	case 1: // We only support decoding of a single PCRSelection.
-	default:
-		return sel, fmt.Errorf("decoding TPML_PCR_SELECTION list longer than 1 is not supported (got length %d)", count)
-	}
 
-	// See comment in encodeTPMLPCRSelection for details on this format.
 	var ts tpmsPCRSelection
-	if err := tpmutil.UnpackBuf(buf, &ts.Hash, &ts.Size); err != nil {
-		return sel, err
-	}
-	ts.PCRs = make(tpmutil.RawBytes, ts.Size)
-	if _, err := buf.Read(ts.PCRs); err != nil {
-		return sel, err
-	}
-
-	sel.Hash = ts.Hash
-	for i := 0; i < int(ts.Size); i++ {
-		for j := 0; j < 8; j++ {
-			set := ts.PCRs[i] & byte(1<<byte(j))
-			if set == 0 {
-				continue
+	for i := 0; i < int(count); i++ {
+		var s PCRSelection
+		if err := tpmutil.UnpackBuf(buf, &ts.Hash, &ts.Size); err != nil {
+			return sel, err
+		}
+		ts.PCRs = make(tpmutil.RawBytes, ts.Size)
+		if _, err := buf.Read(ts.PCRs); err != nil {
+			return sel, err
+		}
+		s.Hash = ts.Hash
+		for j := 0; j < int(ts.Size); j++ {
+			for k := 0; k < 8; k++ {
+				set := ts.PCRs[j] & byte(1<<byte(k))
+				if set == 0 {
+					continue
+				}
+				s.PCRs = append(s.PCRs, 8*j+k)
 			}
-			sel.PCRs = append(sel.PCRs, 8*i+j)
 		}
+		sel = append(sel, s)
+	}
+	if len(sel) == 0 {
+		sel = append(sel, PCRSelection{
+			Hash: AlgUnknown,
+		})
 	}
 	return sel, nil
 }
 
+func decodeOneTPMLPCRSelection(buf *bytes.Buffer) (PCRSelection, error) {
+	sels, err := decodeTPMLPCRSelection(buf)
+	if err != nil {
+		return PCRSelection{}, err
+	}
+	if len(sels) != 1 {
+		return PCRSelection{}, fmt.Errorf("got %d TPMS_PCR_SELECTION items in TPML_PCR_SELECTION, expected 1", len(sels))
+	}
+	return sels[0], nil
+}
+
 func decodeReadPCRs(in []byte) (map[int][]byte, error) {
 	buf := bytes.NewBuffer(in)
 	var updateCounter uint32
@@ -124,9 +157,9 @@ func decodeReadPCRs(in []byte) (map[int][]byte, error) {
 		return nil, err
 	}
 
-	sel, err := decodeTPMLPCRSelection(buf)
+	sel, err := decodeOneTPMLPCRSelection(buf)
 	if err != nil {
-		return nil, fmt.Errorf("decoding TPML_PCR_SELECTION: %v", err)
+		return nil, err
 	}
 
 	var digestCount uint32
@@ -242,6 +275,18 @@ func decodeGetCapability(in []byte) ([]interface{}, bool, error) {
 		}
 		return props, moreData > 0, nil
 
+	case CapabilityPCRs:
+		var pcrss []interface{}
+		pcrs, err := decodeTPMLPCRSelection(buf)
+		if err != nil {
+			return nil, false, fmt.Errorf("could not unpack pcr selection: %v", err)
+		}
+		for i := 0; i < len(pcrs); i++ {
+			pcrss = append(pcrss, pcrs[i])
+		}
+
+		return pcrss, moreData > 0, nil
+
 	default:
 		return nil, false, fmt.Errorf("unsupported capability %v", capReported)
 	}


Test patch:
diff --git a/tpm2/benchmark_test.go b/tpm2/benchmark_test.go
index c45d133..4109490 100644
--- a/tpm2/benchmark_test.go
+++ b/tpm2/benchmark_test.go
@@ -39,7 +39,7 @@ func BenchmarkRSA2048Signing(b *testing.B) {
 		},
 	}
 
-	signerHandle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection, emptyPassword, defaultPassword, pub)
+	signerHandle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection7, emptyPassword, defaultPassword, pub)
 	if err != nil {
 		b.Fatalf("CreatePrimary failed: %v", err)
 	}
@@ -74,7 +74,7 @@ func BenchmarkECCNISTP256Signing(b *testing.B) {
 		},
 	}
 
-	signerHandle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection, emptyPassword, defaultPassword, pub)
+	signerHandle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection7, emptyPassword, defaultPassword, pub)
 	if err != nil {
 		b.Fatalf("CreatePrimary failed: %v", err)
 	}
diff --git a/tpm2/encoding_test.go b/tpm2/encoding_test.go
index a452c3f..f142b03 100644
--- a/tpm2/encoding_test.go
+++ b/tpm2/encoding_test.go
@@ -37,8 +37,24 @@ func TestDecodeReadPCRs(t *testing.T) {
 	}
 }
 
-func TestEncodeDecodeTPMLSelection(t *testing.T) {
-	buf, err := encodeTPMLPCRSelection(pcrSelection)
+func TestSingleEncodeDecodeTPMLSelection(t *testing.T) {
+	buf, err := encodeTPMLPCRSelection(pcrSelection7)
+	if err != nil {
+		t.Fatal(err)
+	}
+	got, err := decodeOneTPMLPCRSelection(bytes.NewBuffer(buf))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if !reflect.DeepEqual(got, pcrSelection7) {
+		t.Errorf("after decoding: %+v, before encoding: %+v", got, pcrSelection7)
+	}
+}
+
+func TestMultiArgsEncodeDecodeTPMLSelection(t *testing.T) {
+	multipcrselection := []PCRSelection{pcrSelection0, pcrSelection1, pcrSelection7}
+	buf, err := encodeTPMLPCRSelection(multipcrselection...)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -47,8 +63,8 @@ func TestEncodeDecodeTPMLSelection(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if !reflect.DeepEqual(got, pcrSelection) {
-		t.Errorf("after decoding: %+v, before encoding: %+v", got, pcrSelection)
+	if !reflect.DeepEqual(got, multipcrselection) {
+		t.Errorf("after decoding: %+v, before encoding %+v", got, multipcrselection)
 	}
 }
 
@@ -130,7 +146,7 @@ func TestEncodeCreate(t *testing.T) {
 			Modulus:  big.NewInt(0),
 		},
 	}
-	cmdBytes, err := encodeCreate(HandleOwner, pcrSelection, "", defaultPassword, []byte{255} /*sensitiveData*/, params)
+	cmdBytes, err := encodeCreate(HandleOwner, pcrSelection7, "", defaultPassword, []byte{255} /*sensitiveData*/, params)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -164,7 +180,7 @@ func TestEncodePolicyPCR(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	cmdBytes, err := encodePolicyPCR(tpmutil.Handle(0x03000000), []byte(nil), pcrSelection)
+	cmdBytes, err := encodePolicyPCR(tpmutil.Handle(0x03000000), []byte(nil), pcrSelection7)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -239,7 +255,7 @@ func TestEncodeQuote(t *testing.T) {
 		t.Fatal(err)
 	}
 	toQuote := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10}
-	cmdBytes, err := encodeQuote(tpmutil.Handle(0x80000001), defaultPassword, "", toQuote, pcrSelection, 0x0010)
+	cmdBytes, err := encodeQuote(tpmutil.Handle(0x80000001), defaultPassword, "", toQuote, pcrSelection7, 0x0010)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -334,7 +350,7 @@ func TestEncodeSensitiveArea(t *testing.T) {
 }
 
 func TestEncodeTPMLPCRSelection(t *testing.T) {
-	s, err := encodeTPMLPCRSelection(pcrSelection)
+	s, err := encodeTPMLPCRSelection(pcrSelection7)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/tpm2/tpm2_test.go b/tpm2/tpm2_test.go
index 62cf750..530350c 100644
--- a/tpm2/tpm2_test.go
+++ b/tpm2/tpm2_test.go
@@ -79,7 +79,9 @@ func (s simulator) Close() error {
 
 var (
 	// PCR7 is for SecureBoot.
-	pcrSelection     = PCRSelection{Hash: AlgSHA1, PCRs: []int{7}}
+	pcrSelection0    = PCRSelection{Hash: AlgSHA1, PCRs: []int{0}}
+	pcrSelection1    = PCRSelection{Hash: AlgSHA1, PCRs: []int{1}}
+	pcrSelection7    = PCRSelection{Hash: AlgSHA1, PCRs: []int{7}}
 	defaultKeyParams = Public{
 		Type:       AlgRSA,
 		NameAlg:    AlgSHA1,
@@ -120,7 +122,7 @@ func TestReadPCRs(t *testing.T) {
 	rw := openTPM(t)
 	defer rw.Close()
 
-	pcrs, err := ReadPCRs(rw, pcrSelection)
+	pcrs, err := ReadPCRs(rw, pcrSelection7)
 	if err != nil {
 		t.Errorf("ReadPCRs failed: %s", err)
 	}
@@ -171,13 +173,13 @@ func TestCombinedKeyTest(t *testing.T) {
 	rw := openTPM(t)
 	defer rw.Close()
 
-	parentHandle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection, emptyPassword, defaultPassword, defaultKeyParams)
+	parentHandle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection7, emptyPassword, defaultPassword, defaultKeyParams)
 	if err != nil {
 		t.Fatalf("CreatePrimary failed: %s", err)
 	}
 	defer FlushContext(rw, parentHandle)
 
-	_, privateBlob, publicBlob, _, _, _, err := CreateKey(rw, parentHandle, pcrSelection, defaultPassword, defaultPassword, defaultKeyParams)
+	_, privateBlob, publicBlob, _, _, _, err := CreateKey(rw, parentHandle, pcrSelection7, defaultPassword, defaultPassword, defaultKeyParams)
 	if err != nil {
 		t.Fatalf("CreateKey failed: %s", err)
 	}
@@ -197,13 +199,13 @@ func TestCombinedEndorsementTest(t *testing.T) {
 	rw := openTPM(t)
 	defer rw.Close()
 
-	parentHandle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection, emptyPassword, emptyPassword, defaultKeyParams)
+	parentHandle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection7, emptyPassword, emptyPassword, defaultKeyParams)
 	if err != nil {
 		t.Fatalf("CreatePrimary failed: %s", err)
 	}
 	defer FlushContext(rw, parentHandle)
 
-	_, privateBlob, publicBlob, _, _, _, err := CreateKey(rw, parentHandle, pcrSelection, emptyPassword, defaultPassword, defaultKeyParams)
+	_, privateBlob, publicBlob, _, _, _, err := CreateKey(rw, parentHandle, pcrSelection7, emptyPassword, defaultPassword, defaultKeyParams)
 	if err != nil {
 		t.Fatalf("CreateKey failed: %s", err)
 	}
@@ -271,7 +273,7 @@ func TestCreatePrimaryEx(t *testing.T) {
 	rw := openTPM(t)
 	defer rw.Close()
 
-	keyHandle, pub1, creation, _, _, name, err := CreatePrimaryEx(rw, HandleOwner, pcrSelection, emptyPassword, emptyPassword, defaultKeyParams)
+	keyHandle, pub1, creation, _, _, name, err := CreatePrimaryEx(rw, HandleOwner, pcrSelection7, emptyPassword, emptyPassword, defaultKeyParams)
 	if err != nil {
 		t.Fatalf("CreatePrimary failed: %v", err)
 	}
@@ -304,14 +306,14 @@ func TestCombinedContextTest(t *testing.T) {
 	rw := openTPM(t)
 	defer rw.Close()
 
-	rootHandle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection, emptyPassword, emptyPassword, defaultKeyParams)
+	rootHandle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection7, emptyPassword, emptyPassword, defaultKeyParams)
 	if err != nil {
 		t.Fatalf("CreatePrimary failed: %v", err)
 	}
 	defer FlushContext(rw, rootHandle)
 
 	// CreateKey (Quote Key)
-	_, quotePrivate, quotePublic, _, _, _, err := CreateKey(rw, rootHandle, pcrSelection, emptyPassword, emptyPassword, defaultKeyParams)
+	_, quotePrivate, quotePublic, _, _, _, err := CreateKey(rw, rootHandle, pcrSelection7, emptyPassword, emptyPassword, defaultKeyParams)
 	if err != nil {
 		t.Fatalf("CreateKey failed: %v", err)
 	}
@@ -338,14 +340,14 @@ func TestEvictControl(t *testing.T) {
 	rw := openTPM(t)
 	defer rw.Close()
 
-	rootHandle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection, emptyPassword, emptyPassword, defaultKeyParams)
+	rootHandle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection7, emptyPassword, emptyPassword, defaultKeyParams)
 	if err != nil {
 		t.Fatalf("CreatePrimary failed: %v", err)
 	}
 	defer FlushContext(rw, rootHandle)
 
 	// CreateKey (Quote Key)
-	_, quotePrivate, quotePublic, _, _, _, err := CreateKey(rw, rootHandle, pcrSelection, emptyPassword, emptyPassword, defaultKeyParams)
+	_, quotePrivate, quotePublic, _, _, _, err := CreateKey(rw, rootHandle, pcrSelection7, emptyPassword, emptyPassword, defaultKeyParams)
 	if err != nil {
 		t.Fatalf("CreateKey failed: %v", err)
 	}
@@ -491,13 +493,13 @@ func TestCertify(t *testing.T) {
 			Modulus: big.NewInt(0),
 		},
 	}
-	signerHandle, signerPub, err := CreatePrimary(rw, HandleOwner, pcrSelection, emptyPassword, defaultPassword, params)
+	signerHandle, signerPub, err := CreatePrimary(rw, HandleOwner, pcrSelection7, emptyPassword, defaultPassword, params)
 	if err != nil {
 		t.Fatalf("CreatePrimary(signer) failed: %s", err)
 	}
 	defer FlushContext(rw, signerHandle)
 
-	subjectHandle, subjectPub, err := CreatePrimary(rw, HandlePlatform, pcrSelection, emptyPassword, defaultPassword, params)
+	subjectHandle, subjectPub, err := CreatePrimary(rw, HandlePlatform, pcrSelection7, emptyPassword, defaultPassword, params)
 	if err != nil {
 		t.Fatalf("CreatePrimary(subject) failed: %s", err)
 	}
@@ -561,7 +563,7 @@ func TestCertifyExternalKey(t *testing.T) {
 			Modulus: big.NewInt(0),
 		},
 	}
-	signerHandle, signerPub, err := CreatePrimary(rw, HandleOwner, pcrSelection, emptyPassword, defaultPassword, params)
+	signerHandle, signerPub, err := CreatePrimary(rw, HandleOwner, pcrSelection7, emptyPassword, defaultPassword, params)
 	if err != nil {
 		t.Fatalf("CreatePrimary(signer) failed: %s", err)
 	}
@@ -643,7 +645,7 @@ func TestSign(t *testing.T) {
 	defer rw.Close()
 
 	run := func(t *testing.T, pub Public) {
-		signerHandle, signerPub, err := CreatePrimary(rw, HandleOwner, pcrSelection, emptyPassword, defaultPassword, pub)
+		signerHandle, signerPub, err := CreatePrimary(rw, HandleOwner, pcrSelection7, emptyPassword, defaultPassword, pub)
 		if err != nil {
 			t.Fatalf("CreatePrimary failed: %s", err)
 		}
@@ -970,7 +972,7 @@ func TestCreateAndCertifyCreation(t *testing.T) {
 			Modulus: big.NewInt(0),
 		},
 	}
-	keyHandle, pub, _, creationHash, tix, _, err := CreatePrimaryEx(rw, HandleEndorsement, pcrSelection, emptyPassword, emptyPassword, params)
+	keyHandle, pub, _, creationHash, tix, _, err := CreatePrimaryEx(rw, HandleEndorsement, pcrSelection7, emptyPassword, emptyPassword, params)
 	if err != nil {
 		t.Fatalf("CreatePrimaryEx failed: %s", err)
 	}
@@ -1092,13 +1094,13 @@ func TestQuote(t *testing.T) {
 			Modulus: big.NewInt(0),
 		},
 	}
-	keyHandle, pub, _, _, _, _, err := CreatePrimaryEx(rw, HandleEndorsement, pcrSelection, emptyPassword, emptyPassword, params)
+	keyHandle, pub, _, _, _, _, err := CreatePrimaryEx(rw, HandleEndorsement, pcrSelection7, emptyPassword, emptyPassword, params)
 	if err != nil {
 		t.Fatalf("CreatePrimaryEx failed: %s", err)
 	}
 	defer FlushContext(rw, keyHandle)
 
-	attestation, signature, err := Quote(rw, keyHandle, emptyPassword, emptyPassword, nil, pcrSelection, AlgNull)
+	attestation, signature, err := Quote(rw, keyHandle, emptyPassword, emptyPassword, nil, pcrSelection7, AlgNull)
 	if err != nil {
 		t.Fatalf("Quote failed: %v", err)
 	}
@@ -1209,7 +1211,7 @@ func TestEncryptDecrypt(t *testing.T) {
 	rw := openTPM(t)
 	defer rw.Close()
 
-	parentHandle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection, emptyPassword, defaultPassword, Public{
+	parentHandle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection7, emptyPassword, defaultPassword, Public{
 		Type:       AlgRSA,
 		NameAlg:    AlgSHA256,
 		Attributes: FlagRestricted | FlagDecrypt | FlagUserWithAuth | FlagFixedParent | FlagFixedTPM | FlagSensitiveDataOrigin,
@@ -1227,7 +1229,7 @@ func TestEncryptDecrypt(t *testing.T) {
 		t.Fatalf("CreatePrimary failed: %s", err)
 	}
 	defer FlushContext(rw, parentHandle)
-	_, privateBlob, publicBlob, _, _, _, err := CreateKey(rw, parentHandle, pcrSelection, defaultPassword, defaultPassword, Public{
+	_, privateBlob, publicBlob, _, _, _, err := CreateKey(rw, parentHandle, pcrSelection7, defaultPassword, defaultPassword, Public{
 		Type:       AlgSymCipher,
 		NameAlg:    AlgSHA256,
 		Attributes: FlagDecrypt | FlagSign | FlagUserWithAuth | FlagFixedParent | FlagFixedTPM | FlagSensitiveDataOrigin,
@@ -1271,7 +1273,7 @@ func TestRSAEncryptDecrypt(t *testing.T) {
 	rw := openTPM(t)
 	defer rw.Close()
 
-	handle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection, emptyPassword, defaultPassword, Public{
+	handle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection7, emptyPassword, defaultPassword, Public{
 		Type:       AlgRSA,
 		NameAlg:    AlgSHA256,
 		Attributes: FlagDecrypt | FlagUserWithAuth | FlagFixedParent | FlagFixedTPM | FlagSensitiveDataOrigin,