blob: 1735f24eca3467cfe5814fd1923018e8051ae801 [file]
// Copyright 2021 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include <string>
#include <trousers/trousers.h>
#include <base/strings/stringprintf.h>
#include "libhwsec/error/tpm1_error.h"
// trousers_types.h
#define TSS_ERROR_LAYER(x) (x & 0x3000)
#define TSS_ERROR_CODE(x) (x & TSS_MAX_ERROR)
namespace {
std::string FormatTrousersErrorCode(TSS_RESULT result) {
return base::StringPrintf("TPM error 0x%x (%s)", result,
Trspi_Error_String(result));
}
} // namespace
namespace hwsec {
TPM1Error::TPM1Error(TSS_RESULT error_code)
: TPMErrorBase(FormatTrousersErrorCode(error_code)),
error_code_(error_code) {}
TPMRetryAction TPM1Error::ToTPMRetryAction() const {
if (TSS_ERROR_CODE(error_code_) == TSS_SUCCESS) {
return TPMRetryAction::kNone;
}
switch (TSS_ERROR_LAYER(error_code_)) {
case TSS_LAYER_TPM:
switch (TSS_ERROR_CODE(error_code_)) {
// Invalid handle to the TPM.
case TPM_E_INVALID_AUTHHANDLE:
return TPMRetryAction::kLater;
// The TPM is defending itself against possible dictionary attacks.
case TPM_E_DEFEND_LOCK_RUNNING:
return TPMRetryAction::kDefend;
// TPM is out of memory, a reboot is needed.
case TPM_E_SIZE:
return TPMRetryAction::kReboot;
// The TPM returned TPM_E_FAIL. A reboot is required.
case TPM_E_FAIL:
return TPMRetryAction::kReboot;
// Retrying will not help.
default:
return TPMRetryAction::kNoRetry;
}
case TSS_LAYER_TCS:
switch (TSS_ERROR_CODE(error_code_)) {
// Communications failure with the TPM.
case TSS_E_COMM_FAILURE:
return TPMRetryAction::kCommunication;
// Key load failed; problem with parent key authorization.
case TCS_E_KM_LOADFAILED:
return TPMRetryAction::kLater;
// Retrying will not help.
default:
return TPMRetryAction::kNoRetry;
}
break;
case TSS_LAYER_TSP:
switch (TSS_ERROR_CODE(error_code_)) {
// Communications failure with the TPM.
case TSS_E_COMM_FAILURE:
return TPMRetryAction::kCommunication;
// Invalid handle to the TPM.
case TSS_E_INVALID_HANDLE:
return TPMRetryAction::kLater;
// Retrying will not help.
default:
return TPMRetryAction::kNoRetry;
}
break;
default:
switch (TSS_ERROR_CODE(error_code_)) {
// Communications failure with the TPM.
case TSS_E_COMM_FAILURE:
return TPMRetryAction::kCommunication;
// Retrying will not help.
default:
return TPMRetryAction::kNoRetry;
}
}
}
} // namespace hwsec