def get_quote(self, aik, pcrs, challenge): """ retrieve a signed set of PCR values :param aik: A TspiObject representing the Attestation Identity Key :param pcrs: A TspiPCRs representing the PCRs to be quoted :param challenge: The challenge to use :returns: A tuple containing the quote data and the validation block """ valid = ffi.new('TSS_VALIDATION *') chalmd = ffi.new('BYTE[]', 20) if challenge: m = hashlib.sha1() m.update(challenge) sha1 = bytearray(m.digest()) for i in range(len(sha1)): chalmd[i] = sha1[i] valid[0].ulExternalDataLength = ffi.sizeof(chalmd) valid[0].rgbExternalData = chalmd tss_lib.Tspi_TPM_Quote(self.handle[0], aik.get_handle(), pcrs.get_handle(), valid) data = bytearray(valid[0].rgbData[0:valid[0].ulDataLength]) validation = bytearray( valid[0].rgbValidationData[0:valid[0].ulValidationDataLength]) tss_lib.Tspi_Context_FreeMemory(self.context, valid[0].rgbData) tss_lib.Tspi_Context_FreeMemory(self.context, valid[0].rgbValidationData) return (data, validation)
def activate_identity(self, aik, asymblob, symblob): """ Decrypt the challenge provided by the attestation host :param aik: A TspiObject representing the Attestation Identity Key :param asymblob: The asymmetrically encrypted challenge data :param symblob: The symmetrically encrypted challenge data :returns: A bytearray containing the decrypted challenge """ casymblob = ffi.new('BYTE[]', len(asymblob)) for i in range(len(asymblob)): casymblob[i] = asymblob[i] csymblob = ffi.new('BYTE[]', len(symblob)) for i in range(len(symblob)): csymblob[i] = symblob[i] credlen = ffi.new('UINT32 *') cred = ffi.new('BYTE **') tss_lib.Tspi_TPM_ActivateIdentity(self.handle[0], aik.get_handle(), len(asymblob), casymblob, len(symblob), csymblob, credlen, cred) ret = bytearray(cred[0][0:credlen[0]]) tss_lib.Tspi_Context_FreeMemory(self.context, cred[0]) return ret
def get_digest(self): """ Get the hash value of this object """ digest_len = ffi.new('UINT32 *') digest = ffi.new('BYTE **') tss_lib.Tspi_Hash_GetHashValue(self.get_handle(), digest_len, digest) ret = bytearray(digest[0][0:digest_len[0]]) tss_lib.Tspi_Context_FreeMemory(self.context, digest[0]) return ret
def get_pub_srk_key(self): """ Get the public portion of the SRK :returns: public portion of SRK and its length """ buf = ffi.new('BYTE **') buf_len = ffi.new('UINT32 *') tss_lib.Tspi_TPM_OwnerGetSRKPubKey(self.get_handle(), buf_len, buf) srk_len = buf_len[0] srk = bytearray(buf[0][0:srk_len]) tss_lib.Tspi_Context_FreeMemory(self.context, buf[0]) return srk, srk_len
def get_pcrs(self): """ Get the digest value of the PCRs referred to by this object :returns: a dictionary of PCR/value pairs """ for pcr in self.pcrs: buf = ffi.new('BYTE **') buflen = ffi.new('UINT32 *') tss_lib.Tspi_PcrComposite_GetPcrValue(self.handle[0], pcr, buflen, buf) self.pcrs[pcr] = bytearray(buf[0][0:buflen[0]]) tss_lib.Tspi_Context_FreeMemory(self.context, buf[0]) return self.pcrs
def get_pcr(self, pcr): """ Get the value of the PCR :param pcr: The PCR to read :returns: PCR value """ buf = ffi.new('BYTE **') buf_len = ffi.new('UINT32 *') tss_lib.Tspi_TPM_PcrRead(self.get_handle(), pcr, buf_len, buf) pcrs = bytearray(buf[0][0:buf_len[0]]) tss_lib.Tspi_Context_FreeMemory(self.context, buf[0]) return pcrs
def sign(self, key): """ Sign this hash with the specified key and return a signature :param key: a TspiKey instance corresponding to a loaded key :return: a string of bytes containing the signature """ csig_size = ffi.new("UINT32*") csig_data = ffi.new("BYTE**") tss_lib.Tspi_Hash_Sign(self.get_handle(), key.get_handle(), csig_size, csig_data) ret = bytearray(csig_data[0][0:csig_size[0]]) tss_lib.Tspi_Context_FreeMemory(self.context, csig_data[0]) return ret
def get_attribute_data(self, attrib, sub): """ Get an arbitrary datatype associated with the object :param attrib: The attribute to modify :param sub: The subattribute to modify :returns: a bytearray containing the data """ bloblen = ffi.new('UINT32 *') blob = ffi.new('BYTE **') tss_lib.Tspi_GetAttribData(self.handle[0], attrib, sub, bloblen, blob) ret = bytearray(blob[0][0:bloblen[0]]) tss_lib.Tspi_Context_FreeMemory(self.context, blob[0]) return ret
def get_random(self, length): """ Generate random number :param length: Length of the generated random number :returns: A bytearray containing the random number """ random_len = ffi.cast('UINT32', length) random_num = ffi.new('BYTE **') tss_lib.Tspi_TPM_GetRandom(self.get_handle(), random_len, random_num) ret = bytearray(random_num[0][0:length]) tss_lib.Tspi_Context_FreeMemory(self.context, random_num[0]) return ret
def get_capability(self, cap, sub): """ Get information on the capabilities of the TPM :param cap: The capability to query :param sub: The subcapability to query :returns: A bytearray containing the capability data """ resp = ffi.new('BYTE **') resplen = ffi.new('UINT32 *') csub = ffi.new('BYTE []', len(sub)) for i in range(len(sub)): csub[i] = sub[i] tss_lib.Tspi_TPM_Getcapability(self.handle[0], cap, len(sub), csub, resplen, resp) ret = bytearray(resp[0][0:resplen[0]]) tss_lib.Tspi_Context_FreeMemory(self.context, resp[0]) return ret
def extend_pcr(self, pcr, data, event): """ Extend a PCR :param pcr: The PCR to extend :param data: The data to be hashed by the TPM for extending the PCR :param event: A dict containing the event data :returns: A bytearray containing the new PCR value """ cdata = ffi.new('BYTE []', len(data)) bloblen = ffi.new('UINT32 *') blob = ffi.new('BYTE **') for i in range(len(data)): cdata[i] = data[i] tss_lib.Tspi_TPM_PcrExtend(self.get_handle(), pcr, len(data), cdata, ffi.NULL, bloblen, blob) ret = bytearray(blob[0][0:bloblen[0]]) tss_lib.Tspi_Context_FreeMemory(self.context, blob[0]) return ret
def collate_identity_request(self, srk, pubkey, aik): """ Generate everything required to authenticate the TPM to a third party :param srk: The storage root key to use :param pubkey: The key to use for signing the output key :param aik: The key to use as the identity key :returns: A bytearray containing a certificate request """ bloblen = ffi.new('UINT32 *') blob = ffi.new('BYTE **') tss_lib.Tspi_TPM_CollateIdentityRequest(self.get_handle(), srk.get_handle(), pubkey.get_handle(), 0, "", aik.get_handle(), tss_lib.TSS_ALG_AES, bloblen, blob) ret = bytearray(blob[0][0:bloblen[0]]) tss_lib.Tspi_Context_FreeMemory(self.context, blob[0]) return ret
def unseal(self, data): """ Unseal data from the local TPM using this key :param data: The data to unseal :returns: a bytearray of the unencrypted data """ encdata = TspiObject(self.context, 'TSS_HENCDATA *', tss_lib.TSS_OBJECT_TYPE_ENCDATA, tss_lib.TSS_ENCDATA_SEAL) encdata.set_attribute_data(tss_lib.TSS_TSPATTRIB_ENCDATA_BLOB, tss_lib.TSS_TSPATTRIB_ENCDATABLOB_BLOB, data) bloblen = ffi.new('UINT32 *') blob = ffi.new('BYTE **') tss_lib.Tspi_Data_Unseal(encdata.get_handle(), self.get_handle(), bloblen, blob) ret = bytearray(blob[0][0:bloblen[0]]) tss_lib.Tspi_Context_FreeMemory(self.context, blob[0]) return ret