Compare commits
6 Commits
1293bb9c34
...
c76d764b80
Author | SHA1 | Date |
---|---|---|
Ani Sinha | c76d764b80 | |
Ani Sinha | 6df2c6d15a | |
Luca Boccassi | 9bf6ffe166 | |
Lennart Poettering | cc6baba720 | |
Lennart Poettering | 3ae48d071c | |
Antonio Alvarez Feijoo | 2ccacdd57c |
|
@ -265,32 +265,11 @@
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
<title>Options</title>
|
<title>Unlocking</title>
|
||||||
|
|
||||||
<para>The following options are understood:</para>
|
<para>The following options are understood that may be used to unlock the device in preparation of the enrollment operations:</para>
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
|
||||||
<term><option>--password</option></term>
|
|
||||||
|
|
||||||
<listitem><para>Enroll a regular password/passphrase. This command is mostly equivalent to
|
|
||||||
<command>cryptsetup luksAddKey</command>, however may be combined with
|
|
||||||
<option>--wipe-slot=</option> in one call, see below.</para>
|
|
||||||
|
|
||||||
<xi:include href="version-info.xml" xpointer="v248"/></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><option>--recovery-key</option></term>
|
|
||||||
|
|
||||||
<listitem><para>Enroll a recovery key. Recovery keys are mostly identical to passphrases, but are
|
|
||||||
computer-generated instead of being chosen by a human, and thus have a guaranteed high entropy. The
|
|
||||||
key uses a character set that is easy to type in, and may be scanned off screen via a QR code.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<xi:include href="version-info.xml" xpointer="v248"/></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--unlock-key-file=<replaceable>PATH</replaceable></option></term>
|
<term><option>--unlock-key-file=<replaceable>PATH</replaceable></option></term>
|
||||||
|
|
||||||
|
@ -328,7 +307,45 @@
|
||||||
|
|
||||||
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
|
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Simple Enrollment</title>
|
||||||
|
|
||||||
|
<para>The following options are understood that may be used to enroll simple user input based
|
||||||
|
unlocking:</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--password</option></term>
|
||||||
|
|
||||||
|
<listitem><para>Enroll a regular password/passphrase. This command is mostly equivalent to
|
||||||
|
<command>cryptsetup luksAddKey</command>, however may be combined with
|
||||||
|
<option>--wipe-slot=</option> in one call, see below.</para>
|
||||||
|
|
||||||
|
<xi:include href="version-info.xml" xpointer="v248"/></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--recovery-key</option></term>
|
||||||
|
|
||||||
|
<listitem><para>Enroll a recovery key. Recovery keys are mostly identical to passphrases, but are
|
||||||
|
computer-generated instead of being chosen by a human, and thus have a guaranteed high entropy. The
|
||||||
|
key uses a character set that is easy to type in, and may be scanned off screen via a QR code.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<xi:include href="version-info.xml" xpointer="v248"/></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>PKCS#11 Enrollment</title>
|
||||||
|
|
||||||
|
<para>The following option is understood that may be used to enroll PKCS#11 tokens:</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--pkcs11-token-uri=<replaceable>URI</replaceable></option></term>
|
<term><option>--pkcs11-token-uri=<replaceable>URI</replaceable></option></term>
|
||||||
|
|
||||||
|
@ -361,7 +378,15 @@
|
||||||
|
|
||||||
<xi:include href="version-info.xml" xpointer="v248"/></listitem>
|
<xi:include href="version-info.xml" xpointer="v248"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>FIDO2 Enrollment</title>
|
||||||
|
|
||||||
|
<para>The following options are understood that may be used to enroll PKCS#11 tokens:</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--fido2-credential-algorithm=<replaceable>STRING</replaceable></option></term>
|
<term><option>--fido2-credential-algorithm=<replaceable>STRING</replaceable></option></term>
|
||||||
<listitem><para>Specify COSE algorithm used in credential generation. The default value is
|
<listitem><para>Specify COSE algorithm used in credential generation. The default value is
|
||||||
|
@ -461,7 +486,15 @@
|
||||||
|
|
||||||
<xi:include href="version-info.xml" xpointer="v249"/></listitem>
|
<xi:include href="version-info.xml" xpointer="v249"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>TPM2 Enrollment</title>
|
||||||
|
|
||||||
|
<para>The following options are understood that may be used to enroll TPM2 devices:</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--tpm2-device=<replaceable>PATH</replaceable></option></term>
|
<term><option>--tpm2-device=<replaceable>PATH</replaceable></option></term>
|
||||||
|
|
||||||
|
@ -636,7 +669,15 @@
|
||||||
|
|
||||||
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
|
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Other Options</title>
|
||||||
|
|
||||||
|
<para>The following additional options are understood:</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--wipe-slot=<replaceable>SLOT<optional>,SLOT...</optional></replaceable></option></term>
|
<term><option>--wipe-slot=<replaceable>SLOT<optional>,SLOT...</optional></replaceable></option></term>
|
||||||
|
|
||||||
|
|
|
@ -38,19 +38,12 @@ __get_tpm2_devices() {
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
__get_block_devices() {
|
|
||||||
local i
|
|
||||||
for i in /dev/*; do
|
|
||||||
[ -b "$i" ] && printf '%s\n' "$i"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
_systemd_cryptenroll() {
|
_systemd_cryptenroll() {
|
||||||
local comps
|
local comps
|
||||||
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
|
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
|
||||||
local -A OPTS=(
|
local -A OPTS=(
|
||||||
[STANDALONE]='-h --help --version
|
[STANDALONE]='-h --help --version
|
||||||
--password --recovery-key'
|
--password --recovery-key --list-devices'
|
||||||
[ARG]='--unlock-key-file
|
[ARG]='--unlock-key-file
|
||||||
--unlock-fido2-device
|
--unlock-fido2-device
|
||||||
--unlock-tpm2-device
|
--unlock-tpm2-device
|
||||||
|
@ -116,7 +109,7 @@ _systemd_cryptenroll() {
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
comps=$(__get_block_devices)
|
comps=$(systemd-cryptenroll --list-devices)
|
||||||
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
|
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,12 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/* Validate the descriptor macros a bit that they match our expectations */
|
/* Validate the descriptor macros a bit that they match our expectations */
|
||||||
assert_cc(DEVICE_DESCRIPTOR_DEVICETREE == UINT32_C(0x1000001C));
|
assert_cc(DEVICE_DESCRIPTOR_DEVICETREE == UINT32_C(0x10000020));
|
||||||
|
assert_cc(DEVICE_DESCRIPTOR_EFIFW == UINT32_C(0x20000020));
|
||||||
assert_cc(DEVICE_SIZE_FROM_DESCRIPTOR(DEVICE_DESCRIPTOR_DEVICETREE) == sizeof(Device));
|
assert_cc(DEVICE_SIZE_FROM_DESCRIPTOR(DEVICE_DESCRIPTOR_DEVICETREE) == sizeof(Device));
|
||||||
assert_cc(DEVICE_TYPE_FROM_DESCRIPTOR(DEVICE_DESCRIPTOR_DEVICETREE) == DEVICE_TYPE_DEVICETREE);
|
assert_cc(DEVICE_TYPE_FROM_DESCRIPTOR(DEVICE_DESCRIPTOR_DEVICETREE) == DEVICE_TYPE_DEVICETREE);
|
||||||
|
assert_cc(DEVICE_SIZE_FROM_DESCRIPTOR(DEVICE_DESCRIPTOR_EFIFW) == sizeof(Device));
|
||||||
|
assert_cc(DEVICE_TYPE_FROM_DESCRIPTOR(DEVICE_DESCRIPTOR_EFIFW) == DEVICE_TYPE_EFIFW);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* smbios_to_hashable_string() - Convert ascii smbios string to stripped char16_t.
|
* smbios_to_hashable_string() - Convert ascii smbios string to stripped char16_t.
|
||||||
|
@ -107,13 +110,15 @@ EFI_STATUS chid_match(const void *hwid_buffer, size_t hwid_length, const Device
|
||||||
return log_error_status(status, "Failed to populate board CHIDs: %m");
|
return log_error_status(status, "Failed to populate board CHIDs: %m");
|
||||||
|
|
||||||
size_t n_devices = 0;
|
size_t n_devices = 0;
|
||||||
|
uint32_t dev_type;
|
||||||
|
|
||||||
/* Count devices and check validity */
|
/* Count devices and check validity */
|
||||||
for (; (n_devices + 1) * sizeof(*devices) < hwid_length;) {
|
for (; (n_devices + 1) * sizeof(*devices) < hwid_length;) {
|
||||||
|
|
||||||
|
dev_type = DEVICE_TYPE_FROM_DESCRIPTOR(devices[n_devices].descriptor);
|
||||||
if (devices[n_devices].descriptor == DEVICE_DESCRIPTOR_EOL)
|
if (devices[n_devices].descriptor == DEVICE_DESCRIPTOR_EOL)
|
||||||
break;
|
break;
|
||||||
if (devices[n_devices].descriptor != DEVICE_DESCRIPTOR_DEVICETREE)
|
if ((dev_type != DEVICE_TYPE_EFIFW) && (dev_type != DEVICE_TYPE_DEVICETREE))
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
n_devices++;
|
n_devices++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,11 +11,13 @@
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
DEVICE_TYPE_DEVICETREE = 0x1, /* A devicetree blob */
|
DEVICE_TYPE_DEVICETREE = 0x1, /* A devicetree blob */
|
||||||
|
DEVICE_TYPE_EFIFW, /* an efi firmware blob */
|
||||||
|
|
||||||
/* Maybe later additional types for:
|
/* Maybe later additional types for:
|
||||||
* - CoCo Bring-Your-Own-Firmware
|
* - CoCo Bring-Your-Own-Firmware
|
||||||
* - ACPI DSDT Overrides
|
* - ACPI DSDT Overrides
|
||||||
* - … */
|
* - … */
|
||||||
|
_DEVICE_TYPE_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEVICE_SIZE_FROM_DESCRIPTOR(u) ((uint32_t) (u) & UINT32_C(0x0FFFFFFF))
|
#define DEVICE_SIZE_FROM_DESCRIPTOR(u) ((uint32_t) (u) & UINT32_C(0x0FFFFFFF))
|
||||||
|
@ -23,6 +25,7 @@ enum {
|
||||||
#define DEVICE_MAKE_DESCRIPTOR(type, size) (((uint32_t) (size) | ((uint32_t) type << 28)))
|
#define DEVICE_MAKE_DESCRIPTOR(type, size) (((uint32_t) (size) | ((uint32_t) type << 28)))
|
||||||
|
|
||||||
#define DEVICE_DESCRIPTOR_DEVICETREE DEVICE_MAKE_DESCRIPTOR(DEVICE_TYPE_DEVICETREE, sizeof(Device))
|
#define DEVICE_DESCRIPTOR_DEVICETREE DEVICE_MAKE_DESCRIPTOR(DEVICE_TYPE_DEVICETREE, sizeof(Device))
|
||||||
|
#define DEVICE_DESCRIPTOR_EFIFW DEVICE_MAKE_DESCRIPTOR(DEVICE_TYPE_EFIFW, sizeof(Device))
|
||||||
#define DEVICE_DESCRIPTOR_EOL UINT32_C(0)
|
#define DEVICE_DESCRIPTOR_EOL UINT32_C(0)
|
||||||
|
|
||||||
typedef struct Device {
|
typedef struct Device {
|
||||||
|
@ -36,6 +39,14 @@ typedef struct Device {
|
||||||
uint32_t name_offset; /* nul-terminated string or 0 if not present */
|
uint32_t name_offset; /* nul-terminated string or 0 if not present */
|
||||||
uint32_t compatible_offset; /* nul-terminated string or 0 if not present */
|
uint32_t compatible_offset; /* nul-terminated string or 0 if not present */
|
||||||
} devicetree;
|
} devicetree;
|
||||||
|
struct {
|
||||||
|
/* Offsets are relative to the beginning of the .hwids PE section.
|
||||||
|
They are nul-terminated strings when present or 0 if not present */
|
||||||
|
uint32_t id_offset; /* identifier for the firmware blob */
|
||||||
|
uint32_t metadata_offset; /* firmware metadata string */
|
||||||
|
uint32_t compatible_offset; /* compatibility identifier to match a specific fw blob */
|
||||||
|
} efifw;
|
||||||
|
|
||||||
/* fields for other descriptor types… */
|
/* fields for other descriptor types… */
|
||||||
};
|
};
|
||||||
} _packed_ Device;
|
} _packed_ Device;
|
||||||
|
@ -45,16 +56,19 @@ assert_cc(offsetof(Device, descriptor) == 0);
|
||||||
assert_cc(offsetof(Device, chid) == 4);
|
assert_cc(offsetof(Device, chid) == 4);
|
||||||
assert_cc(offsetof(Device, devicetree.name_offset) == 20);
|
assert_cc(offsetof(Device, devicetree.name_offset) == 20);
|
||||||
assert_cc(offsetof(Device, devicetree.compatible_offset) == 24);
|
assert_cc(offsetof(Device, devicetree.compatible_offset) == 24);
|
||||||
assert_cc(sizeof(Device) == 28);
|
assert_cc(offsetof(Device, efifw.id_offset) == 20);
|
||||||
|
assert_cc(offsetof(Device, efifw.metadata_offset) == 24);
|
||||||
|
assert_cc(offsetof(Device, efifw.compatible_offset) == 28);
|
||||||
|
assert_cc(sizeof(Device) == 32);
|
||||||
|
|
||||||
static inline const char* device_get_name(const void *base, const Device *device) {
|
static inline const char* device_get_devicetree_name(const void *base, const Device *device) {
|
||||||
if (device->descriptor != DEVICE_DESCRIPTOR_DEVICETREE)
|
if (device->descriptor != DEVICE_DESCRIPTOR_DEVICETREE)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return device->devicetree.name_offset == 0 ? NULL : (const char *) ((const uint8_t *) base + device->devicetree.name_offset);
|
return device->devicetree.name_offset == 0 ? NULL : (const char *) ((const uint8_t *) base + device->devicetree.name_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const char* device_get_compatible(const void *base, const Device *device) {
|
static inline const char* device_get_devicetree_compatible(const void *base, const Device *device) {
|
||||||
if (device->descriptor != DEVICE_DESCRIPTOR_DEVICETREE)
|
if (device->descriptor != DEVICE_DESCRIPTOR_DEVICETREE)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
|
@ -185,7 +185,7 @@ static bool pe_use_this_dtb(
|
||||||
if (!device || !base)
|
if (!device || !base)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const char *compatible = device_get_compatible(base, device);
|
const char *compatible = device_get_devicetree_compatible(base, device);
|
||||||
if (!compatible)
|
if (!compatible)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ static int help(void) {
|
||||||
"\n%3$sSimple Enrollment:%4$s\n"
|
"\n%3$sSimple Enrollment:%4$s\n"
|
||||||
" --password Enroll a user-supplied password\n"
|
" --password Enroll a user-supplied password\n"
|
||||||
" --recovery-key Enroll a recovery key\n"
|
" --recovery-key Enroll a recovery key\n"
|
||||||
"\n%3$sPKCS11 Enrollment:%4$s\n"
|
"\n%3$sPKCS#11 Enrollment:%4$s\n"
|
||||||
" --pkcs11-token-uri=URI\n"
|
" --pkcs11-token-uri=URI\n"
|
||||||
" Specify PKCS#11 security token URI\n"
|
" Specify PKCS#11 security token URI\n"
|
||||||
"\n%3$sFIDO2 Enrollment:%4$s\n"
|
"\n%3$sFIDO2 Enrollment:%4$s\n"
|
||||||
|
|
Loading…
Reference in New Issue