diff -ruN busybox-1.00-pre7/Makefile busybox-1.00-pre7.new/Makefile
--- busybox-1.00-pre7/Makefile	2003-11-17 11:26:43.000000000 +0100
+++ busybox-1.00-pre7.new/Makefile	2004-02-17 03:10:43.975317464 +0100
@@ -216,7 +216,7 @@
 	    docs/busybox.pdf docs/busybox.pod docs/busybox.net/busybox.html \
 	    docs/busybox pod2htm* *.gdb *.elf *~ core .*config.log \
 	    docs/BusyBox.txt docs/BusyBox.1 docs/BusyBox.html \
-	    docs/busybox.net/BusyBox.html busybox.links libbb/loop.h \
+	    docs/busybox.net/BusyBox.html busybox.links \
 	    .config.old .hdepend busybox
 	- rm -rf _install
 	- find . -name .\*.flags -exec rm -f {} \;   
diff -ruN busybox-1.00-pre7/include/libbb.h busybox-1.00-pre7.new/include/libbb.h
--- busybox-1.00-pre7/include/libbb.h	2004-01-17 06:03:30.000000000 +0100
+++ busybox-1.00-pre7.new/include/libbb.h	2004-02-17 03:32:09.981814760 +0100
@@ -232,7 +232,9 @@
 extern int device_open(const char *device, int mode);
 
 extern int del_loop(const char *device);
-extern int set_loop(const char *device, const char *file, int offset, int *loopro);
+extern int set_loop(const char *device, const char *file, int offset,
+		    const char *encnum, const char *encryption, 
+		    int pfd, int *loopro);
 extern char *find_unused_loop_device (void);
 
 
diff -ruN busybox-1.00-pre7/libbb/Makefile.in busybox-1.00-pre7.new/libbb/Makefile.in
--- busybox-1.00-pre7/libbb/Makefile.in	2003-11-10 05:33:54.000000000 +0100
+++ busybox-1.00-pre7.new/libbb/Makefile.in	2004-02-17 03:10:44.024310016 +0100
@@ -98,7 +98,4 @@
 
 $(LIBBB_DIR)loop.o: $(LIBBB_DIR)loop.h
 
-$(LIBBB_DIR)loop.h: $(LIBBB_DIR)mk_loop_h.sh
-	@ $(SHELL) $< > $@
-
 
diff -ruN busybox-1.00-pre7/libbb/loop.c busybox-1.00-pre7.new/libbb/loop.c
--- busybox-1.00-pre7/libbb/loop.c	2003-07-14 23:20:55.000000000 +0200
+++ busybox-1.00-pre7.new/libbb/loop.c	2004-02-17 03:24:49.817729872 +0100
@@ -20,11 +20,14 @@
  */
 
 #include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <string.h>
 #include <unistd.h>
 #include <sys/ioctl.h>
+#include <signal.h>
 #include "libbb.h"
 #include "loop.h" /* Pull in loop device support */
 
@@ -45,11 +48,23 @@
 	return (TRUE);
 }
 
+static int
+digits_only(const char *s) {
+	while (*s)
+		if (!isdigit(*s++))
+			return 0;
+	return 1;
+}
+
 extern int set_loop(const char *device, const char *file, int offset,
-					int *loopro)
+					const char *encnumber,
+					const char *encryption,
+					int pfd, int *loopro)
 {
-	struct loop_info loopinfo;
+//	struct loop_info loopinfo;
+	struct loop_info64 loopinfo64;
 	int fd, ffd, mode;
+	char *pass;
 
 	mode = *loopro ? O_RDONLY : O_RDWR;
 	if ((ffd = open(file, mode)) < 0 && !*loopro
@@ -64,19 +79,68 @@
 	}
 	*loopro = (mode == O_RDONLY);
 
-	memset(&loopinfo, 0, sizeof(loopinfo));
-	safe_strncpy(loopinfo.lo_name, file, LO_NAME_SIZE);
-
-	loopinfo.lo_offset = offset;
+	memset(&loopinfo64, 0, sizeof(loopinfo64));
+	safe_strncpy(loopinfo64.lo_file_name, file, LO_NAME_SIZE);
+	
+	if (encryption && *encryption) {
+		if (digits_only(encryption)) {
+			loopinfo64.lo_encrypt_type = atoi(encryption);
+		} else {
+			char *mark=strrchr(encryption,'-');
+			loopinfo64.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
+			if (mark && digits_only(mark+1))
+				loopinfo64.lo_encrypt_key_size =
+				atoi(mark)/8;
+			else {
+				fprintf(stderr,
+				  "You must specify a key size (in bits)"
+				  "for use with CryptoAPI encryption.\n");
+				return -1;
+			}
+			*mark='\0';
+			snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
+				 "%s", encryption);
+		}
+	}
+	
+	if (encnumber && *encnumber) {
+		if (digits_only(encnumber))
+			loopinfo64.lo_encrypt_type = atoi(encnumber);
+	}
+
+	loopinfo64.lo_offset = offset;
+
+	if (loopinfo64.lo_encrypt_type==LO_CRYPT_NONE)
+		loopinfo64.lo_encrypt_key_size = 0;
+	else {
+		if (pfd == -1) {
+			pass = getpass("Password: ");
+			safe_strncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
+		} else {
+			/* If we're reading from an extenral program,	*
+			 * odds are good that a SIGCHLD will interrupt	*
+			 * this read(), and ruin our whole day. So we	*
+			 * must block it.				*/
+			sigset_t ss, oss;
+			sigemptyset(&ss);
+			sigaddset(&ss, SIGCHLD);
+			sigprocmask(SIG_BLOCK, &ss, &oss);
+			if (read(pfd, loopinfo64.lo_encrypt_key,
+				 LO_KEY_SIZE) == -1) {
+				bb_perror_msg("read");
+				fprintf(stderr, "Error reading encryption key, exiting\n");
+			}
+			sigprocmask(SIG_SETMASK, &oss, NULL);
+		}
+	}
 
-	loopinfo.lo_encrypt_key_size = 0;
 	if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
 		bb_perror_msg("ioctl: LOOP_SET_FD");
 		close(fd);
 		close(ffd);
 		return 1;
 	}
-	if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) {
+	if (ioctl(fd, LOOP_SET_STATUS64, &loopinfo64) < 0) {
 		(void) ioctl(fd, LOOP_CLR_FD, 0);
 		bb_perror_msg("ioctl: LOOP_SET_STATUS");
 		close(fd);
diff -ruN busybox-1.00-pre7/libbb/loop.h busybox-1.00-pre7.new/libbb/loop.h
--- busybox-1.00-pre7/libbb/loop.h	1970-01-01 01:00:00.000000000 +0100
+++ busybox-1.00-pre7.new/libbb/loop.h	2004-02-17 03:19:38.140112072 +0100
@@ -0,0 +1,52 @@
+#define LO_CRYPT_NONE	0
+#define LO_CRYPT_XOR	1
+#define LO_CRYPT_DES	2
+#define LO_CRYPT_CRYPTOAPI 18
+#define LO_CRYPT_COMPRESS  19
+
+#define LOOP_SET_FD		0x4C00
+#define LOOP_CLR_FD		0x4C01
+#define LOOP_SET_STATUS		0x4C02
+#define LOOP_GET_STATUS		0x4C03
+#define LOOP_SET_STATUS64	0x4C04
+#define LOOP_GET_STATUS64	0x4C05
+
+#define LO_NAME_SIZE	64
+#define LO_KEY_SIZE	32
+
+#include "my_dev_t.h"
+
+struct loop_info {
+	int		lo_number;
+	my_dev_t	lo_device;
+	unsigned long	lo_inode;
+	my_dev_t	lo_rdevice;
+	int		lo_offset;
+	int		lo_encrypt_type;
+	int		lo_encrypt_key_size;
+	int		lo_flags;
+	char		lo_name[LO_NAME_SIZE];
+	unsigned char	lo_encrypt_key[LO_KEY_SIZE];
+	unsigned long	lo_init[2];
+	char		reserved[4];
+};
+
+/*
+ * Where to get __u8, __u32, __u64? Let us use unsigned char/int/long long
+ * and get punished when someone comes with 128-bit long longs.
+ */
+struct loop_info64 {
+	unsigned long long	lo_device;
+	unsigned long long	lo_inode;
+	unsigned long long	lo_rdevice;
+	unsigned long long	lo_offset;
+	unsigned long long	lo_sizelimit; /* bytes, 0 == max available */
+	unsigned int		lo_number;
+	unsigned int		lo_encrypt_type;
+	unsigned int		lo_encrypt_key_size;
+	unsigned int		lo_flags;
+	unsigned char		lo_file_name[LO_NAME_SIZE];
+	unsigned char		lo_crypt_name[LO_NAME_SIZE];
+	unsigned char		lo_encrypt_key[LO_KEY_SIZE];
+	unsigned long long	lo_init[2];
+};
diff -ruN busybox-1.00-pre7/libbb/mk_loop_h.sh busybox-1.00-pre7.new/libbb/mk_loop_h.sh
--- busybox-1.00-pre7/libbb/mk_loop_h.sh	2001-02-17 01:42:47.000000000 +0100
+++ busybox-1.00-pre7.new/libbb/mk_loop_h.sh	1970-01-01 01:00:00.000000000 +0100
@@ -1,37 +0,0 @@
-#!/bin/sh
-#
-# Figure out (i) the type of dev_t (ii) the defines for loop stuff
-#
-# Output of this script is normally redirected to "loop.h".
-
-# Since 1.3.79 there is an include file <asm/posix_types.h>
-# that defines __kernel_dev_t.
-# (The file itself appeared in 1.3.78, but there it defined __dev_t.)
-# If it exists, we use it, or, rather, <linux/posix_types.h> which
-# avoids namespace pollution.  Otherwise we guess that __kernel_dev_t
-# is an unsigned short (which is true on i386, but false on alpha).
-
-# BUG: This test is actually broken if your gcc is not configured to
-# search /usr/include, as may well happen with cross-compilers.
-# It would be better to ask $(CC) if these files can be found.
-
-if [ -f /usr/include/linux/posix_types.h ]; then
-   echo '#include <linux/posix_types.h>'
-   echo '#undef dev_t'
-   echo '#define dev_t __kernel_dev_t'
-else
-   echo '#undef dev_t'
-   echo '#define dev_t unsigned short'
-fi
-
-# Next we have to find the loop stuff itself.
-# First try kernel source, then a private version.
-
-if [ -f /usr/include/linux/loop.h ]; then
-   echo '#include <linux/loop.h>'
-else
-   echo '#include "real_loop.h"'
-fi
-
-echo '#undef dev_t'
-
diff -ruN busybox-1.00-pre7/libbb/my_dev_t.h busybox-1.00-pre7.new/libbb/my_dev_t.h
--- busybox-1.00-pre7/libbb/my_dev_t.h	1970-01-01 01:00:00.000000000 +0100
+++ busybox-1.00-pre7.new/libbb/my_dev_t.h	2004-02-17 03:10:44.161289192 +0100
@@ -0,0 +1,13 @@
+/* silliness to get dev_t defined as the kernel defines it */
+/* glibc uses a different dev_t */
+/* maybe we need __kernel_old_dev_t -- later */
+/* for ancient systems use "unsigned short" */
+
+#include <linux/posix_types.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+#define my_dev_t __kernel_dev_t
+#else
+#define my_dev_t int
+#endif
diff -ruN busybox-1.00-pre7/libbb/new_loop.h busybox-1.00-pre7.new/libbb/new_loop.h
--- busybox-1.00-pre7/libbb/new_loop.h	1970-01-01 01:00:00.000000000 +0100
+++ busybox-1.00-pre7.new/libbb/new_loop.h	2004-02-17 03:10:44.162289040 +0100
@@ -0,0 +1,51 @@
+#define LO_CRYPT_NONE	0
+#define LO_CRYPT_XOR	1
+#define LO_CRYPT_DES	2
+#define LO_CRYPT_CRYPTOAPI 18
+
+#define LOOP_SET_FD		0x4C00
+#define LOOP_CLR_FD		0x4C01
+#define LOOP_SET_STATUS		0x4C02
+#define LOOP_GET_STATUS		0x4C03
+#define LOOP_SET_STATUS64	0x4C04
+#define LOOP_GET_STATUS64	0x4C05
+
+#define LO_NAME_SIZE	64
+#define LO_KEY_SIZE	32
+
+#include "my_dev_t.h"
+
+struct loop_info {
+	int		lo_number;
+	my_dev_t	lo_device;
+	unsigned long	lo_inode;
+	my_dev_t	lo_rdevice;
+	int		lo_offset;
+	int		lo_encrypt_type;
+	int		lo_encrypt_key_size;
+	int		lo_flags;
+	char		lo_name[LO_NAME_SIZE];
+	unsigned char	lo_encrypt_key[LO_KEY_SIZE];
+	unsigned long	lo_init[2];
+	char		reserved[4];
+};
+
+/*
+ * Where to get __u8, __u32, __u64? Let us use unsigned char/int/long long
+ * and get punished when someone comes with 128-bit long longs.
+ */
+struct loop_info64 {
+	unsigned long long	lo_device;
+	unsigned long long	lo_inode;
+	unsigned long long	lo_rdevice;
+	unsigned long long	lo_offset;
+	unsigned long long	lo_sizelimit; /* bytes, 0 == max available */
+	unsigned int		lo_number;
+	unsigned int		lo_encrypt_type;
+	unsigned int		lo_encrypt_key_size;
+	unsigned int		lo_flags;
+	unsigned char		lo_file_name[LO_NAME_SIZE];
+	unsigned char		lo_crypt_name[LO_NAME_SIZE];
+	unsigned char		lo_encrypt_key[LO_KEY_SIZE];
+	unsigned long long	lo_init[2];
+};
Files busybox-1.00-pre7/losetup and busybox-1.00-pre7.new/losetup differ
diff -ruN busybox-1.00-pre7/util-linux/losetup.c busybox-1.00-pre7.new/util-linux/losetup.c
--- busybox-1.00-pre7/util-linux/losetup.c	2003-07-30 10:55:59.000000000 +0200
+++ busybox-1.00-pre7.new/util-linux/losetup.c	2004-02-17 03:25:10.157637736 +0100
@@ -29,19 +29,31 @@
 {
   int delete = 0;
   int offset = 0;
-  int opt;
+  int opt, pfd = -1;
+  char *encryption=NULL, *encnum=NULL;
 
-  while ((opt = getopt (argc, argv, "do:")) != -1)
+  while ((opt = getopt (argc, argv, "do:E:e:p:")) != -1)
     switch (opt)
       {
       case 'd':
 	delete = 1;
 	break;
 
-      case 'o':
+      case 'o':	
 	offset = bb_xparse_number (optarg, NULL);
 	break;
 
+      case 'E':
+      	encnum = optarg;
+	break;
+      case 'e':
+	encryption = optarg;
+	break;
+	
+      case 'p':
+      	pfd = bb_xparse_number (optarg,NULL);
+	break;
+
       default:
 	bb_show_usage();
       }
@@ -54,6 +66,7 @@
   if (delete)
     return del_loop (argv[optind]) ? EXIT_SUCCESS : EXIT_FAILURE;
   else
-    return set_loop (argv[optind], argv[optind + 1], offset, &opt)
+    return set_loop (argv[optind], argv[optind + 1], offset, encnum,
+					encryption, pfd, &opt)
       ? EXIT_FAILURE : EXIT_SUCCESS;
 }
diff -ruN busybox-1.00-pre7/util-linux/mount.c busybox-1.00-pre7.new/util-linux/mount.c
--- busybox-1.00-pre7/util-linux/mount.c	2003-12-12 08:01:14.000000000 +0100
+++ busybox-1.00-pre7.new/util-linux/mount.c	2004-02-17 03:25:00.982032640 +0100
@@ -142,7 +142,7 @@
 			if (specialfile == NULL) {
 				bb_error_msg_and_die("Could not find a spare loop device");
 			}
-			if (set_loop(specialfile, lofile, 0, &loro)) {
+			if (set_loop(specialfile, lofile, 0,NULL,NULL,-1, &loro)) {
 				bb_error_msg_and_die("Could not setup loop device");
 			}
 			if (!(flags & MS_RDONLY) && loro) {	/* loop is ro, but wanted rw */
