Update luks_unlock() to support a pre-derived key, such as that obtained from a TKey. This must match the key_size of the LUKS partition, otherwise it will fail to unlock. Signed-off-by: Simon Glass <simon.glass@canonical.com>
184 lines
5.0 KiB
C
184 lines
5.0 KiB
C
/* 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 <linux/types.h>
|
|
|
|
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__ */
|