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
8 *
9 */
10
11
12#include <stdlib.h>
13#include <stdio.h>
14#include <string.h>
15#include <inttypes.h>
16
17#include "trousers/tss.h"
18#include "trousers_types.h"
19#include "tcs_tsp.h"
20#include "tcsps.h"
21#include "tcs_utils.h"
22#include "tcs_int_literals.h"
23#include "capabilities.h"
24#include "tcslog.h"
25#include "tcsd_wrap.h"
26#include "tcsd.h"
27
28extern struct tcsd_config tcsd_options;
29
30TSS_RESULT
31internal_TCSGetCap(TCS_CONTEXT_HANDLE hContext,
32		   TCPA_CAPABILITY_AREA capArea,
33		   UINT32 subCap,
34		   UINT32 * respSize, BYTE ** resp)
35{
36	UINT32 u32value = 0;
37	UINT64 offset;
38	TPM_VERSION tcsVersion = INTERNAL_CAP_VERSION;
39	struct tcsd_config *config = &tcsd_options;
40	struct platform_class *platClass;
41	TSS_BOOL bValue = FALSE;
42
43	LogDebug("Checking Software Cap of TCS");
44	switch (capArea) {
45	case TSS_TCSCAP_ALG:
46		LogDebug("TSS_TCSCAP_ALG");
47
48		switch (subCap) {
49		case TSS_ALG_RSA:
50			*respSize = sizeof(TSS_BOOL);
51			bValue = INTERNAL_CAP_TCS_ALG_RSA;
52			break;
53		case TSS_ALG_DES:
54			*respSize = sizeof(TSS_BOOL);
55			bValue = INTERNAL_CAP_TCS_ALG_DES;
56			break;
57		case TSS_ALG_3DES:
58			*respSize = sizeof(TSS_BOOL);
59			bValue = INTERNAL_CAP_TCS_ALG_3DES;
60			break;
61		case TSS_ALG_SHA:
62			*respSize = sizeof(TSS_BOOL);
63			bValue = INTERNAL_CAP_TCS_ALG_SHA;
64			break;
65		case TSS_ALG_AES:
66			*respSize = sizeof(TSS_BOOL);
67			bValue = INTERNAL_CAP_TCS_ALG_AES;
68			break;
69		case TSS_ALG_HMAC:
70			*respSize = sizeof(TSS_BOOL);
71			bValue = INTERNAL_CAP_TCS_ALG_HMAC;
72			break;
73		case TSS_ALG_DEFAULT:
74			*respSize = sizeof(UINT32);
75			u32value = INTERNAL_CAP_TCS_ALG_DEFAULT;
76			break;
77		case TSS_ALG_DEFAULT_SIZE:
78			*respSize = sizeof(UINT32);
79			u32value = INTERNAL_CAP_TCS_ALG_DEFAULT_SIZE;
80			break;
81		default:
82			*respSize = 0;
83			LogDebugFn("Bad subcap");
84			return TCSERR(TSS_E_BAD_PARAMETER);
85		}
86
87		if ((*resp = malloc(*respSize)) == NULL) {
88			LogError("malloc of %u bytes failed.", *respSize);
89			*respSize = 0;
90			return TCSERR(TSS_E_OUTOFMEMORY);
91		}
92
93		offset = 0;
94		if (*respSize == sizeof(TSS_BOOL))
95			*(TSS_BOOL *)(*resp) = bValue;
96		else
97			*(UINT32 *)(*resp) = u32value;
98		break;
99	case TSS_TCSCAP_VERSION:
100		LogDebug("TSS_TCSCAP_VERSION");
101		if ((*resp = calloc(1, sizeof(TSS_VERSION))) == NULL) {
102			LogError("malloc of %zd bytes failed.", sizeof(TSS_VERSION));
103			return TCSERR(TSS_E_OUTOFMEMORY);
104		}
105		offset = 0;
106		LoadBlob_VERSION(&offset, *resp, &tcsVersion);
107		*respSize = sizeof(TSS_VERSION);
108		break;
109	case TSS_TCSCAP_PERSSTORAGE:
110		LogDebug("TSS_TCSCAP_PERSSTORAGE");
111		if ((*resp = malloc(sizeof(TSS_BOOL))) == NULL) {
112			LogError("malloc of %zd byte failed.", sizeof(TSS_BOOL));
113			return TCSERR(TSS_E_OUTOFMEMORY);
114		}
115		*(TSS_BOOL *)(*resp) = INTERNAL_CAP_TCS_PERSSTORAGE;
116		*respSize = sizeof(TSS_BOOL);
117		break;
118	case TSS_TCSCAP_CACHING:
119		LogDebug("TSS_TCSCAP_CACHING");
120
121		if (subCap == TSS_TCSCAP_PROP_KEYCACHE)
122			bValue = INTERNAL_CAP_TCS_CACHING_KEYCACHE;
123		else if (subCap == TSS_TCSCAP_PROP_AUTHCACHE)
124			bValue = INTERNAL_CAP_TCS_CACHING_AUTHCACHE;
125		else {
126			LogDebugFn("Bad subcap");
127			return TCSERR(TSS_E_BAD_PARAMETER);
128		}
129
130		if ((*resp = malloc(sizeof(TSS_BOOL))) == NULL) {
131			LogError("malloc of %zd byte failed.", sizeof(TSS_BOOL));
132			return TCSERR(TSS_E_OUTOFMEMORY);
133		}
134		*respSize = sizeof(TSS_BOOL);
135		*(TSS_BOOL *)(*resp) = bValue;
136		break;
137	case TSS_TCSCAP_MANUFACTURER:
138		if (subCap == TSS_TCSCAP_PROP_MANUFACTURER_ID) {
139			if ((*resp = malloc(sizeof(UINT32))) == NULL) {
140				LogError("malloc of %zd byte failed.", sizeof(UINT32));
141				return TCSERR(TSS_E_OUTOFMEMORY);
142			}
143			*(UINT32 *)(*resp) = INTERNAL_CAP_MANUFACTURER_ID;
144			*respSize = sizeof(UINT32);
145		} else if (subCap == TSS_TCSCAP_PROP_MANUFACTURER_STR) {
146			BYTE str[] = INTERNAL_CAP_MANUFACTURER_STR;
147
148			if ((*resp = malloc(INTERNAL_CAP_MANUFACTURER_STR_LEN)) == NULL) {
149				LogError("malloc of %d bytes failed.",
150					 INTERNAL_CAP_MANUFACTURER_STR_LEN);
151				return TCSERR(TSS_E_OUTOFMEMORY);
152			}
153			memcpy(*resp, str, INTERNAL_CAP_MANUFACTURER_STR_LEN);
154			*respSize = INTERNAL_CAP_MANUFACTURER_STR_LEN;
155		} else {
156			LogDebugFn("Bad subcap");
157			return TCSERR(TSS_E_BAD_PARAMETER);
158		}
159		break;
160	case TSS_TCSCAP_TRANSPORT:
161		/* A zero value here means the TSP is asking whether we support transport sessions
162		 * at all */
163		if (subCap == TSS_TCSCAP_TRANS_EXCLUSIVE || subCap == 0) {
164			*respSize = sizeof(TSS_BOOL);
165			if ((*resp = malloc(sizeof(TSS_BOOL))) == NULL) {
166				LogError("malloc of %zd byte failed.", sizeof(TSS_BOOL));
167				return TCSERR(TSS_E_OUTOFMEMORY);
168			}
169
170			if (subCap == TSS_TCSCAP_TRANS_EXCLUSIVE)
171				*(TSS_BOOL *)(*resp) = config->exclusive_transport ? TRUE : FALSE;
172			else
173				*(TSS_BOOL *)(*resp) = TRUE;
174		} else {
175			LogDebugFn("Bad subcap");
176			return TCSERR(TSS_E_BAD_PARAMETER);
177		}
178		break;
179	case TSS_TCSCAP_PLATFORM_CLASS:
180		LogDebug("TSS_TCSCAP_PLATFORM_CLASS");
181
182		switch (subCap) {
183		case TSS_TCSCAP_PROP_HOST_PLATFORM:
184			/* Return the TSS_PLATFORM_CLASS */
185			LogDebugFn("TSS_TCSCAP_PROP_HOST_PLATFORM");
186			platClass = config->host_platform_class;
187			/* Computes the size of host platform structure */
188			*respSize = (2 * sizeof(UINT32)) + platClass->classURISize;
189			*resp = malloc(*respSize);
190			if (*resp == NULL) {
191				LogError("malloc of %u bytes failed.", *respSize);
192				return TCSERR(TSS_E_OUTOFMEMORY);
193			}
194			memset(*resp, 0, *respSize);
195			offset = 0;
196			LoadBlob_UINT32(&offset, platClass->simpleID, *resp);
197			LoadBlob_UINT32(&offset, platClass->classURISize, *resp);
198			memcpy(&(*resp)[offset], platClass->classURI, platClass->classURISize);
199			LogBlob(*respSize, *resp);
200			break;
201		case TSS_TCSCAP_PROP_ALL_PLATFORMS:
202			/* Return an array of TSS_PLATFORM_CLASSes, when existent */
203			LogDebugFn("TSS_TCSCAP_PROP_ALL_PLATFORMS");
204			*respSize = 0;
205			*resp = NULL;
206			if ((platClass = config->all_platform_classes) != NULL) {
207				/* Computes the size of all Platform Structures */
208				while (platClass != NULL) {
209					*respSize += (2 * sizeof(UINT32)) + platClass->classURISize;
210					platClass = platClass->next;
211				}
212				*resp = malloc(*respSize);
213				if (*resp == NULL) {
214					LogError("malloc of %u bytes failed.", *respSize);
215					return TCSERR(TSS_E_OUTOFMEMORY);
216				}
217				memset(*resp, 0, *respSize);
218				offset = 0;
219				/* Concatenates all the structures on the BYTE * resp */
220				platClass = config->all_platform_classes;
221				while (platClass != NULL){
222					LoadBlob_UINT32(&offset, platClass->simpleID, *resp);
223					LoadBlob_UINT32(&offset, platClass->classURISize, *resp);
224					memcpy(&(*resp)[offset], platClass->classURI,
225					       platClass->classURISize);
226					offset += platClass->classURISize;
227					platClass = platClass->next;
228				}
229				LogBlob(*respSize, *resp);
230			}
231			break;
232		default:
233			LogDebugFn("Bad subcap");
234			return TCSERR(TSS_E_BAD_PARAMETER);
235		}
236		break;
237	default:
238		LogDebugFn("Bad cap area");
239		return TCSERR(TSS_E_BAD_PARAMETER);
240	}
241
242	return TSS_SUCCESS;
243}
244
245TSS_RESULT
246TCS_GetCapability_Internal(TCS_CONTEXT_HANDLE hContext,	/* in */
247			   TCPA_CAPABILITY_AREA capArea,	/* in */
248			   UINT32 subCapSize,	/* in */
249			   BYTE * subCap,	/* in */
250			   UINT32 * respSize,	/* out */
251			   BYTE ** resp	/* out */
252    )
253{
254	TSS_RESULT result;
255	UINT32 ulSubCap;
256
257	if ((result = ctx_verify_context(hContext)))
258		return result;
259
260	if (subCapSize == sizeof(UINT32))
261		ulSubCap = *(UINT32 *)subCap;
262	else if (subCapSize == 0)
263		ulSubCap = 0;
264	else
265		return TCSERR(TSS_E_BAD_PARAMETER);
266
267	return internal_TCSGetCap(hContext, capArea, ulSubCap, respSize, resp);
268}
269
270