]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Created crypto module. Moved some functions to it.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 12 Nov 2009 21:40:14 +0000 (22:40 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 12 Nov 2009 21:40:14 +0000 (22:40 +0100)
conf/common.rmk
conf/i386-pc.rmk
include/grub/crypto.h
lib/crypto.c [new file with mode: 0644]

index 0d19344a7727e1dccd4176340a7af324620e2fe5..35b4620f4b390646187972aa047617e57b3b58ea 100644 (file)
@@ -619,4 +619,9 @@ setjmp_mod_SOURCES = lib/$(target_cpu)/setjmp.S
 setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS)
 setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+pkglib_MODULES += crypto.mod
+crypto_mod_SOURCES = lib/crypto.c
+crypto_mod_CFLAGS = $(COMMON_CFLAGS)
+crypto_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 include $(srcdir)/conf/gcry.mk
index 45e1ccf91bab7d3a0b42ab4688bea4a2ecd503fa..ac9337e4187db94775a073257b15ec4560d827cb 100644 (file)
@@ -58,15 +58,13 @@ kernel_img_SOURCES = kern/i386/pc/startup.S \
        kern/generic/millisleep.c \
        kern/env.c \
        term/i386/pc/console.c term/i386/vga_common.c \
-       kern/crypto.c \
        symlist.c
 kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
        env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
        partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \
        machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
        machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \
-       machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h \
-       crypto.h
+       machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h
 kernel_img_CFLAGS = $(COMMON_CFLAGS)  $(TARGET_IMG_CFLAGS)
 kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
 kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
index 239b46666e807cbb1e8e0478d51f299b10cfe4bb..5cd7f02b48d6be641e97b9ce9288b57ae5452a14 100644 (file)
@@ -164,205 +164,58 @@ typedef struct gcry_md_spec
   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;
-}
-
-static inline void
-grub_crypto_hash (const gcry_md_spec_t *hash, void *out, void *in,
-                 grub_size_t inlen)
-{
-  grub_uint8_t ctx[hash->contextsize];
-  hash->init (&ctx);
-  hash->write (&ctx, in, inlen);
-  hash->final (&ctx);
-  grub_memcpy (out, hash->read (&ctx), hash->mdlen);
-}
-
-static inline const gcry_md_spec_t *
-grub_crypto_lookup_md_by_name (const char *name)
-{
-  const gcry_md_spec_t *md;
-  for (md = grub_digests; md; md = md->next)
-    if (grub_strcasecmp (name, md->name) == 0)
-      return md;
-  return NULL;
-}
-
 typedef struct grub_crypto_cipher_handle
 {
   const struct gcry_cipher_spec *cipher;
   char ctx[0];
 } *grub_crypto_cipher_handle_t;
 
-static inline const gcry_cipher_spec_t *
-grub_crypto_lookup_cipher_by_name (const char *name)
-{
-  const gcry_cipher_spec_t *ciph;
-  for (ciph = grub_ciphers; ciph; ciph = ciph->next)
-    {
-      const char **alias;
-      if (grub_strcasecmp (name, ciph->name) == 0)
-       return ciph;
-      if (!ciph->aliases)
-       continue;
-      for (alias = ciph->aliases; *alias; alias++)
-       if (grub_strcasecmp (name, *alias) == 0)
-         return ciph;
-    }
-  return NULL;
-}
+const gcry_cipher_spec_t *
+grub_crypto_lookup_cipher_by_name (const char *name);
 
+grub_crypto_cipher_handle_t
+grub_crypto_cipher_open (const struct gcry_cipher_spec *cipher);
 
-static inline grub_crypto_cipher_handle_t
-grub_crypto_cipher_open (const struct gcry_cipher_spec *cipher)
-{
-  grub_crypto_cipher_handle_t ret;
-  ret = grub_malloc (sizeof (*ret) + cipher->contextsize);
-  if (!ret)
-    return NULL;
-  ret->cipher = cipher;
-  return ret;
-}
-
-static inline gcry_err_code_t
+gcry_err_code_t
 grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher,
                            const unsigned char *key,
-                           unsigned keylen)
-{
-  return cipher->cipher->setkey (cipher->ctx, key, keylen);
-}
-
-
-static inline void
-grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher)
-{
-  grub_free (cipher);
-}
-
+                           unsigned keylen);
 
-static inline void
-grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size)
-{
-  const grub_uint8_t *in1ptr = in1, *in2ptr = in2;
-  grub_uint8_t *outptr = out;
-  while (size--)
-    {
-      *outptr = *in1ptr ^ *in2ptr;
-      in1ptr++;
-      in2ptr++;
-      outptr++;
-    }
-}
+void
+grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher);
 
-static inline grub_err_t
+void
+grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size);
+grub_err_t
 grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher,
-                        void *out, void *in, grub_size_t size)
-{
-  grub_uint8_t *inptr, *outptr, *end;
-  if (size % cipher->cipher->blocksize != 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, 
-                      "This encryption can't decrypt partial blocks");
-  end = (grub_uint8_t *) in + size;
-  for (inptr = in, outptr = out; inptr < end;
-       inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
-    cipher->cipher->decrypt (cipher->ctx, outptr, inptr);
-  return GRUB_ERR_NONE;
-}
+                        void *out, void *in, grub_size_t size);
 
-static inline grub_err_t
+grub_err_t
 grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher,
-                        void *out, void *in, grub_size_t size)
-{
-  grub_uint8_t *inptr, *outptr, *end;
-  if (size % cipher->cipher->blocksize != 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, 
-                      "This encryption can't decrypt partial blocks");
-  end = (grub_uint8_t *) in + size;
-  for (inptr = in, outptr = out; inptr < end;
-       inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
-    cipher->cipher->encrypt (cipher->ctx, outptr, inptr);
-  return GRUB_ERR_NONE;
-}
-
-static inline grub_err_t
+                        void *out, void *in, grub_size_t size);
+grub_err_t
 grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher,
                         void *out, void *in, grub_size_t size,
-                        void *iv_in)
-{
-  grub_uint8_t *inptr, *outptr, *end;
-  void *iv;
-  if (size % cipher->cipher->blocksize != 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, 
-                      "This encryption can't decrypt partial blocks");
-  end = (grub_uint8_t *) in + size;
-  iv = iv_in;
-  for (inptr = in, outptr = out; inptr < end;
-       inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
-    {
-      grub_crypto_xor (outptr, inptr, iv, cipher->cipher->blocksize);
-      cipher->cipher->encrypt (cipher->ctx, outptr, outptr);
-      iv = outptr;
-    }
-  grub_memcpy (iv_in, iv, cipher->cipher->blocksize);
-  return GRUB_ERR_NONE;
-}
-
-static inline grub_err_t
+                        void *iv_in);
+grub_err_t
 grub_crypto_cbc_decrypt (grub_crypto_cipher_handle_t cipher,
                         void *out, void *in, grub_size_t size,
-                        void *iv)
-{
-  grub_uint8_t *inptr, *outptr, *end;
-  grub_uint8_t ivt[cipher->cipher->blocksize];
-  if (size % cipher->cipher->blocksize != 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, 
-                      "This encryption can't decrypt partial blocks");
-  end = (grub_uint8_t *) in + size;
-  for (inptr = in, outptr = out; inptr < end;
-       inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
-    {
-      grub_memcpy (ivt, inptr, cipher->cipher->blocksize);
-      cipher->cipher->decrypt (cipher->ctx, outptr, inptr);
-      grub_crypto_xor (outptr, outptr, iv, cipher->cipher->blocksize);
-      grub_memcpy (iv, ivt, cipher->cipher->blocksize);
-    }
-  return GRUB_ERR_NONE;
-}
-
+                        void *iv);
+void 
+grub_cipher_register (gcry_cipher_spec_t *cipher);
+void
+grub_cipher_unregister (gcry_cipher_spec_t *cipher);
+void 
+grub_md_register (gcry_md_spec_t *digest);
+void 
+grub_md_unregister (gcry_md_spec_t *cipher);
+void
+grub_crypto_hash (const gcry_md_spec_t *hash, void *out, void *in,
+                 grub_size_t inlen);
+const gcry_md_spec_t *
+grub_crypto_lookup_md_by_name (const char *name);
 
-void EXPORT_FUNC(grub_burn_stack) (grub_size_t size);
+void grub_burn_stack (grub_size_t size);
 
 extern gcry_md_spec_t _gcry_digest_spec_md5;
 #define GRUB_MD_MD5 ((const gcry_md_spec_t *) &_gcry_digest_spec_md5)
diff --git a/lib/crypto.c b/lib/crypto.c
new file mode 100644 (file)
index 0000000..64c386d
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
+ *                2007, 2008, 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/crypto.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
+static gcry_cipher_spec_t *grub_ciphers = NULL;
+static gcry_md_spec_t *grub_digests = NULL;
+
+/* Based on libgcrypt-1.4.4/src/misc.c.  */
+void
+grub_burn_stack (grub_size_t size)
+{
+  char buf[64];
+
+  grub_memset (buf, 0, sizeof (buf));
+  if (size > sizeof (buf))
+    grub_burn_stack (size - sizeof (buf));
+}
+
+
+void 
+grub_cipher_register (gcry_cipher_spec_t *cipher)
+{
+  cipher->next = grub_ciphers;
+  grub_ciphers = cipher;
+}
+
+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;
+}
+
+void 
+grub_md_register (gcry_md_spec_t *digest)
+{
+  digest->next = grub_digests;
+  grub_digests = digest;
+}
+
+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;
+}
+
+void
+grub_crypto_hash (const gcry_md_spec_t *hash, void *out, void *in,
+                 grub_size_t inlen)
+{
+  grub_uint8_t ctx[hash->contextsize];
+  hash->init (&ctx);
+  hash->write (&ctx, in, inlen);
+  hash->final (&ctx);
+  grub_memcpy (out, hash->read (&ctx), hash->mdlen);
+}
+
+const gcry_md_spec_t *
+grub_crypto_lookup_md_by_name (const char *name)
+{
+  const gcry_md_spec_t *md;
+  for (md = grub_digests; md; md = md->next)
+    if (grub_strcasecmp (name, md->name) == 0)
+      return md;
+  return NULL;
+}
+
+const gcry_cipher_spec_t *
+grub_crypto_lookup_cipher_by_name (const char *name)
+{
+  const gcry_cipher_spec_t *ciph;
+  for (ciph = grub_ciphers; ciph; ciph = ciph->next)
+    {
+      const char **alias;
+      if (grub_strcasecmp (name, ciph->name) == 0)
+       return ciph;
+      if (!ciph->aliases)
+       continue;
+      for (alias = ciph->aliases; *alias; alias++)
+       if (grub_strcasecmp (name, *alias) == 0)
+         return ciph;
+    }
+  return NULL;
+}
+
+
+grub_crypto_cipher_handle_t
+grub_crypto_cipher_open (const struct gcry_cipher_spec *cipher)
+{
+  grub_crypto_cipher_handle_t ret;
+  ret = grub_malloc (sizeof (*ret) + cipher->contextsize);
+  if (!ret)
+    return NULL;
+  ret->cipher = cipher;
+  return ret;
+}
+
+gcry_err_code_t
+grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher,
+                           const unsigned char *key,
+                           unsigned keylen)
+{
+  return cipher->cipher->setkey (cipher->ctx, key, keylen);
+}
+
+
+void
+grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher)
+{
+  grub_free (cipher);
+}
+
+
+void
+grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size)
+{
+  const grub_uint8_t *in1ptr = in1, *in2ptr = in2;
+  grub_uint8_t *outptr = out;
+  while (size--)
+    {
+      *outptr = *in1ptr ^ *in2ptr;
+      in1ptr++;
+      in2ptr++;
+      outptr++;
+    }
+}
+
+grub_err_t
+grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher,
+                        void *out, void *in, grub_size_t size)
+{
+  grub_uint8_t *inptr, *outptr, *end;
+  if (size % cipher->cipher->blocksize != 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, 
+                      "This encryption can't decrypt partial blocks");
+  end = (grub_uint8_t *) in + size;
+  for (inptr = in, outptr = out; inptr < end;
+       inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
+    cipher->cipher->decrypt (cipher->ctx, outptr, inptr);
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher,
+                        void *out, void *in, grub_size_t size)
+{
+  grub_uint8_t *inptr, *outptr, *end;
+  if (size % cipher->cipher->blocksize != 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, 
+                      "This encryption can't decrypt partial blocks");
+  end = (grub_uint8_t *) in + size;
+  for (inptr = in, outptr = out; inptr < end;
+       inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
+    cipher->cipher->encrypt (cipher->ctx, outptr, inptr);
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher,
+                        void *out, void *in, grub_size_t size,
+                        void *iv_in)
+{
+  grub_uint8_t *inptr, *outptr, *end;
+  void *iv;
+  if (size % cipher->cipher->blocksize != 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, 
+                      "This encryption can't decrypt partial blocks");
+  end = (grub_uint8_t *) in + size;
+  iv = iv_in;
+  for (inptr = in, outptr = out; inptr < end;
+       inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
+    {
+      grub_crypto_xor (outptr, inptr, iv, cipher->cipher->blocksize);
+      cipher->cipher->encrypt (cipher->ctx, outptr, outptr);
+      iv = outptr;
+    }
+  grub_memcpy (iv_in, iv, cipher->cipher->blocksize);
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_crypto_cbc_decrypt (grub_crypto_cipher_handle_t cipher,
+                        void *out, void *in, grub_size_t size,
+                        void *iv)
+{
+  grub_uint8_t *inptr, *outptr, *end;
+  grub_uint8_t ivt[cipher->cipher->blocksize];
+  if (size % cipher->cipher->blocksize != 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, 
+                      "This encryption can't decrypt partial blocks");
+  end = (grub_uint8_t *) in + size;
+  for (inptr = in, outptr = out; inptr < end;
+       inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
+    {
+      grub_memcpy (ivt, inptr, cipher->cipher->blocksize);
+      cipher->cipher->decrypt (cipher->ctx, outptr, inptr);
+      grub_crypto_xor (outptr, outptr, iv, cipher->cipher->blocksize);
+      grub_memcpy (iv, ivt, cipher->cipher->blocksize);
+    }
+  return GRUB_ERR_NONE;
+}