2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 1992-1999,2001,2003,2004,2005,2009 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
21 #include <grub/types.h>
22 #include <grub/crypto.h>
23 #include <grub/auth.h>
24 #include <grub/emu/misc.h>
25 #include <grub/util/misc.h>
26 #include <grub/i18n.h>
27 #include <grub/misc.h>
36 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
37 #pragma GCC diagnostic ignored "-Wmissing-declarations"
39 #pragma GCC diagnostic error "-Wmissing-prototypes"
40 #pragma GCC diagnostic error "-Wmissing-declarations"
45 static struct argp_option options
[] = {
46 {"iteration-count", 'c', N_("NUM"), 0, N_("Number of PBKDF2 iterations"), 0},
47 {"buflen", 'l', N_("NUM"), 0, N_("Length of generated hash"), 0},
48 {"salt", 's', N_("NUM"), 0, N_("Length of salt"), 0},
60 argp_parser (int key
, char *arg
, struct argp_state
*state
)
62 /* Get the input argument from argp_parse, which we
63 know is a pointer to our arguments structure. */
64 struct arguments
*arguments
= state
->input
;
69 arguments
->count
= strtoul (arg
, NULL
, 0);
73 arguments
->buflen
= strtoul (arg
, NULL
, 0);
77 arguments
->saltlen
= strtoul (arg
, NULL
, 0);
80 return ARGP_ERR_UNKNOWN
;
85 static struct argp argp
= {
86 options
, argp_parser
, N_("[OPTIONS]"),
87 N_("Generate PBKDF2 password hash."),
93 hexify (char *hex
, grub_uint8_t
*bin
, grub_size_t n
)
97 if (((*bin
& 0xf0) >> 4) < 10)
98 *hex
= ((*bin
& 0xf0) >> 4) + '0';
100 *hex
= ((*bin
& 0xf0) >> 4) + 'A' - 10;
103 if ((*bin
& 0xf) < 10)
104 *hex
= (*bin
& 0xf) + '0';
106 *hex
= (*bin
& 0xf) + 'A' - 10;
114 main (int argc
, char *argv
[])
116 struct arguments arguments
= {
122 gcry_err_code_t gcry_err
;
123 grub_uint8_t
*buf
, *salt
;
124 char pass1
[GRUB_AUTH_MAX_PASSLEN
];
125 char pass2
[GRUB_AUTH_MAX_PASSLEN
];
127 grub_util_host_init (&argc
, &argv
);
129 /* Check for options. */
130 if (argp_parse (&argp
, argc
, argv
, 0, 0, &arguments
) != 0)
132 fprintf (stderr
, "%s", _("Error in parsing command line arguments\n"));
136 printf ("%s", _("Enter password: "));
137 if (!grub_password_get (pass1
, GRUB_AUTH_MAX_PASSLEN
))
138 grub_util_error ("%s", _("failure to read password"));
139 printf ("%s", _("Reenter password: "));
140 if (!grub_password_get (pass2
, GRUB_AUTH_MAX_PASSLEN
))
141 grub_util_error ("%s", _("failure to read password"));
143 if (strcmp (pass1
, pass2
) != 0)
145 memset (pass1
, 0, sizeof (pass1
));
146 memset (pass2
, 0, sizeof (pass2
));
147 grub_util_error ("%s", _("passwords don't match"));
149 memset (pass2
, 0, sizeof (pass2
));
151 buf
= xmalloc (arguments
.buflen
);
152 salt
= xmalloc (arguments
.saltlen
);
154 if (grub_get_random (salt
, arguments
.saltlen
))
156 memset (pass1
, 0, sizeof (pass1
));
159 grub_util_error ("%s", _("couldn't retrieve random data for salt"));
162 gcry_err
= grub_crypto_pbkdf2 (GRUB_MD_SHA512
,
163 (grub_uint8_t
*) pass1
, strlen (pass1
),
164 salt
, arguments
.saltlen
,
165 arguments
.count
, buf
, arguments
.buflen
);
166 memset (pass1
, 0, sizeof (pass1
));
170 memset (buf
, 0, arguments
.buflen
);
172 memset (salt
, 0, arguments
.saltlen
);
174 grub_util_error (_("cryptographic error number %d"), gcry_err
);
177 result
= xmalloc (sizeof ("grub.pbkdf2.sha512.XXXXXXXXXXXXXXXXXXX.S.S")
178 + arguments
.buflen
* 2 + arguments
.saltlen
* 2);
180 memcpy (ptr
, "grub.pbkdf2.sha512.", sizeof ("grub.pbkdf2.sha512.") - 1);
181 ptr
+= sizeof ("grub.pbkdf2.sha512.") - 1;
183 grub_snprintf (ptr
, sizeof ("XXXXXXXXXXXXXXXXXXX"), "%d", arguments
.count
);
186 hexify (ptr
, salt
, arguments
.saltlen
);
187 ptr
+= arguments
.saltlen
* 2;
189 hexify (ptr
, buf
, arguments
.buflen
);
190 ptr
+= arguments
.buflen
* 2;
193 printf (_("PBKDF2 hash of your password is %s\n"), result
);
194 memset (buf
, 0, arguments
.buflen
);
196 memset (salt
, 0, arguments
.saltlen
);