2
* GRUB -- GRand Unified Bootloader
3
* Copyright (C) 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/auth.h>
20
#include <grub/crypto.h>
21
#include <grub/list.h>
23
#include <grub/misc.h>
25
#include <grub/normal.h>
27
#include <grub/i18n.h>
29
static grub_dl_t my_mod;
31
struct pbkdf2_password
36
grub_uint8_t *expected;
41
check_password (const char *user, const char *entered, void *pin)
44
struct pbkdf2_password *pass = pin;
47
buf = grub_malloc (pass->buflen);
49
return grub_crypto_gcry_error (GPG_ERR_OUT_OF_MEMORY);
51
err = grub_crypto_pbkdf2 (GRUB_MD_SHA512, (grub_uint8_t *) entered,
52
grub_strlen (entered),
53
pass->salt, pass->saltlen, pass->c,
58
return grub_crypto_gcry_error (err);
61
if (grub_crypto_memcmp (buf, pass->expected, pass->buflen) != 0)
62
return GRUB_ACCESS_DENIED;
64
grub_auth_authenticate (user);
72
if ('0' <= hex && hex <= '9')
74
if ('a' <= hex && hex <= 'f')
75
return hex - 'a' + 10;
76
if ('A' <= hex && hex <= 'F')
77
return hex - 'A' + 10;
82
grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
83
int argc, char **args)
88
struct pbkdf2_password *pass;
91
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Two arguments expected.");
93
if (grub_memcmp (args[1], "grub.pbkdf2.sha512.",
94
sizeof ("grub.pbkdf2.sha512.") - 1) != 0)
95
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Incorrect PBKDF2 password.");
97
ptr = args[1] + sizeof ("grub.pbkdf2.sha512.") - 1;
99
pass = grub_malloc (sizeof (*pass));
103
pass->c = grub_strtoul (ptr, &ptr, 0);
107
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Incorrect PBKDF2 password.");
111
ptr2 = grub_strchr (ptr, '.');
112
if (!ptr2 || ((ptr2 - ptr) & 1) || grub_strlen (ptr2 + 1) & 1)
115
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Incorrect PBKDF2 password.");
118
pass->saltlen = (ptr2 - ptr) >> 1;
119
pass->buflen = grub_strlen (ptr2 + 1) >> 1;
120
ptro = pass->salt = grub_malloc (pass->saltlen);
129
hex1 = hex2val (*ptr);
131
hex2 = hex2val (*ptr);
133
if (hex1 < 0 || hex2 < 0)
135
grub_free (pass->salt);
137
return grub_error (GRUB_ERR_BAD_ARGUMENT,
138
"Incorrect PBKDF2 password.");
141
*ptro = (hex1 << 4) | hex2;
145
ptro = pass->expected = grub_malloc (pass->buflen);
148
grub_free (pass->salt);
153
ptr2 += grub_strlen (ptr2);
157
hex1 = hex2val (*ptr);
159
hex2 = hex2val (*ptr);
161
if (hex1 < 0 || hex2 < 0)
163
grub_free (pass->expected);
164
grub_free (pass->salt);
166
return grub_error (GRUB_ERR_BAD_ARGUMENT,
167
"Incorrect PBKDF2 password.");
170
*ptro = (hex1 << 4) | hex2;
174
err = grub_auth_register_authentication (args[0], check_password, pass);
180
grub_dl_ref (my_mod);
181
return GRUB_ERR_NONE;
184
static grub_command_t cmd;
186
GRUB_MOD_INIT(password_pbkdf2)
189
cmd = grub_register_command ("password_pbkdf2", grub_cmd_password,
190
N_("USER PBKDF2_PASSWORD"),
191
N_("Set user password (PBKDF2). "));
194
GRUB_MOD_FINI(password_pbkdf2)
196
grub_unregister_command (cmd);