]>
git.proxmox.com Git - grub2.git/blob - commands/password_pbkdf2.c
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>
28 static grub_dl_t my_mod
;
30 struct pbkdf2_password
35 grub_uint8_t
*expected
;
40 check_password (const char *user
, const char *entered
, void *pin
)
43 struct pbkdf2_password
*pass
= pin
;
46 buf
= grub_malloc (pass
->buflen
);
48 return grub_crypto_gcry_error (GPG_ERR_OUT_OF_MEMORY
);
50 err
= grub_crypto_pbkdf2 (GRUB_MD_SHA512
, (grub_uint8_t
*) entered
,
51 grub_strlen (entered
),
52 pass
->salt
, pass
->saltlen
, pass
->c
,
57 return grub_crypto_gcry_error (err
);
60 if (grub_crypto_memcmp (buf
, pass
->expected
, pass
->buflen
) != 0)
61 return GRUB_ACCESS_DENIED
;
63 grub_auth_authenticate (user
);
71 if ('0' <= hex
&& hex
<= '9')
73 if ('a' <= hex
&& hex
<= 'f')
74 return hex
- 'a' + 10;
75 if ('A' <= hex
&& hex
<= 'F')
76 return hex
- 'A' + 10;
81 grub_cmd_password (grub_command_t cmd
__attribute__ ((unused
)),
82 int argc
, char **args
)
87 struct pbkdf2_password
*pass
;
90 return grub_error (GRUB_ERR_BAD_ARGUMENT
, "Two arguments expected.");
92 if (grub_memcmp (args
[1], "grub.pbkdf2.sha512.",
93 sizeof ("grub.pbkdf2.sha512.") - 1) != 0)
94 return grub_error (GRUB_ERR_BAD_ARGUMENT
, "Incorrect PBKDF2 password.");
96 ptr
= args
[1] + sizeof ("grub.pbkdf2.sha512.") - 1;
98 pass
= grub_malloc (sizeof (*pass
));
102 pass
->c
= grub_strtoul (ptr
, &ptr
, 0);
106 return grub_error (GRUB_ERR_BAD_ARGUMENT
, "Incorrect PBKDF2 password.");
110 ptr2
= grub_strchr (ptr
, '.');
111 if (!ptr2
|| ((ptr2
- ptr
) & 1) || grub_strlen (ptr2
+ 1) & 1)
114 return grub_error (GRUB_ERR_BAD_ARGUMENT
, "Incorrect PBKDF2 password.");
117 pass
->saltlen
= (ptr2
- ptr
) >> 1;
118 pass
->buflen
= grub_strlen (ptr2
+ 1) >> 1;
119 ptro
= pass
->salt
= grub_malloc (pass
->saltlen
);
128 hex1
= hex2val (*ptr
);
130 hex2
= hex2val (*ptr
);
132 if (hex1
< 0 || hex2
< 0)
134 grub_free (pass
->salt
);
136 return grub_error (GRUB_ERR_BAD_ARGUMENT
,
137 "Incorrect PBKDF2 password.");
140 *ptro
= (hex1
<< 4) | hex2
;
144 ptro
= pass
->expected
= grub_malloc (pass
->buflen
);
147 grub_free (pass
->salt
);
152 ptr2
+= grub_strlen (ptr2
);
156 hex1
= hex2val (*ptr
);
158 hex2
= hex2val (*ptr
);
160 if (hex1
< 0 || hex2
< 0)
162 grub_free (pass
->expected
);
163 grub_free (pass
->salt
);
165 return grub_error (GRUB_ERR_BAD_ARGUMENT
,
166 "Incorrect PBKDF2 password.");
169 *ptro
= (hex1
<< 4) | hex2
;
173 err
= grub_auth_register_authentication (args
[0], check_password
, pass
);
179 grub_dl_ref (my_mod
);
180 return GRUB_ERR_NONE
;
183 static grub_command_t cmd
;
185 GRUB_MOD_INIT(password_pbkdf2
)
188 cmd
= grub_register_command ("password_pbkdf2", grub_cmd_password
,
189 "password_pbkdf2 USER PBKDF2_PASSWORD",
190 "Set user password (PBKDF2). ");
193 GRUB_MOD_FINI(password_pbkdf2
)
195 grub_unregister_command (cmd
);