Add zfs-tpm-clear-key

This commit is contained in:
наб 2020-10-17 23:36:53 +02:00
parent fd3de56b6c
commit 0cf16ed2a2
No known key found for this signature in database
GPG Key ID: BCFD0B018D2658F1
7 changed files with 77 additions and 8 deletions

View File

@ -15,7 +15,7 @@ Plus it's a pretty good annoyed sigh onomatopoeia.
### Building
You'll need `pkg-config`, `libzfslinux-dev`, `libtss2-dev`<!-- , to initialise the submodules -->, and `make` should hopefully Just Work™ if you have a C++17-capable compiler.
The output binaries are trimmed of extraneous dependencies, so they're all just libc + libzfs and friends + TPM back-end.
The output binaries are trimmed of extraneous dependencies, so they're all just libc + libzfs and friends + TPM back-end, if any.
### Installation

View File

@ -56,8 +56,8 @@ LDD ?= ldd
AWK ?= awk
RONN ?= ronn
OBJ := .o
CXXAR := -g -O3 -std=c++17 -fno-exceptions -Wall -Wextra $(CXXSPECIFIC) -pipe $(INCCXXAR) $(PIC)
STRIP ?= @echo strip
CXXAR := -O3 -std=c++17 -fno-exceptions -Wall -Wextra $(CXXSPECIFIC) -pipe $(INCCXXAR) $(PIC)
STRIP ?= strip
STRIPAR := --strip-all --remove-section=.comment --remove-section=.note
OUTDIR := out/

View File

@ -0,0 +1,29 @@
/* SPDX-License-Identifier: MIT */
#include <libzfs.h>
#include <stdio.h>
#include "../main.hpp"
#include "../zfs.hpp"
int main(int argc, char ** argv) {
return do_main(
argc, argv, "", [&](auto) {},
[&](auto dataset) {
REQUIRE_KEY_LOADED(dataset);
if(zfs_crypto_rewrap(dataset, TRY_PTR("get clear rewrap args", clear_rewrap_args()), B_FALSE))
return __LINE__; // Error printed by libzfs
if(clear_key_props(dataset)) {
fprintf(stderr, "You might need to run \"zfs inherit %s %s\" and \"zfs inherit %s %s\"!\n", PROPNAME_BACKEND, zfs_get_name(dataset), PROPNAME_KEY,
zfs_get_name(dataset));
return __LINE__;
}
return 0;
});
}

View File

@ -46,10 +46,7 @@ int main(int argc, char ** argv) {
return do_main(
argc, argv, "b:", [&](auto) { backup = optarg; },
[&](auto dataset) {
if(zfs_prop_get_int(dataset, ZFS_PROP_KEYSTATUS) == ZFS_KEYSTATUS_UNAVAILABLE) {
fprintf(stderr, "Key change error: Key must be loaded.\n"); // mimic libzfs error output
return __LINE__;
}
REQUIRE_KEY_LOADED(dataset);
// https://software.intel.com/content/www/us/en/develop/articles/code-sample-protecting-secret-data-and-keys-using-intel-platform-trust-technology.html

View File

@ -24,7 +24,6 @@ int main(int argc, char ** argv) {
[&](auto dataset) {
char *backend{}, *handle_s{};
TRY_MAIN(lookup_userprop(zfs_get_user_props(dataset), PROPNAME_BACKEND, backend));
fprintf(stderr, "backend=%s\n", backend);
if(!backend) {
fprintf(stderr, "Dataset %s not encrypted with tzpfms!\n", zfs_get_name(dataset));

View File

@ -30,6 +30,27 @@ nvlist_t * rewrap_args() {
}
static nvlist_t * crrargs{};
static quickscope_wrapper crrargs_deleter{[] { nvlist_free(crrargs); }};
nvlist_t * clear_rewrap_args() {
if(!crrargs)
if(auto err =
[&] {
TRY_NVL("allocate rewrap nvlist", nvlist_alloc(&crrargs, NV_UNIQUE_NAME, 0));
TRY_NVL("add keyformat to rewrap nvlist", nvlist_add_string(crrargs, zfs_prop_to_name(ZFS_PROP_KEYFORMAT), "passphrase"));
TRY_NVL("add keylocation to rewrap nvlist", nvlist_add_string(crrargs, zfs_prop_to_name(ZFS_PROP_KEYLOCATION), "prompt"));
return 0;
}();
err && crrargs) {
nvlist_free(crrargs);
crrargs = nullptr;
errno = err;
}
return crrargs;
}
#define TRY_LOOKUP(what, ...) \
({ \
const auto _try_retl = (__VA_ARGS__); \
@ -38,6 +59,7 @@ nvlist_t * rewrap_args() {
TRY_NVL(what, _try_retl); \
})
// TODO: how does this interact with nested datasets?
int lookup_userprop(nvlist_t * from, const char * name, char *& out) {
// xyz.nabijaczleweli:tzpfms.key:
// value: '76B0286BEB3FAF57536C47D9A2BAD38157FD522A75A59E72867BBFD6AF167395'
@ -69,3 +91,10 @@ int set_key_props(zfs_handle_t * on, const char * backend, uint32_t handle) {
return 0;
}
int clear_key_props(zfs_handle_t * from) {
TRY("delete tzpfms.backend", zfs_prop_inherit(from, PROPNAME_BACKEND, B_FALSE));
TRY("delete tzpfms.key", zfs_prop_inherit(from, PROPNAME_KEY, B_FALSE));
return 0;
}

View File

@ -18,8 +18,20 @@
#define PROPNAME_KEY "xyz.nabijaczleweli:tzpfms.key"
/// Mimic libzfs error output
#define REQUIRE_KEY_LOADED(dataset) \
do { \
if(zfs_prop_get_int(dataset, ZFS_PROP_KEYSTATUS) == ZFS_KEYSTATUS_UNAVAILABLE) { \
fprintf(stderr, "Key change error: Key must be loaded.\n"); \
return __LINE__; \
} \
} while(0)
/// Static nvlist with {keyformat=raw, keylocation=prompt}
extern nvlist_t * rewrap_args();
/// Static nvlist with {keyformat=passphrase, keylocation=prompt}
extern nvlist_t * clear_rewrap_args();
/// Extract user property name from ZFS property list from to out.
///
@ -28,3 +40,6 @@ extern int lookup_userprop(nvlist_t * from, const char * name, char *& out);
/// Set required decoding props on the dataset
extern int set_key_props(zfs_handle_t * on, const char * backend, uint32_t handle);
/// Remove decoding props from the dataset
extern int clear_key_props(zfs_handle_t * from);