mirror of
https://git.sr.ht/~nabijaczleweli/tzpfms
synced 2025-06-02 22:20:59 +03:00
148 lines
3.7 KiB
C++
148 lines
3.7 KiB
C++
/* SPDX-License-Identifier: MIT */
|
|
|
|
|
|
#include "tpm1x.hpp"
|
|
|
|
#include "main.hpp"
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
/// Used as secret for the sealed object itself
|
|
// I just got this out of /dev/random
|
|
static const constexpr uint8_t sealing_secret[TPM_SHA1_160_HASH_LEN]{0xB9, 0xEE, 0x71, 0x5D, 0xBE, 0x4B, 0x24, 0x3F, 0xAA, 0x81,
|
|
0xEA, 0x04, 0x30, 0x6E, 0x06, 0x37, 0x10, 0x38, 0x3E, 0x35};
|
|
|
|
|
|
static int fromxchar(uint8_t & out, char c);
|
|
|
|
|
|
tpm1x_handle::~tpm1x_handle() {
|
|
free(this->parent_key_blob);
|
|
}
|
|
|
|
int tpm1x_parse_handle(const char * dataset_name, char * handle_s, tpm1x_handle & handle) {
|
|
auto midpoint = strchr(handle_s, ':');
|
|
if(!midpoint) {
|
|
fprintf(stderr, "Dataset %s's handle %s not valid.\n", dataset_name, handle_s);
|
|
return __LINE__;
|
|
}
|
|
*midpoint = '\0';
|
|
|
|
auto parent_key_wide_blob = handle_s;
|
|
auto sealed_object_wide_blob = midpoint + 1;
|
|
|
|
handle.parent_key_blob_len = strlen(parent_key_wide_blob) / 2;
|
|
handle.sealed_object_blob_len = strlen(sealed_object_wide_blob) / 2;
|
|
|
|
|
|
handle.parent_key_blob = static_cast<uint8_t *>(TRY_PTR("allocate blob buffer", calloc(handle.parent_key_blob_len + handle.sealed_object_blob_len, 1)));
|
|
handle.sealed_object_blob = handle.parent_key_blob + handle.parent_key_blob_len;
|
|
|
|
{
|
|
auto cur = parent_key_wide_blob;
|
|
for(size_t i = 0; i < handle.parent_key_blob_len; ++i) {
|
|
TRY("parse hex parent key blob", fromxchar(handle.parent_key_blob[i], *cur++));
|
|
handle.parent_key_blob[i] <<= 4;
|
|
TRY("parse hex parent key blob", fromxchar(handle.parent_key_blob[i], *cur++));
|
|
}
|
|
}
|
|
{
|
|
auto cur = sealed_object_wide_blob;
|
|
for(size_t i = 0; i < handle.sealed_object_blob_len; ++i) {
|
|
TRY("parse hex sealed object blob", fromxchar(handle.sealed_object_blob[i], *cur++));
|
|
handle.sealed_object_blob[i] <<= 4;
|
|
TRY("parse hex sealed object blob", fromxchar(handle.sealed_object_blob[i], *cur++));
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int tpm1x_prep_sealed_object(TSS_HCONTEXT ctx, TSS_HOBJECT & sealed_object, TSS_HPOLICY & sealed_object_policy) {
|
|
bool ok = false;
|
|
|
|
TRY_TPM1X("create sealed object", Tspi_Context_CreateObject(ctx, TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_SEAL, &sealed_object));
|
|
quickscope_wrapper sealed_object_deleter{[&] {
|
|
if(!ok)
|
|
Tspi_Context_CloseObject(ctx, sealed_object);
|
|
}};
|
|
TRY_TPM1X("create sealed object policy", Tspi_Context_CreateObject(ctx, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &sealed_object_policy));
|
|
quickscope_wrapper sealed_object_policy_deleter{[&] {
|
|
if(!ok)
|
|
Tspi_Context_CloseObject(ctx, sealed_object_policy);
|
|
}};
|
|
|
|
TRY_TPM1X("assign policy to sealed object", Tspi_Policy_AssignToObject(sealed_object_policy, sealed_object));
|
|
TRY_TPM1X("set secret on sealed object policy",
|
|
Tspi_Policy_SetSecret(sealed_object_policy, TSS_SECRET_MODE_SHA1, sizeof(sealing_secret), (uint8_t *)sealing_secret));
|
|
|
|
ok = true;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/// This feels suboptimal somehow, and yet
|
|
static int fromxchar(uint8_t & out, char c) {
|
|
switch(c) {
|
|
case '0':
|
|
out |= 0x0;
|
|
return 0;
|
|
case '1':
|
|
out |= 0x1;
|
|
return 0;
|
|
case '2':
|
|
out |= 0x2;
|
|
return 0;
|
|
case '3':
|
|
out |= 0x3;
|
|
return 0;
|
|
case '4':
|
|
out |= 0x4;
|
|
return 0;
|
|
case '5':
|
|
out |= 0x5;
|
|
return 0;
|
|
case '6':
|
|
out |= 0x6;
|
|
return 0;
|
|
case '7':
|
|
out |= 0x7;
|
|
return 0;
|
|
case '8':
|
|
out |= 0x8;
|
|
return 0;
|
|
case '9':
|
|
out |= 0x9;
|
|
return 0;
|
|
case 'A':
|
|
case 'a':
|
|
out |= 0xA;
|
|
return 0;
|
|
case 'B':
|
|
case 'b':
|
|
out |= 0xB;
|
|
return 0;
|
|
case 'C':
|
|
case 'c':
|
|
out |= 0xC;
|
|
return 0;
|
|
case 'D':
|
|
case 'd':
|
|
out |= 0xD;
|
|
return 0;
|
|
case 'E':
|
|
case 'e':
|
|
out |= 0xE;
|
|
return 0;
|
|
case 'F':
|
|
case 'f':
|
|
out |= 0xF;
|
|
return 0;
|
|
default:
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
}
|