blob: 61c7f2ab8f5f6d20d4520a1c762cfdabaa72a7fc [file] [log] [blame]
// Copyright 2022 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 <optional>
#include <set>
#include <string>
#include <utility>
#include <cryptohome/proto_bindings/UserDataAuth.pb.h>
#include <gtest/gtest.h>
#include <libhwsec/error/tpm_error.h>
#include <libhwsec/error/tpm_retry_handler.h>
#include <libhwsec-foundation/status/status_chain.h>
#include "cryptohome/error/action.h"
#include "cryptohome/error/cryptohome_tpm_error.h"
namespace cryptohome {
namespace error {
class CryptohomeTPMErrorTest : public ::testing::Test {
protected:
const CryptohomeError::ErrorLocationPair kErrorLocationForTesting1 =
CryptohomeError::ErrorLocationPair(
static_cast<::cryptohome::error::CryptohomeError::ErrorLocation>(1),
std::string("Testing1"));
};
namespace {
using hwsec::TPMError;
using hwsec::TPMErrorBase;
using hwsec::TPMRetryAction;
using hwsec_foundation::status::MakeStatus;
using hwsec_foundation::status::StatusChain;
TEST_F(CryptohomeTPMErrorTest, BasicConstruction) {
auto err1 = MakeStatus<CryptohomeTPMError>(
kErrorLocationForTesting1,
ErrorActionSet({ErrorAction::kResumePreviousMigration}),
hwsec::TPMRetryAction::kNoRetry);
ASSERT_FALSE(err1.ok());
EXPECT_EQ(err1->local_location(), kErrorLocationForTesting1.location());
EXPECT_EQ(err1->local_actions(),
ErrorActionSet({ErrorAction::kResumePreviousMigration,
ErrorAction::kDevCheckUnexpectedState}));
EXPECT_EQ(err1->ToTPMRetryAction(), hwsec::TPMRetryAction::kNoRetry);
}
TEST_F(CryptohomeTPMErrorTest, Success) {
StatusChain<CryptohomeTPMError> err;
EXPECT_TRUE(err.ok());
}
TEST_F(CryptohomeTPMErrorTest, FromTPMError) {
StatusChain<TPMErrorBase> tpm_err =
MakeStatus<TPMError>("QAQ", hwsec::TPMRetryAction::kReboot);
auto err1 = MakeStatus<CryptohomeTPMError>(std::move(tpm_err));
ASSERT_FALSE(err1.ok());
// 0x0132 is precalculated test vector for "QAQ".
EXPECT_EQ(
err1->local_location(),
(0x0132 + hwsec::unified_tpm_error::kUnifiedErrorHashedTpmErrorBase) |
hwsec::unified_tpm_error::kUnifiedErrorBit);
EXPECT_EQ(err1->local_actions(), ErrorActionSet({ErrorAction::kReboot}));
EXPECT_EQ(err1->ToTPMRetryAction(), hwsec::TPMRetryAction::kReboot);
}
TEST_F(CryptohomeTPMErrorTest, FromTPMErrorStacked) {
StatusChain<TPMErrorBase> status1 =
MakeStatus<TPMError>("QAQ", hwsec::TPMRetryAction::kReboot);
StatusChain<TPMErrorBase> status2 =
MakeStatus<TPMError>("QwQ", hwsec::TPMRetryAction::kLater)
.Wrap(std::move(status1));
auto err1 = MakeStatus<CryptohomeTPMError>(std::move(status2));
ASSERT_FALSE(err1.ok());
// The location should still be the one for "QAQ", because it's the last in
// the chain.
EXPECT_EQ(
err1->local_location(),
(0x0132 + hwsec::unified_tpm_error::kUnifiedErrorHashedTpmErrorBase) |
hwsec::unified_tpm_error::kUnifiedErrorBit);
// Retry actions should be from the last in the chain.
EXPECT_EQ(err1->local_actions(), ErrorActionSet({ErrorAction::kReboot}));
EXPECT_EQ(err1->ToTPMRetryAction(), hwsec::TPMRetryAction::kReboot);
}
} // namespace
} // namespace error
} // namespace cryptohome