1 /* xnu_uuid.c - transform 64-bit serial number
2 to 128-bit uuid suitable for xnu. */
4 * GRUB -- GRand Unified Bootloader
5 * Copyright (C) 1995,1996,1998,1999,2001,2002,
6 * 2003, 2009 Free Software Foundation, Inc.
8 * GRUB is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
13 * GRUB is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
22 #include <grub/types.h>
23 #include <grub/misc.h>
27 #include <grub/device.h>
28 #include <grub/disk.h>
30 #include <grub/file.h>
31 #include <grub/misc.h>
33 #include <grub/command.h>
34 #include <grub/i18n.h>
35 #include <grub/crypto.h>
37 /* This prefix is used by xnu and boot-132 to hash
38 together with volume serial. */
39 static grub_uint8_t hash_prefix
[16]
40 = {0xB3, 0xE2, 0x0F, 0x39, 0xF2, 0x92, 0x11, 0xD6,
41 0x97, 0xA4, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC};
44 grub_cmd_xnu_uuid (grub_command_t cmd
__attribute__ ((unused
)),
45 int argc
, char **args
)
48 grub_uint8_t
*xnu_uuid
;
49 char uuid_string
[sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")];
51 grub_uint8_t ctx
[GRUB_MD_MD5
->contextsize
];
54 return grub_error (GRUB_ERR_BAD_ARGUMENT
, "UUID required");
56 serial
= grub_cpu_to_be64 (grub_strtoull (args
[0], 0, 16));
58 GRUB_MD_MD5
->init (&ctx
);
59 GRUB_MD_MD5
->write (&ctx
, hash_prefix
, sizeof (hash_prefix
));
60 GRUB_MD_MD5
->write (&ctx
, &serial
, sizeof (serial
));
61 GRUB_MD_MD5
->final (&ctx
);
62 xnu_uuid
= GRUB_MD_MD5
->read (&ctx
);
64 grub_snprintf (uuid_string
, sizeof (uuid_string
),
65 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
66 (unsigned int) xnu_uuid
[0], (unsigned int) xnu_uuid
[1],
67 (unsigned int) xnu_uuid
[2], (unsigned int) xnu_uuid
[3],
68 (unsigned int) xnu_uuid
[4], (unsigned int) xnu_uuid
[5],
69 (unsigned int) ((xnu_uuid
[6] & 0xf) | 0x30),
70 (unsigned int) xnu_uuid
[7],
71 (unsigned int) ((xnu_uuid
[8] & 0x3f) | 0x80),
72 (unsigned int) xnu_uuid
[9],
73 (unsigned int) xnu_uuid
[10], (unsigned int) xnu_uuid
[11],
74 (unsigned int) xnu_uuid
[12], (unsigned int) xnu_uuid
[13],
75 (unsigned int) xnu_uuid
[14], (unsigned int) xnu_uuid
[15]);
76 for (ptr
= uuid_string
; *ptr
; ptr
++)
77 *ptr
= grub_toupper (*ptr
);
79 grub_printf ("%s", uuid_string
);
81 grub_env_set (args
[1], uuid_string
);
86 static grub_command_t cmd
;
89 GRUB_MOD_INIT (xnu_uuid
)
91 cmd
= grub_register_command ("xnu_uuid", grub_cmd_xnu_uuid
,
92 N_("GRUBUUID [VARNAME]"),
93 N_("Transform 64-bit UUID to format "
94 "suitable for XNU."));
97 GRUB_MOD_FINI (xnu_uuid
)
99 grub_unregister_command (cmd
);