]>
Commit | Line | Data |
---|---|---|
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 |
36 | static 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 | ||
45 | static void | |
46 | usage (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 | 53 | Usage: %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 | 59 | Report bugs to <%s>.\n"), program_name, PACKAGE_BUGREPORT); |
0e3c54a5 VS |
60 | |
61 | exit (status); | |
62 | } | |
63 | ||
64 | static void | |
65 | hexify (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 | ||
85 | int | |
86 | main (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 | } |