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 
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_Data_Bind(TSS_HENCDATA hEncData,TSS_HKEY hEncKey,UINT32 ulDataLength,BYTE * rgbDataToBind)26 Tspi_Data_Bind(TSS_HENCDATA hEncData,	/* in */
27 	       TSS_HKEY hEncKey,	/* in */
28 	       UINT32 ulDataLength,	/* in */
29 	       BYTE *rgbDataToBind)	/* in */
30 {
31 	UINT32 encDataLength;
32 	BYTE encData[256];
33 	BYTE *keyData;
34 	UINT32 keyDataLength;
35 	TCPA_BOUND_DATA boundData;
36 	UINT64 offset;
37 	BYTE bdblob[256];
38 	TCPA_RESULT result;
39 	TSS_KEY keyContainer;
40 	TSS_HCONTEXT tspContext;
41 
42 	if (rgbDataToBind == NULL)
43 		return TSPERR(TSS_E_BAD_PARAMETER);
44 
45 	if (!obj_is_encdata(hEncData))
46 		return TSPERR(TSS_E_INVALID_HANDLE);
47 
48 	if ((result = obj_rsakey_get_tsp_context(hEncKey, &tspContext)))
49 		return result;
50 
51 	/* XXX Just get the pubkey here */
52 	if ((result = obj_rsakey_get_blob(hEncKey, &keyDataLength, &keyData)))
53 		return result;
54 
55 	offset = 0;
56 	if ((result = UnloadBlob_TSS_KEY(&offset, keyData, &keyContainer))) {
57 		free_tspi(tspContext, keyData);
58 		return result;
59 	}
60 	free_tspi(tspContext, keyData);
61 
62 	if (keyContainer.keyUsage != TPM_KEY_BIND &&
63 	    keyContainer.keyUsage != TPM_KEY_LEGACY) {
64 		result = TSPERR(TSS_E_INVALID_KEYUSAGE);
65 		goto done;
66 	}
67 
68 	if (keyContainer.pubKey.keyLength < ulDataLength) {
69 		result = TSPERR(TSS_E_ENC_INVALID_LENGTH);
70 		goto done;
71 	}
72 
73 	if (keyContainer.algorithmParms.encScheme == TCPA_ES_RSAESPKCSv15 &&
74 	    keyContainer.keyUsage == TPM_KEY_LEGACY) {
75 		if ((result = Trspi_RSA_PKCS15_Encrypt(rgbDataToBind, ulDataLength, encData,
76 						       &encDataLength, keyContainer.pubKey.key,
77 						       keyContainer.pubKey.keyLength)))
78 			goto done;
79 	} else if (keyContainer.algorithmParms.encScheme == TCPA_ES_RSAESPKCSv15 &&
80 		   keyContainer.keyUsage == TPM_KEY_BIND) {
81 		boundData.payload = TCPA_PT_BIND;
82 
83 		memcpy(&boundData.ver, &VERSION_1_1, sizeof(TCPA_VERSION));
84 
85 		boundData.payloadData = malloc(ulDataLength);
86 		if (boundData.payloadData == NULL) {
87 			result = TSPERR(TSS_E_OUTOFMEMORY);
88 			goto done;
89 		}
90 		memcpy(boundData.payloadData, rgbDataToBind, ulDataLength);
91 
92 		offset = 0;
93 		Trspi_LoadBlob_BOUND_DATA(&offset, boundData, ulDataLength, bdblob);
94 
95 		if ((result = Trspi_RSA_PKCS15_Encrypt(bdblob, offset, encData,
96 						       &encDataLength, keyContainer.pubKey.key,
97 						       keyContainer.pubKey.keyLength))) {
98 			free(boundData.payloadData);
99 			goto done;
100 		}
101 		free(boundData.payloadData);
102 	} else {
103 		boundData.payload = TCPA_PT_BIND;
104 
105 		memcpy(&boundData.ver, &VERSION_1_1, sizeof(TCPA_VERSION));
106 
107 		boundData.payloadData = malloc(ulDataLength);
108 		if (boundData.payloadData == NULL) {
109 			LogError("malloc of %u bytes failed.", ulDataLength);
110 			result = TSPERR(TSS_E_OUTOFMEMORY);
111 			goto done;
112 		}
113 		memcpy(boundData.payloadData, rgbDataToBind, ulDataLength);
114 
115 		offset = 0;
116 		Trspi_LoadBlob_BOUND_DATA(&offset, boundData, ulDataLength, bdblob);
117 
118 		if ((result = Trspi_RSA_Encrypt(bdblob, offset, encData, &encDataLength,
119 						keyContainer.pubKey.key,
120 						keyContainer.pubKey.keyLength))) {
121 			free(boundData.payloadData);
122 			goto done;
123 		}
124 
125 		free(boundData.payloadData);
126 	}
127 
128 	if ((result = obj_encdata_set_data(hEncData, encDataLength, encData))) {
129 		LogError("Error in calling SetAttribData on the encrypted data object.");
130 		result = TSPERR(TSS_E_INTERNAL_ERROR);
131 		goto done;
132 	}
133 done:
134 	free_key_refs(&keyContainer);
135 	return result;
136 }
137 
138 TSS_RESULT
Tspi_Data_Unbind(TSS_HENCDATA hEncData,TSS_HKEY hKey,UINT32 * pulUnboundDataLength,BYTE ** prgbUnboundData)139 Tspi_Data_Unbind(TSS_HENCDATA hEncData,		/* in */
140 		 TSS_HKEY hKey,			/* in */
141 		 UINT32 * pulUnboundDataLength,	/* out */
142 		 BYTE ** prgbUnboundData)	/* out */
143 {
144 	TCPA_RESULT result;
145 	TPM_AUTH privAuth;
146 	TCPA_DIGEST digest;
147 	TSS_HPOLICY hPolicy;
148 	BYTE *encData;
149 	UINT32 encDataSize;
150 	TCS_KEY_HANDLE tcsKeyHandle;
151 	TSS_BOOL usesAuth;
152 	TPM_AUTH *pPrivAuth;
153         TSS_HCONTEXT tspContext;
154 	Trspi_HashCtx hashCtx;
155 
156 	if (pulUnboundDataLength == NULL || prgbUnboundData == NULL)
157 		return TSPERR(TSS_E_BAD_PARAMETER);
158 
159 	if ((result = obj_encdata_get_tsp_context(hEncData, &tspContext)))
160 		return result;
161 
162 	if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth)))
163 		return result;
164 
165 	if ((result = obj_encdata_get_data(hEncData, &encDataSize, &encData)))
166 		return result == (TSS_E_INVALID_OBJ_ACCESS | TSS_LAYER_TSP) ?
167 		       TSPERR(TSS_E_ENC_NO_DATA) :
168 		       result;
169 
170 	if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle)))
171 		return result;
172 
173 	if (usesAuth) {
174 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
175 		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_UnBind);
176 		result |= Trspi_Hash_UINT32(&hashCtx, encDataSize);
177 		result |= Trspi_HashUpdate(&hashCtx, encDataSize, encData);
178 		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
179 			return result;
180 
181 		if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_UnBind, hPolicy, FALSE, &digest,
182 						      &privAuth)))
183 			return result;
184 		pPrivAuth = &privAuth;
185 	} else {
186 		pPrivAuth = NULL;
187 	}
188 
189 	if ((result = TCS_API(tspContext)->UnBind(tspContext, tcsKeyHandle, encDataSize, encData,
190 						  pPrivAuth, pulUnboundDataLength,
191 						  prgbUnboundData)))
192 		return result;
193 
194 	if (usesAuth) {
195 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
196 		result |= Trspi_Hash_UINT32(&hashCtx, result);
197 		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_UnBind);
198 		result |= Trspi_Hash_UINT32(&hashCtx, *pulUnboundDataLength);
199 		result |= Trspi_HashUpdate(&hashCtx, *pulUnboundDataLength, *prgbUnboundData);
200 		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
201 			goto error;
202 
203 		if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &privAuth)))
204 			goto error;
205 	}
206 
207 	if ((result = __tspi_add_mem_entry(tspContext, *prgbUnboundData)))
208 		goto error;
209 
210 	return TSS_SUCCESS;
211 error:
212 	free(*prgbUnboundData);
213 	*prgbUnboundData = NULL;
214 	*pulUnboundDataLength = 0;
215 	return result;
216 }
217 
218