ia64/xen-unstable

changeset 8407:9f9984af7f40

Move some useful cryptographic enveloping code into their own
functions so they can be used by other parts of the VTPM code.

Signed-off-by: Vinnie Scarlata <vincent.r.scarlata@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Dec 16 18:54:57 2005 +0100 (2005-12-16)
parents b57c6fca4cef
children 6ee4c16bfdec
files tools/vtpm_manager/manager/securestorage.c
line diff
     1.1 --- a/tools/vtpm_manager/manager/securestorage.c	Fri Dec 16 11:51:06 2005 +0000
     1.2 +++ b/tools/vtpm_manager/manager/securestorage.c	Fri Dec 16 18:54:57 2005 +0100
     1.3 @@ -54,31 +54,28 @@
     1.4  #include "buffer.h"
     1.5  #include "log.h"
     1.6  
     1.7 -TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI, 
     1.8 -				const buffer_t *inbuf, 
     1.9 -				buffer_t *outbuf) {
    1.10 -  
    1.11 +TPM_RESULT envelope_encrypt(const buffer_t     *inbuf,
    1.12 +                            CRYPTO_INFO  *asymkey,
    1.13 +                            buffer_t           *sealed_data) {
    1.14    TPM_RESULT status = TPM_SUCCESS;
    1.15    symkey_t    symkey;
    1.16 -  buffer_t    state_cipher = NULL_BUF,
    1.17 +  buffer_t    data_cipher = NULL_BUF,
    1.18                symkey_cipher = NULL_BUF;
    1.19 -  int fh;
    1.20 -  long bytes_written;
    1.21 -  BYTE *sealed_NVM=NULL;
    1.22 -  UINT32 sealed_NVM_size, i;
    1.23 -  struct pack_constbuf_t symkey_cipher32, state_cipher32;
    1.24    
    1.25 -  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x", buffer_len(inbuf));
    1.26 +  UINT32 i;
    1.27 +  struct pack_constbuf_t symkey_cipher32, data_cipher32;
    1.28 +  
    1.29 +  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping[%d]: 0x", buffer_len(inbuf));
    1.30    for (i=0; i< buffer_len(inbuf); i++)
    1.31      vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
    1.32    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
    1.33    
    1.34    // Generate a sym key and encrypt state with it
    1.35    TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_genkey (&symkey) );
    1.36 -  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf, &state_cipher) );
    1.37 +  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf, &data_cipher) );
    1.38    
    1.39    // Encrypt symmetric key
    1.40 -  TPMTRYRETURN( VTSP_Bind(    &vtpm_globals->storageKey, 
    1.41 +  TPMTRYRETURN( VTSP_Bind(    asymkey, 
    1.42  			      &symkey.key, 
    1.43  			      &symkey_cipher) );
    1.44    
    1.45 @@ -87,15 +84,108 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI
    1.46    symkey_cipher32.size = buffer_len(&symkey_cipher);
    1.47    symkey_cipher32.data = symkey_cipher.bytes;
    1.48    
    1.49 -  state_cipher32.size = buffer_len(&state_cipher);
    1.50 -  state_cipher32.data = state_cipher.bytes;
    1.51 +  data_cipher32.size = buffer_len(&data_cipher);
    1.52 +  data_cipher32.data = data_cipher.bytes;
    1.53 +  
    1.54 +  TPMTRYRETURN( buffer_init(sealed_data, 2 * sizeof(UINT32) + symkey_cipher32.size + data_cipher32.size, NULL));
    1.55 +  
    1.56 +  BSG_PackList(sealed_data->bytes, 2,
    1.57 +	       BSG_TPM_SIZE32_DATA, &symkey_cipher32,
    1.58 +	       BSG_TPM_SIZE32_DATA, &data_cipher32);
    1.59 +
    1.60 +  vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of E(data)\n", buffer_len(&symkey_cipher), buffer_len(&data_cipher));
    1.61 +  goto egress;
    1.62 +
    1.63 + abort_egress:
    1.64 +  vtpmlogerror(VTPM_LOG_VTPM, "Failed to envelope encrypt\n.");
    1.65 +  
    1.66 + egress:
    1.67 +  
    1.68 +  buffer_free ( &data_cipher);
    1.69 +  buffer_free ( &symkey_cipher);
    1.70 +  Crypto_symcrypto_freekey (&symkey);
    1.71    
    1.72 -  sealed_NVM = (BYTE *) malloc( 2 * sizeof(UINT32) + symkey_cipher32.size + state_cipher32.size);
    1.73 +  return status;
    1.74 +}
    1.75 +
    1.76 +TPM_RESULT envelope_decrypt(const long         cipher_size,
    1.77 +                            const BYTE         *cipher,
    1.78 +                            TCS_CONTEXT_HANDLE TCSContext,
    1.79 +			    TPM_HANDLE         keyHandle,
    1.80 +			    const TPM_AUTHDATA *key_usage_auth,
    1.81 +                            buffer_t           *unsealed_data) {
    1.82 +
    1.83 +  TPM_RESULT status = TPM_SUCCESS;
    1.84 +  symkey_t    symkey;
    1.85 +  buffer_t    data_cipher = NULL_BUF, 
    1.86 +              symkey_clear = NULL_BUF, 
    1.87 +              symkey_cipher = NULL_BUF;
    1.88 +  struct pack_buf_t symkey_cipher32, data_cipher32;
    1.89 +  int i;
    1.90 +
    1.91 +  memset(&symkey, 0, sizeof(symkey_t));
    1.92 +
    1.93 +  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "envelope decrypting[%ld]: 0x", cipher_size);
    1.94 +  for (i=0; i< cipher_size; i++)
    1.95 +    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cipher[i]);
    1.96 +  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
    1.97 +  
    1.98 +  BSG_UnpackList(cipher, 2,
    1.99 +		 BSG_TPM_SIZE32_DATA, &symkey_cipher32,
   1.100 +		 BSG_TPM_SIZE32_DATA, &data_cipher32);
   1.101    
   1.102 -  sealed_NVM_size = BSG_PackList(sealed_NVM, 2,
   1.103 -				 BSG_TPM_SIZE32_DATA, &symkey_cipher32,
   1.104 -				 BSG_TPM_SIZE32_DATA, &state_cipher32);
   1.105 +  TPMTRYRETURN( buffer_init_convert (&symkey_cipher, 
   1.106 +				     symkey_cipher32.size, 
   1.107 +				     symkey_cipher32.data) );
   1.108 +  
   1.109 +  TPMTRYRETURN( buffer_init_convert (&data_cipher, 
   1.110 +				     data_cipher32.size, 
   1.111 +				     data_cipher32.data) );
   1.112 +
   1.113 +  // Decrypt Symmetric Key
   1.114 +  TPMTRYRETURN( VTSP_Unbind(  TCSContext,
   1.115 +			      keyHandle,
   1.116 +			      &symkey_cipher,
   1.117 +			      key_usage_auth,
   1.118 +			      &symkey_clear,
   1.119 +			      &(vtpm_globals->keyAuth) ) );
   1.120 +  
   1.121 +  // create symmetric key using saved bits
   1.122 +  Crypto_symcrypto_initkey (&symkey, &symkey_clear);
   1.123 +  
   1.124 +  // Decrypt State
   1.125 +  TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &data_cipher, unsealed_data) );
   1.126 +  
   1.127 +  goto egress;
   1.128    
   1.129 + abort_egress:
   1.130 +  vtpmlogerror(VTPM_LOG_VTPM, "Failed to envelope decrypt data\n.");
   1.131 +  
   1.132 + egress:
   1.133 +  buffer_free ( &data_cipher);
   1.134 +  buffer_free ( &symkey_clear);
   1.135 +  buffer_free ( &symkey_cipher);
   1.136 +  Crypto_symcrypto_freekey (&symkey);
   1.137 +  
   1.138 +  return status;
   1.139 +}
   1.140 +
   1.141 +TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI, 
   1.142 +				const buffer_t *inbuf, 
   1.143 +				buffer_t *outbuf) {
   1.144 +  
   1.145 +  TPM_RESULT status = TPM_SUCCESS;
   1.146 +  int fh;
   1.147 +  long bytes_written;
   1.148 +  buffer_t sealed_NVM;
   1.149 +  
   1.150 +  
   1.151 +  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x\n", buffer_len(inbuf));
   1.152 +
   1.153 +  TPMTRYRETURN( envelope_encrypt(inbuf,
   1.154 +                                 &vtpm_globals->storageKey,
   1.155 +                                 &sealed_NVM) );
   1.156 +				  
   1.157    // Mark DMI Table so new save state info will get pushed to disk on return.
   1.158    vtpm_globals->DMI_table_dirty = TRUE;
   1.159    
   1.160 @@ -104,28 +194,22 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI
   1.161    //       after writing the file? We can't get the old one back.
   1.162    // TODO: Backup old file and try and recover that way.
   1.163    fh = open(myDMI->NVMLocation, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
   1.164 -  if ( (bytes_written = write(fh, sealed_NVM, sealed_NVM_size) ) != (long) sealed_NVM_size) {
   1.165 -    vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed to finish. %ld/%ld bytes.\n", bytes_written, (long)sealed_NVM_size);
   1.166 +  if ( (bytes_written = write(fh, sealed_NVM.bytes, buffer_len(&sealed_NVM) ) != (long) buffer_len(&sealed_NVM))) {
   1.167 +    vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed to finish. %ld/%ld bytes.\n", bytes_written, (long)buffer_len(&sealed_NVM));
   1.168      status = TPM_IOERROR;
   1.169      goto abort_egress;
   1.170    }
   1.171    close(fh);
   1.172    
   1.173 -  Crypto_SHA1Full (sealed_NVM, sealed_NVM_size, (BYTE *) &myDMI->NVM_measurement);   
   1.174 +  Crypto_SHA1Full (sealed_NVM.bytes, buffer_len(&sealed_NVM), (BYTE *) &myDMI->NVM_measurement);   
   1.175    
   1.176 -  vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of E(NVM)\n", buffer_len(&symkey_cipher), buffer_len(&state_cipher));
   1.177    goto egress;
   1.178    
   1.179   abort_egress:
   1.180 -  vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
   1.181 +  vtpmlogerror(VTPM_LOG_VTPM, "Failed to save NVM\n.");
   1.182    
   1.183   egress:
   1.184 -  
   1.185 -  buffer_free ( &state_cipher);
   1.186 -  buffer_free ( &symkey_cipher);
   1.187 -  free(sealed_NVM);
   1.188 -  Crypto_symcrypto_freekey (&symkey);
   1.189 -  
   1.190 +  buffer_free(&sealed_NVM);
   1.191    return status;
   1.192  }
   1.193  
   1.194 @@ -136,11 +220,7 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI
   1.195  				buffer_t *outbuf) {
   1.196    
   1.197    TPM_RESULT status = TPM_SUCCESS;
   1.198 -  symkey_t    symkey;
   1.199 -  buffer_t    state_cipher = NULL_BUF, 
   1.200 -              symkey_clear = NULL_BUF, 
   1.201 -              symkey_cipher = NULL_BUF;
   1.202 -  struct pack_buf_t symkey_cipher32, state_cipher32;
   1.203 +
   1.204    
   1.205    UINT32 sealed_NVM_size;
   1.206    BYTE *sealed_NVM = NULL;
   1.207 @@ -148,9 +228,7 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI
   1.208    int fh, stat_ret, i;
   1.209    struct stat file_stat;
   1.210    TPM_DIGEST sealedNVMHash;
   1.211 -  
   1.212 -  memset(&symkey, 0, sizeof(symkey_t));
   1.213 -  
   1.214 +   
   1.215    if (myDMI->NVMLocation == NULL) {
   1.216      vtpmlogerror(VTPM_LOG_VTPM, "Unable to load NVM because the file name NULL.\n");
   1.217      status = TPM_AUTHFAIL;
   1.218 @@ -168,28 +246,14 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI
   1.219    }
   1.220    
   1.221    sealed_NVM = (BYTE *) malloc(fh_size);
   1.222 +  sealed_NVM_size = (UINT32) fh_size;
   1.223    if (read(fh, sealed_NVM, fh_size) != fh_size) {
   1.224      status = TPM_IOERROR;
   1.225      goto abort_egress;
   1.226    }
   1.227    close(fh);
   1.228    
   1.229 -  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%ld]: 0x", fh_size);
   1.230 -  for (i=0; i< fh_size; i++)
   1.231 -    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_NVM[i]);
   1.232 -  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
   1.233 -  
   1.234 -  sealed_NVM_size = BSG_UnpackList(sealed_NVM, 2,
   1.235 -				   BSG_TPM_SIZE32_DATA, &symkey_cipher32,
   1.236 -				   BSG_TPM_SIZE32_DATA, &state_cipher32);
   1.237 -  
   1.238 -  TPMTRYRETURN( buffer_init_convert (&symkey_cipher, 
   1.239 -				     symkey_cipher32.size, 
   1.240 -				     symkey_cipher32.data) );
   1.241 -  
   1.242 -  TPMTRYRETURN( buffer_init_convert (&state_cipher, 
   1.243 -				     state_cipher32.size, 
   1.244 -				     state_cipher32.data) );
   1.245 +  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%ld],\n", fh_size);
   1.246    
   1.247    Crypto_SHA1Full(sealed_NVM, sealed_NVM_size, (BYTE *) &sealedNVMHash);    
   1.248    
   1.249 @@ -210,32 +274,19 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI
   1.250      goto abort_egress;
   1.251    }
   1.252    
   1.253 -  // Decrypt Symmetric Key
   1.254 -  TPMTRYRETURN( VTSP_Unbind(  myDMI->TCSContext,
   1.255 -			      vtpm_globals->storageKeyHandle,
   1.256 -			      &symkey_cipher,
   1.257 -			      (const TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
   1.258 -			      &symkey_clear,
   1.259 -			      &(vtpm_globals->keyAuth) ) );
   1.260 -  
   1.261 -  // create symmetric key using saved bits
   1.262 -  Crypto_symcrypto_initkey (&symkey, &symkey_clear);
   1.263 -  
   1.264 -  // Decrypt State
   1.265 -  TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &state_cipher, outbuf) );
   1.266 -  
   1.267 +    TPMTRYRETURN( envelope_decrypt(fh_size,
   1.268 +                                 sealed_NVM,
   1.269 +                                 myDMI->TCSContext,
   1.270 +		        	 vtpm_globals->storageKeyHandle,
   1.271 +			         (const TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
   1.272 +                                 outbuf) );  
   1.273    goto egress;
   1.274    
   1.275   abort_egress:
   1.276    vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
   1.277    
   1.278   egress:
   1.279 -  
   1.280 -  buffer_free ( &state_cipher);
   1.281 -  buffer_free ( &symkey_clear);
   1.282 -  buffer_free ( &symkey_cipher);
   1.283    free( sealed_NVM );
   1.284 -  Crypto_symcrypto_freekey (&symkey);
   1.285    
   1.286    return status;
   1.287  }