blob: 42b69aaf7d06886bbeb46af861a200a7047922b7 [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.
#include <rmad/utils/cr50_utils_impl.h>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include <base/logging.h>
#include <base/strings/string_util.h>
#include "rmad/utils/cmd_utils_impl.h"
namespace rmad {
namespace {
constexpr char kGsctoolCmd[] = "gsctool";
constexpr char kFactoryModeMatchStr[] = "Capabilities are modified.";
const std::vector<std::string> kRsuArgv{kGsctoolCmd, "-a", "-r"};
const std::vector<std::string> kCcdInfoArgv{kGsctoolCmd, "-a", "-I"};
const std::vector<std::string> kEnableFactoryModeArgv{kGsctoolCmd, "-a", "-F",
"enable"};
const std::vector<std::string> kDisableFactoryModeArgv{kGsctoolCmd, "-a", "-F",
"disable"};
} // namespace
Cr50UtilsImpl::Cr50UtilsImpl() : Cr50Utils() {
cmd_utils_ = std::make_unique<CmdUtilsImpl>();
}
Cr50UtilsImpl::Cr50UtilsImpl(std::unique_ptr<CmdUtils> cmd_utils)
: Cr50Utils(), cmd_utils_(std::move(cmd_utils)) {}
bool Cr50UtilsImpl::GetRsuChallengeCode(std::string* challenge_code) const {
// TODO(chenghan): Check with cr50 team if we can expose a tpm_managerd API
// for this, so we don't need to depend on `gsctool` output
// format to do extra string parsing.
if (cmd_utils_->GetOutput(kRsuArgv, challenge_code)) {
base::RemoveChars(*challenge_code, base::kWhitespaceASCII, challenge_code);
base::ReplaceFirstSubstringAfterOffset(challenge_code, 0, "Challenge:", "");
LOG(INFO) << "Challenge code: " << *challenge_code;
return true;
}
return false;
}
bool Cr50UtilsImpl::PerformRsu(const std::string& unlock_code) const {
std::vector<std::string> argv(kRsuArgv);
argv.push_back(unlock_code);
std::string output;
if (cmd_utils_->GetOutput(argv, &output)) {
LOG(INFO) << "RSU succeeded.";
return true;
}
LOG(INFO) << "RSU failed.";
LOG(ERROR) << output;
return false;
}
bool Cr50UtilsImpl::EnableFactoryMode() const {
if (!IsFactoryModeEnabled()) {
std::string unused_output;
return cmd_utils_->GetOutput(kEnableFactoryModeArgv, &unused_output);
}
return true;
}
bool Cr50UtilsImpl::DisableFactoryMode() const {
if (IsFactoryModeEnabled()) {
std::string unused_output;
return cmd_utils_->GetOutput(kDisableFactoryModeArgv, &unused_output);
}
return true;
}
bool Cr50UtilsImpl::IsFactoryModeEnabled() const {
std::string output;
cmd_utils_->GetOutput(kCcdInfoArgv, &output);
return output.find(kFactoryModeMatchStr) != std::string::npos;
}
} // namespace rmad