/* * 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. */ /* * RMC Library (RMCL) * * Provide API and RMC data types of RMCL to outside */ #ifndef INC_RMCL_H_ #define INC_RMCL_H_ #include #ifndef RMC_EFI #include #endif #pragma pack(push, 1) /* * RMC Fingerprint */ #define END_OF_TABLE_TYPE 127 /* * structures for RMC fingerprint * INIT_RMC_FINGERPRINTS macro is * preferred as long as possible. */ typedef struct rmc_finger { rmc_uint8_t type; rmc_uint8_t offset; char *name; char *value; } rmc_finger_t; #define RMC_FINGER_NUM (5) typedef union rmc_fingerprint { rmc_finger_t rmc_fingers[RMC_FINGER_NUM]; struct rmc_finger_by_name { rmc_finger_t thumb; rmc_finger_t index; rmc_finger_t middle; rmc_finger_t ring; rmc_finger_t pink; } named_fingers; } rmc_fingerprint_t; /* * initialize fingerprint data */ static __inline__ void initialize_fingerprint(rmc_fingerprint_t *fp) { fp->named_fingers.thumb.type = 0x1; fp->named_fingers.thumb.offset = 0x5; fp->named_fingers.thumb.name = "product_name"; fp->named_fingers.thumb.value = ""; fp->named_fingers.index.type = 0x2; fp->named_fingers.index.offset = 0x5; fp->named_fingers.index.name = "product_name"; fp->named_fingers.index.value = ""; fp->named_fingers.middle.type = 0x4; fp->named_fingers.middle.offset = 0x10; fp->named_fingers.middle.name = "version"; fp->named_fingers.middle.value = ""; fp->named_fingers.ring.type = 0x7f; fp->named_fingers.ring.offset = 0x0; fp->named_fingers.ring.name = "reserved"; fp->named_fingers.ring.value = ""; fp->named_fingers.pink.type = 0x7f; fp->named_fingers.pink.offset = 0x0; fp->named_fingers.pink.name = "reserved"; fp->named_fingers.pink.value = ""; } #define RMC_DB_SIG_LEN 5 /* * RMC Database (packed). A RMC DB contains records */ typedef struct rmc_db_header { rmc_uint8_t signature[RMC_DB_SIG_LEN]; rmc_uint8_t version; rmc_uint64_t length; } __attribute__ ((__packed__)) rmc_db_header_t; /* signature is the computation result of fingerprint and what's packed in record */ typedef union rmc_signature { rmc_uint8_t raw[32]; } __attribute__ ((__packed__)) rmc_signature_t; /* * RMC Database Record (packed). A record contains metas for a board type */ typedef struct rmc_record_header { rmc_signature_t signature; /* computation result from finger print */ rmc_uint64_t length; } __attribute__ ((__packed__)) rmc_record_header_t; /* * RMC Database Meta (packed) */ typedef struct rmc_meta_header { rmc_uint8_t type; /* RMC_GENERIC_FILE or or any other types defined later */ rmc_uint64_t length; /* length of blob's name and blob */ /* char *blob_name : Invisible, null-terminated string packed in mem */ /* rmc_uint8_t *blob : Invisible, binary packed in mem */ } __attribute__ ((__packed__)) rmc_meta_header_t; /* We only have one type now but keep a type field internally for extensions in the future. */ #define RMC_GENERIC_FILE 1 typedef struct rmc_file { rmc_uint8_t type; /* RMC_GENERIC_FILE or or any other types defined later */ char *blob_name; /* name of blob for type RMC_GENERIC_FILE */ struct rmc_file *next; /* next rmc file, or null as terminator for the last element */ rmc_size_t blob_len; /* number of bytes of blob, excluding length of name */ rmc_uint8_t *blob; /* blob of policy file, treated as binary, UNNECESSARILY Null terminated */ } rmc_file_t; /* * output of a rmc record file generated by rmcl. * Also as input when generating rmc db with records. */ typedef struct rmc_record_file { rmc_uint8_t *blob; /* record raw data blob */ rmc_size_t length; struct rmc_record_file *next; /* next rmc record file, or null as terminator for the last element */ } rmc_record_file_t; #pragma pack(pop) /* * Generate RMC record file (This function allocate memory) * (in) fingerprint : fingerprint of board, usually generated by rmc tool with rsmp. * (in) policy files : head of a list of policy files, 'next' of the last one must be NULL. * (out) rmc_record : generated rmc record blob with its length * (ret) 0 for success, RMC error code for failures. content of rmc record is undefined for failure. */ extern int rmcl_generate_record(rmc_fingerprint_t *fingerprint, rmc_file_t *policy_files, rmc_record_file_t *record_file); /* * Generate RMC database blob (This function allocate memory) * (in) record_files : head of a list of record files, 'next' of the last one must be NULL. * (in) file_num : number of rmc files passed in * (out) rmc_db : generated rmc database blob, formated by rmcl. * (out) len : length of returned rmc db * (ret) 0 for success, RMC error code for failures. content of rmc_db is NULL for failures. */ extern int rmcl_generate_db(rmc_record_file_t *record_files, rmc_uint8_t **rmc_db, rmc_size_t *len); /* * Query a RMC database blob provided by caller * (in) fingerprint : fingerprint of board * (in) rmc_db : rmc database blob * (in) type : type of record * (in) blob_name : name of file blob to query * (out) policy : policy file data structure provided by caller, holding returned policy data * if there is a matched meta for board. Pointer members of policy hold data location * in rmc_db's memory region. (This functions doesn't copy data.) * * return : 0 when rmcl found a meta in record which has matched signature of fingerprint. non-zero for failures. Content of * policy is not determined when non-zero is returned. */ extern int query_policy_from_db(rmc_fingerprint_t *fingerprint, rmc_uint8_t *rmc_db, rmc_uint8_t type, char *blob_name, rmc_file_t *policy); /* * Check if db_blob has a valid rmc database signature * * return 0 if db_blob has a valid signature or non-zero otherwise */ int is_rmcdb(rmc_uint8_t *db_blob); #endif /* INC_RMCL_H_ */