/*
 * Copyright (C) 1999 by Andries Brouwer
 * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
 * Copyright (C) 2001 by Andreas Dilger
 * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
 * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
 * Copyright (C) 2012 Milan Broz <mbroz@redhat.com>
 *
 * 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 <stdint.h>

#include "superblocks.h"

#define LVM1_ID_LEN 128
#define LVM2_ID_LEN 32

struct lvm2_pv_label_header {
	/* label_header */
	uint8_t		id[8];		/* LABELONE */
	uint64_t	sector_xl;	/* Sector number of this label */
	uint32_t	crc_xl;		/* From next field to end of sector */
	uint32_t	offset_xl;	/* Offset from start of struct to contents */
	uint8_t		type[8];	/* LVM2 001 */
	/* pv_header */
	uint8_t		pv_uuid[LVM2_ID_LEN];
} __attribute__ ((packed));

struct lvm1_pv_label_header {
	uint8_t id[2];			/* HM */
	uint16_t version;		/* version 1 or 2 */
	uint32_t _notused[10];		/* lvm1 internals */
	uint8_t pv_uuid[LVM1_ID_LEN];
} __attribute__ ((packed));

#define LVM2_LABEL_SIZE 512
static unsigned int lvm2_calc_crc(const void *buf, unsigned int size)
{
	static const unsigned int crctab[] = {
		0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
		0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
		0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
		0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
	};
	unsigned int i, crc = 0xf597a6cf;
	const uint8_t *data = (const uint8_t *) buf;

	for (i = 0; i < size; i++) {
		crc ^= *data++;
		crc = (crc >> 4) ^ crctab[crc & 0xf];
		crc = (crc >> 4) ^ crctab[crc & 0xf];
	}
	return crc;
}

/* Length of real UUID is always LVM2_ID_LEN */
static void format_lvm_uuid(char *dst_uuid, char *src_uuid)
{
	unsigned int i, b;

	for (i = 0, b = 1; i < LVM2_ID_LEN; i++, b <<= 1) {
		if (b & 0x4444440)
			*dst_uuid++ = '-';
		*dst_uuid++ = *src_uuid++;
	}
	*dst_uuid = '\0';
}

static int probe_lvm2(blkid_probe pr, const struct blkid_idmag *mag)
{
	int sector = mag->kboff << 1;
	struct lvm2_pv_label_header *label;
	char uuid[LVM2_ID_LEN + 7];
	unsigned char *buf;

	buf = blkid_probe_get_buffer(pr,
			mag->kboff << 10,
			512 + sizeof(struct lvm2_pv_label_header));
	if (!buf)
		return errno ? -errno : 1;

	/* buf is at 0k or 1k offset; find label inside */
	if (memcmp(buf, "LABELONE", 8) == 0) {
		label = (struct lvm2_pv_label_header *) buf;
	} else if (memcmp(buf + 512, "LABELONE", 8) == 0) {
		label = (struct lvm2_pv_label_header *)(buf + 512);
		sector++;
	} else {
		return 1;
	}

	if (le64_to_cpu(label->sector_xl) != (unsigned) sector)
		return 1;

	if (!blkid_probe_verify_csum(
		pr, lvm2_calc_crc(
			&label->offset_xl, LVM2_LABEL_SIZE -
			((char *) &label->offset_xl - (char *) label)),
			le32_to_cpu(label->crc_xl)))
		return 1;

	format_lvm_uuid(uuid, (char *) label->pv_uuid);
	blkid_probe_sprintf_uuid(pr, label->pv_uuid, sizeof(label->pv_uuid),
			"%s", uuid);

	/* the mag->magic is the same string as label->type,
	 * but zero terminated */
	blkid_probe_set_version(pr, mag->magic);

	/* LVM (pvcreate) wipes begin of the device -- let's remember this
	 * to resolve conflicts bettween LVM and partition tables, ...
	 */
	blkid_probe_set_wiper(pr, 0, 8 * 1024);

	return 0;
}

static int probe_lvm1(blkid_probe pr, const struct blkid_idmag *mag)
{
	struct lvm1_pv_label_header *label;
	char uuid[LVM2_ID_LEN + 7];
	unsigned int version;

	label = blkid_probe_get_sb(pr, mag, struct lvm1_pv_label_header);
	if (!label)
		return errno ? -errno : 1;

	version = le16_to_cpu(label->version);
	if (version != 1 && version != 2)
		return 1;

	format_lvm_uuid(uuid, (char *) label->pv_uuid);
	blkid_probe_sprintf_uuid(pr, label->pv_uuid, sizeof(label->pv_uuid),
			"%s", uuid);

	return 0;
}

struct verity_sb {
	uint8_t  signature[8];	/* "verity\0\0" */
	uint32_t version;	/* superblock version */
	uint32_t hash_type;	/* 0 - Chrome OS, 1 - normal */
	uint8_t  uuid[16];	/* UUID of hash device */
	uint8_t  algorithm[32];/* hash algorithm name */
	uint32_t data_block_size; /* data block in bytes */
	uint32_t hash_block_size; /* hash block in bytes */
	uint64_t data_blocks;	/* number of data blocks */
	uint16_t salt_size;	/* salt size */
	uint8_t  _pad1[6];
	uint8_t  salt[256];	/* salt */
	uint8_t  _pad2[168];
} __attribute__((packed));

static int probe_verity(blkid_probe pr, const struct blkid_idmag *mag)
{
	struct verity_sb *sb;
	unsigned int version;

	sb = blkid_probe_get_sb(pr, mag, struct verity_sb);
	if (sb == NULL)
		return errno ? -errno : 1;

	version = le32_to_cpu(sb->version);
	if (version != 1)
		return 1;

	blkid_probe_set_uuid(pr, sb->uuid);
	blkid_probe_sprintf_version(pr, "%u", version);
	return 0;
}

/* NOTE: the original libblkid uses "lvm2pv" as a name */
const struct blkid_idinfo lvm2_idinfo =
{
	.name		= "LVM2_member",
	.usage		= BLKID_USAGE_RAID,
	.probefunc	= probe_lvm2,
	.magics		=
	{
		{ .magic = "LVM2 001", .len = 8, .sboff = 0x218 },
		{ .magic = "LVM2 001", .len = 8, .sboff = 0x018 },
		{ .magic = "LVM2 001", .len = 8, .kboff = 1, .sboff = 0x018 },
		{ .magic = "LVM2 001", .len = 8, .kboff = 1, .sboff = 0x218 },
		{ NULL }
	}
};

const struct blkid_idinfo lvm1_idinfo =
{
	.name		= "LVM1_member",
	.usage		= BLKID_USAGE_RAID,
	.probefunc	= probe_lvm1,
	.magics		=
	{
		{ .magic = "HM", .len = 2 },
		{ NULL }
	}
};

const struct blkid_idinfo snapcow_idinfo =
{
	.name		= "DM_snapshot_cow",
	.usage		= BLKID_USAGE_OTHER,
	.magics		=
	{
		{ .magic = "SnAp", .len = 4 },
		{ NULL }
	}
};

const struct blkid_idinfo verity_hash_idinfo =
{
	.name		= "DM_verity_hash",
	.usage		= BLKID_USAGE_CRYPTO,
	.probefunc	= probe_verity,
	.magics		=
	{
		{ .magic = "verity\0\0", .len = 8 },
		{ NULL }
	}
};
