/*
 * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
 * Copyright (C) 2018 Milan Broz <gmazyland@gmail.com>
 *
 * Inspired by libvolume_id by
 *     Kay Sievers <kay.sievers@vrfy.org>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <stdint.h>

#include "superblocks.h"

#define LUKS_CIPHERNAME_L		32
#define LUKS_CIPHERMODE_L		32
#define LUKS_HASHSPEC_L			32
#define LUKS_DIGESTSIZE			20
#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

#define LUKS_MAGIC	"LUKS\xba\xbe"
#define LUKS_MAGIC_2	"SKUL\xba\xbe"

/* Offsets for secondary header (for scan if primary header is corrupted). */
#define LUKS2_HDR2_OFFSETS { 0x04000, 0x008000, 0x010000, 0x020000, \
                             0x40000, 0x080000, 0x100000, 0x200000, 0x400000 }

static const uint64_t secondary_offsets[] = LUKS2_HDR2_OFFSETS;

struct luks_phdr {
	uint8_t		magic[LUKS_MAGIC_L];
	uint16_t	version;
	uint8_t		cipherName[LUKS_CIPHERNAME_L];
	uint8_t		cipherMode[LUKS_CIPHERMODE_L];
	uint8_t		hashSpec[LUKS_HASHSPEC_L];
	uint32_t	payloadOffset;
	uint32_t	keyBytes;
	uint8_t		mkDigest[LUKS_DIGESTSIZE];
	uint8_t		mkDigestSalt[LUKS_SALTSIZE];
	uint32_t	mkDigestIterations;
	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 luks_attributes(blkid_probe pr, struct luks2_phdr *header, uint64_t offset)
{
	int version;
	struct luks_phdr *header_v1;

	if (blkid_probe_set_magic(pr, offset, LUKS_MAGIC_L, (unsigned char *) &header->magic))
		return BLKID_PROBE_NONE;

	version = be16_to_cpu(header->version);
	blkid_probe_sprintf_version(pr, "%u", 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 BLKID_PROBE_OK;
}

static int probe_luks(blkid_probe pr, const struct blkid_idmag *mag __attribute__((__unused__)))
{
	struct luks2_phdr *header;
	size_t i;

	header = (struct luks2_phdr *) blkid_probe_get_buffer(pr, 0, sizeof(struct luks2_phdr));
	if (!header)
		return errno ? -errno : BLKID_PROBE_NONE;

	if (!memcmp(header->magic, LUKS_MAGIC, LUKS_MAGIC_L)) {
		/* LUKS primary header was found. */
		return luks_attributes(pr, header, 0);
	} else {
		/* No primary header, scan for known offsets of LUKS2 secondary header. */
		for (i = 0; i < ARRAY_SIZE(secondary_offsets); i++) {
			header = (struct luks2_phdr *) blkid_probe_get_buffer(pr,
				  secondary_offsets[i], sizeof(struct luks2_phdr));

			if (!header)
				return errno ? -errno : BLKID_PROBE_NONE;

			if (!memcmp(header->magic, LUKS_MAGIC_2, LUKS_MAGIC_L))
				return luks_attributes(pr, header, secondary_offsets[i]);
		}
	}

	return BLKID_PROBE_NONE;
}

const struct blkid_idinfo luks_idinfo =
{
	.name		= "crypto_LUKS",
	.usage		= BLKID_USAGE_CRYPTO,
	.probefunc	= probe_luks,
	.magics		= BLKID_NONE_MAGIC
};
