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