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