Skip to content

Instantly share code, notes, and snippets.

@williamcroberts
Last active April 18, 2022 19:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save williamcroberts/ff5c97c136d14e48ddcb083c54616db4 to your computer and use it in GitHub Desktop.
Save williamcroberts/ff5c97c136d14e48ddcb083c54616db4 to your computer and use it in GitHub Desktop.
Example for Making and Activating a Credential in tpm2-pytss
#!/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