tpm2_openssl.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /* SPDX-License-Identifier: BSD-3-Clause */
  2. #ifndef LIB_TPM2_OPENSSL_H_
  3. #define LIB_TPM2_OPENSSL_H_
  4. #include <tss2/tss2_sys.h>
  5. #include <openssl/ec.h>
  6. #include <openssl/ecdsa.h>
  7. #include <openssl/err.h>
  8. #include <openssl/hmac.h>
  9. #include <openssl/rsa.h>
  10. #include "pcr.h"
  11. #if (OPENSSL_VERSION_NUMBER < 0x1010000fL && !defined(LIBRESSL_VERSION_NUMBER)) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) /* OpenSSL 1.1.0 */
  12. #define LIB_TPM2_OPENSSL_OPENSSL_PRE11
  13. #endif
  14. #if OPENSSL_VERSION_NUMBER >= 0x10101000L
  15. #define EC_POINT_set_affine_coordinates_tss(group, tpm_pub_key, bn_x, bn_y, dmy) \
  16. EC_POINT_set_affine_coordinates(group, tpm_pub_key, bn_x, bn_y, dmy)
  17. #define EC_POINT_get_affine_coordinates_tss(group, tpm_pub_key, bn_x, bn_y, dmy) \
  18. EC_POINT_get_affine_coordinates(group, tpm_pub_key, bn_x, bn_y, dmy)
  19. #else
  20. #define EC_POINT_set_affine_coordinates_tss(group, tpm_pub_key, bn_x, bn_y, dmy) \
  21. EC_POINT_set_affine_coordinates_GFp(group, tpm_pub_key, bn_x, bn_y, dmy)
  22. #define EC_POINT_get_affine_coordinates_tss(group, tpm_pub_key, bn_x, bn_y, dmy) \
  23. EC_POINT_get_affine_coordinates_GFp(group, tpm_pub_key, bn_x, bn_y, dmy)
  24. #endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
  25. #if defined(LIB_TPM2_OPENSSL_OPENSSL_PRE11)
  26. int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);
  27. void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q);
  28. int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s);
  29. EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void);
  30. void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx);
  31. #endif
  32. /**
  33. * Function prototype for a hashing routine.
  34. *
  35. * This is a wrapper around OSSL SHA256|384 and etc digesters.
  36. *
  37. * @param d
  38. * The data to digest.
  39. * @param n
  40. * The length of the data to digest.
  41. * @param md
  42. * The output message digest.
  43. * @return
  44. * A pointer to the digest or NULL on error.
  45. */
  46. typedef unsigned char *(*digester)(const unsigned char *d, size_t n,
  47. unsigned char *md);
  48. static inline const char *tpm2_openssl_get_err(void) {
  49. return ERR_error_string(ERR_get_error(), NULL);
  50. }
  51. /**
  52. * Get an openssl hash algorithm ID from a tpm hashing algorithm ID.
  53. * @param algorithm
  54. * The tpm algorithm to get the corresponding openssl version of.
  55. * @return
  56. * The openssl hash algorithm id.
  57. */
  58. int tpm2_openssl_halgid_from_tpmhalg(TPMI_ALG_HASH algorithm);
  59. /**
  60. * Get an openssl message digest from a tpm hashing algorithm.
  61. * @param algorithm
  62. * The tpm algorithm to get the corresponding openssl version of.
  63. * @return
  64. * A pointer to a message digester or NULL on failure.
  65. */
  66. const EVP_MD *tpm2_openssl_halg_from_tpmhalg(TPMI_ALG_HASH algorithm);
  67. /**
  68. * Start an openssl hmac session.
  69. * @return
  70. * A valid session pointer or NULL on error.
  71. */
  72. HMAC_CTX *tpm2_openssl_hmac_new();
  73. /**
  74. * Free an hmac context created via tpm2_openssl_hmac_new().
  75. * @param ctx
  76. * The context to release resources of.
  77. */
  78. void tpm2_openssl_hmac_free(HMAC_CTX *ctx);
  79. /**
  80. * Hash a byte buffer.
  81. * @param halg
  82. * The hashing algorithm to use.
  83. * @param buffer
  84. * The byte buffer to be hashed.
  85. * @param length
  86. * The length of the byte buffer to hash.
  87. ^ * @param digest
  88. ^ * The result of hashing digests with halg.
  89. * @return
  90. * true on success, false on error.
  91. */
  92. bool tpm2_openssl_hash_compute_data(TPMI_ALG_HASH halg, BYTE *buffer,
  93. UINT16 length, TPM2B_DIGEST *digest);
  94. /**
  95. * Hash a list of PCR digests.
  96. * @param halg
  97. * The hashing algorithm to use.
  98. * @param digests
  99. * The list of PCR digests to hash.
  100. ^ * @param digest
  101. ^ * The result of hashing digests with halg.
  102. * @return
  103. * true on success, false on error.
  104. */
  105. bool tpm2_openssl_hash_pcr_values(TPMI_ALG_HASH halg, TPML_DIGEST *digests,
  106. TPM2B_DIGEST *digest);
  107. /**
  108. * Hash a list of PCR digests, supporting multiple banks.
  109. * @param halg
  110. * The hashing algorithm to use.
  111. * @param pcr_select
  112. * The list that specifies which PCRs are selected.
  113. * @param pcrs
  114. * The list of PCR banks, each containing a list of PCR digests to hash.
  115. ^ * @param digest
  116. ^ * The result of hashing digests with halg.
  117. * @return
  118. * true on success, false on error.
  119. */
  120. bool tpm2_openssl_hash_pcr_banks(TPMI_ALG_HASH hashAlg,
  121. TPML_PCR_SELECTION *pcr_select, tpm2_pcrs *pcrs, TPM2B_DIGEST *digest);
  122. /*
  123. * Hash a list of PCR digests, supporting multiple banks.
  124. * The data in TPML_PCR_SELECTION and tpm2_pcrs is in little endian format.
  125. *
  126. * @param halg
  127. * The hashing algorithm to use.
  128. * @param pcr_select
  129. * The list that specifies which PCRs are selected.
  130. * @param pcrs
  131. * The list of PCR banks, each containing a list of PCR digests to hash.
  132. ^ * @param digest
  133. ^ * The result of hashing digests with halg.
  134. * @return
  135. * true on success, false on error.
  136. */
  137. bool tpm2_openssl_hash_pcr_banks_le(TPMI_ALG_HASH hashAlg,
  138. TPML_PCR_SELECTION *pcr_select, tpm2_pcrs *pcrs, TPM2B_DIGEST *digest);
  139. /**
  140. * Extend a PCR with a new digest.
  141. * @param halg
  142. * The hashing algorithm to use.
  143. * @param pcr
  144. * A buffer with the current value of the PCR, will be updated in place.
  145. * @param data
  146. * The new digest to be added to the current PCR.
  147. * @param length
  148. * Length of the new data to be added to the digest.
  149. * @return
  150. * true on success, false on error.
  151. */
  152. bool tpm2_openssl_pcr_extend(TPMI_ALG_HASH halg, BYTE *pcr,
  153. const BYTE *data, UINT16 length);
  154. /**
  155. * Obtains an OpenSSL EVP_CIPHER_CTX dealing with version
  156. * API changes in OSSL.
  157. *
  158. * @return
  159. * An Initialized OpenSSL EVP_CIPHER_CTX.
  160. */
  161. EVP_CIPHER_CTX *tpm2_openssl_cipher_new(void);
  162. /**
  163. * Free's an EVP_CIPHER_CTX obtained via tpm2_openssl_cipher_new()
  164. * dealing with OSSL API version changes.
  165. * @param ctx
  166. * The EVP_CIPHER_CTX to free.
  167. */
  168. void tpm2_openssl_cipher_free(EVP_CIPHER_CTX *ctx);
  169. /**
  170. * Returns a function pointer capable of performing the
  171. * given digest from a TPMI_HASH_ALG.
  172. *
  173. * @param halg
  174. * The hashing algorithm to use.
  175. * @return
  176. * NULL on failure or a valid digester on success.
  177. */
  178. digester tpm2_openssl_halg_to_digester(TPMI_ALG_HASH halg);
  179. typedef enum tpm2_openssl_load_rc tpm2_openssl_load_rc;
  180. enum tpm2_openssl_load_rc {
  181. lprc_error = 0, /* an error has occurred */
  182. lprc_private = 1 << 0, /* successfully loaded a private portion of object */
  183. lprc_public = 1 << 1, /* successfully loaded a public portion of object */
  184. };
  185. /**
  186. * Helper routine for gathering if the loading status included a public
  187. * portion of an object.
  188. *
  189. * @param load_status
  190. * The loading status obtained from a call to tpm2_openssl_load_private().
  191. * @return
  192. * True if the load status indicates it loaded a public portion of an object,
  193. * false otherwise.
  194. */
  195. static inline bool tpm2_openssl_did_load_public(
  196. tpm2_openssl_load_rc load_status) {
  197. return (load_status & lprc_public);
  198. }
  199. /**
  200. * Loads a private portion of a key, and possibly the public portion.
  201. * For asymmetric algorithms the public data is in private PEM file.
  202. * For symmetric keys, the file type is raw. For asymmetric keys, the
  203. * file type is a PEM file.
  204. *
  205. * This ONLY supports AES, ECC and RSA.
  206. *
  207. * It populates the sensitive seed with a random value for symmetric keys.
  208. *
  209. * @param path
  210. * The path to load from.
  211. * @param path
  212. * The passphrase for the input file.
  213. * @param alg
  214. * algorithm type to import.
  215. * @param pub
  216. * The public structure to populate. Note that nameAlg must be populated.
  217. * @param priv
  218. * The sensitive structure to populate.
  219. *
  220. * @returns
  221. * A private object loading status
  222. */
  223. tpm2_openssl_load_rc tpm2_openssl_load_private(const char *path,
  224. const char *pass, TPMI_ALG_PUBLIC alg, TPM2B_PUBLIC *pub,
  225. TPM2B_SENSITIVE *priv);
  226. /**
  227. * Load an OpenSSL private key and configure all of the flags based on
  228. * a parent key, policy, attributes, and authorization.
  229. */
  230. bool tpm2_openssl_import_keys(
  231. TPM2B_PUBLIC *parent_pub,
  232. TPM2B_SENSITIVE *private,
  233. TPM2B_PUBLIC *public,
  234. TPM2B_ENCRYPTED_SECRET *encrypted_seed,
  235. const char *input_key_file,
  236. TPMI_ALG_PUBLIC key_type,
  237. const char *auth_key_file,
  238. const char *policy_file,
  239. const char *key_auth_str,
  240. char *attrs_str,
  241. const char *name_alg_str
  242. );
  243. /**
  244. * Loads a public portion of a key from a file. Files can be the raw key, in the case
  245. * of symmetric ciphers, or a PEM file.
  246. *
  247. * @param path
  248. * The path to load from.
  249. * @param alg
  250. * algorithm type to import.
  251. * @param pub
  252. * The public structure to populate.
  253. * @return
  254. * True on success, false on failure.
  255. */
  256. bool tpm2_openssl_load_public(const char *path, TPMI_ALG_PUBLIC alg,
  257. TPM2B_PUBLIC *pub);
  258. /**
  259. * Retrieves a public portion of an ECC key from a PEM file.
  260. *
  261. * @param f
  262. * The FILE object that is open for reading the path.
  263. * @param path
  264. * The path to load from.
  265. * @return
  266. * The public structure.
  267. */
  268. EC_KEY* tpm2_openssl_get_public_ECC_from_pem(FILE *f, const char *path);
  269. /**
  270. * Maps an ECC curve to an openssl nid value.
  271. * @param curve
  272. * The curve to map.
  273. * @return
  274. * -1 on error or a >=0 nid on success.
  275. */
  276. int tpm2_ossl_curve_to_nid(TPMI_ECC_CURVE curve);
  277. #endif /* LIB_TPM2_OPENSSL_H_ */