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