Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement PCR Extend #120

Closed
lukehinds opened this issue Oct 6, 2020 · 4 comments
Closed

Implement PCR Extend #120

lukehinds opened this issue Oct 6, 2020 · 4 comments
Assignees

Comments

@lukehinds
Copy link
Member

lukehinds commented Oct 6, 2020

PCR Extend performs a hash extend operation into the TPM.

A PCR is a platform configuration register

Let’s explore PCRs a bit more.

A Platform Configuration Register is a value that can only be set by the TPM and is a recorded measurement of a system object (by object we could mean file, firmware, bootloader, kernel, etc).

One of the main functions of a PCR is the extend operation.

tpm2_pcrextend 10:sha256=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c

The above command asks the TPM to extend the hash b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c into PCR 10

Each time an extend is made the following mathematical operation occurs:

PCR New Value = Digest of (PCR old value || data to extend)

Here is an example in python

import hashlib

hash_one = hashlib.sha1(b'hello')
hash_two = hashlib.sha1(b'world')
hex_dig_one = hash_one.hexdigest()
hex_dig_two = hash_two.hexdigest()

# concatenate hashes
extend_hash = hex_dig_one.encode('utf-8') + hex_dig_two.encode('utf-8')

# recompute concatenated hash
extend = hashlib.sha1(extend_hash)
extend_dig = extend.hexdigest()

print("hello hash: ", hex_dig_one)
print("world hash: ", hex_dig_two)
print("extended hash: ", extend_dig)
$ python ext.py                                                                                                                                                                                                                                              
hello hash:  aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
world hash:  7c211433f02071597741e6ff5a8ea34789abbf43
extended hash:  39955b37b910e57748368b0922fd44fbff72bda5

This is a one way hash. A one-way hash function is designed in such a way that it is hard to reverse the process, that is, to find a string that hashes to a given value (hence the name one-way.) A hash function also makes it hard to find two strings that would produce the same hash value.

To play with this using the tools, first install the tools:

dnf install tpm2-tools

you can then use tpm2_pcrread to look at the values

tpm2_pcrread| grep 10:                                                                                                                                                         ✔  ⚡ 
  10: 0x44F12027AB81DFB6E096018F5A9F19645F988D45529CDED3427159DC0032D921

and extend it:

tpm2_pcrextend 10:sha256=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae49abc

tpm2_pcrread| grep 10:                                                                                                                                                         ✔  ⚡ 
  10: 0x1CEA6BDAD4B6F40B2A69F916FA81692AB263329E92B069C7B9C5ADDE6405DC3C

We will need to implement this as a function as can be seen in the python code

https://github.com/keylime/keylime/blob/1ef444e2c1f18815dde9826accc4e36da7ba3fd6/keylime/tpm/tpm2.py#L1151-L1155

To do this you can use the pcrextend function in the ESAPI wrapper here:
https://github.com/parallaxsecond/rust-tss-esapi/blob/b74837ceb229a0010c05f6149efa65c4f41f9426/src/context.rs#L774

Check out the existing code to see how you can get a context in my PR #113

@lukehinds
Copy link
Member Author

as mentioned, you could set up a sandbox and just do this in your own main.rs.

we will need to think about captureing the return output. Previously we were marshalling this into YAML, but I don't know how we should approach this yet with the esapi create. We might need a helper function here to serialise output of calls to the tss, @puiterwijk will have some ideas here.

@lkatalin
Copy link
Contributor

lkatalin commented Oct 8, 2020

Thanks for this clear write-up, @lukehinds . tpm2_pcrextend works perfectly on the command line and I'm creating an example with the ESAPI function.

Edit: I made this small example and will implement the Python function next.

@lkatalin
Copy link
Contributor

@lukehinds The ESAPI pcr_extend function already seems to have most of the functionality of the Python version extendPCR, minus setting a default algorithm and dealing with locking. Would it make more sense to directly call tss_esapi::Context::pcr_extend where we need it, rather than implementing a wrapper for it in tpm.rs? Otherwise I do have a tiny PR for the wrapper.

@lkatalin
Copy link
Contributor

lkatalin commented Jul 5, 2021

Closing as this is implemented by the ESAPI and already used here.

@lkatalin lkatalin closed this as completed Jul 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants