]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/tpm2-util.h
tpm2: wrap (7) in UINT32_C()
[thirdparty/systemd.git] / src / shared / tpm2-util.h
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3
4 #include <stdbool.h>
5
6 #include "bitfield.h"
7 #include "io-util.h"
8 #include "json.h"
9 #include "macro.h"
10 #include "openssl-util.h"
11 #include "sha256.h"
12
13 typedef enum TPM2Flags {
14 TPM2_FLAGS_USE_PIN = 1 << 0,
15 } TPM2Flags;
16
17 /* As per https://trustedcomputinggroup.org/wp-content/uploads/TCG_PCClient_PFP_r1p05_v23_pub.pdf a
18 * TPM2 on a Client PC must have at least 24 PCRs. This hardcodes our expectation of 24. */
19 #define TPM2_PCRS_MAX 24U
20 #define TPM2_PCRS_MASK ((UINT32_C(1) << TPM2_PCRS_MAX) - 1)
21 static inline bool TPM2_PCR_INDEX_VALID(unsigned pcr) {
22 return pcr < TPM2_PCRS_MAX;
23 }
24 static inline bool TPM2_PCR_MASK_VALID(uint32_t pcr_mask) {
25 return pcr_mask <= TPM2_PCRS_MASK;
26 }
27
28 #define FOREACH_PCR_IN_MASK(pcr, mask) BIT_FOREACH(pcr, mask)
29
30 #if HAVE_TPM2
31
32 #include <tss2/tss2_esys.h>
33 #include <tss2/tss2_mu.h>
34 #include <tss2/tss2_rc.h>
35
36 int dlopen_tpm2(void);
37
38 typedef struct {
39 unsigned n_ref;
40
41 void *tcti_dl;
42 TSS2_TCTI_CONTEXT *tcti_context;
43 ESYS_CONTEXT *esys_context;
44
45 /* Some selected cached capabilities of the TPM */
46 TPMS_ALG_PROPERTY *capability_algorithms;
47 size_t n_capability_algorithms;
48 TPMA_CC *capability_commands;
49 size_t n_capability_commands;
50 TPML_PCR_SELECTION capability_pcrs;
51 } Tpm2Context;
52
53 int tpm2_context_new(const char *device, Tpm2Context **ret_context);
54 Tpm2Context *tpm2_context_ref(Tpm2Context *context);
55 Tpm2Context *tpm2_context_unref(Tpm2Context *context);
56 DEFINE_TRIVIAL_CLEANUP_FUNC(Tpm2Context*, tpm2_context_unref);
57
58 typedef struct {
59 Tpm2Context *tpm2_context;
60 ESYS_TR esys_handle;
61
62 bool flush;
63 } Tpm2Handle;
64
65 #define _tpm2_handle(c, h) { .tpm2_context = (c), .esys_handle = (h), }
66 static const Tpm2Handle TPM2_HANDLE_NONE = _tpm2_handle(NULL, ESYS_TR_NONE);
67
68 int tpm2_handle_new(Tpm2Context *context, Tpm2Handle **ret_handle);
69 Tpm2Handle *tpm2_handle_free(Tpm2Handle *handle);
70 DEFINE_TRIVIAL_CLEANUP_FUNC(Tpm2Handle*, tpm2_handle_free);
71
72 typedef struct {
73 unsigned index;
74 TPMI_ALG_HASH hash;
75 TPM2B_DIGEST value;
76 } Tpm2PCRValue;
77
78 #define TPM2_PCR_VALUE_MAKE(i, h, v) \
79 (Tpm2PCRValue) { \
80 .index = (i), \
81 .hash = (h), \
82 .value = ((TPM2B_DIGEST) v), \
83 }
84
85 bool tpm2_pcr_value_valid(const Tpm2PCRValue *pcr_value);
86 bool tpm2_pcr_values_has_any_values(const Tpm2PCRValue *pcr_values, size_t n_pcr_values);
87 bool tpm2_pcr_values_has_all_values(const Tpm2PCRValue *pcr_values, size_t n_pcr_values);
88 int tpm2_pcr_value_from_string(const char *arg, Tpm2PCRValue *ret_pcr_value);
89 char *tpm2_pcr_value_to_string(const Tpm2PCRValue *pcr_value);
90
91 bool tpm2_pcr_values_valid(const Tpm2PCRValue *pcr_values, size_t n_pcr_values);
92 void tpm2_sort_pcr_values(Tpm2PCRValue *pcr_values, size_t n_pcr_values);
93 int tpm2_pcr_values_from_mask(uint32_t mask, TPMI_ALG_HASH hash, Tpm2PCRValue **ret_pcr_values, size_t *ret_n_pcr_values);
94 int tpm2_pcr_values_to_mask(const Tpm2PCRValue *pcr_values, size_t n_pcr_values, TPMI_ALG_HASH hash, uint32_t *ret_mask);
95 int tpm2_pcr_values_from_string(const char *arg, Tpm2PCRValue **ret_pcr_values, size_t *ret_n_pcr_values);
96 char *tpm2_pcr_values_to_string(const Tpm2PCRValue *pcr_values, size_t n_pcr_values);
97 int tpm2_pcr_values_hash_count(const Tpm2PCRValue *pcr_values, size_t n_pcr_values, size_t *ret_count);
98 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);
99
100 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);
101 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);
102 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);
103
104 bool tpm2_supports_alg(Tpm2Context *c, TPM2_ALG_ID alg);
105 bool tpm2_supports_command(Tpm2Context *c, TPM2_CC command);
106
107 bool tpm2_test_parms(Tpm2Context *c, TPMI_ALG_PUBLIC alg, const TPMU_PUBLIC_PARMS *parms);
108
109 int tpm2_get_good_pcr_banks(Tpm2Context *c, uint32_t pcr_mask, TPMI_ALG_HASH **ret_banks);
110 int tpm2_get_good_pcr_banks_strv(Tpm2Context *c, uint32_t pcr_mask, char ***ret);
111 int tpm2_get_best_pcr_bank(Tpm2Context *c, uint32_t pcr_mask, TPMI_ALG_HASH *ret);
112
113 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);
114
115 uint32_t tpm2_tpms_pcr_selection_to_mask(const TPMS_PCR_SELECTION *s);
116 void tpm2_tpms_pcr_selection_from_mask(uint32_t mask, TPMI_ALG_HASH hash, TPMS_PCR_SELECTION *ret);
117 bool tpm2_tpms_pcr_selection_has_mask(const TPMS_PCR_SELECTION *s, uint32_t mask);
118 void tpm2_tpms_pcr_selection_add_mask(TPMS_PCR_SELECTION *s, uint32_t mask);
119 void tpm2_tpms_pcr_selection_sub_mask(TPMS_PCR_SELECTION *s, uint32_t mask);
120 void tpm2_tpms_pcr_selection_add(TPMS_PCR_SELECTION *a, const TPMS_PCR_SELECTION *b);
121 void tpm2_tpms_pcr_selection_sub(TPMS_PCR_SELECTION *a, const TPMS_PCR_SELECTION *b);
122 void tpm2_tpms_pcr_selection_move(TPMS_PCR_SELECTION *a, TPMS_PCR_SELECTION *b);
123 char *tpm2_tpms_pcr_selection_to_string(const TPMS_PCR_SELECTION *s);
124 size_t tpm2_tpms_pcr_selection_weight(const TPMS_PCR_SELECTION *s);
125 #define tpm2_tpms_pcr_selection_is_empty(s) (tpm2_tpms_pcr_selection_weight(s) == 0)
126
127 uint32_t tpm2_tpml_pcr_selection_to_mask(const TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash);
128 void tpm2_tpml_pcr_selection_from_mask(uint32_t mask, TPMI_ALG_HASH hash, TPML_PCR_SELECTION *ret);
129 bool tpm2_tpml_pcr_selection_has_mask(const TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash, uint32_t mask);
130 void tpm2_tpml_pcr_selection_add_mask(TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash, uint32_t mask);
131 void tpm2_tpml_pcr_selection_sub_mask(TPML_PCR_SELECTION *l, TPMI_ALG_HASH hash, uint32_t mask);
132 void tpm2_tpml_pcr_selection_add_tpms_pcr_selection(TPML_PCR_SELECTION *l, const TPMS_PCR_SELECTION *s);
133 void tpm2_tpml_pcr_selection_sub_tpms_pcr_selection(TPML_PCR_SELECTION *l, const TPMS_PCR_SELECTION *s);
134 void tpm2_tpml_pcr_selection_add(TPML_PCR_SELECTION *a, const TPML_PCR_SELECTION *b);
135 void tpm2_tpml_pcr_selection_sub(TPML_PCR_SELECTION *a, const TPML_PCR_SELECTION *b);
136 char *tpm2_tpml_pcr_selection_to_string(const TPML_PCR_SELECTION *l);
137 size_t tpm2_tpml_pcr_selection_weight(const TPML_PCR_SELECTION *l);
138 #define tpm2_tpml_pcr_selection_is_empty(l) (tpm2_tpml_pcr_selection_weight(l) == 0)
139
140 int tpm2_digest_many(TPMI_ALG_HASH alg, TPM2B_DIGEST *digest, const struct iovec data[], size_t count, bool extend);
141 static inline int tpm2_digest_buffer(TPMI_ALG_HASH alg, TPM2B_DIGEST *digest, const void *data, size_t len, bool extend) {
142 return tpm2_digest_many(alg, digest, &IOVEC_MAKE((void*) data, len), 1, extend);
143 }
144 int tpm2_digest_many_digests(TPMI_ALG_HASH alg, TPM2B_DIGEST *digest, const TPM2B_DIGEST data[], size_t count, bool extend);
145 static inline int tpm2_digest_rehash(TPMI_ALG_HASH alg, TPM2B_DIGEST *digest) {
146 return tpm2_digest_many(alg, digest, NULL, 0, true);
147 }
148 static inline int tpm2_digest_init(TPMI_ALG_HASH alg, TPM2B_DIGEST *digest) {
149 return tpm2_digest_many(alg, digest, NULL, 0, false);
150 }
151
152 void tpm2_log_debug_tpml_pcr_selection(const TPML_PCR_SELECTION *l, const char *msg);
153 void tpm2_log_debug_pcr_value(const Tpm2PCRValue *pcr_value, const char *msg);
154 void tpm2_log_debug_buffer(const void *buffer, size_t size, const char *msg);
155 void tpm2_log_debug_digest(const TPM2B_DIGEST *digest, const char *msg);
156 void tpm2_log_debug_name(const TPM2B_NAME *name, const char *msg);
157
158 int tpm2_pcr_read(Tpm2Context *c, const TPML_PCR_SELECTION *pcr_selection, Tpm2PCRValue **ret_pcr_values, size_t *ret_n_pcr_values);
159 int tpm2_pcr_read_missing_values(Tpm2Context *c, Tpm2PCRValue *pcr_values, size_t n_pcr_values);
160
161 int tpm2_calculate_name(const TPMT_PUBLIC *public, TPM2B_NAME *ret_name);
162 int tpm2_calculate_policy_auth_value(TPM2B_DIGEST *digest);
163 int tpm2_calculate_policy_authorize(const TPM2B_PUBLIC *public, const TPM2B_DIGEST *policy_ref, TPM2B_DIGEST *digest);
164 int tpm2_calculate_policy_pcr(const Tpm2PCRValue *pcr_values, size_t n_pcr_values, TPM2B_DIGEST *digest);
165 int tpm2_calculate_sealing_policy(const Tpm2PCRValue *pcr_values, size_t n_pcr_values, const TPM2B_PUBLIC *public, bool use_pin, TPM2B_DIGEST *digest);
166
167 int tpm2_seal(Tpm2Context *c, const TPM2B_DIGEST *policy, const char *pin, void **ret_secret, size_t *ret_secret_size, void **ret_blob, size_t *ret_blob_size, uint16_t *ret_primary_alg, void **ret_srk_buf, size_t *ret_srk_buf_size);
168 int tpm2_unseal(const char *device, uint32_t hash_pcr_mask, uint16_t pcr_bank, const void *pubkey, size_t pubkey_size, uint32_t pubkey_pcr_mask, JsonVariant *signature, const char *pin, uint16_t primary_alg, const void *blob, size_t blob_size, const void *policy_hash, size_t policy_hash_size, const void *srk_buf, size_t srk_buf_size, void **ret_secret, size_t *ret_secret_size);
169
170 #if HAVE_OPENSSL
171 int tpm2_tpm2b_public_to_openssl_pkey(const TPM2B_PUBLIC *public, EVP_PKEY **ret);
172 int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret);
173 #endif
174
175 int tpm2_tpm2b_public_from_pem(const void *pem, size_t pem_size, TPM2B_PUBLIC *ret);
176 int tpm2_tpm2b_public_to_fingerprint(const TPM2B_PUBLIC *public, void **ret_fingerprint, size_t *ret_fingerprint_size);
177
178 /* The tpm2-tss library has many structs that are simply a combination of an array (or object) and
179 * size. These macros allow easily initializing or assigning instances of such structs from an existing
180 * buffer/object and size, while also checking the size for safety with the struct buffer/object size. If the
181 * provided buffer/object is NULL, the resulting struct's buffer/object will be 0s. If the provided size is
182 * larger than the struct's buffer/object size, this results in assertion failure; to check the size, use one
183 * of the TPM2B_*_CHECK_SIZE() macros. */
184 #define TPM2B_AUTH_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_AUTH, buffer, size)
185 #define TPM2B_DATA_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_DATA, buffer, size)
186 #define TPM2B_DIGEST_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_DIGEST, buffer, size)
187 #define TPM2B_ECC_PARAMETER_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_ECC_PARAMETER, buffer, size)
188 #define TPM2B_ENCRYPTED_SECRET_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_ENCRYPTED_SECRET, secret, size)
189 #define TPM2B_MAX_BUFFER_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_MAX_BUFFER, buffer, size)
190 #define TPM2B_NAME_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_NAME, name, size)
191 #define TPM2B_PRIVATE_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_PRIVATE, buffer, size)
192 #define TPM2B_PRIVATE_KEY_RSA_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_PRIVATE_KEY_RSA, buffer, size)
193 #define TPM2B_PUBLIC_KEY_RSA_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_PUBLIC_KEY_RSA, buffer, size)
194 #define TPM2B_SENSITIVE_DATA_MAKE(b, s) TPM2B_BUF_SIZE_STRUCT_MAKE(b, s, TPM2B_SENSITIVE_DATA, buffer, size)
195 #define TPM2B_BUF_SIZE_STRUCT_MAKE(buf, size, struct_type, buffer_field, size_field) \
196 _TPM2B_BUF_SIZE_STRUCT_MAKE(buf, size, UNIQ, struct_type, buffer_field, size_field)
197 #define _TPM2B_BUF_SIZE_STRUCT_MAKE(buf, size, uniq, struct_type, buffer_field, size_field) \
198 ({ \
199 typeof(buf) UNIQ_T(BUF, uniq) = (buf); \
200 typeof(size) UNIQ_T(SIZE, uniq) = (size); \
201 struct_type UNIQ_T(STRUCT, uniq) = { .size_field = UNIQ_T(SIZE, uniq), }; \
202 assert(sizeof(UNIQ_T(STRUCT, uniq).buffer_field) >= (size_t) UNIQ_T(SIZE, uniq)); \
203 if (UNIQ_T(BUF, uniq)) \
204 memcpy_safe(UNIQ_T(STRUCT, uniq).buffer_field, UNIQ_T(BUF, uniq), UNIQ_T(SIZE, uniq)); \
205 UNIQ_T(STRUCT, uniq); \
206 })
207
208 /* Check if the size will fit in the TPM2B struct buffer. Returns 0 if the size will fit, otherwise this logs
209 * a debug message and returns < 0. */
210 #define TPM2B_AUTH_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_AUTH, buffer)
211 #define TPM2B_DATA_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_DATA, buffer)
212 #define TPM2B_DIGEST_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_DIGEST, buffer)
213 #define TPM2B_ECC_PARAMETER_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_ECC_PARAMETER, buffer)
214 #define TPM2B_ENCRYPTED_SECRET_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_ENCRYPTED_SECRET, buffer)
215 #define TPM2B_MAX_BUFFER_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_MAX_BUFFER, buffer)
216 #define TPM2B_NAME_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_NAME, name)
217 #define TPM2B_PRIVATE_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_PRIVATE, buffer)
218 #define TPM2B_PRIVATE_KEY_RSA_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_PRIVATE_KEY_RSA, buffer)
219 #define TPM2B_PUBLIC_KEY_RSA_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_PUBLIC_KEY_RSA, buffer)
220 #define TPM2B_SENSITIVE_DATA_CHECK_SIZE(s) TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(s, TPM2B_SENSITIVE_DATA, buffer)
221 #define TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(size, struct_type, buffer_field) \
222 _TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(size, UNIQ, struct_type, buffer_field)
223 #define _TPM2B_BUF_SIZE_STRUCT_CHECK_SIZE(size, uniq, struct_type, buffer_field) \
224 ({ \
225 size_t UNIQ_T(SIZE, uniq) = (size_t) (size); \
226 size_t UNIQ_T(BUFSIZE, uniq) = sizeof_field(struct_type, buffer_field); \
227 UNIQ_T(BUFSIZE, uniq) < UNIQ_T(SIZE, uniq) ? \
228 log_debug_errno(SYNTHETIC_ERRNO(EINVAL), \
229 "Size %zu larger than " #struct_type " buffer size %zu.", \
230 UNIQ_T(SIZE, uniq), UNIQ_T(BUFSIZE, uniq)) : \
231 0; \
232 })
233
234 #else /* HAVE_TPM2 */
235 typedef struct {} Tpm2Context;
236 typedef struct {} Tpm2Handle;
237 typedef struct {} Tpm2PCRValue;
238
239 #define TPM2_PCR_VALUE_MAKE(i, h, v) (Tpm2PCRValue) {}
240 #endif /* HAVE_TPM2 */
241
242 int tpm2_list_devices(void);
243 int tpm2_find_device_auto(int log_level, char **ret);
244
245 int tpm2_make_pcr_json_array(uint32_t pcr_mask, JsonVariant **ret);
246 int tpm2_parse_pcr_json_array(JsonVariant *v, uint32_t *ret);
247
248 int tpm2_make_luks2_json(int keyslot, uint32_t hash_pcr_mask, uint16_t pcr_bank, const void *pubkey, size_t pubkey_size, uint32_t pubkey_pcr_mask, uint16_t primary_alg, const void *blob, size_t blob_size, const void *policy_hash, size_t policy_hash_size, const void *salt, size_t salt_size, const void *srk_buf, size_t srk_buf_size, TPM2Flags flags, JsonVariant **ret);
249 int tpm2_parse_luks2_json(JsonVariant *v, int *ret_keyslot, uint32_t *ret_hash_pcr_mask, uint16_t *ret_pcr_bank, void **ret_pubkey, size_t *ret_pubkey_size, uint32_t *ret_pubkey_pcr_mask, uint16_t *ret_primary_alg, void **ret_blob, size_t *ret_blob_size, void **ret_policy_hash, size_t *ret_policy_hash_size, void **ret_salt, size_t *ret_salt_size, void **ret_srk_buf, size_t *ret_srk_buf_size, TPM2Flags *ret_flags);
250
251 /* Default to PCR 7 only */
252 #define TPM2_PCR_INDEX_DEFAULT UINT32_C(7)
253 #define TPM2_PCR_MASK_DEFAULT INDEX_TO_MASK(uint32_t, TPM2_PCR_INDEX_DEFAULT)
254
255 /* We want the helpers below to work also if TPM2 libs are not available, hence define these four defines if
256 * they are missing. */
257 #ifndef TPM2_ALG_SHA1
258 #define TPM2_ALG_SHA1 0x4
259 #endif
260
261 #ifndef TPM2_ALG_SHA256
262 #define TPM2_ALG_SHA256 0xB
263 #endif
264
265 #ifndef TPM2_ALG_SHA384
266 #define TPM2_ALG_SHA384 0xC
267 #endif
268
269 #ifndef TPM2_ALG_SHA512
270 #define TPM2_ALG_SHA512 0xD
271 #endif
272
273 #ifndef TPM2_ALG_ECC
274 #define TPM2_ALG_ECC 0x23
275 #endif
276
277 #ifndef TPM2_ALG_RSA
278 #define TPM2_ALG_RSA 0x1
279 #endif
280
281 int tpm2_hash_alg_to_size(uint16_t alg);
282
283 const char *tpm2_hash_alg_to_string(uint16_t alg) _const_;
284 int tpm2_hash_alg_from_string(const char *alg) _pure_;
285
286 const char *tpm2_asym_alg_to_string(uint16_t alg) _const_;
287 int tpm2_asym_alg_from_string(const char *alg) _pure_;
288
289 char *tpm2_pcr_mask_to_string(uint32_t mask);
290
291 typedef struct {
292 uint32_t search_pcr_mask;
293 const char *device;
294 const char *signature_path;
295 } systemd_tpm2_plugin_params;
296
297 typedef enum Tpm2Support {
298 /* NOTE! The systemd-creds tool returns these flags 1:1 as exit status. Hence these flags are pretty
299 * much ABI! Hence, be extra careful when changing/extending these definitions. */
300 TPM2_SUPPORT_NONE = 0, /* no support */
301 TPM2_SUPPORT_FIRMWARE = 1 << 0, /* firmware reports TPM2 was used */
302 TPM2_SUPPORT_DRIVER = 1 << 1, /* the kernel has a driver loaded for it */
303 TPM2_SUPPORT_SYSTEM = 1 << 2, /* we support it ourselves */
304 TPM2_SUPPORT_SUBSYSTEM = 1 << 3, /* the kernel has the tpm subsystem enabled */
305 TPM2_SUPPORT_LIBRARIES = 1 << 4, /* we can dlopen the tpm2 libraries */
306 TPM2_SUPPORT_FULL = TPM2_SUPPORT_FIRMWARE|TPM2_SUPPORT_DRIVER|TPM2_SUPPORT_SYSTEM|TPM2_SUPPORT_SUBSYSTEM|TPM2_SUPPORT_LIBRARIES,
307 } Tpm2Support;
308
309 enum {
310 /* The following names for PCRs 0…7 are based on the names in the "TCG PC Client Specific Platform
311 * Firmware Profile Specification"
312 * (https://trustedcomputinggroup.org/resource/pc-client-specific-platform-firmware-profile-specification/) */
313 PCR_PLATFORM_CODE = 0,
314 PCR_PLATFORM_CONFIG = 1,
315 PCR_EXTERNAL_CODE = 2,
316 PCR_EXTERNAL_CONFIG = 3,
317 PCR_BOOT_LOADER_CODE = 4,
318 PCR_BOOT_LOADER_CONFIG = 5,
319 PCR_HOST_PLATFORM = 6,
320 PCR_SECURE_BOOT_POLICY = 7,
321 /* The following names for PCRs 9…15 are based on the "Linux TPM PCR Registry"
322 (https://uapi-group.org/specifications/specs/linux_tpm_pcr_registry/) */
323 PCR_KERNEL_INITRD = 9,
324 PCR_IMA = 10,
325 PCR_KERNEL_BOOT = 11,
326 PCR_KERNEL_CONFIG = 12,
327 PCR_SYSEXTS = 13,
328 PCR_SHIM_POLICY = 14,
329 PCR_SYSTEM_IDENTITY = 15,
330 /* As per "TCG PC Client Specific Platform Firmware Profile Specification" again, see above */
331 PCR_DEBUG = 16,
332 PCR_APPLICATION_SUPPORT = 23,
333 _PCR_INDEX_MAX_DEFINED = TPM2_PCRS_MAX,
334 _PCR_INDEX_INVALID = -EINVAL,
335 };
336
337 Tpm2Support tpm2_support(void);
338
339 int tpm2_parse_pcr_argument(const char *arg, Tpm2PCRValue **ret_pcr_values, size_t *ret_n_pcr_values);
340 int tpm2_parse_pcr_argument_append(const char *arg, Tpm2PCRValue **ret_pcr_values, size_t *ret_n_pcr_values);
341 int tpm2_parse_pcr_argument_to_mask(const char *arg, uint32_t *mask);
342
343 int tpm2_load_pcr_signature(const char *path, JsonVariant **ret);
344 int tpm2_load_pcr_public_key(const char *path, void **ret_pubkey, size_t *ret_pubkey_size);
345
346 int tpm2_util_pbkdf2_hmac_sha256(const void *pass,
347 size_t passlen,
348 const void *salt,
349 size_t saltlen,
350 uint8_t res[static SHA256_DIGEST_SIZE]);
351
352 int pcr_index_from_string(const char *s) _pure_;
353 const char *pcr_index_to_string(int pcr) _const_;