debuggers.hg

view tools/vtpm_manager/manager/migration.c @ 0:7d21f7218375

Exact replica of unstable on 051908 + README-this
author Mukesh Rathor
date Mon May 19 15:34:57 2008 -0700 (2008-05-19)
parents
children
line source
1 // ===================================================================
2 //
3 // Copyright (c) 2005, Intel Corp.
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions
8 // are met:
9 //
10 // * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following
14 // disclaimer in the documentation and/or other materials provided
15 // with the distribution.
16 // * Neither the name of Intel Corporation nor the names of its
17 // contributors may be used to endorse or promote products derived
18 // from this software without specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 // OF THE POSSIBILITY OF SUCH DAMAGE.
32 // ===================================================================
33 //
34 // dmictl.c
35 //
36 // Functions for creating and destroying DMIs
37 //
38 // ==================================================================
40 #include <stdio.h>
41 #include <unistd.h>
42 #include <string.h>
44 #include "vtpmpriv.h"
45 #include "bsg.h"
46 #include "buffer.h"
47 #include "log.h"
48 #include "hashtable.h"
50 TPM_RESULT VTPM_Handle_Migrate_In( const buffer_t *param_buf,
51 buffer_t *result_buf) {
53 TPM_RESULT status=TPM_FAIL;
54 VTPM_DMI_RESOURCE *mig_dmi=NULL;
55 UINT32 dmi_id;
56 buffer_t dmi_state_abuf = NULL_BUF, enc_dmi_abuf = NULL_BUF, clear_dmi_blob = NULL_BUF;
58 if (param_buf == NULL) {
59 vtpmlogerror(VTPM_LOG_VTPM, "Migration Out Failed due to bad parameter.\n");
60 status = TPM_BAD_PARAMETER;
61 goto abort_egress;
62 }
64 struct pack_buf_t enc_dmi_state_pack;
66 BSG_UnpackList(param_buf->bytes, 2,
67 BSG_TYPE_UINT32, &dmi_id,
68 BSG_TPM_SIZE32_DATA, &enc_dmi_state_pack) ;
70 vtpmloginfo(VTPM_LOG_VTPM, "Migrating VTPM in dmi %d.\n", dmi_id);
72 mig_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi_id);
73 if (mig_dmi) {
74 vtpmlogerror(VTPM_LOG_VTPM, "Incoming VTPM claims unavailable id: %d.\n", dmi_id);
75 status = TPM_BAD_PARAMETER;
76 goto abort_egress;
77 }
79 /** UnBind Blob **/
80 TPMTRYRETURN( buffer_init_alias_convert( &enc_dmi_abuf,
81 enc_dmi_state_pack.size,
82 enc_dmi_state_pack.data) );
84 TPMTRYRETURN( envelope_decrypt( &enc_dmi_abuf,
85 vtpm_globals->manager_tcs_handle,
86 vtpm_globals->storageKeyHandle,
87 (const TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
88 &clear_dmi_blob) );
90 // Create new dmi
91 TPMTRYRETURN( init_dmi(dmi_id, VTPM_TYPE_MIGRATABLE, &mig_dmi ) );
93 /** Open Blob **/
94 struct pack_buf_t dmi_state_pack;
96 BSG_UnpackList(clear_dmi_blob.bytes, 2,
97 BSG_TPM_DIGEST, &mig_dmi->DMI_measurement,
98 BSG_TPM_SIZE32_DATA, &dmi_state_pack);
100 TPMTRYRETURN( buffer_init_alias_convert(&dmi_state_abuf,
101 dmi_state_pack.size,
102 dmi_state_pack.data) );
104 TPMTRYRETURN( VTPM_Handle_Save_NVM(mig_dmi, &dmi_state_abuf, NULL ) );
106 status=TPM_SUCCESS;
107 goto egress;
109 abort_egress:
110 vtpmlogerror(VTPM_LOG_VTPM, "VTPM Migration IN of instance %d failed because of %s.\n", dmi_id, tpm_get_error_name(status) );
112 egress:
113 buffer_free(&clear_dmi_blob);
114 buffer_free(&dmi_state_abuf);
116 return status;
117 }
119 TPM_RESULT VTPM_Handle_Migrate_Out( const buffer_t *param_buf,
120 buffer_t *result_buf) {
122 TPM_RESULT status=TPM_FAIL;
123 VTPM_DMI_RESOURCE *mig_dmi;
124 UINT32 dmi_id;
125 VTPM_MIGKEY_LIST *last_mig, *mig_key;
126 buffer_t dmi_state=NULL_BUF, clear_dmi_blob=NULL_BUF;
128 if (param_buf == NULL) {
129 vtpmlogerror(VTPM_LOG_VTPM, "Migration Out Failed due to bad parameter.\n");
130 status = TPM_BAD_PARAMETER;
131 goto abort_egress;
132 }
134 struct pack_buf_t name_pack;
136 BSG_UnpackList( param_buf->bytes, 2,
137 BSG_TYPE_UINT32, &dmi_id,
138 BSG_TPM_SIZE32_DATA, &name_pack);
140 vtpmloginfo(VTPM_LOG_VTPM, "Migrating out dmi %d.\n", dmi_id);
142 mig_dmi = (VTPM_DMI_RESOURCE *) hashtable_search(vtpm_globals->dmi_map, &dmi_id);
143 if (mig_dmi == NULL) {
144 vtpmlogerror(VTPM_LOG_VTPM, "Non-existent VTPM instance (%d) in migration.\n", dmi_id );
145 status = TPM_BAD_PARAMETER;
146 goto abort_egress;
147 }
149 if (mig_dmi->dmi_type != VTPM_TYPE_MIGRATABLE) {
150 vtpmlogerror(VTPM_LOG_VTPM, "Bad VTPM type (%d) in migration of instance (%d).\n", mig_dmi->dmi_type, dmi_id );
151 status = TPM_BAD_PARAMETER;
152 goto abort_egress;
153 }
155 /** Find migration key for dest **/
156 last_mig = NULL;
157 mig_key = vtpm_globals->mig_keys;
158 while (mig_key != NULL) {
159 if (mig_key->name_size == name_pack.size)
160 if (memcmp(mig_key->name, name_pack.data, name_pack.size) == 0) {
161 break;
162 }
164 last_mig = mig_key;
165 mig_key = mig_key->next;
166 }
168 if (!mig_key) {
169 vtpmlogerror(VTPM_LOG_VTPM, "Unknown Migration target host.\n");
170 status = TPM_BAD_PARAMETER;
171 goto abort_egress;
172 }
174 /** Mark vtpm as migrated **/
175 mig_dmi->dmi_type = VTPM_TYPE_MIGRATED;
177 /** Build Blob **/
178 TPMTRYRETURN( VTPM_Handle_Load_NVM(mig_dmi, NULL, &dmi_state) );
180 TPMTRYRETURN( buffer_init(&clear_dmi_blob, sizeof(TPM_DIGEST) + sizeof(UINT32) + buffer_len(&dmi_state), NULL ) );
182 struct pack_constbuf_t dmi_state_pack;
184 dmi_state_pack.size = buffer_len(&dmi_state);
185 dmi_state_pack.data = dmi_state.bytes;
187 BSG_PackList(clear_dmi_blob.bytes, 2,
188 BSG_TPM_DIGEST, &mig_dmi->DMI_measurement,
189 BSG_TPM_SIZE32_DATA, &dmi_state_pack);
191 /** Bind Blob **/
192 TPMTRYRETURN( envelope_encrypt( &clear_dmi_blob,
193 &mig_key->key,
194 result_buf) );
196 if (last_mig)
197 last_mig->next = mig_key->next;
198 else
199 vtpm_globals->mig_keys = mig_key->next;
201 free(mig_key->name);
202 free(mig_key);
204 status=TPM_SUCCESS;
205 goto egress;
207 abort_egress:
208 vtpmlogerror(VTPM_LOG_VTPM, "VTPM Migration OUT of instance %d failed because of %s. Migratoin recovery may be needed.\n", dmi_id, tpm_get_error_name(status) );
210 //TODO: Create and implement a policy for what happens to mig_key on failed migrations.
212 egress:
214 buffer_free(&clear_dmi_blob);
215 buffer_free(&dmi_state);
217 return status;
218 }
221 TPM_RESULT VTPM_Handle_Get_Migration_key( const buffer_t *param_buf,
222 buffer_t *result_buf) {
224 TPM_RESULT status=TPM_FAIL;
226 vtpmloginfo(VTPM_LOG_VTPM, "Getting Migration Public Key.\n");
228 struct pack_buf_t pubkey_exp_pack, pubkey_mod_pack;
229 TPM_KEY mig_key;
231 // Unpack/return key structure
232 BSG_Unpack(BSG_TPM_KEY, vtpm_globals->storageKeyWrap.bytes , &mig_key);
233 TPM_RSA_KEY_PARMS rsaKeyParms;
235 BSG_Unpack(BSG_TPM_RSA_KEY_PARMS,
236 mig_key.algorithmParms.parms,
237 &rsaKeyParms);
239 pubkey_exp_pack.size = rsaKeyParms.exponentSize;
240 pubkey_exp_pack.data = rsaKeyParms.exponent;
241 pubkey_mod_pack.size = mig_key.pubKey.keyLength;
242 pubkey_mod_pack.data = mig_key.pubKey.key;
244 TPMTRYRETURN( buffer_init( result_buf, 2*sizeof(UINT32) +
245 pubkey_exp_pack.size +
246 pubkey_mod_pack.size, NULL ) );
248 BSG_PackList( result_buf->bytes, 2,
249 BSG_TPM_SIZE32_DATA, &pubkey_exp_pack,
250 BSG_TPM_SIZE32_DATA, &pubkey_mod_pack);
253 status=TPM_SUCCESS;
254 goto egress;
256 abort_egress:
257 vtpmlogerror(VTPM_LOG_VTPM, "VTPM Get Migration Key failed because of %s.\n", tpm_get_error_name(status) );
258 egress:
260 return status;
261 }
263 TPM_RESULT VTPM_Handle_Load_Migration_key( const buffer_t *param_buf,
264 buffer_t *result_buf) {
266 TPM_RESULT status=TPM_FAIL;
267 VTPM_MIGKEY_LIST *mig_key;
269 vtpmloginfo(VTPM_LOG_VTPM, "Loading Migration Public Key.\n");
271 //FIXME: Review all uses of unpacking pack_buf_t and ensure free.
272 //FIXME: Review all declarations/initializations of buffer_t that could have a goto that skips them and then tries to free them
274 struct pack_buf_t name_pack, pubkey_exp_pack, pubkey_mod_pack;
276 //FIXME: scan list and verify name is not already in the list
278 BSG_UnpackList( param_buf->bytes, 3,
279 BSG_TPM_SIZE32_DATA, &name_pack,
280 BSG_TPM_SIZE32_DATA, &pubkey_exp_pack,
281 BSG_TPM_SIZE32_DATA, &pubkey_mod_pack);
283 //TODO: Maintain a persistent list for pub_keys.
284 //TODO: Verify pub_key is trusted
286 mig_key = (VTPM_MIGKEY_LIST *) malloc(sizeof(VTPM_MIGKEY_LIST));
287 memset(mig_key, 0, sizeof(VTPM_MIGKEY_LIST) );
288 mig_key->name_size = name_pack.size;
289 mig_key->name = name_pack.data;
291 mig_key->key.encScheme = CRYPTO_ES_RSAESOAEP_SHA1_MGF1;
292 Crypto_RSABuildCryptoInfoPublic( pubkey_exp_pack.size,
293 pubkey_exp_pack.data,
294 pubkey_mod_pack.size,
295 pubkey_mod_pack.data,
296 &mig_key->key);
299 mig_key->next = vtpm_globals->mig_keys;
300 vtpm_globals->mig_keys = mig_key;
302 // free(name_pack.data); Do not free. data is now part of mig_key.
303 free(pubkey_exp_pack.data);
304 free(pubkey_mod_pack.data);
306 return TPM_SUCCESS;
307 }