Last active
April 18, 2022 19:13
-
-
Save williamcroberts/ff5c97c136d14e48ddcb083c54616db4 to your computer and use it in GitHub Desktop.
Example for Making and Activating a Credential in tpm2-pytss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
''' | |
Setup: | |
With the simulator running, I built an EK: tpm2 createek -c 0x81010005 -G rsa -u ek.ak_pub | |
Note this is not the exact template as the EK Spec defines: | |
- https://trustedcomputinggroup.org/wp-content/uploads/TCG_IWG_EKCredentialProfile_v2p4_r3.pdf | |
The Unique Buffer field is not 256 bytes of 0's it's just 0 len. | |
I got the pem file by doing a tpm2 print call: | |
tpm2 print -t TPM2B_PUBLIC -f pem ek.ak_pub > ~/ek.pem | |
''' | |
from tpm2_pytss import * | |
from tpm2_pytss.utils import make_credential | |
def setup_session(ectx, ek_handle): | |
sym = TPMT_SYM_DEF( | |
algorithm=TPM2_ALG.XOR, | |
keyBits=TPMU_SYM_KEY_BITS(exclusiveOr=TPM2_ALG.SHA256), | |
mode=TPMU_SYM_MODE(aes=TPM2_ALG.CFB), | |
) | |
session = ectx.start_auth_session( | |
tpm_key=ek_handle, | |
bind=ESYS_TR.NONE, | |
session_type=TPM2_SE.POLICY, | |
symmetric=sym, | |
auth_hash=TPM2_ALG.SHA256, | |
) | |
nonce = ectx.trsess_get_nonce_tpm(session) | |
expiration = -(10 * 365 * 24 * 60 * 60) | |
ectx.policy_secret( | |
ESYS_TR.ENDORSEMENT, session, nonce, b"", b"", expiration | |
) | |
ectx.trsess_set_attributes(session, TPMA_SESSION.ENCRYPT | TPMA_SESSION.DECRYPT) | |
return session | |
# note use the "b" in mode to get bytes for from_pem file | |
with open("/home/wcrobert/ek.pem", "rb") as f: | |
pem = f.read() | |
# constants to make things a bit easier to modify | |
ek_attrs = "fixedtpm|fixedparent|sensitivedataorigin|adminwithpolicy|restricted|decrypt" | |
ek_auth_policy = "837197674484b3f81a90cc8d46a5d724fd52d76e06520b64f2a1da1b331469aa" | |
ek_expected_name = "000b1c20f42bf39dfcb0081cdca0ff608a016d3d0fc6326723224d1c6d86655d8dfa" | |
ek_asym_detail = "aes128cfb" | |
ek_peristent_handle = 0x81010005 | |
# match the template used from tpm2 createek | |
ek_pub = TPM2B_PUBLIC.from_pem(pem, | |
objectAttributes=ek_attrs, | |
symmetric=ek_asym_detail | |
) | |
# set the auth policy (I'll send a patch upstream to add this to the args in from_pem) | |
ek_pub.publicArea.authPolicy = bytes.fromhex(ek_auth_policy) | |
ek_name = ek_pub.get_name() | |
# coerce TPM2B_NAME to string of hex chars | |
if str(ek_name) != ek_expected_name: | |
raise RuntimeError(f"{ek_name}" != "{ek_expected_name}") | |
# or do it with bytes | |
if ek_name != bytes.fromhex(ek_expected_name): | |
raise RuntimeError(f"{ek_name}" != "{ek_expected_name}") | |
print("Ek Setup Properly") | |
with ESAPI() as ectx: | |
ek_handle = ectx.tr_from_tpmpublic(ek_peristent_handle) | |
# to use the EK we need a policy session with Policy Secret for | |
# the endorsement hierarchy. We will even set up encrypted... | |
# NOTE: Sessions are only good for one command | |
session = setup_session(ectx, ek_handle) | |
# Create an attestation key (AK)... | |
ak_priv, ak_pub = ectx.create(ek_handle, in_sensitive=None, session1=session)[0:2] | |
session = setup_session(ectx, ek_handle) | |
ak_handle = ectx.load(ek_handle, ak_priv, ak_pub, session1=session) | |
# use the AK to make the credential | |
# (typically the third param, ek_name here, is an AK name which is | |
# a child of the EK primary key | |
credblob, secret = make_credential( | |
ek_pub, b"credential data", ak_pub.get_name() | |
) | |
session = setup_session(ectx, ek_handle) | |
certinfo = ectx.activate_credential(ak_handle, ek_handle, credblob, secret, | |
session2=session) | |
print("Credential made and activated") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment