blob: 34811c019637b9bac5792e0c8d1743ebf7dda377 [file] [log] [blame]
// Copyright 2021 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.
package hwsec
/*
This file implements the TPM clear tool in remote tast.
*/
import (
"context"
"path/filepath"
"time"
"chromiumos/tast/common/hwsec"
"chromiumos/tast/dut"
"chromiumos/tast/errors"
"chromiumos/tast/testing"
)
// TPMClearer clear the TPM via crossystem, this would work on both TPM1.2 and TPM2.0.
type TPMClearer struct {
cmdRunner hwsec.CmdRunner
daemonController *hwsec.DaemonController
dut *dut.DUT
}
// NewTPMClearer creates a new TPMClearer object, where r is used to run the command internally.
func NewTPMClearer(cmdRunner hwsec.CmdRunner, daemonController *hwsec.DaemonController, dut *dut.DUT) *TPMClearer {
return &TPMClearer{cmdRunner, daemonController, dut}
}
// PreClearTPM backups the logs
func (tc *TPMClearer) PreClearTPM(ctx context.Context) error {
// Copy logs before TPM reset. Ignore errors on failure.
if outDir, ok := testing.ContextOutDir(ctx); ok {
dateString := time.Now().Format(time.RFC3339)
if err := tc.dut.GetFile(ctx, "/var/log/chrome/", filepath.Join(outDir, "chrome-"+dateString)); err != nil {
testing.ContextLog(ctx, "Failed to copy chrome logs: ", err)
}
}
return nil
}
// ClearTPM sends the TPM clear request
func (tc *TPMClearer) ClearTPM(ctx context.Context) error {
// Reset the flag of finished clearing.
if rawOutput, err := tc.cmdRunner.RunWithCombinedOutput(ctx, "crossystem", "clear_tpm_owner_done=0"); err != nil {
// clear_tpm_owner_done is meaningless on VM.
// We should log the error message instead of failing the test.
testing.ContextLogf(ctx, "Failed to reset clear_tpm_owner_done, output: %q, %v", string(rawOutput), err)
}
// Fire clear TPM owner request to crossystem.
if rawOutput, err := tc.cmdRunner.RunWithCombinedOutput(ctx, "crossystem", "clear_tpm_owner_request=1"); err != nil {
return errors.Wrapf(err, "failed to fire clear_tpm_owner_request, output: %q", string(rawOutput))
}
// Check we have effective value of crossystem.
rawOutput, err := tc.cmdRunner.RunWithCombinedOutput(ctx, "crossystem", "clear_tpm_owner_done")
output := string(rawOutput)
if err != nil {
// clear_tpm_owner_done is meaningless on VM.
// We should log the error message instead of failing the test, the error message is for verbosity.
testing.ContextLogf(ctx, "Failed to query clear_tpm_owner_done, output: %q, %v", output, err)
}
if output != "0" {
// clear_tpm_owner_done is meaningless on VM.
// We should log the error message instead of failing the test, the error message is for verbosity.
testing.ContextLogf(ctx, "clear_tpm_owner_done = %q; want 0", output)
}
rawOutput, err = tc.cmdRunner.RunWithCombinedOutput(ctx, "crossystem", "clear_tpm_owner_request")
output = string(rawOutput)
if err != nil {
return errors.Wrapf(err, "failed to query clear_tpm_owner_request, output: %q", output)
}
if output != "1" {
return errors.Wrapf(err, "clear_tpm_owner_request = %q; want 1", output)
}
return nil
}
// PostClearTPM reboots and ensure every TPM daemon is up.
func (tc *TPMClearer) PostClearTPM(ctx context.Context) error {
if err := tc.dut.Reboot(ctx); err != nil {
return errors.Wrap(err, "failed to reboot")
}
// Wait for services.
if err := tc.daemonController.WaitForAllDBusServices(ctx); err != nil {
return errors.Wrap(err, "failed to wait for hwsec D-Bus services to be ready")
}
// Check we have effective reset of TPM.
rawOutput, err := tc.cmdRunner.RunWithCombinedOutput(ctx, "crossystem", "clear_tpm_owner_done")
output := string(rawOutput)
if err != nil {
// clear_tpm_owner_done is meaningless on VM.
// We should log the error message instead of failing the test.
testing.ContextLogf(ctx, "Failed to query clear_tpm_owner_done, output: %q, %v", output, err)
}
if output != "1" {
// clear_tpm_owner_done is meaningless on VM.
// We should log the error message instead of failing the test.
testing.ContextLogf(ctx, "clear_tpm_owner_done = %q; want 1", output)
}
rawOutput, err = tc.cmdRunner.RunWithCombinedOutput(ctx, "crossystem", "clear_tpm_owner_request")
output = string(rawOutput)
if err != nil {
return errors.Wrapf(err, "failed to query clear_tpm_owner_request, output: %q", output)
}
if output != "0" {
return errors.Wrapf(err, "clear_tpm_owner_request = %q; want 0", output)
}
return nil
}