Upgraded GRUB2 to 2.00 release.
[AROS.git] / arch / all-pc / boot / grub2-aros / util / grub-mkpasswd-pbkdf2.c
blob878d8b59d35f03af99d628bfd8f5943a07e63411
1 /*
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 <config.h>
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>
28 #include <unistd.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
33 #define _GNU_SOURCE 1
35 #include <argp.h>
37 #include "progname.h"
39 static struct argp_option options[] = {
40 {"iteration-count", 'c', N_("NUM"), 0, N_("Number of PBKDF2 iterations"), 0},
41 {"buflen", 'l', N_("NUM"), 0, N_("Length of generated hash"), 0},
42 {"salt", 's', N_("NUM"), 0, N_("Length of salt"), 0},
43 { 0, 0, 0, 0, 0, 0 }
46 struct arguments
48 unsigned int count;
49 unsigned int buflen;
50 unsigned int saltlen;
53 static error_t
54 argp_parser (int key, char *arg, struct argp_state *state)
56 /* Get the input argument from argp_parse, which we
57 know is a pointer to our arguments structure. */
58 struct arguments *arguments = state->input;
60 switch (key)
62 case 'c':
63 arguments->count = strtoul (arg, NULL, 0);
64 break;
66 case 'l':
67 arguments->buflen = strtoul (arg, NULL, 0);
68 break;
70 case 's':
71 arguments->saltlen = strtoul (arg, NULL, 0);
72 break;
73 default:
74 return ARGP_ERR_UNKNOWN;
76 return 0;
79 static struct argp argp = {
80 options, argp_parser, N_("[OPTIONS]"),
81 N_("Generate PBKDF2 password hash."),
82 NULL, NULL, NULL
86 static void
87 hexify (char *hex, grub_uint8_t *bin, grub_size_t n)
89 while (n--)
91 if (((*bin & 0xf0) >> 4) < 10)
92 *hex = ((*bin & 0xf0) >> 4) + '0';
93 else
94 *hex = ((*bin & 0xf0) >> 4) + 'A' - 10;
95 hex++;
97 if ((*bin & 0xf) < 10)
98 *hex = (*bin & 0xf) + '0';
99 else
100 *hex = (*bin & 0xf) + 'A' - 10;
101 hex++;
102 bin++;
104 *hex = 0;
108 main (int argc, char *argv[])
110 struct arguments arguments = {
111 .count = 10000,
112 .buflen = 64,
113 .saltlen = 64
115 char *bufhex, *salthex, *result;
116 gcry_err_code_t gcry_err;
117 grub_uint8_t *buf, *salt;
118 char pass1[GRUB_AUTH_MAX_PASSLEN];
119 char pass2[GRUB_AUTH_MAX_PASSLEN];
121 set_program_name (argv[0]);
123 grub_util_init_nls ();
125 /* Check for options. */
126 if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
128 fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
129 exit(1);
132 bufhex = xmalloc (arguments.buflen * 2 + 1);
133 buf = xmalloc (arguments.buflen);
134 salt = xmalloc (arguments.saltlen);
135 salthex = xmalloc (arguments.saltlen * 2 + 1);
137 printf ("%s", _("Enter password: "));
138 if (!grub_password_get (pass1, GRUB_AUTH_MAX_PASSLEN))
140 free (buf);
141 free (bufhex);
142 free (salthex);
143 free (salt);
144 grub_util_error ("%s", _("failure to read password"));
146 printf ("\n%s", _("Reenter password: "));
147 if (!grub_password_get (pass2, GRUB_AUTH_MAX_PASSLEN))
149 free (buf);
150 free (bufhex);
151 free (salthex);
152 free (salt);
153 grub_util_error ("%s", _("failure to read password"));
156 if (strcmp (pass1, pass2) != 0)
158 memset (pass1, 0, sizeof (pass1));
159 memset (pass2, 0, sizeof (pass2));
160 free (buf);
161 free (bufhex);
162 free (salthex);
163 free (salt);
164 grub_util_error ("%s", _("passwords don't match"));
166 memset (pass2, 0, sizeof (pass2));
168 #if ! defined (__linux__) && ! defined (__FreeBSD__)
169 /* TRANSLATORS: The generator might still be secure just GRUB isn't sure about it. */
170 printf ("%s", _("WARNING: your random generator isn't known to be secure\n"));
171 #endif
174 FILE *f;
175 size_t rd;
176 f = fopen ("/dev/urandom", "rb");
177 if (!f)
179 memset (pass1, 0, sizeof (pass1));
180 free (buf);
181 free (bufhex);
182 free (salthex);
183 free (salt);
184 fclose (f);
185 grub_util_error ("%s", _("couldn't retrieve random data for salt"));
187 rd = fread (salt, 1, arguments.saltlen, f);
188 if (rd != arguments.saltlen)
190 fclose (f);
191 memset (pass1, 0, sizeof (pass1));
192 free (buf);
193 free (bufhex);
194 free (salthex);
195 free (salt);
196 grub_util_error ("%s", _("couldn't retrieve random data for salt"));
198 fclose (f);
201 gcry_err = grub_crypto_pbkdf2 (GRUB_MD_SHA512,
202 (grub_uint8_t *) pass1, strlen (pass1),
203 salt, arguments.saltlen,
204 arguments.count, buf, arguments.buflen);
205 memset (pass1, 0, sizeof (pass1));
207 if (gcry_err)
209 memset (buf, 0, arguments.buflen);
210 memset (bufhex, 0, 2 * arguments.buflen);
211 free (buf);
212 free (bufhex);
213 memset (salt, 0, arguments.saltlen);
214 memset (salthex, 0, 2 * arguments.saltlen);
215 free (salt);
216 free (salthex);
217 grub_util_error (_("cryptographic error number %d"), gcry_err);
220 hexify (bufhex, buf, arguments.buflen);
221 hexify (salthex, salt, arguments.saltlen);
223 result = xmalloc (sizeof ("grub.pbkdf2.sha512.XXXXXXXXXXXXXXXXXXX.S.S")
224 + arguments.buflen * 2 + arguments.saltlen * 2);
225 snprintf (result, sizeof ("grub.pbkdf2.sha512.XXXXXXXXXXXXXXXXXXX.S.S")
226 + arguments.buflen * 2 + arguments.saltlen * 2,
227 "grub.pbkdf2.sha512.%d.%s.%s",
228 arguments.count, salthex, bufhex);
230 printf (_("PBKDF2 hash of your password is %s\n"), result);
231 memset (buf, 0, arguments.buflen);
232 memset (bufhex, 0, 2 * arguments.buflen);
233 free (buf);
234 free (bufhex);
235 memset (salt, 0, arguments.saltlen);
236 memset (salthex, 0, 2 * arguments.saltlen);
237 free (salt);
238 free (salthex);
240 return 0;