def __test_ownerpw(self, owner_pw, reentry=False): # make a temp file for the output with tempfile.NamedTemporaryFile() as tmppath: retDict = self.__run( ["getpubek", "-pwdo", owner_pw, "-ok", tmppath.name], raiseOnError=False, outputpaths=tmppath.name) output = config.list_convert(retDict['retout']) code = retDict['code'] if code != tpm_abstract.AbstractTPM.EXIT_SUCESS: if len(output) > 0 and output[0].startswith( "Error Authentication failed (Incorrect Password) from TPM_OwnerReadPubek" ): return False if len(output) > 0 and output[0].startswith( "Error Defend lock running from TPM_OwnerReadPubek"): if reentry: logger.error("Unable to unlock TPM") return False # tpm got locked. lets try to unlock it logger.error( "TPM is locked from too many invalid owner password attempts, " "attempting to unlock with password: %s" % owner_pw) # i have no idea why, but runnig this twice seems to actually work self.__run(["resetlockvalue", "-pwdo", owner_pw], raiseOnError=False) self.__run(["resetlockvalue", "-pwdo", owner_pw], raiseOnError=False) return self.__test_ownerpw(owner_pw, True) raise Exception("test ownerpw, getpubek failed with code " + str(code) + ": " + str(output)) return True
def read_key_nvram(self): with tempfile.NamedTemporaryFile() as nvpath: owner_pw = self.get_tpm_metadata('owner_pw') cmd = [ "nv_readvalue", "-pwdd", owner_pw, "-in", "1", "-sz", str(config.BOOTSTRAP_KEY_SIZE), "-of", nvpath.name ] retDict = self.__run(cmd, raiseOnError=False, outputpaths=nvpath.name) output = config.list_convert(retDict['retout']) code = retDict['code'] key = retDict['fileouts'][nvpath.name] if code != tpm_abstract.AbstractTPM.EXIT_SUCESS and len( output) > 0 and ( output[0].startswith( "Error Illegal index from NV_ReadValue") or output[0].startswith("Error Authentication failed")): logger.debug("No stored U in TPM NVRAM") return None if code != tpm_abstract.AbstractTPM.EXIT_SUCESS: raise Exception("nv_readvalue failed with code " + str(code) + ": " + str(output)) if len(key) != config.BOOTSTRAP_KEY_SIZE: logger.debug("Invalid key length from NVRAM: %d" % (len(key))) return None return key
def read_ekcert_nvram(self): # make a temp file for the quote with tempfile.NamedTemporaryFile() as nvpath: owner_pw = self.get_tpm_metadata('owner_pw') retDict = self.__run([ "nv_readvalue", "-pwdo", owner_pw, "-in", "1000f000", "-cert", "-of", nvpath.name ], raiseOnError=False, outputpaths=nvpath.name) output = config.list_convert(retDict['retout']) code = retDict['code'] ekcert = retDict['fileouts'][nvpath.name] if code != tpm_abstract.AbstractTPM.EXIT_SUCESS and len( output) > 0 and output[0].startswith( "Error Illegal index from NV_ReadValue"): logger.warning("No EK certificate found in TPM NVRAM") return None if code != tpm_abstract.AbstractTPM.EXIT_SUCESS: raise Exception("nv_readvalue for ekcert failed with code " + str(code) + ": " + str(output)) return base64.b64encode(ekcert)
def __create_aik(self, activate): # if no AIK created, then create one if self.get_tpm_metadata('aik') is not None and self.get_tpm_metadata( 'aikpriv') is not None and self.get_tpm_metadata( 'aikmod') is not None: logger.debug("AIK already created") else: logger.debug("Creating a new AIK identity") extra = "" if activate: extra = "-ac" owner_pw = self.get_tpm_metadata('owner_pw') aik_pw = tpm_abstract.TPM_Utilities.random_password(20) # make a temp file for the output with tempfile.NamedTemporaryFile() as tmppath: retDict = self.__run( "identity -la aik -ok %s -pwdo %s -pwdk %s %s" % (tmppath.name, owner_pw, aik_pw, extra), outputpaths=tmppath.name) retout = config.list_convert(retDict['retout']) code = retDict['code'] fileout = retDict['fileouts'][tmppath.name] inPem = False pem = "" for line in retout: if line.startswith("-----BEGIN PUBLIC KEY-----"): inPem = True if inPem: pem += line if line.startswith("-----END PUBLIC KEY-----"): inPem = False if pem == "": raise Exception( "unable to read public aik from create identity. Is your tpm4720 installation up to date?" ) mod = self.__get_mod_from_pem(pem) # read in the output if fileout == '': raise Exception( "unable to read file output. Is your tpm4720 installation up to date?" ) key = base64.b64encode(fileout) # persist results self._set_tpm_metadata('aik', pem) self._set_tpm_metadata('aikpriv', key) self._set_tpm_metadata('aikmod', mod) self._set_tpm_metadata('aik_pw', aik_pw) if activate: logger.debug("Self-activated AIK identity in test mode") # ensure the AIK is loaded handle = self.__load_aik() self._set_tpm_metadata('aik_handle', handle)
def __create_ek(self): # this function is intended to be idempotent retDict = self.__run("createek", raiseOnError=False) output = config.list_convert(retDict['retout']) code = retDict['code'] if code != tpm_abstract.AbstractTPM.EXIT_SUCESS: if len(output) > 0 and output[0].startswith("Error Target command disabled from TPM_CreateEndorsementKeyPair"): logger.debug("TPM EK already created.") elif len(output) > 0 and output[0].startswith("Error Defend lock running from TPM_CreateEndorsementKeyPair"): logger.debug("createek failed. TPM locked, will attempt unlock during while taking ownership. To manually repair run resetlockvalue -pwdo [owner_password]") else: raise Exception("createek failed with code " + str(code) + ": " + str(output))
def __get_pub_ek(self): # assumes that owner_pw is correct at this point owner_pw = self.get_tpm_metadata('owner_pw') # make a temp file for the output with tempfile.NamedTemporaryFile() as tmppath: # generates pubek.pem retDict = self.__run(["getpubek", "-pwdo", owner_pw, "-ok", tmppath.name], raiseOnError=False, outputpaths=tmppath.name) output = config.list_convert(retDict['retout']) code = retDict['code'] ek = retDict['fileouts'][tmppath.name] if code != tpm_abstract.AbstractTPM.EXIT_SUCESS: raise Exception("getpubek failed with code " + str(code) + ": " + str(output)) self._set_tpm_metadata('ek', ek)
def check_mounted(secdir): whatsmounted = cmd_exec.run("mount", lock=False)['retout'] whatsmounted_converted = config.list_convert(whatsmounted) for line in whatsmounted_converted: tokens = line.split() tmpfs = False if len(tokens) < 3: continue if tokens[0] == 'tmpfs': tmpfs = True if tokens[2] == secdir: if not tmpfs: logger.error("secure storage location %s already mounted on wrong file system type: %s. Unmount to continue." % ( secdir, tokens[0])) raise Exception("secure storage location %s already mounted on wrong file system type: %s. Unmount to continue." % ( secdir, tokens[0])) logger.debug( "secure storage location %s already mounted on tmpfs" % secdir) return True logger.debug("secure storage location %s not mounted " % secdir) return False