123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515 |
- /* SPDX-License-Identifier: BSD-3-Clause */
- #ifndef STRING_BYTES_H
- #define STRING_BYTES_H
- #include <stdbool.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <tss2/tss2_esys.h>
- #include "tpm2_session.h"
- #if defined (__GNUC__)
- #define COMPILER_ATTR(...) __attribute__((__VA_ARGS__))
- #else
- #define COMPILER_ATTR(...)
- #endif
- #define xstr(s) str(s)
- #define str(s) #s
- #define UNUSED(x) (void)x
- #define ARRAY_LEN(x) (sizeof(x)/sizeof(x[0]))
- #define PSTR(x) x ? x : "(null)"
- #define BUFFER_SIZE(type, field) (sizeof((((type *)NULL)->field)))
- #define TSS2_APP_RC_LAYER TSS2_RC_LAYER(5)
- #define TPM2B_TYPE_INIT(type, field) { .size = BUFFER_SIZE(type, field), }
- #define TPM2B_INIT(xsize) { .size = xsize, }
- #define TPM2B_EMPTY_INIT TPM2B_INIT(0)
- #define TPM2B_SENSITIVE_CREATE_EMPTY_INIT { \
- .sensitive = { \
- .data = { \
- .size = 0 \
- }, \
- .userAuth = { \
- .size = 0 \
- } \
- } \
- }
- #define TPMT_TK_CREATION_EMPTY_INIT { \
- .tag = 0, \
- .hierarchy = 0, \
- .digest = TPM2B_EMPTY_INIT \
- }
- #define TPML_PCR_SELECTION_EMPTY_INIT { \
- .count = 0, \
- } //ignore pcrSelections since count is 0.
- #define TPMS_CAPABILITY_DATA_EMPTY_INIT { \
- .capability = 0, \
- } // ignore data since capability is 0.
- #define TPMT_TK_HASHCHECK_EMPTY_INIT { \
- .tag = 0, \
- .hierarchy = 0, \
- .digest = TPM2B_EMPTY_INIT \
- }
- #define TSS2L_SYS_AUTH_COMMAND_INIT(cnt, array) { \
- .count = cnt, \
- .auths = array, \
- }
- /*
- * This macro is useful as a wrapper around SAPI functions to automatically
- * retry function calls when the RC is TPM2_RC_RETRY.
- */
- #define TSS2_RETRY_EXP(expression) \
- ({ \
- TSS2_RC __result = 0; \
- do { \
- __result = (expression); \
- } while (tpm2_error_get(__result) == TPM2_RC_RETRY); \
- __result; \
- })
- typedef struct {
- UINT16 size;
- BYTE buffer[0];
- } TPM2B;
- int tpm2_util_hex_to_byte_structure(const char *in_str, UINT16 *byte_length,
- BYTE *byte_buffer);
- /**
- * Compares two digests to ensure they are equal (for validation).
- * @param quote_digest
- * The digest from the quote.
- * @param pcr_digest
- * The digest calculated off-TMP from the PCRs.
- * @return
- * True on success, false otherwise.
- */
- bool tpm2_util_verify_digests(TPM2B_DIGEST *quote_digest,
- TPM2B_DIGEST *pcr_digest);
- /**
- * Appends a TPM2B buffer to a MAX buffer.
- * @param result
- * The MAX buffer to append to
- * @param append
- * The buffer to append to result.
- * @return
- * true on success, false otherwise.
- */
- bool tpm2_util_concat_buffer(TPM2B_MAX_BUFFER *result, TPM2B *append);
- /**
- * Converts a numerical string into a int32_t value.
- * @param str
- * The numerical string to convert.
- * @param value
- * The value to store the conversion into.
- * @return
- * true on success, false otherwise.
- */
- bool tpm2_util_string_to_int32(const char *str, int32_t *value);
- /**
- * Converts a numerical string into a uint32 value.
- * @param str
- * The numerical string to convert.
- * @param value
- * The value to store the conversion into.
- * @return
- * true on success, false otherwise.
- */
- bool tpm2_util_string_to_uint32(const char *str, uint32_t *value);
- /**
- * Converts a numerical string into a uint64 value.
- * @param str
- * The numerical string to convert.
- * @param value
- * The value to store the conversion into.
- * @return
- * true on success, false otherwise.
- */
- bool tpm2_util_string_to_uint64(const char *str, uint64_t *value);
- /**
- * Converts a numerical string into a uint16 value.
- * @param str
- * The numerical string to convert.
- * @param value
- * The value to store the conversion into.
- * @return
- * true on success, false otherwise.
- */
- bool tpm2_util_string_to_uint16(const char *str, uint16_t *value);
- /**
- * Converts a numerical string into a uint8 value.
- * @param str
- * The numerical string to convert.
- * @param value
- * The value to store the conversion into.
- * @return
- * true on success, false otherwise.
- */
- bool tpm2_util_string_to_uint8(const char *str, uint8_t *value);
- /**
- * Prints an xxd compatible hexdump to stdout if output is enabled,
- * ie no -Q option.
- *
- * @param data
- * The data to print.
- * @param len
- * The length of the data.
- */
- void tpm2_util_hexdump(const BYTE *data, size_t len);
- /**
- * Similar to tpm2_util_hexdump(), but:
- * - does NOT respect the -Q option
- * - allows specification of the output stream.
- * @param f
- * The FILE output stream.
- * @param data
- * The data to convert to hex.
- * @param len
- * The length of the data.
- */
- void tpm2_util_hexdump2(FILE *f, const BYTE *data, size_t len);
- /**
- * Read a hex string converting it to binary or a binary file and
- * store into a binary buffer.
- * @param input
- * Either a hex string or a file path.
- * @param len
- * The maximum length of the buffer.
- * @param buffer
- * The buffer to read into.
- * @return
- * True on success, False otherwise.
- */
- bool tpm2_util_bin_from_hex_or_file(const char *input, UINT16 *len, BYTE *buffer);
- /**
- * Prints a TPM2B as a hex dump respecting the -Q option
- * to stdout.
- *
- * @param buffer the TPM2B to print.
- */
- #define tpm2_util_print_tpm2b(b) _tpm2_util_print_tpm2b((TPM2B *)b)
- static inline void _tpm2_util_print_tpm2b(TPM2B *buffer) {
- return tpm2_util_hexdump(buffer->buffer, buffer->size);
- }
- /**
- * Prints a TPM2B as a hex dump to the FILE specified. Does NOT
- * respect -Q like tpm2_util_print_tpm2b().
- *
- * @param out
- * The output FILE.
- * @param
- * buffer the TPM2B to print.
- */
- #define tpm2_util_print_tpm2b2(o, b) _tpm2_util_print_tpm2b2(o, (TPM2B *)b)
- static inline void _tpm2_util_print_tpm2b2(FILE *out, const TPM2B *buffer) {
- return tpm2_util_hexdump2(out, buffer->buffer, buffer->size);
- }
- /**
- * Determines if given PCR value is selected in TPMS_PCR_SELECTION structure.
- * @param pcr_selection the TPMS_PCR_SELECTION structure to check pcr against.
- * @param pcr the PCR ID to check selection status of.
- */
- static inline bool tpm2_util_is_pcr_select_bit_set(
- const TPMS_PCR_SELECTION *pcr_selection, UINT32 pcr) {
- return (pcr_selection->pcrSelect[((pcr) / 8)] & (1 << ((pcr) % 8)));
- }
- /**
- * Checks if the host is big endian
- * @return
- * True of the host is big endian false otherwise.
- */
- bool tpm2_util_is_big_endian(void);
- /**
- * Swaps the endianess of 16 bit value.
- * @param data
- * A 16 bit value to swap the endianess on.
- * @return
- * The 16 bit value with the endianess swapped.
- */
- UINT16 tpm2_util_endian_swap_16(UINT16 data);
- /**
- * Just like string_bytes_endian_convert_16 but for 32 bit values.
- */
- UINT32 tpm2_util_endian_swap_32(UINT32 data);
- /**
- * Just like string_bytes_endian_convert_16 but for 64 bit values.
- */
- UINT64 tpm2_util_endian_swap_64(UINT64 data);
- /**
- * Converts a 16 bit value from host endianess to network endianess.
- * @param data
- * The data to possibly swap endianess.
- * @return
- * The swapped data.
- */
- UINT16 tpm2_util_hton_16(UINT16 data);
- /**
- * Just like string_bytes_endian_hton_16 but for 32 bit values.
- */
- UINT32 tpm2_util_hton_32(UINT32 data);
- /**
- * Just like string_bytes_endian_hton_16 but for 64 bit values.
- */
- UINT64 tpm2_util_hton_64(UINT64 data);
- /**
- * Converts a 16 bit value from network endianess to host endianess.
- * @param data
- * The data to possibly swap endianess.
- * @return
- * The swapped data.
- */
- UINT16 tpm2_util_ntoh_16(UINT16 data);
- /**
- * Just like string_bytes_endian_ntoh_16 but for 32 bit values.
- */
- UINT32 tpm2_util_ntoh_32(UINT32 data);
- /**
- * Just like string_bytes_endian_ntoh_16 but for 64 bit values.
- */
- UINT64 tpm2_util_ntoh_64(UINT64 data);
- /**
- * Counts the number of set bits aka a population count.
- * @param data
- * The data to count set bits in.
- * @return
- * The number of set bits or population count.
- */
- UINT32 tpm2_util_pop_count(UINT32 data);
- /**
- * Prints whitespace indention for yaml output.
- * @param indent_count
- * Number of times to indent
- */
- void print_yaml_indent(size_t indent_count);
- /**
- * Convert a TPM2B_PUBLIC into a yaml format and output if not quiet.
- * @param public
- * The TPM2B_PUBLIC to output in YAML format.
- * @param indent
- * The level of indentation, can be NULL
- */
- void tpm2_util_public_to_yaml(TPM2B_PUBLIC *public, char *indent);
- void tpm2_util_tpmt_public_to_yaml(TPMT_PUBLIC *public, char *indent);
- /**
- * Convert a TPMA_OBJECT to a yaml format and output if not quiet.
- * @param obj
- * The TPMA_OBJECT attributes to print.
- * @param indent
- * The level of indentation, can be NULL
- */
- void tpm2_util_tpma_object_to_yaml(TPMA_OBJECT obj, char *indent);
- /**
- * Calculates the unique public field. The unique public field is the digest, based on name algorithm
- * of the key + protection seed (concatenated).
- *
- * @param namealg
- * The name algorithm of the object, from the public portion.
- * @param key
- * The key bytes themselves. It seems odd that the type is TPM2B_PRIVATE_VENDOR_SPECIFIC
- * but this for access to the ANY field.
- * @param seed
- * The seed, from the sensitive portion.
- * @param unique
- * The result, a generated unique value for the public portion.
- * @return
- * True on success, false otherwise.
- */
- bool tpm2_util_calc_unique(TPMI_ALG_HASH name_alg,
- TPM2B_PRIVATE_VENDOR_SPECIFIC *key, TPM2B_DIGEST *seed,
- TPM2B_DIGEST *unique);
- /**
- * Uses TR_FromTPMPublic() to construct the ESYS_TR object corresponding
- * to the passed TPM2_HANDLE.
- * @param context
- * an ESAPI context
- * @param sys_handle
- * the TPM2_HANDLE to construct an ESYS_TR handle for
- * @param esys_handle
- * pointer to an ESYS_TR handle to output the found handle into
- * @return
- * A tool_rc indicating status.
- */
- tool_rc tpm2_util_sys_handle_to_esys_handle(ESYS_CONTEXT *context,
- TPM2_HANDLE sys_handle, ESYS_TR *esys_handle);
- /**
- * Map a TPMI_RH_PROVISION to the corresponding ESYS_TR constant
- * @param inh
- * The hierarchy to map
- */
- ESYS_TR tpm2_tpmi_hierarchy_to_esys_tr(TPMI_RH_PROVISION inh);
- char *tpm2_util_getenv(const char *name);
- typedef enum tpm2_handle_flags tpm2_handle_flags;
- enum tpm2_handle_flags {
- TPM2_HANDLE_FLAGS_NONE = 0,
- TPM2_HANDLE_FLAGS_O = 1 << 0,
- TPM2_HANDLE_FLAGS_P = 1 << 1,
- TPM2_HANDLE_FLAGS_E = 1 << 2,
- TPM2_HANDLE_FLAGS_N = 1 << 3,
- TPM2_HANDLE_FLAGS_L = 1 << 4,
- TPM2_HANDLE_FLAGS_ALL_HIERACHIES = 0x1F,
- TPM2_HANDLES_FLAGS_TRANSIENT = 1 << 5,
- TPM2_HANDLES_FLAGS_PERSISTENT = 1 << 6,
- /* bits 7 and 8 are mutually exclusive */
- TPM2_HANDLE_FLAGS_NV = 1 << 7,
- TPM2_HANDLE_ALL_W_NV = 0xFF,
- TPM2_HANDLE_FLAGS_PCR = 1 << 8,
- TPM2_HANDLE_ALL_W_PCR = 0x17F,
- };
- /**
- * Converts an option from the command line into a valid TPM handle, checking
- * for errors and if the tool supports it based on flags settings.
- * @param value
- * The command line value to convert.
- * @param handle
- * The output handle.
- * @param flags
- * The flags indicating what is supported by the tool.
- * @return
- * true on success, false otherwise.
- */
- bool tpm2_util_handle_from_optarg(const char *value,
- TPMI_RH_PROVISION *hierarchy, tpm2_handle_flags flags);
- bool tpm2_util_get_label(const char *value, TPM2B_DATA *label);
- /**
- * Prints a TPMS_TIME_INFO in a YAML compliant format to stdout.
- * @param current_time
- * The time structure to print
- */
- void tpm2_util_print_time(const TPMS_TIME_INFO *current_time);
- /**
- * Given the parent qualified name and the name of an object, computes
- * that objects qualified name.
- *
- * The qualified name is defined as:
- * QNB ≔ HB (QNA || NAMEB)
- *
- * Where:
- * - QNB is the qualified name of the object.
- * - HB is the name hash algorithm of the object.
- * - QNA is the qualified name of the parent object.
- * - NAMEB is the name of the object.
- *
- * @param pqname
- * The parent qualified name.
- * @param halg
- * The name hash algorithm of the object.
- * @param name
- * The name of the object.
- * @param qname
- * The output qname, valid on success.
- * @return
- * True on success, false otherwise.
- */
- bool tpm2_calq_qname(TPM2B_NAME *pqname,
- TPMI_ALG_HASH halg, TPM2B_NAME *name, TPM2B_NAME *qname);
- /**
- * Reads safely from stdin.
- *
- * @param length
- * Maximum length to read.
- * @param data
- * The output data that was read, valid on success.
- * @return
- * True on success, false otherwise.
- */
- bool tpm2_safe_read_from_stdin(int length, char *data);
- /**
- * Converts a PEM-encoded public key to its sha256 representation (fingerprint).
- * The resulting Base64-encoded fingerprint format is based on the SSH:
- * '''
- * ssh-keygen -lf id_ecdsa.pub
- * 256 SHA256:wTUOtZnoSGKwq36mPIN20rCK0Fc1y0zCvHxI2eAvVxU
- * '''
- *
- * @param pem_encoded_key
- * The PEM-encoded public key.
- * @param fingerprint
- * The resulting fingerprint, valid on success.
- * @return
- * True on success, false otherwise.
- */
- bool tpm2_pem_encoded_key_to_fingerprint(const char* pem_encoded_key, char*
- fingerprint);
- /**
- * Restores session handles to be used as auxilary sessions in addition to the
- * possible authorization sessions with a command.
- *
- * @param ectx
- * The ESAPI context
- * @param session_cnt
- * Total number of sessions to restore
- * @param session_path
- * An array of string data specifying the individual session file path
- * @param session_handle
- * An array of session handles updated as a result resuming sessions
- * @param session
- * An array of session structures updated as a result of resuming sessions
- * @return
- * Success: tool_rc_success, Faiure: tool_rc_general_error
- */
- tool_rc tpm2_util_aux_sessions_setup( ESYS_CONTEXT *ectx,
- uint8_t session_cnt, const char **session_path, ESYS_TR *session_handle,
- tpm2_session **session);
- TPMI_ALG_HASH tpm2_util_calculate_phash_algorithm(ESYS_CONTEXT *ectx,
- const char **cphash_path, TPM2B_DIGEST *cp_hash, const char **rphash_path,
- TPM2B_DIGEST *rp_hash, tpm2_session **sessions);
- #endif /* STRING_BYTES_H */
|