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
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include "trousers/tss.h"
16 #include "trousers/trousers.h"
17 #include "trousers_types.h"
18 #include "spi_utils.h"
19 #include "capabilities.h"
20 #include "tsplog.h"
21 #include "obj.h"
22
23
24 void
free_key_refs(TSS_KEY * key)25 free_key_refs(TSS_KEY *key)
26 {
27 free(key->algorithmParms.parms);
28 key->algorithmParms.parms = NULL;
29 key->algorithmParms.parmSize = 0;
30
31 free(key->pubKey.key);
32 key->pubKey.key = NULL;
33 key->pubKey.keyLength = 0;
34
35 free(key->encData);
36 key->encData = NULL;
37 key->encSize = 0;
38
39 free(key->PCRInfo);
40 key->PCRInfo = NULL;
41 key->PCRInfoSize = 0;
42 }
43
44 void
LoadBlob_TSS_KEY(UINT64 * offset,BYTE * blob,TSS_KEY * key)45 LoadBlob_TSS_KEY(UINT64 *offset, BYTE *blob, TSS_KEY *key)
46 {
47 if (key->hdr.key12.tag == TPM_TAG_KEY12)
48 Trspi_LoadBlob_KEY12(offset, blob, (TPM_KEY12 *)key);
49 else
50 Trspi_LoadBlob_KEY(offset, blob, (TCPA_KEY *)key);
51 }
52
53 TSS_RESULT
UnloadBlob_TSS_KEY(UINT64 * offset,BYTE * blob,TSS_KEY * key)54 UnloadBlob_TSS_KEY(UINT64 *offset, BYTE *blob, TSS_KEY *key)
55 {
56 UINT16 tag;
57 UINT64 keyOffset = *offset;
58 TSS_RESULT result;
59
60 Trspi_UnloadBlob_UINT16(&keyOffset, &tag, blob);
61 if (tag == TPM_TAG_KEY12)
62 result = Trspi_UnloadBlob_KEY12(offset, blob, (TPM_KEY12 *)key);
63 else
64 result = Trspi_UnloadBlob_KEY(offset, blob, (TCPA_KEY *)key);
65
66 return result;
67 }
68
69 TSS_RESULT
Hash_TSS_KEY(Trspi_HashCtx * c,TSS_KEY * key)70 Hash_TSS_KEY(Trspi_HashCtx *c, TSS_KEY *key)
71 {
72 TSS_RESULT result;
73
74 if (key->hdr.key12.tag == TPM_TAG_KEY12)
75 result = Trspi_Hash_KEY12(c, (TPM_KEY12 *)key);
76 else
77 result = Trspi_Hash_KEY(c, (TCPA_KEY *)key);
78
79 return result;
80 }
81
82 void
LoadBlob_TSS_PRIVKEY_DIGEST(UINT64 * offset,BYTE * blob,TSS_KEY * key)83 LoadBlob_TSS_PRIVKEY_DIGEST(UINT64 *offset, BYTE *blob, TSS_KEY *key)
84 {
85 if (key->hdr.key12.tag == TPM_TAG_KEY12)
86 Trspi_LoadBlob_PRIVKEY_DIGEST12(offset, blob, (TPM_KEY12 *)key);
87 else
88 Trspi_LoadBlob_PRIVKEY_DIGEST(offset, blob, (TCPA_KEY *)key);
89 }
90
91 TSS_RESULT
Hash_TSS_PRIVKEY_DIGEST(Trspi_HashCtx * c,TSS_KEY * key)92 Hash_TSS_PRIVKEY_DIGEST(Trspi_HashCtx *c, TSS_KEY *key)
93 {
94 TSS_RESULT result;
95
96 if (key->hdr.key12.tag == TPM_TAG_KEY12)
97 result = Trspi_Hash_PRIVKEY_DIGEST12(c, (TPM_KEY12 *)key);
98 else
99 result = Trspi_Hash_PRIVKEY_DIGEST(c, (TCPA_KEY *)key);
100
101 return result;
102 }
103
104 #ifdef TSS_BUILD_TRANSPORT
105 TSS_RESULT
Transport_EvictKey(TSS_HCONTEXT tspContext,TCS_KEY_HANDLE hKey)106 Transport_EvictKey(TSS_HCONTEXT tspContext,
107 TCS_KEY_HANDLE hKey)
108 {
109 TSS_RESULT result;
110 UINT32 handlesLen;
111 TCS_HANDLE *handles, handle;
112 TPM_DIGEST pubKeyHash;
113 Trspi_HashCtx hashCtx;
114
115
116 if ((result = obj_context_transport_init(tspContext)))
117 return result;
118
119 LogDebugFn("Executing in a transport session");
120
121 if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest)))
122 return result;
123
124 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
125 result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
126 if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
127 return result;
128
129 handlesLen = 1;
130 handle = hKey;
131 handles = &handle;
132
133 result = obj_context_transport_execute(tspContext, TPM_ORD_EvictKey, 0, NULL, &pubKeyHash,
134 &handlesLen, &handles, NULL, NULL, NULL, NULL);
135
136 return result;
137 }
138
139 TSS_RESULT
Transport_GetPubKey(TSS_HCONTEXT tspContext,TCS_KEY_HANDLE hKey,TPM_AUTH * pAuth,UINT32 * pcPubKeySize,BYTE ** prgbPubKey)140 Transport_GetPubKey(TSS_HCONTEXT tspContext,
141 TCS_KEY_HANDLE hKey,
142 TPM_AUTH *pAuth,
143 UINT32 *pcPubKeySize,
144 BYTE **prgbPubKey)
145 {
146 TSS_RESULT result;
147 UINT32 handlesLen, decLen;
148 TCS_HANDLE *handles, handle;
149 BYTE *dec = NULL;
150 TPM_DIGEST pubKeyHash;
151 Trspi_HashCtx hashCtx;
152
153
154 if ((result = obj_context_transport_init(tspContext)))
155 return result;
156
157 LogDebugFn("Executing in a transport session");
158
159 if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest)))
160 return result;
161
162 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
163 result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
164 if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
165 return result;
166
167 handlesLen = 1;
168 handle = hKey;
169 handles = &handle;
170
171 if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetPubKey, 0, NULL,
172 &pubKeyHash, &handlesLen, &handles, pAuth, NULL,
173 &decLen, &dec)))
174 return result;
175
176 *prgbPubKey = dec;
177 *pcPubKeySize = decLen;
178
179 return result;
180 }
181
182 TSS_RESULT
Transport_CreateWrapKey(TSS_HCONTEXT tspContext,TCS_KEY_HANDLE hWrappingKey,TPM_ENCAUTH * KeyUsageAuth,TPM_ENCAUTH * KeyMigrationAuth,UINT32 keyInfoSize,BYTE * keyInfo,UINT32 * keyDataSize,BYTE ** keyData,TPM_AUTH * pAuth)183 Transport_CreateWrapKey(TSS_HCONTEXT tspContext, /* in */
184 TCS_KEY_HANDLE hWrappingKey, /* in */
185 TPM_ENCAUTH *KeyUsageAuth, /* in */
186 TPM_ENCAUTH *KeyMigrationAuth, /* in */
187 UINT32 keyInfoSize, /* in */
188 BYTE * keyInfo, /* in */
189 UINT32 * keyDataSize, /* out */
190 BYTE ** keyData, /* out */
191 TPM_AUTH * pAuth) /* in, out */
192 {
193 TSS_RESULT result;
194 UINT32 handlesLen, decLen;
195 TCS_HANDLE *handles, handle;
196 BYTE *dec = NULL;
197 TPM_DIGEST pubKeyHash;
198 Trspi_HashCtx hashCtx;
199 UINT64 offset;
200 BYTE *data;
201
202
203 if ((result = obj_context_transport_init(tspContext)))
204 return result;
205
206 LogDebugFn("Executing in a transport session");
207
208 if ((result = obj_tcskey_get_pubkeyhash(hWrappingKey, pubKeyHash.digest)))
209 return result;
210
211 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
212 result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
213 if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
214 return result;
215
216 handlesLen = 1;
217 handle = hWrappingKey;
218 handles = &handle;
219
220 if ((data = malloc(2 * sizeof(TPM_ENCAUTH) + keyInfoSize)) == NULL) {
221 LogError("malloc of %zd bytes failed", 2 * sizeof(TPM_ENCAUTH) + keyInfoSize);
222 return TSPERR(TSS_E_OUTOFMEMORY);
223 }
224
225 offset = 0;
226 Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, KeyUsageAuth->authdata);
227 Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, KeyMigrationAuth->authdata);
228 Trspi_LoadBlob(&offset, keyInfoSize, data, keyInfo);
229
230 if ((result = obj_context_transport_execute(tspContext, TPM_ORD_CreateWrapKey,
231 (2 * sizeof(TPM_ENCAUTH) + keyInfoSize), data,
232 &pubKeyHash, &handlesLen, &handles, pAuth, NULL,
233 &decLen, &dec)))
234 goto done;
235
236 *keyDataSize = decLen;
237 *keyData = dec;
238 done:
239 free(data);
240
241 return result;
242 }
243
244 TSS_RESULT
Transport_LoadKeyByBlob(TSS_HCONTEXT tspContext,TCS_KEY_HANDLE hParentKey,UINT32 ulBlobLength,BYTE * rgbBlobData,TPM_AUTH * pAuth,TCS_KEY_HANDLE * phKey,TPM_KEY_HANDLE * phSlot)245 Transport_LoadKeyByBlob(TSS_HCONTEXT tspContext,
246 TCS_KEY_HANDLE hParentKey,
247 UINT32 ulBlobLength,
248 BYTE* rgbBlobData,
249 TPM_AUTH* pAuth,
250 TCS_KEY_HANDLE* phKey,
251 TPM_KEY_HANDLE* phSlot)
252 {
253 TSS_RESULT result;
254 UINT32 handlesLen, decLen;
255 TCS_HANDLE *handles, handle;
256 BYTE *dec = NULL;
257 TPM_DIGEST pubKeyHash;
258 Trspi_HashCtx hashCtx;
259
260
261 if ((result = obj_context_transport_init(tspContext)))
262 return result;
263
264 LogDebugFn("Executing in a transport session");
265
266 if ((result = obj_tcskey_get_pubkeyhash(hParentKey, pubKeyHash.digest)))
267 return result;
268
269 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
270 result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
271 if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
272 return result;
273
274 handlesLen = 1;
275 handle = hParentKey;
276 handles = &handle;
277
278 if ((result = obj_context_transport_execute(tspContext, TPM_ORD_LoadKey2, ulBlobLength,
279 rgbBlobData, &pubKeyHash, &handlesLen,
280 &handles, pAuth, NULL, &decLen, &dec)))
281 return result;
282
283 if (handlesLen == 1)
284 *phKey = *(TCS_KEY_HANDLE *)handles;
285 else
286 result = TSPERR(TSS_E_INTERNAL_ERROR);
287
288 free(dec);
289
290 return result;
291 }
292
293 /* This function both encrypts the handle of the pubkey being requested and requires the hash
294 * of that pubkey for the transport log when logging is enabled. */
295 TSS_RESULT
Transport_OwnerReadInternalPub(TSS_HCONTEXT tspContext,TCS_KEY_HANDLE hKey,TPM_AUTH * pOwnerAuth,UINT32 * punPubKeySize,BYTE ** ppbPubKeyData)296 Transport_OwnerReadInternalPub(TSS_HCONTEXT tspContext, /* in */
297 TCS_KEY_HANDLE hKey, /* in */
298 TPM_AUTH* pOwnerAuth, /* in, out */
299 UINT32* punPubKeySize, /* out */
300 BYTE** ppbPubKeyData) /* out */
301 {
302 UINT64 offset;
303 TSS_RESULT result;
304 UINT32 handlesLen = 0, decLen;
305 TPM_DIGEST pubKeyHash;
306 Trspi_HashCtx hashCtx;
307 BYTE *dec = NULL, data[sizeof(TCS_KEY_HANDLE)];
308
309
310 if ((result = obj_context_transport_init(tspContext)))
311 return result;
312
313 LogDebugFn("Executing in a transport session");
314
315 if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest)))
316 return result;
317
318 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
319 result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest);
320 if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest)))
321 return result;
322
323 offset = 0;
324 Trspi_LoadBlob_UINT32(&offset, hKey, data);
325
326 if ((result = obj_context_transport_execute(tspContext, TPM_ORD_OwnerReadInternalPub,
327 sizeof(data), data, &pubKeyHash, &handlesLen,
328 NULL, pOwnerAuth, NULL, &decLen, &dec)))
329 return result;
330
331 *punPubKeySize = decLen;
332 *ppbPubKeyData = dec;
333
334 return result;
335 }
336 #endif
337
338