]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c
repart: Remove outdated comment
[thirdparty/systemd.git] / src / cryptsetup / cryptsetup-tokens / luks2-tpm2.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "alloc-util.h"
4 #include "ask-password-api.h"
5 #include "env-util.h"
6 #include "hexdecoct.h"
7 #include "json.h"
8 #include "log.h"
9 #include "luks2-tpm2.h"
10 #include "parse-util.h"
11 #include "random-util.h"
12 #include "sha256.h"
13 #include "strv.h"
14 #include "tpm2-util.h"
15
16 int acquire_luks2_key(
17 const char *device,
18 uint32_t hash_pcr_mask,
19 uint16_t pcr_bank,
20 const void *pubkey,
21 size_t pubkey_size,
22 uint32_t pubkey_pcr_mask,
23 const char *signature_path,
24 const char *pin,
25 uint16_t primary_alg,
26 const void *key_data,
27 size_t key_data_size,
28 const void *policy_hash,
29 size_t policy_hash_size,
30 const void *salt,
31 size_t salt_size,
32 TPM2Flags flags,
33 void **ret_decrypted_key,
34 size_t *ret_decrypted_key_size) {
35
36 _cleanup_(json_variant_unrefp) JsonVariant *signature_json = NULL;
37 _cleanup_free_ char *auto_device = NULL;
38 _cleanup_(erase_and_freep) char *b64_salted_pin = NULL;
39 int r;
40
41 assert(ret_decrypted_key);
42 assert(ret_decrypted_key_size);
43
44 if (!device) {
45 r = tpm2_find_device_auto(LOG_DEBUG, &auto_device);
46 if (r == -ENODEV)
47 return -EAGAIN; /* Tell the caller to wait for a TPM2 device to show up */
48 if (r < 0)
49 return r;
50
51 device = auto_device;
52 }
53
54 if ((flags & TPM2_FLAGS_USE_PIN) && !pin)
55 return -ENOANO;
56
57 /* If we're using a PIN, and the luks header has a salt, it better have a pin too */
58 if ((flags & TPM2_FLAGS_USE_PIN) && salt && !pin)
59 return -ENOANO;
60
61 if (pin) {
62 uint8_t salted_pin[SHA256_DIGEST_SIZE] = {};
63 CLEANUP_ERASE(salted_pin);
64 r = tpm2_util_pbkdf2_hmac_sha256(pin, strlen(pin), salt, salt_size, salted_pin);
65 if (r < 0)
66 return log_error_errno(r, "Failed to perform PBKDF2: %m");
67
68 r = base64mem(salted_pin, sizeof(salted_pin), &b64_salted_pin);
69 if (r < 0)
70 return log_error_errno(r, "Failed to base64 encode salted pin: %m");
71 pin = b64_salted_pin;
72 }
73
74 if (pubkey_pcr_mask != 0) {
75 r = tpm2_load_pcr_signature(signature_path, &signature_json);
76 if (r < 0)
77 return r;
78 }
79
80 return tpm2_unseal(
81 device,
82 hash_pcr_mask,
83 pcr_bank,
84 pubkey, pubkey_size,
85 pubkey_pcr_mask,
86 signature_json,
87 pin,
88 primary_alg,
89 key_data, key_data_size,
90 policy_hash, policy_hash_size,
91 ret_decrypted_key, ret_decrypted_key_size);
92 }