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
Tspi_TPM_GetCapability(TSS_HTPM hTPM,TSS_FLAG capArea,UINT32 ulSubCapLength,BYTE * rgbSubCap,UINT32 * pulRespDataLength,BYTE ** prgbRespData)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
Tspi_TPM_GetCapabilitySigned(TSS_HTPM hTPM,TSS_HTPM hKey,TSS_FLAG capArea,UINT32 ulSubCapLength,BYTE * rgbSubCap,TSS_VALIDATION * pValidationData,UINT32 * pulRespDataLength,BYTE ** prgbRespData)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