blob: 75abfed302594f0a2bb10886b84f213fe2243ac5 [file] [log] [blame]
// Copyright 2020 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
import (
"context"
"regexp"
"time"
hwseclocal "chromiumos/tast/local/hwsec"
"chromiumos/tast/local/syslog"
"chromiumos/tast/testing"
)
// NOTE: This test is somewhat similar to hwsec.DictionaryAttackLockoutResetTPM2 (a local test), if change is
// made to one, it is likely that the other have to be changed as well.
// The referred test is specifically for TPMv2.0, while this test is for TPMv1.2.
// Both versions of TPM is incompatible with each other and the available NVRAM index differs across the 2 versions.
// Therefore, we need 2 versions of the test.
// This version uses existing NVRAM space (endorsement cert) on TPMv1.2. Reading it with incorrect auth on
// TPMv1.2 will generate dictionary attack counter increment needed by this test. However, on TPMv2.0, this
// behaviour is different so the same method is not used in the other test.
func init() {
testing.AddTest(&testing.Test{
Func: DictionaryAttackLockoutResetTPM1,
Desc: "Verifies that for TPMv1.2 devices, dictionary attack counter functions correctly and can be reset",
Contacts: []string{
"zuan@chromium.org",
"cros-hwsec@chromium.org",
},
SoftwareDeps: []string{"tpm1"},
Attr: []string{"group:mainline", "informational"},
})
}
// DictionaryAttackLockoutResetTPM1 checks that get dictionary attack info and reset dictionary attack lockout works as expected.
func DictionaryAttackLockoutResetTPM1(ctx context.Context, s *testing.State) {
cmdRunner := hwseclocal.NewCmdRunner()
helper, err := hwseclocal.NewHelper(cmdRunner)
if err != nil {
s.Fatal("Failed to create hwsec local helper: ", err)
}
tpmManager := helper.TPMManagerClient()
daemonController := helper.DaemonController()
// In this test, we want to check if DA counter will be reset when it increases.
// Check DA Counter => Read NVRAM Index with incorrect password => Check DA Counter
// Read NVRAM Index with incorrect password is used to trigger an increase in DA counter.
// Check if the DA is not locked out before we increase the DA counter.
if err := hwseclocal.CheckDAIsZeroForTpm1(ctx, tpmManager); err != nil {
s.Fatal("Failed to check DA counter is zero: ", err)
}
if err := hwseclocal.IncreaseDAForTpm1(ctx, tpmManager); err != nil {
s.Fatal("Failed to increase dictionary attcack counter: ", err)
}
// Check if the DA counter is reset properly.
if err := hwseclocal.CheckDAIsZeroForTpm1(ctx, tpmManager); err != nil {
s.Fatal("Failed to check DA counter is zero: ", err)
}
logReader, err := syslog.NewReader(ctx)
if err != nil {
s.Fatal("Failed to create log reader: ", err)
}
// Restart TPM daemons to generate auth failure log
if err := daemonController.RestartTPMDaemons(ctx); err != nil {
s.Fatal("Failed to restart TPM daemons: ", err)
}
matchAuthFailureLog := func(entry *syslog.Entry) bool {
authFailureRegexp := regexp.MustCompile(`Found auth failure in the last life cycle. \(0x.*\)`)
return authFailureRegexp.Match([]byte(entry.Content))
}
matchAnomalyLog := func(entry *syslog.Entry) bool {
anomalyRegexp := regexp.MustCompile(`(anomaly_detector invoking crash_reporter with --auth_failure)|(Ignoring auth_failure 0x.*)`)
return anomalyRegexp.Match([]byte(entry.Content))
}
if _, err := logReader.Wait(ctx, 5*time.Second, matchAuthFailureLog); err != nil {
s.Fatalf("Failed to find auth_failure in %s: %v", syslog.MessageFile, err)
}
if _, err := logReader.Wait(ctx, 5*time.Second, matchAnomalyLog); err != nil {
s.Fatal("Failed to trigger anomaly detector: ", err)
}
}