source: trunk/packages/xen-3.1/xen-3.1/tools/vtpm_manager/manager/migration.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

  • Property svn:mime-type set to text/cpp
File size: 10.1 KB
Line 
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// ==================================================================
39
40#include <stdio.h>
41#include <unistd.h>
42#include <string.h>
43
44#include "vtpmpriv.h"
45#include "bsg.h"
46#include "buffer.h"
47#include "log.h"
48#include "hashtable.h"
49
50TPM_RESULT VTPM_Handle_Migrate_In( const buffer_t *param_buf,
51                                   buffer_t *result_buf) {
52
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;
57
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  }
63
64  struct pack_buf_t enc_dmi_state_pack;
65
66  BSG_UnpackList(param_buf->bytes, 2,
67                 BSG_TYPE_UINT32, &dmi_id,
68                 BSG_TPM_SIZE32_DATA, &enc_dmi_state_pack) ;
69
70  vtpmloginfo(VTPM_LOG_VTPM, "Migrating VTPM in dmi %d.\n", dmi_id);
71
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  }   
78
79  /** UnBind Blob **/
80  TPMTRYRETURN( buffer_init_alias_convert( &enc_dmi_abuf,
81                                           enc_dmi_state_pack.size,
82                                           enc_dmi_state_pack.data) );
83
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) );
89
90  // Create new dmi
91  TPMTRYRETURN( init_dmi(dmi_id, VTPM_TYPE_MIGRATABLE, &mig_dmi ) );
92
93  /** Open Blob **/
94  struct pack_buf_t dmi_state_pack;
95
96  BSG_UnpackList(clear_dmi_blob.bytes, 2,
97                 BSG_TPM_DIGEST, &mig_dmi->DMI_measurement,
98                 BSG_TPM_SIZE32_DATA, &dmi_state_pack);
99
100  TPMTRYRETURN( buffer_init_alias_convert(&dmi_state_abuf,
101                                          dmi_state_pack.size,
102                                          dmi_state_pack.data) );
103
104  TPMTRYRETURN( VTPM_Handle_Save_NVM(mig_dmi, &dmi_state_abuf, NULL ) );
105
106  status=TPM_SUCCESS;
107  goto egress;
108
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) );
111
112 egress:
113  buffer_free(&clear_dmi_blob);
114  buffer_free(&dmi_state_abuf);
115 
116  return status;
117}
118
119TPM_RESULT VTPM_Handle_Migrate_Out( const buffer_t *param_buf,
120                                    buffer_t *result_buf) {
121
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;
127
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  }
133
134  struct pack_buf_t name_pack;
135
136  BSG_UnpackList( param_buf->bytes, 2,
137                  BSG_TYPE_UINT32, &dmi_id,
138                  BSG_TPM_SIZE32_DATA, &name_pack);
139
140  vtpmloginfo(VTPM_LOG_VTPM, "Migrating out dmi %d.\n", dmi_id);
141
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  }
148
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  }
154
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      }
163   
164    last_mig = mig_key;
165    mig_key = mig_key->next;
166  }
167     
168  if (!mig_key) {
169    vtpmlogerror(VTPM_LOG_VTPM, "Unknown Migration target host.\n");
170    status = TPM_BAD_PARAMETER;
171    goto abort_egress;
172  }
173
174  /** Mark vtpm as migrated **/
175  mig_dmi->dmi_type = VTPM_TYPE_MIGRATED;
176
177  /** Build Blob **/
178  TPMTRYRETURN( VTPM_Handle_Load_NVM(mig_dmi, NULL, &dmi_state) );
179
180  TPMTRYRETURN( buffer_init(&clear_dmi_blob, sizeof(TPM_DIGEST) + sizeof(UINT32) + buffer_len(&dmi_state), NULL ) );
181
182  struct pack_constbuf_t dmi_state_pack;
183
184  dmi_state_pack.size = buffer_len(&dmi_state);
185  dmi_state_pack.data = dmi_state.bytes;
186
187  BSG_PackList(clear_dmi_blob.bytes, 2,
188               BSG_TPM_DIGEST, &mig_dmi->DMI_measurement,
189               BSG_TPM_SIZE32_DATA, &dmi_state_pack);
190
191  /** Bind Blob **/
192  TPMTRYRETURN( envelope_encrypt( &clear_dmi_blob,
193                                  &mig_key->key,
194                                  result_buf) );
195
196  if (last_mig)
197    last_mig->next = mig_key->next;
198  else
199    vtpm_globals->mig_keys = mig_key->next;
200 
201  free(mig_key->name);
202  free(mig_key);
203
204  status=TPM_SUCCESS;
205  goto egress;
206
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) );
209
210    //TODO: Create and implement a policy for what happens to mig_key on failed migrations.
211
212 egress:
213
214  buffer_free(&clear_dmi_blob);
215  buffer_free(&dmi_state);
216
217  return status;
218}
219
220
221TPM_RESULT VTPM_Handle_Get_Migration_key( const buffer_t *param_buf,
222                                          buffer_t *result_buf) {
223
224  TPM_RESULT status=TPM_FAIL;
225
226  vtpmloginfo(VTPM_LOG_VTPM, "Getting Migration Public Key.\n");
227
228  struct pack_buf_t pubkey_exp_pack, pubkey_mod_pack;
229  TPM_KEY mig_key;
230
231  // Unpack/return key structure
232  BSG_Unpack(BSG_TPM_KEY, vtpm_globals->storageKeyWrap.bytes , &mig_key);
233  TPM_RSA_KEY_PARMS rsaKeyParms;
234
235  BSG_Unpack(BSG_TPM_RSA_KEY_PARMS,
236               mig_key.algorithmParms.parms,
237               &rsaKeyParms);
238
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;
243
244  TPMTRYRETURN( buffer_init( result_buf, 2*sizeof(UINT32) +
245                                         pubkey_exp_pack.size +
246                                         pubkey_mod_pack.size, NULL ) );
247
248  BSG_PackList( result_buf->bytes, 2,
249                  BSG_TPM_SIZE32_DATA, &pubkey_exp_pack,
250                  BSG_TPM_SIZE32_DATA, &pubkey_mod_pack);
251
252
253  status=TPM_SUCCESS;
254  goto egress;
255
256 abort_egress:
257    vtpmlogerror(VTPM_LOG_VTPM, "VTPM Get Migration Key failed because of %s.\n", tpm_get_error_name(status) );
258 egress:
259
260  return status;
261}
262
263TPM_RESULT VTPM_Handle_Load_Migration_key( const buffer_t *param_buf,
264                                           buffer_t *result_buf) {
265
266  TPM_RESULT status=TPM_FAIL;
267  VTPM_MIGKEY_LIST *mig_key;
268
269  vtpmloginfo(VTPM_LOG_VTPM, "Loading Migration Public Key.\n");
270
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
273
274  struct pack_buf_t name_pack, pubkey_exp_pack, pubkey_mod_pack;
275
276  //FIXME: scan list and verify name is not already in the list
277
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);
282
283  //TODO: Maintain a persistent list for pub_keys.
284  //TODO: Verify pub_key is trusted
285
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;
290
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);
297
298
299  mig_key->next = vtpm_globals->mig_keys;
300  vtpm_globals->mig_keys = mig_key;
301
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);
305
306  return TPM_SUCCESS;
307}
Note: See TracBrowser for help on using the repository browser.