aboutsummaryrefslogtreecommitdiffstats
path: root/tss2.py
diff options
context:
space:
mode:
Diffstat (limited to 'tss2.py')
-rw-r--r--tss2.py233
1 files changed, 233 insertions, 0 deletions
diff --git a/tss2.py b/tss2.py
new file mode 100644
index 0000000..2ef0568
--- /dev/null
+++ b/tss2.py
@@ -0,0 +1,233 @@
+from ctypes import cdll
+import ctypes
+import os
+import tpm2
+lib = cdll.LoadLibrary('libtss.so.0')
+
+class TPM2B_NONCE(ctypes.Structure):
+ _fields_ = [("s", ctypes.c_uint16),
+ ("b", ctypes.c_uint8 * 128)]
+
+class TPM2B_ENCRYPTED_SECRET(ctypes.Structure):
+ _fields_ = [("s", ctypes.c_uint16),
+ ("b", ctypes.c_uint8 * 256)]
+
+class TPMT_SYM_DEF(ctypes.Structure):
+ _fields_ = [("algorithm", ctypes.c_uint16),
+ ("keyBits", ctypes.c_uint16),
+ ("mode", ctypes.c_uint16)]
+
+class TPMT_RSA_SCHEME(ctypes.Structure):
+ _fields_ = [("scheme", ctypes.c_uint16),
+ ("details", ctypes.c_uint8 * 4)]
+
+class TPMS_RSA_PARMS(ctypes.Structure):
+ _fields_ = [("symmetric", TPMT_SYM_DEF),
+ ("scheme", TPMT_RSA_SCHEME),
+ ("keyBits", ctypes.c_uint16),
+ ("exponent", ctypes.c_uint32)]
+
+class TPMU_PUBLIC_PARMS(ctypes.Union):
+ _fields_ = [("buffer", ctypes.c_uint8 *20),
+ ("rsaDetail", TPMS_RSA_PARMS)]
+
+
+class TPMT_PUBLIC(ctypes.Structure):
+ _fields_ = [("Type", ctypes.c_uint16),
+ ("nameAlg", ctypes.c_uint16),
+ ("objectAttributes", ctypes.c_uint32),
+ ("authPolicy", TPM2B_NONCE),
+ ("parameters", TPMU_PUBLIC_PARMS),
+ ("unique", ctypes.c_uint8 * 258)]
+
+class TPM2B_PUBLIC(ctypes.Structure):
+ _fields_ = [("size", ctypes.c_uint16),
+ ("publicArea", TPMT_PUBLIC)]
+
+class TPMT_TK_CREATION(ctypes.Structure):
+ _fields_ = [("tag", ctypes.c_uint16),
+ ("hierarchy", ctypes.c_uint32),
+ ("digest", TPM2B_NONCE)]
+
+class TPM2B_SENSITIVE_DATA(ctypes.Structure):
+ _fields_ = [("size", ctypes.c_uint16),
+ ("buffer", ctypes.c_uint8 * 130)]
+
+class TPMS_SENSITIVE_CREATE(ctypes.Structure):
+ _fields_ = [("userAuth", TPM2B_NONCE),
+ ("data", TPM2B_SENSITIVE_DATA)]
+
+class TPM2B_SENSITIVE_CREATE(ctypes.Structure):
+ _fields_ = [("size", ctypes.c_uint16),
+ ("sensitive", TPMS_SENSITIVE_CREATE)]
+
+class TPM2B_PRIVATE(ctypes.Structure):
+ _fields_ = [("size", ctypes.c_uint16),
+ ("buffer", ctypes.c_uint8 * 1166)]
+
+
+class StartAuthSession_In(ctypes.Structure):
+ _fields_ = [("tpmKey", ctypes.c_uint32),
+ ("bind", ctypes.c_uint32),
+ ("nonce", TPM2B_NONCE),
+ ("encryptedSalt", TPM2B_ENCRYPTED_SECRET),
+ ("sessionType", ctypes.c_uint8),
+ ("symmetric", TPMT_SYM_DEF),
+ ("authHash", ctypes.c_uint16)]
+
+class StartAuthSession_Out(ctypes.Structure):
+ _fields_ = [("sessionHandle", ctypes.c_uint32),
+ ("nonceTPM", TPM2B_NONCE)]
+
+class StartAuthSession_Extra(ctypes.Structure):
+ _fields_ = [("bindPassword", ctypes.c_char_p),
+ ("salt", TPM2B_NONCE)]
+
+class ReadPublic_In(ctypes.Structure):
+ _fields_ = [("objectHandle", ctypes.c_uint32)]
+
+class ReadPublic_Out(ctypes.Structure):
+ _fields_ = [("outPublic", TPM2B_PUBLIC),
+ ("name", TPM2B_NONCE),
+ ("qualifiedName", TPM2B_NONCE)]
+
+class Create_In(ctypes.Structure):
+ _fields_ = [("parentHandle", ctypes.c_uint32),
+ ("inSensitive", TPM2B_SENSITIVE_CREATE),
+ ("inPublic", TPM2B_PUBLIC),
+ ("outsideInfo", TPM2B_NONCE),
+ ("creationPCR", ctypes.c_uint8 * 24)]
+
+class Create_Out(ctypes.Structure):
+ _fields_ = [("outPrivate", TPM2B_PRIVATE),
+ ("outPublic", TPM2B_PUBLIC),
+ ("creationData", ctypes.c_uint8 * 564),
+ ("creationHash", TPM2B_NONCE),
+ ("creationTicket", TPMT_TK_CREATION)]
+
+class FlushContext_In(ctypes.Structure):
+ _fields_ = [("flushHandle", ctypes.c_uint32)]
+
+class Load_In(ctypes.Structure):
+ _fields_ = [("parentHandle", ctypes.c_uint32),
+ ("inPrivate", TPM2B_PRIVATE),
+ ("inPublic", TPM2B_PUBLIC)]
+
+class Load_Out(ctypes.Structure):
+ _fields_ = [("objectHandle", ctypes.c_uint32),
+ ("name", TPM2B_NONCE)]
+
+class tpm_error(Exception):
+
+ def __init__(self, rc):
+ self.rc = rc
+
+ def __str__(self):
+ msg = ctypes.c_char_p()
+ submsg = ctypes.c_char_p()
+ num = ctypes.c_char_p()
+ lib.TSS_ResponseCode_toString(ctypes.byref(msg),
+ ctypes.byref(submsg),
+ ctypes.byref(num), self.rc);
+ return "%s%s%s" % (msg.value, submsg.value, num.value)
+
+class Client:
+
+ def __init__(self):
+ self.ctx = ctypes.c_void_p(None)
+ os.environ["TPM_DEVICE"] = '/dev/tpms1'
+ rc = lib.TSS_Create(ctypes.byref(self.ctx))
+ # verify SRK is at 81000001
+ self.SRK = 0x81000001
+ # we need the public area in the context for salted parameter encryption
+ self.read_public(self.SRK)
+
+ print self.ctx
+
+ def close(self):
+ lib.TSS_Delete(self.ctx)
+ print "closed"
+ print self.ctx
+
+ def TSS_Execute(self, out, inp, extra, ordinal, *sessions):
+ rc = lib.TSS_Execute(self.ctx, out, inp,
+ extra, ordinal, *sessions)
+ if (rc != 0):
+ raise tpm_error(rc)
+
+ def start_session(self, Type, salt_key = tpm2.TPM2_RH_NULL):
+ inp = StartAuthSession_In()
+ out = StartAuthSession_Out()
+ extra = StartAuthSession_Extra()
+
+ inp.sessionType = Type
+ inp.authHash = tpm2.TPM2_ALG_SHA256
+ inp.tpmKey = salt_key
+ inp.symmetric.algorithm = tpm2.TPM2_ALG_AES
+ inp.symmetric.keyBits = 128
+ inp.symmetric.mode = tpm2.TPM2_ALG_CFB
+
+ self.TSS_Execute(ctypes.byref(out), ctypes.byref(inp),
+ ctypes.byref(extra),
+ tpm2.TPM2_CC_START_AUTH_SESSION,
+ tpm2.TPM2_RH_NULL, None, 0)
+ return out.sessionHandle
+
+ def read_public(self, handle):
+ inp = ReadPublic_In()
+ out = ReadPublic_Out()
+ inp.objectHandle = handle
+
+ self.TSS_Execute(ctypes.byref(out), ctypes.byref(inp),
+ None, tpm2.TPM2_CC_READ_PUBLIC,
+ tpm2.TPM2_RH_NULL, None, 0)
+ return out
+
+ def flush_context(self, handle):
+ inp = FlushContext_In()
+ inp.flushHandle = handle
+
+ self.TSS_Execute(None, ctypes.byref(inp), None,
+ tpm2.TPM2_CC_FLUSH_CONTEXT,
+ tpm2.TPM2_RH_NULL, None, 0)
+
+ def create_rsa(self, parent, auth, hmacSession = tpm2.TPM2_RS_PW, hmacCont = 0, encSession = tpm2.TPM2_RH_NULL, encCont = 0):
+ inp = Create_In()
+ out = Create_Out()
+
+ inp.parentHandle = parent
+ if (auth != None):
+ inp.inSensitive.sensitive.userAuth.b = ctypes.c_ubyte_Array_128(auth)
+ inp.inSensitive.sensitive.userAuth.s = strlen(auth)
+ inp.inPublic.publicArea.Type = tpm2.TPM2_ALG_RSA
+ inp.inPublic.publicArea.nameAlg = tpm2.TPM2_ALG_SHA256
+ inp.inPublic.publicArea.objectAttributes = tpm2.TPMA_OBJECT_NODA | tpm2.TPMA_OBJECT_DECRYPT | tpm2.TPMA_OBJECT_USERWITHAUTH | tpm2.TPMA_OBJECT_SENSITIVEDATAORIGIN
+ inp.inPublic.publicArea.parameters.rsaDetail.symmetric.algorithm = tpm2.TPM2_ALG_NULL
+ inp.inPublic.publicArea.parameters.rsaDetail.scheme.scheme = tpm2.TPM2_ALG_NULL
+ inp.inPublic.publicArea.parameters.rsaDetail.keyBits = 2048
+ inp.inPublic.publicArea.parameters.rsaDetail.exponent = 0
+ if (hmacSession == 0):
+ hmacSession = tpm2.TPM2_RS_PW
+
+ self.TSS_Execute(ctypes.byref(out), ctypes.byref(inp), None,
+ tpm2.TPM2_CC_CREATE,
+ hmacSession, None, hmacCont,
+ # 0x20 is TPMA_OBJECT_DECRYPT
+ encSession, None, encCont | 0x20,
+ tpm2.TPM2_RH_NULL, None, 0);
+ return out
+
+ def load(self, parent, private, public, auth, hmacSession = tpm2.TPM2_RS_PW, hmacCont = 0):
+ inp = Load_In()
+ out = Load_Out()
+
+ inp.parentHandle = parent
+ inp.inPrivate = private
+ inp.inPublic = public
+
+ self.TSS_Execute(ctypes.byref(out), ctypes.byref(inp), None,
+ tpm2.TPM2_CC_LOAD,
+ hmacSession, auth, hmacCont,
+ tpm2.TPM2_RH_NULL, None, 0);
+
+ return out.objectHandle