1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "alloc-util.h"
4 #include "ask-password-api.h"
9 #include "luks2-tpm2.h"
10 #include "parse-util.h"
11 #include "random-util.h"
14 #include "tpm2-util.h"
16 int acquire_luks2_key(
18 uint32_t hash_pcr_mask
,
20 const struct iovec
*pubkey
,
21 uint32_t pubkey_pcr_mask
,
22 const char *signature_path
,
24 const char *pcrlock_path
,
26 const struct iovec
*blob
,
27 const struct iovec
*policy_hash
,
28 const struct iovec
*salt
,
29 const struct iovec
*srk
,
31 struct iovec
*ret_decrypted_key
) {
33 _cleanup_(json_variant_unrefp
) JsonVariant
*signature_json
= NULL
;
34 _cleanup_free_
char *auto_device
= NULL
;
35 _cleanup_(erase_and_freep
) char *b64_salted_pin
= NULL
;
38 assert(iovec_is_valid(salt
));
39 assert(ret_decrypted_key
);
42 r
= tpm2_find_device_auto(&auto_device
);
44 return -EAGAIN
; /* Tell the caller to wait for a TPM2 device to show up */
46 return log_error_errno(r
, "Could not find TPM2 device: %m");
51 if ((flags
& TPM2_FLAGS_USE_PIN
) && !pin
)
54 if (pin
&& iovec_is_set(salt
)) {
55 uint8_t salted_pin
[SHA256_DIGEST_SIZE
] = {};
56 CLEANUP_ERASE(salted_pin
);
57 r
= tpm2_util_pbkdf2_hmac_sha256(pin
, strlen(pin
), salt
->iov_base
, salt
->iov_len
, salted_pin
);
59 return log_error_errno(r
, "Failed to perform PBKDF2: %m");
61 r
= base64mem(salted_pin
, sizeof(salted_pin
), &b64_salted_pin
);
63 return log_error_errno(r
, "Failed to base64 encode salted pin: %m");
67 if (pubkey_pcr_mask
!= 0) {
68 r
= tpm2_load_pcr_signature(signature_path
, &signature_json
);
70 return log_error_errno(r
, "Failed to load PCR signature: %m");
73 _cleanup_(tpm2_pcrlock_policy_done
) Tpm2PCRLockPolicy pcrlock_policy
= {};
74 if (FLAGS_SET(flags
, TPM2_FLAGS_USE_PCRLOCK
)) {
75 r
= tpm2_pcrlock_policy_load(pcrlock_path
, &pcrlock_policy
);
80 _cleanup_(tpm2_context_unrefp
) Tpm2Context
*tpm2_context
= NULL
;
81 r
= tpm2_context_new(device
, &tpm2_context
);
83 return log_error_errno(r
, "Failed to create TPM2 context: %m");
85 r
= tpm2_unseal(tpm2_context
,
92 FLAGS_SET(flags
, TPM2_FLAGS_USE_PCRLOCK
) ? &pcrlock_policy
: NULL
,
99 return log_error_errno(r
, "Failed to unseal secret using TPM2: %m");