mirror of
https://github.com/systemd/systemd.git
synced 2024-12-05 00:04:02 +08:00
measure: add --current switch for "systemd-measure calculate"
This allows allows shortcutting measurements of the specified files and use the information from /sys/ instead. This is not too useful on its own given that "systemd-measure status" already exists which displays the current, relevant PCR values. The main difference is how "complete" the information is. "status" will detect if the measurements make any sense, and show more than PCR 11. "calculate --current" otoh only reads PCR 11 and uses that, and that's really it. This is mainly preparation for later work to add PCR signing to the tool, where usually it makes most sense to sign prepared kernel images, but for testing it's really useful to shortcut signing to the current PCR values instead
This commit is contained in:
parent
8e7e4a730b
commit
127b72da2b
@ -91,6 +91,14 @@
|
||||
optional. Each option may be used at most once.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--current</option></term>
|
||||
<listitem><para>When used with the <command>calculate</command> verb, takes the PCR 11 values
|
||||
currently in effect for the system (which should typically reflect the hashes of the currently booted
|
||||
kernel). This can be used in place of <option>--linux=</option> and the other switches listed
|
||||
above.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--bank=DIGEST</option></term>
|
||||
|
||||
|
@ -26,6 +26,7 @@ static char *arg_sections[_UNIFIED_SECTION_MAX] = {};
|
||||
static char **arg_banks = NULL;
|
||||
static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
|
||||
static PagerFlags arg_pager_flags = 0;
|
||||
static bool arg_current = false;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_banks, strv_freep);
|
||||
|
||||
@ -59,6 +60,7 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||
" --initrd=PATH Path to initrd image\n"
|
||||
" --splash=PATH Path to splash bitmap\n"
|
||||
" --dtb=PATH Path to Devicetree file\n"
|
||||
" -c --current Use current PCR values\n"
|
||||
" --bank=DIGEST Select TPM bank (SHA1, SHA256)\n"
|
||||
" --json=MODE Output as JSON\n"
|
||||
" -j Same as --json=pretty on tty, --json=short otherwise\n"
|
||||
@ -99,6 +101,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "initrd", required_argument, NULL, ARG_INITRD },
|
||||
{ "splash", required_argument, NULL, ARG_SPLASH },
|
||||
{ "dtb", required_argument, NULL, ARG_DTB },
|
||||
{ "current", no_argument, NULL, 'c' },
|
||||
{ "bank", required_argument, NULL, ARG_BANK },
|
||||
{ "json", required_argument, NULL, ARG_JSON },
|
||||
{}
|
||||
@ -112,7 +115,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
/* Make sure the arguments list and the section list, stays in sync */
|
||||
assert_cc(_ARG_SECTION_FIRST + _UNIFIED_SECTION_MAX == _ARG_SECTION_LAST + 1);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "hj", options, NULL)) >= 0)
|
||||
while ((c = getopt_long(argc, argv, "hjc", options, NULL)) >= 0)
|
||||
switch (c) {
|
||||
|
||||
case 'h':
|
||||
@ -135,6 +138,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
}
|
||||
|
||||
case 'c':
|
||||
arg_current = true;
|
||||
break;
|
||||
|
||||
case ARG_BANK: {
|
||||
const EVP_MD *implementation;
|
||||
|
||||
@ -176,6 +183,11 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
strv_sort(arg_banks);
|
||||
strv_uniq(arg_banks);
|
||||
|
||||
if (arg_current)
|
||||
for (UnifiedSection us = 0; us < _UNIFIED_SECTION_MAX; us++)
|
||||
if (arg_sections[us])
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "The --current switch cannot be used in combination with --linux= and related switches.");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -259,6 +271,27 @@ static int measure_pcr(PcrState *pcr_states, size_t n) {
|
||||
if (!buffer)
|
||||
return log_oom();
|
||||
|
||||
if (arg_current) {
|
||||
/* Shortcut things, if we should just use the current PCR value */
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
_cleanup_free_ char *p = NULL, *s = NULL;
|
||||
|
||||
if (asprintf(&p, "/sys/class/tpm/tpm0/pcr-%s/%" PRIu32, pcr_states[i].bank, TPM_PCR_INDEX_KERNEL_IMAGE) < 0)
|
||||
return log_oom();
|
||||
|
||||
r = read_virtual_file(p, 4096, &s, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read '%s': %m", p);
|
||||
|
||||
r = unhexmem(strstrip(s), SIZE_MAX, &pcr_states[i].value, &pcr_states[i].value_size);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to decode PCR value '%s': %m", s);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (UnifiedSection c = 0; c < _UNIFIED_SECTION_MAX; c++) {
|
||||
_cleanup_(evp_md_ctx_free_all) EVP_MD_CTX **mdctx = NULL;
|
||||
_cleanup_close_ int fd = -1;
|
||||
@ -345,8 +378,8 @@ static int verb_calculate(int argc, char *argv[], void *userdata) {
|
||||
size_t n = 0;
|
||||
int r;
|
||||
|
||||
if (!arg_sections[UNIFIED_SECTION_LINUX])
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--linux= switch must be specified, refusing.");
|
||||
if (!arg_sections[UNIFIED_SECTION_LINUX] && !arg_current)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Either --linux= or --current must be specified, refusing.");
|
||||
|
||||
pcr_states = new0(PcrState, strv_length(arg_banks) + 1);
|
||||
if (!pcr_states)
|
||||
|
Loading…
Reference in New Issue
Block a user