• 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	5
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 	/**
65 	 * @metadata_callbacks: if non-NULL, this gives a set of callback
66 	 * functions to which libfsverity_compute_digest() will pass the Merkle
67 	 * tree blocks and fs-verity descriptor after they are computed.
68 	 * Normally this isn't useful, but this can be needed in rare cases
69 	 * where the metadata needs to be consumed by something other than one
70 	 * of the native Linux kernel implementations of fs-verity.
71 	 */
72 	const struct libfsverity_metadata_callbacks *metadata_callbacks;
73 
74 	/** @reserved2: must be 0 */
75 	uintptr_t reserved2[7];
76 };
77 
78 struct libfsverity_digest {
79 	uint16_t digest_algorithm;	/* one of FS_VERITY_HASH_ALG_* */
80 	uint16_t digest_size;		/* digest size in bytes */
81 	uint8_t digest[];		/* the actual digest */
82 };
83 
84 /**
85  * struct libfsverity_signature_params - certificate and private key information
86  *
87  * Zero this, then set @certfile.  Then, to specify the private key by key file,
88  * set @keyfile.  Alternatively, to specify the private key by PKCS#11 token,
89  * set @pkcs11_engine, @pkcs11_module, and optionally @pkcs11_keyid.
90  *
91  * Support for PKCS#11 tokens is unavailable when libfsverity was linked to
92  * BoringSSL rather than OpenSSL.
93  */
94 struct libfsverity_signature_params {
95 
96 	/** @keyfile: the path to the key file in PEM format, when applicable */
97 	const char *keyfile;
98 
99 	/** @certfile: the path to the certificate file in PEM format */
100 	const char *certfile;
101 
102 	/** @reserved1: must be 0 */
103 	uint64_t reserved1[8];
104 
105 	/**
106 	 * @pkcs11_engine: the path to the PKCS#11 engine .so file, when
107 	 * applicable
108 	 */
109 	const char *pkcs11_engine;
110 
111 	/**
112 	 * @pkcs11_module: the path to the PKCS#11 module .so file, when
113 	 * applicable
114 	 */
115 	const char *pkcs11_module;
116 
117 	/** @pkcs11_keyid: the PKCS#11 key identifier, when applicable */
118 	const char *pkcs11_keyid;
119 
120 	/** @reserved2: must be 0 */
121 	uintptr_t reserved2[5];
122 };
123 
124 struct libfsverity_metadata_callbacks {
125 
126 	/** @ctx: context passed to the below callbacks (opaque to library) */
127 	void *ctx;
128 
129 	/**
130 	 * @merkle_tree_size: if non-NULL, called with the total size of the
131 	 * Merkle tree in bytes, prior to any call to @merkle_tree_block.  Must
132 	 * return 0 on success, or a negative errno value on failure.
133 	 */
134 	int (*merkle_tree_size)(void *ctx, uint64_t size);
135 
136 	/**
137 	 * @merkle_tree_block: if non-NULL, called with each block of the
138 	 * Merkle tree after it is computed.  The offset is the offset in bytes
139 	 * to the block within the Merkle tree, using the Merkle tree layout
140 	 * used by FS_IOC_READ_VERITY_METADATA.  The offsets won't necessarily
141 	 * be in increasing order.  Must return 0 on success, or a negative
142 	 * errno value on failure.
143 	 */
144 	int (*merkle_tree_block)(void *ctx, const void *block, size_t size,
145 				 uint64_t offset);
146 
147 	/**
148 	 * @descriptor: if non-NULL, called with the fs-verity descriptor after
149 	 * it is computed.  Must return 0 on success, or a negative errno value
150 	 * on failure.
151 	 */
152 	int (*descriptor)(void *ctx, const void *descriptor, size_t size);
153 };
154 
155 /*
156  * libfsverity_read_fn_t - callback that incrementally provides a file's data
157  * @fd: the user-provided "file descriptor" (opaque to library)
158  * @buf: buffer into which to read the next chunk of the file's data
159  * @count: number of bytes to read in this chunk
160  *
161  * Must return 0 on success (all 'count' bytes read), or a negative errno value
162  * on failure.
163  */
164 typedef int (*libfsverity_read_fn_t)(void *fd, void *buf, size_t count);
165 
166 /**
167  * libfsverity_compute_digest() - Compute digest of a file
168  *          A fs-verity file digest is the hash of a file's fsverity_descriptor.
169  *          Not to be confused with a traditional file digest computed over the
170  *          entire file, or with the bare fsverity_descriptor::root_hash.
171  * @fd: context that will be passed to @read_fn
172  * @read_fn: a function that will read the data of the file
173  * @params: Pointer to the Merkle tree parameters
174  * @digest_ret: Pointer to pointer for computed digest.
175  *
176  * Returns:
177  * * 0 for success, -EINVAL for invalid input arguments, -ENOMEM if libfsverity
178  *   failed to allocate memory, or an error returned by @read_fn or by one of
179  *   the @params->metadata_callbacks.
180  * * digest_ret returns a pointer to the digest on success. The digest object
181  *   is allocated by libfsverity and must be freed by the caller using free().
182  */
183 int
184 libfsverity_compute_digest(void *fd, libfsverity_read_fn_t read_fn,
185 			   const struct libfsverity_merkle_tree_params *params,
186 			   struct libfsverity_digest **digest_ret);
187 
188 /**
189  * libfsverity_sign_digest() - Sign a file for built-in signature verification
190  *	    Sign a file digest in a way that is compatible with the Linux
191  *	    kernel's fs-verity built-in signature verification support.  The
192  *	    resulting signature will be a PKCS#7 message in DER format.  Note
193  *	    that this is not the only way to do signatures with fs-verity.  For
194  *	    more details, refer to the fsverity-utils README and to
195  *	    Documentation/filesystems/fsverity.rst in the kernel source tree.
196  * @digest: pointer to previously computed digest
197  * @sig_params: pointer to the certificate and private key information
198  * @sig_ret: Pointer to pointer for signed digest
199  * @sig_size_ret: Pointer to size of signed return digest
200  *
201  * Return:
202  * * 0 for success, -EINVAL for invalid input arguments or if the cryptographic
203  *   operations to sign the digest failed, -EBADMSG if the key and/or
204  *   certificate file is invalid, or another negative errno value.
205  * * sig_ret returns a pointer to the signed digest on success. This object
206  *   is allocated by libfsverity and must be freed by the caller using free().
207  * * sig_size_ret returns the size (in bytes) of the signed digest on success.
208  */
209 int
210 libfsverity_sign_digest(const struct libfsverity_digest *digest,
211 			const struct libfsverity_signature_params *sig_params,
212 			uint8_t **sig_ret, size_t *sig_size_ret);
213 
214 /**
215  * libfsverity_enable() - Enable fs-verity on a file
216  * @fd: read-only file descriptor to the file
217  * @params: pointer to the Merkle tree parameters
218  *
219  * This is a simple wrapper around the FS_IOC_ENABLE_VERITY ioctl.
220  *
221  * Return: 0 on success, -EINVAL for invalid arguments, or a negative errno
222  *	   value from the FS_IOC_ENABLE_VERITY ioctl.  See
223  *	   Documentation/filesystems/fsverity.rst in the kernel source tree for
224  *	   the possible error codes from FS_IOC_ENABLE_VERITY.
225  */
226 int
227 libfsverity_enable(int fd, const struct libfsverity_merkle_tree_params *params);
228 
229 /**
230  * libfsverity_enable_with_sig() - Enable fs-verity on a file, with a signature
231  * @fd: read-only file descriptor to the file
232  * @params: pointer to the Merkle tree parameters
233  * @sig: pointer to the file's signature
234  * @sig_size: size of the file's signature in bytes
235  *
236  * Like libfsverity_enable(), but allows specifying a built-in signature (i.e. a
237  * singature created with libfsverity_sign_digest()) to associate with the file.
238  * This is only needed if the in-kernel signature verification support is being
239  * used; it is not needed if signatures are being verified in userspace.
240  *
241  * If @sig is NULL and @sig_size is 0, this is the same as libfsverity_enable().
242  *
243  * Return: See libfsverity_enable().
244  */
245 int
246 libfsverity_enable_with_sig(int fd,
247 			    const struct libfsverity_merkle_tree_params *params,
248 			    const uint8_t *sig, size_t sig_size);
249 
250 /**
251  * libfsverity_find_hash_alg_by_name() - Find hash algorithm by name
252  * @name: Pointer to name of hash algorithm
253  *
254  * Return: The hash algorithm number, or zero if not found.
255  */
256 uint32_t libfsverity_find_hash_alg_by_name(const char *name);
257 
258 /**
259  * libfsverity_get_digest_size() - Get size of digest for a given algorithm
260  * @alg_num: Number of hash algorithm
261  *
262  * Return: size of digest in bytes, or -1 if algorithm is unknown.
263  */
264 int libfsverity_get_digest_size(uint32_t alg_num);
265 
266 /**
267  * libfsverity_get_hash_name() - Get name of hash algorithm by number
268  * @alg_num: Number of hash algorithm
269  *
270  * Return: The name of the hash algorithm, or NULL if algorithm is unknown.
271  */
272 const char *libfsverity_get_hash_name(uint32_t alg_num);
273 
274 /**
275  * libfsverity_set_error_callback() - Set callback to handle error messages
276  * @cb: the callback function.
277  *
278  * If a callback is already set, it is replaced.  @cb may be NULL in order to
279  * remove the existing callback.
280  */
281 void libfsverity_set_error_callback(void (*cb)(const char *msg));
282 
283 #ifdef __cplusplus
284 }
285 #endif
286 
287 #endif /* LIBFSVERITY_H */
288