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. 2007
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 "obj.h"
21 #include "tsplog.h"
22 #include "authsess.h"
23 
24 
25 #ifdef TSS_BUILD_SEALX
26 TSS_RESULT
sealx_mask_cb(PVOID lpAppData,TSS_HKEY hEncKey,TSS_HENCDATA hEncData,TSS_ALGORITHM_ID algId,UINT32 ulSizeNonces,BYTE * rgbNonceEven,BYTE * rgbNonceOdd,BYTE * rgbNonceEvenOSAP,BYTE * rgbNonceOddOSAP,UINT32 ulDataLength,BYTE * rgbDataToMask,BYTE * rgbMaskedData)27 sealx_mask_cb(PVOID lpAppData,
28 	      TSS_HKEY hEncKey,
29 	      TSS_HENCDATA hEncData,
30 	      TSS_ALGORITHM_ID algId,
31 	      UINT32 ulSizeNonces,
32 	      BYTE *rgbNonceEven,
33 	      BYTE *rgbNonceOdd,
34 	      BYTE *rgbNonceEvenOSAP,
35 	      BYTE *rgbNonceOddOSAP,
36 	      UINT32 ulDataLength,
37 	      BYTE *rgbDataToMask,
38 	      BYTE *rgbMaskedData)
39 {
40 	UINT32 mgf1SeedLen, sharedSecretLen = sizeof(TPM_DIGEST);
41 	BYTE *mgf1Seed, *mgf1Buffer;
42 	UINT32 i;
43 	TSS_RESULT result;
44 	struct authsess *sess = (struct authsess *)lpAppData;
45 
46 	mgf1SeedLen = (ulSizeNonces * 2) + strlen("XOR") + sharedSecretLen;
47 	if ((mgf1Seed = (BYTE *)calloc(1, mgf1SeedLen)) == NULL) {
48 		LogError("malloc of %u bytes failed.", mgf1SeedLen);
49 		return TSPERR(TSS_E_OUTOFMEMORY);
50 	}
51 	mgf1Buffer = mgf1Seed;
52 	memcpy(mgf1Buffer, rgbNonceEven, ulSizeNonces);
53 	mgf1Buffer += ulSizeNonces;
54 	memcpy(mgf1Buffer, rgbNonceOdd, ulSizeNonces);
55 	mgf1Buffer += ulSizeNonces;
56 	memcpy(mgf1Buffer, "XOR", strlen("XOR"));
57 	mgf1Buffer += strlen("XOR");
58 	memcpy(mgf1Buffer, sess->sharedSecret.digest, sharedSecretLen);
59 
60 	if ((result = Trspi_MGF1(TSS_HASH_SHA1, mgf1SeedLen, mgf1Seed, ulDataLength,
61 				 rgbMaskedData)))
62 		goto done;
63 
64 	for (i = 0; i < ulDataLength; i++)
65 		rgbMaskedData[i] ^= rgbDataToMask[i];
66 
67 done:
68 	free(mgf1Seed);
69 
70 	return result;
71 }
72 #endif
73 
74 #ifdef TSS_BUILD_TRANSPORT
75 TSS_RESULT
Transport_Seal(TSS_HCONTEXT tspContext,TCS_KEY_HANDLE keyHandle,TCPA_ENCAUTH * encAuth,UINT32 pcrInfoSize,BYTE * PcrInfo,UINT32 inDataSize,BYTE * inData,TPM_AUTH * pubAuth,UINT32 * SealedDataSize,BYTE ** SealedData)76 Transport_Seal(TSS_HCONTEXT tspContext,    /* in */
77 	       TCS_KEY_HANDLE keyHandle,   /* in */
78 	       TCPA_ENCAUTH *encAuth,       /* in */
79 	       UINT32 pcrInfoSize, /* in */
80 	       BYTE * PcrInfo,     /* in */
81 	       UINT32 inDataSize,  /* in */
82 	       BYTE * inData,      /* in */
83 	       TPM_AUTH * pubAuth, /* in, out */
84 	       UINT32 * SealedDataSize,    /* out */
85 	       BYTE ** SealedData) /* out */
86 {
87 	TSS_RESULT result;
88 	UINT32 handlesLen, decLen, dataLen;
89 	TCS_HANDLE *handles, handle;
90 	TPM_DIGEST pubKeyHash;
91 	Trspi_HashCtx hashCtx;
92 	UINT64 offset;
93 	BYTE *data, *dec;
94 
95 
96 	if ((result = obj_context_transport_init(tspContext)))
97 		return result;
98 
99 	LogDebugFn("Executing in a transport session");
100 
101 	if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest)))
102 		return result;
103 
104 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
105 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
106 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
107 		return result;
108 
109 	handlesLen = 1;
110 	handle = keyHandle;
111 	handles = &handle;
112 
113 	dataLen = (2 * sizeof(UINT32)) + sizeof(TPM_ENCAUTH) + pcrInfoSize + inDataSize;
114 	if ((data = malloc(dataLen)) == NULL) {
115 		LogError("malloc of %u bytes failed", dataLen);
116 		return TSPERR(TSS_E_OUTOFMEMORY);
117 	}
118 
119 	offset = 0;
120 	Trspi_LoadBlob_DIGEST(&offset, data, (TPM_DIGEST *)encAuth);
121 	Trspi_LoadBlob_UINT32(&offset, pcrInfoSize, data);
122 	Trspi_LoadBlob(&offset, pcrInfoSize, data, PcrInfo);
123 	Trspi_LoadBlob_UINT32(&offset, inDataSize, data);
124 	Trspi_LoadBlob(&offset, inDataSize, data, inData);
125 
126 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Seal, dataLen, data,
127 						    &pubKeyHash, &handlesLen, &handles, pubAuth,
128 						    NULL, &decLen, &dec)))
129 		return result;
130 
131 	*SealedDataSize = decLen;
132 	*SealedData = dec;
133 
134 	return result;
135 }
136 
137 TSS_RESULT
Transport_Sealx(TSS_HCONTEXT tspContext,TCS_KEY_HANDLE keyHandle,TCPA_ENCAUTH * encAuth,UINT32 pcrInfoSize,BYTE * PcrInfo,UINT32 inDataSize,BYTE * inData,TPM_AUTH * pubAuth,UINT32 * SealedDataSize,BYTE ** SealedData)138 Transport_Sealx(TSS_HCONTEXT tspContext,   /* in */
139 		TCS_KEY_HANDLE keyHandle,  /* in */
140 		TCPA_ENCAUTH *encAuth,      /* in */
141 		UINT32 pcrInfoSize,        /* in */
142 		BYTE * PcrInfo,    /* in */
143 		UINT32 inDataSize, /* in */
144 		BYTE * inData,     /* in */
145 		TPM_AUTH * pubAuth,        /* in, out */
146 		UINT32 * SealedDataSize,   /* out */
147 		BYTE ** SealedData)        /* out */
148 {
149 	TSS_RESULT result;
150 	UINT32 handlesLen, decLen, dataLen;
151 	TCS_HANDLE *handles, handle;
152 	TPM_DIGEST pubKeyHash;
153 	Trspi_HashCtx hashCtx;
154 	UINT64 offset;
155 	BYTE *data, *dec;
156 
157 
158 	if ((result = obj_context_transport_init(tspContext)))
159 		return result;
160 
161 	LogDebugFn("Executing in a transport session");
162 
163 	if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest)))
164 		return result;
165 
166 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
167 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
168 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
169 		return result;
170 
171 	handlesLen = 1;
172 	handle = keyHandle;
173 	handles = &handle;
174 
175 	dataLen = (2 * sizeof(UINT32)) + sizeof(TPM_ENCAUTH) + pcrInfoSize + inDataSize;
176 	if ((data = malloc(dataLen)) == NULL) {
177 		LogError("malloc of %u bytes failed", dataLen);
178 		return TSPERR(TSS_E_OUTOFMEMORY);
179 	}
180 
181 	offset = 0;
182 	Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, encAuth->authdata);
183 	Trspi_LoadBlob_UINT32(&offset, pcrInfoSize, data);
184 	Trspi_LoadBlob(&offset, pcrInfoSize, data, PcrInfo);
185 	Trspi_LoadBlob_UINT32(&offset, inDataSize, data);
186 	Trspi_LoadBlob(&offset, inDataSize, data, inData);
187 
188 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Sealx, dataLen, data,
189 						    &pubKeyHash, &handlesLen, &handles, pubAuth,
190 						    NULL, &decLen, &dec)))
191 		return result;
192 
193 	*SealedDataSize = decLen;
194 	*SealedData = dec;
195 
196 	return result;
197 }
198 
199 TSS_RESULT
Transport_Unseal(TSS_HCONTEXT tspContext,TCS_KEY_HANDLE parentHandle,UINT32 SealedDataSize,BYTE * SealedData,TPM_AUTH * parentAuth,TPM_AUTH * dataAuth,UINT32 * DataSize,BYTE ** Data)200 Transport_Unseal(TSS_HCONTEXT tspContext,  /* in */
201 		 TCS_KEY_HANDLE parentHandle,      /* in */
202 		 UINT32 SealedDataSize,    /* in */
203 		 BYTE * SealedData,        /* in */
204 		 TPM_AUTH * parentAuth,    /* in, out */
205 		 TPM_AUTH * dataAuth,      /* in, out */
206 		 UINT32 * DataSize,        /* out */
207 		 BYTE ** Data)     /* out */
208 {
209 	UINT64 offset;
210 	TSS_RESULT result;
211 	UINT32 handlesLen, decLen;
212 	TCS_HANDLE *handles, handle;
213 	TPM_DIGEST pubKeyHash;
214 	Trspi_HashCtx hashCtx;
215 	BYTE *dec;
216 
217 
218 	if ((result = obj_context_transport_init(tspContext)))
219 		return result;
220 
221 	LogDebugFn("Executing in a transport session");
222 
223 	if ((result = obj_tcskey_get_pubkeyhash(parentHandle, pubKeyHash.digest)))
224 		return result;
225 
226 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
227 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
228 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
229 		return result;
230 
231 	handlesLen = 1;
232 	handle = parentHandle;
233 	handles = &handle;
234 
235 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Unseal, SealedDataSize,
236 						    SealedData, &pubKeyHash, &handlesLen, &handles,
237 						    parentAuth, dataAuth, &decLen, &dec)))
238 		return result;
239 
240 	offset = 0;
241 	Trspi_UnloadBlob_UINT32(&offset, DataSize, dec);
242 
243 	if ((*Data = malloc(*DataSize)) == NULL) {
244 		free(dec);
245 		LogError("malloc of %u bytes failed", *DataSize);
246 		return TSPERR(TSS_E_OUTOFMEMORY);
247 	}
248 	Trspi_UnloadBlob(&offset, *DataSize, dec, *Data);
249 
250 	free(dec);
251 
252 	return result;
253 }
254 #endif
255