# Copyright 2014 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.

"""
Provides a utility function for working with TPM DAM logic.

Dictionary Attack Mitigation (DAM) logic causes TPMs to enter a locked down
state to defend against dictionary attacks. Authentication failures cause a
counter to increment and when the counter exceeds some threshold, the defense
mechanism is triggered.
"""

import re

from autotest_lib.client.common_lib import utils
from autotest_lib.client.cros import service_stopper

def get_dictionary_attack_counter():
    """Returns the current dictionary attack counter."""
    tpm_command_info = {
        '0x49465800': {  # Infineon
            'command': ('00 c1 '         # Tag = TPM_TAG_RQU_COMMAND
                        '00 00 00 16 '   # Size = 22
                        '00 00 00 65 '   # Ordinal = TPM_ORD_GetCapability
                        '00 00 00 10 '   # Capability Area = TPM_CAP_MFR
                        '00 00 00 04 '   # Size = 4
                        '00 00 08 02'),  # Vendor-specific
            'response_offset': 23},      # Vendor-specific
        '0x57454300': {  # Nuvoton
            'command': ('00 c1 '         # Tag = TPM_TAG_RQU_COMMAND
                        '00 00 00 14 '   # Size = 20
                        '00 00 00 65 '   # Ordinal = TPM_ORD_GetCapability
                        '00 00 00 19 '   # Capability Area = TPM_CAP_DA_LOGIC
                        '00 00 00 02 '   # Size = 2
                        '00 04'),        # Entity Type = TPM_ET_SRK
            'response_offset': 18},      # TPM_DA_INFO.currentCount LSB
        '0x53544d20': {  # STMicro
            'command': ('00 c1 '         # Tag = TPM_TAG_RQU_COMMAND
                        '00 00 00 14 '   # Size = 20
                        '00 00 00 65 '   # Ordinal = TPM_ORD_GetCapability
                        '00 00 00 19 '   # Capability Area = TPM_CAP_DA_LOGIC
                        '00 00 00 02 '   # Size = 2
                        '00 04'),        # Entity Type = TPM_ET_SRK
            'response_offset': 18}}      # TPM_DA_INFO.currentCount LSB
    try:
        with open('/sys/class/misc/tpm0/device/caps', 'r') as fp:
            caps = fp.read()
    except IOError:
        return 'Could not read TPM device caps.'
    match = re.search(r'Manufacturer: (0x[0-9A-Fa-f]*)', caps)
    if not match:
        return 'Could not find TPM manufacturer.'
    manufacturer = match.group(1)
    if manufacturer not in tpm_command_info:
        return 'TPM manufacturer not supported.'
    with service_stopper.ServiceStopper(['cryptohomed',
                                         'chapsd',
                                         'tcsd']):
        # The output of 'tpmc raw' is a series of bytes in the form
        # '0x00 0x01 0x02 ...'.
        tpm_response = utils.system_output(
                'tpmc raw %s' % tpm_command_info[manufacturer]['command'],
                ignore_status=True).split()
    offset = tpm_command_info[manufacturer]['response_offset']
    if (len(tpm_response) <= offset):
        return 'Unexpected TPM response (length = %d).' % len(tpm_response)
    return int(tpm_response[offset], base=16)


