OrderedHashmap *subvolumes;
char *default_subvolume;
EncryptMode encrypt;
+ struct iovec key;
Tpm2PCRValue *tpm2_hash_pcr_values;
size_t tpm2_n_hash_pcr_values;
VerityMode verity;
free(p->compression);
free(p->compression_level);
+ iovec_done_erase(&p->key);
+
copy_files_free_many(p->copy_files, p->n_copy_files);
iovec_done(&p->roothash);
p->compression = mfree(p->compression);
p->compression_level = mfree(p->compression_level);
+ iovec_done_erase(&p->key);
+
copy_files_free_many(p->copy_files, p->n_copy_files);
p->copy_files = NULL;
p->n_copy_files = 0;
&partition->tpm2_n_hash_pcr_values);
}
+static int parse_key_file(const char *filename, struct iovec *key) {
+ _cleanup_(erase_and_freep) char *k = NULL;
+ size_t n = 0;
+ int r;
+
+ r = read_full_file_full(
+ AT_FDCWD, filename,
+ /* offset= */ UINT64_MAX,
+ /* size= */ SIZE_MAX,
+ READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET,
+ /* bind_name= */ NULL,
+ &k, &n);
+ if (r < 0)
+ return log_error_errno(r, "Failed to read key file '%s': %m", filename);
+
+ iovec_done_erase(key);
+ *key = IOVEC_MAKE(TAKE_PTR(k), n);
+
+ return 0;
+}
+
+static int config_parse_key_file(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Partition *partition = ASSERT_PTR(userdata);
+
+ assert(rvalue);
+
+ if (isempty(rvalue)) {
+ iovec_done_erase(&partition->key);
+ return 0;
+ }
+
+ return parse_key_file(rvalue, &partition->key);
+}
+
static DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_verity, verity_mode, VerityMode, VERITY_OFF);
static DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_minimize, minimize_mode, MinimizeMode, MINIMIZE_OFF);
{ "Partition", "MountPoint", config_parse_mountpoint, 0, p },
{ "Partition", "EncryptedVolume", config_parse_encrypted_volume, 0, p },
{ "Partition", "TPM2PCRs", config_parse_tpm2_pcrs, 0, p },
+ { "Partition", "KeyFile", config_parse_key_file, 0, p },
{ "Partition", "Compression", config_parse_string, CONFIG_PARSE_STRING_SAFE_AND_ASCII, &p->compression },
{ "Partition", "CompressionLevel", config_parse_string, CONFIG_PARSE_STRING_SAFE_AND_ASCII, &p->compression_level },
{ "Partition", "SupplementFor", config_parse_string, 0, &p->supplement_for_name },
return log_error_errno(r, "Failed to LUKS2 format future partition: %m");
if (IN_SET(p->encrypt, ENCRYPT_KEY_FILE, ENCRYPT_KEY_FILE_TPM2)) {
+ /* Use partition-specific key if available, otherwise fall back to global key */
+ struct iovec *iovec_key = arg_key.iov_base ? &arg_key : &p->key;
+
r = sym_crypt_keyslot_add_by_volume_key(
cd,
CRYPT_ANY_SLOT,
NULL,
VOLUME_KEY_SIZE,
- strempty(arg_key.iov_base),
- arg_key.iov_len);
+ strempty(iovec_key->iov_base),
+ iovec_key->iov_len);
if (r < 0)
return log_error_errno(r, "Failed to add LUKS2 key: %m");
- passphrase = strempty(arg_key.iov_base);
- passphrase_size = arg_key.iov_len;
+ passphrase = strempty(iovec_key->iov_base);
+ passphrase_size = iovec_key->iov_len;
}
if (IN_SET(p->encrypt, ENCRYPT_TPM2, ENCRYPT_KEY_FILE_TPM2)) {
break;
case ARG_KEY_FILE: {
- struct iovec key = {};
-
- r = read_full_file_full(
- AT_FDCWD, optarg,
- /* offset= */ UINT64_MAX,
- /* size= */ SIZE_MAX,
- READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET,
- /* bind_name= */ NULL,
- (char **) &key.iov_base,
- &key.iov_len);
+ r = parse_key_file(optarg, &arg_key);
if (r < 0)
- return log_error_errno(r, "Failed to read key file '%s': %m", optarg);
-
- iovec_done_erase(&arg_key);
- arg_key = key;
+ return r;
break;
}