| # Copyright (c) 2012 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. |
| |
| description "TrouSerS daemon" |
| author "chromium-os-dev@chromium.org" |
| |
| # The TrouSerS daemon implements TSS, a standard API for access to |
| # TPM hardware (or to a TPM emulator). |
| # |
| # No 'start on'; the job is started with 'start' from tpm-probe. |
| stop on stopping boot-services |
| respawn |
| |
| pre-start script |
| # If we're booting in recovery mode, first do a sanity check of the TPM and |
| # try to bring it to a sane state. Then clear the TPM owner and lock the |
| # TPM down. |
| if ! crossystem "recovery_reason?0" ; then |
| chromeos-tpm-recovery /var/log/tpm-recovery.log || |
| logger -t "$UPSTART_JOB" "tpm-recovery status $?" |
| tpmc clear || logger -t "$UPSTART_JOB" "tpmc clear: status $?" |
| tpmc enable || logger -t "$UPSTART_JOB" "tpmc enable: status $?" |
| tpmc act || logger -t "$UPSTART_JOB" "tpmc act: status $?" |
| tpmc block || logger -t "$UPSTART_JOB" "tpmc block: status $?" |
| tpmc pplock || logger -t "$UPSTART_JOB" "tpmc pplock: status $?" |
| fi |
| |
| if [ -e /sys/class/misc/tpm0/device/owned ]; then |
| owned=$(cat /sys/class/misc/tpm0/device/owned || echo "") |
| if [ "$owned" -eq "0" ]; then |
| # Clean up any existing tcsd state. |
| rm -rf /var/lib/tpm/* |
| elif [ "$owned" -eq "1" ]; then |
| # Already owned. |
| # Check if trousers' system.data is size zero. If so, then the TPM has |
| # been owned already and we need to copy over an empty system.data to be |
| # able to use it in trousers. |
| if [ ! -f /var/lib/tpm/system.data ] || |
| [ ! -s /var/lib/tpm/system.data ]; then |
| if [ ! -e /var/lib/tpm ]; then |
| mkdir -m 0700 -p /var/lib/tpm |
| fi |
| umask 0177 |
| cp --no-preserve=mode /etc/trousers/system.data.auth \ |
| /var/lib/tpm/system.data |
| umask 0133 |
| touch /var/lib/.tpm_owned |
| fi |
| fi |
| fi |
| |
| # Check the dictionary-attack counter. |
| if grep -q "Manufacturer: 0x49465800" /sys/class/misc/tpm0/device/caps; then |
| # Infineon has a vendor-specific capability for this. The following command |
| # queries the TPM_CAP_MFR capability area. |
| tpm_command="00 c1 00 00 00 16 00 00 00 65 00 00 00 10 00 00 00 04 00 00 \ |
| 08 02" |
| # The output is vendor-specific; we're interested in the 24th byte. The |
| # output is printed in rows of 8 bytes so we want row 3, field 8. |
| count=$(($(tpmc raw $tpm_command | awk 'NR == 3 { print $8; }'))) |
| elif [ -e /sys/class/misc/tpm0/device/caps ]; then |
| # If not Infineon, try to query the TPM_CAP_DA_LOGIC capability area with a |
| # TPM_ET_SRK entity type. |
| tpm_command="00 c1 00 00 00 14 00 00 00 65 00 00 00 19 00 00 00 02 00 04" |
| # The output is a TPM_DA_INFO structure; we're interested in the least |
| # significant byte of the currentCount field (row 3, field 3). |
| count=$(($(tpmc raw $tpm_command | awk 'NR == 3 { print $3; }'))) |
| fi |
| if [ "$count" == "" ]; then |
| # Report 100 when we don't know the counter value. |
| count=100 |
| fi |
| metrics_client -b -e Platform.TPM.DictionaryAttackCounter $count 100 || |
| logger -t "$UPSTART_JOB" "metrics_client -e: status $?" |
| if [ $count -ne 0 ]; then |
| logger -t "$UPSTART_JOB" "WARNING: Non-zero dictionary attack counter found: $count" |
| metrics_client -b -v TPM.NonZeroDictionaryAttackCounter || |
| logger -t "$UPSTART_JOB" "metrics_client -v: status $?" |
| fi |
| end script |
| |
| expect fork |
| exec tcsd |