/* SPDX-License-Identifier: GPL-2.0+ */ /* * LUKS (Linux Unified Key Setup) filesystem support * * Copyright (C) 2025 Canonical Ltd */ #ifndef __LUKS_H__ #define __LUKS_H__ #include struct udevice; struct disk_partition; /* LUKS magic bytes: "LUKS" followed by 0xba 0xbe */ #define LUKS_MAGIC "LUKS\xba\xbe" #define LUKS_MAGIC_LEN 6 /* LUKS versions */ #define LUKS_VERSION_1 1 #define LUKS_VERSION_2 2 /* LUKS constants */ #define LUKS_DIGESTSIZE 20 #define LUKS_SALTSIZE 32 #define LUKS_NUMKEYS 8 #define LUKS_KEY_DISABLED 0x0000dead #define LUKS_KEY_ENABLED 0x00ac71f3 #define LUKS_STRIPES 4000 /** * struct luks1_keyslot - LUKS1 key slot * * @active: Key slot state (LUKS_KEY_ENABLED/DISABLED) * @iterations: PBKDF2 iteration count * @salt: Salt for PBKDF2 * @key_material_offset: Start sector of key material * @stripes: Number of anti-forensic stripes */ struct luks1_keyslot { __be32 active; __be32 iterations; char salt[LUKS_SALTSIZE]; __be32 key_material_offset; __be32 stripes; } __packed; /** * struct luks1_phdr - LUKS1 header structure * * @magic: LUKS magic bytes * @version: LUKS version * @cipher_name: Cipher name * @cipher_mode: Cipher mode * @hash_spec: Hash specification * @payload_offset: Payload offset in sectors * @key_bytes: Key length in bytes * @mk_digest: Master key digest * @mk_digest_salt: Salt for master key digest * @mk_digest_iter: Iterations for master key digest * @uuid: Partition UUID * @key_slot: Key slots (8 total) */ struct luks1_phdr { char magic[LUKS_MAGIC_LEN]; __be16 version; char cipher_name[32]; char cipher_mode[32]; char hash_spec[32]; __be32 payload_offset; __be32 key_bytes; char mk_digest[LUKS_DIGESTSIZE]; char mk_digest_salt[LUKS_SALTSIZE]; __be32 mk_digest_iter; char uuid[40]; struct luks1_keyslot key_slot[LUKS_NUMKEYS]; } __packed; /** * struct luks2_hdr - LUKS2 binary header * * @magic: LUKS magic bytes * @version: LUKS version * @hdr_size: Header size (includes binary header + JSON area) * @seqid: Sequence ID * @label: Label string * @csum_alg: Checksum algorithm * @salt: Salt for header checksum * @uuid: Partition UUID * @subsystem: Subsystem identifier * @hdr_offset: Offset of this header * @_padding: Reserved padding * @csum: Header checksum * @_padding4096: Padding to 4096 bytes */ struct luks2_hdr { char magic[LUKS_MAGIC_LEN]; __be16 version; __be64 hdr_size; __be64 seqid; char label[48]; char csum_alg[32]; u8 salt[64]; char uuid[40]; char subsystem[48]; __be64 hdr_offset; u8 _padding[184]; u8 csum[64]; u8 _padding4096[3584]; } __packed; /** * luks_detect() - Detect if a partition is LUKS encrypted * * @blk: Block device * @pinfo: Partition information * Return: 0 if LUKS partition detected, -ve on error */ int luks_detect(struct udevice *blk, struct disk_partition *pinfo); /** * luks_get_version() - Get LUKS version of a partition * * @blk: Block device * @pinfo: Partition information * Return: LUKS version (1 or 2) if detected, -ve on error */ int luks_get_version(struct udevice *blk, struct disk_partition *pinfo); /** * luks_show_info() - Display LUKS header information * * @blk: Block device * @pinfo: Partition information * Return: 0 on success, -ve on error */ int luks_show_info(struct udevice *blk, struct disk_partition *pinfo); /** * luks_unlock() - Unlock a LUKS partition with a passphrase * * This attempts to decrypt the master key using the provided passphrase. * Supports LUKS1 (PBKDF2, AES-CBC/XTS) and LUKS2 (PBKDF2/Argon2, AES-XTS). * * @blk: Block device * @pinfo: Partition information * @pass: Passphrase to unlock the partition * @pass_len: Length of the passphrase in bytes * @master_key: Buffer to receive the decrypted master key * @key_size: Size of the master_key buffer * Return: 0 on success, * -EINVAL if null parameters, * -EACCES if passphrase is incorrect, * -ENOENT if not a LUKS partition or no active key slots, * -ENOTSUPP if unsupported version/cipher/hash, * -ENOMEM if memory allocation failed, * -EIO if failed to read from block device */ int luks_unlock(struct udevice *blk, struct disk_partition *pinfo, const u8 *pass, size_t pass_len, bool pre_derived, u8 *master_key, u32 *key_size); /** * luks_create_blkmap() - Create a blkmap device for a LUKS partition * * This creates and configures a blkmap device to provide access to the * decrypted contents of a LUKS partition. The master key must already be * unlocked using luks_unlock(). * * @blk: Block device containing the LUKS partition * @pinfo: Partition information * @master_key: Unlocked master key * @key_size: Size of the master key in bytes * @label: Label for the blkmap device * @blkmap_dev: Output pointer for created blkmap device * Return: 0 on success, -ve on error */ int luks_create_blkmap(struct udevice *blk, struct disk_partition *pinfo, const u8 *master_key, u32 key_size, const char *label, struct udevice **blkmap_dev); #endif /* __LUKS_H__ */