Как правильно использовать `Tspi_data_unseal` - PullRequest
0 голосов
/ 06 января 2020

Я писал код для запечатывания и распечатывания данных, используя 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, потому что он не показан в книге, из которой я работал. Спасибо за любую помощь.

...