2010-01-07 Vladimir Serbinenko <phcoder@gmail.com>

Merge crypto branch.

	* Makefile.in (pkglib_DATA):  Add crypto.lst.
	(crypto.lst): New target.
	* commands/hashsum.c: New file.
	* commands/password.c (check_password): Use grub_crypto_memcmp.
	* commands/password_pbkdf2.c: New file.
	* commands/xnu_uuid.c: Remove MD5. Use GRUB_MD_MD5.
	* conf/any-emu.rmk (grub_emu_SOURCES): Add lib/crypto.c,
	normal/crypto.c and lib/libgcrypt-grub/cipher/md5.c.
	(grub_emu_CFLAGS): Add -Wno-missing-field-initializers -Wno-error
	-I$(srcdir)/lib/libgcrypt_wrap.
	* conf/common.rmk (normal_mod_SOURCES): Add normal/crypto.c.
	(pkglib_MODULES): Add crypto.mod, hashsum.mod, pbkdf2.mod and
	password_pbkdf2.mod.
	(crypto_mod_SOURCES): New variable.
	(crypto_mod_CFLAGS): Likewise.
	(crypto_mod_LDFLAGS): Likewise.
	(hashsum_mod_SOURCES): New variable.
	(hashsum_mod_CFLAGS): Likewise.
	(hashsum_mod_LDFLAGS): Likewise.
	(pbkdf2_mod_SOURCES): New variable.
	(pbkdf2_mod_CFLAGS): Likewise.
	(pbkdf2_mod_LDFLAGS): Likewise.
	(password_pbkdf2_mod_SOURCES): New variable.
	(password_pbkdf2_mod_CFLAGS): Likewise.
	(password_pbkdf2_mod_LDFLAGS): Likewise.
	(bin_UTILITIES): Add grub-mkpasswd-pbkdf2.
	(grub_mkpasswd_pbkdf2_SOURCES): New variable.
	(grub_mkpasswd_pbkdf2_CFLAGS): Likewise.
	Include conf/gcry.rmk.
	* include/grub/auth.h: Rewritten.
	* include/grub/crypto.h: New file.
	* include/grub/disk.h (grub_disk_dev_id): Add GRUB_DISK_DEVICE_LUKS_ID.
	* include/grub/normal.h (read_crypto_list): New prototype.
	* lib/crypto.c: New file.
	* lib/libgcrypt_wrap/cipher_wrap.h: Likewise.
	* lib/pbkdf2.c: Likewise.
	* normal/auth.c (grub_auth_strcmp): Removed.
	(grub_iswordseparator): Likewise.
	(grub_auth_strword): Likewise.
	(is_authenticated): Use grub_strword.
	(grub_auth_check_authentication): Use grub_strcmp, grub_password_get
	and grub_strword. Pass entered password to authentication callback.
	* normal/crypto.c: New file.
	* normal/main.c: Call read_crypto_list.
	* util/grub-mkpasswd-pbkdf2.c: New file.
	* util/import_gcry.py: Generate crypto.lst. Add hash blocklen.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-01-07 01:13:01 +01:00
commit 607a3701db
21 changed files with 2086 additions and 414 deletions

View file

@ -36,58 +36,6 @@ struct grub_auth_user
struct grub_auth_user *users = NULL;
int
grub_auth_strcmp (const char *s1, const char *s2)
{
int ret;
grub_uint64_t end;
end = grub_get_time_ms () + 100;
ret = grub_strcmp (s1, s2);
/* This prevents an attacker from deriving information about the
password from the time it took to execute this function. */
while (grub_get_time_ms () < end);
return ret;
}
static int
grub_iswordseparator (int c)
{
return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&');
}
int
grub_auth_strword (const char *haystack, const char *needle)
{
const char *n_pos = needle;
int found = 0;
while (grub_iswordseparator (*haystack))
haystack++;
while (*haystack)
{
int ok = 1;
/* Crawl both the needle and the haystack word we're on. */
while(*haystack && !grub_iswordseparator (*haystack))
{
if (*haystack == *n_pos && ok)
n_pos++;
else
ok = 0;
haystack++;
}
if (ok)
found = 1;
}
return found;
}
grub_err_t
grub_auth_register_authentication (const char *user,
grub_auth_callback_t callback,
@ -194,8 +142,8 @@ is_authenticated (const char *userlist)
return 0;
name = ((struct grub_auth_user *) item)->name;
return (userlist && grub_auth_strword (userlist, name))
|| grub_auth_strword (superusers, name);
return (userlist && grub_strword (userlist, name))
|| grub_strword (superusers, name);
}
superusers = grub_env_get ("superusers");
@ -213,11 +161,12 @@ grub_auth_check_authentication (const char *userlist)
struct grub_auth_user *cur = NULL;
grub_err_t err;
static unsigned long punishment_delay = 1;
char entered[GRUB_AUTH_MAX_PASSLEN];
auto int hook (grub_list_t item);
int hook (grub_list_t item)
{
if (grub_auth_strcmp (login, ((struct grub_auth_user *) item)->name) == 0)
if (grub_strcmp (login, ((struct grub_auth_user *) item)->name) == 0)
cur = (struct grub_auth_user *) item;
return 0;
}
@ -242,22 +191,17 @@ grub_auth_check_authentication (const char *userlist)
0, 0, 0))
goto access_denied;
grub_printf ("Enter password: ");
if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN))
goto access_denied;
grub_list_iterate (GRUB_AS_LIST (users), hook);
if (!cur || ! cur->callback)
{
grub_list_iterate (GRUB_AS_LIST (users), hook_any);
goto access_denied;
/* No users present at all. */
if (!cur)
goto access_denied;
/* Display any of available authentication schemes. */
err = cur->callback (login, 0);
goto access_denied;
}
err = cur->callback (login, cur->arg);
err = cur->callback (login, entered, cur->arg);
if (is_authenticated (userlist))
{
punishment_delay = 1;

153
normal/crypto.c Normal file
View file

@ -0,0 +1,153 @@
/* crypto.c - support crypto autoload */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/dl.h>
#include <grub/mm.h>
#include <grub/env.h>
#include <grub/misc.h>
#include <grub/crypto.h>
#include <grub/normal.h>
struct load_spec
{
struct load_spec *next;
char *name;
char *modname;
};
struct load_spec *crypto_specs = NULL;
static void
grub_crypto_autoload (const char *name)
{
struct load_spec *cur;
grub_dl_t mod;
for (cur = crypto_specs; cur; cur = cur->next)
if (grub_strcasecmp (name, cur->name) == 0)
{
mod = grub_dl_load (cur->modname);
if (mod)
grub_dl_ref (mod);
grub_errno = GRUB_ERR_NONE;
}
}
static void
grub_crypto_spec_free (void)
{
struct load_spec *cur, *next;
for (cur = crypto_specs; cur; cur = next)
{
next = cur->next;
grub_free (cur->name);
grub_free (cur->modname);
grub_free (cur);
}
crypto_specs = NULL;
}
/* Read the file crypto.lst for auto-loading. */
void
read_crypto_list (void)
{
const char *prefix;
char *filename;
grub_file_t file;
char *buf = NULL;
prefix = grub_env_get ("prefix");
if (!prefix)
{
grub_errno = GRUB_ERR_NONE;
return;
}
filename = grub_malloc (grub_strlen (prefix) + sizeof ("/crypto.lst"));
if (!filename)
{
grub_errno = GRUB_ERR_NONE;
return;
}
grub_sprintf (filename, "%s/crypto.lst", prefix);
file = grub_file_open (filename);
if (!file)
{
grub_errno = GRUB_ERR_NONE;
return;
}
/* Override previous commands.lst. */
grub_crypto_spec_free ();
for (;; grub_free (buf))
{
char *p, *name;
struct load_spec *cur;
buf = grub_file_getline (file);
if (! buf)
break;
name = buf;
p = grub_strchr (name, ':');
if (! p)
continue;
*p = '\0';
while (*++p == ' ')
;
cur = grub_malloc (sizeof (*cur));
if (!cur)
{
grub_errno = GRUB_ERR_NONE;
continue;
}
cur->name = grub_strdup (name);
if (! name)
{
grub_errno = GRUB_ERR_NONE;
grub_free (cur);
continue;
}
cur->modname = grub_strdup (p);
if (! cur->modname)
{
grub_errno = GRUB_ERR_NONE;
grub_free (cur);
grub_free (cur->name);
continue;
}
cur->next = crypto_specs;
crypto_specs = cur;
}
grub_file_close (file);
grub_errno = GRUB_ERR_NONE;
grub_crypto_autoload_hook = grub_crypto_autoload;
}

View file

@ -428,6 +428,7 @@ grub_normal_execute (const char *config, int nested, int batch)
read_command_list ();
read_fs_list ();
read_handler_list ();
read_crypto_list ();
grub_command_execute ("parser.grub", 0, 0);
reader_nested = nested;