2019-07-22 09:26:21 -07:00
/* SPDX-License-Identifier: GPL-2.0 */
/*
* fs - verity : read - only file - based authenticity protection
*
* Copyright 2019 Google LLC
*/
# ifndef _FSVERITY_PRIVATE_H
# define _FSVERITY_PRIVATE_H
# define pr_fmt(fmt) "fs-verity: " fmt
2019-07-22 09:26:22 -07:00
# include <linux/fsverity.h>
2019-12-31 11:55:45 -06:00
# include <linux/mempool.h>
2019-07-22 09:26:21 -07:00
struct ahash_request ;
/*
* Implementation limit : maximum depth of the Merkle tree . For now 8 is plenty ;
* it ' s enough for over U64_MAX bytes of data using SHA - 256 and 4 K blocks .
*/
# define FS_VERITY_MAX_LEVELS 8
/* A hash algorithm supported by fs-verity */
struct fsverity_hash_alg {
struct crypto_ahash * tfm ; /* hash tfm, allocated on demand */
const char * name ; /* crypto API name, e.g. sha256 */
unsigned int digest_size ; /* digest size in bytes, e.g. 32 for SHA-256 */
unsigned int block_size ; /* block size in bytes, e.g. 64 for SHA-256 */
2019-12-31 11:55:45 -06:00
mempool_t req_pool ; /* mempool with a preallocated hash request */
2022-11-28 20:51:39 -08:00
/*
* The HASH_ALGO_ * constant for this algorithm . This is different from
* FS_VERITY_HASH_ALG_ * , which uses a different numbering scheme .
*/
enum hash_algo algo_id ;
2019-07-22 09:26:21 -07:00
} ;
/* Merkle tree parameters: hash algorithm, initial hash state, and topology */
struct merkle_tree_params {
2019-12-31 11:55:45 -06:00
struct fsverity_hash_alg * hash_alg ; /* the hash algorithm */
2019-07-22 09:26:21 -07:00
const u8 * hashstate ; /* initial hash state or NULL */
unsigned int digest_size ; /* same as hash_alg->digest_size */
unsigned int block_size ; /* size of data and tree blocks */
unsigned int hashes_per_block ; /* number of hashes per tree block */
2022-12-23 12:36:33 -08:00
unsigned int blocks_per_page ; /* PAGE_SIZE / block_size */
2022-12-23 12:36:30 -08:00
u8 log_digestsize ; /* log2(digest_size) */
u8 log_blocksize ; /* log2(block_size) */
u8 log_arity ; /* log2(hashes_per_block) */
2022-12-23 12:36:33 -08:00
u8 log_blocks_per_page ; /* log2(blocks_per_page) */
2019-07-22 09:26:21 -07:00
unsigned int num_levels ; /* number of levels in Merkle tree */
u64 tree_size ; /* Merkle tree size in bytes */
2022-12-23 12:36:29 -08:00
unsigned long tree_pages ; /* Merkle tree size in pages */
2019-07-22 09:26:21 -07:00
/*
* Starting block index for each tree level , ordered from leaf level ( 0 )
* to root level ( ' num_levels - 1 ' )
*/
2022-12-23 12:36:28 -08:00
unsigned long level_start [ FS_VERITY_MAX_LEVELS ] ;
2019-07-22 09:26:21 -07:00
} ;
2020-05-11 12:21:17 -07:00
/*
2019-07-22 09:26:22 -07:00
* fsverity_info - cached verity metadata for an inode
*
* When a verity file is first opened , an instance of this struct is allocated
* and stored in - > i_verity_info ; it remains until the inode is evicted . It
* caches information about the Merkle tree that ' s needed to efficiently verify
2020-11-13 13:19:17 -08:00
* data read from the file . It also caches the file digest . The Merkle tree
* pages themselves are not cached here , but the filesystem may cache them .
2019-07-22 09:26:22 -07:00
*/
struct fsverity_info {
struct merkle_tree_params tree_params ;
u8 root_hash [ FS_VERITY_MAX_DIGEST_SIZE ] ;
2020-11-13 13:19:17 -08:00
u8 file_digest [ FS_VERITY_MAX_DIGEST_SIZE ] ;
2019-07-22 09:26:22 -07:00
const struct inode * inode ;
2022-12-23 12:36:33 -08:00
unsigned long * hash_block_verified ;
spinlock_t hash_page_init_lock ;
2019-07-22 09:26:22 -07:00
} ;
2019-07-22 09:26:23 -07:00
# define FS_VERITY_MAX_SIGNATURE_SIZE (FS_VERITY_MAX_DESCRIPTOR_SIZE - \
sizeof ( struct fsverity_descriptor ) )
2019-07-22 09:26:21 -07:00
/* hash_algs.c */
extern struct fsverity_hash_alg fsverity_hash_algs [ ] ;
2019-12-31 11:55:45 -06:00
struct fsverity_hash_alg * fsverity_get_hash_alg ( const struct inode * inode ,
unsigned int num ) ;
struct ahash_request * fsverity_alloc_hash_request ( struct fsverity_hash_alg * alg ,
gfp_t gfp_flags ) ;
void fsverity_free_hash_request ( struct fsverity_hash_alg * alg ,
struct ahash_request * req ) ;
const u8 * fsverity_prepare_hash_state ( struct fsverity_hash_alg * alg ,
2019-07-22 09:26:21 -07:00
const u8 * salt , size_t salt_size ) ;
2022-12-23 12:36:32 -08:00
int fsverity_hash_block ( const struct merkle_tree_params * params ,
const struct inode * inode , struct ahash_request * req ,
struct page * page , unsigned int offset , u8 * out ) ;
2019-12-31 11:55:45 -06:00
int fsverity_hash_buffer ( struct fsverity_hash_alg * alg ,
2019-07-22 09:26:21 -07:00
const void * data , size_t size , u8 * out ) ;
void __init fsverity_check_hash_algs ( void ) ;
/* init.c */
2020-05-11 12:21:18 -07:00
void __printf ( 3 , 4 ) __cold
2019-07-22 09:26:21 -07:00
fsverity_msg ( const struct inode * inode , const char * level ,
const char * fmt , . . . ) ;
# define fsverity_warn(inode, fmt, ...) \
fsverity_msg ( ( inode ) , KERN_WARNING , fmt , # # __VA_ARGS__ )
# define fsverity_err(inode, fmt, ...) \
fsverity_msg ( ( inode ) , KERN_ERR , fmt , # # __VA_ARGS__ )
2019-07-22 09:26:22 -07:00
/* open.c */
int fsverity_init_merkle_tree_params ( struct merkle_tree_params * params ,
const struct inode * inode ,
unsigned int hash_algorithm ,
unsigned int log_blocksize ,
const u8 * salt , size_t salt_size ) ;
struct fsverity_info * fsverity_create_info ( const struct inode * inode ,
2022-05-18 21:22:56 +08:00
struct fsverity_descriptor * desc ) ;
2019-07-22 09:26:22 -07:00
void fsverity_set_info ( struct inode * inode , struct fsverity_info * vi ) ;
void fsverity_free_info ( struct fsverity_info * vi ) ;
2021-01-15 10:18:14 -08:00
int fsverity_get_descriptor ( struct inode * inode ,
2022-05-18 21:22:56 +08:00
struct fsverity_descriptor * * desc_ret ) ;
2021-01-15 10:18:14 -08:00
2019-07-22 09:26:22 -07:00
int __init fsverity_init_info_cache ( void ) ;
2019-07-22 09:26:22 -07:00
void __init fsverity_exit_info_cache ( void ) ;
2019-07-22 09:26:23 -07:00
/* signature.c */
# ifdef CONFIG_FS_VERITY_BUILTIN_SIGNATURES
int fsverity_verify_signature ( const struct fsverity_info * vi ,
2021-01-15 10:18:15 -08:00
const u8 * signature , size_t sig_size ) ;
2019-07-22 09:26:23 -07:00
int __init fsverity_init_signature ( void ) ;
# else /* !CONFIG_FS_VERITY_BUILTIN_SIGNATURES */
static inline int
fsverity_verify_signature ( const struct fsverity_info * vi ,
2021-01-15 10:18:15 -08:00
const u8 * signature , size_t sig_size )
2019-07-22 09:26:23 -07:00
{
return 0 ;
}
static inline int fsverity_init_signature ( void )
{
return 0 ;
}
# endif /* !CONFIG_FS_VERITY_BUILTIN_SIGNATURES */
2019-07-22 09:26:22 -07:00
/* verify.c */
int __init fsverity_init_workqueue ( void ) ;
2019-07-22 09:26:23 -07:00
void __init fsverity_exit_workqueue ( void ) ;
2019-07-22 09:26:22 -07:00
2019-07-22 09:26:21 -07:00
# endif /* _FSVERITY_PRIVATE_H */