Files
u-boot/include/luks.h
Simon Glass 48dd57511c luks: Support a pre-derived key
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>
2025-11-17 06:59:47 -07:00

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__ */