Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable systemd-cryptenroll to support pcr literals on the command line. #28339

Closed
wants to merge 8 commits into from
1 change: 1 addition & 0 deletions src/basic/hashmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1357,6 +1357,7 @@ void* _hashmap_get(HashmapBase *h, const void *key) {

hash = bucket_hash(h, key);
idx = bucket_scan(h, hash, key);
fprintf(stderr, "HM: %p %s %u %u\n", h, (char*)key, hash, idx);
if (idx == IDX_NIL)
return NULL;

Expand Down
7 changes: 5 additions & 2 deletions src/creds/creds.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "escape.h"
#include "fileio.h"
#include "format-table.h"
#include "hashmap.h"
#include "hexdecoct.h"
#include "io-util.h"
#include "json.h"
Expand Down Expand Up @@ -45,6 +46,7 @@ static int arg_newline = -1;
static sd_id128_t arg_with_key = _CRED_AUTO;
static const char *arg_tpm2_device = NULL;
static uint32_t arg_tpm2_pcr_mask = UINT32_MAX;
static Hashmap *arg_tpm2_pcr_literal = NULL;
static char *arg_tpm2_public_key = NULL;
static uint32_t arg_tpm2_public_key_pcr_mask = UINT32_MAX;
static char *arg_tpm2_signature = NULL;
Expand Down Expand Up @@ -495,6 +497,7 @@ static int verb_encrypt(int argc, char **argv, void *userdata) {
arg_not_after,
arg_tpm2_device,
arg_tpm2_pcr_mask,
arg_tpm2_pcr_literal,
arg_tpm2_public_key,
arg_tpm2_public_key_pcr_mask,
plaintext, plaintext_size,
Expand Down Expand Up @@ -858,7 +861,7 @@ static int parse_argv(int argc, char *argv[]) {
break;

case ARG_TPM2_PCRS: /* For fixed hash PCR policies only */
r = tpm2_parse_pcr_argument(optarg, &arg_tpm2_pcr_mask);
r = tpm2_parse_pcr_argument(optarg, &arg_tpm2_pcr_mask, arg_tpm2_pcr_literal);
if (r < 0)
return r;

Expand All @@ -872,7 +875,7 @@ static int parse_argv(int argc, char *argv[]) {
break;

case ARG_TPM2_PUBLIC_KEY_PCRS: /* For public key PCR policies only */
r = tpm2_parse_pcr_argument(optarg, &arg_tpm2_public_key_pcr_mask);
r = tpm2_parse_pcr_argument(optarg, &arg_tpm2_public_key_pcr_mask, arg_tpm2_pcr_literal);
if (r < 0)
return r;

Expand Down
5 changes: 5 additions & 0 deletions src/cryptenroll/cryptenroll-tpm2.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ int enroll_tpm2(struct crypt_device *cd,
size_t volume_key_size,
const char *device,
uint32_t hash_pcr_mask,
Hashmap *hash_pcr_literal,
const char *pubkey_path,
uint32_t pubkey_pcr_mask,
const char *signature_path,
Expand Down Expand Up @@ -164,6 +165,7 @@ int enroll_tpm2(struct crypt_device *cd,
assert(volume_key);
assert(volume_key_size > 0);
assert(TPM2_PCR_MASK_VALID(hash_pcr_mask));
assert(TPM2_PCR_MASK_VALID(tpm2_mask_from_literals(hash_pcr_literal)));
assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask));

assert_se(node = crypt_get_device_name(cd));
Expand Down Expand Up @@ -208,6 +210,7 @@ int enroll_tpm2(struct crypt_device *cd,

r = tpm2_seal(device,
hash_pcr_mask,
hash_pcr_literal,
pubkey, pubkey_size,
pubkey_pcr_mask,
pin_str,
Expand Down Expand Up @@ -240,6 +243,7 @@ int enroll_tpm2(struct crypt_device *cd,
log_debug("Unsealing for verification...");
r = tpm2_unseal(device,
hash_pcr_mask,
hash_pcr_literal,
pcr_bank,
pubkey, pubkey_size,
pubkey_pcr_mask,
Expand Down Expand Up @@ -279,6 +283,7 @@ int enroll_tpm2(struct crypt_device *cd,
r = tpm2_make_luks2_json(
keyslot,
hash_pcr_mask,
hash_pcr_literal,
pcr_bank,
pubkey, pubkey_size,
pubkey_pcr_mask,
Expand Down
5 changes: 3 additions & 2 deletions src/cryptenroll/cryptenroll-tpm2.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
#include <sys/types.h>

#include "cryptsetup-util.h"
#include "sha256.h"
#include "log.h"

#if HAVE_TPM2
int enroll_tpm2(struct crypt_device *cd, const void *volume_key, size_t volume_key_size, const char *device, uint32_t hash_pcr_mask, const char *pubkey_path, uint32_t pubkey_pcr_mask, const char *signature_path, bool use_pin);
int enroll_tpm2(struct crypt_device *cd, const void *volume_key, size_t volume_key_size, const char *device, uint32_t hash_pcr_mask, Hashmap *hash_pcr_literal, const char *pubkey_path, uint32_t pubkey_pcr_mask, const char *signature_path, bool use_pin);
#else
static inline int enroll_tpm2(struct crypt_device *cd, const void *volume_key, size_t volume_key_size, const char *device, uint32_t hash_pcr_mask, const char *pubkey_path, uint32_t pubkey_pcr_mask, const char *signature_path, bool use_pin) {
static inline int enroll_tpm2(struct crypt_device *cd, const void *volume_key, size_t volume_key_size, const char *device, uint32_t hash_pcr_mask, Hashmap *hash_pcr_literal, const char *pubkey_path, uint32_t pubkey_pcr_mask, const char *signature_path, bool use_pin) {
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"TPM2 key enrollment not supported.");
}
Expand Down
10 changes: 7 additions & 3 deletions src/cryptenroll/cryptenroll.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "env-util.h"
#include "escape.h"
#include "fileio.h"
#include "hashmap.h"
#include "libfido2-util.h"
#include "main-func.h"
#include "memory-util.h"
Expand All @@ -38,6 +39,7 @@ static char *arg_pkcs11_token_uri = NULL;
static char *arg_fido2_device = NULL;
static char *arg_tpm2_device = NULL;
static uint32_t arg_tpm2_pcr_mask = UINT32_MAX;
static Hashmap *arg_tpm2_pcr_literal = NULL;
static bool arg_tpm2_pin = false;
static char *arg_tpm2_public_key = NULL;
static uint32_t arg_tpm2_public_key_pcr_mask = UINT32_MAX;
Expand Down Expand Up @@ -356,7 +358,7 @@ static int parse_argv(int argc, char *argv[]) {
}

case ARG_TPM2_PCRS:
r = tpm2_parse_pcr_argument(optarg, &arg_tpm2_pcr_mask);
r = tpm2_parse_pcr_argument(optarg, &arg_tpm2_pcr_mask, arg_tpm2_pcr_literal);
if (r < 0)
return r;

Expand All @@ -377,7 +379,7 @@ static int parse_argv(int argc, char *argv[]) {
break;

case ARG_TPM2_PUBLIC_KEY_PCRS:
r = tpm2_parse_pcr_argument(optarg, &arg_tpm2_public_key_pcr_mask);
r = tpm2_parse_pcr_argument(optarg, &arg_tpm2_public_key_pcr_mask, arg_tpm2_pcr_literal);
if (r < 0)
return r;

Expand Down Expand Up @@ -623,6 +625,8 @@ static int run(int argc, char *argv[]) {
log_parse_environment();
log_open();

//tpm2_create_literals_store(&arg_tpm2_pcr_literal);

r = parse_argv(argc, argv);
if (r <= 0)
return r;
Expand Down Expand Up @@ -655,7 +659,7 @@ static int run(int argc, char *argv[]) {
break;

case ENROLL_TPM2:
slot = enroll_tpm2(cd, vk, vks, arg_tpm2_device, arg_tpm2_pcr_mask, arg_tpm2_public_key, arg_tpm2_public_key_pcr_mask, arg_tpm2_signature, arg_tpm2_pin);
slot = enroll_tpm2(cd, vk, vks, arg_tpm2_device, arg_tpm2_pcr_mask, arg_tpm2_pcr_literal, arg_tpm2_public_key, arg_tpm2_public_key_pcr_mask, arg_tpm2_signature, arg_tpm2_pin);
break;

case _ENROLL_TYPE_INVALID:
Expand Down
2 changes: 2 additions & 0 deletions src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ int acquire_luks2_key(
_cleanup_free_ char *auto_device = NULL;
_cleanup_(erase_and_freep) char *b64_salted_pin = NULL;
int r;
Hashmap *hash_pcr_literal = NULL;

assert(salt || salt_size == 0);
assert(ret_decrypted_key);
Expand Down Expand Up @@ -83,6 +84,7 @@ int acquire_luks2_key(
return tpm2_unseal(
device,
hash_pcr_mask,
hash_pcr_literal,
pcr_bank,
pubkey, pubkey_size,
pubkey_pcr_mask,
Expand Down
3 changes: 3 additions & 0 deletions src/cryptsetup/cryptsetup-tpm2.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ int acquire_tpm2_key(
const char *volume_name,
const char *device,
uint32_t hash_pcr_mask,
Hashmap *hash_pcr_literal,
uint16_t pcr_bank,
const void *pubkey,
size_t pubkey_size,
Expand Down Expand Up @@ -133,6 +134,7 @@ int acquire_tpm2_key(
return tpm2_unseal(
device,
hash_pcr_mask,
hash_pcr_literal,
pcr_bank,
pubkey, pubkey_size,
pubkey_pcr_mask,
Expand Down Expand Up @@ -175,6 +177,7 @@ int acquire_tpm2_key(

r = tpm2_unseal(device,
hash_pcr_mask,
hash_pcr_literal,
pcr_bank,
pubkey, pubkey_size,
pubkey_pcr_mask,
Expand Down
2 changes: 2 additions & 0 deletions src/cryptsetup/cryptsetup-tpm2.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ int acquire_tpm2_key(
const char *volume_name,
const char *device,
uint32_t hash_pcr_mask,
Hashmap *hash_pcr_literal,
uint16_t pcr_bank,
const void *pubkey,
size_t pubkey_size,
Expand Down Expand Up @@ -67,6 +68,7 @@ static inline int acquire_tpm2_key(
const char *volume_name,
const char *device,
uint32_t hash_pcr_mask,
Hashmap *hash_pcr_literal,
uint16_t pcr_bank,
const void *pubkey,
size_t pubkey_size,
Expand Down
5 changes: 4 additions & 1 deletion src/cryptsetup/cryptsetup.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ static char *arg_fido2_rp_id = NULL;
static char *arg_tpm2_device = NULL; /* These and the following fields are about locking an encrypted volume to the local TPM */
static bool arg_tpm2_device_auto = false;
static uint32_t arg_tpm2_pcr_mask = UINT32_MAX;
static Hashmap *arg_tpm2_pcr_literal = NULL;
static char *arg_tpm2_signature = NULL;
static bool arg_tpm2_pin = false;
static bool arg_headless = false;
Expand Down Expand Up @@ -399,7 +400,7 @@ static int parse_one_option(const char *option) {

} else if ((val = startswith(option, "tpm2-pcrs="))) {

r = tpm2_parse_pcr_argument(val, &arg_tpm2_pcr_mask);
r = tpm2_parse_pcr_argument(val, &arg_tpm2_pcr_mask, arg_tpm2_pcr_literal);
if (r < 0)
return r;

Expand Down Expand Up @@ -1644,6 +1645,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
name,
arg_tpm2_device,
arg_tpm2_pcr_mask == UINT32_MAX ? TPM2_PCR_MASK_DEFAULT : arg_tpm2_pcr_mask,
arg_tpm2_pcr_literal,
UINT16_MAX,
/* pubkey= */ NULL, /* pubkey_size= */ 0,
/* pubkey_pcr_mask= */ 0,
Expand Down Expand Up @@ -1739,6 +1741,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
name,
arg_tpm2_device,
hash_pcr_mask,
arg_tpm2_pcr_literal,
pcr_bank,
pubkey, pubkey_size,
pubkey_pcr_mask,
Expand Down
7 changes: 5 additions & 2 deletions src/partition/repart.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ static EVP_PKEY *arg_private_key = NULL;
static X509 *arg_certificate = NULL;
static char *arg_tpm2_device = NULL;
static uint32_t arg_tpm2_pcr_mask = UINT32_MAX;
static Hashmap *arg_tpm2_pcr_literal = NULL;
static char *arg_tpm2_public_key = NULL;
static uint32_t arg_tpm2_public_key_pcr_mask = UINT32_MAX;
static bool arg_split = false;
Expand Down Expand Up @@ -3526,6 +3527,7 @@ static int partition_encrypt(Context *context, Partition *p, PartitionTarget *ta

r = tpm2_seal(arg_tpm2_device,
arg_tpm2_pcr_mask,
arg_tpm2_pcr_literal,
pubkey, pubkey_size,
arg_tpm2_public_key_pcr_mask,
/* pin= */ NULL,
Expand Down Expand Up @@ -3560,6 +3562,7 @@ static int partition_encrypt(Context *context, Partition *p, PartitionTarget *ta
r = tpm2_make_luks2_json(
keyslot,
arg_tpm2_pcr_mask,
arg_tpm2_pcr_literal,
pcr_bank,
pubkey, pubkey_size,
arg_tpm2_public_key_pcr_mask,
Expand Down Expand Up @@ -6283,7 +6286,7 @@ static int parse_argv(int argc, char *argv[]) {
}

case ARG_TPM2_PCRS:
r = tpm2_parse_pcr_argument(optarg, &arg_tpm2_pcr_mask);
r = tpm2_parse_pcr_argument(optarg, &arg_tpm2_pcr_mask, arg_tpm2_pcr_literal);
if (r < 0)
return r;

Expand All @@ -6297,7 +6300,7 @@ static int parse_argv(int argc, char *argv[]) {
break;

case ARG_TPM2_PUBLIC_KEY_PCRS:
r = tpm2_parse_pcr_argument(optarg, &arg_tpm2_public_key_pcr_mask);
r = tpm2_parse_pcr_argument(optarg, &arg_tpm2_public_key_pcr_mask, arg_tpm2_pcr_literal);
if (r < 0)
return r;

Expand Down
6 changes: 5 additions & 1 deletion src/shared/creds-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,7 @@ int encrypt_credential_and_warn(
usec_t not_after,
const char *tpm2_device,
uint32_t tpm2_hash_pcr_mask,
Hashmap *hash_pcr_literal,
const char *tpm2_pubkey_path,
uint32_t tpm2_pubkey_pcr_mask,
const void *input,
Expand Down Expand Up @@ -815,6 +816,7 @@ int encrypt_credential_and_warn(

r = tpm2_seal(tpm2_device,
tpm2_hash_pcr_mask,
hash_pcr_literal,
pubkey, pubkey_size,
tpm2_pubkey_pcr_mask,
/* pin= */ NULL,
Expand Down Expand Up @@ -1108,6 +1110,7 @@ int decrypt_credential_and_warn(
#if HAVE_TPM2
struct tpm2_credential_header* t = (struct tpm2_credential_header*) ((uint8_t*) input + p);
struct tpm2_public_key_credential_header *z = NULL;
Hashmap *hash_pcr_literal = NULL;

if (!TPM2_PCR_MASK_VALID(t->pcr_mask))
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "TPM2 PCR mask out of range.");
Expand Down Expand Up @@ -1158,6 +1161,7 @@ int decrypt_credential_and_warn(
// through and used to verify the TPM session.
r = tpm2_unseal(tpm2_device,
le64toh(t->pcr_mask),
hash_pcr_literal,
le16toh(t->pcr_bank),
z ? z->data : NULL,
z ? le32toh(z->size) : 0,
Expand Down Expand Up @@ -1328,7 +1332,7 @@ int get_credential_host_secret(CredentialSecretFlags flags, void **ret, size_t *
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Support for encrypted credentials not available.");
}

int encrypt_credential_and_warn(sd_id128_t with_key, const char *name, usec_t timestamp, usec_t not_after, const char *tpm2_device, uint32_t tpm2_hash_pcr_mask, const char *tpm2_pubkey_path, uint32_t tpm2_pubkey_pcr_mask, const void *input, size_t input_size, void **ret, size_t *ret_size) {
int encrypt_credential_and_warn(sd_id128_t with_key, const char *name, usec_t timestamp, usec_t not_after, const char *tpm2_device, uint32_t tpm2_hash_pcr_mask, Hashmap *hash_pcr_literal, const char *tpm2_pubkey_path, uint32_t tpm2_pubkey_pcr_mask, const void *input, size_t input_size, void **ret, size_t *ret_size) {
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Support for encrypted credentials not available.");
}

Expand Down
4 changes: 3 additions & 1 deletion src/shared/creds-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <stdbool.h>
#include <sys/types.h>

#include "hashmap.h"
#include "sha256.h"
#include "sd-id128.h"

#include "fd-util.h"
Expand Down Expand Up @@ -73,5 +75,5 @@ int get_credential_user_password(const char *username, char **ret_password, bool
#define _CRED_AUTO SD_ID128_MAKE(a2,19,cb,07,85,b2,4c,04,b1,6d,18,ca,b9,d2,ee,01)
#define _CRED_AUTO_INITRD SD_ID128_MAKE(02,dc,8e,de,3a,02,43,ab,a9,ec,54,9c,05,e6,a0,71)

int encrypt_credential_and_warn(sd_id128_t with_key, const char *name, usec_t timestamp, usec_t not_after, const char *tpm2_device, uint32_t tpm2_hash_pcr_mask, const char *tpm2_pubkey_path, uint32_t tpm2_pubkey_pcr_mask, const void *input, size_t input_size, void **ret, size_t *ret_size);
int encrypt_credential_and_warn(sd_id128_t with_key, const char *name, usec_t timestamp, usec_t not_after, const char *tpm2_device, uint32_t tpm2_hash_pcr_mask, Hashmap *hash_pcr_literal, const char *tpm2_pubkey_path, uint32_t tpm2_pubkey_pcr_mask, const void *input, size_t input_size, void **ret, size_t *ret_size);
int decrypt_credential_and_warn(const char *validate_name, usec_t validate_timestamp, const char *tpm2_device, const char *tpm2_signature_path, const void *input, size_t input_size, void **ret, size_t *ret_size);