this is somewhat related to the post in: Perform OR on two hash outputs of sha1sum

I have a sample set of TPM measurements, e.g. the following:

10 1ca03ef9cca98b0a04e5b01dabe1ff825ff0280a ima 0ea26e75253dc2fda7e4210980537d035e2fb9f8         boot_aggregate
10 7f36b991f8ae94141753bcb2cf78936476d82f1d ima d0eee5a3d35f0a6912b5c6e51d00a360e859a668 /init
10 8bc0209c604fd4d3b54b6089eac786a4e0cb1fbf ima cc57839b8e5c4c58612daaf6fff48abd4bac1bd7 /init
10 d30b96ced261df085c800968fe34abe5fa0e3f4d ima 1712b5017baec2d24c8165dfc1b98168cdf6aa25 ld-linux-x86-64.so.2

According to the TPM spec, also referred to in the above post, the PCR extend operation is: PCR := SHA1(PCR || data), i.e. "concatenate the old value of PCR with the data, hash the concatenated string and store the hash in PCR". Also, the spec multiple papers and presentations I have found mention that data is a hash of the software to be loaded.

However, when I do an operation like echo H(PCR)||H(data) | sha1sum, I do not obtain a correct resulting value. I.e., when calculatinng (using the above hashes): echo 1ca03ef9cca98b0a04e5b01dabe1ff825ff0280a0ea26e75253dc2fda7e4210980537d035e2fb9f8 | sha1sum, the resuting value is NOT 7f36b991f8ae94141753bcb2cf78936476d82f1d.

Is my understanding of the TPM_Extend operation correct? if so, why is the resulting hash different from the one in the sample measurement file?

Thanks! /n

有帮助吗?

解决方案

To answer your very first question: Your understanding of extend operation is more or less correct. But you have 2 problems:

  1. You are misinterpreting the things you have copied in here
  2. You can't calculate hashes like you do on the shell

The log output you provided here is from Linux's IMA. According to the documentation the first hash is template-hash and defined as

template-hash: SHA1(filedata-hash | filename-hint) 
filedata-hash: SHA1(filedata)

So for the first line: SHA1(0ea26e75253dc2fda7e4210980537d035e2fb9f8 | "boot_aggregate") results in 1ca03ef9cca98b0a04e5b01dabe1ff825ff0280a.

Note that the filename-hint is 256 byte long - it is 0-padded at the end. (thumbs up for digging this out of the kernel source ;))

So to make it clear: In your log are no PCR values.

I wrote something in Ruby to verify my findings:

require 'digest/sha1'
filedata_hash = ["0ea26e75253dc2fda7e4210980537d035e2fb9f8"].pack('H*')
filename_hint = "boot_aggregate".ljust(256, "\x00")
puts Digest::SHA1.hexdigest(filedata_hash + filename_hint)

Now to your commands:

The way you are using it here, you are interpreting the hashes as ASCII-strings. Also note that echo will add an additional new line character to the output. The character sequence 1ca03ef9cca98b0a04e5b01dabe1ff825ff0280a is hexadecimal encoding of 160 bit binary data - a SHA1 hash value. So basically you are right, you have to concatenate the two values and calculate the SHA1 of the resulting 320 bit of data.

So the correct command for the command line would be something like

printf "\x1c\xa0\x3e\xf9\xcc\xa9\x8b\x0a\x04\xe5\xb0\x1d\xab\xe1\xff\x82\x5f\xf0\x28\x0a\x0e\xa2\x6e\x75\x25\x3d\xc2\xfd\xa7\xe4\x21\x09\x80\x53\x7d\x03\x5e\x2f\xb9\xf8" | sha1sum

The \xXX in the printf string will convert the hex code XX into one byte of binary output.

This will result in the output of d14f958b2804cc930f2f5226494bd60ee5174cfa, and that's fine.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top