Home | History | Annotate | Line # | Download | only in tspi
      1 
      2 /*
      3  * Licensed Materials - Property of IBM
      4  *
      5  * trousers - An open source TCG Software Stack
      6  *
      7  * (C) Copyright International Business Machines Corp. 2004-2006
      8  *
      9  */
     10 
     11 #include <stdlib.h>
     12 #include <stdio.h>
     13 #include <string.h>
     14 #include <inttypes.h>
     15 
     16 #include "trousers/tss.h"
     17 #include "trousers/trousers.h"
     18 #include "trousers_types.h"
     19 #include "spi_utils.h"
     20 #include "capabilities.h"
     21 #include "tsplog.h"
     22 #include "obj.h"
     23 
     24 
     25 TSS_RESULT
     26 Tspi_TPM_GetCapability(TSS_HTPM hTPM,			/* in */
     27 		       TSS_FLAG capArea,		/* in */
     28 		       UINT32 ulSubCapLength,		/* in */
     29 		       BYTE * rgbSubCap,		/* in */
     30 		       UINT32 * pulRespDataLength,	/* out */
     31 		       BYTE ** prgbRespData)		/* out */
     32 {
     33 	TSS_HCONTEXT tspContext;
     34 	TPM_CAPABILITY_AREA tcsCapArea;
     35 	UINT32 tcsSubCap = 0;
     36 	UINT32 tcsSubCapContainer;
     37 	TSS_RESULT result;
     38 	UINT32 nonVolFlags, volFlags, respLen;
     39 	BYTE *respData;
     40 	UINT64 offset;
     41 	TSS_BOOL fOwnerAuth = FALSE, endianFlag = TRUE;
     42 
     43 	if (pulRespDataLength == NULL || prgbRespData == NULL)
     44 		return TSPERR(TSS_E_BAD_PARAMETER);
     45 
     46 	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
     47 		return result;
     48 
     49 	/* Verify the caps and subcaps */
     50 	switch (capArea) {
     51 	case TSS_TPMCAP_ORD:
     52 		if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap)
     53 			return TSPERR(TSS_E_BAD_PARAMETER);
     54 
     55 		tcsCapArea = TCPA_CAP_ORD;
     56 		tcsSubCap = *(UINT32 *)rgbSubCap;
     57 		break;
     58 	case TSS_TPMCAP_FLAG:
     59 		fOwnerAuth = TRUE;
     60 		break;
     61 	case TSS_TPMCAP_AUTH_ENCRYPT:
     62 	case TSS_TPMCAP_ALG:
     63 		if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap)
     64 			return TSPERR(TSS_E_BAD_PARAMETER);
     65 
     66 		/* Test capArea again here in order to keep from having to duplicate the switch
     67 		 * statement below */
     68 		tcsCapArea = (capArea == TSS_TPMCAP_ALG ? TPM_CAP_ALG : TPM_CAP_AUTH_ENCRYPT);
     69 
     70 		switch (*(UINT32 *)rgbSubCap) {
     71 		case TSS_ALG_RSA:
     72 			tcsSubCap = TPM_ALG_RSA;
     73 			break;
     74 		case TSS_ALG_AES128:
     75 			tcsSubCap = TPM_ALG_AES128;
     76 			break;
     77 		case TSS_ALG_AES192:
     78 			tcsSubCap = TPM_ALG_AES192;
     79 			break;
     80 		case TSS_ALG_AES256:
     81 			tcsSubCap = TPM_ALG_AES256;
     82 			break;
     83 		case TSS_ALG_3DES:
     84 			tcsSubCap = TPM_ALG_3DES;
     85 			break;
     86 		case TSS_ALG_DES:
     87 			tcsSubCap = TPM_ALG_DES;
     88 			break;
     89 		case TSS_ALG_SHA:
     90 			tcsSubCap = TPM_ALG_SHA;
     91 			break;
     92 		case TSS_ALG_HMAC:
     93 			tcsSubCap = TPM_ALG_HMAC;
     94 			break;
     95 		case TSS_ALG_MGF1:
     96 			tcsSubCap = TPM_ALG_MGF1;
     97 			break;
     98 		case TSS_ALG_XOR:
     99 			tcsSubCap = TPM_ALG_XOR;
    100 			break;
    101 		default:
    102 			tcsSubCap = *(UINT32 *)rgbSubCap;
    103 			break;
    104 		}
    105 		break;
    106 #ifdef TSS_BUILD_NV
    107 	case TSS_TPMCAP_NV_LIST:
    108 		tcsCapArea = TPM_CAP_NV_LIST;
    109 		endianFlag = FALSE;
    110 		break;
    111 	case TSS_TPMCAP_NV_INDEX:
    112 		if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap)
    113 			return TSPERR(TSS_E_BAD_PARAMETER);
    114 
    115 		tcsCapArea = TPM_CAP_NV_INDEX;
    116 		tcsSubCap = *(UINT32 *)rgbSubCap;
    117 		break;
    118 #endif
    119 	case TSS_TPMCAP_PROPERTY:	/* Determines a physical property of the TPM. */
    120 		if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap)
    121 			return TSPERR(TSS_E_BAD_PARAMETER);
    122 
    123 		tcsCapArea = TCPA_CAP_PROPERTY;
    124 		tcsSubCapContainer = *(UINT32 *)rgbSubCap;
    125 
    126 		switch (tcsSubCapContainer) {
    127 		case TSS_TPMCAP_PROP_PCR:
    128 			tcsSubCap = TPM_CAP_PROP_PCR;
    129 			break;
    130 		case TSS_TPMCAP_PROP_DIR:
    131 			tcsSubCap = TPM_CAP_PROP_DIR;
    132 			break;
    133 		/* case TSS_TPMCAP_PROP_SLOTS: */
    134 		case TSS_TPMCAP_PROP_KEYS:
    135 			tcsSubCap = TPM_CAP_PROP_SLOTS;
    136 			break;
    137 		case TSS_TPMCAP_PROP_MANUFACTURER:
    138 			tcsSubCap = TPM_CAP_PROP_MANUFACTURER;
    139 			endianFlag = FALSE;
    140 			break;
    141 		case TSS_TPMCAP_PROP_COUNTERS:
    142 			tcsSubCap = TPM_CAP_PROP_COUNTERS;
    143 			break;
    144 		case TSS_TPMCAP_PROP_MAXCOUNTERS:
    145 			tcsSubCap = TPM_CAP_PROP_MAX_COUNTERS;
    146 			break;
    147 		/*case TSS_TPMCAP_PROP_MINCOUNTERINCTIME: */
    148 		case TSS_TPMCAP_PROP_MIN_COUNTER:
    149 			tcsSubCap = TPM_CAP_PROP_MIN_COUNTER;
    150 			break;
    151 		case TSS_TPMCAP_PROP_ACTIVECOUNTER:
    152 			tcsSubCap = TPM_CAP_PROP_ACTIVE_COUNTER;
    153 			break;
    154 		case TSS_TPMCAP_PROP_TRANSESSIONS:
    155 			tcsSubCap = TPM_CAP_PROP_TRANSSESS;
    156 			break;
    157 		case TSS_TPMCAP_PROP_MAXTRANSESSIONS:
    158 			tcsSubCap = TPM_CAP_PROP_MAX_TRANSSESS;
    159 			break;
    160 		case TSS_TPMCAP_PROP_SESSIONS:
    161 			tcsSubCap = TPM_CAP_PROP_SESSIONS;
    162 			break;
    163 		case TSS_TPMCAP_PROP_MAXSESSIONS:
    164 			tcsSubCap = TPM_CAP_PROP_MAX_SESSIONS;
    165 			break;
    166 		case TSS_TPMCAP_PROP_FAMILYROWS:
    167 			tcsSubCap = TPM_CAP_PROP_FAMILYROWS;
    168 			break;
    169 		case TSS_TPMCAP_PROP_DELEGATEROWS:
    170 			tcsSubCap = TPM_CAP_PROP_DELEGATE_ROW;
    171 			break;
    172 		case TSS_TPMCAP_PROP_OWNER:
    173 			tcsSubCap = TPM_CAP_PROP_OWNER;
    174 			break;
    175 		case TSS_TPMCAP_PROP_MAXKEYS:
    176 			tcsSubCap = TPM_CAP_PROP_MAX_KEYS;
    177 			break;
    178 		case TSS_TPMCAP_PROP_AUTHSESSIONS:
    179 			tcsSubCap = TPM_CAP_PROP_AUTHSESS;
    180 			break;
    181 		case TSS_TPMCAP_PROP_MAXAUTHSESSIONS:
    182 			tcsSubCap = TPM_CAP_PROP_MAX_AUTHSESS;
    183 			break;
    184 		case TSS_TPMCAP_PROP_CONTEXTS:
    185 			tcsSubCap = TPM_CAP_PROP_CONTEXT;
    186 			break;
    187 		case TSS_TPMCAP_PROP_MAXCONTEXTS:
    188 			tcsSubCap = TPM_CAP_PROP_MAX_CONTEXT;
    189 			break;
    190 		case TSS_TPMCAP_PROP_DAASESSIONS:
    191 			tcsSubCap = TPM_CAP_PROP_SESSION_DAA;
    192 			break;
    193 		case TSS_TPMCAP_PROP_MAXDAASESSIONS:
    194 			tcsSubCap = TPM_CAP_PROP_DAA_MAX;
    195 			break;
    196 		case TSS_TPMCAP_PROP_TISTIMEOUTS:
    197 			tcsSubCap = TPM_CAP_PROP_TIS_TIMEOUT;
    198 			break;
    199 		case TSS_TPMCAP_PROP_STARTUPEFFECTS:
    200 			tcsSubCap = TPM_CAP_PROP_STARTUP_EFFECT;
    201 			endianFlag = FALSE;
    202 			break;
    203 		case TSS_TPMCAP_PROP_MAXCONTEXTCOUNTDIST:
    204 			tcsSubCap = TPM_CAP_PROP_CONTEXT_DIST;
    205 			break;
    206 		case TSS_TPMCAP_PROP_CMKRESTRICTION:
    207 			tcsSubCap = TPM_CAP_PROP_CMK_RESTRICTION;
    208 			break;
    209 		case TSS_TPMCAP_PROP_DURATION:
    210 			tcsSubCap = TPM_CAP_PROP_DURATION;
    211 			break;
    212 		case TSS_TPMCAP_PROP_MAXNVAVAILABLE:
    213 			tcsSubCap = TPM_CAP_PROP_NV_AVAILABLE;
    214 			break;
    215 		case TSS_TPMCAP_PROP_INPUTBUFFERSIZE:
    216 			tcsSubCap = TPM_CAP_PROP_INPUT_BUFFER;
    217 			break;
    218 #if 0
    219 		/* There isn't a way to query the TPM for these, the TPMWG is considering how to
    220 		 * address some of them in the next version of the TPM - KEY Oct 15, 2007*/
    221 		case TSS_TPMCAP_PROP_MAXNVWRITE:
    222 			break;
    223 		case TSS_TPMCAP_PROP_REVISION:
    224 			break;
    225 		case TSS_TPMCAP_PROP_LOCALITIES_AVAIL:
    226 			break;
    227 		case TSS_TPMCAP_PROP_PCRMAP:
    228 			break;
    229 #endif
    230 		default:
    231 			return TSPERR(TSS_E_BAD_PARAMETER);
    232 		}
    233 		break;
    234 	case TSS_TPMCAP_VERSION:	/* Queries the current TPM version. */
    235 		tcsCapArea = TCPA_CAP_VERSION;
    236 		endianFlag = FALSE;
    237 		break;
    238 	case TSS_TPMCAP_VERSION_VAL:	/* Queries the current TPM version for 1.2 TPM device. */
    239 		tcsCapArea = TPM_CAP_VERSION_VAL;
    240 		endianFlag = FALSE;
    241 		break;
    242 	case TSS_TPMCAP_MFR:
    243 		tcsCapArea = TPM_CAP_MFR;
    244 		endianFlag = FALSE;
    245 		break;
    246 	case TSS_TPMCAP_SYM_MODE:
    247 		if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap)
    248 			return TSPERR(TSS_E_BAD_PARAMETER);
    249 
    250 		tcsCapArea = TPM_CAP_SYM_MODE;
    251 		tcsSubCap = *(UINT32 *)rgbSubCap;
    252 		break;
    253 	case TSS_TPMCAP_HANDLE:
    254 		if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap)
    255 			return TSPERR(TSS_E_BAD_PARAMETER);
    256 
    257 		tcsCapArea = TPM_CAP_HANDLE;
    258 		tcsSubCap = *(UINT32 *)rgbSubCap;
    259 		break;
    260 	case TSS_TPMCAP_TRANS_ES:
    261 		if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap)
    262 			return TSPERR(TSS_E_BAD_PARAMETER);
    263 
    264 		tcsCapArea = TPM_CAP_TRANS_ES;
    265 		switch (*(UINT32 *)rgbSubCap) {
    266 		case TSS_ES_NONE:
    267 			tcsSubCap = TPM_ES_NONE;
    268 			break;
    269 		case TSS_ES_RSAESPKCSV15:
    270 			tcsSubCap = TPM_ES_RSAESPKCSv15;
    271 			break;
    272 		case TSS_ES_RSAESOAEP_SHA1_MGF1:
    273 			tcsSubCap = TPM_ES_RSAESOAEP_SHA1_MGF1;
    274 			break;
    275 		case TSS_ES_SYM_CNT:
    276 			tcsSubCap = TPM_ES_SYM_CNT;
    277 			break;
    278 		case TSS_ES_SYM_OFB:
    279 			tcsSubCap = TPM_ES_SYM_OFB;
    280 			break;
    281 		case TSS_ES_SYM_CBC_PKCS5PAD:
    282 			tcsSubCap = TPM_ES_SYM_CBC_PKCS5PAD;
    283 			break;
    284 		default:
    285 			tcsSubCap = *(UINT32 *)rgbSubCap;
    286 			break;
    287 		}
    288 		break;
    289 	default:
    290 		return TSPERR(TSS_E_BAD_PARAMETER);
    291 		break;
    292 	}
    293 
    294 	if (fOwnerAuth) {
    295 		/* do an owner authorized get capability call */
    296 		if ((result = get_tpm_flags(tspContext, hTPM, &volFlags, &nonVolFlags)))
    297 			return result;
    298 
    299 		respLen = 2 * sizeof(UINT32);
    300 		respData = calloc_tspi(tspContext, respLen);
    301 		if (respData == NULL) {
    302 			LogError("malloc of %u bytes failed.", respLen);
    303 			return TSPERR(TSS_E_OUTOFMEMORY);
    304 		}
    305 
    306 		offset = 0;
    307 		Trspi_LoadBlob_UINT32(&offset, nonVolFlags, respData);
    308 		Trspi_LoadBlob_UINT32(&offset, volFlags, respData);
    309 
    310 		*pulRespDataLength = respLen;
    311 		*prgbRespData = respData;
    312 
    313 		return TSS_SUCCESS;
    314 	}
    315 
    316 	tcsSubCap = endian32(tcsSubCap);
    317 
    318 	if ((result = TCS_API(tspContext)->GetTPMCapability(tspContext, tcsCapArea, ulSubCapLength,
    319 							    (BYTE *)&tcsSubCap, pulRespDataLength,
    320 							    prgbRespData)))
    321 		return result;
    322 
    323 	if (endianFlag) {
    324 		if (*pulRespDataLength == sizeof(UINT32))
    325 			*(UINT32 *)(*prgbRespData) = endian32(*(UINT32 *)(*prgbRespData));
    326 		else if (*pulRespDataLength == sizeof(UINT16))
    327 			*(UINT32 *)(*prgbRespData) = endian16(*(UINT32 *)(*prgbRespData));
    328 	}
    329 
    330 	if ((result = __tspi_add_mem_entry(tspContext, *prgbRespData))) {
    331 		free(*prgbRespData);
    332 		*prgbRespData = NULL;
    333 		*pulRespDataLength = 0;
    334 		return result;
    335 	}
    336 
    337 	return TSS_SUCCESS;
    338 }
    339 
    340 TSS_RESULT
    341 Tspi_TPM_GetCapabilitySigned(TSS_HTPM hTPM,			/* in */
    342 			     TSS_HTPM hKey,			/* in */
    343 			     TSS_FLAG capArea,			/* in */
    344 			     UINT32 ulSubCapLength,		/* in */
    345 			     BYTE * rgbSubCap,			/* in */
    346 			     TSS_VALIDATION * pValidationData,	/* in, out */
    347 			     UINT32 * pulRespDataLength,	/* out */
    348 			     BYTE ** prgbRespData)		/* out */
    349 {
    350 	/*
    351 	 * Function was found to have a vulnerability, so implementation is not
    352 	 * required by the TSS 1.1b spec.
    353 	 */
    354 	return TSPERR(TSS_E_NOTIMPL);
    355 }
    356 
    357