diff options
Diffstat (limited to 'src/tspi/tspi_caps_tpm.c')
-rw-r--r-- | src/tspi/tspi_caps_tpm.c | 356 |
1 files changed, 356 insertions, 0 deletions
diff --git a/src/tspi/tspi_caps_tpm.c b/src/tspi/tspi_caps_tpm.c new file mode 100644 index 0000000..131e67b --- /dev/null +++ b/src/tspi/tspi_caps_tpm.c @@ -0,0 +1,356 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_TPM_GetCapability(TSS_HTPM hTPM, /* in */ + TSS_FLAG capArea, /* in */ + UINT32 ulSubCapLength, /* in */ + BYTE * rgbSubCap, /* in */ + UINT32 * pulRespDataLength, /* out */ + BYTE ** prgbRespData) /* out */ +{ + TSS_HCONTEXT tspContext; + TPM_CAPABILITY_AREA tcsCapArea; + UINT32 tcsSubCap = 0; + UINT32 tcsSubCapContainer; + TSS_RESULT result; + UINT32 nonVolFlags, volFlags, respLen; + BYTE *respData; + UINT64 offset; + TSS_BOOL fOwnerAuth = FALSE, endianFlag = TRUE; + + if (pulRespDataLength == NULL || prgbRespData == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + /* Verify the caps and subcaps */ + switch (capArea) { + case TSS_TPMCAP_ORD: + if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) + return TSPERR(TSS_E_BAD_PARAMETER); + + tcsCapArea = TCPA_CAP_ORD; + tcsSubCap = *(UINT32 *)rgbSubCap; + break; + case TSS_TPMCAP_FLAG: + fOwnerAuth = TRUE; + break; + case TSS_TPMCAP_AUTH_ENCRYPT: + case TSS_TPMCAP_ALG: + if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) + return TSPERR(TSS_E_BAD_PARAMETER); + + /* Test capArea again here in order to keep from having to duplicate the switch + * statement below */ + tcsCapArea = (capArea == TSS_TPMCAP_ALG ? TPM_CAP_ALG : TPM_CAP_AUTH_ENCRYPT); + + switch (*(UINT32 *)rgbSubCap) { + case TSS_ALG_RSA: + tcsSubCap = TPM_ALG_RSA; + break; + case TSS_ALG_AES128: + tcsSubCap = TPM_ALG_AES128; + break; + case TSS_ALG_AES192: + tcsSubCap = TPM_ALG_AES192; + break; + case TSS_ALG_AES256: + tcsSubCap = TPM_ALG_AES256; + break; + case TSS_ALG_3DES: + tcsSubCap = TPM_ALG_3DES; + break; + case TSS_ALG_DES: + tcsSubCap = TPM_ALG_DES; + break; + case TSS_ALG_SHA: + tcsSubCap = TPM_ALG_SHA; + break; + case TSS_ALG_HMAC: + tcsSubCap = TPM_ALG_HMAC; + break; + case TSS_ALG_MGF1: + tcsSubCap = TPM_ALG_MGF1; + break; + case TSS_ALG_XOR: + tcsSubCap = TPM_ALG_XOR; + break; + default: + tcsSubCap = *(UINT32 *)rgbSubCap; + break; + } + break; +#ifdef TSS_BUILD_NV + case TSS_TPMCAP_NV_LIST: + tcsCapArea = TPM_CAP_NV_LIST; + endianFlag = FALSE; + break; + case TSS_TPMCAP_NV_INDEX: + if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) + return TSPERR(TSS_E_BAD_PARAMETER); + + tcsCapArea = TPM_CAP_NV_INDEX; + tcsSubCap = *(UINT32 *)rgbSubCap; + break; +#endif + case TSS_TPMCAP_PROPERTY: /* Determines a physical property of the TPM. */ + if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) + return TSPERR(TSS_E_BAD_PARAMETER); + + tcsCapArea = TCPA_CAP_PROPERTY; + tcsSubCapContainer = *(UINT32 *)rgbSubCap; + + switch (tcsSubCapContainer) { + case TSS_TPMCAP_PROP_PCR: + tcsSubCap = TPM_CAP_PROP_PCR; + break; + case TSS_TPMCAP_PROP_DIR: + tcsSubCap = TPM_CAP_PROP_DIR; + break; + /* case TSS_TPMCAP_PROP_SLOTS: */ + case TSS_TPMCAP_PROP_KEYS: + tcsSubCap = TPM_CAP_PROP_SLOTS; + break; + case TSS_TPMCAP_PROP_MANUFACTURER: + tcsSubCap = TPM_CAP_PROP_MANUFACTURER; + endianFlag = FALSE; + break; + case TSS_TPMCAP_PROP_COUNTERS: + tcsSubCap = TPM_CAP_PROP_COUNTERS; + break; + case TSS_TPMCAP_PROP_MAXCOUNTERS: + tcsSubCap = TPM_CAP_PROP_MAX_COUNTERS; + break; + /*case TSS_TPMCAP_PROP_MINCOUNTERINCTIME: */ + case TSS_TPMCAP_PROP_MIN_COUNTER: + tcsSubCap = TPM_CAP_PROP_MIN_COUNTER; + break; + case TSS_TPMCAP_PROP_ACTIVECOUNTER: + tcsSubCap = TPM_CAP_PROP_ACTIVE_COUNTER; + break; + case TSS_TPMCAP_PROP_TRANSESSIONS: + tcsSubCap = TPM_CAP_PROP_TRANSSESS; + break; + case TSS_TPMCAP_PROP_MAXTRANSESSIONS: + tcsSubCap = TPM_CAP_PROP_MAX_TRANSSESS; + break; + case TSS_TPMCAP_PROP_SESSIONS: + tcsSubCap = TPM_CAP_PROP_SESSIONS; + break; + case TSS_TPMCAP_PROP_MAXSESSIONS: + tcsSubCap = TPM_CAP_PROP_MAX_SESSIONS; + break; + case TSS_TPMCAP_PROP_FAMILYROWS: + tcsSubCap = TPM_CAP_PROP_FAMILYROWS; + break; + case TSS_TPMCAP_PROP_DELEGATEROWS: + tcsSubCap = TPM_CAP_PROP_DELEGATE_ROW; + break; + case TSS_TPMCAP_PROP_OWNER: + tcsSubCap = TPM_CAP_PROP_OWNER; + break; + case TSS_TPMCAP_PROP_MAXKEYS: + tcsSubCap = TPM_CAP_PROP_MAX_KEYS; + break; + case TSS_TPMCAP_PROP_AUTHSESSIONS: + tcsSubCap = TPM_CAP_PROP_AUTHSESS; + break; + case TSS_TPMCAP_PROP_MAXAUTHSESSIONS: + tcsSubCap = TPM_CAP_PROP_MAX_AUTHSESS; + break; + case TSS_TPMCAP_PROP_CONTEXTS: + tcsSubCap = TPM_CAP_PROP_CONTEXT; + break; + case TSS_TPMCAP_PROP_MAXCONTEXTS: + tcsSubCap = TPM_CAP_PROP_MAX_CONTEXT; + break; + case TSS_TPMCAP_PROP_DAASESSIONS: + tcsSubCap = TPM_CAP_PROP_SESSION_DAA; + break; + case TSS_TPMCAP_PROP_MAXDAASESSIONS: + tcsSubCap = TPM_CAP_PROP_DAA_MAX; + break; + case TSS_TPMCAP_PROP_TISTIMEOUTS: + tcsSubCap = TPM_CAP_PROP_TIS_TIMEOUT; + break; + case TSS_TPMCAP_PROP_STARTUPEFFECTS: + tcsSubCap = TPM_CAP_PROP_STARTUP_EFFECT; + endianFlag = FALSE; + break; + case TSS_TPMCAP_PROP_MAXCONTEXTCOUNTDIST: + tcsSubCap = TPM_CAP_PROP_CONTEXT_DIST; + break; + case TSS_TPMCAP_PROP_CMKRESTRICTION: + tcsSubCap = TPM_CAP_PROP_CMK_RESTRICTION; + break; + case TSS_TPMCAP_PROP_DURATION: + tcsSubCap = TPM_CAP_PROP_DURATION; + break; + case TSS_TPMCAP_PROP_MAXNVAVAILABLE: + tcsSubCap = TPM_CAP_PROP_NV_AVAILABLE; + break; + case TSS_TPMCAP_PROP_INPUTBUFFERSIZE: + tcsSubCap = TPM_CAP_PROP_INPUT_BUFFER; + break; +#if 0 + /* There isn't a way to query the TPM for these, the TPMWG is considering how to + * address some of them in the next version of the TPM - KEY Oct 15, 2007*/ + case TSS_TPMCAP_PROP_MAXNVWRITE: + break; + case TSS_TPMCAP_PROP_REVISION: + break; + case TSS_TPMCAP_PROP_LOCALITIES_AVAIL: + break; + case TSS_TPMCAP_PROP_PCRMAP: + break; +#endif + default: + return TSPERR(TSS_E_BAD_PARAMETER); + } + break; + case TSS_TPMCAP_VERSION: /* Queries the current TPM version. */ + tcsCapArea = TCPA_CAP_VERSION; + endianFlag = FALSE; + break; + case TSS_TPMCAP_VERSION_VAL: /* Queries the current TPM version for 1.2 TPM device. */ + tcsCapArea = TPM_CAP_VERSION_VAL; + endianFlag = FALSE; + break; + case TSS_TPMCAP_MFR: + tcsCapArea = TPM_CAP_MFR; + endianFlag = FALSE; + break; + case TSS_TPMCAP_SYM_MODE: + if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) + return TSPERR(TSS_E_BAD_PARAMETER); + + tcsCapArea = TPM_CAP_SYM_MODE; + tcsSubCap = *(UINT32 *)rgbSubCap; + break; + case TSS_TPMCAP_HANDLE: + if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) + return TSPERR(TSS_E_BAD_PARAMETER); + + tcsCapArea = TPM_CAP_HANDLE; + tcsSubCap = *(UINT32 *)rgbSubCap; + break; + case TSS_TPMCAP_TRANS_ES: + if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) + return TSPERR(TSS_E_BAD_PARAMETER); + + tcsCapArea = TPM_CAP_TRANS_ES; + switch (*(UINT32 *)rgbSubCap) { + case TSS_ES_NONE: + tcsSubCap = TPM_ES_NONE; + break; + case TSS_ES_RSAESPKCSV15: + tcsSubCap = TPM_ES_RSAESPKCSv15; + break; + case TSS_ES_RSAESOAEP_SHA1_MGF1: + tcsSubCap = TPM_ES_RSAESOAEP_SHA1_MGF1; + break; + case TSS_ES_SYM_CNT: + tcsSubCap = TPM_ES_SYM_CNT; + break; + case TSS_ES_SYM_OFB: + tcsSubCap = TPM_ES_SYM_OFB; + break; + case TSS_ES_SYM_CBC_PKCS5PAD: + tcsSubCap = TPM_ES_SYM_CBC_PKCS5PAD; + break; + default: + tcsSubCap = *(UINT32 *)rgbSubCap; + break; + } + break; + default: + return TSPERR(TSS_E_BAD_PARAMETER); + break; + } + + if (fOwnerAuth) { + /* do an owner authorized get capability call */ + if ((result = get_tpm_flags(tspContext, hTPM, &volFlags, &nonVolFlags))) + return result; + + respLen = 2 * sizeof(UINT32); + respData = calloc_tspi(tspContext, respLen); + if (respData == NULL) { + LogError("malloc of %u bytes failed.", respLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, nonVolFlags, respData); + Trspi_LoadBlob_UINT32(&offset, volFlags, respData); + + *pulRespDataLength = respLen; + *prgbRespData = respData; + + return TSS_SUCCESS; + } + + tcsSubCap = endian32(tcsSubCap); + + if ((result = TCS_API(tspContext)->GetTPMCapability(tspContext, tcsCapArea, ulSubCapLength, + (BYTE *)&tcsSubCap, pulRespDataLength, + prgbRespData))) + return result; + + if (endianFlag) { + if (*pulRespDataLength == sizeof(UINT32)) + *(UINT32 *)(*prgbRespData) = endian32(*(UINT32 *)(*prgbRespData)); + else if (*pulRespDataLength == sizeof(UINT16)) + *(UINT32 *)(*prgbRespData) = endian16(*(UINT32 *)(*prgbRespData)); + } + + if ((result = __tspi_add_mem_entry(tspContext, *prgbRespData))) { + free(*prgbRespData); + *prgbRespData = NULL; + *pulRespDataLength = 0; + return result; + } + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_TPM_GetCapabilitySigned(TSS_HTPM hTPM, /* in */ + TSS_HTPM hKey, /* in */ + TSS_FLAG capArea, /* in */ + UINT32 ulSubCapLength, /* in */ + BYTE * rgbSubCap, /* in */ + TSS_VALIDATION * pValidationData, /* in, out */ + UINT32 * pulRespDataLength, /* out */ + BYTE ** prgbRespData) /* out */ +{ + /* + * Function was found to have a vulnerability, so implementation is not + * required by the TSS 1.1b spec. + */ + return TSPERR(TSS_E_NOTIMPL); +} + |