blob: efb43b86ae8cd1e4e3c5e85d5133760a8a48d370 [file] [log] [blame]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package firmware
import (
"context"
"fmt"
"time"
"go.chromium.org/tast-tests/cros/common/firmware/bios"
"go.chromium.org/tast-tests/cros/common/firmware/futility"
"go.chromium.org/tast-tests/cros/remote/firmware"
"go.chromium.org/tast-tests/cros/remote/firmware/fixture"
"go.chromium.org/tast/core/errors"
"go.chromium.org/tast/core/ssh"
"go.chromium.org/tast/core/testing"
"go.chromium.org/tast/core/testing/hwdep"
)
func init() {
testing.AddTest(&testing.Test{
Func: CorruptBothSignedAMDFWAB,
Desc: "Servo based both A and B signed AMDFW corruption test. This test corrupts both A and B SIGNED_AMDFW FMAP section, and restores it via servo",
Contacts: []string{"chromeos-faft@google.com", "kramasub@google.com"},
BugComponent: "b:792402", // ChromeOS > Platform > Enablement > Firmware > FAFT
Attr: []string{"group:firmware", "firmware_bios", "firmware_level3", "firmware_ro"},
Requirements: []string{"sys-fw-0021-v01", "sys-fw-0024-v01"},
HardwareDeps: hwdep.D(hwdep.ChromeEC(), hwdep.SkipOnModel(
// AMD devices before skyrim don't have the separate signed AMDFW section.
// grunt
"aleena", "barla", "careena", "kasumi", "kasumi360", "liara", "treeya", "treeya360",
// guybrush
"dewatt", "nipperkin",
// zork
"berknip", "dirinboz", "ezkinil", "gumboz", "jelboz360", "morphius", "vilboz", "vilboz14", "vilboz360", "woomax",
)),
Timeout: 50 * time.Minute,
Vars: []string{"firmware.skipFlashUSB"},
SoftwareDeps: []string{"crossystem", "flashrom", "amd_cpu"},
ServiceDeps: []string{"tast.cros.firmware.UtilsService"},
LacrosStatus: testing.LacrosVariantUnneeded,
Params: []testing.Param{
{
Name: "normal_mode",
Fixture: fixture.BootModeFixtureWithAPBackup(fixture.NormalMode),
Val: &corruptTestVal{
bios.SignedAMDFWAImageSection, bios.SignedAMDFWBImageSection,
},
},
{
Name: "dev_mode",
Fixture: fixture.BootModeFixtureWithAPBackup(fixture.DevMode),
Val: &corruptTestVal{
bios.SignedAMDFWAImageSection, bios.SignedAMDFWBImageSection,
},
},
},
})
}
func CorruptSignedAMDFWSection(ctx context.Context, s *testing.State, h *firmware.Helper, corruptBiosRemoteImage, backupBiosRemoteImage, remoteTempDir string) error {
s.Log("Corrupting SIGNED_AMDFW sections")
futilityInstance, err := futility.NewLocalBuilder(h.DUT).Build()
if err != nil {
s.Fatal("Failed to setup futility instance: ", err)
}
// - Get the body sizes
sections, out, err := futilityInstance.DumpFmap(ctx, backupBiosRemoteImage, []string{string(bios.SignedAMDFWAImageSection), string(bios.SignedAMDFWBImageSection)})
if err != nil {
s.Error("Failed getting section sizes: ", err, "\nOutput:\n", string(out))
return err
}
if len(sections) == 0 {
s.Error("Output doesn't match regex: ", string(out))
return errors.New("no sections matching SignedAMDFW")
}
// - Create corrupt bodies for A & B
for _, m := range sections {
out, err = h.DUT.Conn().CommandContext(ctx, "dd", fmt.Sprintf("of=%s/%s_corrupt.bin", remoteTempDir, m.Name), "if=/dev/random", fmt.Sprintf("bs=%d", m.Size), "count=1").Output(ssh.DumpLogOnError)
if err != nil {
s.Error("Failed creating corrupt file: ", err)
return err
}
}
// - Generate a new image that contains those bodies
out, err = futilityInstance.LoadFmap(ctx, backupBiosRemoteImage, corruptBiosRemoteImage, map[string]string{
string(bios.SignedAMDFWAImageSection): fmt.Sprintf("%s/%s_corrupt.bin", remoteTempDir, bios.SignedAMDFWAImageSection),
string(bios.SignedAMDFWBImageSection): fmt.Sprintf("%s/%s_corrupt.bin", remoteTempDir, bios.SignedAMDFWBImageSection),
})
if err != nil {
s.Error("Failed to load flashmap sections: ", err, "\nOutput:\n", string(out))
return err
}
return nil
}
func CorruptBothSignedAMDFWAB(ctx context.Context, s *testing.State) {
corruptFWSectionTest(ctx, s, CorruptSignedAMDFWSection, "RW firmware vendor blob verification failure")
}