1*9c5db199SXin Li# Lint as: python2, python3 2*9c5db199SXin Li# Copyright (c) 2011 The Chromium OS Authors. All rights reserved. 3*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 4*9c5db199SXin Li# found in the LICENSE file. 5*9c5db199SXin Li 6*9c5db199SXin Li"""A Python library to interact with TPM module for testing. 7*9c5db199SXin Li 8*9c5db199SXin LiBackground 9*9c5db199SXin Li - TPM stands for Trusted Platform Module, a piece of security device 10*9c5db199SXin Li - TPM specification is the work of Trusted Computing Group 11*9c5db199SXin Li - As of September 2011, the current TPM specification is version 1.2 12*9c5db199SXin Li 13*9c5db199SXin LiDependency 14*9c5db199SXin Li - This library depends on a C shared library called "libtspi.so", which 15*9c5db199SXin Li contains a set of APIs for interacting with TPM module 16*9c5db199SXin Li 17*9c5db199SXin LiNotes: 18*9c5db199SXin Li - An exception is raised if it doesn't make logical sense to continue program 19*9c5db199SXin Li flow (e.g. I/O error prevents test case from executing) 20*9c5db199SXin Li - An exception is caught and then converted to an error code if the caller 21*9c5db199SXin Li expects to check for error code per API definition 22*9c5db199SXin Li""" 23*9c5db199SXin Li 24*9c5db199SXin Lifrom __future__ import absolute_import 25*9c5db199SXin Lifrom __future__ import division 26*9c5db199SXin Lifrom __future__ import print_function 27*9c5db199SXin Li 28*9c5db199SXin Liimport datetime, logging 29*9c5db199SXin Lifrom six.moves import range 30*9c5db199SXin Li 31*9c5db199SXin Lifrom autotest_lib.client.common_lib import smogcheck_ttci 32*9c5db199SXin Li# Use explicit import to make code more readable 33*9c5db199SXin Lifrom ctypes import c_uint, c_uint32, cdll, c_bool, Structure, POINTER, \ 34*9c5db199SXin Li c_ubyte, c_byte, byref, c_uint16, cast, create_string_buffer, c_uint64, \ 35*9c5db199SXin Li c_char_p, addressof, c_char, pointer 36*9c5db199SXin Li 37*9c5db199SXin Li 38*9c5db199SXin Li# TPM flags 39*9c5db199SXin Li# TODO(tgao): possible to import from trousers/src/include/tss/tss_defines.h? 40*9c5db199SXin LiTSS_KEY_AUTHORIZATION = c_uint32(0x00000001) 41*9c5db199SXin LiTSS_KEY_TSP_SRK = c_uint32(0x04000000) 42*9c5db199SXin LiTSS_POLICY_USAGE = c_uint32(0x00000001) 43*9c5db199SXin LiTSS_OBJECT_TYPE_RSAKEY = c_uint(0x02) 44*9c5db199SXin LiTSS_SECRET_MODE_SHA1 = c_uint32(0x00001000) 45*9c5db199SXin LiTSS_SECRET_MODE_PLAIN = c_uint32(0x00001800) 46*9c5db199SXin LiTSS_TPMCAP_PROP_MANUFACTURER = c_uint(0x12) 47*9c5db199SXin LiTSS_TPMCAP_PROPERTY = c_uint(0x13) 48*9c5db199SXin LiTSS_TPMCAP_VERSION = c_uint(0x14) 49*9c5db199SXin LiTSS_TPMCAP_VERSION_VAL = c_uint32(0x15) 50*9c5db199SXin LiTSS_TPMSTATUS_DISABLEOWNERCLEAR = c_uint32(0x00000001) 51*9c5db199SXin LiTSS_TPMSTATUS_DISABLEFORCECLEAR = c_uint32(0x00000002) 52*9c5db199SXin LiTSS_TPMSTATUS_PHYSICALSETDEACTIVATED = c_uint32(0x00000010) 53*9c5db199SXin LiTSS_TPMSTATUS_SETTEMPDEACTIVATED = c_uint32(0x00000011) 54*9c5db199SXin Li 55*9c5db199SXin Li# TODO(tgao): possible to import from trousers/src/include/tss/tpm.h? 56*9c5db199SXin LiTPM_SHA1_160_HASH_LEN = c_uint(0x14) 57*9c5db199SXin Li 58*9c5db199SXin Li# Path to TSPI shared library. 59*9c5db199SXin LiTSPI_C_LIB = "/usr/lib/libtspi.so.1" 60*9c5db199SXin Li 61*9c5db199SXin Li# Valid operation of tpmSetActive(). Equivalent CLI commands: 62*9c5db199SXin Li# 'status' = tpm_setactive --well-known --status 63*9c5db199SXin Li# 'activate' = tpm_setactive --well-known --active 64*9c5db199SXin Li# 'deactivate' = tpm_setactive --well-known --inactive 65*9c5db199SXin Li# 'temp' = tpm_setactive --well-known --temp 66*9c5db199SXin LiTPM_SETACTIVE_OP = ['status', 'activate', 'deactivate', 'temp'] 67*9c5db199SXin Li 68*9c5db199SXin Li# Valid operation of tpmSetClearable(). Equivalent CLI commands: 69*9c5db199SXin Li# 'status' = tpm_setclearable --well-known --status 70*9c5db199SXin Li# 'owner' = tpm_setclearable --well-known --owner 71*9c5db199SXin Li# 'force' = tpm_setclearable --well-known --force 72*9c5db199SXin LiTPM_SETCLEARABLE_OP = ['status', 'owner', 'force'] 73*9c5db199SXin Li 74*9c5db199SXin Li# Secret mode for setPolicySecret() 75*9c5db199SXin LiTSS_SECRET_MODE = dict(sha1=TSS_SECRET_MODE_SHA1, 76*9c5db199SXin Li plain=TSS_SECRET_MODE_PLAIN) 77*9c5db199SXin Li 78*9c5db199SXin Li 79*9c5db199SXin Liclass SmogcheckError(Exception): 80*9c5db199SXin Li """Base class for all smogcheck API errors.""" 81*9c5db199SXin Li 82*9c5db199SXin Li 83*9c5db199SXin Liclass TpmVersion(Structure): 84*9c5db199SXin Li """Defines TPM version string struct. 85*9c5db199SXin Li 86*9c5db199SXin Li Declared in tss/tpm.h and named TPM_VERSION. 87*9c5db199SXin Li """ 88*9c5db199SXin Li _fields_ = [('major', c_ubyte), 89*9c5db199SXin Li ('minor', c_ubyte), 90*9c5db199SXin Li ('revMajor', c_ubyte), 91*9c5db199SXin Li ('revMinor', c_ubyte)] 92*9c5db199SXin Li 93*9c5db199SXin Li 94*9c5db199SXin Liclass TpmCapVersionInfo(Structure): 95*9c5db199SXin Li """Defines TPM version info struct. 96*9c5db199SXin Li 97*9c5db199SXin Li Declared in tss/tpm.h and named TPM_CAP_VERSION_INFO. 98*9c5db199SXin Li """ 99*9c5db199SXin Li _fields_ = [('tag', c_uint16), 100*9c5db199SXin Li ('version', TpmVersion), 101*9c5db199SXin Li ('specLevel', c_uint16), 102*9c5db199SXin Li ('errataRev', c_ubyte), 103*9c5db199SXin Li ('tpmVendorID', c_char*4), 104*9c5db199SXin Li ('vendorSpecific', POINTER(c_ubyte))] 105*9c5db199SXin Li 106*9c5db199SXin Li 107*9c5db199SXin Lidef InitVersionInfo(vi): 108*9c5db199SXin Li """Utility method to allocate memory for TPM version info. 109*9c5db199SXin Li 110*9c5db199SXin Li Args: 111*9c5db199SXin Li vi: a TpmCapVerisonInfo object, just created. 112*9c5db199SXin Li """ 113*9c5db199SXin Li vi.tpmVendorId = create_string_buffer(4) # Allocate 4 bytes 114*9c5db199SXin Li vendorDetail = create_string_buffer(64) # Allocate 64 bytes 115*9c5db199SXin Li vi.vendorSpecific = cast(pointer(vendorDetail), POINTER(c_ubyte)) 116*9c5db199SXin Li 117*9c5db199SXin Li 118*9c5db199SXin Lidef PrintVersionInfo(vi): 119*9c5db199SXin Li """Utility method to print TPM version info. 120*9c5db199SXin Li 121*9c5db199SXin Li Args: 122*9c5db199SXin Li vi: a TpmCapVerisonInfo object. 123*9c5db199SXin Li """ 124*9c5db199SXin Li logging.info(' TPM 1.2 Version Info:\n') 125*9c5db199SXin Li logging.info(' Chip Version: %d.%d.%d.%d.', vi.version.major, 126*9c5db199SXin Li vi.version.minor, vi.version.revMajor, vi.version.revMinor) 127*9c5db199SXin Li logging.info(' Spec Level: %d', vi.specLevel) 128*9c5db199SXin Li logging.info(' Errata Revision: %d', vi.errataRev) 129*9c5db199SXin Li vendorId = [i for i in vi.tpmVendorID if i] 130*9c5db199SXin Li logging.info(' TPM Vendor ID: %s', ''.join(vendorId)) 131*9c5db199SXin Li # TODO(tgao): handle the case when there's no vendor specific data. 132*9c5db199SXin Li logging.info(' Vendor Specific data (first 4 bytes in Hex): ' 133*9c5db199SXin Li '%.2x %.2x %.2x %.2x', vi.vendorSpecific[0], 134*9c5db199SXin Li vi.vendorSpecific[1], vi.vendorSpecific[2], 135*9c5db199SXin Li vi.vendorSpecific[3]) 136*9c5db199SXin Li 137*9c5db199SXin Li 138*9c5db199SXin Lidef PrintSelfTestResult(str_len, pResult): 139*9c5db199SXin Li """Utility method to print TPM self test result. 140*9c5db199SXin Li 141*9c5db199SXin Li Args: 142*9c5db199SXin Li str_len: an integer, length of string pointed to by pResult. 143*9c5db199SXin Li pResult: a c_char_p, pointer to result. 144*9c5db199SXin Li """ 145*9c5db199SXin Li out = [] 146*9c5db199SXin Li for i in range(str_len): 147*9c5db199SXin Li if i and not i % 32: 148*9c5db199SXin Li out.append('\t') 149*9c5db199SXin Li if not i % 4: 150*9c5db199SXin Li out.append(' ') 151*9c5db199SXin Li b = pResult.value[i] 152*9c5db199SXin Li out.append('%02x' % ord(b)) 153*9c5db199SXin Li logging.info(' TPM Test Results: %s', ''.join(out)) 154*9c5db199SXin Li 155*9c5db199SXin Li 156*9c5db199SXin Liclass TpmController(object): 157*9c5db199SXin Li """Object to interact with TPM module for testing.""" 158*9c5db199SXin Li 159*9c5db199SXin Li def __init__(self): 160*9c5db199SXin Li """Constructor. 161*9c5db199SXin Li 162*9c5db199SXin Li Mandatory params: 163*9c5db199SXin Li hContext: a c_uint32, context object handle. 164*9c5db199SXin Li _contextSet: a boolean, True if TPM context is set. 165*9c5db199SXin Li hTpm: a c_uint32, TPM object handle. 166*9c5db199SXin Li hTpmPolicy: a c_uint32, TPM policy object handle. 167*9c5db199SXin Li tspi_lib: a shared library object (libtspi.so). 168*9c5db199SXin Li 169*9c5db199SXin Li Raises: 170*9c5db199SXin Li SmogcheckError: if error initializing TpmController. 171*9c5db199SXin Li """ 172*9c5db199SXin Li self.hContext = c_uint32(0) 173*9c5db199SXin Li self._contextSet = False 174*9c5db199SXin Li self.hTpm = c_uint32(0) 175*9c5db199SXin Li self.hTpmPolicy = c_uint32(0) 176*9c5db199SXin Li 177*9c5db199SXin Li logging.info('Attempt to load shared library %s', TSPI_C_LIB) 178*9c5db199SXin Li try: 179*9c5db199SXin Li self.tspi_lib = cdll.LoadLibrary(TSPI_C_LIB) 180*9c5db199SXin Li except OSError as e: 181*9c5db199SXin Li raise SmogcheckError('Error loading C library %s: %r' % 182*9c5db199SXin Li (TSPI_C_LIB, e)) 183*9c5db199SXin Li logging.info('Successfully loaded shared library %s', TSPI_C_LIB) 184*9c5db199SXin Li 185*9c5db199SXin Li def closeContext(self): 186*9c5db199SXin Li """Closes TPM context and cleans up. 187*9c5db199SXin Li 188*9c5db199SXin Li Returns: 189*9c5db199SXin Li an integer, 0 for success and -1 for error. 190*9c5db199SXin Li """ 191*9c5db199SXin Li if not self._contextSet: 192*9c5db199SXin Li logging.debug('TPM context NOT set.') 193*9c5db199SXin Li return 0 194*9c5db199SXin Li 195*9c5db199SXin Li ret = -1 196*9c5db199SXin Li # Calling the pointer type without an argument creates a NULL pointer 197*9c5db199SXin Li if self.tspi_lib.Tspi_Context_FreeMemory(self.hContext, 198*9c5db199SXin Li POINTER(c_byte)()) != 0: 199*9c5db199SXin Li logging.error('Error freeing memory when closing TPM context') 200*9c5db199SXin Li else: 201*9c5db199SXin Li logging.debug('Tspi_Context_FreeMemory() success') 202*9c5db199SXin Li 203*9c5db199SXin Li if self.tspi_lib.Tspi_Context_Close(self.hContext) != 0: 204*9c5db199SXin Li logging.error('Error closing TPM context') 205*9c5db199SXin Li else: 206*9c5db199SXin Li logging.debug('Tspi_Context_Close() success') 207*9c5db199SXin Li ret = 0 208*9c5db199SXin Li self._contextSet = False 209*9c5db199SXin Li 210*9c5db199SXin Li return ret 211*9c5db199SXin Li 212*9c5db199SXin Li def _closeContextObject(self, hObject): 213*9c5db199SXin Li """Closes TPM context object. 214*9c5db199SXin Li 215*9c5db199SXin Li Args: 216*9c5db199SXin Li hObject: an integer, basic object handle. 217*9c5db199SXin Li 218*9c5db199SXin Li Raises: 219*9c5db199SXin Li SmogcheckError: if an error is encountered. 220*9c5db199SXin Li """ 221*9c5db199SXin Li if self.tspi_lib.Tspi_Context_CloseObject(self.hContext, hObject) != 0: 222*9c5db199SXin Li raise SmogcheckError('Error closing TPM context object') 223*9c5db199SXin Li 224*9c5db199SXin Li logging.debug('Tspi_Context_CloseObject() success') 225*9c5db199SXin Li 226*9c5db199SXin Li def setupContext(self): 227*9c5db199SXin Li """Sets up tspi context for TPM access. 228*9c5db199SXin Li 229*9c5db199SXin Li TPM context cannot be reused. Therefore, each new Tspi_* command would 230*9c5db199SXin Li require a new context to be set up before execution and closing that 231*9c5db199SXin Li context after execution (or error). 232*9c5db199SXin Li 233*9c5db199SXin Li Raises: 234*9c5db199SXin Li SmogcheckError: if an error is encountered. 235*9c5db199SXin Li """ 236*9c5db199SXin Li if self._contextSet: 237*9c5db199SXin Li logging.debug('TPM context already set.') 238*9c5db199SXin Li return 239*9c5db199SXin Li 240*9c5db199SXin Li if self.tspi_lib.Tspi_Context_Create(byref(self.hContext)) != 0: 241*9c5db199SXin Li raise SmogcheckError('Error creating tspi context') 242*9c5db199SXin Li 243*9c5db199SXin Li logging.info('Created tspi context = 0x%x', self.hContext.value) 244*9c5db199SXin Li 245*9c5db199SXin Li if self.tspi_lib.Tspi_Context_Connect(self.hContext, 246*9c5db199SXin Li POINTER(c_uint16)()) != 0: 247*9c5db199SXin Li raise SmogcheckError('Error connecting to tspi context') 248*9c5db199SXin Li 249*9c5db199SXin Li logging.info('Connected to tspi context') 250*9c5db199SXin Li 251*9c5db199SXin Li if self.tspi_lib.Tspi_Context_GetTpmObject(self.hContext, 252*9c5db199SXin Li byref(self.hTpm)) != 0: 253*9c5db199SXin Li raise SmogcheckError('Error getting TPM object from tspi context') 254*9c5db199SXin Li 255*9c5db199SXin Li logging.info('Got tpm object from tspi context = 0x%x', self.hTpm.value) 256*9c5db199SXin Li self._contextSet = True 257*9c5db199SXin Li 258*9c5db199SXin Li def _getTpmStatus(self, flag, bValue): 259*9c5db199SXin Li """Wrapper function to call Tspi_TPM_GetStatus(). 260*9c5db199SXin Li 261*9c5db199SXin Li Args: 262*9c5db199SXin Li flag: a c_uint, TPM status info flag, values defined in C header file 263*9c5db199SXin Li "tss/tss_defines.h". 264*9c5db199SXin Li bValue: a c_bool, place holder for specific TPM flag bit value (0/1). 265*9c5db199SXin Li 266*9c5db199SXin Li Raises: 267*9c5db199SXin Li SmogcheckError: if an error is encountered. 268*9c5db199SXin Li """ 269*9c5db199SXin Li result = self.tspi_lib.Tspi_TPM_GetStatus(self.hTpm, flag, 270*9c5db199SXin Li byref(bValue)) 271*9c5db199SXin Li if result != 0: 272*9c5db199SXin Li msg = ('Error (0x%x) getting status for flag 0x%x' % 273*9c5db199SXin Li (result, flag.value)) 274*9c5db199SXin Li raise SmogcheckError(msg) 275*9c5db199SXin Li 276*9c5db199SXin Li logging.info('Tspi_TPM_GetStatus(): success for flag 0x%x', 277*9c5db199SXin Li flag.value) 278*9c5db199SXin Li 279*9c5db199SXin Li def _setTpmStatus(self, flag, bValue): 280*9c5db199SXin Li """Wrapper function to call Tspi_TPM_GetStatus(). 281*9c5db199SXin Li 282*9c5db199SXin Li Args: 283*9c5db199SXin Li flag: a c_uint, TPM status info flag. 284*9c5db199SXin Li bValue: a c_bool, place holder for specific TPM flag bit value (0/1). 285*9c5db199SXin Li 286*9c5db199SXin Li Raises: 287*9c5db199SXin Li SmogcheckError: if an error is encountered. 288*9c5db199SXin Li """ 289*9c5db199SXin Li result = self.tspi_lib.Tspi_TPM_SetStatus(self.hTpm, flag, bValue) 290*9c5db199SXin Li if result != 0: 291*9c5db199SXin Li msg = ('Error (0x%x) setting status for flag 0x%x' % 292*9c5db199SXin Li (result, flag.value)) 293*9c5db199SXin Li raise SmogcheckError(msg) 294*9c5db199SXin Li 295*9c5db199SXin Li logging.info('Tspi_TPM_SetStatus(): success for flag 0x%x', 296*9c5db199SXin Li flag.value) 297*9c5db199SXin Li 298*9c5db199SXin Li def getPolicyObject(self, hTpm=None, hPolicy=None): 299*9c5db199SXin Li """Get TPM policy object. 300*9c5db199SXin Li 301*9c5db199SXin Li Args: 302*9c5db199SXin Li hTpm: a c_uint, TPM object handle. 303*9c5db199SXin Li hPolicy: a c_uint, TPM policy object handle. 304*9c5db199SXin Li 305*9c5db199SXin Li Raises: 306*9c5db199SXin Li SmogcheckError: if an error is encountered. 307*9c5db199SXin Li """ 308*9c5db199SXin Li if hTpm is None: 309*9c5db199SXin Li hTpm = self.hTpm 310*9c5db199SXin Li 311*9c5db199SXin Li if hPolicy is None: 312*9c5db199SXin Li hPolicy = self.hTpmPolicy 313*9c5db199SXin Li 314*9c5db199SXin Li logging.debug('Tspi_GetPolicyObject(): hTpm = 0x%x, hPolicy = 0x%x', 315*9c5db199SXin Li hTpm.value, hPolicy.value) 316*9c5db199SXin Li result = self.tspi_lib.Tspi_GetPolicyObject(hTpm, TSS_POLICY_USAGE, 317*9c5db199SXin Li byref(hPolicy)) 318*9c5db199SXin Li if result != 0: 319*9c5db199SXin Li msg = 'Error (0x%x) getting TPM policy object' % result 320*9c5db199SXin Li raise SmogcheckError(msg) 321*9c5db199SXin Li 322*9c5db199SXin Li logging.debug('Tspi_GetPolicyObject() success hTpm = 0x%x, ' 323*9c5db199SXin Li 'hPolicy = 0x%x', hTpm.value, hPolicy.value) 324*9c5db199SXin Li 325*9c5db199SXin Li def setPolicySecret(self, hPolicy=None, pSecret=None, secret_mode=None): 326*9c5db199SXin Li """Sets TPM policy secret. 327*9c5db199SXin Li 328*9c5db199SXin Li Args: 329*9c5db199SXin Li hPolicy: a c_uint, TPM policy object handle. 330*9c5db199SXin Li pSecret: a pointer to a byte array, which holds the TSS secret. 331*9c5db199SXin Li secret_mode: a string, valid values are keys of TSS_SECRET_MODE. 332*9c5db199SXin Li 333*9c5db199SXin Li Raises: 334*9c5db199SXin Li SmogcheckError: if an error is encountered. 335*9c5db199SXin Li """ 336*9c5db199SXin Li if hPolicy is None: 337*9c5db199SXin Li hPolicy = self.hTpmPolicy 338*9c5db199SXin Li 339*9c5db199SXin Li if pSecret is None: 340*9c5db199SXin Li raise SmogcheckError('setPolicySecret(): pSecret cannot be None') 341*9c5db199SXin Li 342*9c5db199SXin Li if secret_mode is None or secret_mode not in TSS_SECRET_MODE: 343*9c5db199SXin Li raise SmogcheckError('setPolicySecret(): invalid secret_mode') 344*9c5db199SXin Li 345*9c5db199SXin Li logging.debug('Tspi_Policy_SetSecret(): hPolicy = 0x%x, secret_mode ' 346*9c5db199SXin Li '(%r) = %r', hPolicy.value, secret_mode, 347*9c5db199SXin Li TSS_SECRET_MODE[secret_mode]) 348*9c5db199SXin Li 349*9c5db199SXin Li result = self.tspi_lib.Tspi_Policy_SetSecret( 350*9c5db199SXin Li hPolicy, TSS_SECRET_MODE[secret_mode], TPM_SHA1_160_HASH_LEN, 351*9c5db199SXin Li pSecret) 352*9c5db199SXin Li if result != 0: 353*9c5db199SXin Li msg = 'Error (0x%x) setting TPM policy secret' % result 354*9c5db199SXin Li raise SmogcheckError(msg) 355*9c5db199SXin Li 356*9c5db199SXin Li logging.debug('Tspi_Policy_SetSecret() success, hPolicy = 0x%x', 357*9c5db199SXin Li hPolicy.value) 358*9c5db199SXin Li 359*9c5db199SXin Li def getTpmVersion(self): 360*9c5db199SXin Li """Gets TPM version info. 361*9c5db199SXin Li 362*9c5db199SXin Li Implementation based on tpm-tools-1.3.4/src/tpm_mgmt/tpm_version.c 363*9c5db199SXin Li Downloaded from: 364*9c5db199SXin Li http://sourceforge.net/projects/trousers/files/tpm-tools/1.3.4/\ 365*9c5db199SXin Li tpm-tools-1.3.4.tar.gz 366*9c5db199SXin Li 367*9c5db199SXin Li Raises: 368*9c5db199SXin Li SmogcheckError: if an error is encountered. 369*9c5db199SXin Li """ 370*9c5db199SXin Li uiResultLen = c_uint32(0) 371*9c5db199SXin Li pResult = c_char_p() 372*9c5db199SXin Li offset = c_uint64(0) 373*9c5db199SXin Li versionInfo = TpmCapVersionInfo() 374*9c5db199SXin Li InitVersionInfo(versionInfo) 375*9c5db199SXin Li 376*9c5db199SXin Li logging.debug('Successfully set up tspi context: hTpm = %r', self.hTpm) 377*9c5db199SXin Li 378*9c5db199SXin Li result = self.tspi_lib.Tspi_TPM_GetCapability( 379*9c5db199SXin Li self.hTpm, TSS_TPMCAP_VERSION_VAL, 0, POINTER(c_byte)(), 380*9c5db199SXin Li byref(uiResultLen), byref(pResult)) 381*9c5db199SXin Li if result != 0: 382*9c5db199SXin Li msg = 'Error (0x%x) getting TPM capability, pResult = %r' % ( 383*9c5db199SXin Li result, pResult.value) 384*9c5db199SXin Li raise SmogcheckError(msg) 385*9c5db199SXin Li 386*9c5db199SXin Li logging.info('Successfully received TPM capability: ' 387*9c5db199SXin Li 'uiResultLen = %d, pResult=%r', uiResultLen.value, 388*9c5db199SXin Li pResult.value) 389*9c5db199SXin Li result = self.tspi_lib.Trspi_UnloadBlob_CAP_VERSION_INFO( 390*9c5db199SXin Li byref(offset), pResult, cast(byref(versionInfo), 391*9c5db199SXin Li POINTER(c_byte))) 392*9c5db199SXin Li if result != 0: 393*9c5db199SXin Li msg = 'Error (0x%x) unloading TPM CAP version info' % result 394*9c5db199SXin Li raise SmogcheckError(msg) 395*9c5db199SXin Li 396*9c5db199SXin Li PrintVersionInfo(versionInfo) 397*9c5db199SXin Li 398*9c5db199SXin Li def runTpmSelfTest(self): 399*9c5db199SXin Li """Executes TPM self test. 400*9c5db199SXin Li 401*9c5db199SXin Li Implementation based on tpm-tools-1.3.4/src/tpm_mgmt/tpm_selftest.c 402*9c5db199SXin Li 403*9c5db199SXin Li Raises: 404*9c5db199SXin Li SmogcheckError: if an error is encountered. 405*9c5db199SXin Li """ 406*9c5db199SXin Li uiResultLen = c_uint32(0) 407*9c5db199SXin Li pResult = c_char_p() 408*9c5db199SXin Li self.setupContext() 409*9c5db199SXin Li 410*9c5db199SXin Li logging.debug('Successfully set up tspi context: hTpm = 0x%x', 411*9c5db199SXin Li self.hTpm.value) 412*9c5db199SXin Li 413*9c5db199SXin Li result = self.tspi_lib.Tspi_TPM_SelfTestFull(self.hTpm) 414*9c5db199SXin Li if result != 0: 415*9c5db199SXin Li self.closeContext() 416*9c5db199SXin Li raise SmogcheckError('Error (0x%x) with TPM self test' % result) 417*9c5db199SXin Li 418*9c5db199SXin Li logging.info('Successfully executed TPM self test: hTpm = 0x%x', 419*9c5db199SXin Li self.hTpm.value) 420*9c5db199SXin Li result = self.tspi_lib.Tspi_TPM_GetTestResult( 421*9c5db199SXin Li self.hTpm, byref(uiResultLen), byref(pResult)) 422*9c5db199SXin Li if result != 0: 423*9c5db199SXin Li self.closeContext() 424*9c5db199SXin Li raise SmogcheckError('Error (0x%x) getting test results' % result) 425*9c5db199SXin Li 426*9c5db199SXin Li logging.info('TPM self test results: uiResultLen = %d, pResult=%r', 427*9c5db199SXin Li uiResultLen.value, pResult.value) 428*9c5db199SXin Li PrintSelfTestResult(uiResultLen.value, pResult) 429*9c5db199SXin Li self.closeContext() 430*9c5db199SXin Li 431*9c5db199SXin Li def takeTpmOwnership(self): 432*9c5db199SXin Li """Take TPM ownership. 433*9c5db199SXin Li 434*9c5db199SXin Li Implementation based on tpm-tools-1.3.4/src/tpm_mgmt/tpm_takeownership.c 435*9c5db199SXin Li 436*9c5db199SXin Li Raises: 437*9c5db199SXin Li SmogcheckError: if an error is encountered. 438*9c5db199SXin Li """ 439*9c5db199SXin Li hSrk = c_uint32(0) # TPM Storage Root Key 440*9c5db199SXin Li hSrkPolicy = c_uint32(0) 441*9c5db199SXin Li # Defaults each byte value to 0x00 442*9c5db199SXin Li well_known_secret = create_string_buffer(20) 443*9c5db199SXin Li pSecret = c_char_p(addressof(well_known_secret)) 444*9c5db199SXin Li 445*9c5db199SXin Li self.setupContext() 446*9c5db199SXin Li logging.debug('Successfully set up tspi context: hTpm = 0x%x', 447*9c5db199SXin Li self.hTpm.value) 448*9c5db199SXin Li 449*9c5db199SXin Li try: 450*9c5db199SXin Li self.getPolicyObject() 451*9c5db199SXin Li self.setPolicySecret(pSecret=pSecret, secret_mode='sha1') 452*9c5db199SXin Li except SmogcheckError: 453*9c5db199SXin Li if hSrk != 0: 454*9c5db199SXin Li self._closeContextObject(hSrk) 455*9c5db199SXin Li self.closeContext() 456*9c5db199SXin Li raise # re-raise 457*9c5db199SXin Li 458*9c5db199SXin Li flag = TSS_KEY_TSP_SRK.value | TSS_KEY_AUTHORIZATION.value 459*9c5db199SXin Li result = self.tspi_lib.Tspi_Context_CreateObject( 460*9c5db199SXin Li self.hContext, TSS_OBJECT_TYPE_RSAKEY, flag, byref(hSrk)) 461*9c5db199SXin Li if result != 0: 462*9c5db199SXin Li raise SmogcheckError('Error (0x%x) creating context object' % 463*9c5db199SXin Li result) 464*9c5db199SXin Li logging.debug('hTpm = 0x%x, flag = 0x%x, hSrk = 0x%x', 465*9c5db199SXin Li self.hTpm.value, flag, hSrk.value) # DEBUG 466*9c5db199SXin Li 467*9c5db199SXin Li try: 468*9c5db199SXin Li self.getPolicyObject(hTpm=hSrk, hPolicy=hSrkPolicy) 469*9c5db199SXin Li self.setPolicySecret(hPolicy=hSrkPolicy, pSecret=pSecret, 470*9c5db199SXin Li secret_mode='sha1') 471*9c5db199SXin Li except SmogcheckError: 472*9c5db199SXin Li if hSrk != 0: 473*9c5db199SXin Li self._closeContextObject(hSrk) 474*9c5db199SXin Li self.closeContext() 475*9c5db199SXin Li raise # re-raise 476*9c5db199SXin Li 477*9c5db199SXin Li logging.debug('Successfully set up SRK policy: secret = %r, ' 478*9c5db199SXin Li 'hSrk = 0x%x, hSrkPolicy = 0x%x', 479*9c5db199SXin Li well_known_secret.value, hSrk.value, hSrkPolicy.value) 480*9c5db199SXin Li 481*9c5db199SXin Li start_time = datetime.datetime.now() 482*9c5db199SXin Li result = self.tspi_lib.Tspi_TPM_TakeOwnership(self.hTpm, hSrk, 483*9c5db199SXin Li c_uint(0)) 484*9c5db199SXin Li end_time = datetime.datetime.now() 485*9c5db199SXin Li if result != 0: 486*9c5db199SXin Li logging.info('Tspi_TPM_TakeOwnership error') 487*9c5db199SXin Li self._closeContextObject(hSrk) 488*9c5db199SXin Li self.closeContext() 489*9c5db199SXin Li raise SmogcheckError('Error (0x%x) taking TPM ownership' % result) 490*9c5db199SXin Li 491*9c5db199SXin Li logging.info('Successfully took TPM ownership') 492*9c5db199SXin Li self._closeContextObject(hSrk) 493*9c5db199SXin Li self.closeContext() 494*9c5db199SXin Li return smogcheck_ttci.computeTimeElapsed(end_time, start_time) 495*9c5db199SXin Li 496*9c5db199SXin Li def clearTpm(self): 497*9c5db199SXin Li """Return TPM to default state. 498*9c5db199SXin Li 499*9c5db199SXin Li Implementation based on tpm-tools-1.3.4/src/tpm_mgmt/tpm_clear.c 500*9c5db199SXin Li 501*9c5db199SXin Li Raises: 502*9c5db199SXin Li SmogcheckError: if an error is encountered. 503*9c5db199SXin Li """ 504*9c5db199SXin Li logging.debug('Successfully set up tspi context: hTpm = %r', self.hTpm) 505*9c5db199SXin Li 506*9c5db199SXin Li result = self.tspi_lib.Tspi_TPM_ClearOwner(self.hTpm, True) 507*9c5db199SXin Li if result != 0: 508*9c5db199SXin Li raise SmogcheckError('Error (0x%x) clearing TPM' % result) 509*9c5db199SXin Li 510*9c5db199SXin Li logging.info('Successfully cleared TPM') 511*9c5db199SXin Li 512*9c5db199SXin Li def setTpmActive(self, op): 513*9c5db199SXin Li """Change TPM active state. 514*9c5db199SXin Li 515*9c5db199SXin Li Implementation based on tpm-tools-1.3.4/src/tpm_mgmt/tpm_activate.c 516*9c5db199SXin Li 517*9c5db199SXin Li Args: 518*9c5db199SXin Li op: a string, desired operation. Valid values are defined in 519*9c5db199SXin Li TPM_SETACTIVE_OP. 520*9c5db199SXin Li 521*9c5db199SXin Li Raises: 522*9c5db199SXin Li SmogcheckError: if an error is encountered. 523*9c5db199SXin Li """ 524*9c5db199SXin Li bValue = c_bool() 525*9c5db199SXin Li # Defaults each byte value to 0x00 526*9c5db199SXin Li well_known_secret = create_string_buffer(20) 527*9c5db199SXin Li pSecret = c_char_p(addressof(well_known_secret)) 528*9c5db199SXin Li 529*9c5db199SXin Li if op not in TPM_SETACTIVE_OP: 530*9c5db199SXin Li msg = ('Invalid op (%s) for tpmSetActive(). Valid values are %r' % 531*9c5db199SXin Li (op, TPM_SETACTIVE_OP)) 532*9c5db199SXin Li raise SmogcheckError(msg) 533*9c5db199SXin Li 534*9c5db199SXin Li logging.debug('Successfully set up tspi context: hTpm = %r', self.hTpm) 535*9c5db199SXin Li 536*9c5db199SXin Li if op == 'status': 537*9c5db199SXin Li self.getPolicyObject() 538*9c5db199SXin Li self.setPolicySecret(pSecret=pSecret, secret_mode='sha1') 539*9c5db199SXin Li 540*9c5db199SXin Li self._getTpmStatus( 541*9c5db199SXin Li TSS_TPMSTATUS_PHYSICALSETDEACTIVATED, bValue) 542*9c5db199SXin Li logging.info('Persistent Deactivated Status: %s', bValue.value) 543*9c5db199SXin Li 544*9c5db199SXin Li self._getTpmStatus( 545*9c5db199SXin Li TSS_TPMSTATUS_SETTEMPDEACTIVATED, bValue) 546*9c5db199SXin Li logging.info('Volatile Deactivated Status: %s', bValue.value) 547*9c5db199SXin Li elif op == 'activate': 548*9c5db199SXin Li self._setTpmStatus( 549*9c5db199SXin Li TSS_TPMSTATUS_PHYSICALSETDEACTIVATED, False) 550*9c5db199SXin Li logging.info('Successfully activated TPM') 551*9c5db199SXin Li elif op == 'deactivate': 552*9c5db199SXin Li self._setTpmStatus( 553*9c5db199SXin Li TSS_TPMSTATUS_PHYSICALSETDEACTIVATED, True) 554*9c5db199SXin Li logging.info('Successfully deactivated TPM') 555*9c5db199SXin Li elif op == 'temp': 556*9c5db199SXin Li self._setTpmStatus( 557*9c5db199SXin Li TSS_TPMSTATUS_SETTEMPDEACTIVATED, True) 558*9c5db199SXin Li logging.info('Successfully deactivated TPM for current boot') 559*9c5db199SXin Li 560*9c5db199SXin Li def setTpmClearable(self, op): 561*9c5db199SXin Li """Disable TPM clear operations. 562*9c5db199SXin Li 563*9c5db199SXin Li Implementation based on tpm-tools-1.3.4/src/tpm_mgmt/tpm_clearable.c 564*9c5db199SXin Li 565*9c5db199SXin Li Args: 566*9c5db199SXin Li op: a string, desired operation. Valid values are defined in 567*9c5db199SXin Li TPM_SETCLEARABLE_OP. 568*9c5db199SXin Li 569*9c5db199SXin Li Raises: 570*9c5db199SXin Li SmogcheckError: if an error is encountered. 571*9c5db199SXin Li """ 572*9c5db199SXin Li bValue = c_bool() 573*9c5db199SXin Li # Defaults each byte value to 0x00 574*9c5db199SXin Li well_known_secret = create_string_buffer(20) 575*9c5db199SXin Li pSecret = c_char_p(addressof(well_known_secret)) 576*9c5db199SXin Li 577*9c5db199SXin Li if op not in TPM_SETCLEARABLE_OP: 578*9c5db199SXin Li msg = ('Invalid op (%s) for tpmSetClearable(). Valid values are %r' 579*9c5db199SXin Li % (op, TPM_SETCLEARABLE_OP)) 580*9c5db199SXin Li raise SmogcheckError(msg) 581*9c5db199SXin Li 582*9c5db199SXin Li logging.debug('Successfully set up tspi context: hTpm = %r', self.hTpm) 583*9c5db199SXin Li 584*9c5db199SXin Li if op == 'status': 585*9c5db199SXin Li self.getPolicyObject() 586*9c5db199SXin Li self.setPolicySecret(pSecret=pSecret, secret_mode='sha1') 587*9c5db199SXin Li 588*9c5db199SXin Li self._getTpmStatus( 589*9c5db199SXin Li TSS_TPMSTATUS_DISABLEOWNERCLEAR, bValue) 590*9c5db199SXin Li logging.info('Owner Clear Disabled: %s', bValue.value) 591*9c5db199SXin Li 592*9c5db199SXin Li self._getTpmStatus( 593*9c5db199SXin Li TSS_TPMSTATUS_DISABLEFORCECLEAR, bValue) 594*9c5db199SXin Li logging.info('Force Clear Disabled: %s', bValue.value) 595*9c5db199SXin Li elif op == 'owner': 596*9c5db199SXin Li self.getPolicyObject() 597*9c5db199SXin Li self.setPolicySecret(pSecret=pSecret, secret_mode='sha1') 598*9c5db199SXin Li 599*9c5db199SXin Li self._setTpmStatus( 600*9c5db199SXin Li TSS_TPMSTATUS_DISABLEOWNERCLEAR, False) 601*9c5db199SXin Li logging.info('Successfully disabled Owner Clear') 602*9c5db199SXin Li elif op == 'force': 603*9c5db199SXin Li self._setTpmStatus( 604*9c5db199SXin Li TSS_TPMSTATUS_DISABLEFORCECLEAR, True) 605*9c5db199SXin Li logging.info('Successfully disabled Force Clear') 606