1

I am using the tpm 2 library to write (extend) and read from a PCR. However, I have observed that the values written to the PCR do not match the values read from it after writing. This suggests an inconsistency. Can someone help me with with this issue?

The source code:

package main

import (
    "fmt"
    "log"

    "github.com/google/go-tpm-tools/simulator"
    "github.com/google/go-tpm/tpm2"
    "github.com/google/go-tpm/tpmutil"
)

func main() {
    // Initialize the TPM simulator.
    sim, err := simulator.Get()
    if err != nil {
        log.Fatalf("failed to initialize sim: %v", err)
    }
    defer func(sim *simulator.Simulator) {
        err := sim.Close()
        if err != nil {
            log.Printf("failed to close sim: %v", err)
        }
    }(sim)

    // Extend a value into PCR 16.
    pcrIndex := 16
    pcr := tpmutil.Handle(pcrIndex)
    hash := []byte{180, 62, 62, 60, 193, 42, 73, 38, 4, 48, 163, 67, 240, 116, 35, 151, 125, 172, 172, 200, 140, 175, 141, 215, 94, 181, 12, 165, 44, 146, 178, 188}
    err = tpm2.PCRExtend(sim, pcr, tpm2.AlgSHA256, hash, "")
    if err != nil {
        log.Fatalf("failed to extend PCR: %v", err)
    }
    pcrValue, err := tpm2.ReadPCR(sim, pcrIndex, tpm2.AlgSHA256)
    if err != nil {
        log.Fatalf("failed to read PCR: %v", err)
    }

    // Compare the hash with the value read from the PCR.
    if fmt.Sprintf("%x", hash) == fmt.Sprintf("%x", pcrValue) {
        fmt.Println("PCR value matches the extended value.")
    } else {
        fmt.Println("PCR value does not match the extended value.")
        fmt.Printf("Expected: %x\n", hash)
        fmt.Printf("Actual:   %x\n", pcrValue)
    }
}

Output:

PCR value does not match the extended value.
Expected: b43e3e3cc12a49260430a343f07423977dacacc88caf8dd75eb50ca52c92b2bc
Actual:   ce132d926f5fa91481f6499d2bc01eb8e601233edb1b5e9a90954bd371372786
mkrieger1
  • 19,194
  • 5
  • 54
  • 65

1 Answers1

0

pcrValue equals sha256.Sum256(append(oldPCRValue, hash...)) instead of hash; where oldPCRValue is the PCR value before it's extended.

See TestPCRExtend in the package.

Here is the updated demo:

package main

import (
    "crypto/sha256"
    "fmt"
    "log"

    "github.com/google/go-tpm-tools/simulator"
    "github.com/google/go-tpm/tpm2"
    "github.com/google/go-tpm/tpmutil"
)

func main() {
    // Initialize the TPM simulator.
    sim, err := simulator.Get()
    if err != nil {
        log.Fatalf("failed to initialize sim: %v", err)
    }
    defer func() {
        err := sim.Close()
        if err != nil {
            log.Printf("failed to close sim: %v", err)
        }
    }()

    // Extend a value into PCR 16.
    pcrIndex := 16
    pcr := tpmutil.Handle(pcrIndex)

    oldPCRValue, err := tpm2.ReadPCR(sim, pcrIndex, tpm2.AlgSHA256)
    if err != nil {
        log.Fatalf("failed to read original PCR: %v", err)
    }

    hash := []byte{180, 62, 62, 60, 193, 42, 73, 38, 4, 48, 163, 67, 240, 116, 35, 151, 125, 172, 172, 200, 140, 175, 141, 215, 94, 181, 12, 165, 44, 146, 178, 188}

    err = tpm2.PCRExtend(sim, pcr, tpm2.AlgSHA256, hash, "")
    if err != nil {
        log.Fatalf("failed to extend PCR: %v", err)
    }
    pcrValue, err := tpm2.ReadPCR(sim, pcrIndex, tpm2.AlgSHA256)
    if err != nil {
        log.Fatalf("failed to read PCR: %v", err)
    }

    finalPCR := sha256.Sum256(append(oldPCRValue, hash...))
    // Compare the hash with the value read from the PCR.
    if fmt.Sprintf("%x", finalPCR) == fmt.Sprintf("%x", pcrValue) {
        fmt.Println("PCR value matches the extended value.")
    } else {
        fmt.Println("PCR value does not match the extended value.")
        fmt.Printf("Expected: %x\n", finalPCR)
        fmt.Printf("Actual:   %x\n", pcrValue)
    }
}
Zeke Lu
  • 6,349
  • 1
  • 17
  • 23