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