From 4c87a1868835d05f1cadae7b8ad6a7c95d9d9c0e Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Tue, 14 Mar 2017 15:40:33 -0400 Subject: Initial commit of EFI TBOOT work from internal project. Signed-off-by: Ross Philipson --- tboot/errors.c | 285 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 tboot/errors.c (limited to 'tboot/errors.c') 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +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: + */ -- cgit v1.2.3