]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Various cleanups and wrapper functions. Allocate disk id for LUKS.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 12 Nov 2009 17:08:44 +0000 (18:08 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 12 Nov 2009 17:08:44 +0000 (18:08 +0100)
commands/xnu_uuid.c
import_gcry.py
include/grub/crypto.h
include/grub/disk.h

index d7f86276b9f1f26972e231146952544c98aeee3a..48c67d18e71167ef8cba55f3ed97fdb4214ca3eb 100644 (file)
@@ -33,8 +33,6 @@
 #include <grub/command.h>
 #include <grub/crypto.h>
 
-extern gcry_md_spec_t _gcry_digest_spec_md5;
-
 /* This prefix is used by xnu and boot-132 to hash 
    together with volume serial. */
 static grub_uint8_t hash_prefix[16] 
@@ -49,18 +47,18 @@ grub_cmd_xnu_uuid (grub_command_t cmd __attribute__ ((unused)),
   grub_uint8_t *xnu_uuid;
   char uuid_string[sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")];
   char *ptr;
-  grub_uint8_t ctx[_gcry_digest_spec_md5.contextsize];
+  grub_uint8_t ctx[GRUB_MD_MD5->contextsize];
 
   if (argc < 1)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, "UUID required");
 
   serial = grub_cpu_to_be64 (grub_strtoull (args[0], 0, 16));
 
-  _gcry_digest_spec_md5.init (&ctx);
-  _gcry_digest_spec_md5.write (&ctx, hash_prefix, sizeof (hash_prefix));
-  _gcry_digest_spec_md5.write (&ctx, &serial, sizeof (serial));
-  _gcry_digest_spec_md5.final (&ctx);
-  xnu_uuid = _gcry_digest_spec_md5.read (&ctx);
+  GRUB_MD_MD5->init (&ctx);
+  GRUB_MD_MD5->write (&ctx, hash_prefix, sizeof (hash_prefix));
+  GRUB_MD_MD5->write (&ctx, &serial, sizeof (serial));
+  GRUB_MD_MD5->final (&ctx);
+  xnu_uuid = GRUB_MD_MD5->read (&ctx);
 
   grub_sprintf (uuid_string,
                "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
index ca03729af40e05e20e0b99e3d107729968ef62b8..39542d8c4d3cfa7449a65f9fc0820838ef3312ed 100644 (file)
@@ -26,6 +26,20 @@ conf = open (os.path.join (outdir, "conf", "gcry.rmk"), "w")
 conf.write ("# -*- makefile -*-\n\n")
 chlog = ""
 
+mdblocksizes = {"_gcry_digest_spec_crc32" : 1,
+                "_gcry_digest_spec_crc32_rfc1510" : 1,
+                "_gcry_digest_spec_crc24_rfc2440" : 1,
+                "_gcry_digest_spec_md4" : 64,
+                "_gcry_digest_spec_md5" : 64,
+                "_gcry_digest_spec_rmd160" : 64,
+                "_gcry_digest_spec_sha1" : 64,
+                "_gcry_digest_spec_sha224" : 64,
+                "_gcry_digest_spec_sha256" : 64,
+                "_gcry_digest_spec_sha384" : 128,
+                "_gcry_digest_spec_sha512" : 128,
+                "_gcry_digest_spec_tiger" : 64,
+                "_gcry_digest_spec_whirlpool" : 64}
+
 for cipher_file in cipher_files:
     infile = os.path.join (cipher_dir_in, cipher_file)
     outfile = os.path.join (cipher_dir_out, cipher_file)
@@ -44,6 +58,8 @@ for cipher_file in cipher_files:
         hold = False
         skip = False
         skip2 = False
+        ismd = False
+        iscomma = False
         for line in f:
             if skip:
                 if line[0] == "}":
@@ -53,6 +69,16 @@ for cipher_file in cipher_files:
                 if not re.search (" *};", line) is None:
                     skip2 = False
                 continue
+            if ismd:
+                if not re.search (" *};", line) is None:
+                    if not mdblocksizes.has_key (mdname):
+                        print ("ERROR: Unknown digest blocksize: %s\n" % mdname)
+                        exit (1)
+                    if not iscomma:
+                        fw.write ("    ,\n")
+                    fw.write ("    .blocksize = %s\n" % mdblocksizes [mdname])
+                    ismd = False
+                iscomma = not re.search (",$", line) is None
             if hold:
                 hold = False
                 # We're optimising for size.
@@ -85,9 +111,11 @@ for cipher_file in cipher_files:
                 ciphernames.append (ciphername)
             m = re.match ("gcry_md_spec_t", line)
             if isc and not m is None:
+                assert (not ismd)
                 mdname = line [len ("gcry_md_spec_t"):].strip ()
                 mdname = re.match("[a-zA-Z0-9_]*",mdname).group ()
                 mdnames.append (mdname)
+                ismd = True
             m = re.match ("static const char \*selftest.*;$", line)
             if not m is None:
                 fname = line[len ("static const char \*"):]
index 17f14de86b628180fe1ee7f494c8c7bd1de80b4a..239b46666e807cbb1e8e0478d51f299b10cfe4bb 100644 (file)
@@ -25,6 +25,8 @@
 
 #include <grub/symbol.h>
 #include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
 
 typedef enum 
   {
@@ -127,35 +129,6 @@ typedef struct gcry_cipher_spec
   struct gcry_cipher_spec *next;
 } gcry_cipher_spec_t;
 
-/* Definition of a function used to report selftest failures. 
-   DOMAIN is a string describing the function block:
-          "cipher", "digest", "pubkey or "random",
-   ALGO   is the algorithm under test,
-   WHAT   is a string describing what has been tested,
-   DESC   is a string describing the error. */
-typedef void (*selftest_report_func_t)(const char *domain,
-                                       int algo, 
-                                       const char *what,
-                                       const char *errdesc);
-
-/* Definition of the selftest functions.  */
-typedef gpg_err_code_t (*selftest_func_t)
-     (int algo, int extended, selftest_report_func_t report);
-
-/* The type used to convey additional information to a cipher.  */
-typedef gpg_err_code_t (*cipher_set_extra_info_t)
-     (void *c, int what, const void *buffer, grub_size_t buflen);
-
-
-/* Extra module specification structures.  These are used for internal
-   modules which provide more functions than available through the
-   public algorithm register APIs.  */
-typedef struct cipher_extra_spec
-{
-  selftest_func_t selftest;
-  cipher_set_extra_info_t set_extra_info;
-} cipher_extra_spec_t;
-
 /* Type for the md_init function.  */
 typedef void (*gcry_md_init_t) (void *c);
 
@@ -180,12 +153,14 @@ typedef struct gcry_md_spec
   unsigned char *asnoid;
   int asnlen;
   gcry_md_oid_spec_t *oids;
-  int mdlen;
+  grub_size_t 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 */
+  /* Block size, needed for HMAC.  */
+  grub_size_t blocksize;
   struct gcry_md_spec *next;
 } gcry_md_spec_t;
 
@@ -199,7 +174,7 @@ grub_cipher_register (gcry_cipher_spec_t *cipher)
   grub_ciphers = cipher;
 }
 
-static inline void 
+static inline void
 grub_cipher_unregister (gcry_cipher_spec_t *cipher)
 {
   gcry_cipher_spec_t **ciph;
@@ -224,7 +199,172 @@ grub_md_unregister (gcry_md_spec_t *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;
+}
+
+
+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
+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);
+}
+
+
+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++;
+    }
+}
+
+static inline 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;
+}
+
+static inline 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
+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
+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 EXPORT_FUNC(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)
+
 #endif
index de71bb5881ab9d41938eb59e7c790cb4c181e640..cc801bc67f50fb9b646933a64d1b5f29775b9896 100644 (file)
@@ -42,6 +42,7 @@ enum grub_disk_dev_id
     GRUB_DISK_DEVICE_PXE_ID,
     GRUB_DISK_DEVICE_SCSI_ID,
     GRUB_DISK_DEVICE_FILE_ID,
+    GRUB_DISK_DEVICE_LUKS_ID
   };
 
 struct grub_disk;