• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * libfsverity API
4  *
5  * Copyright 2018 Google LLC
6  * Copyright (C) 2020 Facebook
7  *
8  * Use of this source code is governed by an MIT-style
9  * license that can be found in the LICENSE file or at
10  * https://opensource.org/licenses/MIT.
11  */
12 
13 #ifndef LIBFSVERITY_H
14 #define LIBFSVERITY_H
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 #include <errno.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 #define FSVERITY_UTILS_MAJOR_VERSION	1
25 #define FSVERITY_UTILS_MINOR_VERSION	3
26 
27 #define FS_VERITY_HASH_ALG_SHA256       1
28 #define FS_VERITY_HASH_ALG_SHA512       2
29 
30 /**
31  * struct libfsverity_merkle_tree_params - properties of a file's Merkle tree
32  *
33  * Zero this, then fill in at least @version and @file_size.
34  */
35 struct libfsverity_merkle_tree_params {
36 
37 	/** @version: must be 1 */
38 	uint32_t version;
39 
40 	/**
41 	 * @hash_algorithm: one of FS_VERITY_HASH_ALG_*, or 0 to use the default
42 	 * of FS_VERITY_HASH_ALG_SHA256
43 	 */
44 	uint32_t hash_algorithm;
45 
46 	/** @file_size: the file size in bytes */
47 	uint64_t file_size;
48 
49 	/**
50 	 * @block_size: the Merkle tree block size in bytes, or 0 to use the
51 	 * default of 4096 bytes
52 	 */
53 	uint32_t block_size;
54 
55 	/** @salt_size: the salt size in bytes, or 0 if unsalted */
56 	uint32_t salt_size;
57 
58 	/** @salt: pointer to the salt, or NULL if unsalted */
59 	const uint8_t *salt;
60 
61 	/** @reserved1: must be 0 */
62 	uint64_t reserved1[8];
63 
64 	/** @reserved2: must be 0 */
65 	uintptr_t reserved2[8];
66 };
67 
68 struct libfsverity_digest {
69 	uint16_t digest_algorithm;	/* one of FS_VERITY_HASH_ALG_* */
70 	uint16_t digest_size;		/* digest size in bytes */
71 	uint8_t digest[];		/* the actual digest */
72 };
73 
74 struct libfsverity_signature_params {
75 	const char *keyfile;		/* path to key file (PEM format) */
76 	const char *certfile;		/* path to certificate (PEM format) */
77 	uint64_t reserved1[8];		/* must be 0 */
78 	uintptr_t reserved2[8];		/* must be 0 */
79 };
80 
81 /*
82  * libfsverity_read_fn_t - callback that incrementally provides a file's data
83  * @fd: the user-provided "file descriptor" (opaque to library)
84  * @buf: buffer into which to read the next chunk of the file's data
85  * @count: number of bytes to read in this chunk
86  *
87  * Must return 0 on success (all 'count' bytes read), or a negative errno value
88  * on failure.
89  */
90 typedef int (*libfsverity_read_fn_t)(void *fd, void *buf, size_t count);
91 
92 /**
93  * libfsverity_compute_digest() - Compute digest of a file
94  *          A fs-verity file digest is the hash of a file's fsverity_descriptor.
95  *          Not to be confused with a traditional file digest computed over the
96  *          entire file, or with the bare fsverity_descriptor::root_hash.
97  * @fd: context that will be passed to @read_fn
98  * @read_fn: a function that will read the data of the file
99  * @params: Pointer to the Merkle tree parameters
100  * @digest_ret: Pointer to pointer for computed digest.
101  *
102  * Returns:
103  * * 0 for success, -EINVAL for invalid input arguments, -ENOMEM if libfsverity
104  *   failed to allocate memory, or an error returned by @read_fn.
105  * * digest_ret returns a pointer to the digest on success. The digest object
106  *   is allocated by libfsverity and must be freed by the caller using free().
107  */
108 int
109 libfsverity_compute_digest(void *fd, libfsverity_read_fn_t read_fn,
110 			   const struct libfsverity_merkle_tree_params *params,
111 			   struct libfsverity_digest **digest_ret);
112 
113 /**
114  * libfsverity_sign_digest() - Sign previously computed digest of a file
115  *          This signature is used by the filesystem to validate the signed file
116  *          digest against a public key loaded into the .fs-verity kernel
117  *          keyring, when CONFIG_FS_VERITY_BUILTIN_SIGNATURES is enabled. The
118  *          signature is formatted as PKCS#7 stored in DER format. See
119  *          Documentation/filesystems/fsverity.rst in the kernel source tree for
120  *          further details.
121  * @digest: pointer to previously computed digest
122  * @sig_params: struct libfsverity_signature_params providing filenames of
123  *          the keyfile and certificate file. Reserved fields must be zero.
124  * @sig_ret: Pointer to pointer for signed digest
125  * @sig_size_ret: Pointer to size of signed return digest
126  *
127  * Return:
128  * * 0 for success, -EINVAL for invalid input arguments or if the cryptographic
129  *   operations to sign the digest failed, -EBADMSG if the key and/or
130  *   certificate file is invalid, or another negative errno value.
131  * * sig_ret returns a pointer to the signed digest on success. This object
132  *   is allocated by libfsverity and must be freed by the caller using free().
133  * * sig_size_ret returns the size (in bytes) of the signed digest on success.
134  */
135 int
136 libfsverity_sign_digest(const struct libfsverity_digest *digest,
137 			const struct libfsverity_signature_params *sig_params,
138 			uint8_t **sig_ret, size_t *sig_size_ret);
139 
140 /**
141  * libfsverity_enable() - Enable fs-verity on a file
142  * @fd: read-only file descriptor to the file
143  * @params: pointer to the Merkle tree parameters
144  *
145  * This is a simple wrapper around the FS_IOC_ENABLE_VERITY ioctl.
146  *
147  * Return: 0 on success, -EINVAL for invalid arguments, or a negative errno
148  *	   value from the FS_IOC_ENABLE_VERITY ioctl.  See
149  *	   Documentation/filesystems/fsverity.rst in the kernel source tree for
150  *	   the possible error codes from FS_IOC_ENABLE_VERITY.
151  */
152 int
153 libfsverity_enable(int fd, const struct libfsverity_merkle_tree_params *params);
154 
155 /**
156  * libfsverity_enable_with_sig() - Enable fs-verity on a file, with a signature
157  * @fd: read-only file descriptor to the file
158  * @params: pointer to the Merkle tree parameters
159  * @sig: pointer to the file's signature
160  * @sig_size: size of the file's signature in bytes
161  *
162  * Like libfsverity_enable(), but allows specifying a built-in signature (i.e. a
163  * singature created with libfsverity_sign_digest()) to associate with the file.
164  * This is only needed if the in-kernel signature verification support is being
165  * used; it is not needed if signatures are being verified in userspace.
166  *
167  * If @sig is NULL and @sig_size is 0, this is the same as libfsverity_enable().
168  *
169  * Return: See libfsverity_enable().
170  */
171 int
172 libfsverity_enable_with_sig(int fd,
173 			    const struct libfsverity_merkle_tree_params *params,
174 			    const uint8_t *sig, size_t sig_size);
175 
176 /**
177  * libfsverity_find_hash_alg_by_name() - Find hash algorithm by name
178  * @name: Pointer to name of hash algorithm
179  *
180  * Return: The hash algorithm number, or zero if not found.
181  */
182 uint32_t libfsverity_find_hash_alg_by_name(const char *name);
183 
184 /**
185  * libfsverity_get_digest_size() - Get size of digest for a given algorithm
186  * @alg_num: Number of hash algorithm
187  *
188  * Return: size of digest in bytes, or -1 if algorithm is unknown.
189  */
190 int libfsverity_get_digest_size(uint32_t alg_num);
191 
192 /**
193  * libfsverity_get_hash_name() - Get name of hash algorithm by number
194  * @alg_num: Number of hash algorithm
195  *
196  * Return: The name of the hash algorithm, or NULL if algorithm is unknown.
197  */
198 const char *libfsverity_get_hash_name(uint32_t alg_num);
199 
200 /**
201  * libfsverity_set_error_callback() - Set callback to handle error messages
202  * @cb: the callback function.
203  *
204  * If a callback is already set, it is replaced.  @cb may be NULL in order to
205  * remove the existing callback.
206  */
207 void libfsverity_set_error_callback(void (*cb)(const char *msg));
208 
209 #ifdef __cplusplus
210 }
211 #endif
212 
213 #endif /* LIBFSVERITY_H */
214