Я писал код для запечатывания и распечатывания данных, используя tpm и библиотеку Tspi. После того, как я много потрудился с вещами, которые я пытался понять, и использовал практическое руководство по доверенному программированию, у меня есть программа, которая компилируется и запускается.
Кажется, что данные запечатаны без проблем (код возврата Tspi_Data_Seal
равен 0), но затем не удается распечатать их, возвращая код 1. Я просмотрел список кодов возврата TSS, но Кажется, что 1 среди них нет в списке, чтобы увидеть, была ли ошибка в другом месте моего кода (скажем, когда я создавал новый HENCDATA
для размещения большого двоичного объекта, который должен быть распечатан).
Я позвонил Tspi_Data_Unseal
сразу после моего звонка для печати, а затем добавил вызов printf, чтобы увидеть, какими должны быть распечатанные данные, однако он по-прежнему показывает беспорядок и возвращает код ошибки 1. На данный момент это закомментировано вне, но оставлено в коде, чтобы вы могли видеть, где это было легко.
#include "test.h"
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tss/platform.h>
#include <tss/tss_structs.h>
#include <tss/tss_typedef.h>
#include <unistd.h>
int main() {
TSS_HPCRS pcrs;
UINT32 pcrsToUse[8] = {0, 1, 2, 3, 4, 5, 6, 7};
UINT32 numOfPcrs = 8, inSize = 0, outSize = 0;
createKey();
CreatePcrs(numOfPcrs, pcrsToUse, &pcrs);
// read file
FILE *fin, *fout;
BYTE inBuffer[400] = {0}, outBuffer[400] = {0};
fin = fopen("/home/bham/Desktop/testfile", "rb");
fseek(fin, 0, SEEK_END);
inSize = ftell(fin);
outSize = inSize + 103;
fseek(fin, 0, SEEK_SET);
fread(inBuffer, inSize, 1, fin);
fclose(fin);
// seal data
SealData(kHandle, pcrs, inSize, inBuffer, &outSize, outBuffer);
printf("sealed out %u\n", outSize);
// write out sealed data
fout = fopen("/home/bham/Desktop/testfile.enc", "w");
write(fileno(fout), outBuffer, outSize);
fclose(fout);
fin = fopen("/home/bham/Desktop/testfile.enc", "rb");
fseek(fin, 0, SEEK_END);
inSize = ftell(fin);
outSize = inSize;
fseek(fin, 0, SEEK_SET);
fread(inBuffer, inSize, 1, fin);
fclose(fin);
unsealData(kHandle, inSize, inBuffer, &outSize, outBuffer);
printf("%s\n", outBuffer);
Tspi_Context_FreeMemory(hContext, NULL);
Tspi_Context_Close(hContext);
printf("result = %u\n", result);
return 0;
}
int createKey() {
TSS_FLAG initFlags;
TSS_HKEY hSRK = 0;
TSS_HKEY hKey;
TSS_UUID key_uuid = {9};
TSS_UUID SRK_UUID = TSS_UUID_SRK;
TSS_HPOLICY hOwnerPolicy;
Tspi_Context_Create(&hContext);
Tspi_SetAttribUint32(hContext, TSS_TSPATTRIB_CONTEXT_VERSION_MODE, 0,
TSS_TSPATTRIB_CONTEXT_VERSION_V1_2);
Tspi_Context_Connect(hContext, NULL);
// set self to owner
Tspi_Context_GetTpmObject(hContext, &hTPM);
Tspi_GetPolicyObject(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy);
Tspi_Policy_SetSecret(hOwnerPolicy, TSS_SECRET_MODE_SHA1, 0, "");
Tspi_Context_LoadKeyByUUID(hContext, TSS_PS_TYPE_SYSTEM, SRK_UUID, &hSRK);
// set SRK secret to well known secret
Tspi_GetPolicyObject(hSRK, TSS_POLICY_USAGE, &hOwnerPolicy);
Tspi_Policy_SetSecret(hOwnerPolicy, TSS_SECRET_MODE_SHA1, 20, wks);
initFlags = TSS_KEY_TYPE_STORAGE | TSS_KEY_SIZE_2048 | TSS_KEY_NOT_MIGRATABLE;
Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY, initFlags, &hKey);
/* Create the key, not bound to any PCRs. That can be done on* a blob by blob
* basis */
Tspi_Key_CreateKey(hKey, hSRK, 0);
result = Tspi_Context_UnregisterKey(hContext, TSS_PS_TYPE_SYSTEM, key_uuid,
&kHandle);
result = Tspi_Context_RegisterKey(hContext, hKey, TSS_PS_TYPE_SYSTEM,
key_uuid, TSS_PS_TYPE_SYSTEM, SRK_UUID);
result = Tspi_Context_LoadKeyByUUID(hContext, TSS_PS_TYPE_SYSTEM, key_uuid,
&kHandle);
return 0;
}
int unsealData(TSS_HKEY hKey, UINT32 in_size, BYTE *in, UINT32 *out_size,
BYTE *out) {
TSS_HENCDATA hEncData;
UINT32 keySize;
/* Create the encrypted data object in the TSP */
Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_SEAL,
&hEncData);
Tspi_SetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB,
TSS_TSPATTRIB_ENCDATABLOB_BLOB, in_size, in);
printf("%u\n", in_size);
printf("%u\n", *out_size);
result = Tspi_Data_Unseal(hEncData, hKey, out_size, &out);
printf("%s\n", out);
/* Close the encrypted data object, it will no longer * be used */
Tspi_Context_CloseObject(hContext, hEncData);
}
int SealData(TSS_HKEY hKey, TSS_HPCRS hPcrs, UINT32 in_size, BYTE *in,
UINT32 *out_size, BYTE *out) {
TSS_HENCDATA hEncData;
UINT32 keySize, tmp_out_size;
BYTE *tmp_out;
/* Create the encrypted data object in the TSP */
Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_SEAL,
&hEncData);
Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_SIZE,
&keySize);
printf("%u is key size\n", keySize);
/* Make sure the data is small enough to be bound by this*
key,taking into account the OAEP padding size (38) and* the
size of the TPM_SEALED_DATA structure (65) */
if (in_size > 153) {
printf("Data to be encrypted is too big !\n");
return -1;
}
printf("%u\n", in_size);
printf("%s\n", in);
printf("%u\n", *out_size);
Tspi_Data_Seal(hEncData, hKey, in_size, in, hPcrs);
/* Now hEncData contains an encrypted blob, let’s extract * it */
Tspi_GetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB,
TSS_TSPATTRIB_ENCDATABLOB_BLOB, &tmp_out_size, &tmp_out);
// This is the test unseal mentioned in the question
// result = Tspi_Data_Unseal(hEncData, hKey, out_size, &out);
// printf("%s\n", out);
memcpy(out, tmp_out, tmp_out_size);
*out_size = tmp_out_size;
/* Free the blob returned by the TSP */
Tspi_Context_FreeMemory(hContext, tmp_out);
/* Close the encrypted data object, it will no longer * be used */
Tspi_Context_CloseObject(hContext, hEncData);
return 0;
}
int CreatePcrs(UINT32 num_pcrs, UINT32 *pcrs, TSS_HPCRS *hPcrs) {
UINT32 numPcrs, subCap, i;
UINT32 ulPcrValueLength;
BYTE *rgbPcrValue, *rgbNumPcrs;
Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_PCRS, 0, hPcrs);
// Retrieve number of PCRs from the TPM
subCap = TSS_TPMCAP_PROP_PCR;
Tspi_TPM_GetCapability(hTPM, TSS_TPMCAP_PROPERTY, sizeof(UINT32),
(BYTE *)&subCap, &ulPcrValueLength, &rgbNumPcrs);
numPcrs = *(UINT32 *)rgbNumPcrs;
Tspi_Context_FreeMemory(hContext, rgbNumPcrs);
for (i = 0; i < num_pcrs; i++) {
if (pcrs[i] >= numPcrs) {
printf("PCR value %u is too big !\n", pcrs[i]);
Tspi_Context_CloseObject(hContext, *hPcrs);
return -1;
}
Tspi_TPM_PcrRead(hTPM, pcrs[i], &ulPcrValueLength, &rgbPcrValue);
Tspi_PcrComposite_SetPcrValue(*hPcrs, pcrs[i], ulPcrValueLength,
rgbPcrValue);
Tspi_Context_FreeMemory(hContext, rgbPcrValue);
}
return 0;
}
test .h просто содержит
#include <tss/tspi.h>
TSS_RESULT result;
TSS_HCONTEXT hContext;
TSS_HTPM hTPM;
TSS_HKEY kHandle;
BYTE wks[20] = TSS_WELL_KNOWN_SECRET;
int createKey();
int SealData(TSS_HKEY hKey, TSS_HPCRS hPcrs, UINT32 in_size, BYTE *in,
UINT32 *out_size, BYTE *out);
int unsealData(TSS_HKEY hKey, UINT32 in_size, BYTE *in, UINT32 *out_size,
BYTE *out);
int CreatePcrs(UINT32 num_pcrs, UINT32 *pcrs, TSS_HPCRS *hPcrs);
Пароль владельца в настоящее время не установлен, и srk использует общеизвестный секрет, файл, который должен быть запечатан в данный момент, является просто текстовым файлом, содержащим «Данные для печати»
Из этого я могу только предположить, что я допускаю некоторую ошибку в моем использовании Tspi_Data_Unseal
, однако я могу найти отн Вначале мало показывая, как его использовать, я предполагал, что он будет работать примерно так же, как и Tspi_Data_Seal
, потому что он не показан в книге, из которой я работал. Спасибо за любую помощь.