forked from pool/grub2
139 lines
4.1 KiB
Diff
139 lines
4.1 KiB
Diff
|
Index: grub-2.06/grub-core/tpm2/module.c
|
||
|
===================================================================
|
||
|
--- grub-2.06.orig/grub-core/tpm2/module.c
|
||
|
+++ grub-2.06/grub-core/tpm2/module.c
|
||
|
@@ -26,6 +26,7 @@
|
||
|
#include <grub/tpm2/internal/args.h>
|
||
|
#include <grub/tpm2/mu.h>
|
||
|
#include <grub/tpm2/tpm2.h>
|
||
|
+#include <grub/efi/efi.h>
|
||
|
|
||
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||
|
|
||
|
@@ -46,6 +47,7 @@ struct grub_tpm2_protector_context
|
||
|
const char *keyfile;
|
||
|
TPM_HANDLE srk;
|
||
|
TPM_HANDLE nv;
|
||
|
+ const char *efivar;
|
||
|
};
|
||
|
|
||
|
static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] =
|
||
|
@@ -122,6 +124,16 @@ static const struct grub_arg_option grub
|
||
|
N_("Required in NV Index mode, the NV handle to read which must "
|
||
|
"readily exist on the TPM and which contains the key."),
|
||
|
},
|
||
|
+ /* When publishing the unsealed key to a UEFI variable */
|
||
|
+ {
|
||
|
+ .longarg = "efivar",
|
||
|
+ .shortarg = 'E',
|
||
|
+ .flags = 0,
|
||
|
+ .arg = NULL,
|
||
|
+ .type = ARG_TYPE_STRING,
|
||
|
+ .doc =
|
||
|
+ N_("Publish the unsealed key to the indicated UEFI variable."),
|
||
|
+ },
|
||
|
/* End of list */
|
||
|
{0, 0, 0, 0, 0, 0}
|
||
|
};
|
||
|
@@ -302,6 +314,34 @@ grub_tpm2_protector_srk_get (const struc
|
||
|
}
|
||
|
|
||
|
static grub_err_t
|
||
|
+grub_tpm2_protector_publish_key (grub_uint8_t *key, grub_size_t key_size,
|
||
|
+ const char *var_name)
|
||
|
+{
|
||
|
+ grub_efi_guid_t vendor_guid = { 0x58aca851, 0x8af7, 0x4738, { 0xa5, 0x42, 0x26, 0x6e, 0x21, 0xf5, 0xca, 0xd9 }};
|
||
|
+ grub_uint8_t *tmp_key;
|
||
|
+ grub_err_t err;
|
||
|
+
|
||
|
+ /* It appears that EFI's set_var function overwrites the key. */
|
||
|
+ tmp_key = grub_malloc (key_size);
|
||
|
+ if (!tmp_key)
|
||
|
+ {
|
||
|
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("No memory left to allocate temporary key buffer"));
|
||
|
+ return GRUB_ERR_OUT_OF_MEMORY;
|
||
|
+ }
|
||
|
+
|
||
|
+ grub_memcpy(tmp_key, key, key_size);
|
||
|
+
|
||
|
+ err = grub_efi_set_variable_with_attributes(var_name, &vendor_guid,
|
||
|
+ GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS | GRUB_EFI_VARIABLE_RUNTIME_ACCESS,
|
||
|
+ tmp_key, key_size);
|
||
|
+ if (err)
|
||
|
+ grub_error (err, N_("Failed to export LUKS key as EFI variable %s"), var_name);
|
||
|
+
|
||
|
+ grub_free (tmp_key);
|
||
|
+ return err;
|
||
|
+}
|
||
|
+
|
||
|
+static grub_err_t
|
||
|
grub_tpm2_protector_srk_recover (const struct grub_tpm2_protector_context *ctx,
|
||
|
grub_uint8_t **key, grub_size_t *key_size)
|
||
|
{
|
||
|
@@ -421,6 +461,13 @@ grub_tpm2_protector_srk_recover (const s
|
||
|
goto exit4;
|
||
|
}
|
||
|
|
||
|
+ if (ctx->efivar)
|
||
|
+ {
|
||
|
+ rc = grub_tpm2_protector_publish_key (data.buffer, data.size, ctx->efivar);
|
||
|
+ if (rc)
|
||
|
+ goto exit4;
|
||
|
+ }
|
||
|
+
|
||
|
grub_memcpy (key_out, data.buffer, data.size);
|
||
|
|
||
|
*key = key_out;
|
||
|
@@ -549,20 +596,32 @@ grub_tpm2_protector_check_args (struct g
|
||
|
}
|
||
|
|
||
|
static grub_err_t
|
||
|
-grub_tpm2_protector_parse_keyfile (const char *value, const char **keyfile)
|
||
|
+grub_tpm2_protector_parse_string (const char *value, const char **var, const char *arg_name)
|
||
|
{
|
||
|
if (grub_strlen (value) == 0)
|
||
|
return GRUB_ERR_BAD_ARGUMENT;
|
||
|
|
||
|
- *keyfile = grub_strdup (value);
|
||
|
- if (!*keyfile)
|
||
|
+ *var = grub_strdup (value);
|
||
|
+ if (!*var)
|
||
|
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||
|
- N_("No memory to duplicate keyfile path"));
|
||
|
+ N_("No memory to duplicate %s argument"), arg_name);
|
||
|
|
||
|
return GRUB_ERR_NONE;
|
||
|
}
|
||
|
|
||
|
static grub_err_t
|
||
|
+grub_tpm2_protector_parse_keyfile (const char *value, const char **keyfile)
|
||
|
+{
|
||
|
+ return grub_tpm2_protector_parse_string (value, keyfile, "keyfile");
|
||
|
+}
|
||
|
+
|
||
|
+static grub_err_t
|
||
|
+grub_tpm2_protector_parse_efivar (const char *value, const char **efivar)
|
||
|
+{
|
||
|
+ return grub_tpm2_protector_parse_string (value, efivar, "efivar");
|
||
|
+}
|
||
|
+
|
||
|
+static grub_err_t
|
||
|
grub_tpm2_protector_parse_mode (const char *value,
|
||
|
grub_tpm2_protector_mode_t *mode)
|
||
|
{
|
||
|
@@ -650,6 +709,14 @@ grub_tpm2_protector_init_cmd_handler (gr
|
||
|
if (err)
|
||
|
return err;
|
||
|
}
|
||
|
+
|
||
|
+ if (state[7].set) /* efivar */
|
||
|
+ {
|
||
|
+ err = grub_tpm2_protector_parse_efivar (state[7].arg,
|
||
|
+ &grub_tpm2_protector_ctx.efivar);
|
||
|
+ if (err)
|
||
|
+ return err;
|
||
|
+ }
|
||
|
|
||
|
err = grub_tpm2_protector_check_args (&grub_tpm2_protector_ctx);
|
||
|
|