123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- /* SPDX-License-Identifier: BSD-3-Clause */
- #ifndef LIB_TPM2_OPENSSL_H_
- #define LIB_TPM2_OPENSSL_H_
- #include <tss2/tss2_sys.h>
- #include <openssl/ec.h>
- #include <openssl/ecdsa.h>
- #include <openssl/err.h>
- #include <openssl/hmac.h>
- #include <openssl/rsa.h>
- #include "pcr.h"
- #if (OPENSSL_VERSION_NUMBER < 0x1010000fL && !defined(LIBRESSL_VERSION_NUMBER)) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) /* OpenSSL 1.1.0 */
- #define LIB_TPM2_OPENSSL_OPENSSL_PRE11
- #endif
- #if OPENSSL_VERSION_NUMBER >= 0x10101000L
- #define EC_POINT_set_affine_coordinates_tss(group, tpm_pub_key, bn_x, bn_y, dmy) \
- EC_POINT_set_affine_coordinates(group, tpm_pub_key, bn_x, bn_y, dmy)
- #define EC_POINT_get_affine_coordinates_tss(group, tpm_pub_key, bn_x, bn_y, dmy) \
- EC_POINT_get_affine_coordinates(group, tpm_pub_key, bn_x, bn_y, dmy)
- #else
- #define EC_POINT_set_affine_coordinates_tss(group, tpm_pub_key, bn_x, bn_y, dmy) \
- EC_POINT_set_affine_coordinates_GFp(group, tpm_pub_key, bn_x, bn_y, dmy)
- #define EC_POINT_get_affine_coordinates_tss(group, tpm_pub_key, bn_x, bn_y, dmy) \
- EC_POINT_get_affine_coordinates_GFp(group, tpm_pub_key, bn_x, bn_y, dmy)
- #endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
- #if defined(LIB_TPM2_OPENSSL_OPENSSL_PRE11)
- int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);
- void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q);
- int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s);
- EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void);
- void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx);
- #endif
- /**
- * Function prototype for a hashing routine.
- *
- * This is a wrapper around OSSL SHA256|384 and etc digesters.
- *
- * @param d
- * The data to digest.
- * @param n
- * The length of the data to digest.
- * @param md
- * The output message digest.
- * @return
- * A pointer to the digest or NULL on error.
- */
- typedef unsigned char *(*digester)(const unsigned char *d, size_t n,
- unsigned char *md);
- static inline const char *tpm2_openssl_get_err(void) {
- return ERR_error_string(ERR_get_error(), NULL);
- }
- /**
- * Get an openssl hash algorithm ID from a tpm hashing algorithm ID.
- * @param algorithm
- * The tpm algorithm to get the corresponding openssl version of.
- * @return
- * The openssl hash algorithm id.
- */
- int tpm2_openssl_halgid_from_tpmhalg(TPMI_ALG_HASH algorithm);
- /**
- * Get an openssl message digest from a tpm hashing algorithm.
- * @param algorithm
- * The tpm algorithm to get the corresponding openssl version of.
- * @return
- * A pointer to a message digester or NULL on failure.
- */
- const EVP_MD *tpm2_openssl_halg_from_tpmhalg(TPMI_ALG_HASH algorithm);
- /**
- * Start an openssl hmac session.
- * @return
- * A valid session pointer or NULL on error.
- */
- HMAC_CTX *tpm2_openssl_hmac_new();
- /**
- * Free an hmac context created via tpm2_openssl_hmac_new().
- * @param ctx
- * The context to release resources of.
- */
- void tpm2_openssl_hmac_free(HMAC_CTX *ctx);
- /**
- * Hash a byte buffer.
- * @param halg
- * The hashing algorithm to use.
- * @param buffer
- * The byte buffer to be hashed.
- * @param length
- * The length of the byte buffer to hash.
- ^ * @param digest
- ^ * The result of hashing digests with halg.
- * @return
- * true on success, false on error.
- */
- bool tpm2_openssl_hash_compute_data(TPMI_ALG_HASH halg, BYTE *buffer,
- UINT16 length, TPM2B_DIGEST *digest);
- /**
- * Hash a list of PCR digests.
- * @param halg
- * The hashing algorithm to use.
- * @param digests
- * The list of PCR digests to hash.
- ^ * @param digest
- ^ * The result of hashing digests with halg.
- * @return
- * true on success, false on error.
- */
- bool tpm2_openssl_hash_pcr_values(TPMI_ALG_HASH halg, TPML_DIGEST *digests,
- TPM2B_DIGEST *digest);
- /**
- * Hash a list of PCR digests, supporting multiple banks.
- * @param halg
- * The hashing algorithm to use.
- * @param pcr_select
- * The list that specifies which PCRs are selected.
- * @param pcrs
- * The list of PCR banks, each containing a list of PCR digests to hash.
- ^ * @param digest
- ^ * The result of hashing digests with halg.
- * @return
- * true on success, false on error.
- */
- bool tpm2_openssl_hash_pcr_banks(TPMI_ALG_HASH hashAlg,
- TPML_PCR_SELECTION *pcr_select, tpm2_pcrs *pcrs, TPM2B_DIGEST *digest);
- /*
- * Hash a list of PCR digests, supporting multiple banks.
- * The data in TPML_PCR_SELECTION and tpm2_pcrs is in little endian format.
- *
- * @param halg
- * The hashing algorithm to use.
- * @param pcr_select
- * The list that specifies which PCRs are selected.
- * @param pcrs
- * The list of PCR banks, each containing a list of PCR digests to hash.
- ^ * @param digest
- ^ * The result of hashing digests with halg.
- * @return
- * true on success, false on error.
- */
- bool tpm2_openssl_hash_pcr_banks_le(TPMI_ALG_HASH hashAlg,
- TPML_PCR_SELECTION *pcr_select, tpm2_pcrs *pcrs, TPM2B_DIGEST *digest);
- /**
- * Extend a PCR with a new digest.
- * @param halg
- * The hashing algorithm to use.
- * @param pcr
- * A buffer with the current value of the PCR, will be updated in place.
- * @param data
- * The new digest to be added to the current PCR.
- * @param length
- * Length of the new data to be added to the digest.
- * @return
- * true on success, false on error.
- */
- bool tpm2_openssl_pcr_extend(TPMI_ALG_HASH halg, BYTE *pcr,
- const BYTE *data, UINT16 length);
- /**
- * Obtains an OpenSSL EVP_CIPHER_CTX dealing with version
- * API changes in OSSL.
- *
- * @return
- * An Initialized OpenSSL EVP_CIPHER_CTX.
- */
- EVP_CIPHER_CTX *tpm2_openssl_cipher_new(void);
- /**
- * Free's an EVP_CIPHER_CTX obtained via tpm2_openssl_cipher_new()
- * dealing with OSSL API version changes.
- * @param ctx
- * The EVP_CIPHER_CTX to free.
- */
- void tpm2_openssl_cipher_free(EVP_CIPHER_CTX *ctx);
- /**
- * Returns a function pointer capable of performing the
- * given digest from a TPMI_HASH_ALG.
- *
- * @param halg
- * The hashing algorithm to use.
- * @return
- * NULL on failure or a valid digester on success.
- */
- digester tpm2_openssl_halg_to_digester(TPMI_ALG_HASH halg);
- typedef enum tpm2_openssl_load_rc tpm2_openssl_load_rc;
- enum tpm2_openssl_load_rc {
- lprc_error = 0, /* an error has occurred */
- lprc_private = 1 << 0, /* successfully loaded a private portion of object */
- lprc_public = 1 << 1, /* successfully loaded a public portion of object */
- };
- /**
- * Helper routine for gathering if the loading status included a public
- * portion of an object.
- *
- * @param load_status
- * The loading status obtained from a call to tpm2_openssl_load_private().
- * @return
- * True if the load status indicates it loaded a public portion of an object,
- * false otherwise.
- */
- static inline bool tpm2_openssl_did_load_public(
- tpm2_openssl_load_rc load_status) {
- return (load_status & lprc_public);
- }
- /**
- * Loads a private portion of a key, and possibly the public portion.
- * For asymmetric algorithms the public data is in private PEM file.
- * For symmetric keys, the file type is raw. For asymmetric keys, the
- * file type is a PEM file.
- *
- * This ONLY supports AES, ECC and RSA.
- *
- * It populates the sensitive seed with a random value for symmetric keys.
- *
- * @param path
- * The path to load from.
- * @param path
- * The passphrase for the input file.
- * @param alg
- * algorithm type to import.
- * @param pub
- * The public structure to populate. Note that nameAlg must be populated.
- * @param priv
- * The sensitive structure to populate.
- *
- * @returns
- * A private object loading status
- */
- tpm2_openssl_load_rc tpm2_openssl_load_private(const char *path,
- const char *pass, TPMI_ALG_PUBLIC alg, TPM2B_PUBLIC *pub,
- TPM2B_SENSITIVE *priv);
- /**
- * Load an OpenSSL private key and configure all of the flags based on
- * a parent key, policy, attributes, and authorization.
- */
- bool tpm2_openssl_import_keys(
- TPM2B_PUBLIC *parent_pub,
- TPM2B_SENSITIVE *private,
- TPM2B_PUBLIC *public,
- TPM2B_ENCRYPTED_SECRET *encrypted_seed,
- const char *input_key_file,
- TPMI_ALG_PUBLIC key_type,
- const char *auth_key_file,
- const char *policy_file,
- const char *key_auth_str,
- char *attrs_str,
- const char *name_alg_str
- );
- /**
- * Loads a public portion of a key from a file. Files can be the raw key, in the case
- * of symmetric ciphers, or a PEM file.
- *
- * @param path
- * The path to load from.
- * @param alg
- * algorithm type to import.
- * @param pub
- * The public structure to populate.
- * @return
- * True on success, false on failure.
- */
- bool tpm2_openssl_load_public(const char *path, TPMI_ALG_PUBLIC alg,
- TPM2B_PUBLIC *pub);
- /**
- * Retrieves a public portion of an ECC key from a PEM file.
- *
- * @param f
- * The FILE object that is open for reading the path.
- * @param path
- * The path to load from.
- * @return
- * The public structure.
- */
- EC_KEY* tpm2_openssl_get_public_ECC_from_pem(FILE *f, const char *path);
- /**
- * Maps an ECC curve to an openssl nid value.
- * @param curve
- * The curve to map.
- * @return
- * -1 on error or a >=0 nid on success.
- */
- int tpm2_ossl_curve_to_nid(TPMI_ECC_CURVE curve);
- #endif /* LIB_TPM2_OPENSSL_H_ */
|