xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/tspi/tsp_caps_tpm.c (revision 2d5f7628c5531eb583b9313ac2fd1cf8582b4479)
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. 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 /*
26  * This function provides a funnel through which all the TCSP_SetCapability requests can be
27  * sent.  This will keep the owner auth code from being duplicated around the TSP.
28  */
29 TSS_RESULT
TSP_SetCapability(TSS_HCONTEXT tspContext,TSS_HTPM hTPM,TSS_HPOLICY hTPMPolicy,TPM_CAPABILITY_AREA tcsCapArea,UINT32 subCap,TSS_BOOL value)30 TSP_SetCapability(TSS_HCONTEXT tspContext,
31 		  TSS_HTPM hTPM,
32 		  TSS_HPOLICY hTPMPolicy,
33 		  TPM_CAPABILITY_AREA tcsCapArea,
34 		  UINT32 subCap,
35 		  TSS_BOOL value)
36 {
37 	TSS_RESULT result;
38 	Trspi_HashCtx hashCtx;
39 	TPM_DIGEST digest;
40 	TPM_AUTH auth;
41 
42 	subCap = endian32(subCap);
43 
44 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
45 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetCapability);
46 	result |= Trspi_Hash_UINT32(&hashCtx, tcsCapArea);
47 	result |= Trspi_Hash_UINT32(&hashCtx, (UINT32)sizeof(UINT32));
48 	result |= Trspi_HashUpdate(&hashCtx, (UINT32)sizeof(UINT32), (BYTE *)&subCap);
49 	result |= Trspi_Hash_UINT32(&hashCtx, (UINT32)sizeof(TSS_BOOL));
50 	result |= Trspi_Hash_BOOL(&hashCtx, value);
51 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
52 		return result;
53 
54 	if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_SetCapability, hTPMPolicy, FALSE,
55 					      &digest, &auth)))
56 		return result;
57 
58 	if ((result = TCS_API(tspContext)->SetCapability(tspContext, tcsCapArea, sizeof(UINT32),
59 							 (BYTE *)&subCap, sizeof(TSS_BOOL),
60 							 (BYTE *)&value, &auth)))
61 		return result;
62 
63 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
64 	result |= Trspi_Hash_UINT32(&hashCtx, result);
65 	result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetCapability);
66 	if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
67 		return result;
68 
69 	return obj_policy_validate_auth_oiap(hTPMPolicy, &digest, &auth);
70 }
71 
72 #ifdef TSS_BUILD_TRANSPORT
73 TSS_RESULT
Transport_GetTPMCapability(TSS_HCONTEXT tspContext,TPM_CAPABILITY_AREA capArea,UINT32 subCapLen,BYTE * subCap,UINT32 * respLen,BYTE ** resp)74 Transport_GetTPMCapability(TSS_HCONTEXT        tspContext,	/* in */
75 			   TPM_CAPABILITY_AREA capArea,	/* in */
76 			   UINT32              subCapLen,	/* in */
77 			   BYTE*               subCap,	/* in */
78 			   UINT32*             respLen,	/* out */
79 			   BYTE**              resp)	/* out */
80 {
81 	TSS_RESULT result;
82 	UINT32 decLen = 0, dataLen;
83 	BYTE *dec = NULL;
84 	UINT64 offset;
85 	TCS_HANDLE handlesLen = 0;
86 	BYTE *data;
87 
88 	if ((result = obj_context_transport_init(tspContext)))
89 		return result;
90 
91 	LogDebugFn("Executing in a transport session");
92 
93 	dataLen = (2 * sizeof(UINT32)) + subCapLen;
94 	if ((data = malloc(dataLen)) == NULL) {
95 		LogError("malloc of %u bytes failed", dataLen);
96 		return TSPERR(TSS_E_OUTOFMEMORY);
97 	}
98 
99 	offset = 0;
100 	Trspi_LoadBlob_UINT32(&offset, capArea, data);
101 	Trspi_LoadBlob_UINT32(&offset, subCapLen, data);
102 	Trspi_LoadBlob(&offset, subCapLen, data, subCap);
103 
104 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetCapability, dataLen,
105 						    data, NULL, &handlesLen, NULL, NULL, NULL,
106 						    &decLen, &dec))) {
107 		free(data);
108 		return result;
109 	}
110 	free(data);
111 
112 	offset = 0;
113 	Trspi_UnloadBlob_UINT32(&offset, respLen, dec);
114 
115 	if ((*resp = malloc(*respLen)) == NULL) {
116 		free(dec);
117 		LogError("malloc of %u bytes failed", *respLen);
118 		return TSPERR(TSS_E_OUTOFMEMORY);
119 	}
120 
121 	Trspi_UnloadBlob(&offset, *respLen, dec, *resp);
122 	free(dec);
123 
124 	return result;
125 
126 }
127 
128 TSS_RESULT
Transport_SetCapability(TSS_HCONTEXT tspContext,TCPA_CAPABILITY_AREA capArea,UINT32 subCapSize,BYTE * subCap,UINT32 valueSize,BYTE * value,TPM_AUTH * ownerAuth)129 Transport_SetCapability(TSS_HCONTEXT tspContext,	/* in */
130 			TCPA_CAPABILITY_AREA capArea,	/* in */
131 			UINT32 subCapSize,	/* in */
132 			BYTE * subCap,	/* in */
133 			UINT32 valueSize,	/* in */
134 			BYTE * value,	/* in */
135 			TPM_AUTH *ownerAuth) /* in, out */
136 {
137 	TSS_RESULT result;
138 	UINT32 dataLen;
139 	UINT64 offset;
140 	TCS_HANDLE handlesLen = 0;
141 	BYTE *data;
142 
143 	if ((result = obj_context_transport_init(tspContext)))
144 		return result;
145 
146 	LogDebugFn("Executing in a transport session");
147 
148 	dataLen = (3 * sizeof(UINT32)) + subCapSize + valueSize;
149 	if ((data = malloc(dataLen)) == NULL) {
150 		LogError("malloc of %u bytes failed", dataLen);
151 		return TSPERR(TSS_E_OUTOFMEMORY);
152 	}
153 
154 	offset = 0;
155 	Trspi_LoadBlob_UINT32(&offset, capArea, data);
156 	Trspi_LoadBlob_UINT32(&offset, subCapSize, data);
157 	Trspi_LoadBlob(&offset, subCapSize, data, subCap);
158 	Trspi_LoadBlob_UINT32(&offset, valueSize, data);
159 	Trspi_LoadBlob(&offset, valueSize, data, value);
160 
161 	result = obj_context_transport_execute(tspContext, TPM_ORD_SetCapability, dataLen, data,
162 					       NULL, &handlesLen, NULL, NULL, NULL, NULL, NULL);
163 
164 	free(data);
165 	return result;
166 }
167 #endif
168