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-2007
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 #ifdef TSS_BUILD_TRANSPORT
25 TSS_RESULT
Transport_CreateMigrationBlob(TSS_HCONTEXT tspContext,TCS_KEY_HANDLE parentHandle,TCPA_MIGRATE_SCHEME migrationType,UINT32 MigrationKeyAuthSize,BYTE * MigrationKeyAuth,UINT32 encDataSize,BYTE * encData,TPM_AUTH * parentAuth,TPM_AUTH * entityAuth,UINT32 * randomSize,BYTE ** random,UINT32 * outDataSize,BYTE ** outData)26 Transport_CreateMigrationBlob(TSS_HCONTEXT tspContext,	/* in */
27 			      TCS_KEY_HANDLE parentHandle,	/* in */
28 			      TCPA_MIGRATE_SCHEME migrationType,	/* in */
29 			      UINT32 MigrationKeyAuthSize,	/* in */
30 			      BYTE * MigrationKeyAuth,	/* in */
31 			      UINT32 encDataSize,	/* in */
32 			      BYTE * encData,	/* in */
33 			      TPM_AUTH * parentAuth,	/* in, out */
34 			      TPM_AUTH * entityAuth,	/* in, out */
35 			      UINT32 * randomSize,	/* out */
36 			      BYTE ** random,	/* out */
37 			      UINT32 * outDataSize,	/* out */
38 			      BYTE ** outData)	/* out */
39 {
40 	UINT64 offset;
41 	TSS_RESULT result;
42 	UINT32 handlesLen, dataLen, decLen;
43 	TCS_HANDLE *handles, handle;
44 	TPM_DIGEST pubKeyHash;
45 	Trspi_HashCtx hashCtx;
46 	BYTE *data, *dec;
47 
48 
49 	if ((result = obj_context_transport_init(tspContext)))
50 		return result;
51 
52 	LogDebugFn("Executing in a transport session");
53 
54 	if ((result = obj_tcskey_get_pubkeyhash(parentHandle, pubKeyHash.digest)))
55 		return result;
56 
57 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
58 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
59 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
60 		return result;
61 
62 	handlesLen = 1;
63 	handle = parentHandle;
64 	handles = &handle;
65 
66 	dataLen = sizeof(TCPA_MIGRATE_SCHEME)
67 		  + MigrationKeyAuthSize
68 		  + sizeof(UINT32)
69 		  + encDataSize;
70 	if ((data = malloc(dataLen)) == NULL) {
71 		LogError("malloc of %u bytes failed", dataLen);
72 		return TSPERR(TSS_E_OUTOFMEMORY);
73 	}
74 
75 	offset = 0;
76 	Trspi_LoadBlob_UINT16(&offset, migrationType, data);
77 	Trspi_LoadBlob(&offset, MigrationKeyAuthSize, data, MigrationKeyAuth);
78 	Trspi_LoadBlob_UINT32(&offset, encDataSize, data);
79 	Trspi_LoadBlob(&offset, encDataSize, data, encData);
80 
81 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_CreateMigrationBlob,
82 						    dataLen, data, &pubKeyHash, &handlesLen,
83 						    &handles, parentAuth, entityAuth, &decLen,
84 						    &dec))) {
85 		free(data);
86 		return result;
87 	}
88 	free(data);
89 
90 	offset = 0;
91 	Trspi_UnloadBlob_UINT32(&offset, randomSize, dec);
92 
93 	if ((*random = malloc(*randomSize)) == NULL) {
94 		free(dec);
95 		LogError("malloc of %u bytes failed", *randomSize);
96 		*randomSize = 0;
97 		return TSPERR(TSS_E_OUTOFMEMORY);
98 	}
99 	Trspi_UnloadBlob(&offset, *randomSize, dec, *random);
100 
101 	Trspi_UnloadBlob_UINT32(&offset, outDataSize, dec);
102 
103 	if ((*outData = malloc(*outDataSize)) == NULL) {
104 		free(*random);
105 		*random = NULL;
106 		*randomSize = 0;
107 		free(dec);
108 		LogError("malloc of %u bytes failed", *outDataSize);
109 		*outDataSize = 0;
110 		return TSPERR(TSS_E_OUTOFMEMORY);
111 	}
112 	Trspi_UnloadBlob(&offset, *outDataSize, dec, *outData);
113 	free(dec);
114 
115 	return result;
116 }
117 
118 TSS_RESULT
Transport_ConvertMigrationBlob(TSS_HCONTEXT tspContext,TCS_KEY_HANDLE parentHandle,UINT32 inDataSize,BYTE * inData,UINT32 randomSize,BYTE * random,TPM_AUTH * parentAuth,UINT32 * outDataSize,BYTE ** outData)119 Transport_ConvertMigrationBlob(TSS_HCONTEXT tspContext,	/* in */
120 			       TCS_KEY_HANDLE parentHandle,	/* in */
121 			       UINT32 inDataSize,	/* in */
122 			       BYTE * inData,	/* in */
123 			       UINT32 randomSize,	/* in */
124 			       BYTE * random,	/* in */
125 			       TPM_AUTH * parentAuth,	/* in, out */
126 			       UINT32 * outDataSize,	/* out */
127 			       BYTE ** outData)	/* out */
128 {
129 	UINT64 offset;
130 	TSS_RESULT result;
131 	UINT32 handlesLen, dataLen, decLen;
132 	TCS_HANDLE *handles, handle;
133 	TPM_DIGEST pubKeyHash;
134 	Trspi_HashCtx hashCtx;
135 	BYTE *data, *dec;
136 
137 
138 	if ((result = obj_context_transport_init(tspContext)))
139 		return result;
140 
141 	LogDebugFn("Executing in a transport session");
142 
143 	if ((result = obj_tcskey_get_pubkeyhash(parentHandle, pubKeyHash.digest)))
144 		return result;
145 
146 	result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
147 	result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
148 	if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
149 		return result;
150 
151 	handlesLen = 1;
152 	handle = parentHandle;
153 	handles = &handle;
154 
155 	dataLen = (2 * sizeof(UINT32)) + randomSize + inDataSize;
156 	if ((data = malloc(dataLen)) == NULL) {
157 		LogError("malloc of %u bytes failed", dataLen);
158 		return TSPERR(TSS_E_OUTOFMEMORY);
159 	}
160 
161 	offset = 0;
162 	Trspi_LoadBlob_UINT32(&offset, inDataSize, data);
163 	Trspi_LoadBlob(&offset, inDataSize, data, inData);
164 	Trspi_LoadBlob_UINT32(&offset, randomSize, data);
165 	Trspi_LoadBlob(&offset, randomSize, data, random);
166 
167 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_ConvertMigrationBlob,
168 						    dataLen, data, &pubKeyHash, &handlesLen,
169 						    &handles, parentAuth, NULL, &decLen, &dec))) {
170 		free(data);
171 		return result;
172 	}
173 	free(data);
174 
175 	offset = 0;
176 	Trspi_UnloadBlob_UINT32(&offset, outDataSize, dec);
177 
178 	if ((*outData = malloc(*outDataSize)) == NULL) {
179 		free(dec);
180 		LogError("malloc of %u bytes failed", *outDataSize);
181 		*outDataSize = 0;
182 		return TSPERR(TSS_E_OUTOFMEMORY);
183 	}
184 	Trspi_UnloadBlob(&offset, *outDataSize, dec, *outData);
185 	free(dec);
186 
187 	return result;
188 }
189 
190 TSS_RESULT
Transport_AuthorizeMigrationKey(TSS_HCONTEXT tspContext,TCPA_MIGRATE_SCHEME migrateScheme,UINT32 MigrationKeySize,BYTE * MigrationKey,TPM_AUTH * ownerAuth,UINT32 * MigrationKeyAuthSize,BYTE ** MigrationKeyAuth)191 Transport_AuthorizeMigrationKey(TSS_HCONTEXT tspContext,	/* in */
192 				TCPA_MIGRATE_SCHEME migrateScheme,	/* in */
193 				UINT32 MigrationKeySize,	/* in */
194 				BYTE * MigrationKey,	/* in */
195 				TPM_AUTH * ownerAuth,	/* in, out */
196 				UINT32 * MigrationKeyAuthSize,	/* out */
197 				BYTE ** MigrationKeyAuth)	/* out */
198 {
199 	UINT64 offset;
200 	UINT16 tpmMigrateScheme;
201 	TSS_RESULT result;
202 	UINT32 handlesLen = 0, dataLen, decLen;
203 	BYTE *data, *dec;
204 
205 
206 	if ((result = obj_context_transport_init(tspContext)))
207 		return result;
208 
209 	LogDebugFn("Executing in a transport session");
210 
211 	/* The TSS_MIGRATE_SCHEME must be changed to a TPM_MIGRATE_SCHEME here, since the TCS
212 	 * expects a TSS migrate scheme, but this could be wrapped by the TSP before it gets to the
213 	 * TCS. */
214 	switch (migrateScheme) {
215 		case TSS_MS_MIGRATE:
216 			tpmMigrateScheme = TCPA_MS_MIGRATE;
217 			break;
218 		case TSS_MS_REWRAP:
219 			tpmMigrateScheme = TCPA_MS_REWRAP;
220 			break;
221 		case TSS_MS_MAINT:
222 			tpmMigrateScheme = TCPA_MS_MAINT;
223 			break;
224 #ifdef TSS_BUILD_CMK
225 		case TSS_MS_RESTRICT_MIGRATE:
226 			tpmMigrateScheme = TPM_MS_RESTRICT_MIGRATE;
227 			break;
228 
229 		case TSS_MS_RESTRICT_APPROVE_DOUBLE:
230 			tpmMigrateScheme = TPM_MS_RESTRICT_APPROVE_DOUBLE;
231 			break;
232 #endif
233 		default:
234 			return TSPERR(TSS_E_BAD_PARAMETER);
235 			break;
236 	}
237 
238 	dataLen = sizeof(TCPA_MIGRATE_SCHEME) + MigrationKeySize;
239 	if ((data = malloc(dataLen)) == NULL) {
240 		LogError("malloc of %u bytes failed", dataLen);
241 		return TSPERR(TSS_E_OUTOFMEMORY);
242 	}
243 
244 	offset = 0;
245 	Trspi_LoadBlob_UINT16(&offset, tpmMigrateScheme, data);
246 	Trspi_LoadBlob(&offset, MigrationKeySize, data, MigrationKey);
247 
248 	if ((result = obj_context_transport_execute(tspContext, TPM_ORD_AuthorizeMigrationKey,
249 						    dataLen, data, NULL, &handlesLen, NULL,
250 						    ownerAuth, NULL, &decLen, &dec))) {
251 		free(data);
252 		return result;
253 	}
254 	free(data);
255 
256 	*MigrationKeyAuthSize = decLen;
257 	*MigrationKeyAuth = dec;
258 
259 	return result;
260 }
261 
262 #endif
263 
264