/*
 * Copyright (C) 2012 Red Hat, Inc.
 * Copyright (C) 2015 Google, Inc.
 *
 * Author: Mikulas Patocka <mpatocka@redhat.com>
 *
 * Based on Chromium dm-verity driver (C) 2011 The Chromium OS Authors
 *
 * This file is released under the GPLv2.
 */

#ifndef DM_VERITY_H
#define DM_VERITY_H

#include "dm-bufio.h"
#include <linux/device-mapper.h>
#include <crypto/hash.h>
#include <linux/notifier.h>

#define DM_VERITY_MAX_LEVELS		63

enum verity_mode {
	DM_VERITY_MODE_EIO,
	DM_VERITY_MODE_LOGGING,
	DM_VERITY_MODE_RESTART
};

enum verity_block_type {
	DM_VERITY_BLOCK_TYPE_DATA,
	DM_VERITY_BLOCK_TYPE_METADATA
};

struct dm_verity_fec;

struct dm_verity {
	struct dm_dev *data_dev;
	struct dm_dev *hash_dev;
	struct dm_target *ti;
	struct dm_bufio_client *bufio;
	char *alg_name;
	struct crypto_ahash *tfm;
	u8 *root_digest;	/* digest of the root block */
	u8 *salt;		/* salt: its size is salt_size */
	u8 *zero_digest;	/* digest for a zero block */
	unsigned salt_size;
	sector_t data_start;	/* data offset in 512-byte sectors */
	sector_t hash_start;	/* hash start in blocks */
	sector_t data_blocks;	/* the number of data blocks */
	sector_t hash_blocks;	/* the number of hash blocks */
	unsigned char data_dev_block_bits;	/* log2(data blocksize) */
	unsigned char hash_dev_block_bits;	/* log2(hash blocksize) */
	unsigned char hash_per_block_bits;	/* log2(hashes in hash block) */
	unsigned char levels;	/* the number of tree levels */
	unsigned char version;
	unsigned digest_size;	/* digest size for the current hash algorithm */
	unsigned int ahash_reqsize;/* the size of temporary space for crypto */
	int hash_failed;	/* set to 1 if hash of any block failed */
	enum verity_mode mode;	/* mode for handling verification errors */
	unsigned corrupted_errs;/* Number of errors for corrupted blocks */
	int error_behavior;	/* selects error behavior on io errors */

	struct workqueue_struct *verify_wq;

	/* starting blocks for each tree level. 0 is the lowest level. */
	sector_t hash_level_block[DM_VERITY_MAX_LEVELS];

	struct dm_verity_fec *fec;	/* forward error correction */
};

struct dm_verity_io {
	struct dm_verity *v;

	/* original value of bio->bi_end_io */
	bio_end_io_t *orig_bi_end_io;

	sector_t block;
	unsigned n_blocks;

	struct bvec_iter iter;

	struct work_struct work;

	/*
	 * Three variably-size fields follow this struct:
	 *
	 * u8 hash_req[v->ahash_reqsize];
	 * u8 real_digest[v->digest_size];
	 * u8 want_digest[v->digest_size];
	 *
	 * To access them use: verity_io_hash_req(), verity_io_real_digest()
	 * and verity_io_want_digest().
	 */
};

struct verity_result {
	struct completion completion;
	int err;
};

struct dm_verity_error_state {
	int code;
	int transient;  /* Likely to not happen after a reboot */
	u64 block;
	const char *message;

	sector_t dev_start;
	sector_t dev_len;
	struct block_device *dev;

	sector_t hash_dev_start;
	sector_t hash_dev_len;
	struct block_device *hash_dev;

	/* Final behavior after all notifications are completed. */
	int behavior;
};

/* This enum must be matched to allowed_error_behaviors in dm-verity.c */
enum dm_verity_error_behavior {
	DM_VERITY_ERROR_BEHAVIOR_EIO = 0,
	DM_VERITY_ERROR_BEHAVIOR_PANIC,
	DM_VERITY_ERROR_BEHAVIOR_NONE,
	DM_VERITY_ERROR_BEHAVIOR_NOTIFY
};

int dm_verity_register_error_notifier(struct notifier_block *nb);
int dm_verity_unregister_error_notifier(struct notifier_block *nb);

static inline struct ahash_request *verity_io_hash_req(struct dm_verity *v,
						     struct dm_verity_io *io)
{
	return (struct ahash_request *)(io + 1);
}

static inline u8 *verity_io_real_digest(struct dm_verity *v,
					struct dm_verity_io *io)
{
	return (u8 *)(io + 1) + v->ahash_reqsize;
}

static inline u8 *verity_io_want_digest(struct dm_verity *v,
					struct dm_verity_io *io)
{
	return (u8 *)(io + 1) + v->ahash_reqsize + v->digest_size;
}

static inline u8 *verity_io_digest_end(struct dm_verity *v,
				       struct dm_verity_io *io)
{
	return verity_io_want_digest(v, io) + v->digest_size;
}

extern int verity_for_bv_block(struct dm_verity *v, struct dm_verity_io *io,
			       struct bvec_iter *iter,
			       int (*process)(struct dm_verity *v,
					      struct dm_verity_io *io,
					      u8 *data, size_t len));

extern int verity_hash(struct dm_verity *v, struct ahash_request *req,
		       const u8 *data, size_t len, u8 *digest);

extern int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io,
				 sector_t block, u8 *digest, bool *is_zero);

extern void verity_status(struct dm_target *ti, status_type_t type,
			unsigned status_flags, char *result, unsigned maxlen);
extern int verity_prepare_ioctl(struct dm_target *ti,
                struct block_device **bdev, fmode_t *mode);
extern int verity_iterate_devices(struct dm_target *ti,
				iterate_devices_callout_fn fn, void *data);
extern void verity_io_hints(struct dm_target *ti, struct queue_limits *limits);
extern void verity_dtr(struct dm_target *ti);
extern int verity_ctr(struct dm_target *ti, unsigned argc, char **argv);
extern int verity_map(struct dm_target *ti, struct bio *bio);
#endif /* DM_VERITY_H */
