mirror of
https://git.sr.ht/~nabijaczleweli/tzpfms
synced 2025-05-29 22:09:14 +03:00
82 lines
3.3 KiB
C++
82 lines
3.3 KiB
C++
/* SPDX-License-Identifier: MIT */
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "../fd.hpp"
|
|
#include "../main.hpp"
|
|
#include "../tpm1x.hpp"
|
|
#include "../zfs.hpp"
|
|
|
|
|
|
#define THIS_BACKEND "TPM1.X"
|
|
|
|
|
|
int main(int argc, char ** argv) {
|
|
auto noop = false;
|
|
return do_main(
|
|
argc, argv, "n", "[-n]", [&](auto) { noop = true; },
|
|
[&](auto dataset) {
|
|
/// Vaguely based on tpmUnsealFile(3) from src:tpm-tools.
|
|
|
|
char * handle_s{};
|
|
TRY_MAIN(parse_key_props(dataset, THIS_BACKEND, handle_s));
|
|
|
|
tpm1x_handle handle{};
|
|
TRY_MAIN(tpm1x_parse_handle(zfs_get_name(dataset), handle_s, handle));
|
|
|
|
|
|
uint8_t wrap_key[WRAPPING_KEY_LEN]{};
|
|
TRY_MAIN(with_tpm1x_session([&](auto ctx, auto srk, auto srk_policy) {
|
|
TSS_HOBJECT parent_key{};
|
|
TRY_MAIN(try_policy_or_passphrase("load sealant key from blob (did you take ownership?)", "TPM1.X SRK", srk_policy, [&] {
|
|
return Tspi_Context_LoadKeyByBlob(ctx, srk, handle.parent_key_blob_len, handle.parent_key_blob, &parent_key);
|
|
}));
|
|
quickscope_wrapper parent_key_deleter{[&] { Tspi_Key_UnloadKey(parent_key); }};
|
|
|
|
TSS_HPOLICY parent_key_policy{};
|
|
TRY_TPM1X("create sealant key policy", Tspi_Context_CreateObject(ctx, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &parent_key_policy));
|
|
TRY_TPM1X("assign policy to sealant key", Tspi_Policy_AssignToObject(parent_key_policy, parent_key));
|
|
quickscope_wrapper parent_key_policy_deleter{[&] {
|
|
Tspi_Policy_FlushSecret(parent_key_policy);
|
|
Tspi_Context_CloseObject(ctx, parent_key_policy);
|
|
}};
|
|
TRY_TPM1X("assign default sealant key secret",
|
|
Tspi_Policy_SetSecret(parent_key_policy, TSS_SECRET_MODE_SHA1, sizeof(parent_key_secret), (BYTE *)parent_key_secret));
|
|
|
|
|
|
TSS_HOBJECT sealed_object{};
|
|
TSS_HPOLICY sealed_object_policy{};
|
|
TRY_MAIN(tpm1x_prep_sealed_object(ctx, sealed_object, sealed_object_policy));
|
|
|
|
TRY_TPM1X("load sealed object from blob", Tspi_SetAttribData(sealed_object, TSS_TSPATTRIB_ENCDATA_BLOB, TSS_TSPATTRIB_ENCDATABLOB_BLOB,
|
|
handle.sealed_object_blob_len, handle.sealed_object_blob));
|
|
|
|
char what_for[ZFS_MAX_DATASET_NAME_LEN + 512 + 1];
|
|
// %s=dataset name, then TPM1.x. noun for "Enter passphrase for" prompt
|
|
snprintf(what_for, sizeof(what_for), gettext("%s %s wrapping key"), zfs_get_name(dataset), THIS_BACKEND);
|
|
|
|
uint8_t * loaded_wrap_key{};
|
|
uint32_t loaded_wrap_key_len{};
|
|
TRY_MAIN(try_policy_or_passphrase("unseal wrapping key", what_for, parent_key_policy,
|
|
[&] { return Tspi_Data_Unseal(sealed_object, parent_key, &loaded_wrap_key_len, &loaded_wrap_key); }));
|
|
if(loaded_wrap_key_len != sizeof(wrap_key)) {
|
|
// 0A1234... follows
|
|
fprintf(stderr, gettext("Wrong sealed data length (%u != %zu): "), loaded_wrap_key_len, sizeof(wrap_key));
|
|
for(auto i = 0u; i < loaded_wrap_key_len; ++i)
|
|
fprintf(stderr, "%02hhX", loaded_wrap_key[i]);
|
|
fprintf(stderr, "\n");
|
|
return __LINE__;
|
|
}
|
|
|
|
memcpy(wrap_key, loaded_wrap_key, sizeof(wrap_key));
|
|
return 0;
|
|
}));
|
|
|
|
TRY_MAIN(load_key(dataset, wrap_key, noop));
|
|
return 0;
|
|
});
|
|
}
|