]> git.proxmox.com Git - grub2.git/blame - util/grub-mkpasswd-pbkdf2.c
Put recheck back
[grub2.git] / util / grub-mkpasswd-pbkdf2.c
CommitLineData
0e3c54a5
VS
1/*
2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 1992-1999,2001,2003,2004,2005,2009 Free Software Foundation, Inc.
4 *
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.
9 *
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.
14 *
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/>.
17 */
18
1d12cf29
YB
19#include <config.h>
20
0e3c54a5
VS
21#include <grub/types.h>
22#include <grub/crypto.h>
2cb55e6f 23#include <grub/auth.h>
8c411768 24#include <grub/emu/misc.h>
0e3c54a5 25#include <grub/util/misc.h>
fd39f820 26#include <grub/i18n.h>
0e3c54a5
VS
27
28#include <unistd.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <getopt.h>
0e3c54a5 33
fd39f820 34#include "progname.h"
0e3c54a5 35
0e3c54a5
VS
36static struct option options[] =
37 {
38 {"iteration_count", required_argument, 0, 'c'},
39 {"buflen", required_argument, 0, 'l'},
40 {"saltlen", required_argument, 0, 's'},
41 {"help", no_argument, 0, 'h'},
42 {"version", no_argument, 0, 'V'},
43 };
44
45static void
46usage (int status)
47{
48 if (status)
10f0117b
VS
49 fprintf (stderr, _("Try `%s --help' for more information.\n"),
50 program_name);
0e3c54a5 51 else
10f0117b 52 printf (_("\
409ae1c9 53Usage: %s [OPTIONS]\n\
0e3c54a5
VS
54\nOptions:\n\
55 -c number, --iteration-count=number Number of PBKDF2 iterations\n\
56 -l number, --buflen=number Length of generated hash\n\
57 -s number, --salt=number Length of salt\n\
58\n\
10f0117b 59Report bugs to <%s>.\n"), program_name, PACKAGE_BUGREPORT);
0e3c54a5
VS
60
61 exit (status);
62}
63
64static void
65hexify (char *hex, grub_uint8_t *bin, grub_size_t n)
66{
67 while (n--)
68 {
69 if (((*bin & 0xf0) >> 4) < 10)
70 *hex = ((*bin & 0xf0) >> 4) + '0';
71 else
72 *hex = ((*bin & 0xf0) >> 4) + 'A' - 10;
73 hex++;
74
75 if ((*bin & 0xf) < 10)
76 *hex = (*bin & 0xf) + '0';
77 else
78 *hex = (*bin & 0xf) + 'A' - 10;
79 hex++;
80 bin++;
81 }
82 *hex = 0;
83}
84
85int
86main (int argc, char *argv[])
87{
db8fa1ad 88 unsigned int count = 10000, buflen = 64, saltlen = 64;
0e3c54a5
VS
89 char *bufhex, *salthex;
90 gcry_err_code_t gcry_err;
91 grub_uint8_t *buf, *salt;
92 ssize_t nr;
2cb55e6f
VS
93 char pass1[GRUB_AUTH_MAX_PASSLEN];
94 char pass2[GRUB_AUTH_MAX_PASSLEN];
0e3c54a5 95
fd39f820 96 set_program_name (argv[0]);
0b8a223c
VS
97
98 grub_util_init_nls ();
0e3c54a5
VS
99
100 /* Check for options. */
101 while (1)
102 {
103 int c = getopt_long (argc, argv, "c:l:s:hvV", options, 0);
104
105 if (c == -1)
106 break;
107
108 switch (c)
109 {
110 case 'c':
db8fa1ad 111 count = strtoul (optarg, NULL, 0);
0e3c54a5
VS
112 break;
113
114 case 'l':
115 buflen = strtoul (optarg, NULL, 0);
116 break;
117
118 case 's':
119 saltlen = strtoul (optarg, NULL, 0);
120 break;
121
122 case 'h':
123 usage (0);
124 return 0;
125
126 case 'V':
fd39f820 127 printf ("%s (%s) %s\n", program_name,
0e3c54a5
VS
128 PACKAGE_NAME, PACKAGE_VERSION);
129 return 0;
130
131 default:
132 usage (1);
133 return 1;
134 }
135 }
136
137 bufhex = malloc (buflen * 2 + 1);
138 if (!bufhex)
10f0117b 139 grub_util_error (_("out of memory"));
0e3c54a5
VS
140 buf = malloc (buflen);
141 if (!buf)
142 {
143 free (bufhex);
10f0117b 144 grub_util_error (_("out of memory"));
0e3c54a5
VS
145 }
146
147 salt = malloc (saltlen);
148 if (!salt)
149 {
150 free (bufhex);
151 free (buf);
10f0117b 152 grub_util_error (_("out of memory"));
0e3c54a5
VS
153 }
154 salthex = malloc (saltlen * 2 + 1);
155 if (!salthex)
156 {
157 free (salt);
158 free (bufhex);
159 free (buf);
10f0117b 160 grub_util_error (_("out of memory"));
0e3c54a5 161 }
0e3c54a5 162
10f0117b 163 printf ("%s", _("Enter password: "));
2cb55e6f 164 if (!grub_password_get (pass1, GRUB_AUTH_MAX_PASSLEN))
0e3c54a5
VS
165 {
166 free (buf);
167 free (bufhex);
168 free (salthex);
169 free (salt);
10f0117b 170 grub_util_error (_("failure to read password"));
0e3c54a5 171 }
10f0117b 172 printf ("\n%s", _("Reenter password: "));
2cb55e6f 173 if (!grub_password_get (pass2, GRUB_AUTH_MAX_PASSLEN))
0e3c54a5 174 {
0e3c54a5
VS
175 free (buf);
176 free (bufhex);
177 free (salthex);
178 free (salt);
10f0117b 179 grub_util_error (_("failure to read password"));
0e3c54a5 180 }
0e3c54a5
VS
181
182 if (strcmp (pass1, pass2) != 0)
183 {
2cb55e6f
VS
184 memset (pass1, 0, sizeof (pass1));
185 memset (pass2, 0, sizeof (pass2));
0e3c54a5
VS
186 free (buf);
187 free (bufhex);
188 free (salthex);
189 free (salt);
10f0117b 190 grub_util_error (_("passwords don't match"));
0e3c54a5 191 }
2cb55e6f 192 memset (pass2, 0, sizeof (pass2));
0e3c54a5
VS
193
194#if ! defined (__linux__) && ! defined (__FreeBSD__)
10f0117b 195 printf ("%s", _("WARNING: your random generator isn't known to be secure\n"));
0e3c54a5
VS
196#endif
197
198 {
199 FILE *f;
200 size_t rd;
7c515bee 201 f = fopen ("/dev/urandom", "rb");
0e3c54a5
VS
202 if (!f)
203 {
2cb55e6f 204 memset (pass1, 0, sizeof (pass1));
0e3c54a5
VS
205 free (buf);
206 free (bufhex);
207 free (salthex);
208 free (salt);
209 fclose (f);
10f0117b 210 grub_util_error (_("couldn't retrieve random data for salt"));
0e3c54a5
VS
211 }
212 rd = fread (salt, 1, saltlen, f);
213 if (rd != saltlen)
214 {
215 fclose (f);
2cb55e6f 216 memset (pass1, 0, sizeof (pass1));
0e3c54a5
VS
217 free (buf);
218 free (bufhex);
219 free (salthex);
220 free (salt);
10f0117b 221 grub_util_error (_("couldn't retrieve random data for salt"));
0e3c54a5
VS
222 }
223 fclose (f);
224 }
225
226 gcry_err = grub_crypto_pbkdf2 (GRUB_MD_SHA512,
227 (grub_uint8_t *) pass1, strlen (pass1),
228 salt, saltlen,
db8fa1ad 229 count, buf, buflen);
2cb55e6f 230 memset (pass1, 0, sizeof (pass1));
0e3c54a5
VS
231
232 if (gcry_err)
233 {
234 memset (buf, 0, buflen);
235 memset (bufhex, 0, 2 * buflen);
236 free (buf);
237 free (bufhex);
238 memset (salt, 0, saltlen);
239 memset (salthex, 0, 2 * saltlen);
240 free (salt);
241 free (salthex);
10f0117b 242 grub_util_error (_("cryptographic error number %d"), gcry_err);
0e3c54a5
VS
243 }
244
245 hexify (bufhex, buf, buflen);
246 hexify (salthex, salt, saltlen);
247
10f0117b 248 printf (_("Your PBKDF2 is grub.pbkdf2.sha512.%d.%s.%s\n"),
db8fa1ad 249 count, salthex, bufhex);
0e3c54a5
VS
250 memset (buf, 0, buflen);
251 memset (bufhex, 0, 2 * buflen);
252 free (buf);
253 free (bufhex);
254 memset (salt, 0, saltlen);
255 memset (salthex, 0, 2 * saltlen);
256 free (salt);
257 free (salthex);
258
259 return 0;
260}