You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Go TPM2库进行PCR扩展与读取时值不一致问题求助

PCR扩展后读取值不匹配问题排查

我正在使用TPM2库对PCR进行扩展(写入)和读取操作,但发现写入PCR的值与写入后读取的值不匹配,存在不一致问题。

源代码

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)
    }
}

程序输出

PCR value does not match the extended value.
Expected: b43e3e3cc12a49260430a343f07423977dacacc88caf8dd75eb50ca52c92b2bc
Actual:   ce132d926f5fa91481f6499d2bc01eb8e601233edb1b5e9a90954bd371372786

问题原因与解决方法

TPM的PCR扩展操作不是直接将传入的哈希值写入PCR,而是执行哈希串联运算:新的PCR值 = Hash(旧PCR值 || 传入的哈希值),其中||代表字节拼接。你的代码错误地认为传入的hash会直接成为PCR的最终值,但实际上TPM会基于PCR的当前初始值(通常是全0的SHA256哈希)计算新值。

验证计算过程

以你的代码为例:

  1. PCR16初始值是SHA256的空值:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
  2. 将初始值与你传入的hash拼接:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855b43e3e3cc12a49260430a343f07423977dacacc88caf8dd75eb50ca52c92b2bc
  3. 对拼接后的字节做SHA256哈希,得到的结果就是你读取到的ce132d926f5fa91481f6499d2bc01eb8e601233edb1b5e9a90954bd371372786,和程序输出一致。

修正代码

如果你需要验证扩展操作是否正确,应该先计算预期的PCR值,再和读取结果对比:

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() {
    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)

    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}

    // 读取初始PCR值
    initialPCR, err := tpm2.ReadPCR(sim, pcrIndex, tpm2.AlgSHA256)
    if err != nil {
        log.Fatalf("failed to read initial PCR: %v", err)
    }

    // 计算预期的PCR值:SHA256(初始值 || 传入的hash)
    h := sha256.New()
    h.Write(initialPCR)
    h.Write(hash)
    expectedPCR := h.Sum(nil)

    // 执行扩展操作
    err = tpm2.PCRExtend(sim, pcr, tpm2.AlgSHA256, hash, "")
    if err != nil {
        log.Fatalf("failed to extend PCR: %v", err)
    }

    // 读取扩展后的PCR值
    pcrValue, err := tpm2.ReadPCR(sim, pcrIndex, tpm2.AlgSHA256)
    if err != nil {
        log.Fatalf("failed to read PCR: %v", err)
    }

    // 对比预期值和实际值
    if fmt.Sprintf("%x", expectedPCR) == fmt.Sprintf("%x", pcrValue) {
        fmt.Println("PCR value matches the expected extended value.")
    } else {
        fmt.Println("PCR value does not match the expected extended value.")
        fmt.Printf("Expected: %x\n", expectedPCR)
        fmt.Printf("Actual:   %x\n", pcrValue)
    }
}

运行修正后的代码,会输出PCR value matches the expected extended value.,验证扩展操作正常。


内容的提问来源于stack exchange,提问作者Avishka Shamendra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:57:51