tpm_handler.py revision 9999730bc117c6a6363b616d3da5dbf0eb6b4d50
1# Copyright (c) 2010 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 module containing TPM handler class used by SAFT.""" 6 7FW_NV_ADDRESS = 0x1007 8KERNEL_NV_ADDRESS = 0x1008 9 10class TpmError(Exception): 11 pass 12 13class TpmNvRam(object): 14 """An object representing TPM NvRam. 15 16 Attributes: 17 addr: a number, NvRAm address in TPM. 18 size: a number, count of bites in this NvRam section. 19 os_if: an instance of the OS interface (chromeos_interface or a mock 20 object). 21 version_offset: - a number, offset into the NvRam contents where the the 22 versions are stored. The total version field size is 4 bytes, the 23 first two bytes are the body version, the second two bytes are the key 24 version. Numbers are stored in little endian format. 25 pattern: optional, a tuple of two elements, the first element is the 26 offset of the pattern expected to be present in the NvRam, and the 27 second element is an array of bytes the pattern must match. 28 contents: an array of bytes, the contents of the NvRam. 29 """ 30 31 def __init__(self, addr, size, version_offset, data_pattern=None): 32 self.addr = addr 33 self.size = size 34 self.os_if = None 35 self.version_offset = version_offset 36 self.pattern = data_pattern 37 self.contents = [] 38 39 def init(self, os_if): 40 self.os_if = os_if 41 cmd = 'tpmc read 0x%x 0x%x' % (self.addr, self.size) 42 nvram_data = self.os_if.run_shell_command_get_output(cmd)[0].split() 43 self.contents = [int(x, 16) for x in nvram_data] 44 if self.pattern: 45 pattern_offset = self.pattern[0] 46 pattern_data = self.pattern[1] 47 contents_pattern = self.contents[pattern_offset:pattern_offset + 48 len(pattern_data)] 49 if contents_pattern != pattern_data: 50 raise TpmError('Nvram pattern does not match') 51 52 def get_body_version(self): 53 return self.contents[ 54 self.version_offset + 1] * 256 + self.contents[self.version_offset] 55 56 def get_key_version(self): 57 return self.contents[ 58 self.version_offset + 3] * 256 + self.contents[ 59 self.version_offset + 2] 60 61class TpmHandler(object): 62 """An object to control TPM device's NVRAM. 63 64 Attributes: 65 cros_if: an instance of the OS interface (chromeos_interface or a mock 66 object). 67 nvrams: A dictionary where the keys are the nvram names, and the values 68 are instances of TpmNvRam objects, providing access to the 69 appropriate TPM NvRam sections. 70 """ 71 72 def __init__(self): 73 self.cros_if = None 74 self.nvrams = { 75 'kernel': TpmNvRam(KERNEL_NV_ADDRESS, 13, 5, ( 76 1, [0x4c, 0x57, 0x52, 0x47])), 77 'bios': TpmNvRam(FW_NV_ADDRESS, 10, 2) 78 } 79 80 def init(self, cros_if): 81 self.cros_if = cros_if 82 status = self.cros_if.run_shell_command_get_output( 83 'initctl status tcsd')[0] 84 if status.startswith('tcsd start/running'): 85 self.cros_if.run_shell_command('stop tcsd') 86 87 for nvram in self.nvrams.itervalues(): 88 nvram.init(self.cros_if) 89 90 def get_fw_version(self): 91 return self.nvrams['bios'].get_body_version() 92 93 def get_fw_body_version(self): 94 return self.nvrams['bios'].get_key_version() 95 96 def get_kernel_version(self): 97 return self.nvrams['kernel'].get_body_version() 98