google / go-tpm-tools

Go packages built on go-tpm providing a high-level API for using TPMs
Apache License 2.0
231 stars 71 forks source link

failed to validate the PCClient event log in VMware #223

Open GastonMeghi opened 2 years ago

GastonMeghi commented 2 years ago

I've created the following script for testing proposes and I'm running it on a VMware VM with a virtualized TPM with RHEL8 as the OS. I got the following error when running server.VerifyAttestation:

failed to validate the PCClient event log: failed to replay event log: event log failed to verify: the following registers failed to replay: [0]

Is this expected to happen? I'm thinking about testing this on my real machine with the actual TPM but I afraid to break something.

The code is pretty much the same as the verify_test.go one but using VMwares virtualized TPM.

`package main

import ( "crypto" "fmt"

"github.com/google/go-tpm-tools/client"
"github.com/google/go-tpm-tools/server"
"github.com/google/go-tpm/tpm2"

)

func main() {

tpm, err := tpm2.OpenTPM()
if err != nil {
    fmt.Println("[ERROR] opening tpm failed: ", err)
    return
}

AttestationKeyRSA, err := client.AttestationKeyRSA(tpm)
defer AttestationKeyRSA.Close()

if err != nil {
    fmt.Println("[ERROR] RSA AK Creation failed: ", err)
    return
}
fmt.Println("[INFO] AK Created: ", AttestationKeyRSA)

nonce, err := tpm2.GetRandom(tpm, 15)

if err != nil {
    fmt.Println("[ERROR] nonce creation failed: ", err)
    return
}
fmt.Println("[INFO] nonce Created: ", nonce)

attestation, err := AttestationKeyRSA.Attest(client.AttestOpts{Nonce: nonce})

if err != nil {
    fmt.Println("[ERROR] Attestation failed: ", err)
    return
}

MachineState, err := server.VerifyAttestation(attestation, server.VerifyOpts{
    Nonce:      nonce,
    TrustedAKs: []crypto.PublicKey{AttestationKeyRSA.PublicKey()},
})

if err != nil {
    // handle error
    fmt.Println("[ERROR] VerifyAttestation failed: ", err)
    return
}

fmt.Println("INFO: Grub State", MachineState)

}`

alexmwu commented 2 years ago

This is not unexpected. See https://github.com/google/go-tpm-tools/issues/141 for another example.

Basically, this error means the event log located at /sys/kernel/security/tpm0/binary_bios_measurements failed to replay against PCR0 (BIOS measurements, including CRTM). It could be a firmware bug as firmware has been known to log a different measurement in the event log than what they measure into the TPM.

Feel free to dump that here and I can take a look, or you can also examine the event log yourself by running tpm2_eventlog /sys/kernel/security/tpm0/binary_bios_measurements. (https://github.com/tpm2-software/tpm2-tools/blob/master/man/tpm2_eventlog.1.md)

GastonMeghi commented 2 years ago

okay, no worries! I can check it. One question though, how risky is it to run this types of routines agains the real TPM? I don't need to do more than a credential activation to verify that the AK comes from a real TPM as shown on the readme of go attestation, and after that do boot measurements. I think it's risk free right? Because I tried this same program on ubuntu 22.04 and it didn't work also. It might be VMware the one causing issues.

alexmwu commented 2 years ago

I think the only mutating command you're running above is in creating the AttestationKey: AttestationKeyRSA, err := client.AttestationKeyRSA(tpm). This is cached, however, and should not create a new one if you call it again (provided the template is the same)

Everything else reads from the TPM or the firmware event log and does not modify the TPM.