141 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Copyright (C) 2012 Red Hat, Inc.4 * Copyright (C) 2015 Google, Inc.5 *6 * Author: Mikulas Patocka <mpatocka@redhat.com>7 *8 * Based on Chromium dm-verity driver (C) 2011 The Chromium OS Authors9 */10 11#ifndef DM_VERITY_H12#define DM_VERITY_H13 14#include <linux/dm-io.h>15#include <linux/dm-bufio.h>16#include <linux/device-mapper.h>17#include <linux/interrupt.h>18#include <crypto/hash.h>19 20#define DM_VERITY_MAX_LEVELS 6321 22enum verity_mode {23 DM_VERITY_MODE_EIO,24 DM_VERITY_MODE_LOGGING,25 DM_VERITY_MODE_RESTART,26 DM_VERITY_MODE_PANIC27};28 29enum verity_block_type {30 DM_VERITY_BLOCK_TYPE_DATA,31 DM_VERITY_BLOCK_TYPE_METADATA32};33 34struct dm_verity_fec;35 36struct dm_verity {37 struct dm_dev *data_dev;38 struct dm_dev *hash_dev;39 struct dm_target *ti;40 struct dm_bufio_client *bufio;41 char *alg_name;42 struct crypto_ahash *ahash_tfm; /* either this or shash_tfm is set */43 struct crypto_shash *shash_tfm; /* either this or ahash_tfm is set */44 u8 *root_digest; /* digest of the root block */45 u8 *salt; /* salt: its size is salt_size */46 u8 *initial_hashstate; /* salted initial state, if shash_tfm is set */47 u8 *zero_digest; /* digest for a zero block */48#ifdef CONFIG_SECURITY49 u8 *root_digest_sig; /* signature of the root digest */50 unsigned int sig_size; /* root digest signature size */51#endif /* CONFIG_SECURITY */52 unsigned int salt_size;53 sector_t data_start; /* data offset in 512-byte sectors */54 sector_t hash_start; /* hash start in blocks */55 sector_t data_blocks; /* the number of data blocks */56 sector_t hash_blocks; /* the number of hash blocks */57 unsigned char data_dev_block_bits; /* log2(data blocksize) */58 unsigned char hash_dev_block_bits; /* log2(hash blocksize) */59 unsigned char hash_per_block_bits; /* log2(hashes in hash block) */60 unsigned char levels; /* the number of tree levels */61 unsigned char version;62 bool hash_failed:1; /* set if hash of any block failed */63 bool use_bh_wq:1; /* try to verify in BH wq before normal work-queue */64 unsigned int digest_size; /* digest size for the current hash algorithm */65 unsigned int hash_reqsize; /* the size of temporary space for crypto */66 enum verity_mode mode; /* mode for handling verification errors */67 enum verity_mode error_mode;/* mode for handling I/O errors */68 unsigned int corrupted_errs;/* Number of errors for corrupted blocks */69 70 struct workqueue_struct *verify_wq;71 72 /* starting blocks for each tree level. 0 is the lowest level. */73 sector_t hash_level_block[DM_VERITY_MAX_LEVELS];74 75 struct dm_verity_fec *fec; /* forward error correction */76 unsigned long *validated_blocks; /* bitset blocks validated */77 78 char *signature_key_desc; /* signature keyring reference */79 80 struct dm_io_client *io;81 mempool_t recheck_pool;82};83 84struct dm_verity_io {85 struct dm_verity *v;86 87 /* original value of bio->bi_end_io */88 bio_end_io_t *orig_bi_end_io;89 90 struct bvec_iter iter;91 92 sector_t block;93 unsigned int n_blocks;94 bool in_bh;95 bool had_mismatch;96 97 struct work_struct work;98 struct work_struct bh_work;99 100 u8 real_digest[HASH_MAX_DIGESTSIZE];101 u8 want_digest[HASH_MAX_DIGESTSIZE];102 103 /*104 * This struct is followed by a variable-sized hash request of size105 * v->hash_reqsize, either a struct ahash_request or a struct shash_desc106 * (depending on whether ahash_tfm or shash_tfm is being used). To107 * access it, use verity_io_hash_req().108 */109};110 111static inline void *verity_io_hash_req(struct dm_verity *v,112 struct dm_verity_io *io)113{114 return io + 1;115}116 117static inline u8 *verity_io_real_digest(struct dm_verity *v,118 struct dm_verity_io *io)119{120 return io->real_digest;121}122 123static inline u8 *verity_io_want_digest(struct dm_verity *v,124 struct dm_verity_io *io)125{126 return io->want_digest;127}128 129extern int verity_hash(struct dm_verity *v, struct dm_verity_io *io,130 const u8 *data, size_t len, u8 *digest, bool may_sleep);131 132extern int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io,133 sector_t block, u8 *digest, bool *is_zero);134 135extern bool dm_is_verity_target(struct dm_target *ti);136extern int dm_verity_get_mode(struct dm_target *ti);137extern int dm_verity_get_root_digest(struct dm_target *ti, u8 **root_digest,138 unsigned int *digest_size);139 140#endif /* DM_VERITY_H */141