summaryrefslogtreecommitdiffstats
path: root/libblkid
diff options
context:
space:
mode:
authorMilan Broz2017-10-23 16:26:51 +0200
committerKarel Zak2017-10-23 16:31:46 +0200
commit573538bfba202d2c32f6688feaf2f50d8c603508 (patch)
tree93b28ea1d94a35b825621aed1f1028bdcdd0ba66 /libblkid
parentchmem: cleanup includes (diff)
downloadkernel-qcow2-util-linux-573538bfba202d2c32f6688feaf2f50d8c603508.tar.gz
kernel-qcow2-util-linux-573538bfba202d2c32f6688feaf2f50d8c603508.tar.xz
kernel-qcow2-util-linux-573538bfba202d2c32f6688feaf2f50d8c603508.zip
blkid: Add support for LUKS2 and new LABEL attributes.
This patch adds support for detection of a LUKS2 superblock. LUKS2 is new version of Linux Unified Key Setup for encrypted block devices. LUKS2 contains a binary header and then JSON area for metadata. Blkid should only parse the binary part, including newly available optional LABEL and SUBSYSTEM fields. LABEL is similar to filesystem label. The SUBSYSTEM field is in principle, just a second label and can be used for specific udev rules (for example if you have some 3rd party system that activates volumes automatically, you can mark devices using this attribute). Both labels are optional. The magic string and UUID location are intentionally on the same offset as LUKS v1, so even unpatched blkid now recognizes LUKS2. Anyway, the code should not parse other versions of the header, so we now explicitly check for header version and support only version 1 and 2. Signed-off-by: Milan Broz <gmazyland@gmail.com>
Diffstat (limited to 'libblkid')
-rw-r--r--libblkid/src/superblocks/luks.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/libblkid/src/superblocks/luks.c b/libblkid/src/superblocks/luks.c
index 00696f28c..bc3d7f558 100644
--- a/libblkid/src/superblocks/luks.c
+++ b/libblkid/src/superblocks/luks.c
@@ -24,6 +24,10 @@
#define LUKS_SALTSIZE 32
#define LUKS_MAGIC_L 6
#define UUID_STRING_L 40
+#define LUKS2_LABEL_L 48
+#define LUKS2_SALT_L 64
+#define LUKS2_CHECKSUM_ALG_L 32
+#define LUKS2_CHECKSUM_L 64
struct luks_phdr {
uint8_t magic[LUKS_MAGIC_L];
@@ -39,17 +43,47 @@ struct luks_phdr {
uint8_t uuid[UUID_STRING_L];
} __attribute__((packed));
+struct luks2_phdr {
+ char magic[LUKS_MAGIC_L];
+ uint16_t version;
+ uint64_t hdr_size; /* in bytes, including JSON area */
+ uint64_t seqid; /* increased on every update */
+ char label[LUKS2_LABEL_L];
+ char checksum_alg[LUKS2_CHECKSUM_ALG_L];
+ uint8_t salt[LUKS2_SALT_L]; /* unique for every header/offset */
+ char uuid[UUID_STRING_L];
+ char subsystem[LUKS2_LABEL_L]; /* owner subsystem label */
+ uint64_t hdr_offset; /* offset from device start in bytes */
+ char _padding[184];
+ uint8_t csum[LUKS2_CHECKSUM_L];
+ /* Padding to 4k, then JSON area */
+} __attribute__ ((packed));
+
static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct luks_phdr *header;
+ struct luks_phdr *header_v1;
+ struct luks2_phdr *header;
+ int version;
- header = blkid_probe_get_sb(pr, mag, struct luks_phdr);
+ header = blkid_probe_get_sb(pr, mag, struct luks2_phdr);
if (header == NULL)
return errno ? -errno : 1;
- blkid_probe_strncpy_uuid(pr, (unsigned char *) header->uuid,
- sizeof(header->uuid));
+ version = be16_to_cpu(header->version);
blkid_probe_sprintf_version(pr, "%u", be16_to_cpu(header->version));
+
+ if (version == 1) {
+ header_v1 = (struct luks_phdr *)header;
+ blkid_probe_strncpy_uuid(pr,
+ (unsigned char *) header_v1->uuid, UUID_STRING_L);
+ } else if (version == 2) {
+ blkid_probe_strncpy_uuid(pr,
+ (unsigned char *) header->uuid, UUID_STRING_L);
+ blkid_probe_set_label(pr,
+ (unsigned char *) header->label, LUKS2_LABEL_L);
+ blkid_probe_set_id_label(pr, "SUBSYSTEM",
+ (unsigned char *) header->subsystem, LUKS2_LABEL_L);
+ }
return 0;
}