From: Milan Broz Date: Mon, 12 Dec 2022 15:45:15 +0000 (+0100) Subject: libblkid: Add detection of FileVault2 partitions X-Git-Tag: v2.39-rc1~374^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=773a1fe3f14e55309bc066dfea183cb750bd1684;p=thirdparty%2Futil-linux.git libblkid: Add detection of FileVault2 partitions 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 --- diff --git a/libblkid/meson.build b/libblkid/meson.build index 01572af75a..0cb134ff9f 100644 --- a/libblkid/meson.build +++ b/libblkid/meson.build @@ -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 diff --git a/libblkid/src/Makemodule.am b/libblkid/src/Makemodule.am index caac7f2faf..6cd8642e36 100644 --- a/libblkid/src/Makemodule.am +++ b/libblkid/src/Makemodule.am @@ -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 index 0000000000..ef2b567c46 --- /dev/null +++ b/libblkid/src/superblocks/cs_fvault2.c @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2022 Milan Broz + * + * 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 } + } +}; diff --git a/libblkid/src/superblocks/superblocks.c b/libblkid/src/superblocks/superblocks.c index b94a2c8ae0..f1c230779f 100644 --- a/libblkid/src/superblocks/superblocks.c +++ b/libblkid/src/superblocks/superblocks.c @@ -124,6 +124,7 @@ static const struct blkid_idinfo *idinfos[] = &vdo_idinfo, &stratis_idinfo, &bitlocker_idinfo, + &cs_fvault2_idinfo, /* Filesystems */ &vfat_idinfo, diff --git a/libblkid/src/superblocks/superblocks.h b/libblkid/src/superblocks/superblocks.h index 0d1c461a77..dd0ba2b51e 100644 --- a/libblkid/src/superblocks/superblocks.h +++ b/libblkid/src/superblocks/superblocks.h @@ -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 index 0000000000..0f16dcf0e3 --- /dev/null +++ b/tests/expected/blkid/low-probe-cs_fvault2 @@ -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 index 0000000000..a1dec14422 Binary files /dev/null and b/tests/ts/blkid/images-fs/cs_fvault2.img.xz differ