1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
10 #include "openssl-util.h"
11 #include "ordered-set.h"
15 typedef enum TPM2Flags
{
16 TPM2_FLAGS_USE_PIN
= 1 << 0,
17 TPM2_FLAGS_USE_PCRLOCK
= 1 << 1,
20 /* As per https://trustedcomputinggroup.org/wp-content/uploads/TCG_PCClient_PFP_r1p05_v23_pub.pdf a
21 * TPM2 on a Client PC must have at least 24 PCRs. This hardcodes our expectation of 24. */
22 #define TPM2_PCRS_MAX 24U
23 #define TPM2_PCRS_MASK ((UINT32_C(1) << TPM2_PCRS_MAX) - 1)
25 /* The SRK handle is defined in the Provisioning Guidance document (see above) in the table "Reserved Handles
26 * for TPM Provisioning Fundamental Elements". The SRK is useful because it is "shared", meaning it has no
27 * authValue nor authPolicy set, and thus may be used by anyone on the system to generate derived keys or
28 * seal secrets. This is useful if the TPM has an auth (password) set for the 'owner hierarchy', which would
29 * prevent users from generating primary transient keys, unless they knew the owner hierarchy auth. See
30 * the Provisioning Guidance document for more details. */
31 #define TPM2_SRK_HANDLE UINT32_C(0x81000001)
33 /* The TPM specification limits sealed data to MAX_SYM_DATA. Unfortunately, tpm2-tss incorrectly
34 * defines this value as 256; the TPM specification Part 2 ("Structures") section
35 * "TPMU_SENSITIVE_CREATE" states "For interoperability, MAX_SYM_DATA should be 128." */
36 #define TPM2_MAX_SEALED_DATA UINT16_C(128)
38 static inline bool TPM2_PCR_INDEX_VALID(unsigned pcr
) {
39 return pcr
< TPM2_PCRS_MAX
;
41 static inline bool TPM2_PCR_MASK_VALID(uint32_t pcr_mask
) {
42 return pcr_mask
<= TPM2_PCRS_MASK
;
45 #define FOREACH_PCR_IN_MASK(pcr, mask) BIT_FOREACH(pcr, mask)
47 #define TPM2_N_HASH_ALGORITHMS 4U
51 #include <tss2/tss2_esys.h>
52 #include <tss2/tss2_mu.h>
53 #include <tss2/tss2_rc.h>
55 int dlopen_tpm2(void);
61 TSS2_TCTI_CONTEXT
*tcti_context
;
62 ESYS_CONTEXT
*esys_context
;
64 /* Some selected cached capabilities of the TPM */
65 TPMS_ALG_PROPERTY
*capability_algorithms
;
66 size_t n_capability_algorithms
;
67 TPMA_CC
*capability_commands
;
68 size_t n_capability_commands
;
69 TPM2_ECC_CURVE
*capability_ecc_curves
;
70 size_t n_capability_ecc_curves
;
71 TPML_PCR_SELECTION capability_pcrs
;
74 int tpm2_context_new(const char *device
, Tpm2Context
**ret_context
);
75 Tpm2Context
*tpm2_context_ref(Tpm2Context
*context
);
76 Tpm2Context
*tpm2_context_unref(Tpm2Context
*context
);
77 DEFINE_TRIVIAL_CLEANUP_FUNC(Tpm2Context
*, tpm2_context_unref
);
80 Tpm2Context
*tpm2_context
;
86 #define _tpm2_handle(c, h) { .tpm2_context = (c), .esys_handle = (h), }
87 static const Tpm2Handle TPM2_HANDLE_NONE
= _tpm2_handle(NULL
, ESYS_TR_NONE
);
89 void Esys_Freep(void *p
);
91 int tpm2_handle_new(Tpm2Context
*context
, Tpm2Handle
**ret_handle
);
92 Tpm2Handle
*tpm2_handle_free(Tpm2Handle
*handle
);
93 DEFINE_TRIVIAL_CLEANUP_FUNC(Tpm2Handle
*, tpm2_handle_free
);
101 #define TPM2_PCR_VALUE_MAKE(i, h, v) \
105 .value = ((TPM2B_DIGEST) v), \
108 bool tpm2_pcr_value_valid(const Tpm2PCRValue
*pcr_value
);
109 bool tpm2_pcr_values_has_any_values(const Tpm2PCRValue
*pcr_values
, size_t n_pcr_values
);
110 bool tpm2_pcr_values_has_all_values(const Tpm2PCRValue
*pcr_values
, size_t n_pcr_values
);
111 int tpm2_pcr_value_from_string(const char *arg
, Tpm2PCRValue
*ret_pcr_value
);
112 char *tpm2_pcr_value_to_string(const Tpm2PCRValue
*pcr_value
);
114 bool tpm2_pcr_values_valid(const Tpm2PCRValue
*pcr_values
, size_t n_pcr_values
);
115 void tpm2_sort_pcr_values(Tpm2PCRValue
*pcr_values
, size_t n_pcr_values
);
116 int tpm2_pcr_values_from_mask(uint32_t mask
, TPMI_ALG_HASH hash
, Tpm2PCRValue
**ret_pcr_values
, size_t *ret_n_pcr_values
);
117 int tpm2_pcr_values_to_mask(const Tpm2PCRValue
*pcr_values
, size_t n_pcr_values
, TPMI_ALG_HASH hash
, uint32_t *ret_mask
);
118 int tpm2_pcr_values_from_string(const char *arg
, Tpm2PCRValue
**ret_pcr_values
, size_t *ret_n_pcr_values
);
119 char *tpm2_pcr_values_to_string(const Tpm2PCRValue
*pcr_values
, size_t n_pcr_values
);
120 int tpm2_pcr_values_hash_count(const Tpm2PCRValue
*pcr_values
, size_t n_pcr_values
, size_t *ret_count
);
121 int tpm2_tpml_pcr_selection_from_pcr_values(const Tpm2PCRValue
*pcr_values
, size_t n_pcr_values
, TPML_PCR_SELECTION
*ret_selection
, TPM2B_DIGEST
**ret_values
, size_t *ret_n_values
);
123 int tpm2_make_encryption_session(Tpm2Context
*c
, const Tpm2Handle
*primary
, const Tpm2Handle
*bind_key
, Tpm2Handle
**ret_session
);
125 int tpm2_create_primary(Tpm2Context
*c
, const Tpm2Handle
*session
, const TPM2B_PUBLIC
*template, const TPM2B_SENSITIVE_CREATE
*sensitive
, TPM2B_PUBLIC
**ret_public
, Tpm2Handle
**ret_handle
);
126 int tpm2_create(Tpm2Context
*c
, const Tpm2Handle
*parent
, const Tpm2Handle
*session
, const TPMT_PUBLIC
*template, const TPMS_SENSITIVE_CREATE
*sensitive
, TPM2B_PUBLIC
**ret_public
, TPM2B_PRIVATE
**ret_private
);
127 int tpm2_create_loaded(Tpm2Context
*c
, const Tpm2Handle
*parent
, const Tpm2Handle
*session
, const TPMT_PUBLIC
*template, const TPMS_SENSITIVE_CREATE
*sensitive
, TPM2B_PUBLIC
**ret_public
, TPM2B_PRIVATE
**ret_private
, Tpm2Handle
**ret_handle
);
128 int tpm2_load(Tpm2Context
*c
, const Tpm2Handle
*parent
, const Tpm2Handle
*session
, const TPM2B_PUBLIC
*public, const TPM2B_PRIVATE
*private, Tpm2Handle
**ret_handle
);
129 int tpm2_marshal_public(const TPM2B_PUBLIC
*public, void **ret
, size_t *ret_size
);
130 int tpm2_marshal_nv_public(const TPM2B_NV_PUBLIC
*nv_public
, void **ret
, size_t *ret_size
);
131 int tpm2_unmarshal_nv_public(const void *data
, size_t size
, TPM2B_NV_PUBLIC
*ret_nv_public
);
132 int tpm2_marshal_blob(const TPM2B_PUBLIC
*public, const TPM2B_PRIVATE
*private, const TPM2B_ENCRYPTED_SECRET
*seed
, void **ret_blob
, size_t *ret_blob_size
);
133 int tpm2_unmarshal_blob(const void *blob
, size_t blob_size
, TPM2B_PUBLIC
*ret_public
, TPM2B_PRIVATE
*ret_private
, TPM2B_ENCRYPTED_SECRET
*ret_seed
);
135 bool tpm2_supports_alg(Tpm2Context
*c
, TPM2_ALG_ID alg
);
136 bool tpm2_supports_command(Tpm2Context
*c
, TPM2_CC command
);
137 bool tpm2_supports_ecc_curve(Tpm2Context
*c
, TPM2_ECC_CURVE ecc_curve
);
139 bool tpm2_test_parms(Tpm2Context
*c
, TPMI_ALG_PUBLIC alg
, const TPMU_PUBLIC_PARMS
*parms
);
141 int tpm2_get_good_pcr_banks(Tpm2Context
*c
, uint32_t pcr_mask
, TPMI_ALG_HASH
**ret_banks
);
142 int tpm2_get_good_pcr_banks_strv(Tpm2Context
*c
, uint32_t pcr_mask
, char ***ret
);
143 int tpm2_get_best_pcr_bank(Tpm2Context
*c
, uint32_t pcr_mask
, TPMI_ALG_HASH
*ret
);
145 const char *tpm2_userspace_log_path(void);
146 const char *tpm2_firmware_log_path(void);
148 typedef enum Tpm2UserspaceEventType
{
150 TPM2_EVENT_FILESYSTEM
,
151 TPM2_EVENT_VOLUME_KEY
,
152 TPM2_EVENT_MACHINE_ID
,
153 _TPM2_USERSPACE_EVENT_TYPE_MAX
,
154 _TPM2_USERSPACE_EVENT_TYPE_INVALID
= -EINVAL
,
155 } Tpm2UserspaceEventType
;
157 const char* tpm2_userspace_event_type_to_string(Tpm2UserspaceEventType type
) _const_
;
158 Tpm2UserspaceEventType
tpm2_userspace_event_type_from_string(const char *s
) _pure_
;
160 int tpm2_extend_bytes(Tpm2Context
*c
, char **banks
, unsigned pcr_index
, const void *data
, size_t data_size
, const void *secret
, size_t secret_size
, Tpm2UserspaceEventType event
, const char *description
);
162 uint32_t tpm2_tpms_pcr_selection_to_mask(const TPMS_PCR_SELECTION
*s
);
163 void tpm2_tpms_pcr_selection_from_mask(uint32_t mask
, TPMI_ALG_HASH hash
, TPMS_PCR_SELECTION
*ret
);
164 bool tpm2_tpms_pcr_selection_has_mask(const TPMS_PCR_SELECTION
*s
, uint32_t mask
);
165 void tpm2_tpms_pcr_selection_add_mask(TPMS_PCR_SELECTION
*s
, uint32_t mask
);
166 void tpm2_tpms_pcr_selection_sub_mask(TPMS_PCR_SELECTION
*s
, uint32_t mask
);
167 void tpm2_tpms_pcr_selection_add(TPMS_PCR_SELECTION
*a
, const TPMS_PCR_SELECTION
*b
);
168 void tpm2_tpms_pcr_selection_sub(TPMS_PCR_SELECTION
*a
, const TPMS_PCR_SELECTION
*b
);
169 void tpm2_tpms_pcr_selection_move(TPMS_PCR_SELECTION
*a
, TPMS_PCR_SELECTION
*b
);
170 char *tpm2_tpms_pcr_selection_to_string(const TPMS_PCR_SELECTION
*s
);
171 size_t tpm2_tpms_pcr_selection_weight(const TPMS_PCR_SELECTION
*s
);
172 #define tpm2_tpms_pcr_selection_is_empty(s) (tpm2_tpms_pcr_selection_weight(s) == 0)
174 uint32_t tpm2_tpml_pcr_selection_to_mask(const TPML_PCR_SELECTION
*l
, TPMI_ALG_HASH hash
);
175 void tpm2_tpml_pcr_selection_from_mask(uint32_t mask
, TPMI_ALG_HASH hash
, TPML_PCR_SELECTION
*ret
);
176 bool tpm2_tpml_pcr_selection_has_mask(const TPML_PCR_SELECTION
*l
, TPMI_ALG_HASH hash
, uint32_t mask
);
177 void tpm2_tpml_pcr_selection_add_mask(TPML_PCR_SELECTION
*l
, TPMI_ALG_HASH hash
, uint32_t mask
);
178 void tpm2_tpml_pcr_selection_sub_mask(TPML_PCR_SELECTION
*l
, TPMI_ALG_HASH hash
, uint32_t mask
);
179 void tpm2_tpml_pcr_selection_add_tpms_pcr_selection(TPML_PCR_SELECTION
*l
, const TPMS_PCR_SELECTION
*s
);
180 void tpm2_tpml_pcr_selection_sub_tpms_pcr_selection(TPML_PCR_SELECTION
*l
, const TPMS_PCR_SELECTION
*s
);
181 void tpm2_tpml_pcr_selection_add(TPML_PCR_SELECTION
*a
, const TPML_PCR_SELECTION
*b
);
182 void tpm2_tpml_pcr_selection_sub(TPML_PCR_SELECTION
*a
, const TPML_PCR_SELECTION
*b
);
183 char *tpm2_tpml_pcr_selection_to_string(const TPML_PCR_SELECTION
*l
);
184 size_t tpm2_tpml_pcr_selection_weight(const TPML_PCR_SELECTION
*l
);
185 #define tpm2_tpml_pcr_selection_is_empty(l) (tpm2_tpml_pcr_selection_weight(l) == 0)
187 int tpm2_digest_many(TPMI_ALG_HASH alg
, TPM2B_DIGEST
*digest
, const struct iovec data
[], size_t count
, bool extend
);
188 static inline int tpm2_digest_buffer(TPMI_ALG_HASH alg
, TPM2B_DIGEST
*digest
, const void *data
, size_t len
, bool extend
) {
189 return tpm2_digest_many(alg
, digest
, &IOVEC_MAKE((void*) data
, len
), 1, extend
);
191 int tpm2_digest_many_digests(TPMI_ALG_HASH alg
, TPM2B_DIGEST
*digest
, const TPM2B_DIGEST data
[], size_t count
, bool extend
);
192 static inline int tpm2_digest_rehash(TPMI_ALG_HASH alg
, TPM2B_DIGEST
*digest
) {
193 return tpm2_digest_many(alg
, digest
, NULL
, 0, true);
195 static inline int tpm2_digest_init(TPMI_ALG_HASH alg
, TPM2B_DIGEST
*digest
) {
196 return tpm2_digest_many(alg
, digest
, NULL
, 0, false);
199 void tpm2_log_debug_tpml_pcr_selection(const TPML_PCR_SELECTION
*l
, const char *msg
);
200 void tpm2_log_debug_pcr_value(const Tpm2PCRValue
*pcr_value
, const char *msg
);
201 void tpm2_log_debug_buffer(const void *buffer
, size_t size
, const char *msg
);
202 void tpm2_log_debug_digest(const TPM2B_DIGEST
*digest
, const char *msg
);
203 void tpm2_log_debug_name(const TPM2B_NAME
*name
, const char *msg
);
205 typedef struct Tpm2PCRPredictionResult
{
206 TPM2B_DIGEST hash
[TPM2_N_HASH_ALGORITHMS
]; /* a hash for each potential algorithm */
207 } Tpm2PCRPredictionResult
;
209 TPM2B_DIGEST
*tpm2_pcr_prediction_result_get_hash(Tpm2PCRPredictionResult
*result
, uint16_t alg
);
211 /* A structure encapsulating a full set of PCR predictions with alternatives. This can be converted into a
212 * series of PolicyOR + PolicyPCR items for the TPM. */
213 typedef struct Tpm2PCRPrediction
{
214 uint32_t pcrs
; /* A mask of pcrs included */
215 OrderedSet
* results
[TPM2_PCRS_MAX
]; /* set of Tpm2PCRPredictionResult objects, one for each PCR */
218 void tpm2_pcr_prediction_done(Tpm2PCRPrediction
*p
);
220 extern const struct hash_ops tpm2_pcr_prediction_result_hash_ops
;
222 bool tpm2_pcr_prediction_equal(Tpm2PCRPrediction
*a
, Tpm2PCRPrediction
*b
, uint16_t algorithm
);
224 int tpm2_pcr_prediction_to_json(const Tpm2PCRPrediction
*prediction
, uint16_t algorithm
, JsonVariant
**ret
);
225 int tpm2_pcr_prediction_from_json(Tpm2PCRPrediction
*prediction
, uint16_t algorithm
, JsonVariant
*aj
);
227 /* As structure encapsulating all metadata stored for a pcrlock policy on disk */
228 typedef struct Tpm2PCRLockPolicy
{
229 /* The below is the fixed metadata encoding information about the NV index we store the
230 * PolicyAuthorizeNV policy in, as well as a pinned SRK, and the encrypted PIN to use for writing to
234 struct iovec nv_handle
;
235 struct iovec nv_public
;
236 struct iovec srk_handle
;
237 struct iovec pin_public
;
238 struct iovec pin_private
;
240 /* The below contains the current prediction whose resulting policy is stored in the NV
241 * index. Once in JSON and once in parsed form. When the policy is updated the fields below are
242 * changed, the fields above remain fixed. */
243 JsonVariant
*prediction_json
;
244 Tpm2PCRPrediction prediction
;
247 void tpm2_pcrlock_policy_done(Tpm2PCRLockPolicy
*data
);
248 int tpm2_pcrlock_search_file(const char *path
, FILE **ret_file
, char **ret_path
);
249 int tpm2_pcrlock_policy_load(const char *path
, Tpm2PCRLockPolicy
*ret_policy
);
251 int tpm2_index_to_handle(Tpm2Context
*c
, TPM2_HANDLE index
, const Tpm2Handle
*session
, TPM2B_PUBLIC
**ret_public
, TPM2B_NAME
**ret_name
, TPM2B_NAME
**ret_qname
, Tpm2Handle
**ret_handle
);
252 int tpm2_index_from_handle(Tpm2Context
*c
, const Tpm2Handle
*handle
, TPM2_HANDLE
*ret_index
);
254 int tpm2_pcr_read(Tpm2Context
*c
, const TPML_PCR_SELECTION
*pcr_selection
, Tpm2PCRValue
**ret_pcr_values
, size_t *ret_n_pcr_values
);
255 int tpm2_pcr_read_missing_values(Tpm2Context
*c
, Tpm2PCRValue
*pcr_values
, size_t n_pcr_values
);
257 int tpm2_get_pin_auth(TPMI_ALG_HASH hash
, const char *pin
, TPM2B_AUTH
*ret_auth
);
258 int tpm2_set_auth(Tpm2Context
*c
, const Tpm2Handle
*handle
, const char *pin
);
259 int tpm2_set_auth_binary(Tpm2Context
*c
, const Tpm2Handle
*handle
, const TPM2B_AUTH
*auth
);
261 int tpm2_make_policy_session(Tpm2Context
*c
, const Tpm2Handle
*primary
, const Tpm2Handle
*encryption_session
, Tpm2Handle
**ret_session
);
263 int tpm2_policy_auth_value(Tpm2Context
*c
, const Tpm2Handle
*session
, TPM2B_DIGEST
**ret_policy_digest
);
264 int tpm2_policy_authorize_nv(Tpm2Context
*c
, const Tpm2Handle
*session
, const Tpm2Handle
*nv_handle
, TPM2B_DIGEST
**ret_policy_digest
);
265 int tpm2_policy_pcr(Tpm2Context
*c
, const Tpm2Handle
*session
, const TPML_PCR_SELECTION
*pcr_selection
, TPM2B_DIGEST
**ret_policy_digest
);
266 int tpm2_policy_or(Tpm2Context
*c
, const Tpm2Handle
*session
, const TPM2B_DIGEST
*branches
, size_t n_branches
, TPM2B_DIGEST
**ret_policy_digest
);
267 int tpm2_policy_super_pcr(Tpm2Context
*c
, const Tpm2Handle
*session
, const Tpm2PCRPrediction
*prediction
, uint16_t algorithm
);
269 int tpm2_calculate_pubkey_name(const TPMT_PUBLIC
*public, TPM2B_NAME
*ret_name
);
270 int tpm2_calculate_nv_index_name(const TPMS_NV_PUBLIC
*nvpublic
, TPM2B_NAME
*ret_name
);
272 int tpm2_calculate_policy_auth_value(TPM2B_DIGEST
*digest
);
273 int tpm2_calculate_policy_authorize(const TPM2B_PUBLIC
*public, const TPM2B_DIGEST
*policy_ref
, TPM2B_DIGEST
*digest
);
274 int tpm2_calculate_policy_authorize_nv(const TPM2B_NV_PUBLIC
*public, TPM2B_DIGEST
*digest
);
275 int tpm2_calculate_policy_pcr(const Tpm2PCRValue
*pcr_values
, size_t n_pcr_values
, TPM2B_DIGEST
*digest
);
276 int tpm2_calculate_policy_or(const TPM2B_DIGEST
*branches
, size_t n_branches
, TPM2B_DIGEST
*digest
);
277 int tpm2_calculate_policy_super_pcr(Tpm2PCRPrediction
*prediction
, uint16_t algorithm
, TPM2B_DIGEST
*pcr_policy
);
278 int tpm2_calculate_serialize(TPM2_HANDLE handle
, const TPM2B_NAME
*name
, const TPM2B_PUBLIC
*public, void **ret_serialized
, size_t *ret_serialized_size
);
279 int tpm2_calculate_sealing_policy(const Tpm2PCRValue
*pcr_values
, size_t n_pcr_values
, const TPM2B_PUBLIC
*public, bool use_pin
, const Tpm2PCRLockPolicy
*policy
, TPM2B_DIGEST
*digest
);
280 int tpm2_calculate_seal(TPM2_HANDLE parent_handle
, const TPM2B_PUBLIC
*parent_public
, const TPMA_OBJECT
*attributes
, const struct iovec
*secret
, const TPM2B_DIGEST
*policy
, const char *pin
, struct iovec
*ret_secret
, struct iovec
*ret_blob
, struct iovec
*ret_serialized_parent
);
282 int tpm2_get_srk_template(TPMI_ALG_PUBLIC alg
, TPMT_PUBLIC
*ret_template
);
283 int tpm2_get_best_srk_template(Tpm2Context
*c
, TPMT_PUBLIC
*ret_template
);
285 int tpm2_get_srk(Tpm2Context
*c
, const Tpm2Handle
*session
, TPM2B_PUBLIC
**ret_public
, TPM2B_NAME
**ret_name
, TPM2B_NAME
**ret_qname
, Tpm2Handle
**ret_handle
);
286 int tpm2_get_or_create_srk(Tpm2Context
*c
, const Tpm2Handle
*session
, TPM2B_PUBLIC
**ret_public
, TPM2B_NAME
**ret_name
, TPM2B_NAME
**ret_qname
, Tpm2Handle
**ret_handle
);
288 int tpm2_seal(Tpm2Context
*c
, uint32_t seal_key_handle
, const TPM2B_DIGEST
*policy
, const char *pin
, struct iovec
*ret_secret
, struct iovec
*ret_blob
, uint16_t *ret_primary_alg
, struct iovec
*ret_srk
);
289 int tpm2_unseal(Tpm2Context
*c
, uint32_t hash_pcr_mask
, uint16_t pcr_bank
, const struct iovec
*pubkey
, uint32_t pubkey_pcr_mask
, JsonVariant
*signature
, const char *pin
, const Tpm2PCRLockPolicy
*pcrlock_policy
, uint16_t primary_alg
, const struct iovec
*blob
, const struct iovec
*policy_hash
, const struct iovec
*srk
, struct iovec
*ret_secret
);
292 int tpm2_tpm2b_public_to_openssl_pkey(const TPM2B_PUBLIC
*public, EVP_PKEY
**ret
);
293 int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY
*pkey
, TPM2B_PUBLIC
*ret
);
296 int tpm2_tpm2b_public_from_pem(const void *pem
, size_t pem_size
, TPM2B_PUBLIC
*ret
);
297 int tpm2_tpm2b_public_to_fingerprint(const TPM2B_PUBLIC
*public, void **ret_fingerprint
, size_t *ret_fingerprint_size
);
299 int tpm2_define_policy_nv_index(Tpm2Context
*c
, const Tpm2Handle
*session
, TPM2_HANDLE requested_nv_index
, const TPM2B_DIGEST
*write_policy
, const char *pin
, const TPM2B_AUTH
*auth
, TPM2_HANDLE
*ret_nv_index
, Tpm2Handle
**ret_nv_handle
, TPM2B_NV_PUBLIC
*ret_nv_public
);
300 int tpm2_write_policy_nv_index(Tpm2Context
*c
, const Tpm2Handle
*policy_session
, TPM2_HANDLE nv_index
, const Tpm2Handle
*nv_handle
, const TPM2B_DIGEST
*policy_digest
);
301 int tpm2_undefine_policy_nv_index(Tpm2Context
*c
, const Tpm2Handle
*session
, TPM2_HANDLE nv_index
, const Tpm2Handle
*nv_handle
);
303 int tpm2_seal_data(Tpm2Context
*c
, const struct iovec
*data
, const Tpm2Handle
*primary_handle
, const Tpm2Handle
*encryption_session
, const TPM2B_DIGEST
*policy
, struct iovec
*ret_public
, struct iovec
*ret_private
);
304 int tpm2_unseal_data(Tpm2Context
*c
, const struct iovec
*public, const struct iovec
*private, const Tpm2Handle
*primary_handle
, const Tpm2Handle
*policy_session
, const Tpm2Handle
*encryption_session
, struct iovec
*ret_data
);
306 int tpm2_serialize(Tpm2Context
*c
, const Tpm2Handle
*handle
, void **ret_serialized
, size_t *ret_serialized_size
);
307 int tpm2_deserialize(Tpm2Context
*c
, const void *serialized
, size_t serialized_size
, Tpm2Handle
**ret_handle
);
309 int tpm2_load_public_key_file(const char *path
, TPM2B_PUBLIC
*ret
);
311 /* The tpm2-tss library has many structs that are simply a combination of an array (or object) and
312 * size. These macros allow easily initializing or assigning instances of such structs from an existing
313 * buffer/object and size, while also checking the size for safety with the struct buffer/object size. If the
314 * provided buffer/object is NULL, the resulting struct's buffer/object will be 0s. If the provided size is
315 * larger than the struct's buffer/object size, this results in assertion failure; to check the size, use one
316 * of the TPM2B_*_CHECK_SIZE() macros. */
317 #define TPM2B_AUTH_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_AUTH, buffer, size)
318 #define TPM2B_DATA_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_DATA, buffer, size)
319 #define TPM2B_DIGEST_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_DIGEST, buffer, size)
320 #define TPM2B_ECC_PARAMETER_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_ECC_PARAMETER, buffer, size)
321 #define TPM2B_ENCRYPTED_SECRET_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_ENCRYPTED_SECRET, secret, size)
322 #define TPM2B_MAX_BUFFER_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_MAX_BUFFER, buffer, size)
323 #define TPM2B_NAME_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_NAME, name, size)
324 #define TPM2B_PRIVATE_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_PRIVATE, buffer, size)
325 #define TPM2B_PRIVATE_KEY_RSA_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_PRIVATE_KEY_RSA, buffer, size)
326 #define TPM2B_PUBLIC_KEY_RSA_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_PUBLIC_KEY_RSA, buffer, size)
327 #define TPM2B_SENSITIVE_DATA_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_SENSITIVE_DATA, buffer, size)
328 #define TPM2B_BUF_SIZE_STRUCT_MAKE(buf, size, struct_type, buffer_field, size_field) \
329 _TPM2B_BUF_SIZE_STRUCT_MAKE(buf, size, UNIQ, struct_type, buffer_field, size_field)
330 #define _TPM2B_BUF_SIZE_STRUCT_MAKE(buf, size, uniq, struct_type, buffer_field, size_field) \
332 typeof(buf) UNIQ_T(BUF, uniq) = (buf); \
333 typeof(size) UNIQ_T(SIZE, uniq) = (size); \
334 struct_type UNIQ_T(STRUCT, uniq) = { .size_field = UNIQ_T(SIZE, uniq), }; \
335 assert(sizeof(UNIQ_T(STRUCT, uniq).buffer_field) >= (size_t) UNIQ_T(SIZE, uniq)); \
336 if (UNIQ_T(BUF, uniq)) \
337 memcpy_safe(UNIQ_T(STRUCT, uniq).buffer_field, UNIQ_T(BUF, uniq), UNIQ_T(SIZE, uniq)); \
338 UNIQ_T(STRUCT, uniq); \
341 /* Check if the size will fit in the TPM2B struct buffer. Returns 0 if the size will fit, otherwise this logs
342 * a debug message and returns < 0. */
343 #define TPM2B_AUTH_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_AUTH, buffer)
344 #define TPM2B_DATA_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_DATA, buffer)
345 #define TPM2B_DIGEST_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_DIGEST, buffer)
346 #define TPM2B_ECC_PARAMETER_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_ECC_PARAMETER, buffer)
347 #define TPM2B_ENCRYPTED_SECRET_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_ENCRYPTED_SECRET, buffer)
348 #define TPM2B_MAX_BUFFER_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_MAX_BUFFER, buffer)
349 #define TPM2B_NAME_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_NAME, name)
350 #define TPM2B_PRIVATE_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_PRIVATE, buffer)
351 #define TPM2B_PRIVATE_KEY_RSA_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_PRIVATE_KEY_RSA, buffer)
352 #define TPM2B_PUBLIC_KEY_RSA_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_PUBLIC_KEY_RSA, buffer)
353 #define TPM2B_SENSITIVE_DATA_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_SENSITIVE_DATA, buffer)
354 #define TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(size, struct_type, buffer_field) \
355 _TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(size, UNIQ, struct_type, buffer_field)
356 #define _TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(size, uniq, struct_type, buffer_field) \
358 size_t UNIQ_T(SIZE, uniq) = (size_t) (size); \
359 size_t UNIQ_T(BUFSIZE, uniq) = sizeof_field(struct_type, buffer_field); \
360 UNIQ_T(BUFSIZE, uniq) < UNIQ_T(SIZE, uniq) ? \
361 log_debug_errno(SYNTHETIC_ERRNO(EINVAL), \
362 "Size %zu larger than " #struct_type " buffer size %zu.", \
363 UNIQ_T(SIZE, uniq), UNIQ_T(BUFSIZE, uniq)) : \
367 #else /* HAVE_TPM2 */
368 typedef struct {} Tpm2Context
;
369 typedef struct {} Tpm2Handle
;
370 typedef struct {} Tpm2PCRValue
;
372 #define TPM2_PCR_VALUE_MAKE(i, h, v) (Tpm2PCRValue) {}
374 static inline int tpm2_pcrlock_search_file(const char *path
, FILE **ret_file
, char **ret_path
) {
378 #endif /* HAVE_TPM2 */
380 int tpm2_list_devices(void);
381 int tpm2_find_device_auto(char **ret
);
383 int tpm2_make_pcr_json_array(uint32_t pcr_mask
, JsonVariant
**ret
);
384 int tpm2_parse_pcr_json_array(JsonVariant
*v
, uint32_t *ret
);
386 int tpm2_make_luks2_json(int keyslot
, uint32_t hash_pcr_mask
, uint16_t pcr_bank
, const struct iovec
*pubkey
, uint32_t pubkey_pcr_mask
, uint16_t primary_alg
, const struct iovec
*blob
, const struct iovec
*policy_hash
, const struct iovec
*salt
, const struct iovec
*srk
, TPM2Flags flags
, JsonVariant
**ret
);
387 int tpm2_parse_luks2_json(JsonVariant
*v
, int *ret_keyslot
, uint32_t *ret_hash_pcr_mask
, uint16_t *ret_pcr_bank
, struct iovec
*ret_pubkey
, uint32_t *ret_pubkey_pcr_mask
, uint16_t *ret_primary_alg
, struct iovec
*ret_blob
, struct iovec
*ret_policy_hash
, struct iovec
*ret_salt
, struct iovec
*ret_srk
, TPM2Flags
*ret_flags
);
389 /* Default to PCR 7 only */
390 #define TPM2_PCR_INDEX_DEFAULT UINT32_C(7)
391 #define TPM2_PCR_MASK_DEFAULT INDEX_TO_MASK(uint32_t, TPM2_PCR_INDEX_DEFAULT)
393 /* We want the helpers below to work also if TPM2 libs are not available, hence define these four defines if
394 * they are missing. */
395 #ifndef TPM2_ALG_SHA1
396 #define TPM2_ALG_SHA1 0x4
399 #ifndef TPM2_ALG_SHA256
400 #define TPM2_ALG_SHA256 0xB
403 #ifndef TPM2_ALG_SHA384
404 #define TPM2_ALG_SHA384 0xC
407 #ifndef TPM2_ALG_SHA512
408 #define TPM2_ALG_SHA512 0xD
412 #define TPM2_ALG_ECC 0x23
416 #define TPM2_ALG_RSA 0x1
419 int tpm2_hash_alg_to_size(uint16_t alg
);
421 const char *tpm2_hash_alg_to_string(uint16_t alg
) _const_
;
422 int tpm2_hash_alg_from_string(const char *alg
) _pure_
;
424 const char *tpm2_asym_alg_to_string(uint16_t alg
) _const_
;
425 int tpm2_asym_alg_from_string(const char *alg
) _pure_
;
427 const char *tpm2_sym_alg_to_string(uint16_t alg
) _const_
;
428 int tpm2_sym_alg_from_string(const char *alg
) _pure_
;
430 const char *tpm2_sym_mode_to_string(uint16_t mode
) _const_
;
431 int tpm2_sym_mode_from_string(const char *mode
) _pure_
;
433 char *tpm2_pcr_mask_to_string(uint32_t mask
);
435 extern const uint16_t tpm2_hash_algorithms
[];
438 uint32_t search_pcr_mask
;
440 const char *signature_path
;
441 const char *pcrlock_path
;
442 } systemd_tpm2_plugin_params
;
444 typedef enum Tpm2Support
{
445 /* NOTE! The systemd-creds tool returns these flags 1:1 as exit status. Hence these flags are pretty
446 * much ABI! Hence, be extra careful when changing/extending these definitions. */
447 TPM2_SUPPORT_NONE
= 0, /* no support */
448 TPM2_SUPPORT_FIRMWARE
= 1 << 0, /* firmware reports TPM2 was used */
449 TPM2_SUPPORT_DRIVER
= 1 << 1, /* the kernel has a driver loaded for it */
450 TPM2_SUPPORT_SYSTEM
= 1 << 2, /* we support it ourselves */
451 TPM2_SUPPORT_SUBSYSTEM
= 1 << 3, /* the kernel has the tpm subsystem enabled */
452 TPM2_SUPPORT_LIBRARIES
= 1 << 4, /* we can dlopen the tpm2 libraries */
453 TPM2_SUPPORT_FULL
= TPM2_SUPPORT_FIRMWARE
|TPM2_SUPPORT_DRIVER
|TPM2_SUPPORT_SYSTEM
|TPM2_SUPPORT_SUBSYSTEM
|TPM2_SUPPORT_LIBRARIES
,
456 Tpm2Support
tpm2_support(void);
458 int tpm2_parse_pcr_argument(const char *arg
, Tpm2PCRValue
**ret_pcr_values
, size_t *ret_n_pcr_values
);
459 int tpm2_parse_pcr_argument_append(const char *arg
, Tpm2PCRValue
**ret_pcr_values
, size_t *ret_n_pcr_values
);
460 int tpm2_parse_pcr_argument_to_mask(const char *arg
, uint32_t *mask
);
462 int tpm2_load_pcr_signature(const char *path
, JsonVariant
**ret
);
463 int tpm2_load_pcr_public_key(const char *path
, void **ret_pubkey
, size_t *ret_pubkey_size
);
465 int tpm2_util_pbkdf2_hmac_sha256(const void *pass
,
469 uint8_t res
[static SHA256_DIGEST_SIZE
]);
472 /* Additional defines for the PCR index naming enum from "fundamental/tpm2-pcr.h" */
473 _TPM2_PCR_INDEX_MAX_DEFINED
= TPM2_PCRS_MAX
,
474 _TPM2_PCR_INDEX_INVALID
= -EINVAL
,
477 int tpm2_pcr_index_from_string(const char *s
) _pure_
;
478 const char *tpm2_pcr_index_to_string(int pcr
) _const_
;