summaryrefslogtreecommitdiffstats
path: root/tboot/errors.c
diff options
context:
space:
mode:
Diffstat (limited to 'tboot/errors.c')
-rw-r--r--tboot/errors.c285
1 files changed, 285 insertions, 0 deletions
diff --git a/tboot/errors.c b/tboot/errors.c
new file mode 100644
index 0000000..5d22b40
--- /dev/null
+++ b/tboot/errors.c
@@ -0,0 +1,285 @@
+/*
+ * errors.c: parse and return status of Intel(r) TXT error codes
+ *
+ * Copyright (c) 2003-2011, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+#include <efibase.h>
+#include <stdbool.h>
+#include <types.h>
+#include <string.h>
+#include <printk.h>
+#include <atomic.h>
+#include <uuid.h>
+#include <tb_error.h>
+#include <txt/txt.h>
+#include <txt/config_regs.h>
+#include <txt/errorcode.h>
+
+
+static void display_errors(void)
+{
+ txt_errorcode_t err;
+ txt_ests_t ests;
+ txt_e2sts_t e2sts;
+ txt_errorcode_sw_t sw_err;
+ acmod_error_t acmod_err;
+
+ /*
+ * display TXT.ERRORODE error
+ */
+ err = (txt_errorcode_t)read_pub_config_reg(TXTCR_ERRORCODE);
+ if (err._raw == 0 || err._raw == 0xc0000001 || err._raw == 0xc0000009)
+ printk(TBOOT_INFO"TXT.ERRORCODE: 0x%Lx\n", err._raw);
+ else
+ printk(TBOOT_ERR"TXT.ERRORCODE: 0x%Lx\n", err._raw);
+
+ /* AC module error (don't know how to parse other errors) */
+ if ( err.valid ) {
+ if ( err.external == 0 ) /* processor error */
+ printk(TBOOT_ERR"\t processor error 0x%x\n", (uint32_t)err.type);
+ else { /* external SW error */
+ sw_err._raw = err.type;
+ if ( sw_err.src == 1 ) /* unknown SW error */
+ printk(TBOOT_ERR"unknown SW error 0x%x:0x%x\n", sw_err.err1, sw_err.err2);
+ else { /* ACM error */
+ acmod_err._raw = sw_err._raw;
+ if ( acmod_err._raw == 0x0 || acmod_err._raw == 0x1 ||
+ acmod_err._raw == 0x9 )
+ printk(TBOOT_INFO"AC module error : acm_type=0x%x, progress=0x%02x, "
+ "error=0x%x\n", acmod_err.acm_type, acmod_err.progress,
+ acmod_err.error);
+ else
+ printk(TBOOT_ERR"AC module error : acm_type=0x%x, progress=0x%02x, "
+ "error=0x%x\n", acmod_err.acm_type, acmod_err.progress,
+ acmod_err.error);
+ /* error = 0x0a, progress = 0x0d => TPM error */
+ if ( acmod_err.error == 0x0a && acmod_err.progress == 0x0d )
+ printk(TBOOT_ERR"TPM error code = 0x%x\n", acmod_err.tpm_err);
+ /* progress = 0x10 => LCP2 error */
+ else if ( acmod_err.progress == 0x10 && acmod_err.lcp_minor != 0 )
+ printk(TBOOT_ERR"LCP2 error: minor error = 0x%x, index = %u\n",
+ acmod_err.lcp_minor, acmod_err.lcp_index);
+ }
+ }
+ }
+
+ /*
+ * display TXT.ESTS error
+ */
+ ests = (txt_ests_t)read_pub_config_reg(TXTCR_ESTS);
+ if (ests._raw == 0)
+ printk(TBOOT_INFO"TXT.ESTS: 0x%Lx\n", ests._raw);
+ else
+ printk(TBOOT_ERR"TXT.ESTS: 0x%Lx\n", ests._raw);
+
+ /*
+ * display TXT.E2STS error
+ */
+ e2sts = (txt_e2sts_t)read_pub_config_reg(TXTCR_E2STS);
+ if (e2sts._raw == 0 || e2sts._raw == 0x200000000)
+ printk(TBOOT_INFO"TXT.E2STS: 0x%Lx\n", e2sts._raw);
+ else
+ printk(TBOOT_ERR"TXT.E2STS: 0x%Lx\n", e2sts._raw);
+}
+
+bool txt_get_error(void)
+{
+ txt_errorcode_t err;
+
+ display_errors();
+
+ err = (txt_errorcode_t)read_pub_config_reg(TXTCR_ERRORCODE);
+ if ( err.valid )
+ return false;
+ else
+ return true;
+}
+
+#define CLASS_ACM_ENTRY 0x1
+enum ENUM_ACM_ENTRY {
+ ERR_LAUNCH = 1,
+ ERR_NEM_ENABLED,
+ ERR_CPU_LT_TYPE,
+ ERR_DEV_ID,
+ ERR_CPU_ID,
+ ERR_NO_UCODE_UPDATE ,
+ ERR_DEBUG_MCU,
+ ERR_DMI_LINK_DOWN,
+ ERR_ACM_REVOKED,
+ ERR_TPM_DOUBLE_AUX
+};
+#define CLASS_TPM_ACCESS 0x4
+enum ENUM_TPM_ACCESS {
+ ERR_OK, /* Indicator of successful execution of the function.*/
+ ERR_TPM_ERROR, /* TPM returned an error */
+ ERR_LOCALITY,
+ ERR_ACC_INVLD,
+ ERR_NV_UNLOCKED, /* TPM NV RAM not locked */
+ ERR_TPM_DISABLED, /* TPM is disabled */
+ ERR_TPM_DEACTIVATED, /* TPM is deactivated */
+ ERR_TPM_NV_INDEX_INVALID, /* TPM NV indices incorrectly defined */
+ ERR_TPM_INCOMPET_BIOSAC, /* Incompatible BIOS ACM */
+ ERR_TPM_INCOMPET_AUXREV, /* Incompatible AUX revision */
+ ERR_TPM_INBUF_TOO_SHORT, /* Input buffer is too short */
+ ERR_TPM_OUTBUF_TOO_SHORT, /* Output buffer is too short */
+ ERR_TPM_NV_PO_INDEX_INVALID = 0x10,
+
+ /*
+ * Errors returned by TPM driver
+ */
+ ERR_OUTPUT_BUFFER_TOO_SHORT = 0x1B, /* Output buffer for the TPM response to short */
+ ERR_INVALID_INPUT_PARA = 0x1C, /* Input parameter for the function invalid */
+ ERR_INVALID_RESPONSE_WR = 0x1D, /* The response from the TPM was invalid */
+ ERR_INVALID_RESPONSE_RD = 0x1E, /* The response from the TPM was invalid */
+ ERR_RESPONSE_TIMEOUT = 0x1F /* Time out for TPM response */
+};
+#define CLASS_MISC_CONFIG 0x8
+enum ENUM_MISC_CONFIG {
+ ERR_INTERRUPT = 1,
+ ERR_FORBIDDEN_BY_OWNER = 0x10,
+ ERR_TOOL_LAUNCH,
+ ERR_CANNOT_REVERSE,
+ ERR_ALREADY_REVOKED,
+ ERR_INVALID_RETURN_ADDR,
+ ERR_NO_TPM,
+};
+
+void txt_get_racm_error(void)
+{
+ txt_errorcode_t err;
+ acmod_error_t acmod_err;
+
+ /*
+ * display TXT.ERRORODE error
+ */
+ err = (txt_errorcode_t)read_pub_config_reg(TXTCR_ERRORCODE);
+
+ /* AC module error (don't know how to parse other errors) */
+ if ( err.valid == 0 ) {
+ printk(TBOOT_ERR
+ "Cannot retrieve status - ERRORSTS register is not valid.\n");
+ return;
+ }
+
+ if ( err.external == 0 ) { /* processor error */
+ printk(TBOOT_ERR"CPU generated error 0x%x\n", (uint32_t)err.type);
+ return;
+ }
+
+ acmod_err._raw = err.type;
+ if ( acmod_err.src == 1 ) {
+ printk(TBOOT_ERR"Unknown SW error.\n");
+ return;
+ }
+
+ if ( acmod_err.acm_type != 0x9 ) {
+ printk(TBOOT_ERR
+ "Cannot retrieve status - wrong ACM type in ERRORSTS register.\n");
+ return;
+ }
+
+ if ( acmod_err.progress == CLASS_ACM_ENTRY &&
+ acmod_err.error == ERR_TPM_DOUBLE_AUX ) {
+ printk(TBOOT_ERR
+ "Nothing to do: double AUX index is not valid TXT configuration.\n");
+ return;
+ }
+
+ if ( acmod_err.progress == CLASS_TPM_ACCESS &&
+ acmod_err.error == ERR_TPM_NV_INDEX_INVALID ) {
+ printk(TBOOT_ERR
+ "Nothing to do: invalid AUX index attributes.\n");
+ return;
+ }
+
+ if ( acmod_err.progress == CLASS_TPM_ACCESS &&
+ acmod_err.error == ERR_TPM_NV_PO_INDEX_INVALID ) {
+ printk(TBOOT_ERR
+ "Error: invalid PO index attributes.\n");
+ return;
+ }
+
+ if ( acmod_err.progress == CLASS_MISC_CONFIG &&
+ acmod_err.error == ERR_ALREADY_REVOKED ) {
+ printk(TBOOT_ERR
+ "Nothing to do: already revoked.\n");
+ return;
+ }
+
+ if ( acmod_err.progress == CLASS_MISC_CONFIG &&
+ acmod_err.error == ERR_FORBIDDEN_BY_OWNER ) {
+ printk(TBOOT_ERR
+ "Error: revocation forbidden by owner.\n");
+ return;
+ }
+
+ if ( acmod_err.progress == CLASS_MISC_CONFIG &&
+ acmod_err.error == ERR_CANNOT_REVERSE ) {
+ printk(TBOOT_ERR
+ "Error: cannot decrement revocation version.\n");
+ return;
+ }
+
+ if ( acmod_err.progress == CLASS_MISC_CONFIG &&
+ acmod_err.error == ERR_INVALID_RETURN_ADDR ) {
+ printk(TBOOT_ERR
+ "Error: invalid input address of return point.\n");
+ return;
+ }
+
+ if ( acmod_err.progress == CLASS_MISC_CONFIG &&
+ acmod_err.error == ERR_NO_TPM ) {
+ printk(TBOOT_ERR
+ "Nothing to do: No TPM present.\n");
+ return;
+ }
+
+ if ( acmod_err.progress == 0 && acmod_err.error == 0 ) {
+ printk(TBOOT_INFO
+ "Success: Revocation completed.\n");
+ return;
+ }
+
+ printk(TBOOT_ERR"RACM generated error 0x%Lx.\n", err._raw);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */