github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/tss/pcr.go (about)

     1  // Copyright 2020 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package tss
     6  
     7  import (
     8  	"fmt"
     9  	"io"
    10  
    11  	"github.com/google/go-tpm/tpm"
    12  	"github.com/google/go-tpm/tpm2"
    13  	"github.com/google/go-tpm/tpmutil"
    14  )
    15  
    16  func extendPCR12(rwc io.ReadWriter, pcrIndex uint32, hash [20]byte) error {
    17  	if _, err := tpm.PcrExtend(rwc, pcrIndex, hash); err != nil {
    18  		return err
    19  	}
    20  	return nil
    21  }
    22  
    23  func extendPCR20(rwc io.ReadWriter, pcrIndex uint32, hash []byte) error {
    24  	if err := tpm2.PCRExtend(rwc, tpmutil.Handle(pcrIndex), tpm2.AlgSHA256, hash, ""); err != nil {
    25  		return err
    26  	}
    27  	return nil
    28  }
    29  
    30  func readAllPCRs20(tpm io.ReadWriter, alg tpm2.Algorithm) (map[uint32][]byte, error) {
    31  	numPCRs := 24
    32  	out := map[uint32][]byte{}
    33  
    34  	// The TPM 2.0 spec says that the TPM can partially fulfill the
    35  	// request. As such, we repeat the command up to 8 times to get all
    36  	// 24 PCRs.
    37  	for i := 0; i < numPCRs; i++ {
    38  		// Build a selection structure, specifying all PCRs we do
    39  		// not have the value for.
    40  		sel := tpm2.PCRSelection{Hash: alg}
    41  		for pcr := 0; pcr < numPCRs; pcr++ {
    42  			if _, present := out[uint32(pcr)]; !present {
    43  				sel.PCRs = append(sel.PCRs, pcr)
    44  			}
    45  		}
    46  
    47  		// Ask the TPM for those PCR values.
    48  		ret, err := tpm2.ReadPCRs(tpm, sel)
    49  		if err != nil {
    50  			return nil, fmt.Errorf("tpm2.ReadPCRs(%+v) failed with err: %v", sel, err)
    51  		}
    52  		// Keep track of the PCRs we were actually given.
    53  		for pcr, digest := range ret {
    54  			out[uint32(pcr)] = digest
    55  		}
    56  		if len(out) == numPCRs {
    57  			break
    58  		}
    59  	}
    60  
    61  	if len(out) != numPCRs {
    62  		return nil, fmt.Errorf("failed to read all PCRs, only read %d", len(out))
    63  	}
    64  
    65  	return out, nil
    66  }
    67  
    68  func readAllPCRs12(rwc io.ReadWriter) (map[uint32][]byte, error) {
    69  	numPCRs := 24
    70  	out := map[uint32][]byte{}
    71  
    72  	for i := 0; i < numPCRs; i++ {
    73  		// Ask the TPM for those PCR values.
    74  		pcr, err := tpm.ReadPCR(rwc, uint32(i))
    75  		if err != nil {
    76  			return nil, fmt.Errorf("tpm.ReadPCR(%d) failed with err: %v", i, err)
    77  		}
    78  		out[uint32(i)] = pcr
    79  		if len(out) == numPCRs {
    80  			break
    81  		}
    82  	}
    83  
    84  	if len(out) != numPCRs {
    85  		return nil, fmt.Errorf("failed to read all PCRs, only read %d", len(out))
    86  	}
    87  
    88  	return out, nil
    89  }
    90  
    91  func readPCR12(rwc io.ReadWriter, pcrIndex uint32) ([]byte, error) {
    92  	return tpm.ReadPCR(rwc, pcrIndex)
    93  }
    94  
    95  func readPCR20(rwc io.ReadWriter, pcrIndex uint32) ([]byte, error) {
    96  	return tpm2.ReadPCR(rwc, int(pcrIndex), tpm2.AlgSHA256)
    97  }