Introduce 'fixate-volume-key' option to repart/cryptsetup to pin the exact LUKS volume key hash (#40343)
Add an option to generate the expected volume key hash for LUKS volumes by systemd-repart and put it to crypttab, make systemd-cryptsetup check it upon attaching. The format of the hash matches what's currently being measured to TPM2 PCR with tpm2-measure-pcr=. Closes #40123
This commit is contained in:
@@ -7,6 +7,9 @@
|
||||
#include "alloc-util.h"
|
||||
#include "cryptsetup-util.h"
|
||||
#include "dlfcn-util.h"
|
||||
#include "escape.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "hmac.h"
|
||||
#include "log.h"
|
||||
#include "parse-util.h"
|
||||
#include "string-util.h"
|
||||
@@ -198,6 +201,64 @@ int cryptsetup_add_token_json(struct crypt_device *cd, sd_json_variant *v) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cryptsetup_get_volume_key_prefix(
|
||||
struct crypt_device *cd,
|
||||
const char *volume_name,
|
||||
char **ret) {
|
||||
|
||||
_cleanup_free_ char *volume = NULL;
|
||||
const char *uuid;
|
||||
char *s;
|
||||
|
||||
uuid = sym_crypt_get_uuid(cd);
|
||||
if (!uuid)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to get LUKS UUID.");
|
||||
|
||||
if (volume_name)
|
||||
/* avoid ambiguity around ":" once we join things below */
|
||||
volume = xescape(volume_name, ":");
|
||||
else
|
||||
volume = strjoin("luks-", uuid);
|
||||
if (!volume)
|
||||
return log_oom_debug();
|
||||
|
||||
s = strjoin("cryptsetup:", volume, ":", uuid);
|
||||
if (!s)
|
||||
return log_oom_debug();
|
||||
|
||||
*ret = s;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The hash must match what measure_volume_key() extends to the SHA256 bank of the TPM2. */
|
||||
int cryptsetup_get_volume_key_id(
|
||||
struct crypt_device *cd,
|
||||
const char *volume_name,
|
||||
const void *volume_key,
|
||||
size_t volume_key_size,
|
||||
char **ret) {
|
||||
|
||||
_cleanup_free_ char *prefix = NULL;
|
||||
uint8_t digest[SHA256_DIGEST_SIZE];
|
||||
char *hex;
|
||||
int r;
|
||||
|
||||
r = cryptsetup_get_volume_key_prefix(cd, volume_name, &prefix);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get LUKS volume key prefix.");
|
||||
|
||||
hmac_sha256(volume_key, volume_key_size, prefix, strlen(prefix), digest);
|
||||
|
||||
hex = hexmem(digest, sizeof(digest));
|
||||
if (!hex)
|
||||
return log_oom_debug();
|
||||
|
||||
*ret = hex;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int dlopen_cryptsetup(void) {
|
||||
|
||||
@@ -66,6 +66,9 @@ int cryptsetup_set_minimal_pbkdf(struct crypt_device *cd);
|
||||
|
||||
int cryptsetup_get_token_as_json(struct crypt_device *cd, int idx, const char *verify_type, sd_json_variant **ret);
|
||||
int cryptsetup_add_token_json(struct crypt_device *cd, sd_json_variant *v);
|
||||
int cryptsetup_get_volume_key_prefix(struct crypt_device *cd, const char *volume_name, char **ret);
|
||||
int cryptsetup_get_volume_key_id(struct crypt_device *cd, const char *volume_name, const void *volume_key,
|
||||
size_t volume_key_size, char **ret);
|
||||
#endif
|
||||
|
||||
int dlopen_cryptsetup(void);
|
||||
|
||||
@@ -151,7 +151,7 @@ typedef enum Tpm2UserspaceEventType {
|
||||
|
||||
DECLARE_STRING_TABLE_LOOKUP(tpm2_userspace_event_type, Tpm2UserspaceEventType);
|
||||
|
||||
int tpm2_pcr_extend_bytes(Tpm2Context *c, char **banks, unsigned pcr_index, const struct iovec *data, const struct iovec *secret, Tpm2UserspaceEventType event, const char *description);
|
||||
int tpm2_pcr_extend_bytes(Tpm2Context *c, char **banks, unsigned pcr_index, const struct iovec *data, const struct iovec *secret, Tpm2UserspaceEventType event_type, const char *description);
|
||||
int tpm2_nvpcr_get_index(const char *name, uint32_t *ret);
|
||||
int tpm2_nvpcr_extend_bytes(Tpm2Context *c, const Tpm2Handle *session, const char *name, const struct iovec *data, const struct iovec *secret, Tpm2UserspaceEventType event_type, const char *description);
|
||||
int tpm2_nvpcr_acquire_anchor_secret(struct iovec *ret, bool sync_secondary);
|
||||
|
||||
Reference in New Issue
Block a user