/* * Copyright (c) 2016 - 2017 Intel Corporation. * * Author: Jianxun Zhang * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* header file of RMC APIs for clients to call at run time */ #ifndef INC_RMC_API_H_ #define INC_RMC_API_H_ #include #include /* * Introduction: RMC APIs * * RMC clients like programs or libraries call these APIs to query files specific to * the type of board on client software at runtime. The APIs are grouped by contexts * (Linux user space or UEFI). API are designed to provide very similar forms and * effects across contexts, in order to ease the learning curve at client side. But * please refer to the description for an API to learn the difference in behaviors. * * Single VS double-action: * A Single-action API only performs one step of the whole procedure to query files. * That means you have to call them in a series of statements. But you have a chance * to reuse intermediate data (e.g. fingerprint) without bothering a previous step in * the following queries. This should bring some advantage on performance when a client * needs to perform multiple queries. * * Double-action APIs can be regarded as one-stop wrappers of single-action APIs. One * function call is enough to perform a query with basic parameters provided by callers. * They help to reduce the size of change in code when a client software only needs to * fetch a file and then do little with RMC in the rest of live cycle. * * Eventually, calling all single-action APIs one by one has the same effect as calling * a double action API for a single query. * * A group of helper APIs is also provided specific for a context if they are needed by * clients. */ #ifndef RMC_EFI /* 1 - APIs for Linux user space */ /* 1.1 - Single-action APIs */ /* get board's RMC fingerprint * (out) fp: fingerprint data to be filled. Allocated internal data in * the returned fp can be freed with rmc_free_fingerprint() * if the call successes (ret = 0) * But caller needs to allocate and free memory for fp structure itself. * return: 0 for success, non-zero for failures. */ extern int rmc_get_fingerprint(rmc_fingerprint_t *fp); /* query a file in a RMC database file associated to a provided fingerprint * (in) fp: fingerprint generated by rmc_get_fingerprint() for the running board * (in) db_pathname: The path and file name of a RMC database file generated by RMC tool * (in) file_name: The name of a file blob to be queried in the database * (out) file: Holds the content of successfully retrieved from the database. Caller is * responsible to free the _internal_ data allocated in file by calling * rmc_free_file(); * return: 0 for success, non-zero for failures. */ extern int rmc_query_file_by_fp(rmc_fingerprint_t *fp, char *db_pathname, char *file_name, rmc_file_t *file); /* 1.2 - Double-action API */ /* query a file in a RMC database file associated to the board we run on * (in) db_pathname: The path and file name of a RMC database file generated by RMC tool * (in) file_name: The name of a file blob to be queried in the database * (out) file: Holds the content of successfully retrieved from the database. Caller is * responsible to free the _internal_ data allocated in file by calling * rmc_free_file(); * return: 0 for success, non-zero for failures. */ extern int rmc_gimme_file(char* db_pathname, char *file_name, rmc_file_t *file); /* 1.3 - Helper APIs */ /* Free allocated data referred in a fingerprint * Note: It does NOT free memory of fignerprint itself * (in) fp: fingerprint structure allocated by caller */ extern void rmc_free_fingerprint(rmc_fingerprint_t *fp); /* Free allocated data referenced in a RMC file structure * Note: It does NOT free memory of RMC file structure itself * (in) file: RMC file structure */ extern void rmc_free_file(rmc_file_t *fp); /* * utility function to read a file into mem. This function allocates memory * (in) pathname : file pathname to read * (out) data : address of point that points to the data read * (out) len : pointer of total number of bytes read from file * * return : 0 for success, non-zeor for failures */ extern int read_file(const char *pathname, char **data, rmc_size_t* len); /* * utility function to write data into file. * (in) pathname : file pathname to write * (in) data : pointer of data buffer * (in) len : total number of bytes to write * (in) append : 0 to write from file's beginning, non-zero to write data from file's end. * * return : 0 when successfully write all data into file, non-zeor for failures */ int write_file(const char *pathname, void *data, rmc_size_t len, int append); /* extract the contents of a database file and store the files corresponding to * each record in a separate directory. The name of each directory is the signature * of the fingerpring for that record with all non-alphanumeric characters stripped * (in) db_pathname: The path and file name of a RMC database file generated by RMC tool * (in) output_path: A directory path to extract the database to * return: 0 on success, non-zero on failure. */ int dump_db(char *db_pathname, char *output_path) ; #else /* 2 - API for UEFI context */ /* EFI applications are using different UEFI implementations and libraries. For example, APIs * provided by gun-efi have equivalent but different interfaces in grub-efi's own UEFI code. * We have to leave some low-level work (file operations, allocate/free memory, etc) to * callers at this point until we have a universal EFI solution in RMC to achieve the * convenience in Linux user space. * * RMC UEFI APIs do NOT allocate and memory. The returned data pointers actually reference to * the addresses in system tables and memory regions of a read database file. Generally, these * regions should be treated as "read-only". */ /* 2.1 - Single-action APIs */ /* get board's RMC fingerprint * (in) sys_table: address of UEFI system configuration table * (out) fp: fingerprint data to be filled. * return: 0 for success, non-zero for failures. */ extern int rmc_get_fingerprint(void *sys_table, rmc_fingerprint_t *fp); /* query a file in a RMC database file associated to a provided fingerprint * (in) fp: fingerprint from rmc_get_fingerprint() * (in) db_blob: memory chunk of raw data of whole database provided by callers. * (in) file_name: The name of a file blob to be queried in the database * (out) file: Holds the content of successfully retrieved from the database. * * return: 0 for success, non-zero for failures. */ extern int rmc_query_file_by_fp(rmc_fingerprint_t *fp, unsigned char *db_blob, char *file_name, rmc_file_t *file); /* 2.2 Double-action APIs */ /* query a file in a RMC database file associated to the board we run on * (in) sys_table: address of UEFI system configuration table * (in) db_blob: memory chunk of raw data of whole database provided by callers. * (in) file_name: The name of a file blob to be queried in the database * (out) file: Holds the content of successfully retrieved from the database. * * return: 0 for success, non-zero for failures. */ extern int rmc_gimme_file(void *sys_table, unsigned char *db_blob, char *file_name, rmc_file_t *file); #endif #endif /* INC_RMC_API_H_ */