⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tpm_unseal.c

📁 Linux下关于TPM的一些检测小工具
💻 C
字号:
/* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005, 2006 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */#include "tpm_tspi.h"#include "tpm_seal.h"#include "tpm_unseal.h"#include <errno.h>#include <string.h>#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <openssl/evp.h>#include <trousers/tss.h>#include <trousers/trousers.h>enum tspi_errors {	ETSPICTXCREAT = 0,	ETSPICTXCNCT,	ETSPICTXCO,	ETSPICTXLKBU,	ETSPICTXLKBB,	ETSPISETAD,	ETSPIGETPO,	ETSPIPOLSS,	ETSPIDATU,	ETSPIPOLATO};#define TSPI_FUNCTION_NAME_MAX 30char tspi_error_strings[][TSPI_FUNCTION_NAME_MAX]= { 				"Tspi_Context_Create",				"Tspi_Context_Connect",				"Tspi_Context_CreateObject",				"Tspi_Context_LoadKeyByUUID",				"Tspi_Context_LoadKeyByBlob",				"Tspi_SetAttribData",				"Tspi_GetPolicyObject",				"Tspi_Policy_SetSecret",				"Tspi_Data_Unseal",				"Tspi_Policy_AssignToObject"};#define TSSKEY_DEFAULT_SIZE 768#define EVPKEY_DEFAULT_SIZE 512int tpm_errno;TSS_UUID SRK_UUID = TSS_UUID_SRK;int tpmUnsealFile( char* fname, unsigned char** tss_data, int* tss_size ) {	int rc, rcLen=0, tssLen=0, evpLen=0;	BYTE* rcPtr;	char data[EVP_CIPHER_block_size(EVP_aes_256_cbc()) * 16];	BYTE *tssKeyData = NULL;	int tssKeyDataSize = 0;	BYTE *evpKeyData = NULL;	int evpKeyDataSize = 0;	struct stat stats;	TSS_HCONTEXT hContext;	TSS_HENCDATA hEncdata;	TSS_HKEY hSrk, hKey;	TSS_HPOLICY hPolicy;	UINT32 symKeyLen;	BYTE *symKey;	unsigned char* res_data = NULL;	int res_size = 0;	BIO *bdata = NULL, *b64 = NULL, *bmem = NULL;	int bioRc;	if ( tss_data == NULL || tss_size == NULL ) {		rc = TPMSEAL_STD_ERROR;		tpm_errno = EINVAL;		goto out;	}	*tss_data = NULL;	*tss_size = 0;	/* Test for file existence */	if ((rc = stat(fname, &stats))) {		tpm_errno = errno;		goto out;	}		/* Create an input file BIO */	if((bdata = BIO_new_file(fname, "r")) == NULL ) {		tpm_errno = errno;		rc = TPMSEAL_STD_ERROR;		goto out;	}	/* Test file header for TSS */	BIO_gets(bdata, data, sizeof(data));	if (strncmp(data, TPMSEAL_HDR_STRING, 			strlen(TPMSEAL_HDR_STRING)) != 0) {		rc = TPMSEAL_FILE_ERROR;		tpm_errno = ENOTSSHDR;		goto out;	}			/* Looking for TSS Key Header */	BIO_gets(bdata, data, sizeof(data));	if (strncmp(data, TPMSEAL_TSS_STRING, 			strlen(TPMSEAL_TSS_STRING)) != 0) {		rc = TPMSEAL_FILE_ERROR;		tpm_errno = EWRONGTSSTAG;		goto out;	}	/* Create a memory BIO to hold the base64 TSS key */	if ((bmem = BIO_new(BIO_s_mem())) == NULL) {		tpm_errno = EAGAIN;		rc = TPMSEAL_STD_ERROR;		goto out;	}	BIO_set_mem_eof_return(bmem, 0);	/* Read the base64 TSS key into the memory BIO */	while ((rcLen = BIO_gets(bdata, data, sizeof(data))) > 0) {		/* Look for EVP Key Header (end of key) */		if (strncmp(data, TPMSEAL_EVP_STRING,				strlen(TPMSEAL_EVP_STRING)) == 0)			break;		if (BIO_write(bmem, data, rcLen) <= 0) {			tpm_errno = EIO; 			rc = TPMSEAL_STD_ERROR;			goto out;		}	}	if (strncmp(data, TPMSEAL_EVP_STRING, 			strlen(TPMSEAL_EVP_STRING)) != 0 ) {		tpm_errno = EWRONGEVPTAG;		rc = TPMSEAL_FILE_ERROR;		goto out;	}	/* Create a base64 BIO to decode the TSS key */	if ((b64 = BIO_new(BIO_f_base64())) == NULL) {		tpm_errno = EAGAIN;		rc = TPMSEAL_STD_ERROR;		goto out;	}	/* Decode the TSS key */	bmem = BIO_push( b64, bmem );	while ((rcLen = BIO_read(bmem, data, sizeof(data))) > 0) {		if ((tssLen + rcLen) > tssKeyDataSize) {			tssKeyDataSize += TSSKEY_DEFAULT_SIZE;			rcPtr = realloc( tssKeyData, tssKeyDataSize);			if ( rcPtr == NULL ) {				tpm_errno = ENOMEM;				rc = TPMSEAL_STD_ERROR;				goto out;			}			tssKeyData = rcPtr;		}		memcpy(tssKeyData + tssLen, data, rcLen);		tssLen += rcLen;	}	bmem = BIO_pop(b64);	BIO_free(b64);	b64 = NULL;	bioRc = BIO_reset(bmem);	/* Check for EVP Key Type Header */	BIO_gets(bdata, data, sizeof(data));	if (strncmp(data, TPMSEAL_KEYTYPE_SYM, 			strlen(TPMSEAL_KEYTYPE_SYM)) != 0 ) {		rc = TPMSEAL_FILE_ERROR;		tpm_errno = EWRONGKEYTYPE;		goto out;	}	/* Make sure it's a supported cipher	   (currently only AES 256 CBC) */	if (strncmp(data + strlen(TPMSEAL_KEYTYPE_SYM),			TPMSEAL_CIPHER_AES256CBC,			strlen(TPMSEAL_CIPHER_AES256CBC)) != 0) {		rc = TPMSEAL_FILE_ERROR;		tpm_errno = EWRONGKEYTYPE;		goto out;	}	/* Read the base64 Symmetric key into the memory BIO */	while ((rcLen = BIO_gets(bdata, data, sizeof(data))) > 0) {		/* Look for Encrypted Data Header (end of key) */		if (strncmp(data, TPMSEAL_ENC_STRING,				strlen(TPMSEAL_ENC_STRING)) == 0)			break;		if (BIO_write(bmem, data, rcLen) <= 0) {			tpm_errno = EIO; 			rc = TPMSEAL_STD_ERROR;			goto out;		}	}	if (strncmp(data, TPMSEAL_ENC_STRING, 			strlen(TPMSEAL_ENC_STRING)) != 0 ) {		tpm_errno = EWRONGDATTAG;		rc = TPMSEAL_FILE_ERROR;		goto out;	}	/* Create a base64 BIO to decode the Symmetric key */	if ((b64 = BIO_new(BIO_f_base64())) == NULL) {		tpm_errno = EAGAIN;		rc = TPMSEAL_STD_ERROR;		goto out;	}	/* Decode the Symmetric key */	bmem = BIO_push( b64, bmem );	while ((rcLen = BIO_read(bmem, data, sizeof(data))) > 0) {		if ((evpLen + rcLen) > evpKeyDataSize) {			evpKeyDataSize += EVPKEY_DEFAULT_SIZE;			rcPtr = realloc( evpKeyData, evpKeyDataSize);			if ( rcPtr == NULL ) {				tpm_errno = ENOMEM;				rc = TPMSEAL_STD_ERROR;				goto out;			}			evpKeyData = rcPtr;		}		memcpy(evpKeyData + evpLen, data, rcLen);		evpLen += rcLen;	}	bmem = BIO_pop(b64);	BIO_free(b64);	b64 = NULL;	bioRc = BIO_reset(bmem);	/* Read the base64 encrypted data into the memory BIO */	while ((rcLen = BIO_gets(bdata, data, sizeof(data))) > 0) {		/* Look for TSS Footer (end of data) */		if (strncmp(data, TPMSEAL_FTR_STRING,				strlen(TPMSEAL_FTR_STRING)) == 0)			break;		if (BIO_write(bmem, data, rcLen) <= 0) {			tpm_errno = EIO; 			rc = TPMSEAL_STD_ERROR;			goto out;		}	}	if (strncmp(data, TPMSEAL_FTR_STRING, 			strlen(TPMSEAL_FTR_STRING)) != 0 ) {		tpm_errno = ENOTSSFTR;		rc = TPMSEAL_FILE_ERROR;		goto out;	}	/* Unseal */	if ((rc=Tspi_Context_Create(&hContext)) != TSS_SUCCESS) {		tpm_errno = ETSPICTXCREAT;		goto out;	}	if ((rc=Tspi_Context_Connect(hContext, NULL)) != TSS_SUCCESS) {		tpm_errno = ETSPICTXCNCT;		goto tss_out;	}				if ((rc=Tspi_Context_CreateObject(hContext,					TSS_OBJECT_TYPE_ENCDATA,					TSS_ENCDATA_SEAL,					&hEncdata)) != TSS_SUCCESS) {		tpm_errno = ETSPICTXCO;		goto tss_out;	}	        	if ((rc=Tspi_SetAttribData(hEncdata,				TSS_TSPATTRIB_ENCDATA_BLOB,				TSS_TSPATTRIB_ENCDATABLOB_BLOB,				evpLen, evpKeyData)) != TSS_SUCCESS) {		tpm_errno = ETSPISETAD;		goto tss_out;	}	if ((rc=Tspi_Context_CreateObject(hContext,					TSS_OBJECT_TYPE_POLICY,					TSS_POLICY_USAGE,					&hPolicy)) != TSS_SUCCESS) {		tpm_errno = ETSPICTXCO;		goto tss_out;	}	if ((rc=Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_PLAIN,					strlen(TPMSEAL_SECRET),					(BYTE *)TPMSEAL_SECRET)) != TSS_SUCCESS) {		tpm_errno = ETSPIPOLSS;		goto tss_out;	}	if ((rc=Tspi_Policy_AssignToObject(hPolicy, hEncdata)) != TSS_SUCCESS) {		tpm_errno = ETSPIPOLATO;		goto tss_out;	}	if ((rc=Tspi_Context_LoadKeyByUUID(hContext, TSS_PS_TYPE_SYSTEM, 					SRK_UUID, &hSrk)) != TSS_SUCCESS) {		tpm_errno = ETSPICTXLKBU;		goto tss_out;	}	/* Don't create a new policy for the SRK's secret, just use the context's	 * default policy */	if ((rc=Tspi_GetPolicyObject(hSrk, TSS_POLICY_USAGE, 					&hPolicy)) != TSS_SUCCESS){		tpm_errno = ETSPIGETPO;		goto tss_out;	}	if ((rc=Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_PLAIN, 0, NULL)) 					!= TSS_SUCCESS) {		tpm_errno = ETSPIPOLSS;		goto tss_out;	}	/* Failure point if trying to unseal data on a differnt TPM */	if ((rc=Tspi_Context_LoadKeyByBlob(hContext, hSrk, tssLen, 					tssKeyData, &hKey)) != TSS_SUCCESS) {		tpm_errno = ETSPICTXLKBB;		goto tss_out;	}	if ((rc=Tspi_Context_CreateObject(hContext,					TSS_OBJECT_TYPE_POLICY,					TSS_POLICY_USAGE,					&hPolicy)) != TSS_SUCCESS) {		tpm_errno = ETSPICTXCO;		goto tss_out;	}	if ((rc=Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_PLAIN,					strlen(TPMSEAL_SECRET),					(BYTE *)TPMSEAL_SECRET)) != TSS_SUCCESS) {		tpm_errno = ETSPIPOLSS;		goto tss_out;	}	if ((rc=Tspi_Policy_AssignToObject(hPolicy, hKey)) != TSS_SUCCESS) {		tpm_errno = ETSPIPOLATO;		goto tss_out;	}	if ((rc=Tspi_Data_Unseal(hEncdata, hKey, &symKeyLen,					&symKey)) != TSS_SUCCESS) {		tpm_errno = ETSPIDATU;		goto tss_out;	}	/* Malloc a block of storage to hold the decrypted data	   Using the size of the mem BIO is more than enough	   (plus an extra cipher block size) */	res_data = malloc(BIO_pending(bmem) + EVP_CIPHER_block_size(EVP_aes_256_cbc()));	if ( res_data == NULL ) {		rc = TPMSEAL_STD_ERROR;		tpm_errno = ENOMEM;		goto tss_out;	}	/* Decode and decrypt the encrypted data */	EVP_CIPHER_CTX ctx;	EVP_DecryptInit(&ctx, EVP_aes_256_cbc(), symKey, (unsigned char *)TPMSEAL_IV);	/* Create a base64 BIO to decode the encrypted data */	if ((b64 = BIO_new(BIO_f_base64())) == NULL) {		tpm_errno = EAGAIN;		rc = TPMSEAL_STD_ERROR;		goto tss_out;	}	bmem = BIO_push( b64, bmem );	while ((rcLen = BIO_read(bmem, data, sizeof(data))) > 0) {		EVP_DecryptUpdate(&ctx, res_data+res_size,					&rcLen, (unsigned char *)data, rcLen);		res_size += rcLen;	}	EVP_DecryptFinal(&ctx, res_data+res_size, &rcLen);	res_size += rcLen;	bmem = BIO_pop(b64);	BIO_free(b64);	b64 = NULL;	bioRc = BIO_reset(bmem);tss_out:	Tspi_Context_Close(hContext);out:	if ( bdata )		BIO_free(bdata);	if ( b64 )		BIO_free(b64);	if ( bmem ) {		bioRc = BIO_set_close(bmem, BIO_CLOSE);		BIO_free(bmem);	}	if ( evpKeyData )		free(evpKeyData);	if ( tssKeyData )		free(tssKeyData);	if ( rc == 0 ) {		*tss_data = res_data;		*tss_size = res_size;	}	return rc;}void tpmUnsealShred(unsigned char* data, int size) {	if ( data != NULL ) {		memset( data, 0, size);		free(data);	}}char tpm_error_buf[512];char * tpmUnsealStrerror(int rc) {	switch(rc) {		case 0:			return "Success";		case TPMSEAL_STD_ERROR:			return strerror(tpm_errno);		case TPMSEAL_FILE_ERROR:			switch(tpm_errno) {				case ENOTSSHDR:					return _("No TSS header present");				case ENOTSSFTR:					return _("No TSS footer present");				case EWRONGTSSTAG:					return _("Wrong TSS tag");				case EWRONGEVPTAG:					return _("Wrong EVP tag");				case EWRONGDATTAG:					return _("Wrong DATA tag");				case EWRONGKEYTYPE:					return _("Not a Symmetric EVP Key");				case EBADSEEK:					return _("Unable to move to desired file position");			}		default:			snprintf(tpm_error_buf, sizeof(tpm_error_buf), 				"%s: 0x%08x - layer=%s, code=%04x (%d), %s", 				tspi_error_strings[tpm_errno],				rc, Trspi_Error_Layer(rc), 				Trspi_Error_Code(rc), 				Trspi_Error_Code(rc), 				Trspi_Error_String(rc)); 			return tpm_error_buf;	}	return "";}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -