summaryrefslogtreecommitdiffstats
path: root/grub-core/commands/xnu_uuid.c
diff options
context:
space:
mode:
Diffstat (limited to 'grub-core/commands/xnu_uuid.c')
-rw-r--r--grub-core/commands/xnu_uuid.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/grub-core/commands/xnu_uuid.c b/grub-core/commands/xnu_uuid.c
new file mode 100644
index 0000000..ae4b3a4
--- /dev/null
+++ b/grub-core/commands/xnu_uuid.c
@@ -0,0 +1,119 @@
+/* xnu_uuid.c - transform 64-bit serial number
+ to 128-bit uuid suitable for xnu. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1995,1996,1998,1999,2001,2002,
+ * 2003, 2009 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/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/fs.h>
+#include <grub/file.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+#include <grub/crypto.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+/* This prefix is used by xnu and boot-132 to hash
+ together with volume serial. */
+static grub_uint8_t hash_prefix[16]
+ = {0xB3, 0xE2, 0x0F, 0x39, 0xF2, 0x92, 0x11, 0xD6,
+ 0x97, 0xA4, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC};
+
+static grub_err_t
+grub_cmd_xnu_uuid (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char **args)
+{
+ grub_uint64_t serial;
+ grub_uint8_t *xnu_uuid;
+ char uuid_string[sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")];
+ char *ptr;
+ void *ctx;
+ int low = 0;
+
+ if (argc < 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "UUID required");
+
+ if (argc > 1 && grub_strcmp (args[0], "-l") == 0)
+ {
+ low = 1;
+ argc--;
+ args++;
+ }
+
+ serial = grub_cpu_to_be64 (grub_strtoull (args[0], 0, 16));
+
+ ctx = grub_zalloc (GRUB_MD_MD5->contextsize);
+ if (!ctx)
+ return grub_errno;
+ GRUB_MD_MD5->init (ctx);
+ GRUB_MD_MD5->write (ctx, hash_prefix, sizeof (hash_prefix));
+ GRUB_MD_MD5->write (ctx, &serial, sizeof (serial));
+ GRUB_MD_MD5->final (ctx);
+ xnu_uuid = GRUB_MD_MD5->read (ctx);
+
+ grub_snprintf (uuid_string, sizeof (uuid_string),
+ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ (unsigned int) xnu_uuid[0], (unsigned int) xnu_uuid[1],
+ (unsigned int) xnu_uuid[2], (unsigned int) xnu_uuid[3],
+ (unsigned int) xnu_uuid[4], (unsigned int) xnu_uuid[5],
+ (unsigned int) ((xnu_uuid[6] & 0xf) | 0x30),
+ (unsigned int) xnu_uuid[7],
+ (unsigned int) ((xnu_uuid[8] & 0x3f) | 0x80),
+ (unsigned int) xnu_uuid[9],
+ (unsigned int) xnu_uuid[10], (unsigned int) xnu_uuid[11],
+ (unsigned int) xnu_uuid[12], (unsigned int) xnu_uuid[13],
+ (unsigned int) xnu_uuid[14], (unsigned int) xnu_uuid[15]);
+ if (!low)
+ for (ptr = uuid_string; *ptr; ptr++)
+ *ptr = grub_toupper (*ptr);
+ if (argc == 1)
+ grub_printf ("%s\n", uuid_string);
+ if (argc > 1)
+ grub_env_set (args[1], uuid_string);
+
+ grub_free (ctx);
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd;
+
+
+GRUB_MOD_INIT (xnu_uuid)
+{
+ cmd = grub_register_command ("xnu_uuid", grub_cmd_xnu_uuid,
+ /* TRANSLATORS: GRUBUUID stands for "filesystem
+ UUID as used in GRUB". */
+ N_("[-l] GRUBUUID [VARNAME]"),
+ N_("Transform 64-bit UUID to format "
+ "suitable for XNU. If -l is given keep "
+ "it lowercase as done by blkid."));
+}
+
+GRUB_MOD_FINI (xnu_uuid)
+{
+ grub_unregister_command (cmd);
+}