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