📄 securestorage.c
字号:
// ===================================================================// // Copyright (c) 2005, Intel Corp.// All rights reserved.//// Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met://// * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution.// * Neither the name of Intel Corporation nor the names of its // contributors may be used to endorse or promote products derived// from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED// OF THE POSSIBILITY OF SUCH DAMAGE.// ===================================================================// // securestorage.c// // Functions regarding securely storing DMI secrets.//// ==================================================================#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#include "tcg.h"#include "vtpm_manager.h"#include "vtpmpriv.h"#include "vtsp.h"#include "bsg.h"#include "crypto.h"#include "hashtable.h"#include "hashtable_itr.h"#include "buffer.h"#include "log.h"TPM_RESULT envelope_encrypt(const buffer_t *inbuf, CRYPTO_INFO *asymkey, buffer_t *sealed_data) { TPM_RESULT status = TPM_SUCCESS; symkey_t symkey; buffer_t data_cipher = NULL_BUF, symkey_cipher = NULL_BUF; UINT32 i; struct pack_constbuf_t symkey_cipher32, data_cipher32; vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping Input[%d]: 0x", buffer_len(inbuf)); for (i=0; i< buffer_len(inbuf); i++) vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]); vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); // Generate a sym key and encrypt state with it TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_genkey (&symkey) ); TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf, &data_cipher) ); // Encrypt symmetric key TPMTRYRETURN( VTSP_Bind( asymkey, &symkey.key, &symkey_cipher) ); // Create output blob: symkey_size + symkey_cipher + state_cipher_size + state_cipher symkey_cipher32.size = buffer_len(&symkey_cipher); symkey_cipher32.data = symkey_cipher.bytes; data_cipher32.size = buffer_len(&data_cipher); data_cipher32.data = data_cipher.bytes; TPMTRYRETURN( buffer_init(sealed_data, 2 * sizeof(UINT32) + symkey_cipher32.size + data_cipher32.size, NULL)); BSG_PackList(sealed_data->bytes, 2, BSG_TPM_SIZE32_DATA, &symkey_cipher32, BSG_TPM_SIZE32_DATA, &data_cipher32); vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of E(data)\n", buffer_len(&symkey_cipher), buffer_len(&data_cipher)); vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping Output[%d]: 0x", buffer_len(sealed_data)); for (i=0; i< buffer_len(sealed_data); i++) vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_data->bytes[i]); vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); goto egress; abort_egress: vtpmlogerror(VTPM_LOG_VTPM, "Failed to envelope encrypt\n."); egress: buffer_free ( &data_cipher); buffer_free ( &symkey_cipher); Crypto_symcrypto_freekey (&symkey); return status;}TPM_RESULT envelope_decrypt(const buffer_t *cipher, TCS_CONTEXT_HANDLE TCSContext, TPM_HANDLE keyHandle, const TPM_AUTHDATA *key_usage_auth, buffer_t *unsealed_data) { TPM_RESULT status = TPM_SUCCESS; symkey_t symkey; buffer_t data_cipher = NULL_BUF, symkey_clear = NULL_BUF, symkey_cipher = NULL_BUF; struct pack_buf_t symkey_cipher32, data_cipher32; int i; memset(&symkey, 0, sizeof(symkey_t)); vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypt Input[%d]: 0x", buffer_len(cipher) ); for (i=0; i< buffer_len(cipher); i++) vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cipher->bytes[i]); vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); BSG_UnpackList(cipher->bytes, 2, BSG_TPM_SIZE32_DATA, &symkey_cipher32, BSG_TPM_SIZE32_DATA, &data_cipher32); TPMTRYRETURN( buffer_init_alias_convert (&symkey_cipher, symkey_cipher32.size, symkey_cipher32.data) ); TPMTRYRETURN( buffer_init_alias_convert (&data_cipher, data_cipher32.size, data_cipher32.data) ); // Decrypt Symmetric Key TPMTRYRETURN( VTSP_Unbind( TCSContext, keyHandle, &symkey_cipher, key_usage_auth, &symkey_clear, &(vtpm_globals->keyAuth) ) ); // create symmetric key using saved bits Crypto_symcrypto_initkey (&symkey, &symkey_clear); // Decrypt State TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &data_cipher, unsealed_data) ); vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypte Output[%d]: 0x", buffer_len(unsealed_data)); for (i=0; i< buffer_len(unsealed_data); i++) vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", unsealed_data->bytes[i]); vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); goto egress; abort_egress: vtpmlogerror(VTPM_LOG_VTPM, "Failed to envelope decrypt data\n."); egress: buffer_free ( &data_cipher); buffer_free ( &symkey_clear); buffer_free ( &symkey_cipher); Crypto_symcrypto_freekey (&symkey); return status;}TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI, const buffer_t *inbuf, buffer_t *outbuf) { TPM_RESULT status = TPM_SUCCESS; int fh; long bytes_written; buffer_t sealed_NVM = NULL_BUF; vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Saving %d bytes of NVM.\n", buffer_len(inbuf)); TPMTRYRETURN( envelope_encrypt(inbuf, &vtpm_globals->storageKey, &sealed_NVM) ); // Write sealed blob off disk from NVMLocation // TODO: How to properly return from these. Do we care if we return failure // after writing the file? We can't get the old one back. // TODO: Backup old file and try and recover that way. fh = open(myDMI->NVMLocation, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); if ( (bytes_written = write(fh, sealed_NVM.bytes, buffer_len(&sealed_NVM) ) != (long) buffer_len(&sealed_NVM))) { 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)); status = TPM_IOERROR; goto abort_egress; } close(fh); Crypto_SHA1Full (sealed_NVM.bytes, buffer_len(&sealed_NVM), (BYTE *) &myDMI->NVM_measurement); goto egress; abort_egress: vtpmlogerror(VTPM_LOG_VTPM, "Failed to save NVM\n."); egress: buffer_free(&sealed_NVM); return status;}/* Expected Params: inbuf = null, outbuf = sealed blob size, sealed blob.*/TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE *myDMI, const buffer_t *inbuf, buffer_t *outbuf) { TPM_RESULT status = TPM_SUCCESS; buffer_t sealed_NVM = NULL_BUF; long fh_size; int fh, stat_ret, i; struct stat file_stat; TPM_DIGEST sealedNVMHash; if (myDMI->NVMLocation == NULL) { vtpmlogerror(VTPM_LOG_VTPM, "Unable to load NVM because the file name NULL.\n"); status = TPM_AUTHFAIL; goto abort_egress; } //Read sealed blob off disk from NVMLocation fh = open(myDMI->NVMLocation, O_RDONLY); stat_ret = fstat(fh, &file_stat); if (stat_ret == 0) fh_size = file_stat.st_size; else { status = TPM_IOERROR; goto abort_egress; } TPMTRYRETURN( buffer_init( &sealed_NVM, fh_size, NULL) ); if (read(fh, sealed_NVM.bytes, buffer_len(&sealed_NVM)) != fh_size) { status = TPM_IOERROR; goto abort_egress; } close(fh);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -