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) {