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