diff options
Diffstat (limited to 'TPM2-Plugin/lib/tpm2_error.c')
-rw-r--r-- | TPM2-Plugin/lib/tpm2_error.c | 871 |
1 files changed, 0 insertions, 871 deletions
diff --git a/TPM2-Plugin/lib/tpm2_error.c b/TPM2-Plugin/lib/tpm2_error.c deleted file mode 100644 index 32eeb41..0000000 --- a/TPM2-Plugin/lib/tpm2_error.c +++ /dev/null @@ -1,871 +0,0 @@ -//**********************************************************************; -// Copyright (c) 2018, 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: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. 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. -// -// 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 HOLDER 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 <stdarg.h> -#include <stdbool.h> -#include <stdio.h> -#include <string.h> - -#include <tss2/tss2_sys.h> - -#include "tpm2_error.h" -#include "tpm2_util.h" - -/** - * The maximum size of a layer name. - */ -#define TSS2_ERR_LAYER_NAME_MAX 4 - -/** - * The maximum size for layer specific error strings. - */ -#define TSS2_ERR_LAYER_ERROR_STR_MAX 512 - -/** - * Concatenates (safely) onto a static buffer given a format and varaidic - * arguments similar to sprintf. - * @param b - * The static buffer to concatenate onto. - * @param fmt - * The format specifier as understood by printf followed by the variadic - * parameters for the specifier. - */ -#define catbuf(b, fmt, ...) _catbuf(b, sizeof(b), fmt, ##__VA_ARGS__) - -/** - * Clears out a static buffer by setting index 0 to the null byte. - * @param buffer - * The buffer to clear out. - */ -static void clearbuf(char *buffer) { - buffer[0] = '\0'; -} - -/** - * Prints to a buffer using snprintf(3) using the supplied fmt - * and varaiadic arguments. - * @param buf - * The buffer to print into. - * @param len - * The length of that buffer. - * @param fmt - * The format string - * @warning - * DO NOT CALL DIRECTLY, use the catbuf() macro. - */ -static void COMPILER_ATTR(format (printf, 3, 4)) -_catbuf(char *buf, size_t len, const char *fmt, ...) { - va_list argptr; - va_start(argptr, fmt); - size_t offset = strlen(buf); - vsnprintf(&buf[offset], len - offset, fmt, argptr); - va_end(argptr); -} - -/** - * Retrieves the layer number. The layer number is in the 3rd - * octet and is thus 1 byte big. - * - * @param rc - * The rc to query for the layer number. - * @return - * The layer number. - */ -static inline UINT8 tss2_rc_layer_number_get(TSS2_RC rc) { - return ((rc & TSS2_RC_LAYER_MASK) >> TSS2_RC_LAYER_SHIFT); -} - -/** - * Queries a TPM format 1 error codes N field. The N field - * is a 4 bit field located at bits 8:12. - * @param rc - * The rc to query the N field for. - * @return - * The N field value. - */ -static inline UINT8 tpm2_rc_fmt1_N_get(TPM2_RC rc) { - return ((rc & (0xF << 8)) >> 8); -} - -/** - * Queries the index bits out of the N field contained in a TPM format 1 - * error code. The index bits are the low 3 bits of the N field. - * @param rc - * The TPM format 1 error code to query for the index bits. - * @return - * The index bits from the N field. - */ -static inline UINT8 tpm2_rc_fmt1_N_index_get(TPM2_RC rc) { - return (tpm2_rc_fmt1_N_get(rc) & 0x7); -} - -/** - * Determines if the N field in a TPM format 1 error code is - * a handle or not. - * @param rc - * The TPM format 1 error code to query. - * @return - * True if it is a handle, false otherwise. - */ -static inline bool tpm2_rc_fmt1_N_is_handle(TPM2_RC rc) { - return ((tpm2_rc_fmt1_N_get(rc) & 0x8) == 0); -} - -static inline UINT8 tpm2_rc_fmt1_P_get(TPM2_RC rc) { - return ((rc & (1 << 6)) >> 6); -} - -static inline UINT16 tpm2_rc_fmt1_error_get(TPM2_RC rc) { - return (rc & 0x3F); -} - -static inline UINT16 tpm2_rc_fmt0_error_get(TPM2_RC rc) { - return (rc & 0x7F); -} - -static inline UINT8 tpm2_rc_tpm_fmt0_V_get(TPM2_RC rc) { - return ((rc & (1 << 8)) >> 8); -} - -static inline UINT8 tpm2_rc_fmt0_T_get(TPM2_RC rc) { - return ((rc & (1 << 10)) >> 8); -} - -static inline UINT8 tpm2_rc_fmt0_S_get(TSS2_RC rc) { - return ((rc & (1 << 11)) >> 8); -} - -/** - * Helper macro for adding a layer handler to the layer - * registration array. - */ -#define ADD_HANDLER(name, handler) \ - { name, handler } - -/** - * Same as ADD_HANDLER but sets it to NULL. Used as a placeholder - * for non-registered indexes into the handler array. - */ -#define ADD_NULL_HANDLER ADD_HANDLER(NULL, NULL) - -static const char *tpm2_err_handler_fmt1(TPM2_RC rc) { - - /* - * format 1 error codes start at 1, so - * add a NULL entry to index 0. - */ - static const char *fmt1_err_strs[] = { - // 0x0 - EMPTY - NULL, - // 0x1 - TPM2_RC_ASYMMETRIC - "asymmetric algorithm not supported or not correct", - // 0x2 - TPM2_RC_ATTRIBUTES - "inconsistent attributes", - // 0x3 - TPM2_RC_HASH - "hash algorithm not supported or not appropriate", - // 0x4 - TPM2_RC_VALUE - "value is out of range or is not correct for the context", - // 0x5 - TPM2_RC_HIERARCHY - "hierarchy is not enabled or is not correct for the use", - // 0x6 - EMPTY - NULL, - // 0x7 - TPM2_RC_KEY_SIZE - "key size is not supported", - // 0x8 - TPM2_RC_MGF - "mask generation function not supported", - // 0x9 - TPM2_RC_MODE - "mode of operation not supported", - // 0xA - TPM2_RC_TYPE - "the type of the value is not appropriate for the use", - // 0xB - TPM2_RC_HANDLE - "the handle is not correct for the use", - // 0xC - TPM2_RC_KDF - "unsupported key derivation function or function not appropriate for " - "use", - // 0xD - TPM2_RC_RANGE - "value was out of allowed range", - // 0xE - TPM2_RC_AUTH_FAIL - "the authorization HMAC check failed and DA counter incremented", - // 0xF - TPM2_RC_NONCE - "invalid nonce size or nonce value mismatch", - // 0x10 - TPM2_RC_PP - "authorization requires assertion of PP", - // 0x11 - EMPTY - NULL, - // 0x12 - TPM2_RC_SCHEME - "unsupported or incompatible scheme", - // 0x13 - EMPTY - NULL, - // 0x14 - EMPTY - NULL, - // 0x15 - TPM2_RC_SIZE - "structure is the wrong size", - // 0x16 - TPM2_RC_SYMMETRIC - "unsupported symmetric algorithm or key size, or not appropriate for" - " instance", - // 0x17 - TPM2_RC_TAG - "incorrect structure tag", - // 0x18 - TPM2_RC_SELECTOR - "union selector is incorrect", - // 0x19 - EMPTY - NULL, - // 0x1A - TPM2_RC_INSUFFICIENT - "the TPM was unable to unmarshal a value because there were not enough" - " octets in the input buffer", - // 0x1B - TPM2_RC_SIGNATURE - "the signature is not valid", - // 0x1C - TPM2_RC_KEY - "key fields are not compatible with the selected use", - // 0x1D - TPM2_RC_POLICY_FAIL - "a policy check failed", - // 0x1E - EMPTY - NULL, - // 0x1F - TPM2_RC_INTEGRITY - "integrity check failed", - // 0x20 - TPM2_RC_TICKET - "invalid ticket", - // 0x21 - TPM2_RC_RESERVED_BITS - "reserved bits not set to zero as required", - // 0x22 - TPM2_RC_BAD_AUTH - "authorization failure without DA implications", - // 0x23 - TPM2_RC_EXPIRED - "the policy has expired", - // 0x24 - TPM2_RC_POLICY_CC - "the commandCode in the policy is not the commandCode of the command" - " or the command code in a policy command references a command that" - " is not implemented", - // 0x25 - TPM2_RC_BINDING - "public and sensitive portions of an object are not cryptographically bound", - // 0x26 - TPM2_RC_CURVE - "curve not supported", - // 0x27 - TPM2_RC_ECC_POINT - "point is not on the required curve", - }; - - static char buf[TSS2_ERR_LAYER_ERROR_STR_MAX + 1]; - - clearbuf(buf); - - /* Print whether or not the error is caused by a bad - * handle or parameter. On the case of a Handle (P == 0) - * then the N field top bit will be set. Un-set this bit - * to get the handle index by subtracting 8 as N is a 4 - * bit field. - * - * the lower 3 bits of N indicate index, and the high bit - * indicates - */ - UINT8 index = tpm2_rc_fmt1_N_index_get(rc); - - bool is_handle = tpm2_rc_fmt1_N_is_handle(rc); - const char *m = tpm2_rc_fmt1_P_get(rc) ? "parameter" : - is_handle ? "handle" : "session"; - catbuf(buf, "%s", m); - - if (index) { - catbuf(buf, "(%u):", index); - } else { - catbuf(buf, "%s", "(unk):"); - } - - UINT8 errnum = tpm2_rc_fmt1_error_get(rc); - if (errnum < ARRAY_LEN(fmt1_err_strs)) { - m = fmt1_err_strs[errnum]; - catbuf(buf, "%s", m); - } else { - catbuf(buf, "unknown error num: 0x%X", errnum); - } - - return buf; -} - -static const char *tpm2_err_handler_fmt0(TSS2_RC rc) { - - /* - * format 0 error codes start at 1, so - * add a NULL entry to index 0. - * Thus, no need to offset the error bits - * and fmt0 and fmt1 arrays can be used - * in-place of each other for lookups. - */ - static const char *fmt0_warn_strs[] = { - // 0x0 - EMPTY - NULL, - // 0x1 - TPM2_RC_CONTEXT_GAP - "gap for context ID is too large", - // 0x2 - TPM2_RC_OBJECT_MEMORY - "out of memory for object contexts", - // 0x3 - TPM2_RC_SESSION_MEMORY - "out of memory for session contexts", - // 0x4 - TPM2_RC_MEMORY - "out of shared object/session memory or need space for internal" - " operations", - // 0x5 - TPM2_RC_SESSION_HANDLES - "out of session handles", - // 0x6 - TPM2_RC_OBJECT_HANDLES - "out of object handles", - // 0x7 - TPM2_RC_LOCALITY - "bad locality", - // 0x8 - TPM2_RC_YIELDED - "the TPM has suspended operation on the command; forward progress" - " was made and the command may be retried", - // 0x9 - TPM2_RC_CANCELED - "the command was canceled", - // 0xA - TPM2_RC_TESTING - "TPM is performing self-tests", - // 0xB - EMPTY - NULL, - // 0xC - EMPTY - NULL, - // 0xD - EMPTY - NULL, - // 0xE - EMPTY - NULL, - // 0xF - EMPTY - NULL, - // 0x10 - TPM2_RC_REFERENCE_H0 - "the 1st handle in the handle area references a transient object" - " or session that is not loaded", - // 0x11 - TPM2_RC_REFERENCE_H1 - "the 2nd handle in the handle area references a transient object" - " or session that is not loaded", - // 0x12 - TPM2_RC_REFERENCE_H2 - "the 3rd handle in the handle area references a transient object" - " or session that is not loaded", - // 0x13 - TPM2_RC_REFERENCE_H3 - "the 4th handle in the handle area references a transient object" - " or session that is not loaded", - // 0x14 - TPM2_RC_REFERENCE_H4 - "the 5th handle in the handle area references a transient object" - " or session that is not loaded", - // 0x15 - TPM2_RC_REFERENCE_H5 - "the 6th handle in the handle area references a transient object" - " or session that is not loaded", - // 0x16 - TPM2_RC_REFERENCE_H6 - "the 7th handle in the handle area references a transient object" - " or session that is not loaded", - // 0x17 - EMPTY, - // 0x18 - TPM2_RC_REFERENCE_S0 - "the 1st authorization session handle references a session that" - " is not loaded", - // 0x19 - TPM2_RC_REFERENCE_S1 - "the 2nd authorization session handle references a session that" - " is not loaded", - // 0x1A - TPM2_RC_REFERENCE_S2 - "the 3rd authorization session handle references a session that" - " is not loaded", - // 0x1B - TPM2_RC_REFERENCE_S3 - "the 4th authorization session handle references a session that" - " is not loaded", - // 0x1C - TPM2_RC_REFERENCE_S4 - "the 5th authorization session handle references a session that" - " is not loaded", - // 0x1D - TPM2_RC_REFERENCE_S5 - "the 6th authorization session handle references a session that" - " is not loaded", - // 0x1E - TPM2_RC_REFERENCE_S6 - "the 7th authorization session handle references a session that" - " is not loaded", - // 0x20 -TPM2_RC_NV_RATE - "the TPM is rate-limiting accesses to prevent wearout of NV", - // 0x21 - TPM2_RC_LOCKOUT - "authorizations for objects subject to DA protection are not" - " allowed at this time because the TPM is in DA lockout mode", - // 0x22 - TPM2_RC_RETRY - "the TPM was not able to start the command", - // 0x23 - TPM2_RC_NV_UNAVAILABLE - "the command may require writing of NV and NV is not current" - " accessible", - }; - - /* - * format 1 error codes start at 0, so - * no need to offset the error bits. - */ - static const char *fmt0_err_strs[] = { - // 0x0 - TPM2_RC_INITIALIZE - "TPM not initialized by TPM2_Startup or already initialized", - // 0x1 - TPM2_RC_FAILURE - "commands not being accepted because of a TPM failure", - // 0x2 - EMPTY - NULL, - // 0x3 - TPM2_RC_SEQUENCE - "improper use of a sequence handle", - // 0x4 - EMPTY - NULL, - // 0x5 - EMPTY - NULL, - // 0x6 - EMPTY - NULL, - // 0x7 - EMPTY - NULL, - // 0x8 - EMPTY - NULL, - // 0x9 - EMPTY - NULL, - // 0xA - EMPTY - NULL, - // 0xB - TPM2_RC_PRIVATE - "not currently used", - // 0xC - EMPTY - NULL, - // 0xD - EMPTY - NULL, - // 0xE - EMPTY - NULL, - // 0xF - EMPTY - NULL, - // 0x10 - EMPTY - NULL, - // 0x11 - EMPTY - NULL, - // 0x12 - EMPTY - NULL, - // 0x13 - EMPTY - NULL, - // 0x14 - EMPTY - NULL, - // 0x15 - EMPTY - NULL, - // 0x16 - EMPTY - NULL, - // 0x17 - EMPTY - NULL, - // 0x18 - EMPTY - NULL, - // 0x19 - TPM2_RC_HMAC - "not currently used", - // 0x1A - EMPTY - NULL, - // 0x1B - EMPTY - NULL, - // 0x1C - EMPTY - NULL, - // 0x1D - EMPTY - NULL, - // 0x1E - EMPTY - NULL, - // 0x1F - EMPTY - NULL, - // 0x20 - TPM2_RC_DISABLED - "the command is disabled", - // 0x21 - TPM2_RC_EXCLUSIVE - "command failed because audit sequence required exclusivity", - // 0x22 - EMPTY - NULL, - // 0x23 - EMPTY, - NULL, - // 0x24 - TPM2_RC_AUTH_TYPE - "authorization handle is not correct for command", - // 0x25 - TPM2_RC_AUTH_MISSING - "command requires an authorization session for handle and it is" - " not present", - // 0x26 - TPM2_RC_POLICY - "policy failure in math operation or an invalid authPolicy value", - // 0x27 - TPM2_RC_PCR - "PCR check fail", - // 0x28 - TPM2_RC_PCR_CHANGED - "PCR have changed since checked", - // 0x29 - EMPTY - NULL, - // 0x2A - EMPTY - NULL, - // 0x2B - EMPTY - NULL, - // 0x2C - EMPTY - NULL, - // 0x2D - TPM2_RC_UPGRADE - "TPM is in field upgrade mode unless called via" - " TPM2_FieldUpgradeData(), then it is not in field upgrade mode", - // 0x2E - TPM2_RC_TOO_MANY_CONTEXTS - "context ID counter is at maximum", - // 0x2F - TPM2_RC_AUTH_UNAVAILABLE - "authValue or authPolicy is not available for selected entity", - // 0x30 - TPM2_RC_REBOOT - "a _TPM_Init and Startup(CLEAR) is required before the TPM can" - " resume operation", - // 0x31 - TPM2_RC_UNBALANCED - "the protection algorithms (hash and symmetric) are not reasonably" - " balanced. The digest size of the hash must be larger than the key" - " size of the symmetric algorithm.", - // 0x32 - EMPTY - NULL, - // 0x33 - EMPTY - NULL, - // 0x34 - EMPTY - NULL, - // 0x35 - EMPTY - NULL, - // 0x36 - EMPTY - NULL, - // 0x37 - EMPTY - NULL, - // 0x38 - EMPTY - NULL, - // 0x39 - EMPTY - NULL, - // 0x3A - EMPTY - NULL, - // 0x3B - EMPTY - NULL, - // 0x3C - EMPTY - NULL, - // 0x3D - EMPTY - NULL, - // 0x3E - EMPTY - NULL, - // 0x3F - EMPTY - NULL, - // 0x40 - EMPTY - NULL, - // 0x41 - EMPTY - NULL, - // 0x42 - TPM2_RC_COMMAND_SIZE - "command commandSize value is inconsistent with contents of the" - " command buffer; either the size is not the same as the octets" - " loaded by the hardware interface layer or the value is not large" - " enough to hold a command header", - // 0x43 - TPM2_RC_COMMAND_CODE - "command code not supported", - // 0x44 - TPM2_RC_AUTHSIZE - "the value of authorizationSize is out of range or the number of" - " octets in the Authorization Area is greater than required", - // 0x45 - TPM2_RC_AUTH_CONTEXT - "use of an authorization session with a context command or another" - " command that cannot have an authorization session", - // 0x46 - TPM2_RC_NV_RANGE - "NV offset+size is out of range", - // 0x47 - TPM2_RC_NV_SIZE - "Requested allocation size is larger than allowed", - // 0x48 - TPM2_RC_NV_LOCKED - "NV access locked", - // 0x49 - TPM2_RC_NV_AUTHORIZATION - "NV access authorization fails in command actions", - // 0x4A - TPM2_RC_NV_UNINITIALIZED - "an NV Index is used before being initialized or the state saved" - " by TPM2_Shutdown(STATE) could not be restored", - // 0x4B - TPM2_RC_NV_SPACE - "insufficient space for NV allocation", - // 0x4C - TPM2_RC_NV_DEFINED - "NV Index or persistent object already defined", - // 0x4D - EMPTY - NULL, - // 0x4E - EMPTY - NULL, - // 0x4F - EMPTY - NULL, - // 0x50 - TPM2_RC_BAD_CONTEXT - "context in TPM2_ContextLoad() is not valid", - // 0x51 - TPM2_RC_CPHASH - "cpHash value already set or not correct for use", - // 0x52 - TPM2_RC_PARENT - "handle for parent is not a valid parent", - // 0x53 - TPM2_RC_NEEDS_TEST - "some function needs testing", - // 0x54 - TPM2_RC_NO_RESULT - "returned when an internal function cannot process a request due to" - " an unspecified problem. This code is usually related to invalid" - " parameters that are not properly filtered by the input" - " unmarshaling code", - // 0x55 - TPM2_RC_SENSITIVE - "the sensitive area did not unmarshal correctly after decryption", - }; - - static char buf[TSS2_ERR_LAYER_ERROR_STR_MAX + 1]; - - clearbuf(buf); - - char *e = tpm2_rc_fmt0_S_get(rc) ? "warn" : "error"; - char *v = tpm2_rc_tpm_fmt0_V_get(rc) ? "2.0" : "1.2"; - catbuf(buf, "%s(%s): ", e, v); - - UINT8 errnum = tpm2_rc_fmt0_error_get(rc); - /* We only have version 2.0 spec codes defined */ - if (tpm2_rc_tpm_fmt0_V_get(rc)) { - /* TCG specific error code */ - if (tpm2_rc_fmt0_T_get(rc)) { - catbuf(buf, "Vendor specific error: 0x%X", errnum); - return buf; - } - - /* is it a warning (version 2 error string) or is it a 1.2 error? */ - size_t len = - tpm2_rc_fmt0_S_get(rc) ? - ARRAY_LEN(fmt0_warn_strs) : ARRAY_LEN(fmt0_err_strs); - const char **selection = - tpm2_rc_fmt0_S_get(rc) ? fmt0_warn_strs : fmt0_err_strs; - if (errnum >= len) { - return NULL; - } - - const char *m = selection[errnum]; - if (!m) { - return NULL; - } - - catbuf(buf, "%s", m); - return buf; - } - - catbuf(buf, "%s", "unknown version 1.2 error code"); - - return buf; -} - -/** - * Retrieves the layer field from a TSS2_RC code. - * @param rc - * The rc to query the layer index of. - * @return - * The layer index. - */ -static inline UINT8 tss2_rc_layer_format_get(TSS2_RC rc) { - - return ((rc & (1 << 7)) >> 7); -} - -/** - * Handler for tpm2 error codes. ie codes - * coming from the tpm layer aka layer 0. - * @param rc - * The rc to decode. - * @return - * An error string. - */ -static const char *tpm2_ehandler(TSS2_RC rc) { - - bool is_fmt_1 = tss2_rc_layer_format_get(rc); - - return is_fmt_1 ? tpm2_err_handler_fmt1(rc) : tpm2_err_handler_fmt0(rc); -} - -/** - * The default system code handler. This handles codes - * from the RM (itself and simlated tpm responses), the marshaling - * library (mu), and the tcti layers. - * @param rc - * The rc to decode. - * @return - * An error string. - */ -static const char *sys_err_handler (TSS2_RC rc) { - UNUSED(rc); - - /* - * subtract 1 from the error number - * before indexing into this array. - * - * Commented offsets are for the corresponding - * error number *before* subtraction. Ie error - * number 4 is at array index 3. - */ - static const char *errors[] = { - // 1 - TSS2_BASE_RC_GENERAL_FAILURE - "Catch all for all errors not otherwise specified", - // 2 - TSS2_BASE_RC_NOT_IMPLEMENTED - "If called functionality isn't implemented", - // 3 - TSS2_BASE_RC_BAD_CONTEXT - "A context structure is bad", - // 4 - TSS2_BASE_RC_ABI_MISMATCH - "Passed in ABI version doesn't match called module's ABI version", - // 5 - TSS2_BASE_RC_BAD_REFERENCE - "A pointer is NULL that isn't allowed to be NULL.", - // 6 - TSS2_BASE_RC_INSUFFICIENT_BUFFER - "A buffer isn't large enough", - // 7 - TSS2_BASE_RC_BAD_SEQUENCE - "Function called in the wrong order", - // 8 - TSS2_BASE_RC_NO_CONNECTION - "Fails to connect to next lower layer", - // 9 - TSS2_BASE_RC_TRY_AGAIN - "Operation timed out; function must be called again to be completed", - // 10 - TSS2_BASE_RC_IO_ERROR - "IO failure", - // 11 - TSS2_BASE_RC_BAD_VALUE - "A parameter has a bad value", - // 12 - TSS2_BASE_RC_NOT_PERMITTED - "Operation not permitted.", - // 13 - TSS2_BASE_RC_INVALID_SESSIONS - "Session structures were sent, but command doesn't use them or doesn't" - " use the specified number of them", - // 14 - TSS2_BASE_RC_NO_DECRYPT_PARAM - "If function called that uses decrypt parameter, but command doesn't" - " support decrypt parameter.", - // 15 - TSS2_BASE_RC_NO_ENCRYPT_PARAM - "If function called that uses encrypt parameter, but command doesn't" - " support decrypt parameter.", - // 16 - TSS2_BASE_RC_BAD_SIZE - "If size of a parameter is incorrect", - // 17 - TSS2_BASE_RC_MALFORMED_RESPONSE - "Response is malformed", - // 18 - TSS2_BASE_RC_INSUFFICIENT_CONTEXT - "Context not large enough", - // 19 - TSS2_BASE_RC_INSUFFICIENT_RESPONSE - "Response is not long enough", - // 20 - TSS2_BASE_RC_INCOMPATIBLE_TCTI - "Unknown or unusable TCTI version", - // 21 - TSS2_BASE_RC_NOT_SUPPORTED - "Functionality not supported", - // 22 - TSS2_BASE_RC_BAD_TCTI_STRUCTURE - "TCTI context is bad" - }; - - return (rc - 1u < ARRAY_LEN(errors)) ? errors[rc - 1u] : NULL; -} - - -static struct { - const char *name; - tpm2_error_handler handler; -} layer_handler[TPM2_ERROR_TSS2_RC_LAYER_COUNT] = { - ADD_HANDLER("tpm" , tpm2_ehandler), - ADD_NULL_HANDLER, // layer 1 is unused - ADD_NULL_HANDLER, // layer 2 is unused - ADD_NULL_HANDLER, // layer 3 is unused - ADD_NULL_HANDLER, // layer 4 is unused - ADD_NULL_HANDLER, // layer 5 is unused - ADD_NULL_HANDLER, // layer 6 is the feature rc - ADD_HANDLER("fapi", NULL), // layer 7 is the esapi rc - ADD_HANDLER("sys", sys_err_handler), // layer 8 is the sys rc - ADD_HANDLER("mu", sys_err_handler), // layer 9 is the mu rc - // Defaults to the system handler - ADD_HANDLER("tcti", sys_err_handler), // layer 10 is the tcti rc - // Defaults to the system handler - ADD_HANDLER("rmt", tpm2_ehandler), // layer 11 is the resource manager TPM RC - // The RM usually duplicates TPM responses - // So just default the handler to tpm2. - ADD_HANDLER("rm", NULL), // layer 12 is the rm rc - ADD_HANDLER("drvr", NULL), // layer 13 is the driver rc -}; - -/** - * Determines if the layer allowed to be registered to. - * @param layer - * The layer to determine handler assignment eligibility of. - * @return - * True if it is reserved and thus non-assignable, false otherwise. - */ -static bool is_reserved_layer(UINT8 layer) { - return layer == 0; -} - -/** - * If a layer has no handler registered, default to this - * handler that prints the error number in hex. - * @param rc - * The rc to print the error number of. - * @return - * The string. - */ -static const char *unkown_layer_handler(TSS2_RC rc) { - UNUSED(rc); - - static char buf[32]; - - clearbuf(buf); - catbuf(buf, "0x%X", tpm2_error_get(rc)); - - return buf; -} - -/** - * Register or unregister a custom layer error handler. - * @param layer - * The layer in which to register a handler for. It is an error - * to register for the following reserved layers: - * - TSS2_TPM_RC_LAYER - layer 0 - * - TSS2_SYS_RC_LAYER - layer 8 - * - TSS2_MU_RC_LAYER - layer 9 - * - TSS2_TCTI_RC_LAYER - layer 10 - * @param name - * A friendly layer name. It is an error for the name to be of - * length 0 or greater than 4. - * @param handler - * The handler function to register or NULL to unregister. - * @return - * True on success or False on error. - */ -bool tpm2_error_set_handler(UINT8 layer, const char *name, - tpm2_error_handler handler) { - - /* don't allow setting reserved layers */ - if (is_reserved_layer(layer)) { - return false; - } - - /* - * if they are clearing the handler, name doesn't matter - * clear it too. - */ - if (!handler) { - name = NULL; - } - - /* Perform a zero and max-name length check if name is being set */ - if (name) { - size_t len = name ? strlen(name) : 0; - if (!len || len > TSS2_ERR_LAYER_NAME_MAX) - return false; - } - - layer_handler[layer].handler = handler; - layer_handler[layer].name = name; - - return true; -} - -const char * tpm2_error_str(TSS2_RC rc) { - - static char buf[TSS2_ERR_LAYER_NAME_MAX + TSS2_ERR_LAYER_ERROR_STR_MAX + 1]; - - clearbuf(buf); - - UINT8 layer = tss2_rc_layer_number_get(rc); - - tpm2_error_handler handler = layer_handler[layer].handler; - const char *lname = layer_handler[layer].name; - - if (lname) { - catbuf(buf, "%s:", lname); - } else { - catbuf(buf, "%u:", layer); - } - - handler = !handler ? unkown_layer_handler : handler; - - // Handlers only need the error bits. This way they don't - // need to concern themselves with masking off the layer - // bits or anything else. - UINT16 err_bits = tpm2_error_get(rc); - const char *e = err_bits ? handler(err_bits) : "success"; - if (e) { - catbuf(buf, "%s", e); - } else { - catbuf(buf, "0x%X", err_bits); - } - - return buf; -} |