Crypto module autoloading
This commit is contained in:
parent
ba136b293a
commit
7316783f35
9 changed files with 230 additions and 21 deletions
|
@ -169,7 +169,7 @@ endif
|
||||||
### General targets.
|
### General targets.
|
||||||
|
|
||||||
CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA) po/*.mo
|
CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA) po/*.mo
|
||||||
pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst
|
pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst
|
||||||
moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep.awk
|
moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep.awk
|
||||||
cat $(DEFSYMFILES) /dev/null \
|
cat $(DEFSYMFILES) /dev/null \
|
||||||
| $(AWK) -f $(srcdir)/genmoddep.awk $(UNDSYMFILES) > $@ \
|
| $(AWK) -f $(srcdir)/genmoddep.awk $(UNDSYMFILES) > $@ \
|
||||||
|
@ -193,6 +193,9 @@ parttool.lst: $(PARTTOOLFILES)
|
||||||
video.lst: $(VIDEOFILES)
|
video.lst: $(VIDEOFILES)
|
||||||
cat $^ /dev/null | sort | uniq > $@
|
cat $^ /dev/null | sort | uniq > $@
|
||||||
|
|
||||||
|
crypto.lst: lib/libgcrypt-grub/cipher/crypto.lst
|
||||||
|
cp $^ $@
|
||||||
|
|
||||||
ifneq (true, $(MAKEINFO))
|
ifneq (true, $(MAKEINFO))
|
||||||
info_INFOS += docs/grub.info
|
info_INFOS += docs/grub.info
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -27,7 +27,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
|
||||||
normal/handler.c normal/auth.c lib/crypto.c normal/autofs.c \
|
normal/handler.c normal/auth.c lib/crypto.c normal/autofs.c \
|
||||||
normal/completion.c normal/main.c normal/color.c \
|
normal/completion.c normal/main.c normal/color.c \
|
||||||
normal/menu.c normal/menu_entry.c normal/menu_viewer.c \
|
normal/menu.c normal/menu_entry.c normal/menu_viewer.c \
|
||||||
normal/menu_text.c \
|
normal/menu_text.c normal/crypto.c \
|
||||||
script/main.c script/execute.c script/function.c \
|
script/main.c script/execute.c script/function.c \
|
||||||
script/lexer.c script/script.c grub_script.tab.c \
|
script/lexer.c script/script.c grub_script.tab.c \
|
||||||
partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.c \
|
partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.c \
|
||||||
|
|
|
@ -543,7 +543,7 @@ normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
|
||||||
normal/auth.c normal/autofs.c normal/handler.c \
|
normal/auth.c normal/autofs.c normal/handler.c \
|
||||||
normal/color.c normal/completion.c normal/datetime.c normal/menu.c \
|
normal/color.c normal/completion.c normal/datetime.c normal/menu.c \
|
||||||
normal/menu_entry.c normal/menu_text.c normal/menu_viewer.c \
|
normal/menu_entry.c normal/menu_text.c normal/menu_viewer.c \
|
||||||
normal/misc.c
|
normal/misc.c normal/crypto.c
|
||||||
normal_mod_CFLAGS = $(COMMON_CFLAGS)
|
normal_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||||
normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
||||||
|
|
||||||
|
|
|
@ -270,4 +270,6 @@ grub_password_get (char buf[], unsigned buf_size);
|
||||||
/* For indistinguishibility. */
|
/* For indistinguishibility. */
|
||||||
#define GRUB_ACCESS_DENIED grub_error (GRUB_ERR_ACCESS_DENIED, "Access denied.")
|
#define GRUB_ACCESS_DENIED grub_error (GRUB_ERR_ACCESS_DENIED, "Access denied.")
|
||||||
|
|
||||||
|
extern void (*grub_crypto_autoload_hook) (const char *name);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -95,6 +95,8 @@ void read_command_list (void);
|
||||||
/* Defined in `autofs.c'. */
|
/* Defined in `autofs.c'. */
|
||||||
void read_fs_list (void);
|
void read_fs_list (void);
|
||||||
|
|
||||||
|
void read_crypto_list (void);
|
||||||
|
|
||||||
|
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
void grub_normal_init (void);
|
void grub_normal_init (void);
|
||||||
|
|
46
lib/crypto.c
46
lib/crypto.c
|
@ -32,6 +32,8 @@ struct grub_crypto_hmac_handle
|
||||||
static gcry_cipher_spec_t *grub_ciphers = NULL;
|
static gcry_cipher_spec_t *grub_ciphers = NULL;
|
||||||
static gcry_md_spec_t *grub_digests = NULL;
|
static gcry_md_spec_t *grub_digests = NULL;
|
||||||
|
|
||||||
|
void (*grub_crypto_autoload_hook) (const char *name) = NULL;
|
||||||
|
|
||||||
/* Based on libgcrypt-1.4.4/src/misc.c. */
|
/* Based on libgcrypt-1.4.4/src/misc.c. */
|
||||||
void
|
void
|
||||||
grub_burn_stack (grub_size_t size)
|
grub_burn_stack (grub_size_t size)
|
||||||
|
@ -91,28 +93,44 @@ const gcry_md_spec_t *
|
||||||
grub_crypto_lookup_md_by_name (const char *name)
|
grub_crypto_lookup_md_by_name (const char *name)
|
||||||
{
|
{
|
||||||
const gcry_md_spec_t *md;
|
const gcry_md_spec_t *md;
|
||||||
for (md = grub_digests; md; md = md->next)
|
int first = 1;
|
||||||
if (grub_strcasecmp (name, md->name) == 0)
|
while (1)
|
||||||
return md;
|
{
|
||||||
return NULL;
|
for (md = grub_digests; md; md = md->next)
|
||||||
|
if (grub_strcasecmp (name, md->name) == 0)
|
||||||
|
return md;
|
||||||
|
if (grub_crypto_autoload_hook && first)
|
||||||
|
grub_crypto_autoload_hook (name);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
first = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const gcry_cipher_spec_t *
|
const gcry_cipher_spec_t *
|
||||||
grub_crypto_lookup_cipher_by_name (const char *name)
|
grub_crypto_lookup_cipher_by_name (const char *name)
|
||||||
{
|
{
|
||||||
const gcry_cipher_spec_t *ciph;
|
const gcry_cipher_spec_t *ciph;
|
||||||
for (ciph = grub_ciphers; ciph; ciph = ciph->next)
|
int first = 1;
|
||||||
|
while (1)
|
||||||
{
|
{
|
||||||
const char **alias;
|
for (ciph = grub_ciphers; ciph; ciph = ciph->next)
|
||||||
if (grub_strcasecmp (name, ciph->name) == 0)
|
{
|
||||||
return ciph;
|
const char **alias;
|
||||||
if (!ciph->aliases)
|
if (grub_strcasecmp (name, ciph->name) == 0)
|
||||||
continue;
|
return ciph;
|
||||||
for (alias = ciph->aliases; *alias; alias++)
|
if (!ciph->aliases)
|
||||||
if (grub_strcasecmp (name, *alias) == 0)
|
continue;
|
||||||
return ciph;
|
for (alias = ciph->aliases; *alias; alias++)
|
||||||
|
if (grub_strcasecmp (name, *alias) == 0)
|
||||||
|
return ciph;
|
||||||
|
}
|
||||||
|
if (grub_crypto_autoload_hook && first)
|
||||||
|
grub_crypto_autoload_hook (name);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
first = 0;
|
||||||
}
|
}
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
153
normal/crypto.c
Normal file
153
normal/crypto.c
Normal 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;
|
||||||
|
}
|
|
@ -428,6 +428,7 @@ grub_normal_execute (const char *config, int nested, int batch)
|
||||||
read_command_list ();
|
read_command_list ();
|
||||||
read_fs_list ();
|
read_fs_list ();
|
||||||
read_handler_list ();
|
read_handler_list ();
|
||||||
|
read_crypto_list ();
|
||||||
grub_command_execute ("parser.grub", 0, 0);
|
grub_command_execute ("parser.grub", 0, 0);
|
||||||
|
|
||||||
reader_nested = nested;
|
reader_nested = nested;
|
||||||
|
|
|
@ -61,6 +61,18 @@ mdblocksizes = {"_gcry_digest_spec_crc32" : 64,
|
||||||
"_gcry_digest_spec_tiger" : 64,
|
"_gcry_digest_spec_tiger" : 64,
|
||||||
"_gcry_digest_spec_whirlpool" : 64}
|
"_gcry_digest_spec_whirlpool" : 64}
|
||||||
|
|
||||||
|
cryptolist = open (os.path.join (cipher_dir_out, "crypto.lst"), "w")
|
||||||
|
|
||||||
|
# rijndael is the only cipher using aliases. So no need for mangling, just
|
||||||
|
# hardcode it
|
||||||
|
cryptolist.write ("RIJNDAEL: gcry_rijndael\n");
|
||||||
|
cryptolist.write ("RIJNDAEL192: gcry_rijndael\n");
|
||||||
|
cryptolist.write ("RIJNDAEL256: gcry_rijndael\n");
|
||||||
|
cryptolist.write ("AES128: gcry_rijndael\n");
|
||||||
|
cryptolist.write ("AES-128: gcry_rijndael\n");
|
||||||
|
cryptolist.write ("AES-192: gcry_rijndael\n");
|
||||||
|
cryptolist.write ("AES-256: gcry_rijndael\n");
|
||||||
|
|
||||||
for cipher_file in cipher_files:
|
for cipher_file in cipher_files:
|
||||||
infile = os.path.join (cipher_dir_in, cipher_file)
|
infile = os.path.join (cipher_dir_in, cipher_file)
|
||||||
outfile = os.path.join (cipher_dir_out, cipher_file)
|
outfile = os.path.join (cipher_dir_out, cipher_file)
|
||||||
|
@ -86,7 +98,15 @@ for cipher_file in cipher_files:
|
||||||
skip = False
|
skip = False
|
||||||
skip2 = False
|
skip2 = False
|
||||||
ismd = False
|
ismd = False
|
||||||
|
iscryptostart = False
|
||||||
iscomma = False
|
iscomma = False
|
||||||
|
isglue = False
|
||||||
|
if isc:
|
||||||
|
modname = cipher_file [0:len(cipher_file) - 2]
|
||||||
|
if re.match (".*-glue$", modname):
|
||||||
|
modname = modname.replace ("-glue", "")
|
||||||
|
isglue = True
|
||||||
|
modname = "gcry_%s" % modname
|
||||||
for line in f:
|
for line in f:
|
||||||
if skip:
|
if skip:
|
||||||
if line[0] == "}":
|
if line[0] == "}":
|
||||||
|
@ -96,6 +116,12 @@ for cipher_file in cipher_files:
|
||||||
if not re.search (" *};", line) is None:
|
if not re.search (" *};", line) is None:
|
||||||
skip2 = False
|
skip2 = False
|
||||||
continue
|
continue
|
||||||
|
if iscryptostart:
|
||||||
|
s = re.search (" *\"([A-Z0-9_a-z]*)\"", line)
|
||||||
|
if not s is None:
|
||||||
|
sg = s.groups()[0]
|
||||||
|
cryptolist.write (("%s: %s\n") % (sg, modname))
|
||||||
|
iscryptostart = False
|
||||||
if ismd:
|
if ismd:
|
||||||
if not re.search (" *};", line) is None:
|
if not re.search (" *};", line) is None:
|
||||||
if not mdblocksizes.has_key (mdname):
|
if not mdblocksizes.has_key (mdname):
|
||||||
|
@ -133,16 +159,20 @@ for cipher_file in cipher_files:
|
||||||
continue
|
continue
|
||||||
m = re.match ("gcry_cipher_spec_t", line)
|
m = re.match ("gcry_cipher_spec_t", line)
|
||||||
if isc and not m is None:
|
if isc and not m is None:
|
||||||
|
assert (not iscryptostart)
|
||||||
ciphername = line [len ("gcry_cipher_spec_t"):].strip ()
|
ciphername = line [len ("gcry_cipher_spec_t"):].strip ()
|
||||||
ciphername = re.match("[a-zA-Z0-9_]*",ciphername).group ()
|
ciphername = re.match("[a-zA-Z0-9_]*",ciphername).group ()
|
||||||
ciphernames.append (ciphername)
|
ciphernames.append (ciphername)
|
||||||
|
iscryptostart = True
|
||||||
m = re.match ("gcry_md_spec_t", line)
|
m = re.match ("gcry_md_spec_t", line)
|
||||||
if isc and not m is None:
|
if isc and not m is None:
|
||||||
assert (not ismd)
|
assert (not ismd)
|
||||||
|
assert (not iscryptostart)
|
||||||
mdname = line [len ("gcry_md_spec_t"):].strip ()
|
mdname = line [len ("gcry_md_spec_t"):].strip ()
|
||||||
mdname = re.match("[a-zA-Z0-9_]*",mdname).group ()
|
mdname = re.match("[a-zA-Z0-9_]*",mdname).group ()
|
||||||
mdnames.append (mdname)
|
mdnames.append (mdname)
|
||||||
ismd = True
|
ismd = True
|
||||||
|
iscryptostart = True
|
||||||
m = re.match ("static const char \*selftest.*;$", line)
|
m = re.match ("static const char \*selftest.*;$", line)
|
||||||
if not m is None:
|
if not m is None:
|
||||||
fname = line[len ("static const char \*"):]
|
fname = line[len ("static const char \*"):]
|
||||||
|
@ -185,14 +215,11 @@ for cipher_file in cipher_files:
|
||||||
continue
|
continue
|
||||||
fw.write (line)
|
fw.write (line)
|
||||||
if len (ciphernames) > 0 or len (mdnames) > 0:
|
if len (ciphernames) > 0 or len (mdnames) > 0:
|
||||||
modname = cipher_file [0:len(cipher_file) - 2]
|
if isglue:
|
||||||
if re.match (".*-glue$", modname):
|
|
||||||
modfiles = "lib/libgcrypt-grub/cipher/%s lib/libgcrypt-grub/cipher/%s" \
|
modfiles = "lib/libgcrypt-grub/cipher/%s lib/libgcrypt-grub/cipher/%s" \
|
||||||
% (cipher_file, cipher_file.replace ("-glue.c", ".c"))
|
% (cipher_file, cipher_file.replace ("-glue.c", ".c"))
|
||||||
modname = modname.replace ("-glue", "")
|
|
||||||
else:
|
else:
|
||||||
modfiles = "lib/libgcrypt-grub/cipher/%s" % cipher_file
|
modfiles = "lib/libgcrypt-grub/cipher/%s" % cipher_file
|
||||||
modname = "gcry_%s" % modname
|
|
||||||
chmsg = "(GRUB_MOD_INIT(%s)): New function\n" % modname
|
chmsg = "(GRUB_MOD_INIT(%s)): New function\n" % modname
|
||||||
if nch:
|
if nch:
|
||||||
chlognew = "%s\n %s" % (chlognew, chmsg)
|
chlognew = "%s\n %s" % (chlognew, chmsg)
|
||||||
|
@ -238,6 +265,9 @@ for cipher_file in cipher_files:
|
||||||
chlog = "%s%sSkipped unknown file\n" % (chlog, chlognew)
|
chlog = "%s%sSkipped unknown file\n" % (chlog, chlognew)
|
||||||
print ("WARNING: unknown file %s" % cipher_file)
|
print ("WARNING: unknown file %s" % cipher_file)
|
||||||
|
|
||||||
|
cryptolist.close ()
|
||||||
|
chlog = "%s * crypto.lst: New file.\n" % chlog
|
||||||
|
|
||||||
outfile = os.path.join (cipher_dir_out, "types.h")
|
outfile = os.path.join (cipher_dir_out, "types.h")
|
||||||
fw=open (outfile, "w")
|
fw=open (outfile, "w")
|
||||||
fw.write ("#include <grub/types.h>\n")
|
fw.write ("#include <grub/types.h>\n")
|
||||||
|
|
Loading…
Reference in a new issue