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