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/>.
19 #include <grub/types.h>
20 #include <grub/crypto.h>
21 #include <grub/util/misc.h>
22 #include <grub/i18n.h>
33 /* Few functions to make crypto happy. */
35 grub_memmove (void *dest
, const void *src
, grub_size_t n
)
37 return memmove (dest
, src
, n
);
41 grub_memset (void *s
, int c
, grub_size_t n
)
43 return memset (s
, c
, n
);
47 grub_vprintf (const char *fmt
, va_list args
)
49 return vprintf (fmt
, args
);
53 grub_vsnprintf (char *str
, grub_size_t n
, const char *fmt
, va_list args
)
55 return vsnprintf (str
, n
, fmt
, args
);
64 static struct option options
[] =
66 {"iteration_count", required_argument
, 0, 'c'},
67 {"buflen", required_argument
, 0, 'l'},
68 {"saltlen", required_argument
, 0, 's'},
69 {"help", no_argument
, 0, 'h'},
70 {"version", no_argument
, 0, 'V'},
77 fprintf (stderr
, "Try `%s --help' for more information.\n", program_name
);
80 Usage: %s [OPTIONS]\n\
82 -c number, --iteration-count=number Number of PBKDF2 iterations\n\
83 -l number, --buflen=number Length of generated hash\n\
84 -s number, --salt=number Length of salt\n\
86 Report bugs to <%s>.\n", program_name
, PACKAGE_BUGREPORT
);
92 hexify (char *hex
, grub_uint8_t
*bin
, grub_size_t n
)
96 if (((*bin
& 0xf0) >> 4) < 10)
97 *hex
= ((*bin
& 0xf0) >> 4) + '0';
99 *hex
= ((*bin
& 0xf0) >> 4) + 'A' - 10;
102 if ((*bin
& 0xf) < 10)
103 *hex
= (*bin
& 0xf) + '0';
105 *hex
= (*bin
& 0xf) + 'A' - 10;
113 main (int argc
, char *argv
[])
115 unsigned int c
= 10000, buflen
= 64, saltlen
= 64;
117 char *bufhex
, *salthex
;
118 gcry_err_code_t gcry_err
;
119 grub_uint8_t
*buf
, *salt
;
125 set_program_name (argv
[0]);
127 grub_util_init_nls ();
129 /* Check for options. */
132 int c
= getopt_long (argc
, argv
, "c:l:s:hvV", options
, 0);
140 c
= strtoul (optarg
, NULL
, 0);
144 buflen
= strtoul (optarg
, NULL
, 0);
148 saltlen
= strtoul (optarg
, NULL
, 0);
156 printf ("%s (%s) %s\n", program_name
,
157 PACKAGE_NAME
, PACKAGE_VERSION
);
166 bufhex
= malloc (buflen
* 2 + 1);
168 grub_util_error ("out of memory");
169 buf
= malloc (buflen
);
173 grub_util_error ("out of memory");
176 salt
= malloc (saltlen
);
181 grub_util_error ("out of memory");
183 salthex
= malloc (saltlen
* 2 + 1);
189 grub_util_error ("out of memory");
192 /* Disable echoing. Based on glibc. */
193 in
= fopen ("/dev/tty", "w+c");
202 if (tcgetattr (fileno (in
), &t
) == 0)
204 /* Save the old one. */
206 /* Tricky, tricky. */
207 t
.c_lflag
&= ~(ECHO
|ISIG
);
208 tty_changed
= (tcsetattr (fileno (in
), TCSAFLUSH
, &t
) == 0);
213 printf ("Enter password: ");
217 nr
= getline (&pass1
, &n
, stdin
);
219 if (nr
< 0 || !pass1
)
225 /* Restore the original setting. */
227 (void) tcsetattr (fileno (in
), TCSAFLUSH
, &s
);
228 grub_util_error ("failure to read password");
230 if (nr
>= 1 && pass1
[nr
-1] == '\n')
233 printf ("\nReenter password: ");
237 nr
= getline (&pass2
, &n
, stdin
);
239 /* Restore the original setting. */
241 (void) tcsetattr (fileno (in
), TCSAFLUSH
, &s
);
244 if (nr
< 0 || !pass2
)
246 memset (pass1
, 0, strlen (pass1
));
252 grub_util_error ("failure to read password");
254 if (nr
>= 1 && pass2
[nr
-1] == '\n')
257 if (strcmp (pass1
, pass2
) != 0)
259 memset (pass1
, 0, strlen (pass1
));
260 memset (pass2
, 0, strlen (pass2
));
267 grub_util_error ("passwords don't match");
269 memset (pass2
, 0, strlen (pass2
));
272 #if ! defined (__linux__) && ! defined (__FreeBSD__)
273 printf ("WARNING: your random generator isn't known to be secure\n");
279 f
= fopen ("/dev/random", "rb");
282 memset (pass1
, 0, strlen (pass1
));
289 grub_util_error ("couldn't retrieve random data for salt");
291 rd
= fread (salt
, 1, saltlen
, f
);
295 memset (pass1
, 0, strlen (pass1
));
302 grub_util_error ("couldn't retrieve random data for salt");
307 gcry_err
= grub_crypto_pbkdf2 (GRUB_MD_SHA512
,
308 (grub_uint8_t
*) pass1
, strlen (pass1
),
311 memset (pass1
, 0, strlen (pass1
));
316 memset (buf
, 0, buflen
);
317 memset (bufhex
, 0, 2 * buflen
);
320 memset (salt
, 0, saltlen
);
321 memset (salthex
, 0, 2 * saltlen
);
324 grub_util_error ("cryptographic error number %d", gcry_err
);
327 hexify (bufhex
, buf
, buflen
);
328 hexify (salthex
, salt
, saltlen
);
330 printf ("Your PBKDF2 is grub.pbkdf2.sha512.%d.%s.%s\n", c
, salthex
, bufhex
);
331 memset (buf
, 0, buflen
);
332 memset (bufhex
, 0, 2 * buflen
);
335 memset (salt
, 0, saltlen
);
336 memset (salthex
, 0, 2 * saltlen
);