使用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哈希)计算新值。
验证计算过程
以你的代码为例:
- PCR16初始值是SHA256的空值:
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 - 将初始值与你传入的
hash拼接:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855b43e3e3cc12a49260430a343f07423977dacacc88caf8dd75eb50ca52c92b2bc - 对拼接后的字节做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
相关产品推荐
相关产品推荐

