diff -u --recursive --new-file cryptsetup-1.0.5-vanilla/lib/Makefile.am cryptsetup-1.0.5/lib/Makefile.am
--- cryptsetup-1.0.5-vanilla/lib/Makefile.am	2008-08-31 19:33:59.000000000 -0400
+++ cryptsetup-1.0.5/lib/Makefile.am	2008-08-31 23:39:26.000000000 -0400
@@ -61,6 +61,7 @@
 	../luks/libluks.la
 
 libcryptsetup_la_SOURCES = \
+	dmi.c					\
 	setup.c					\
 	internal.h				\
 	blockdev.h				\
diff -u --recursive --new-file cryptsetup-1.0.5-vanilla/lib/Makefile.in cryptsetup-1.0.5/lib/Makefile.in
--- cryptsetup-1.0.5-vanilla/lib/Makefile.in	2008-08-31 19:34:00.000000000 -0400
+++ cryptsetup-1.0.5/lib/Makefile.in	2008-08-31 23:56:41.000000000 -0400
@@ -77,11 +77,11 @@
 am__DEPENDENCIES_1 =
 libcryptsetup_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_1) ../luks/libluks.la
-am__libcryptsetup_la_SOURCES_DIST = setup.c internal.h blockdev.h \
+am__libcryptsetup_la_SOURCES_DIST = dmi.c setup.c internal.h blockdev.h \
 	libcryptsetup.h utils.c backends.c libdevmapper.c gcrypt.c
 @BUILD_LIBDEVMAPPER_TRUE@am__objects_1 = libdevmapper.lo
 @BUILD_LIBGCRYPT_TRUE@am__objects_2 = gcrypt.lo
-am_libcryptsetup_la_OBJECTS = setup.lo utils.lo backends.lo \
+am_libcryptsetup_la_OBJECTS = dmi.lo setup.lo utils.lo backends.lo \
 	$(am__objects_1) $(am__objects_2)
 libcryptsetup_la_OBJECTS = $(am_libcryptsetup_la_OBJECTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
@@ -292,6 +292,7 @@
 	../luks/libluks.la
 
 libcryptsetup_la_SOURCES = \
+	dmi.c   				\
 	setup.c					\
 	internal.h				\
 	blockdev.h				\
@@ -404,6 +405,7 @@
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dmi.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backends.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcrypt.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdevmapper.Plo@am__quote@
diff -u --recursive --new-file cryptsetup-1.0.5-vanilla/lib/dmi.c cryptsetup-1.0.5/lib/dmi.c
--- cryptsetup-1.0.5-vanilla/lib/dmi.c	1969-12-31 19:00:00.000000000 -0500
+++ cryptsetup-1.0.5/lib/dmi.c	2008-09-10 21:04:53.000000000 -0400
@@ -0,0 +1,299 @@
+/* Copyright (c) 2008 W. Michael Petullo <mike@flyn.org>
+ * All rights reserved.
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* See the "System Management BIOS (SMBIOS) Reference Specification"
+ * for details on the following structures 
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "libcryptsetup.h"
+#include "internal.h"
+
+#define MEMDEV "/dev/mem"
+
+typedef struct smbios_entry_point {
+  unsigned char anchor[4];
+  unsigned char checksum;
+  unsigned char length;
+  unsigned char bios_major_version;
+  unsigned char bios_minor_version;
+  unsigned short max_struct_size;
+  unsigned char revision;
+  unsigned char formatted_area[5];
+  unsigned char intermediate_anchor[5];
+  unsigned char intermediate_checksum;
+  unsigned short structure_table_length;
+  unsigned int structure_table_address;
+  unsigned short num_structures;
+  unsigned char bcd_version;
+} smbios_entry_point_t;
+
+typedef struct smbios_generic_header {
+  unsigned char type;
+  unsigned char length;
+  unsigned short handle;
+} smbios_generic_header_t;
+
+/* NOTE: there are more fields in the specification. However, the
+ * fields beginning with "BIOS Characteristics Extension Bytes" are
+ * not included because this field has a variable number of bytes.
+ */
+typedef struct smbios_bios_information {
+  unsigned char type;
+  unsigned char length;
+  unsigned short handle;
+  unsigned char vendor;
+  unsigned char version;
+  unsigned short start_addr;
+  unsigned char release_date;
+  unsigned char rom_size;
+  unsigned long long characteristics;
+} smbios_bios_information_t;
+
+typedef struct smbios_system_information {
+  unsigned char type;
+  unsigned char length;
+  unsigned short handle;
+  unsigned char manufacturer;
+  unsigned char product;
+  unsigned char version;
+  unsigned char serial_number;
+  unsigned char uuid[16];
+  unsigned char wakeup_time;
+  unsigned char sku;
+  unsigned char family;
+} smbios_system_information_t;
+
+static int dmi_checksum (char *ptr, int length)
+{
+  unsigned char sum = 0;
+  length--;
+  while(length >= 0) {
+    sum += ptr[length--];
+  }
+  return sum;
+}
+
+static const char * dmi_get_string (char *ptr, char n)
+/* Given ptr to beginning of SMBIOS structure and structure length, 
+ * print nth string, if n is too big, will return pointer to 0x00
+ * that terminates string list (empty string).
+ */
+{
+  ptr += *(ptr + 1); /* Skip header, ptr + 1 byte is header length */
+  /* String numbering starts at 1, so --n */
+  while (--n > 0 && *ptr != 0x00) {
+      ptr += strlen(ptr) + 1;
+  }
+  return ptr;
+}
+
+static void dmi_read_generic_header (char *ptr)
+{
+  ptr += *(ptr + 1); /* Skip header, ptr + 1 byte is header length */
+
+  /* If we see a 0x00 here, it's the second one, as we've already 
+  * incremented past the null terminator with ptr += ... below.
+  * The empty string is indicated by a 0 in the SMBIOS structure
+  * above, so we won't see one here.
+  */
+  while (*ptr != 0x00) {
+    printf("%s\n", ptr);
+    ptr += strlen(ptr) + 1;
+  }
+}
+
+static void dmi_read_bios_information (char *ptr, char **key, int *passLen)
+{
+  smbios_bios_information_t bios_information;
+  memcpy(&bios_information, ptr, sizeof(smbios_bios_information_t));
+
+  printf("Length:        %d\n", bios_information.length);
+  printf("Handle:        0x%x\n", bios_information.handle);
+  printf("Vendor:        %s\n", 
+              dmi_get_string(ptr, bios_information.vendor));
+  printf("Version:       %s\n",
+              dmi_get_string(ptr, bios_information.version));
+  printf("BIOS Addr.:    0x%x\n", bios_information.start_addr);
+  printf("Rel. Date:     %s\n",
+              dmi_get_string(ptr, bios_information.release_date));
+  printf("BIOS ROM Size: %d\n", bios_information.rom_size);
+
+  /* FIXME: These lines should be changed to get the encryption key instead */
+  *key = safe_strdup(dmi_get_string(ptr, bios_information.vendor));
+  *passLen = strlen(*key);
+}
+
+static void dmi_read_system_information (char *ptr)
+{
+  smbios_system_information_t system_information;
+  memcpy(&system_information, ptr, sizeof(smbios_system_information_t));
+
+  printf("Length:        %d\n", system_information.length);
+  printf("Handle:        0x%x\n", system_information.handle);
+  printf("Manufacturer:  %s\n", 
+              dmi_get_string(ptr, system_information.manufacturer));
+  printf("Product:       %s\n",
+              dmi_get_string(ptr, system_information.product));
+  printf("Version:       0x%s\n",
+              dmi_get_string(ptr, system_information.version));
+  printf("Serial Num:    %s\n",
+              dmi_get_string(ptr, system_information.serial_number));
+  printf("Wake-up Time:  %x\n", system_information.wakeup_time);
+  printf("SKU:           %s\n",
+              dmi_get_string(ptr, system_information.sku));
+  printf("Family:        %s\n",
+              dmi_get_string(ptr, system_information.family));
+}
+
+int get_key_dmi(char **key, int *passLen)
+{
+  int fd;
+  int fnval = 0;
+  char *ptr, *dmi_addr;
+  smbios_entry_point_t entry_point;
+
+  const int SEARCH_START = 0x000f0000;
+  const int SEARCH_END = 0x000fffff;
+  const int SEARCH_LENGTH = SEARCH_END - SEARCH_START;
+
+  fd = open(MEMDEV, O_RDONLY);
+  if (-1 == fd) {
+    set_error("Could not open %s\n", MEMDEV);
+    fnval = 1;
+    goto _return_no_mmap;
+  }
+
+  dmi_addr = mmap(NULL, SEARCH_LENGTH, PROT_READ, MAP_PRIVATE, fd, SEARCH_START);
+  if (MAP_FAILED == dmi_addr) {
+    set_error("Could not mmap %s\n", MEMDEV);
+    fnval = 1;
+    goto _return_no_mmap;
+  }
+
+  for (ptr = dmi_addr; ptr < dmi_addr + SEARCH_LENGTH - sizeof("_SM_"); ptr++) {
+    if (0 == strncmp("_SM_", ptr, 4)) {
+      int i;
+
+      printf("Found '_SM_' at 0x%x\n", (unsigned int) ptr);
+
+      if (0 != dmi_checksum(ptr, *(ptr + 0x05))) {
+        printf("Checksum failed!\n");
+        continue;
+      } else {
+        printf("Checksum passed\n");
+      }
+
+      memcpy(&entry_point, ptr, sizeof(smbios_entry_point_t));
+
+      if (0 != strncmp("_DMI_", entry_point.intermediate_anchor, 5)) {
+        printf("Missing '_DMI_'!\n");
+        continue;
+      }
+
+      if (0 != dmi_checksum((char *) &(entry_point.intermediate_anchor), 0x0F)) {
+        printf("Intermediate checksum failed!\n");
+        continue;
+      } else {
+        printf("Intermediate checksum passed\n");
+      }
+
+      for (i = 0; i < entry_point.length; i+=2) {
+        printf("0x%x", ptr[i]);
+        printf("%x ", ptr[i+1]);
+        if (i % 8 == 0) {
+          printf("\n");
+        }
+      }
+
+      printf("Table Length:  %d\n", entry_point.structure_table_length);
+      printf("Table Address: 0x%x\n", entry_point.structure_table_address);
+
+      ptr = dmi_addr + (entry_point.structure_table_address - SEARCH_START);
+
+      do {
+        smbios_generic_header_t generic_header;
+        memcpy(&generic_header, ptr, sizeof(smbios_generic_header_t));
+
+        switch (*ptr) {
+          case 0:
+            printf("Found BIOS information struct at 0x%x\n", 
+                        (unsigned int) ptr);
+            dmi_read_bios_information (ptr, key, passLen);
+            break;
+          case 1:
+            printf("Found system information struct at 0x%x\n",
+                        (unsigned int) ptr);
+            dmi_read_system_information (ptr);
+            break;
+          default:
+            printf("Unknown information stuct (%d) at 0x%x\n", *ptr, 
+                        (unsigned int) ptr);
+            dmi_read_generic_header (ptr);
+            break;
+        }
+
+        printf("Advance past struct (%d)\n", generic_header.length);
+        ptr += generic_header.length; /* Advance past struct to strings */
+
+        do { /* Advance past strings: */
+          printf("Advance past string (%d)\n", strlen(ptr) + 1);
+          ptr += strlen(ptr) + 1;
+        } while (*ptr != 0x00);
+        /* This is a do...while instead of a while because:
+         *
+         *   a. if there is a string it will be advanced over and the
+         *   string's null may be the first of the double null terminator
+         *
+         *   b. if there are no strings at all, the first null of the
+         *   double null terminator will be advanced over as if it were 
+         *   part of an empty string
+         *
+         * If we see a 0x00 here, it's the second one, as we've already 
+         * incremented past the null terminator with ptr += ... above.
+         * The empty string is indicated by a 0 in the SMBIOS structure
+         * above, so we won't see one here.
+         */
+
+        printf("Advance one more\n");
+        ptr++; /* Advance past second 0x00 that signifies end of strings */
+
+      } while (ptr < (char *) entry_point.structure_table_address + entry_point.structure_table_length);
+
+      break;
+    }
+  }
+  if (ptr == (char *) 0x000fffff) {
+    set_error("Did not find DMI data!\n");
+    fnval = 1;
+    goto _return;
+  }
+_return:
+  munmap(dmi_addr, SEARCH_LENGTH);
+_return_no_mmap:
+  return fnval;
+}
+
+/* vi: set et sw=2 sts=2: */
diff -u --recursive --new-file cryptsetup-1.0.5-vanilla/lib/libcryptsetup.h cryptsetup-1.0.5/lib/libcryptsetup.h
--- cryptsetup-1.0.5-vanilla/lib/libcryptsetup.h	2008-08-31 19:33:59.000000000 -0400
+++ cryptsetup-1.0.5/lib/libcryptsetup.h	2008-08-31 19:54:01.000000000 -0400
@@ -17,6 +17,7 @@
 
 	const char	*passphrase;
 	int		passphrase_fd;
+	int             dmi;
 	const char	*key_file;
 	const char	*new_key_file;	
 	int		key_size;
diff -u --recursive --new-file cryptsetup-1.0.5-vanilla/lib/setup.c cryptsetup-1.0.5/lib/setup.c
--- cryptsetup-1.0.5-vanilla/lib/setup.c	2008-08-31 19:34:00.000000000 -0400
+++ cryptsetup-1.0.5/lib/setup.c	2008-08-31 23:36:39.000000000 -0400
@@ -149,6 +149,7 @@
  * interactive      | Y | Y | Y | Inf
  * from fd          | N | N | Y | Inf
  * from binary file | N | N | N | Inf or options->key_size
+ * from DMI         | N | N | N | Inf
  *
  * Legend: p..prompt, v..can verify, n..newline-stop, h..read horizon
  *
@@ -167,7 +168,11 @@
 	int newline_stop;
 	int read_horizon;
 	
-	if(options->key_file && !strcmp(options->key_file, "-")) {
+	if (options->dmi) {
+		fd = -1;
+		newline_stop = 0;
+		read_horizon = 0;
+	} else if(options->key_file && !strcmp(options->key_file, "-")) {
 		/* Allow binary reading from stdin */
 		fd = options->passphrase_fd;
 		newline_stop = 0;
@@ -191,8 +196,13 @@
 		read_horizon = 0;   /* Infinite, if read from terminal or fd */
 	}	
 
+	if (options->dmi) {
+		if (0 != get_key_dmi(key, passLen)) {
+			set_error("Error reading passphrase from DMI");
+			goto out_err;
+		}
 	/* Interactive case */
-	if(isatty(fd)) {
+	} else if(isatty(fd)) {
 		int i;
 
 		pass = safe_alloc(512);
@@ -262,7 +272,7 @@
 		*passLen = i;
 	}
 
-	return isatty(fd); /* Return true, when password reading can be tried on interactive fds */
+	return (! options->dmi) && isatty(fd); /* Return true, when password reading can be tried on interactive fds */
 
 out_err:
 	if(pass)
@@ -690,10 +700,12 @@
 	unsigned int i; unsigned int keyIndex;
 	const char *device = options->device;
 	struct crypt_options optionsCheck = { 
+		.dmi = options->dmi,
 		.key_file = options->key_file,
 		.flags = options->flags & ~(CRYPT_FLAG_VERIFY | CRYPT_FLAG_VERIFY_IF_POSSIBLE),
 	};
 	struct crypt_options optionsSet = { 
+		.dmi = options->dmi,
 		.key_file = options->new_key_file,
 		.flags = options->flags,
 	};
diff -u --recursive --new-file cryptsetup-1.0.5-vanilla/src/cryptsetup.c cryptsetup-1.0.5/src/cryptsetup.c
--- cryptsetup-1.0.5-vanilla/src/cryptsetup.c	2008-08-31 19:34:00.000000000 -0400
+++ cryptsetup-1.0.5/src/cryptsetup.c	2008-09-01 00:01:12.000000000 -0400
@@ -17,6 +17,7 @@
 static char *opt_cipher = NULL;
 static char *opt_hash = DEFAULT_HASH;
 static int opt_verify_passphrase = 0;
+static int opt_dmi = 0;
 static char *opt_key_file = NULL;
 static unsigned int opt_key_size = 0;
 static uint64_t opt_size = 0;
@@ -102,6 +103,7 @@
 		.device = action_argv[1],
 		.cipher = opt_cipher?opt_cipher:DEFAULT_CIPHER,
 		.hash = opt_hash,
+		.dmi = opt_dmi,
 		.key_file = opt_key_file,
 		.key_size = ((opt_key_size)?opt_key_size:DEFAULT_KEY_SIZE)/8,
 		.passphrase_fd = 0,	/* stdin */
@@ -214,6 +216,7 @@
 		.key_size = (opt_key_size != 0 ? opt_key_size : DEFAULT_LUKS_KEY_SIZE) / 8,
 		.device = action_argv[0],
 		.cipher = opt_cipher?opt_cipher:DEFAULT_LUKS_CIPHER,
+		.dmi = opt_dmi,
 		.new_key_file = action_argc > 1 ? action_argv[1] : NULL,
 		.flags = opt_verify_passphrase ? CRYPT_FLAG_VERIFY : (!opt_batch_mode?CRYPT_FLAG_VERIFY_IF_POSSIBLE :  0),
 		.iteration_time = opt_iteration_time,
@@ -238,6 +241,7 @@
 	struct crypt_options options = {
 		.name = action_argv[1],
 		.device = action_argv[0],
+		.dmi = opt_dmi,
 		.key_file = opt_key_file,
 		.timeout = opt_timeout,
 		.tries = opt_tries
@@ -258,6 +262,7 @@
 	struct crypt_options options = {
 		.device = action_argv[0],
 		.key_slot = atoi(action_argv[1]),
+		.dmi = opt_dmi,
 		.key_file = opt_key_file,
 		.timeout = opt_timeout,
 		.flags = !opt_batch_mode?CRYPT_FLAG_VERIFY_ON_DELKEY : 0,
@@ -279,6 +284,7 @@
 {
 	struct crypt_options options = {
 		.device = action_argv[0],
+		.dmi = opt_dmi,
 		.new_key_file = action_argc>1?action_argv[1]:NULL,
 		.key_file = opt_key_file,
 		.flags = opt_verify_passphrase ? CRYPT_FLAG_VERIFY : (!opt_batch_mode?CRYPT_FLAG_VERIFY_IF_POSSIBLE : 0),
@@ -378,6 +384,7 @@
 		{ "cipher",            'c',  POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &opt_cipher,            0, N_("The cipher used to encrypt the disk (see /proc/crypto)"),          NULL },
 		{ "hash",              'h',  POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &opt_hash,              0, N_("The hash used to create the encryption key from the passphrase"),  NULL },
 		{ "verify-passphrase", 'y',  POPT_ARG_NONE,                               &opt_verify_passphrase, 0, N_("Verifies the passphrase by asking for it twice"),                  NULL },
+		{ "dmi",               'D',  POPT_ARG_NONE,                               &opt_dmi,               0, N_("Read the key from DMI"),                                           NULL },
 		{ "key-file",          'd',  POPT_ARG_STRING,                             &opt_key_file,          0, N_("Read the key from a file (can be /dev/random)"),                   NULL },
 		{ "key-size",          's',  POPT_ARG_INT    | POPT_ARGFLAG_SHOW_DEFAULT, &opt_key_size,          0, N_("The size of the encryption key"),                                  N_("BITS") },
 		{ "size",              'b',  POPT_ARG_STRING,                             &popt_tmp,              1, N_("The size of the device"),                                          N_("SECTORS") },
@@ -444,6 +451,11 @@
 		usage(popt_context, 1,
 		      _("Key size must be a multiple of 8 bits"),
 		      poptGetInvocationName(popt_context));
+
+	if (opt_dmi != 0 && opt_key_file != NULL)
+		usage(popt_context, 1,
+		      _("Cannot specify DMI and key file"),
+		      poptGetInvocationName(popt_context));
 	
 	if (!(aname = (char *)poptGetArg(popt_context)))
 		usage(popt_context, 1, _("Argument <action> missing."),
