]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
key_protector: Add key protectors framework
authorHernan Gatta <hegatta@linux.microsoft.com>
Fri, 15 Nov 2024 07:34:47 +0000 (15:34 +0800)
committerDaniel Kiper <daniel.kiper@oracle.com>
Thu, 28 Nov 2024 20:50:55 +0000 (21:50 +0100)
A key protector encapsulates functionality to retrieve an unlocking key
for a fully-encrypted disk from a specific source. A key protector
module registers itself with the key protectors framework when it is
loaded and unregisters when unloaded. Additionally, a key protector may
accept parameters that describe how it should operate.

The key protectors framework, besides offering registration and
unregistration functions, also offers a one-stop routine for finding and
invoking a key protector by name. If a key protector with the specified
name exists and if an unlocking key is successfully retrieved by it, the
function returns to the caller the retrieved key and its length.

Cc: Vladimir Serbinenko <phcoder@gmail.com>
Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
Signed-off-by: Gary Lin <glin@suse.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
grub-core/Makefile.am
grub-core/Makefile.core.def
grub-core/disk/key_protector.c [new file with mode: 0644]
include/grub/key_protector.h [new file with mode: 0644]

index 1eda467e00ace48dde47c9db4b835a0b95e994a1..e50db81061f1af4da95da135e2f68621028f6a02 100644 (file)
@@ -90,6 +90,7 @@ endif
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/key_protector.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/stack_protector.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
index a38955e185d33885f17e71ccaf778d03411712b3..37f131ae22df32bcc0aeb8ac7f2b72d2e56dd986 100644 (file)
@@ -1282,6 +1282,11 @@ module = {
   common = disk/raid6_recover.c;
 };
 
+module = {
+  name = key_protector;
+  common = disk/key_protector.c;
+};
+
 module = {
   name = scsi;
   common = disk/scsi.c;
diff --git a/grub-core/disk/key_protector.c b/grub-core/disk/key_protector.c
new file mode 100644 (file)
index 0000000..0d146c1
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2022 Microsoft Corporation
+ *  Copyright (C) 2024 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/list.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/key_protector.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+struct grub_key_protector *grub_key_protectors = NULL;
+
+grub_err_t
+grub_key_protector_register (struct grub_key_protector *protector)
+{
+  if (protector == NULL || protector->name == NULL || protector->name[0] == '\0')
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector for registration");
+
+  if (grub_key_protectors != NULL &&
+      grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), protector->name) != NULL)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Key protector '%s' already registered", protector->name);
+
+  grub_list_push (GRUB_AS_LIST_P (&grub_key_protectors), GRUB_AS_LIST (protector));
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_key_protector_unregister (struct grub_key_protector *protector)
+{
+  if (protector == NULL)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector for unregistration");
+
+  grub_list_remove (GRUB_AS_LIST (protector));
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_key_protector_recover_key (const char *protector, grub_uint8_t **key,
+                               grub_size_t *key_size)
+{
+  struct grub_key_protector *kp = NULL;
+
+  if (grub_key_protectors == NULL)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "No key protector registered");
+
+  if (protector == NULL || protector[0] == '\0')
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector");
+
+  kp = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), protector);
+  if (kp == NULL)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "Key protector '%s' not found", protector);
+
+  return kp->recover_key (key, key_size);
+}
diff --git a/include/grub/key_protector.h b/include/grub/key_protector.h
new file mode 100644 (file)
index 0000000..00b15c1
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2022 Microsoft Corporation
+ *  Copyright (C) 2024 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_PROTECTOR_HEADER
+#define GRUB_PROTECTOR_HEADER 1
+
+#include <grub/err.h>
+#include <grub/types.h>
+
+struct grub_key_protector
+{
+  struct grub_key_protector *next;
+  struct grub_key_protector **prev;
+
+  const char *name;
+
+  grub_err_t (*recover_key) (grub_uint8_t **key, grub_size_t *key_size);
+};
+
+grub_err_t
+grub_key_protector_register (struct grub_key_protector *protector);
+
+grub_err_t
+grub_key_protector_unregister (struct grub_key_protector *protector);
+
+grub_err_t
+grub_key_protector_recover_key (const char *protector,
+                               grub_uint8_t **key,
+                               grub_size_t *key_size);
+
+#endif /* ! GRUB_PROTECTOR_HEADER */