diff --git a/import_gcry.py b/import_gcry.py index 738c2c479..cc06142e6 100644 --- a/import_gcry.py +++ b/import_gcry.py @@ -33,6 +33,7 @@ for cipher_file in cipher_files: fw.write ("/* This file was automatically imported with \n") fw.write (" import_gcry.py. Please don't modify it */\n"); ciphernames = [] + mdnames = [] for line in f: m = re.match ("#include <.*>", line) if not m is None: @@ -49,9 +50,21 @@ for cipher_file in cipher_files: ciphername = line [len ("gcry_cipher_spec_t"):].strip () ciphername = re.match("[a-zA-Z0-9_]*",ciphername).group () ciphernames.append (ciphername) + m = re.match ("gcry_md_spec_t", line) + if isc and not m is None: + mdname = line [len ("gcry_md_spec_t"):].strip () + mdname = re.match("[a-zA-Z0-9_]*",mdname).group () + mdnames.append (mdname) fw.write (line) - if len (ciphernames) > 0: + if len (ciphernames) > 0 or len (mdnames) > 0: modname = cipher_file [0:len(cipher_file) - 2] + if re.match (".*-glue$", modname): + modfiles = "gcry/cipher/%s gcry/cipher/%s" \ + % (cipher_file, cipher_file.replace ("-glue.c", ".c")) + modname = modname.replace ("-glue", "") + else: + modfiles = "gcry/cipher/%s" % cipher_file + modname = "gcry_%s" % modname chmsg = "(GRUB_MOD_INIT(%s)): New function\n" % modname if nch: chlognew = "%s\n %s" % (chlognew, chmsg) @@ -64,6 +77,10 @@ for cipher_file in cipher_files: chmsg = "Register cipher %s" % ciphername chlognew = "%s\n %s" % (chlognew, chmsg) fw.write (" grub_cipher_register (&%s);\n" % ciphername) + for mdname in mdnames: + chmsg = "Register digest %s" % mdname + chlognew = "%s\n %s" % (chlognew, chmsg) + fw.write (" grub_md_register (&%s);\n" % mdname) fw.write ("}") chmsg = "(GRUB_MOD_FINI(%s)): New function\n" % modname chlognew = "%s\n %s" % (chlognew, chmsg) @@ -73,14 +90,18 @@ for cipher_file in cipher_files: chmsg = "Unregister cipher %s" % ciphername chlognew = "%s\n %s" % (chlognew, chmsg) fw.write (" grub_cipher_unregister (&%s);\n" % ciphername) + for mdname in mdnames: + chmsg = "Unregister MD %s" % mdname + chlognew = "%s\n %s" % (chlognew, chmsg) + fw.write (" grub_md_unregister (&%s);\n" % mdname) fw.write ("}\n") conf.write ("pkglib_MODULES += %s.mod\n" % modname) - conf.write ("%s_mod_SOURCES = gcry/cipher/%s\n" %\ - (modname, cipher_file)) + conf.write ("%s_mod_SOURCES = %s\n" %\ + (modname, modfiles)) conf.write ("%s_mod_CFLAGS = $(COMMON_CFLAGS) -Wno-missing-field-initializers -Wno-error\n" % modname) conf.write ("%s_mod_LDFLAGS = $(COMMON_LDFLAGS)\n\n" % modname) - elif isc: - print ("WARNING: c file isn't a module: %s" % cipher_file) + elif isc and cipher_file != "camellia.c": + print ("WARNING: C file isn't a module: %s" % cipher_file) f.close () fw.close () if nch: diff --git a/include/grub/crypto.h b/include/grub/crypto.h index ab482f467..bd236116d 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -123,6 +123,7 @@ typedef struct gcry_cipher_spec gcry_cipher_decrypt_t decrypt; gcry_cipher_stencrypt_t stencrypt; gcry_cipher_stdecrypt_t stdecrypt; + struct gcry_cipher_spec *next; } gcry_cipher_spec_t; /* Definition of a function used to report selftest failures. @@ -154,33 +155,75 @@ typedef struct cipher_extra_spec cipher_set_extra_info_t set_extra_info; } cipher_extra_spec_t; -/* (Forward declaration.) */ -struct gcry_md_context; +/* Type for the md_init function. */ +typedef void (*gcry_md_init_t) (void *c); -/* This object is used to hold a handle to a message digest object. - This structure is private - only to be used by the public gcry_md_* - macros. */ -typedef struct gcry_md_handle +/* Type for the md_write function. */ +typedef void (*gcry_md_write_t) (void *c, const void *buf, grub_size_t nbytes); + +/* Type for the md_final function. */ +typedef void (*gcry_md_final_t) (void *c); + +/* Type for the md_read function. */ +typedef unsigned char *(*gcry_md_read_t) (void *c); + +typedef struct gcry_md_oid_spec { - /* Actual context. */ - struct gcry_md_context *ctx; - - /* Buffer management. */ - int bufpos; - int bufsize; - unsigned char buf[1]; -} *gcry_md_hd_t; + const char *oidstring; +} gcry_md_oid_spec_t; - -struct grub_cipher +/* Module specification structure for message digests. */ +typedef struct gcry_md_spec { - struct grub_cipher *next; const char *name; -}; -typedef struct grub_cipher *grub_cipher_t; + unsigned char *asnoid; + int asnlen; + gcry_md_oid_spec_t *oids; + int mdlen; + gcry_md_init_t init; + gcry_md_write_t write; + gcry_md_final_t final; + gcry_md_read_t read; + grub_size_t contextsize; /* allocate this amount of context */ + struct gcry_md_spec *next; +} gcry_md_spec_t; + +extern gcry_cipher_spec_t *EXPORT_VAR (grub_ciphers); +extern gcry_md_spec_t *EXPORT_VAR (grub_digests); + +static inline void +grub_cipher_register (gcry_cipher_spec_t *cipher) +{ + cipher->next = grub_ciphers; + grub_ciphers = cipher; +} + +static inline void +grub_cipher_unregister (gcry_cipher_spec_t *cipher) +{ + gcry_cipher_spec_t **ciph; + for (ciph = &grub_ciphers; *ciph; ciph = &((*ciph)->next)) + if (*ciph == cipher) + *ciph = (*ciph)->next; +} + +static inline void +grub_md_register (gcry_md_spec_t *digest) +{ + digest->next = grub_digests; + grub_digests = digest; +} + +static inline void +grub_md_unregister (gcry_md_spec_t *cipher) +{ + gcry_md_spec_t **ciph; + for (ciph = &grub_digests; *ciph; ciph = &((*ciph)->next)) + if (*ciph == cipher) + *ciph = (*ciph)->next; +} + -extern grub_cipher_t EXPORT_VAR (grub_ciphers); void EXPORT_FUNC(grub_burn_stack) (grub_size_t size); - #endif diff --git a/include/grub/gcry_wrap.h b/include/grub/gcry_wrap.h index 6f415a2e5..37a1ee4d7 100644 --- a/include/grub/gcry_wrap.h +++ b/include/grub/gcry_wrap.h @@ -27,12 +27,45 @@ #define __GNU_LIBRARY__ +#define DIM ARRAY_SIZE + +typedef grub_uint64_t u64; typedef grub_uint32_t u32; typedef grub_uint16_t u16; typedef grub_uint8_t byte; typedef grub_size_t size_t; +#define U64_C(c) (c ## ULL) + #define _gcry_burn_stack grub_burn_stack #define log_error(fmt, args...) grub_dprintf ("crypto", fmt, ## args) + +#define PUBKEY_FLAG_NO_BLINDING (1 << 0) + +#define CIPHER_INFO_NO_WEAK_KEY 1 + +#define HAVE_U64_TYPEDEF 1 + +typedef union { + int a; + short b; + char c[1]; + long d; +#ifdef HAVE_U64_TYPEDEF + u64 e; +#endif + float f; + double g; +} PROPERLY_ALIGNED_TYPE; + +#define gcry_assert(x) grub_assert_real(__FILE__, __LINE__, x) + +static inline void +grub_assert_real (const char *file, int line, int cond) +{ + if (cond) + grub_fatal ("Assertion failed at %s:%d\n", file, line); +} + #endif diff --git a/kern/crypto.c b/kern/crypto.c index 7dd00c84d..83e2d96df 100644 --- a/kern/crypto.c +++ b/kern/crypto.c @@ -18,8 +18,10 @@ */ #include #include +#include -grub_cipher_t grub_ciphers; +gcry_cipher_spec_t *grub_ciphers = NULL; +gcry_md_spec_t *grub_digests = NULL; /* Based on libgcrypt-1.4.4/src/misc.c. */ void