PATCH 1/2: variable key length for losetup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch allows losetup and mount to do cryptoloop encryption with keys
of size other than 256 bits. For example, to use 128-bit AES-CBC encryption,
the syntax is:

losetup -e aes-cbc-128 /dev/loop/10 /home/sluskyb/testloop
or
mount -o loop,encryption=aes-cbc-128 /home/sluskyb/testloop /mnt/testloop

I figured that since we're now requiring the user to add the -cbc (or -ctr
etc.), -128 would fit in.

This is implemented using POSIX regular expressions. I'm not particularly 
proud of that, but I think if we want to specify key size within the existing
encryption= option then that's the best way to go.

QCF?

-- 
Ben Slusky                      |    You must be smarter than 
sluskyb@xxxxxxxxxxxxxx          | <= this stick to ride the
sluskyb@xxxxxxxxxx              |    internet.
PGP keyID ADA44B3B      
--- lomount.c-fixed-key-size	2003-07-16 19:56:53.000000000 -0400
+++ lomount.c	2003-08-02 19:25:01.000000000 -0400
@@ -24,12 +24,15 @@
 #include <ctype.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <limits.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <sys/types.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
 #include <sys/sysmacros.h>
+#include <regex.h>
 
 #include "loop.h"
 #include "lomount.h"
@@ -249,8 +252,10 @@
 set_loop(const char *device, const char *file, int offset,
 	 const char *encryption, int pfd, int *loopro) {
 	struct loop_info64 loopinfo64;
-	int fd, ffd, mode;
-	char *pass;
+	int fd, ffd, mode, keysize = 0, rerror;
+	char *pass, *encryption_buf, rerror_buf[LINE_MAX+1];
+	regex_t keysize_re;
+	regmatch_t keysize_rm;
 
 	mode = (*loopro ? O_RDONLY : O_RDWR);
 	if ((ffd = open(file, mode)) < 0) {
@@ -276,8 +281,38 @@
 			loopinfo64.lo_encrypt_type = atoi(encryption);
 		} else {
 			loopinfo64.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
+
+			if((encryption_buf = strdup(encryption)) == NULL) {
+				perror("strdup");
+				fprintf(stderr,
+					_("Couldn't allocate memory, exiting.\n"));
+				exit(1);
+			}
+
+			if ((rerror = regcomp(&keysize_re,
+					      "-[[:digit:]]+$",
+					      REG_EXTENDED)) != 0) {
+				fprintf(stderr, _("regcomp: "));	
+				regerror(rerror, &keysize_re, rerror_buf,
+					 LINE_MAX);
+				fprintf(stderr, "%s\n", rerror_buf);
+			} else {
+				if (regexec(&keysize_re, encryption_buf,
+				   	    1, &keysize_rm, 0) == 0) {
+					keysize = atoi(encryption_buf +
+						       keysize_rm.rm_so + 1);
+					/* convert #bits to #bytes */
+					keysize /= 8;
+					/* cut the keysize out now */
+					encryption_buf[keysize_rm.rm_so] = '\0';
+				}
+
+				regfree(&keysize_re);
+			}
+			
 			snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
-				 "%s", encryption);
+				 "%s", encryption_buf);
+			free(encryption_buf);
 		}
 	}
 
@@ -307,9 +342,14 @@
 			strlen(loopinfo64.lo_encrypt_key);
 		break;
 	default:
+		if (keysize == 0) {
+			fprintf(stderr, _("You must specify a key size (in bits) for use with CryptoAPI encryption.\n"));
+			return -1;
+		}
+		/* FIXME we should be checking keysize against the min/max in /proc/crypto */
 		pass = xgetpass(pfd, _("Password: "));
 		xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
-		loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;
+		loopinfo64.lo_encrypt_key_size = keysize;
 	}
 
 	if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {

[Index of Archives]     [Kernel]     [Linux Crypto]     [Gnu Crypto]     [Gnu Classpath]     [Netfilter]     [Bugtraq]
  Powered by Linux