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