]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: Add detection of FileVault2 partitions
authorMilan Broz <gmazyland@gmail.com>
Mon, 12 Dec 2022 15:45:15 +0000 (16:45 +0100)
committerMilan Broz <gmazyland@gmail.com>
Mon, 12 Dec 2022 18:08:44 +0000 (19:08 +0100)
FileVault is full disk encryption format based on Apple
Core Storage, used in older macOS versions.

This patch allows automatic detection of Core Storage partition
to be later used with existing cryptsetup support for FileVault2.

Note that we intentionally ignore generic Core Storage; only
specific configuration is detected as cs_fvault2 type here.

Signed-off-by: Milan Broz <gmazyland@gmail.com>
libblkid/meson.build
libblkid/src/Makemodule.am
libblkid/src/superblocks/cs_fvault2.c [new file with mode: 0644]
libblkid/src/superblocks/superblocks.c
libblkid/src/superblocks/superblocks.h
tests/expected/blkid/low-probe-cs_fvault2 [new file with mode: 0644]
tests/ts/blkid/images-fs/cs_fvault2.img.xz [new file with mode: 0644]

index 01572af75a1220f47f3799dddc88aa786113d1f0..0cb134ff9f3b804db14a1954f80e4e7f5f8c57de 100644 (file)
@@ -55,6 +55,7 @@ lib_blkid_sources = '''
   src/superblocks/bitlocker.c
   src/superblocks/bluestore.c
   src/superblocks/btrfs.c
+  src/superblocks/cs_fvault2.c
   src/superblocks/cramfs.c
   src/superblocks/ddf_raid.c
   src/superblocks/drbd.c
index caac7f2faf85cbd616dbf4b7cb19065d72fcaf99..6cd8642e369335cf7ea538c2d9896cee0629bfc7 100644 (file)
@@ -50,6 +50,7 @@ libblkid_la_SOURCES = \
        libblkid/src/superblocks/bitlocker.c \
        libblkid/src/superblocks/bluestore.c \
        libblkid/src/superblocks/btrfs.c \
+       libblkid/src/superblocks/cs_fvault2.c \
        libblkid/src/superblocks/cramfs.c \
        libblkid/src/superblocks/ddf_raid.c \
        libblkid/src/superblocks/drbd.c \
diff --git a/libblkid/src/superblocks/cs_fvault2.c b/libblkid/src/superblocks/cs_fvault2.c
new file mode 100644 (file)
index 0000000..ef2b567
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2022 Milan Broz <gmazyland@gmail.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ */
+
+#include "superblocks.h"
+#include "crc32c.h"
+
+/*
+ * For header details, see:
+ * https://github.com/libyal/libfvde/blob/main/documentation/FileVault%20Drive%20Encryption%20(FVDE).asciidoc
+ * https://is.muni.cz/auth/th/p0aok/thesis.pdf
+ */
+
+/* Apple Core Storage magic bytes */
+#define CS_MAGIC       "CS"
+
+struct crc32_checksum {
+       uint32_t value;
+       uint32_t seed;
+} __attribute__((packed));
+
+/*
+ * The superblock structure describes "physical volume"; Core Storage
+ * then uses another abstractions above, similar to LVM.
+ * After activation through dm-crypt, filesystem (usually HFS+) is on top.
+ * The filesystem block size and used data size cannot be directly derived from
+ * this superblock structure without parsing other metadata blocks.
+ */
+
+struct cs_fvault2_sb {
+       struct crc32_checksum checksum;
+       uint16_t version;
+       uint16_t block_type;
+       uint8_t unknown1[52];
+       uint64_t ph_vol_size;
+       uint8_t unknown2[16];
+       uint16_t magic;
+       uint32_t checksum_algo;
+       uint8_t unknown3[2];
+       uint32_t block_size;
+       uint32_t metadata_size;
+       uint64_t disklbl_blkoff;
+       uint64_t other_md_blkoffs[3];
+       uint8_t unknown4[32];
+       uint32_t key_data_size;
+       uint32_t cipher;
+       uint8_t key_data[16];
+       uint8_t unknown5[112];
+       uint8_t ph_vol_uuid[16];
+       uint8_t unknown6[192];
+} __attribute__((packed));
+
+static int cs_fvault2_verify_csum(blkid_probe pr, const struct cs_fvault2_sb *sb)
+{
+       uint32_t seed = le32_to_cpu(sb->checksum.seed);
+       uint32_t crc = le32_to_cpu(sb->checksum.value);
+       unsigned char *buf = (unsigned char *)sb + sizeof(sb->checksum);
+       size_t buf_size = sizeof(*sb) - sizeof(sb->checksum);
+
+       return blkid_probe_verify_csum(pr, crc32c(seed, buf, buf_size), crc);
+}
+
+static int probe_cs_fvault2(blkid_probe pr, const struct blkid_idmag *mag)
+{
+       struct cs_fvault2_sb *sb;
+
+       sb = blkid_probe_get_sb(pr, mag, struct cs_fvault2_sb);
+       if (!sb)
+               return errno ? -errno : BLKID_PROBE_NONE;
+
+       /* Apple Core storage Physical Volume Header; only type 1 checksum is supported  */
+       if (le16_to_cpu(sb->version) != 1 ||
+           le32_to_cpu(sb->checksum_algo) != 1)
+               return BLKID_PROBE_NONE;
+
+       if (!cs_fvault2_verify_csum(pr, sb))
+               return BLKID_PROBE_NONE;
+
+       /* We support only block type 0x10 as it should be used for FileVault2 */
+       if (le16_to_cpu(sb->block_type) != 0x10 ||
+           le32_to_cpu(sb->key_data_size) != 16 ||
+           le32_to_cpu(sb->cipher) != 2 /* AES-XTS */)
+               return BLKID_PROBE_NONE;
+
+       blkid_probe_sprintf_version(pr, "%u", le16_to_cpu(sb->version));
+       blkid_probe_set_uuid(pr, sb->ph_vol_uuid);
+
+       return BLKID_PROBE_OK;
+}
+
+const struct blkid_idinfo cs_fvault2_idinfo =
+{
+       .name           = "cs_fvault2",
+       .usage          = BLKID_USAGE_CRYPTO,
+       .probefunc      = probe_cs_fvault2,
+       .magics         =
+       {
+               { .magic = CS_MAGIC, .len = 2, .sboff = 88 },
+               { NULL }
+       }
+};
index b94a2c8ae0807908659bed5ca8f3fb485e5cfeee..f1c230779ff52ce7ed49e86fa2a751dec29f270b 100644 (file)
@@ -124,6 +124,7 @@ static const struct blkid_idinfo *idinfos[] =
        &vdo_idinfo,
        &stratis_idinfo,
        &bitlocker_idinfo,
+       &cs_fvault2_idinfo,
 
        /* Filesystems */
        &vfat_idinfo,
index 0d1c461a77b32cb98ecbc8a22af535aa4dd495e0..dd0ba2b51eabb84827cec6471e0af4437232fce6 100644 (file)
@@ -98,6 +98,7 @@ extern const struct blkid_idinfo bitlocker_idinfo;
 extern const struct blkid_idinfo apfs_idinfo;
 extern const struct blkid_idinfo zonefs_idinfo;
 extern const struct blkid_idinfo erofs_idinfo;
+extern const struct blkid_idinfo cs_fvault2_idinfo;
 
 /*
  * superblock functions
diff --git a/tests/expected/blkid/low-probe-cs_fvault2 b/tests/expected/blkid/low-probe-cs_fvault2
new file mode 100644 (file)
index 0000000..0f16dcf
--- /dev/null
@@ -0,0 +1,5 @@
+ID_FS_TYPE=cs_fvault2
+ID_FS_USAGE=crypto
+ID_FS_UUID=fc52bfae-5a1f-4f9b-b3a6-f33303a0e401
+ID_FS_UUID_ENC=fc52bfae-5a1f-4f9b-b3a6-f33303a0e401
+ID_FS_VERSION=1
diff --git a/tests/ts/blkid/images-fs/cs_fvault2.img.xz b/tests/ts/blkid/images-fs/cs_fvault2.img.xz
new file mode 100644 (file)
index 0000000..a1dec14
Binary files /dev/null and b/tests/ts/blkid/images-fs/cs_fvault2.img.xz differ