return log_oom();
color = (f & _PARTITION_POLICY_USE_MASK) == PARTITION_POLICY_IGNORE ? ansi_grey() :
- ((f & (PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ABSENT)) ==
- (PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ABSENT)) ? ansi_highlight_yellow() :
+ ((f & (PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ABSENT)) ==
+ (PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ABSENT)) ? ansi_highlight_yellow() :
(f & _PARTITION_POLICY_USE_MASK) == PARTITION_POLICY_ABSENT ? ansi_highlight_red() :
!(f & PARTITION_POLICY_UNPROTECTED) ? ansi_highlight_green() : NULL;
DLSYM_PROTOTYPE(crypt_volume_key_get) = NULL;
DLSYM_PROTOTYPE(crypt_volume_key_keyring) = NULL;
DLSYM_PROTOTYPE(crypt_wipe) = NULL;
+DLSYM_PROTOTYPE(crypt_get_integrity_info) = NULL;
static void cryptsetup_log_glue(int level, const char *msg, void *usrptr) {
DLSYM_ARG(crypt_token_status),
DLSYM_ARG(crypt_volume_key_get),
DLSYM_ARG(crypt_volume_key_keyring),
- DLSYM_ARG(crypt_wipe));
+ DLSYM_ARG(crypt_wipe),
+ DLSYM_ARG(crypt_get_integrity_info));
if (r <= 0)
return r;
extern DLSYM_PROTOTYPE(crypt_volume_key_get);
extern DLSYM_PROTOTYPE(crypt_volume_key_keyring);
extern DLSYM_PROTOTYPE(crypt_wipe);
+extern DLSYM_PROTOTYPE(crypt_get_integrity_info);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct crypt_device *, crypt_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct crypt_device *, sym_crypt_free, NULL);
return 0;
}
+/* internal LUKS2 header defines */
+#define LUKS2_FIXED_HDR_SIZE UINT64_C(0x1000)
+#define LUKS2_MAGIC "LUKS\xba\xbe"
+
+/* Matches the beginning of 'struct luks2_hdr_disk' from cryptsetup */
+struct luks_header_incomplete {
+ char luks_magic[sizeof(LUKS2_MAGIC) - 1];
+ be16_t version;
+ be64_t hdr_len;
+};
+
+/* 'integrity' information from LUKS JSON header. Currenly, only 'type' is extracted/checked. */
+struct luks_integrity_data {
+ char *type;
+};
+
+static int integrity_information(const char *name, sd_json_variant *v, sd_json_dispatch_flags_t flags, void *userdata) {
+ static const sd_json_dispatch_field table[] = {
+ { "type", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(struct luks_integrity_data, type), SD_JSON_MANDATORY },
+ {}
+ };
+
+ return sd_json_dispatch(v, table, flags, userdata);
+}
+
+/* cryptsetup needs a loop device to work with a partition which has offset/size but
+ * dissect may be running unpriviliged. Implement a minimal custom LUKS header parser
+ * checking integrity protection information. */
+static int partition_is_luks2_integrity(int part_fd, uint64_t offset, uint64_t size) {
+ _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
+ _cleanup_free_ char *json = NULL;
+ sd_json_variant *w;
+ const char *key;
+ struct luks_header_incomplete header;
+ ssize_t sz, json_len;
+ int r;
+
+ assert(part_fd >= 0);
+
+ if (size < LUKS2_FIXED_HDR_SIZE) {
+ log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Partition is too small to contain a LUKS header.");
+ return 0;
+ }
+
+ sz = pread(part_fd, &header, sizeof(header), offset);
+ if (sz < 0)
+ return log_error_errno(errno, "Failed to read LUKS header.");
+ if (sz != sizeof(header))
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to read LUKS header.");
+
+ if (memcmp(header.luks_magic, LUKS2_MAGIC, sizeof(header.luks_magic)) != 0)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Partition's magic is not LUKS.");
+
+ if (be16toh(header.version) != 2)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unsupported LUKS header version: %" PRIu16 ".", be16toh(header.version));
+
+ if (be64toh(header.hdr_len) > size)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "LUKS header length exceeds partition size.");
+
+ if (be64toh(header.hdr_len) <= LUKS2_FIXED_HDR_SIZE || offset > UINT64_MAX - be64toh(header.hdr_len))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid LUKS header length: %" PRIu64 ".", be64toh(header.hdr_len));
+
+ json_len = be64toh(header.hdr_len) - LUKS2_FIXED_HDR_SIZE;
+ json = malloc(json_len + 1);
+ if (!json)
+ return -ENOMEM;
+
+ sz = pread(part_fd, json, json_len, offset + LUKS2_FIXED_HDR_SIZE);
+ if (sz < 0)
+ return log_error_errno(errno, "Failed to read LUKS JSON header.");
+ if (sz != json_len)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to read LUKS JSON header.");
+ json[sz] = '\0';
+
+ r = sd_json_parse(json, /* flags = */ 0, &v, /* reterr_line = */ NULL, /* reterr_column = */ NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse LUKS JSON header.");
+
+ v = sd_json_variant_by_key(v, "segments");
+ if (!v || !sd_json_variant_is_object(v)) {
+ log_debug("LUKS JSON header lacks 'segments' information, assuming no integrity.");
+ return 0;
+ }
+
+ /* Verify that all segments have integrity protection */
+ JSON_VARIANT_OBJECT_FOREACH(key, w, v) {
+ struct luks_integrity_data data = {};
+
+ static const sd_json_dispatch_field dispatch_segment[] = {
+ { "integrity", SD_JSON_VARIANT_OBJECT, integrity_information, 0, SD_JSON_MANDATORY },
+ {}
+ };
+
+ r = sd_json_dispatch(w, dispatch_segment, SD_JSON_ALLOW_EXTENSIONS, &data);
+ if (r < 0) {
+ log_debug("Failed to get integrity information from LUKS JSON for segment %s, assuming no integrity.", key);
+ return 0;
+ }
+
+ /* We don't require a particular integrity algorithm, everything but 'none' (which shouldn't
+ * be there in the first place but is theoretically possible) works. */
+ if (streq(data.type, "none"))
+ return 0;
+ }
+
+ return 1;
+}
+
static int image_policy_check_partition_flags(
const ImagePolicy *policy,
PartitionDesignator designator,
if (streq_ptr(p->fstype, "crypto_LUKS")) {
m->encrypted = true;
- found_flags = PARTITION_POLICY_UNUSED|PARTITION_POLICY_ENCRYPTED; /* found this one, and its definitely encrypted */
+
+ if (p->mount_node_fd >= 0)
+ r = partition_is_luks2_integrity(p->mount_node_fd, /* offset = */ 0, /* size = */ UINT64_MAX);
+ else
+ r = partition_is_luks2_integrity(fd, p->offset, p->size);
+ if (r < 0)
+ return r;
+
+ /* found this one, it's definitely encrypted + with or without integrity checking */
+ found_flags = PARTITION_POLICY_UNUSED|(r > 0 ? PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY : PARTITION_POLICY_ENCRYPTED);
} else
/* found it, but it's definitely not encrypted, hence mask the encrypted flag, but
* set all other ways that indicate "present". */
if (verity_settings_data_covers(verity, PARTITION_ROOT))
found_flags = iovec_is_set(&verity->root_hash_sig) ? PARTITION_POLICY_SIGNED : PARTITION_POLICY_VERITY;
- else
- found_flags = encrypted ? PARTITION_POLICY_ENCRYPTED : PARTITION_POLICY_UNPROTECTED;
+ else if (encrypted) {
+ r = partition_is_luks2_integrity(fd, /* offset = */ 0, /* size = */ UINT64_MAX);
+ if (r < 0)
+ return r;
+
+ found_flags = r > 0 ? PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY : PARTITION_POLICY_ENCRYPTED;
+ } else
+ found_flags = PARTITION_POLICY_UNPROTECTED;
r = image_policy_check_protection(policy, PARTITION_ROOT, found_flags);
if (r < 0)
/* Determine the verity protection level for this partition. */
PartitionPolicyFlags found_flags;
if (m->partitions[di].found) {
- found_flags = PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_UNUSED;
+ found_flags = PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_UNUSED;
PartitionDesignator vi = partition_verity_hash_of(di);
if (vi >= 0 && m->partitions[vi].found) {
* all needs no protection, because it *is* the protection */
if (partition_verity_hash_to_data(policy->designator) >= 0 ||
partition_verity_sig_to_data(policy->designator) >= 0)
- flags &= ~(PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED);
+ flags &= ~(PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY);
/* if this designator has no verity concept, then mask off verity protection flags */
if (partition_verity_hash_of(policy->designator) < 0)
return PARTITION_POLICY_SIGNED;
if (streq(s, "encrypted"))
return PARTITION_POLICY_ENCRYPTED;
+ if (streq(s, "encryptedwithintegrity"))
+ return PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY;
if (streq(s, "unprotected"))
return PARTITION_POLICY_UNPROTECTED;
if (streq(s, "unused"))
l[m++] = "signed";
if (flags & PARTITION_POLICY_ENCRYPTED)
l[m++] = "encrypted";
+ if (flags & PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY)
+ l[m++] = "encryptedwithintegrity";
if (flags & PARTITION_POLICY_UNPROTECTED)
l[m++] = "unprotected";
if (flags & PARTITION_POLICY_UNUSED)
* be. */
.n_policies = 2,
.policies = {
- { PARTITION_ROOT, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_USR, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_ROOT, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_USR, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
},
.default_flags = PARTITION_POLICY_IGNORE,
};
* are only interested in the /etc/ tree anyway, and that's really the only place it can be. */
.n_policies = 1,
.policies = {
- { PARTITION_ROOT, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_ROOT, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
},
.default_flags = PARTITION_POLICY_IGNORE,
};
/* For systemd-nspawn containers we use all partitions, with the exception of swap */
.n_policies = 8,
.policies = {
- { PARTITION_ROOT, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_USR, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_HOME, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_SRV, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_ROOT, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_USR, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_HOME, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_SRV, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
{ PARTITION_ESP, PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
{ PARTITION_XBOOTLDR, PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_TMP, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_VAR, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_TMP, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_VAR, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
},
.default_flags = PARTITION_POLICY_IGNORE,
};
/* For the host policy we basically use everything */
.n_policies = 9,
.policies = {
- { PARTITION_ROOT, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_USR, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_HOME, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_SRV, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_ROOT, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_USR, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_HOME, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_SRV, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
{ PARTITION_ESP, PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
{ PARTITION_XBOOTLDR, PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_SWAP, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_TMP, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_VAR, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_SWAP, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_TMP, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_VAR, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
},
.default_flags = PARTITION_POLICY_IGNORE,
};
/* For RootImage= in services we skip ESP/XBOOTLDR and swap */
.n_policies = 6,
.policies = {
- { PARTITION_ROOT, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_USR, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_HOME, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_SRV, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_TMP, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
- { PARTITION_VAR, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_ROOT, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_USR, PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_HOME, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_SRV, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_TMP, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
+ { PARTITION_VAR, PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_ABSENT },
},
.default_flags = PARTITION_POLICY_IGNORE,
};
* on. Example: a default policy of "verity+encrypted" certainly makes sense, but for /home/
* partitions this gracefully degrades to "encrypted" (as we do not have a concept of verity for
* /home/), and so on. */
- PARTITION_POLICY_VERITY = 1 << 0, /* must exist, activate with verity (only applies to root/usr partitions) */
- PARTITION_POLICY_SIGNED = 1 << 1, /* must exist, activate with signed verity (only applies to root/usr partitions) */
- PARTITION_POLICY_ENCRYPTED = 1 << 2, /* must exist, activate with LUKS encryption (applies to any data partition, but not to verity/signature partitions */
- PARTITION_POLICY_UNPROTECTED = 1 << 3, /* must exist, activate without encryption/verity */
- PARTITION_POLICY_UNUSED = 1 << 4, /* must exist, don't use */
- PARTITION_POLICY_ABSENT = 1 << 5, /* must not exist */
- PARTITION_POLICY_OPEN = PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|
- PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_UNUSED|PARTITION_POLICY_ABSENT,
- PARTITION_POLICY_IGNORE = PARTITION_POLICY_UNUSED|PARTITION_POLICY_ABSENT,
- _PARTITION_POLICY_USE_MASK = PARTITION_POLICY_OPEN,
-
- PARTITION_POLICY_READ_ONLY_OFF = 1 << 6, /* State of GPT partition flag "read-only" must be on */
- PARTITION_POLICY_READ_ONLY_ON = 1 << 7,
- _PARTITION_POLICY_READ_ONLY_MASK = PARTITION_POLICY_READ_ONLY_OFF|PARTITION_POLICY_READ_ONLY_ON,
- PARTITION_POLICY_GROWFS_OFF = 1 << 8, /* State of GPT partition flag "growfs" must be on */
- PARTITION_POLICY_GROWFS_ON = 1 << 9,
- _PARTITION_POLICY_GROWFS_MASK = PARTITION_POLICY_GROWFS_OFF|PARTITION_POLICY_GROWFS_ON,
- _PARTITION_POLICY_PFLAGS_MASK = _PARTITION_POLICY_READ_ONLY_MASK|_PARTITION_POLICY_GROWFS_MASK,
-
- _PARTITION_POLICY_MASK = _PARTITION_POLICY_USE_MASK|_PARTITION_POLICY_READ_ONLY_MASK|_PARTITION_POLICY_GROWFS_MASK,
-
- _PARTITION_POLICY_FLAGS_INVALID = -EINVAL,
- _PARTITION_POLICY_FLAGS_ERRNO_MAX = -ERRNO_MAX, /* Ensure the whole errno range fits into this enum */
+ PARTITION_POLICY_VERITY = 1 << 0, /* must exist, activate with verity (only applies to root/usr partitions) */
+ PARTITION_POLICY_SIGNED = 1 << 1, /* must exist, activate with signed verity (only applies to root/usr partitions) */
+ PARTITION_POLICY_ENCRYPTED = 1 << 2, /* must exist, activate with LUKS encryption (applies to any data partition, but not to verity/signature partitions */
+ PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY = 1 << 3, /* same as PARTITION_POLICY_ENCRYPTED but also requires integrity checking */
+ PARTITION_POLICY_UNPROTECTED = 1 << 4, /* must exist, activate without encryption/verity */
+ PARTITION_POLICY_UNUSED = 1 << 5, /* must exist, don't use */
+ PARTITION_POLICY_ABSENT = 1 << 6, /* must not exist */
+ PARTITION_POLICY_OPEN = PARTITION_POLICY_VERITY|PARTITION_POLICY_SIGNED|PARTITION_POLICY_ENCRYPTED|PARTITION_POLICY_ENCRYPTEDWITHINTEGRITY|
+ PARTITION_POLICY_UNPROTECTED|PARTITION_POLICY_UNUSED|PARTITION_POLICY_ABSENT,
+ PARTITION_POLICY_IGNORE = PARTITION_POLICY_UNUSED|PARTITION_POLICY_ABSENT,
+ _PARTITION_POLICY_USE_MASK = PARTITION_POLICY_OPEN,
+
+ PARTITION_POLICY_READ_ONLY_OFF = 1 << 7, /* State of GPT partition flag "read-only" must be on */
+ PARTITION_POLICY_READ_ONLY_ON = 1 << 8,
+ _PARTITION_POLICY_READ_ONLY_MASK = PARTITION_POLICY_READ_ONLY_OFF|PARTITION_POLICY_READ_ONLY_ON,
+ PARTITION_POLICY_GROWFS_OFF = 1 << 9, /* State of GPT partition flag "growfs" must be on */
+ PARTITION_POLICY_GROWFS_ON = 1 << 10,
+ _PARTITION_POLICY_GROWFS_MASK = PARTITION_POLICY_GROWFS_OFF|PARTITION_POLICY_GROWFS_ON,
+ _PARTITION_POLICY_PFLAGS_MASK = _PARTITION_POLICY_READ_ONLY_MASK|_PARTITION_POLICY_GROWFS_MASK,
+
+ _PARTITION_POLICY_MASK = _PARTITION_POLICY_USE_MASK|_PARTITION_POLICY_READ_ONLY_MASK|_PARTITION_POLICY_GROWFS_MASK,
+
+ _PARTITION_POLICY_FLAGS_INVALID = -EINVAL,
+ _PARTITION_POLICY_FLAGS_ERRNO_MAX = -ERRNO_MAX, /* Ensure the whole errno range fits into this enum */
} PartitionPolicyFlags;
assert_cc((_PARTITION_POLICY_USE_MASK | _PARTITION_POLICY_PFLAGS_MASK) >= 0); /* ensure flags don't collide with errno range */
test_policy_equiv("~", image_policy_equiv_deny);
test_policy_equiv("=absent", image_policy_equiv_deny);
test_policy_equiv("=open", image_policy_equiv_allow);
- test_policy_equiv("=verity+signed+encrypted+unprotected+unused+absent", image_policy_equiv_allow);
- test_policy_equiv("=signed+verity+encrypted+unused+unprotected+absent", image_policy_equiv_allow);
+ test_policy_equiv("=verity+signed+encrypted+encryptedwithintegrity+unprotected+unused+absent", image_policy_equiv_allow);
+ test_policy_equiv("=signed+verity+encrypted+encryptedwithintegrity+unused+unprotected+absent", image_policy_equiv_allow);
test_policy_equiv("=ignore", image_policy_equiv_ignore);
test_policy_equiv("=absent+unused", image_policy_equiv_ignore);
test_policy_equiv("=unused+absent", image_policy_equiv_ignore);
# Let's also test the "image-policy" verb
-systemd-analyze image-policy '*' 2>&1 | grep -F "Long form: =verity+signed+encrypted+unprotected+unused+absent" >/dev/null
+systemd-analyze image-policy '*' 2>&1 | grep -F "Long form: =verity+signed+encrypted+encryptedwithintegrity+unprotected+unused+absent" >/dev/null
systemd-analyze image-policy '-' 2>&1 | grep -F "Long form: =unused+absent" >/dev/null
systemd-analyze image-policy 'home=encrypted:usr=verity' 2>&1 | grep -F "Long form: usr=verity:home=encrypted:=unused+absent" >/dev/null
systemd-analyze image-policy 'home=encrypted:usr=verity' 2>&1 | grep -e '^home \+encrypted \+' >/dev/null