--- cryptsetup-1.6.1/lib/crypto_backend/crypto_backend.h 
+++ crypto_backend.h 
@@ -23,7 +23,9 @@
 
 #include <stdint.h>
 #include <string.h>
-#include "config.h"
+
+#include "../config.h"
+#define USE_INTERNAL_PBKDF2 1
 
 struct crypt_device;
 struct crypt_hash;
@@ -73,7 +75,7 @@
 		 const char *P, size_t Plen,
 		 const char *S, size_t Slen,
 		 unsigned int c,
-		 unsigned int dkLen,char *DK);
+		 unsigned int dkLen,char *DK, int perfcheck);
 #endif
 
 /* CRC32 */
--- cryptsetup-1.6.1/lib/crypto_backend/crypto_gcrypt.c 
+++ crypto_gcrypt.c 
@@ -26,6 +26,10 @@
 #include <gcrypt.h>
 #include "crypto_backend.h"
 
+#ifndef GCRYPT_REQ_VERSION
+#  define GCRYPT_REQ_VERSION "1.1.42"
+#endif
+
 static int crypto_backend_initialised = 0;
 static int crypto_backend_secmem = 1;
 static char version[64];
@@ -46,6 +50,11 @@
 {
 	if (crypto_backend_initialised)
 		return 0;
+
+#if !CM_MULTIPLE_INIT
+	crypto_backend_initialised = 1;
+    return 0;   /* cryptmount will already have initialized libgcrypt */
+#endif
 
 	if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) {
 		if (!gcry_check_version (GCRYPT_REQ_VERSION)) {
@@ -266,7 +275,7 @@
 		return -EINVAL;
 
 	return pkcs5_pbkdf2(hash, password, password_length, salt, salt_length,
-			    iterations, key_length, key);
+			    iterations, key_length, key, 0);
 
 #else /* USE_INTERNAL_PBKDF2 */
 	int hash_id = gcry_md_map_name(hash);
--- cryptsetup-1.6.1/lib/internal.h 
+++ internal.h 
@@ -24,16 +24,39 @@
 #ifndef INTERNAL_H
 #define INTERNAL_H
 
-#ifdef HAVE_CONFIG_H
-#	include "config.h"
-#endif
+#include "../config.h"
+
 
 #include <stdint.h>
 #include <stdarg.h>
 #include <unistd.h>
 #include <inttypes.h>
+#if HAVE_UUID
+#  include <uuid.h>
+#endif
 
-#include "nls.h"
+
+/* cryptmount patches: */
+#ifndef _
+#  define _(Text) Text 
+#  define ngettext(Text, TextP, N) (N == 1 ? Text : TextP)
+#endif
+/* Avoid multiple libgcrypt inits within cryptmount: */
+#define CM_MULTIPLE_INIT 0
+#ifndef DEFAULT_KEYFILE_SIZE_MAXKB
+#  define DEFAULT_KEYFILE_SIZE_MAXKB 8192
+#endif
+#ifndef DEFAULT_PASSPHRASE_SIZE_MAX
+#  define DEFAULT_PASSPHRASE_SIZE_MAX 512
+#endif
+#ifndef DEFAULT_RNG
+#  define DEFAULT_RNG "/dev/random"
+#endif
+#ifndef DEFAULT_LOOPAES_CIPHER
+#  define DEFAULT_LOOPAES_CIPHER "aes"
+#endif
+
+
 #include "bitops.h"
 #include "utils_crypt.h"
 #include "utils_loop.h"
--- cryptsetup-1.6.1/lib/luks1/keymanage.c 
+++ keymanage.c 
@@ -30,7 +30,9 @@
 #include <string.h>
 #include <ctype.h>
 #include <assert.h>
-#include <uuid/uuid.h>
+#if HAVE_UUID
+#  include <uuid/uuid.h>
+#endif
 
 #include "luks.h"
 #include "af.h"
@@ -313,6 +315,7 @@
 /* This routine should do some just basic recovery for known problems. */
 static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
 {
+#if HAVE_UUID
 	struct luks_phdr temp_phdr;
 	const unsigned char *sector = (const unsigned char*)phdr;
 	struct volume_key *vk;
@@ -394,6 +397,10 @@
 	crypt_free_volume_key(vk);
 	memset(&temp_phdr, 0, sizeof(temp_phdr));
 	return r;
+#else   /* !HAVE_UUID */
+    log_err(ctx, _("Repair not attempted - no UUID library."));
+    return -1;
+#endif  /* HAVE_UUID */
 }
 
 static int _check_and_convert_hdr(const char *device,
@@ -535,6 +542,8 @@
 	close(devfd);
 	return r;
 }
+
+#if HAVE_UUID
 
 int LUKS_write_phdr(struct luks_phdr *hdr,
 		    struct crypt_device *ctx)
@@ -828,6 +837,8 @@
 	return r;
 }
 
+#endif	/* HAVE_UUID */
+
 /* Check whether a volume key is invalid. */
 int LUKS_verify_volume_key(const struct luks_phdr *hdr,
 			   const struct volume_key *vk)
@@ -900,8 +911,10 @@
 		goto out;
 
 	r = LUKS_verify_volume_key(hdr, vk);
-	if (!r)
+	if (!r) {
 		log_verbose(ctx, _("Key slot %d unlocked.\n"), keyIndex);
+		r = keyIndex;	/* cryptmount: return slot-number like LUKS_open_key_with_hdr() */
+	}
 out:
 	crypt_safe_free(AfKey);
 	crypt_free_volume_key(derived_key);
@@ -939,6 +952,8 @@
 	log_err(ctx, _("No key available with this passphrase.\n"));
 	return -EPERM;
 }
+
+#if HAVE_UUID
 
 int LUKS_del_key(unsigned int keyIndex,
 		 struct luks_phdr *hdr,
@@ -985,6 +1000,8 @@
 
 	return r;
 }
+
+#endif	/* HAVE_UUID */
 
 crypt_keyslot_info LUKS_keyslot_info(struct luks_phdr *hdr, int keyslot)
 {
--- cryptsetup-1.6.1/lib/libcryptsetup.h 
+++ libcryptsetup.h 
@@ -39,6 +39,15 @@
 #include <stdint.h>
 
 struct crypt_device; /* crypt device handle */
+
+/* cryptmount helper routines: */
+struct luks_phdr;
+struct device;
+struct device *crypt_get_device(struct crypt_device *luks_ctxt);
+struct luks_phdr *crypt_get_lukshdr(struct crypt_device *luks_ctxt);
+void crypt_get_pbkdf2params(struct crypt_device *luks_ctxt,
+			uint64_t **ittime_ptr, uint64_t **persec_ptr);
+
 
 /**
  * Initialize crypt device handle and check if provided device exists.
--- cryptsetup-1.6.1/lib/libdevmapper.c 
+++ libdevmapper.c 
@@ -27,7 +27,9 @@
 #include <libdevmapper.h>
 #include <fcntl.h>
 #include <linux/fs.h>
-#include <uuid/uuid.h>
+#if HAVE_UUID
+#  include <uuid/uuid.h>
+#endif
 
 #include "internal.h"
 
@@ -486,6 +488,8 @@
 	return r;
 }
 
+#if HAVE_UUID
+
 #define UUID_LEN 37 /* 36 + \0, libuuid ... */
 /*
  * UUID has format: CRYPT-<devicetype>-[<uuid>-]<device name>
@@ -525,6 +529,8 @@
 	return 0;
 }
 
+#endif	/* HAVE_UUID */
+
 static int _dm_create_device(const char *name, const char *type,
 			     struct device *device, uint32_t flags,
 			     const char *uuid, uint64_t size,
@@ -549,9 +555,11 @@
 		if (!dm_task_set_name(dmt, name))
 			goto out_no_removal;
 	} else {
+#if HAVE_UUID
 		r = dm_prepare_uuid(name, type, uuid, dev_uuid, sizeof(dev_uuid));
 		if (r < 0)
 			return r;
+#endif
 
 		if (!(dmt = dm_task_create(DM_DEVICE_CREATE)))
 			goto out_no_removal;
@@ -559,8 +567,10 @@
 		if (!dm_task_set_name(dmt, name))
 			goto out_no_removal;
 
+#if HAVE_UUID
 		if (!dm_task_set_uuid(dmt, dev_uuid))
 			goto out_no_removal;
+#endif
 
 		if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
 			goto out_no_removal;
--- cryptsetup-1.6.1/lib/luks1/luks.h 
+++ luks.h 
@@ -31,12 +31,12 @@
 #define LUKS_CIPHERNAME_L 32
 #define LUKS_CIPHERMODE_L 32
 #define LUKS_HASHSPEC_L 32
-#define LUKS_DIGESTSIZE 20 // since SHA1
+#define LUKS_DIGESTSIZE 20 /* since SHA1 */
 #define LUKS_HMACSIZE 32
 #define LUKS_SALTSIZE 32
 #define LUKS_NUMKEYS 8
 
-// Minimal number of iterations
+/* Minimal number of iterations */
 #define LUKS_MKD_ITERATIONS_MIN  1000
 #define LUKS_SLOT_ITERATIONS_MIN 1000
 
@@ -48,7 +48,7 @@
 
 #define LUKS_STRIPES 4000
 
-// partition header starts with magic
+/* partition header starts with magic */
 #define LUKS_MAGIC {'L','U','K','S', 0xba, 0xbe};
 #define LUKS_MAGIC_L 6
 
--- cryptsetup-1.6.1/lib/utils.c 
+++ luksutils.c 
@@ -28,6 +28,7 @@
 #include <sys/mman.h>
 #include <sys/resource.h>
 
+#include "libcryptsetup.h"
 #include "internal.h"
 
 unsigned crypt_getpagesize(void)
--- cryptsetup-1.6.1/lib/setup.c 
+++ setup.c 
@@ -32,7 +32,6 @@
 #include "luks.h"
 #include "loopaes.h"
 #include "verity.h"
-#include "tcrypt.h"
 #include "internal.h"
 
 struct crypt_device {
@@ -74,10 +73,12 @@
 		unsigned int root_hash_size;
 		char *uuid;
 	} verity;
+#if CM_UNSUPPORTED
 	struct { /* used in CRYPT_TCRYPT */
 		struct crypt_params_tcrypt params;
 		struct tcrypt_phdr hdr;
 	} tcrypt;
+#endif
 	} u;
 
 	/* callbacks definitions */
@@ -91,6 +92,26 @@
 	/* last error message */
 	char error[MAX_ERROR_LENGTH];
 };
+
+
+/* cryptmount helper routines: */
+struct device *crypt_get_device(struct crypt_device *luks_ctxt)
+{
+    return luks_ctxt->device;
+}
+
+struct luks_phdr *crypt_get_lukshdr(struct crypt_device *luks_ctxt)
+{
+    return &luks_ctxt->u.luks1.hdr;
+}
+
+void crypt_get_pbkdf2params(struct crypt_device *luks_ctxt,
+                            uint64_t **ittime_ptr, uint64_t **persec_ptr)
+{
+    *ittime_ptr = &luks_ctxt->iteration_time;
+    *persec_ptr = &luks_ctxt->u.luks1.PBKDF2_per_sec;
+}
+
 
 /* Global error */
 /* FIXME: not thread safe, remove this later */
@@ -627,6 +648,9 @@
 	return r;
 }
 
+
+#if CM_UNSUPPORTED
+
 static int _crypt_load_tcrypt(struct crypt_device *cd, struct crypt_params_tcrypt *params)
 {
 	int r;
@@ -656,6 +680,10 @@
 	return r;
 }
 
+#endif  /* CM_UNSUPPORTED */
+
+#if HAVE_UUID
+
 static int _crypt_load_verity(struct crypt_device *cd, struct crypt_params_verity *params)
 {
 	int r;
@@ -692,6 +720,9 @@
 
 	return r;
 }
+
+#endif  /* HAVE_UUID */
+
 
 static int _init_by_name_crypt(struct crypt_device *cd, const char *name)
 {
@@ -756,9 +787,11 @@
 			cd->type = NULL;
 			r = 0;
 		}
+#if CM_UNSUPPORTED
 	} else if (isTCRYPT(cd->type)) {
 		r = TCRYPT_init_by_name(cd, name, &dmd, &cd->device,
 					&cd->u.tcrypt.params, &cd->u.tcrypt.hdr);
+#endif
 	}
 out:
 	crypt_free_volume_key(dmd.u.crypt.vk);
@@ -896,6 +929,8 @@
 	return crypt_init_by_name_and_header(cd, name, NULL);
 }
 
+#if HAVE_UUID
+
 static int _crypt_format_plain(struct crypt_device *cd,
 			       const char *cipher,
 			       const char *cipher_mode,
@@ -1212,6 +1247,8 @@
 	return r;
 }
 
+#endif	/* HAVE_UUID */
+
 int crypt_load(struct crypt_device *cd,
 	       const char *requested_type,
 	       void *params)
@@ -1231,18 +1268,22 @@
 		}
 
 		r = _crypt_load_luks1(cd, 1, 0);
+#if HAVE_UUID
 	} else if (isVERITY(requested_type)) {
 		if (cd->type && !isVERITY(cd->type)) {
 			log_dbg("Context is already initialised to type %s", cd->type);
 			return -EINVAL;
 		}
 		r = _crypt_load_verity(cd, params);
+#endif  /* HAVE_UUID */
+#if CM_UNSUPPORTED
 	} else if (isTCRYPT(requested_type)) {
 		if (cd->type && !isTCRYPT(cd->type)) {
 			log_dbg("Context is already initialised to type %s", cd->type);
 			return -EINVAL;
 		}
 		r = _crypt_load_tcrypt(cd, params);
+#endif
 	} else
 		return -EINVAL;
 
@@ -1331,6 +1372,9 @@
 	return r;
 }
 
+
+#if HAVE_UUID
+
 int crypt_set_uuid(struct crypt_device *cd, const char *uuid)
 {
 	if (!isLUKS(cd->type)) {
@@ -1354,6 +1398,9 @@
 
 	return LUKS_hdr_uuid_set(&cd->u.luks1.hdr, uuid, cd);
 }
+
+#endif  /* HAVE_UUID */
+
 
 int crypt_header_backup(struct crypt_device *cd,
 			const char *requested_type,
@@ -1578,6 +1625,8 @@
 	return crypt_resume_by_keyfile_offset(cd, name, keyslot,
 					      keyfile, keyfile_size, 0);
 }
+
+#if HAVE_UUID
 
 // slot manipulation
 int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
@@ -1879,6 +1928,8 @@
 	return LUKS_del_key(keyslot, &cd->u.luks1.hdr, cd);
 }
 
+#endif	/* HAVE_UUID */
+
 // activation/deactivation of device mapping
 int crypt_activate_by_passphrase(struct crypt_device *cd,
 	const char *name,
@@ -2127,11 +2178,13 @@
 			if (cd->u.verity.root_hash)
 				memcpy(cd->u.verity.root_hash, volume_key, volume_key_size);
 		}
+#if CM_UNSUPPORTED
 	} else if (isTCRYPT(cd->type)) {
 		if (!name)
 			return 0;
 		r = TCRYPT_activate(cd, name, &cd->u.tcrypt.hdr,
 				    &cd->u.tcrypt.params, flags);
+#endif
 	} else
 		log_err(cd, _("Device type is not properly initialised.\n"));
 
@@ -2160,9 +2213,11 @@
 	switch (crypt_status(cd, name)) {
 		case CRYPT_ACTIVE:
 		case CRYPT_BUSY:
+#if CM_UNSUPPORTED
 			if (isTCRYPT(cd->type))
 				r = TCRYPT_deactivate(cd, name);
 			else
+#endif
 				r = dm_remove_device(cd, name, 0, 0);
 			if (r < 0 && crypt_status(cd, name) == CRYPT_BUSY) {
 				log_err(cd, _("Device %s is still in use.\n"), name);
@@ -2213,8 +2268,10 @@
 	} else if (isLUKS(cd->type)) {
 		r = LUKS_open_key_with_hdr(keyslot, passphrase,
 					passphrase_size, &cd->u.luks1.hdr, &vk, cd);
+#if CM_UNSUPPORTED
 	} else if (isTCRYPT(cd->type)) {
 		r = TCRYPT_get_volume_key(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params, &vk);
+#endif
 	} else
 		log_err(cd, _("This operation is not supported for %s crypt device.\n"), cd->type ?: "(none)");
 
@@ -2410,8 +2467,10 @@
 		return _luks_dump(cd);
 	else if (isVERITY(cd->type))
 		return _verity_dump(cd);
+#if CM_UNSUPPORTED
 	else if (isTCRYPT(cd->type))
 		return TCRYPT_dump(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params);
+#endif
 
 	log_err(cd, _("Dump operation is not supported for this device type.\n"));
 	return -EINVAL;
@@ -2428,8 +2487,10 @@
 	if (isLOOPAES(cd->type))
 		return cd->u.loopaes.cipher;
 
+#if CM_UNSUPPORTED
 	if (isTCRYPT(cd->type))
 		return cd->u.tcrypt.params.cipher;
+#endif
 
 	return NULL;
 }
@@ -2445,8 +2506,10 @@
 	if (isLOOPAES(cd->type))
 		return cd->u.loopaes.cipher_mode;
 
+#if CM_UNSUPPORTED
 	if (isTCRYPT(cd->type))
 		return cd->u.tcrypt.params.mode;
+#endif
 
 	return NULL;
 }
@@ -2486,8 +2549,10 @@
 	if (isVERITY(cd->type))
 		return cd->u.verity.root_hash_size;
 
+#if CM_UNSUPPORTED
 	if (isTCRYPT(cd->type))
 		return cd->u.tcrypt.params.key_size;
+#endif
 
 	return 0;
 }
@@ -2503,8 +2568,10 @@
 	if (isLOOPAES(cd->type))
 		return cd->u.loopaes.hdr.offset;
 
+#if CM_UNSUPPORTED
 	if (isTCRYPT(cd->type))
 		return TCRYPT_get_data_offset(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params);
+#endif
 
 	return 0;
 }
@@ -2520,8 +2587,10 @@
 	if (isLOOPAES(cd->type))
 		return cd->u.loopaes.hdr.skip;
 
+#if CM_UNSUPPORTED
 	if (isTCRYPT(cd->type))
 		return TCRYPT_get_iv_offset(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params);
+#endif
 
 	return 0;
 }
@@ -2593,10 +2662,14 @@
 	if (dmd.target != DM_CRYPT && dmd.target != DM_VERITY)
 		return -ENOTSUP;
 
+#if CM_UNSUPPORTED
 	if (cd && isTCRYPT(cd->type)) {
 		cad->offset	= TCRYPT_get_data_offset(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params);
 		cad->iv_offset	= TCRYPT_get_iv_offset(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params);
 	} else {
+#else
+    {
+#endif
 		cad->offset	= dmd.u.crypt.offset;
 		cad->iv_offset	= dmd.u.crypt.iv_offset;
 	}
--- cryptsetup-1.6.1/lib/utils_crypt.c 
+++ utils_crypt.c 
@@ -33,12 +33,17 @@
 #include <fcntl.h>
 #include <termios.h>
 
+#include "internal.h"
 #include "libcryptsetup.h"
-#include "nls.h"
 #include "utils_crypt.h"
 
-#define log_dbg(x) crypt_log(NULL, CRYPT_LOG_DEBUG, x)
-#define log_err(cd, x) crypt_log(cd, CRYPT_LOG_ERROR, x)
+#ifndef DEFAULT_KEYFILE_SIZE_MAXKB
+#  define DEFAULT_KEYFILE_SIZE_MAXKB 8192
+#endif
+#ifndef DEFAULT_PASSPHRASE_SIZE_MAX
+#  define DEFAULT_PASSPHRASE_SIZE_MAX 512
+#endif
+
 
 struct safe_allocation {
 	size_t	size;
--- cryptsetup-1.6.1/lib/verity/verity.c 
+++ verity.c 
@@ -27,7 +27,9 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <netinet/in.h>
-#include <uuid/uuid.h>
+#if HAVE_UUID
+#  include <uuid/uuid.h>
+#endif
 
 #include "libcryptsetup.h"
 #include "verity.h"
@@ -51,6 +53,9 @@
 	uint8_t  _pad2[168];
 } __attribute__((packed));
 
+
+#if HAVE_UUID
+
 /* Read verity superblock from disk */
 int VERITY_read_sb(struct crypt_device *cd,
 		   uint64_t sb_offset,
@@ -145,6 +150,7 @@
 	params->hash_area_offset = sb_offset;
 	return 0;
 }
+
 
 /* Write verity superblock to disk */
 int VERITY_write_sb(struct crypt_device *cd,
@@ -200,6 +206,9 @@
 	return r;
 }
 
+#endif  /* HAVE_UUID */
+
+
 /* Calculate hash offset in hash blocks */
 uint64_t VERITY_hash_offset_block(struct crypt_params_verity *params)
 {
@@ -213,6 +222,9 @@
 
 	return hash_offset / params->hash_block_size;
 }
+
+
+#if HAVE_UUID
 
 int VERITY_UUID_generate(struct crypt_device *cd, char **uuid_string)
 {
@@ -224,6 +236,9 @@
 	uuid_unparse(uuid, *uuid_string);
 	return 0;
 }
+
+#endif  /* HAVE_UUID */
+
 
 /* Activate verity device in kernel device-mapper */
 int VERITY_activate(struct crypt_device *cd,
