Home | History | Annotate | Line # | Download | only in tcs
      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 
     12 #include <stdlib.h>
     13 #include <stdio.h>
     14 #include <string.h>
     15 #include <unistd.h>
     16 #include <sys/types.h>
     17 #include <sys/stat.h>
     18 #include <sys/mman.h>
     19 #include <fcntl.h>
     20 #include <errno.h>
     21 
     22 #include "trousers/tss.h"
     23 #include "trousers_types.h"
     24 #include "tcs_tsp.h"
     25 #include "tcs_utils.h"
     26 #include "tcs_int_literals.h"
     27 #include "capabilities.h"
     28 #include "tcsps.h"
     29 #include "tcslog.h"
     30 #include "tddl.h"
     31 #include "req_mgr.h"
     32 
     33 
     34 TSS_RESULT
     35 get_current_version(TPM_VERSION *version)
     36 {
     37 	TCPA_CAPABILITY_AREA capArea = TPM_CAP_VERSION_VAL;
     38 	UINT32 respSize;
     39 	BYTE *resp;
     40 	TSS_RESULT result;
     41 	UINT64 offset;
     42 
     43 	/* try the 1.2 way first */
     44 	result = TCSP_GetCapability_Internal(InternalContext, capArea, 0, NULL, &respSize, &resp);
     45 	if (result == TSS_SUCCESS) {
     46 		offset = sizeof(UINT16); // XXX hack
     47 		UnloadBlob_VERSION(&offset, resp, version);
     48 		free(resp);
     49 	} else if (result == TCPA_E_BAD_MODE) {
     50 		/* if the TPM doesn't understand VERSION_VAL, try the 1.1 way */
     51 		capArea = TCPA_CAP_VERSION;
     52 		result = TCSP_GetCapability_Internal(InternalContext, capArea, 0, NULL, &respSize,
     53 						     &resp);
     54 		if (result == TSS_SUCCESS) {
     55 			offset = 0;
     56 			UnloadBlob_VERSION(&offset, resp, version);
     57 			free(resp);
     58 		}
     59 	}
     60 
     61 	return result;
     62 }
     63 
     64 TSS_RESULT
     65 get_cap_uint32(TCPA_CAPABILITY_AREA capArea, BYTE *subCap, UINT32 subCapSize, UINT32 *v)
     66 {
     67 	UINT32 respSize;
     68 	BYTE *resp;
     69 	TSS_RESULT result;
     70 	UINT64 offset;
     71 
     72 	result = TCSP_GetCapability_Internal(InternalContext, capArea, subCapSize, subCap,
     73 					     &respSize, &resp);
     74 	if (!result) {
     75 		offset = 0;
     76 		switch (respSize) {
     77 			case 1:
     78 				UnloadBlob_BYTE(&offset, (BYTE *)v, resp);
     79 				break;
     80 			case sizeof(UINT16):
     81 				UnloadBlob_UINT16(&offset, (UINT16 *)v, resp);
     82 				break;
     83 			case sizeof(UINT32):
     84 				UnloadBlob_UINT32(&offset, v, resp);
     85 				break;
     86 			default:
     87 				LogDebug("TCSP_GetCapability_Internal returned"
     88 					  " %u bytes", respSize);
     89 				result = TCSERR(TSS_E_FAIL);
     90 				break;
     91 		}
     92 		free(resp);
     93 	}
     94 
     95 	return result;
     96 }
     97 
     98 
     99 TSS_RESULT
    100 get_max_auths(UINT32 *auths)
    101 {
    102 	TCS_AUTHHANDLE handles[TSS_MAX_AUTHS_CAP];
    103 	TCPA_NONCE nonce;
    104 	UINT32 subCap;
    105 	TSS_RESULT result;
    106 	int i;
    107 
    108 	if (TPM_VERSION_IS(1,2)) {
    109 		UINT32ToArray(TPM_CAP_PROP_MAX_AUTHSESS, (BYTE *)(&subCap));
    110 		result = get_cap_uint32(TPM_CAP_PROPERTY, (BYTE *)&subCap, sizeof(subCap), auths);
    111 	} else if (TPM_VERSION_IS(1,1)) {
    112 		/* open auth sessions until we get a failure */
    113 		for (i = 0; i < TSS_MAX_AUTHS_CAP; i++) {
    114 			result = TCSP_OIAP_Internal(InternalContext, &(handles[i]), &nonce);
    115 			if (result != TSS_SUCCESS) {
    116 				/* this is not off by one since we're 0 indexed */
    117 				*auths = i;
    118 				break;
    119 			}
    120 		}
    121 
    122 		if (i == TSS_MAX_AUTHS_CAP)
    123 			*auths = TSS_MAX_AUTHS_CAP;
    124 
    125 		/* close the auth sessions */
    126 		for (i = 0; (UINT32)i < *auths; i++) {
    127 			internal_TerminateHandle(handles[i]);
    128 		}
    129 	} else {
    130 		result = TCSERR(TSS_E_INTERNAL_ERROR);
    131 		*auths = 0;
    132 	}
    133 
    134 	if (*auths < 2) {
    135 		LogError("%s reported only %u auth available!", __FUNCTION__, *auths);
    136 		LogError("Your TPM must be reset before the TCSD can be started.");
    137 	} else {
    138 		LogDebug("get_max_auths reports %u auth contexts found", *auths);
    139 		result = TSS_SUCCESS;
    140 	}
    141 
    142 	return result;
    143 }
    144 
    145 /* This is only called from init paths, so printing an error message is
    146  * appropriate if something goes wrong */
    147 TSS_RESULT
    148 get_tpm_metrics(struct tpm_properties *p)
    149 {
    150 	TSS_RESULT result;
    151 	UINT32 subCap, rv = 0;
    152 
    153 	if ((result = get_current_version(&p->version)))
    154 		goto err;
    155 
    156 	UINT32ToArray(TPM_ORD_SaveKeyContext, (BYTE *)&subCap);
    157 	if ((result = get_cap_uint32(TCPA_CAP_ORD, (BYTE *)&subCap, sizeof(UINT32), &rv)))
    158 		goto err;
    159 	p->keyctx_swap = rv ? TRUE : FALSE;
    160 
    161 	rv = 0;
    162 	UINT32ToArray(TPM_ORD_SaveAuthContext, (BYTE *)&subCap);
    163 	if ((result = get_cap_uint32(TCPA_CAP_ORD, (BYTE *)&subCap, sizeof(UINT32), &rv)))
    164 		goto err;
    165 	p->authctx_swap = rv ? TRUE : FALSE;
    166 
    167 	UINT32ToArray(TPM_CAP_PROP_PCR, (BYTE *)&subCap);
    168 	if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32),
    169 					&p->num_pcrs)))
    170 		goto err;
    171 
    172 	UINT32ToArray(TPM_CAP_PROP_DIR, (BYTE *)&subCap);
    173 	if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32),
    174 					&p->num_dirs)))
    175 		goto err;
    176 
    177 	UINT32ToArray(TPM_CAP_PROP_SLOTS, (BYTE *)&subCap);
    178 	if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32),
    179 					&p->num_keys)))
    180 		goto err;
    181 
    182 	UINT32ToArray(TPM_CAP_PROP_MANUFACTURER, (BYTE *)&subCap);
    183 	if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32),
    184 					(UINT32 *)&p->manufacturer)))
    185 		goto err;
    186 
    187 	result = get_max_auths(&(p->num_auths));
    188 
    189 err:
    190 	if (result)
    191 		LogError("TCS GetCapability failed with result = 0x%x", result);
    192 
    193 	return result;
    194 }
    195 
    196