xref: /aosp_15_r20/external/coreboot/src/commonlib/bsd/include/commonlib/bsd/cbfs_private.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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