1 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later */ 2 3 #ifndef _COMMONLIB_BSD_CBFS_PRIVATE_H_ 4 #define _COMMONLIB_BSD_CBFS_PRIVATE_H_ 5 6 7 #include <commonlib/bsd/cb_err.h> 8 #include <commonlib/bsd/cbfs_mdata.h> 9 #include <commonlib/bsd/sysincludes.h> 10 #include <stdbool.h> 11 #include <stdint.h> 12 #include <vb2_sha.h> 13 14 /* 15 * This header implements low-level CBFS access APIs that can be shared across different 16 * host applications (e.g. coreboot, libpayload, cbfstool). For verification purposes it 17 * implements the metadata hashing part but not the file hashing part, so the host application 18 * will need to verify file hashes itself after loading each file. Host applications that use 19 * verification should implement wrapper APIs that combine the lookup, loading and hashing steps 20 * into a single, safe function call and outside of the code implementing those APIs should not 21 * be accessing the low-level APIs in this file directly (e.g. coreboot SoC/driver code should 22 * never directly #include this file, and always use the higher level APIs in src/lib/cbfs.c). 23 * 24 * <cbfs_glue.h> needs to be provided by the host application using this CBFS library. It must 25 * define the following type, macros and functions: 26 * 27 * cbfs_dev_t An opaque type representing a CBFS storage backend. 28 * CBFS_ENABLE_HASHING Should be 0 to avoid linking hashing features, 1 otherwise. (Only for 29 * metadata hashing. Host application needs to check file hashes itself.) 30 * CBFS_HASH_HWCRYPTO Should evaluate to true to allow using vboot hardware crypto routines 31 * for hashing, false to forbid. This macro may expand to a function call 32 * to decide this at runtime. 33 * ERROR(...) printf-style macro to print errors. 34 * LOG(...) printf-style macro to print normal-operation log messages. 35 * DEBUG(...) printf-style macro to print detailed debug output. 36 * 37 * ssize_t cbfs_dev_read(cbfs_dev_t dev, void *buffer, size_t offset, size_t size); 38 * Read |size| bytes starting at |offset| from |dev| into |buffer|. 39 * Returns amount of bytes read on success and < 0 on error. 40 * This function *MUST* sanity-check offset/size on its own. 41 * 42 * size_t cbfs_dev_size(cbfs_dev_t dev); 43 * Return the total size in bytes of the CBFS storage (actual CBFS area). 44 */ 45 #include <cbfs_glue.h> 46 47 /* Flags that modify behavior of cbfs_walk(). */ 48 enum cbfs_walk_flags { 49 /* Write the calculated hash back out to |metadata_hash->hash| rather than comparing it. 50 |metadata_hash->algo| must still have been initialized by the caller. */ 51 CBFS_WALK_WRITEBACK_HASH = (1 << 0), 52 /* Call |walker| for empty file entries (i.e. entries with one of the CBFS_TYPE_DELETED 53 types that mark free space in the CBFS). Otherwise, those entries will be skipped. 54 Either way, these entries are never included in the metadata_hash calculation. */ 55 CBFS_WALK_INCLUDE_EMPTY = (1 << 1), 56 }; 57 58 /* 59 * Traverse a CBFS and call a |walker| callback function for every file. Can additionally 60 * calculate a hash over the metadata of all files in the CBFS. If |metadata_hash| is NULL, 61 * hashing is disabled. If |walker| is NULL, will just traverse and hash the CBFS without 62 * invoking any callbacks (and always return CB_CBFS_NOT_FOUND unless there was another error). 63 * 64 * |arg| and |dev| will be passed through to |walker| unmodified. |offset| is the absolute 65 * offset in |dev| at which the current file metadata starts. |mdata| is a temporary buffer 66 * (only valid for the duration of this call to |walker|) containing already read metadata from 67 * the current file, up to |already_read| bytes. This will always at least contain the header 68 * fields and filename, but may contain more (i.e. attributes), depending on whether hashing is 69 * enabled. |walker| should call into cbfs_copy_fill_medadata() to copy the metadata of a file 70 * to a persistent buffer and automatically load remaining metadata from |dev| as needed based 71 * on the value of |already_read|. 72 * 73 * |walker| should return CB_CBFS_NOT_FOUND if it wants to continue being called for further 74 * files. Any other return code will be used as the final return code for cbfs_walk(). It will 75 * return immediately unless it needs to calculate a hash in which case it will still traverse 76 * the remaining CBFS (but not call |walker| anymore). 77 * 78 * Returns, from highest to lowest priority: 79 * CB_CBFS_IO - There was an IO error with the CBFS device (always considered fatal) 80 * CB_CBFS_HASH_MISMATCH - |metadata_hash| was provided and did not match the CBFS 81 * CB_SUCCESS/<other> - First non-CB_CBFS_NOT_FOUND code returned by walker() 82 * CB_CBFS_NOT_FOUND - walker() returned CB_CBFS_NOT_FOUND for every file in the CBFS 83 */ 84 enum cb_err cbfs_walk(cbfs_dev_t dev, enum cb_err (*walker)(cbfs_dev_t dev, size_t offset, 85 const union cbfs_mdata *mdata, 86 size_t already_read, void *arg), 87 void *arg, struct vb2_hash *metadata_hash, enum cbfs_walk_flags); 88 89 /* 90 * Helper function that can be used by a |walker| callback to cbfs_walk() to copy the metadata 91 * of a file into a permanent buffer. Will copy the |already_read| metadata from |src| into 92 * |dst| and load remaining metadata from |dev| as required. 93 */ 94 enum cb_err cbfs_copy_fill_metadata(union cbfs_mdata *dst, const union cbfs_mdata *src, 95 size_t already_read, cbfs_dev_t dev, size_t offset); 96 97 /* Find a file named |name| in the CBFS on |dev|. Copy its metadata (including attributes) 98 * into |mdata_out| and pass out the offset to the file data on the CBFS device. 99 * Verify the metadata with |metadata_hash| if provided. */ 100 enum cb_err cbfs_lookup(cbfs_dev_t dev, const char *name, union cbfs_mdata *mdata_out, 101 size_t *data_offset_out, struct vb2_hash *metadata_hash); 102 103 /* Both base address and size of CBFS mcaches must be aligned to this value! */ 104 #define CBFS_MCACHE_ALIGNMENT sizeof(uint32_t) /* Largest data type used in CBFS */ 105 106 /* Build an in-memory CBFS metadata cache out of the CBFS on |dev| into a |mcache_size| bytes 107 * memory area at |mcache|. Also verify |metadata_hash| unless it is NULL. If this returns 108 * CB_CBFS_CACHE_FULL, the mcache is still valid and can be used, but lookups may return 109 * CB_CBFS_CACHE_FULL for files that didn't fit to indicate that the caller needs to fall back 110 * to cbfs_lookup(). */ 111 enum cb_err cbfs_mcache_build(cbfs_dev_t dev, void *mcache, size_t mcache_size, 112 struct vb2_hash *metadata_hash); 113 114 /* 115 * Find a file named |name| in a CBFS metadata cache and copy its metadata into |mdata_out|. 116 * Pass out offset to the file data (on the original CBFS device used for cbfs_mcache_build()). 117 */ 118 enum cb_err cbfs_mcache_lookup(const void *mcache, size_t mcache_size, const char *name, 119 union cbfs_mdata *mdata_out, size_t *data_offset_out); 120 121 /* Returns the amount of bytes actually used by the CBFS metadata cache in |mcache|. */ 122 size_t cbfs_mcache_real_size(const void *mcache, size_t mcache_size); 123 124 #endif /* _COMMONLIB_BSD_CBFS_PRIVATE_H_ */ 125