# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""A module containing TPM handler class used by SAFT."""

FW_NV_ADDRESS = 0x1007
KERNEL_NV_ADDRESS = 0x1008

class TpmError(Exception):
    pass

class TpmNvRam(object):
    """An object representing TPM NvRam.

    Attributes:
    addr: a number, NvRAm address in TPM.
    size: a number, count of bites in this NvRam section.
    os_if: an instance of the OS interface (os_interface or a mock object).
    version_offset: - a number, offset into the NvRam contents where the the
        versions are stored. The total version field size is 4 bytes, the
        first two bytes are the body version, the second two bytes are the key
        version. Numbers are stored in little endian format.
    pattern: optional, a tuple of two elements, the first element is the
       offset of the pattern expected to be present in the NvRam, and the
       second element is an array of bytes the pattern must match.
    contents: an array of bytes, the contents of the NvRam.
    """

    def __init__(self, addr, size, version_offset, data_pattern=None):
        self.addr = addr
        self.size = size
        self.os_if = None
        self.version_offset = version_offset
        self.pattern = data_pattern
        self.contents = []

    def init(self, os_if):
        self.os_if = os_if
        cmd = 'tpmc read 0x%x 0x%x' % (self.addr, self.size)
        nvram_data = self.os_if.run_shell_command_get_output(cmd)[0].split()
        self.contents = [int(x, 16) for x in nvram_data]
        if self.pattern:
            pattern_offset = self.pattern[0]
            pattern_data = self.pattern[1]
            contents_pattern = self.contents[pattern_offset:pattern_offset +
                                             len(pattern_data)]
            if contents_pattern != pattern_data:
                raise TpmError('Nvram pattern does not match')

    def get_body_version(self):
        return self.contents[
            self.version_offset + 1] * 256 + self.contents[self.version_offset]

    def get_key_version(self):
        return self.contents[
            self.version_offset + 3] * 256 + self.contents[
            self.version_offset + 2]

class TpmHandler(object):
    """An object to control TPM device's NVRAM.

    Attributes:
      os_if: an instance of the OS interface (os_interface or a mock object).
      nvrams: A dictionary where the keys are the nvram names, and the values
          are instances of TpmNvRam objects, providing access to the
          appropriate TPM NvRam sections.
    """

    def __init__(self):
        self.os_if = None
        self.nvrams = {
            'kernel': TpmNvRam(KERNEL_NV_ADDRESS, 13, 5, (
                    1, [0x4c, 0x57, 0x52, 0x47])),
            'bios': TpmNvRam(FW_NV_ADDRESS, 10, 2)
            }
        self.trunksd_started = False
        self.tcsd_started = False

    def init(self, os_if):
        self.os_if = os_if
        self.stop_daemon()
        for nvram in self.nvrams.itervalues():
            nvram.init(self.os_if)
        self.restart_daemon()

    def get_fw_version(self):
        return self.nvrams['bios'].get_body_version()

    def get_fw_key_version(self):
        return self.nvrams['bios'].get_key_version()

    def get_kernel_version(self):
        return self.nvrams['kernel'].get_body_version()

    def get_kernel_key_version(self):
        return self.nvrams['kernel'].get_key_version()

    def stop_daemon(self):
        """Stop TPM related daemon."""
        if self.trunksd_started or self.tcsd_started:
            raise TpmError('Called stop_daemon() before')

        cmd = 'initctl status tcsd || initctl status trunksd'
        status = self.os_if.run_shell_command_get_output(cmd) or ['']
        # Expected status is like ['trunksd start/running, process 2375']
        self.trunksd_started = status[0].startswith('trunksd start/running')
        if self.trunksd_started:
            self.os_if.run_shell_command('stop trunksd')
        else:
            self.tcsd_started = status[0].startswith('tcsd start/running')
            if self.tcsd_started:
                self.os_if.run_shell_command('stop tcsd')

    def restart_daemon(self):
        """Restart TPM related daemon which was stopped by stop_daemon()."""
        if self.trunksd_started:
            self.os_if.run_shell_command('start trunksd')
            self.trunksd_started = False
        elif self.tcsd_started:
            self.os_if.run_shell_command('start tcsd')
            self.tcsd_started = False
