diff -Nur util-linux-2.11zorg/mount/Makefile util-linux-2.11z/mount/Makefile --- util-linux-2.11zorg/mount/Makefile Tue Nov 26 09:53:59 2002 +++ util-linux-2.11z/mount/Makefile Fri Mar 28 21:43:00 2003 @@ -24,7 +24,7 @@ MAYBE = pivot_root swapoff -LO_OBJS = lomount.o $(LIB)/xstrncpy.o +LO_OBJS = lomount.o $(LIB)/xstrncpy.o sha512.o rmd160.o NFS_OBJS = nfsmount.o nfsmount_xdr.o nfsmount_clnt.o GEN_FILES = nfsmount.h nfsmount_xdr.c nfsmount_clnt.c @@ -57,9 +57,13 @@ main_losetup.o: lomount.c $(COMPILE) -DMAIN lomount.c -o $@ -losetup: main_losetup.o $(LIB)/xstrncpy.o +losetup: main_losetup.o $(LIB)/xstrncpy.o sha512.o rmd160.o $(LINK) $^ -o $@ +rmd160.o lomount.o main_losetup.o: rmd160.h + +sha512.o lomount.o main_losetup.o: sha512.h + mount.o umount.o nfsmount.o losetup.o fstab.o realpath.o sundries.o: sundries.h mount.o umount.o fstab.o sundries.o: fstab.h diff -Nur util-linux-2.11zorg/mount/lomount.c util-linux-2.11z/mount/lomount.c --- util-linux-2.11zorg/mount/lomount.c Fri Nov 1 01:58:51 2002 +++ util-linux-2.11z/mount/lomount.c Fri Mar 28 21:43:00 2003 @@ -6,6 +6,11 @@ * - added Native Language Support * Sun Mar 21 1999 - Arnaldo Carvalho de Melo * - fixed strerr(errno) in gettext calls + * 2000-09-24 Marc Mutz + * - added long option names and the --pass-fd option to pass + * passphrases via fd's to losetup/mount. Used for encryption in + * non-interactive environments. The idea behind xgetpass() is stolen + * from GnuPG, v.1.0.3 (http://www.gnupg.org/). */ #define PROC_DEVICES "/proc/devices" @@ -21,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -28,48 +34,102 @@ #include "loop.h" #include "lomount.h" +#include "rmd160.h" +#include "sha512.h" #include "xstrncpy.h" #include "nls.h" +#ifndef LO_CRYPT_CRYPTOAPI +#define LO_CRYPT_CRYPTOAPI 18 +#endif +#ifndef LO_CRYPT_NONE +#define LO_CRYPT_NONE 0 +#endif +#ifndef LO_CRYPT_XOR +#define LO_CRYPT_XOR 1 +#endif +#ifndef LO_CRYPT_DES +#define LO_CRYPT_DES 2 +#endif +#ifndef LO_CRYPT_FISH2 +#define LO_CRYPT_FISH2 3 +#endif +#ifndef LO_CRYPT_BLOW +#define LO_CRYPT_BLOW 4 +#endif +#ifndef LO_CRYPT_CAST128 +#define LO_CRYPT_CAST128 5 +#endif +#ifndef LO_CRYPT_IDEA +#define LO_CRYPT_IDEA 6 +#endif +#ifndef LO_CRYPT_SERPENT +#define LO_CRYPT_SERPENT 7 +#endif +#ifndef LO_CRYPT_MARS +#define LO_CRYPT_MARS 8 +#endif +#ifndef LO_CRYPT_RC6 +#define LO_CRYPT_RC6 11 +#endif +#ifndef LO_CRYPT_3DES +#define LO_CRYPT_3DES 12 +#endif +#ifndef LO_CRYPT_DFC +#define LO_CRYPT_DFC 15 +#endif +#ifndef LO_CRYPT_RIJNDAEL +#define LO_CRYPT_RIJNDAEL 16 +#endif + + extern int verbose; extern char *xstrdup (const char *s); /* not: #include "sundries.h" */ extern void error (const char *fmt, ...); /* idem */ + +struct cipher_info +{ + const char *name; + int blocksize; + int keysize_mask; + int ivsize; + int key_schedule_size; +}; + +static int set_loop_passwd(struct loop_info *_loopinfo, int pfd, int keysz, + const char *phash_name, const char *encryption, + int fd, int ffd); +static int get_cipher_info(const char *name, struct cipher_info *res); +static int name_to_id(const char *name); +#ifdef MAIN +static char *id_to_name(int id); +#endif + + #ifdef LOOP_SET_FD struct crypt_type_struct { int id; char *name; + int keylength; } crypt_type_tbl[] = { - { LO_CRYPT_NONE, "no" }, - { LO_CRYPT_NONE, "none" }, - { LO_CRYPT_XOR, "xor" }, - { LO_CRYPT_DES, "DES" }, - { -1, NULL } + { LO_CRYPT_NONE, "none", 0 }, + { LO_CRYPT_XOR, "xor", 0 }, + { LO_CRYPT_DES, "des", 8 }, + { LO_CRYPT_FISH2, "twofish", 20 }, + { LO_CRYPT_BLOW, "blowfish", 20 }, + { LO_CRYPT_CAST128, "cast", 16 }, + { LO_CRYPT_SERPENT, "serpent", 16 }, + { LO_CRYPT_MARS, "mars", 16 }, + { LO_CRYPT_RC6, "rc6", 16 }, + { LO_CRYPT_3DES, "des-ede3", 24 }, + { LO_CRYPT_DFC, "dfc", 16 }, + { LO_CRYPT_IDEA, "idea", 16 }, + { LO_CRYPT_RIJNDAEL, "rijndael", 16 }, + { -1, NULL,0 } }; -static int -crypt_type (const char *name) { - int i; - - if (name) { - for (i = 0; crypt_type_tbl[i].id != -1; i++) - if (!strcasecmp (name, crypt_type_tbl[i].name)) - return crypt_type_tbl[i].id; - } - return -1; -} - #ifdef MAIN -static char * -crypt_name (int id) { - int i; - - for (i = 0; crypt_type_tbl[i].id != -1; i++) - if (id == crypt_type_tbl[i].id) - return crypt_type_tbl[i].name; - return "undefined"; -} - static int show_loop (char *device) { struct loop_info loopinfo; @@ -91,7 +151,7 @@ printf (_("%s: [%04x]:%ld (%s) offset %d, %s encryption\n"), device, loopinfo.lo_device, loopinfo.lo_inode, loopinfo.lo_name, loopinfo.lo_offset, - crypt_name (loopinfo.lo_encrypt_type)); + id_to_name(loopinfo.lo_encrypt_type)); close (fd); return 0; @@ -184,24 +244,62 @@ error(_( "mount: Could not find any loop device, and, according to %s,\n" " this kernel does not know about the loop device.\n" - " (If so, then recompile or `insmod loop.o'.)"), + " (If so, then recompile or `modprobe loop'.)"), PROC_DEVICES); else error(_( "mount: Could not find any loop device. Maybe this kernel does not know\n" - " about the loop device (then recompile or `insmod loop.o'), or\n" + " about the loop device (then recompile or `modprobe loop'), or\n" " maybe /dev/loop# has the wrong major number?")); } else error(_("mount: could not find any free loop device")); return 0; } +/* A function to read the passphrase either from the terminal or from + * an open file descriptor */ +static char * +xgetpass (int pfd, const char *prompt) +{ + if (pfd < 0) /* terminal */ + return (getpass(prompt)); + else { /* file descriptor */ + char *pass = NULL; + int buflen, i; + + buflen=0; + for (i=0; ; i++) { + if (i >= buflen-1) { + /* we're running out of space in the buffer. + * Make it bigger: */ + char *tmppass = pass; + buflen += 128; + pass = realloc(tmppass,buflen); + if (pass == NULL) { + /* realloc failed. Stop reading _now_. */ + error("not enough memory while reading passphrase"); + pass = tmppass; /* the old buffer hasn't changed */ + break; + } + }; + if ( read(pfd,pass+i, 1) != 1 || pass[i] == '\n' ) + break; + } + if (pass == NULL) + return ""; + else { + pass[i] = 0; + return pass; + } + } +} + int set_loop (const char *device, const char *file, int offset, - const char *encryption, int *loopro) { + const char *encryption, int pfd, int keysz, int *loopro, + const char *phash_name) { struct loop_info loopinfo; - int fd, ffd, mode, i; - char *pass; + int fd, ffd, mode, tried_old; mode = (*loopro ? O_RDONLY : O_RDWR); if ((ffd = open (file, mode)) < 0) { @@ -219,13 +317,10 @@ *loopro = (mode == O_RDONLY); memset (&loopinfo, 0, sizeof (loopinfo)); - xstrncpy (loopinfo.lo_name, file, LO_NAME_SIZE); - if (encryption && (loopinfo.lo_encrypt_type = crypt_type (encryption)) - < 0) { - fprintf (stderr, _("Unsupported encryption type %s\n"), - encryption); - return 1; - } + snprintf(loopinfo.lo_name, sizeof(loopinfo.lo_name), + "%s-cbc", encryption); + loopinfo.lo_name[LO_NAME_SIZE - 1] = 0; + loopinfo.lo_encrypt_type = LO_CRYPT_CRYPTOAPI; loopinfo.lo_offset = offset; #ifdef MCL_FUTURE @@ -241,24 +336,148 @@ } #endif - switch (loopinfo.lo_encrypt_type) { + if (ioctl (fd, LOOP_SET_FD, ffd) < 0) { + perror ("ioctl: LOOP_SET_FD"); + return 1; + } + + tried_old = 0; +again: + set_loop_passwd(&loopinfo, pfd, keysz, phash_name, encryption, fd, ffd); + + if (ioctl (fd, LOOP_SET_STATUS, &loopinfo) < 0) { + /* Try again with old-style LO_CRYPT_XX if + new-style LO_CRYPT_CRYPTOAPI ioctl didn't work */ + if (tried_old) { + error("The cipher does not exist, or a cipher module " + "needs to be loaded into the kernel"); + perror ("ioctl: LOOP_SET_STATUS"); + goto out_ioctl; + } + strncpy (loopinfo.lo_name, file, LO_NAME_SIZE); + loopinfo.lo_name[LO_NAME_SIZE - 1] = 0; + loopinfo.lo_encrypt_type = name_to_id (encryption); + tried_old = 1; + goto again; + } + close (fd); + close (ffd); + if (verbose > 1) + printf(_("set_loop(%s,%s,%d): success\n"), + device, file, offset); + return 0; +out_ioctl: + (void) ioctl (fd, LOOP_CLR_FD, 0); + return 1; +} + + + +typedef int (*phash_func_t)(char dest[LO_KEY_SIZE], const char src[], size_t src_len); + +#define PASSWDBUFFLEN 130 + +static int +phash_rmd160old (char dest[LO_KEY_SIZE], const char src[], size_t src_len) +{ + char tmp[PASSWDBUFFLEN] = { 'A', 0, }; + char key[RMD160_HASH_SIZE * 2] = { 0, }; + + strncpy (tmp + 1, src, PASSWDBUFFLEN - 1); + tmp[PASSWDBUFFLEN - 1] = '\0'; + + rmd160_hash_buffer(key, src, src_len); + rmd160_hash_buffer(key + RMD160_HASH_SIZE, tmp, src_len + 1 /* dangerous! */); + + memcpy (dest, key, LO_KEY_SIZE); + + return 0; +} + +static int +phash_sha256 (char dest[LO_KEY_SIZE], const char src[], size_t src_len) +{ + memset (dest, 0, LO_KEY_SIZE); + sha256_hash_buffer ((char *) src, src_len, dest, LO_KEY_SIZE); + return 0; +} + +static int +phash_sha384 (char dest[LO_KEY_SIZE], const char src[], size_t src_len) +{ + memset (dest, 0, LO_KEY_SIZE); + sha384_hash_buffer ((char *) src, src_len, dest, LO_KEY_SIZE); + return 0; +} + +static int +phash_sha512 (char dest[LO_KEY_SIZE], const char src[], size_t src_len) +{ + memset (dest, 0, LO_KEY_SIZE); + sha512_hash_buffer ((char *) src, src_len, dest, LO_KEY_SIZE); + return 0; +} + +static int +phash_default (char dest[LO_KEY_SIZE], const char src[], size_t src_len) +{ + fprintf (stderr, "unknown hash type requested\n"); + return 1; +} + +static phash_func_t +phash_lookup (const char phash_name[]) +{ + struct { + const char *name; + phash_func_t func; + } func_table[] = { + {"rmd160old", phash_rmd160old }, + {"sha256", phash_sha256 }, + {"sha384", phash_sha384 }, + {"sha512", phash_sha512 }, + { 0, phash_default } + }, *p = func_table; + + for (; p->name; p++) + if (!strcmp (phash_name, p->name)) + break; + + return p->func; +} + + +int +set_loop_passwd(struct loop_info *loopinfo, int pfd, int keysz, + const char *phash_name, const char *encryption, + int fd, int ffd) +{ + int i; + int keylength; + char *pass; + struct cipher_info info; + + switch (loopinfo->lo_encrypt_type) { case LO_CRYPT_NONE: - loopinfo.lo_encrypt_key_size = 0; + loopinfo->lo_encrypt_key_size = 0; break; case LO_CRYPT_XOR: - pass = getpass (_("Password: ")); - xstrncpy (loopinfo.lo_encrypt_key, pass, LO_KEY_SIZE); - loopinfo.lo_encrypt_key_size = strlen(loopinfo.lo_encrypt_key); + /* WARNING: xgetpass() can return massive amounts of data, + * not only 128 bytes like the original getpass(3) */ + pass = xgetpass (pfd,_("Password: ")); + xstrncpy (loopinfo->lo_encrypt_key, pass, LO_KEY_SIZE); + loopinfo->lo_encrypt_key_size = strlen(loopinfo->lo_encrypt_key); break; case LO_CRYPT_DES: - pass = getpass (_("Password: ")); - strncpy (loopinfo.lo_encrypt_key, pass, 8); - loopinfo.lo_encrypt_key[8] = 0; - loopinfo.lo_encrypt_key_size = 8; + printf(_("WARNING: Use of DES is depreciated.\n")); + pass = xgetpass (pfd,_("Password: ")); + strncpy (loopinfo->lo_encrypt_key, pass, 8); + loopinfo->lo_encrypt_key[8] = 0; + loopinfo->lo_encrypt_key_size = 8; pass = getpass (_("Init (up to 16 hex digits): ")); for (i = 0; i < 16 && pass[i]; i++) if (isxdigit (pass[i])) { - loopinfo.lo_init[i >> 3] |= (pass[i] > '9' ? + loopinfo->lo_init[i >> 3] |= (pass[i] > '9' ? (islower (pass[i]) ? toupper (pass[i]) : pass[i])-'A'+10 : pass[i]-'0') << (i&7) * 4; } else { @@ -267,29 +486,83 @@ return 1; } break; + case LO_CRYPT_FISH2: + case LO_CRYPT_BLOW: + case LO_CRYPT_IDEA: + case LO_CRYPT_CAST128: + case LO_CRYPT_SERPENT: + case LO_CRYPT_MARS: + case LO_CRYPT_RC6: + case LO_CRYPT_3DES: + case LO_CRYPT_DFC: + case LO_CRYPT_RIJNDAEL: + pass = xgetpass(pfd, _("Password: ")); + + if (phash_lookup (phash_name) (loopinfo->lo_encrypt_key, pass, strlen (pass))) + return 1; + + keylength=0; + for(i=0; crypt_type_tbl[i].id != -1; i++){ + if(loopinfo->lo_encrypt_type == crypt_type_tbl[i].id){ + keylength = crypt_type_tbl[i].keylength; + break; + } + } + loopinfo->lo_encrypt_key_size = keylength; + break; + case LO_CRYPT_CRYPTOAPI: + /* Give the kernel an opportunity to load the cipher */ + (void) ioctl (fd, LOOP_SET_STATUS, loopinfo); + if (get_cipher_info(loopinfo->lo_name, &info) < 0) { + return 1; + } + if (keysz > 0 && + !((1 << ((keysz / 8) - 1)) & info.keysize_mask)) { + error("The specified keysize is not supported by " + "the selected cipher"); + keysz = 0; + } + + while (keysz <= 0 || + !((1 << ((keysz / 8) - 1)) & info.keysize_mask)) { + int i = 0; + int available = 0; + char keysize[200]; + printf("Available keysizes (bits): "); + for (; i < 32; i++) { + if (info.keysize_mask & (1 << i)) { + printf("%d ", 8*(i+1)); + available = 1; + } + } + if (!available) { + printf("none"); + } + printf("\nKeysize: "); + fgets(keysize, sizeof(keysize), stdin); + keysz = atoi(keysize); + } + + pass = xgetpass(pfd, _("Password: ")); + + if (phash_lookup (phash_name) (loopinfo->lo_encrypt_key, pass, strlen (pass))) + return 1; + + loopinfo->lo_encrypt_key_size=keysz/8; + + break; default: fprintf (stderr, _("Don't know how to get key for encryption system %d\n"), - loopinfo.lo_encrypt_type); + loopinfo->lo_encrypt_type); return 1; } - if (ioctl (fd, LOOP_SET_FD, ffd) < 0) { - perror ("ioctl: LOOP_SET_FD"); - return 1; - } - if (ioctl (fd, LOOP_SET_STATUS, &loopinfo) < 0) { - (void) ioctl (fd, LOOP_CLR_FD, 0); - perror ("ioctl: LOOP_SET_STATUS"); - return 1; - } - close (fd); - close (ffd); - if (verbose > 1) - printf(_("set_loop(%s,%s,%d): success\n"), - device, file, offset); - return 0; + return 0; } + + + int del_loop (const char *device) { int fd; @@ -320,7 +593,7 @@ int set_loop (const char *device, const char *file, int offset, - const char *encryption, int *loopro) { + const char *encryption, int pfd, int *loopro) { mutter(); return 1; } @@ -349,12 +622,45 @@ int verbose = 0; static char *progname; +static struct option longopts[] = { + { "delete", 0, 0, 'd' }, + { "detach", 0, 0, 'd' }, + { "encryption", 1, 0, 'e' }, + { "help", 0, 0, 'h' }, + { "offset", 1, 0, 'o' }, + { "pass-fd", 1, 0, 'p' }, + { "phash", 1, 0, 'P' }, + { "verbose", 0, 0, 'v' }, + { "keybits", 1, 0, 'k' }, + { NULL, 0, 0, 0 } +}; + + static void usage(void) { - fprintf(stderr, _("usage:\n\ + fprintf(stderr, +_("usage:\n\ %s loop_device # give info\n\ %s -d loop_device # delete\n\ - %s [ -e encryption ] [ -o offset ] loop_device file # setup\n"), + %s [ options ] loop_device file # setup\n\ + where options include\n\ + --offset , -o \n\ + start at offset into file.\n\ + --pass-fd , -p \n\ + read passphrase from file descriptor \n\ + instead of the terminal.\n\ + --encryption , -e \n\ + encrypt with .\n\ + Check /proc/crypto/cipher for available ciphers.\n\ + --keybits , -k \n\ + specify number of bits in the hashed key given\n\ + to the cipher. Some ciphers support several key\n\ + sizes and might be more efficient with a smaller\n\ + key size. Key sizes < 128 are generally not\n\ + recommended\n\ + --phash , -P \n\ + specify to use for hashing the passphrase\n\ + (supported: rmd160old, sha256, sha384, sha512)\n"), progname, progname, progname); exit(1); } @@ -388,19 +694,20 @@ int main(int argc, char **argv) { - char *offset, *encryption; - int delete,off,c; + char *offset = 0, *encryption = 0, *passfd = 0, *keysize = 0, *phash_name = 0; + int delete = 0, off = 0, c = 0; + int pfd = -1; int res = 0; int ro = 0; + int keysz = 0; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - delete = off = 0; - offset = encryption = NULL; progname = argv[0]; - while ((c = getopt(argc,argv,"de:o:v")) != -1) { + while ((c = getopt_long(argc,argv,"de:h:k:o:p:P:v", + longopts, NULL)) != -1) { switch (c) { case 'd': delete = 1; @@ -408,9 +715,18 @@ case 'e': encryption = optarg; break; + case 'k': + keysize = optarg; + break; case 'o': offset = optarg; break; + case 'p': + passfd = optarg; + break; + case 'P': + phash_name = optarg; + break; case 'v': verbose = 1; break; @@ -419,7 +735,7 @@ } } if (argc == 1) usage(); - if ((delete && (argc != optind+1 || encryption || offset)) || + if ((delete && (argc != optind+1 || encryption || offset || passfd)) || (!delete && (argc < optind+1 || argc > optind+2))) usage(); if (argc == optind+1) { @@ -430,7 +746,13 @@ } else { if (offset && sscanf(offset,"%d",&off) != 1) usage(); - res = set_loop(argv[optind],argv[optind+1],off,encryption,&ro); + if (passfd && sscanf(passfd,"%d",&pfd) != 1) + usage(); + if (keysize && sscanf(keysize,"%d",&keysz) != 1) + usage(); + res = set_loop(argv[optind], argv[optind+1], off, + encryption, pfd, keysz, &ro, + phash_name ? phash_name : "rmd160old"); } return res; } @@ -446,3 +768,61 @@ } #endif #endif + +static int get_cipher_info(const char *name, struct cipher_info *res) +{ + char path[PATH_MAX]; + char buf[2000]; + FILE *f; + struct { + int *out; + const char *prefix; + } fields[] = {{&res->blocksize, "blocksize:"}, + {&res->keysize_mask, "keysize_mask:"}, + {&res->ivsize, "ivsize:"}, + {&res->key_schedule_size, "key_schedule_size:"}}; + snprintf(path, sizeof(path), "/proc/crypto/cipher/%s", name); + f = fopen(path, "r"); + while(f && fgets(buf, sizeof(buf), f)) { + int i; + for (i = 0; i < sizeof(fields)/sizeof(fields[0]); i++) { + int len = strlen(fields[i].prefix); + if (strncmp(buf, fields[i].prefix, len) == 0) { + *fields[i].out = strtoul(&buf[len+1], NULL, 0); + break; + } + } + + } + if (!f) + return -1; + return 0; +} + + +static int +name_to_id(const char *name) +{ + int i; + + if (name) { + for (i = 0; crypt_type_tbl[i].id != -1; i++) + if (!strcasecmp (name, crypt_type_tbl[i].name)) + return crypt_type_tbl[i].id; + } else + return LO_CRYPT_NONE; + return LO_CRYPT_CRYPTOAPI; +} + +#ifdef MAIN +static char * +id_to_name(int id) { + int i; + + for (i = 0; crypt_type_tbl[i].id != -1; i++) + if (id == crypt_type_tbl[i].id) + return crypt_type_tbl[i].name; + return "undefined"; +} +#endif + diff -Nur util-linux-2.11zorg/mount/lomount.h util-linux-2.11z/mount/lomount.h --- util-linux-2.11zorg/mount/lomount.h Fri Dec 8 18:08:02 2000 +++ util-linux-2.11z/mount/lomount.h Fri Mar 28 21:43:00 2003 @@ -1,5 +1,6 @@ extern int verbose; -extern int set_loop (const char *, const char *, int, const char *, int *); +extern int set_loop (const char *, const char *, int, const char *, + int, int, int *, const char *); extern int del_loop (const char *); extern int is_loop_device (const char *); extern char * find_unused_loop_device (void); diff -Nur util-linux-2.11zorg/mount/losetup.8 util-linux-2.11z/mount/losetup.8 --- util-linux-2.11zorg/mount/losetup.8 Fri Aug 11 11:11:30 2000 +++ util-linux-2.11z/mount/losetup.8 Fri Mar 28 21:43:00 2003 @@ -10,6 +10,9 @@ ] [ .B \-o .I offset +] [ +.B \-p +.I num ] .I loop_device file .br @@ -26,9 +29,9 @@ \fIloop_device\fP argument is given, the status of the corresponding loop device is shown. .SH OPTIONS -.IP \fB\-d\fP +.IP "\fB\-\-delete, \-\-detach, \-d\fP" detach the file or device associated with the specified loop device. -.IP "\fB\-e \fIencryption\fP" +.IP "\fB\-\-encryption, \-e \fIencryption\fP" .RS enable data encryption. The following keywords are recognized: .IP \fBNONE\fP @@ -36,16 +39,62 @@ .PD 0 .IP \fBXOR\fP use a simple XOR encryption. +.IP \fBAES\fP +use Advanced Encryption Standard encryption. AES encryption is only available +if you are using the international kernel and AES encryption has been enabled +in the Crypto API. +enabled in the Crypto API. +.IP \fBBlowfish\fP +use Blowfish encryption. Blowfish encryption is only available if you +are using the international kernel and Blowfish encryption has been +enabled in the Crypto API. +.IP \fBTwofish\fP +use Twofish encryption. Twofish encryption is only available if you +are using the international kernel and Twofish encryption has been +enabled in the Crypto API. +.IP \fBCAST\fP +use CAST encryption. CAST encryption is only available if you +are using the international kernel and CAST encryption has been +enabled in the Crypto API. .IP \fBDES\fP use DES encryption. DES encryption is only available if the optional DES package has been added to the kernel. DES encryption uses an additional start value that is used to protect passwords against dictionary -attacks. +attacks. Use of DES is deprecated. +.IP \fBDFC\fP +use DFC encryption. DFC encryption is only available if you +are using the international kernel and DFC encryption has been +enabled in the Crypto API. +.IP \fBIDEA\fP +use IDEA encryption. IDEA encryption is only available if you +are using the international kernel and IDEA encryption has been +enabled in the Crypto API. +.IP \fBMARS\fP +use MARS encryption. MARS encryption is only available if you +are using the international kernel and MARS encryption has been +enabled in the Crypto API. +.IP \fBRC5\fP +use RC5 encryption. RC5 encryption is only available if you +are using the international kernel and RC5 encryption has been +enabled in the Crypto API. +.IP \fBRC6\fP +use RC6 encryption. RC6 encryption is only available if you +are using the international kernel and RC6 encryption has been +enabled in the Crypto API. +.IP \fBSerpent\fP +use Serpent encryption. Serpent encryption is only available if you +are using the international kernel and Serpent encryption has been +enabled in the Crypto API. .PD .RE -.IP "\fB\-o \fIoffset\fP" +.IP "\fB\-\-offset, \-o \fIoffset\fP" the data start is moved \fIoffset\fP bytes into the specified file or device. +.IP "\fB\-\-pass-fd, \-p \fInum\fP" +read the passphrase from file descriptor \fInum\fP instead of the +terminal. +.IP "\fB\-\-keybits, \-k \fInum\fP" +set the number of bits to use in key to \fInum\fP. .SH RETURN VALUE .B losetup returns 0 on success, nonzero on failure. When @@ -58,6 +107,7 @@ .SH FILES .nf /dev/loop0,/dev/loop1,... loop devices (major=7) +/proc/cipher/* available ciphers .fi .SH EXAMPLE If you are using the loadable module you must have the module loaded @@ -69,9 +119,8 @@ .nf .IP dd if=/dev/zero of=/file bs=1k count=100 -losetup -e des /dev/loop0 /file -Password: -Init (up to 16 hex digits): +losetup -e blowfish /dev/loop0 /file +Password : mkfs -t ext2 /dev/loop0 100 mount -t ext2 /dev/loop0 /mnt ... @@ -85,8 +134,12 @@ # rmmod loop .LP .fi -.SH RESTRICTION -DES encryption is painfully slow. On the other hand, XOR is terribly weak. +.SH RESTRICTIONS +DES encryption is painfully slow. On the other hand, XOR is terribly +weak. Both are insecure nowadays. Some ciphers require a licence for +you to be allowed to use them. +.SH BUGS +CAST, DES, RC5 and Twofish are currently broken and cannot be used. .SH AUTHORS .nf Original version: Theodore Ts'o diff -Nur util-linux-2.11zorg/mount/mount.8 util-linux-2.11z/mount/mount.8 --- util-linux-2.11zorg/mount/mount.8 Tue Jan 21 13:45:54 2003 +++ util-linux-2.11z/mount/mount.8 Fri Mar 28 21:43:00 2003 @@ -270,6 +270,12 @@ .B \-v Verbose mode. .TP +.B \-p "\fInum\fP" +If the mount requires a passphrase to be entered, read it from file +descriptor +.IR num\fP +instead of from the terminal. +.TP .B \-a Mount all filesystems (of the given types) mentioned in .IR fstab . @@ -627,6 +633,15 @@ .BR noexec ", " nosuid ", and " nodev (unless overridden by subsequent options, as in the option line .BR users,exec,dev,suid ). +.TP +.B encryption +Specifies an encryption algorithm to use. Used in conjunction with the +.BR loop " option." +.TP +.B keybits +Specifies the key size to use for an encryption algorithm. Used in conjunction +with the +.BR loop " and " encryption " options." .RE .TP .B \-\-bind @@ -1688,7 +1703,10 @@ .BR loop ", " offset " and " encryption , that are really options to .BR losetup (8). -If no explicit loop device is mentioned +If the mount requires a passphrase, you will be prompted for one unless +you specify a file descriptor to read from instead with the +.BR \-\-pass-fd +option. If no explicit loop device is mentioned (but just an option `\fB\-o loop\fP' is given), then .B mount will try to find some unused loop device and use that. diff -Nur util-linux-2.11zorg/mount/mount.c util-linux-2.11z/mount/mount.c --- util-linux-2.11zorg/mount/mount.c Thu Jan 2 19:38:44 2003 +++ util-linux-2.11z/mount/mount.c Fri Mar 28 21:44:26 2003 @@ -113,6 +113,9 @@ /* True if ruid != euid. */ static int suid = 0; +/* Contains the fd no. to read the passphrase from, if any */ +static int pfd = -1; + /* Map from -o and fstab option strings to the flag argument to mount(2). */ struct opt_map { const char *opt; /* option name */ @@ -192,7 +195,7 @@ }; static char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption, - *opt_speed; + *opt_keybits, *opt_speed, *opt_phash; static struct string_opt_map { char *tag; @@ -203,6 +206,8 @@ { "vfs=", 1, &opt_vfstype }, { "offset=", 0, &opt_offset }, { "encryption=", 0, &opt_encryption }, + { "keybits=", 0, &opt_keybits }, + { "phash=", 0, &opt_phash }, { "speed=", 0, &opt_speed }, { NULL, 0, NULL } }; @@ -553,7 +558,7 @@ static int loop_check(char **spec, char **type, int *flags, int *loop, char **loopdev, char **loopfile) { - int looptype, offset; + int looptype, offset, keybits; /* * In the case of a loop mount, either type is of the form lo@/dev/loop5 @@ -596,7 +601,10 @@ if (verbose) printf(_("mount: going to use the loop device %s\n"), *loopdev); offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0; - if (set_loop (*loopdev, *loopfile, offset, opt_encryption, &loopro)) { + keybits = opt_keybits ? strtoul(opt_keybits, NULL, 0) : 0; + if (set_loop (*loopdev, *loopfile, offset, opt_encryption, pfd, + keybits, &loopro, + opt_phash ? opt_phash : "rmd160old")) { if (verbose) printf(_("mount: failed setting up loop device\n")); return EX_FAIL; @@ -1352,6 +1360,7 @@ { "rw", 0, 0, 'w' }, { "options", 1, 0, 'o' }, { "test-opts", 1, 0, 'O' }, + { "pass-fd", 1, 0, 'p' }, { "types", 1, 0, 't' }, { "bind", 0, 0, 128 }, { "replace", 0, 0, 129 }, @@ -1389,7 +1398,7 @@ " mount --move olddir newdir\n" "A device can be given by name, say /dev/hda1 or /dev/cdrom,\n" "or by label, using -L label or by uuid, using -U uuid .\n" - "Other options: [-nfFrsvw] [-o options].\n" + "Other options: [-nfFrsvw] [-o options] [-p num].\n" "For many more details, say man 8 mount .\n" )); /* @@ -1405,6 +1414,7 @@ int c, result = 0, specseen; char *options = NULL, *test_opts = NULL, *spec, *node; char *volumelabel = NULL; + char *passfd = NULL; char *uuid = NULL; char *types = NULL; struct mntentchn *mc; @@ -1428,7 +1438,7 @@ initproctitle(argc, argv); #endif - while ((c = getopt_long (argc, argv, "afFhilL:no:O:rsU:vVwt:", + while ((c = getopt_long (argc, argv, "afFhilL:no:O:p:rsU:vVwt:", longopts, NULL)) != -1) { switch (c) { case 'a': /* mount everything in fstab */ @@ -1467,6 +1477,9 @@ else test_opts = xstrdup(optarg); break; + case 'p': /* read passphrase from given fd */ + passfd = optarg; + break; case 'r': /* mount readonly */ readonly = 1; readwrite = 0; @@ -1576,6 +1589,9 @@ } else spec = NULL; /* just for gcc */ + if (passfd && sscanf(passfd,"%d",&pfd) != 1) + die (EX_USAGE, _("mount: argument to --pass-fd or -p must be a number")); + switch (argc+specseen) { case 0: /* mount -a */ diff -Nur util-linux-2.11zorg/mount/rmd160.c util-linux-2.11z/mount/rmd160.c --- util-linux-2.11zorg/mount/rmd160.c Thu Jan 1 00:00:00 1970 +++ util-linux-2.11z/mount/rmd160.c Fri Mar 28 21:43:00 2003 @@ -0,0 +1,532 @@ +/* rmd160.c - RIPE-MD160 + * Copyright (C) 1998 Free Software Foundation, Inc. + */ + +/* This file was part of GnuPG. Modified for use within the Linux + * mount utility by Marc Mutz . None of this code is + * by myself. I just removed everything that you don't need when all + * you want to do is to use rmd160_hash_buffer(). + * My comments are marked with (mm). */ + +/* GnuPG 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. + * + * GnuPG 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 */ + +#include /* (mm) for memcpy */ +#include /* (mm) for BIG_ENDIAN and BYTE_ORDER */ +#include "rmd160.h" + +/* (mm) these are used by the original GnuPG file. In order to modify + * that file not too much, we keep the notations. maybe it would be + * better to include linux/types.h and typedef __u32 to u32 and __u8 + * to byte? */ +typedef unsigned int u32; /* taken from e.g. util-linux's minix.h */ +typedef unsigned char byte; + +typedef struct { + u32 h0,h1,h2,h3,h4; + u32 nblocks; + byte buf[64]; + int count; +} RMD160_CONTEXT; + +/**************** + * Rotate a 32 bit integer by n bytes + */ +#if defined(__GNUC__) && defined(__i386__) +static inline u32 +rol( u32 x, int n) +{ + __asm__("roll %%cl,%0" + :"=r" (x) + :"0" (x),"c" (n)); + return x; +} +#else + #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) ) +#endif + +/********************************* + * RIPEMD-160 is not patented, see (as of 25.10.97) + * http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html + * Note that the code uses Little Endian byteorder, which is good for + * 386 etc, but we must add some conversion when used on a big endian box. + * + * + * Pseudo-code for RIPEMD-160 + * + * RIPEMD-160 is an iterative hash function that operates on 32-bit words. + * The round function takes as input a 5-word chaining variable and a 16-word + * message block and maps this to a new chaining variable. All operations are + * defined on 32-bit words. Padding is identical to that of MD4. + * + * + * RIPEMD-160: definitions + * + * + * nonlinear functions at bit level: exor, mux, -, mux, - + * + * f(j, x, y, z) = x XOR y XOR z (0 <= j <= 15) + * f(j, x, y, z) = (x AND y) OR (NOT(x) AND z) (16 <= j <= 31) + * f(j, x, y, z) = (x OR NOT(y)) XOR z (32 <= j <= 47) + * f(j, x, y, z) = (x AND z) OR (y AND NOT(z)) (48 <= j <= 63) + * f(j, x, y, z) = x XOR (y OR NOT(z)) (64 <= j <= 79) + * + * + * added constants (hexadecimal) + * + * K(j) = 0x00000000 (0 <= j <= 15) + * K(j) = 0x5A827999 (16 <= j <= 31) int(2**30 x sqrt(2)) + * K(j) = 0x6ED9EBA1 (32 <= j <= 47) int(2**30 x sqrt(3)) + * K(j) = 0x8F1BBCDC (48 <= j <= 63) int(2**30 x sqrt(5)) + * K(j) = 0xA953FD4E (64 <= j <= 79) int(2**30 x sqrt(7)) + * K'(j) = 0x50A28BE6 (0 <= j <= 15) int(2**30 x cbrt(2)) + * K'(j) = 0x5C4DD124 (16 <= j <= 31) int(2**30 x cbrt(3)) + * K'(j) = 0x6D703EF3 (32 <= j <= 47) int(2**30 x cbrt(5)) + * K'(j) = 0x7A6D76E9 (48 <= j <= 63) int(2**30 x cbrt(7)) + * K'(j) = 0x00000000 (64 <= j <= 79) + * + * + * selection of message word + * + * r(j) = j (0 <= j <= 15) + * r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8 + * r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12 + * r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2 + * r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 + * r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12 + * r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2 + * r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13 + * r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14 + * r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 + * + * + * amount for rotate left (rol) + * + * s(0..15) = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8 + * s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12 + * s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5 + * s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12 + * s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 + * s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6 + * s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11 + * s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5 + * s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8 + * s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 + * + * + * initial value (hexadecimal) + * + * h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476; + * h4 = 0xC3D2E1F0; + * + * + * RIPEMD-160: pseudo-code + * + * It is assumed that the message after padding consists of t 16-word blocks + * that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15. + * The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left + * shift (rotate) over s positions. + * + * + * for i := 0 to t-1 { + * A := h0; B := h1; C := h2; D = h3; E = h4; + * A' := h0; B' := h1; C' := h2; D' = h3; E' = h4; + * for j := 0 to 79 { + * T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E; + * A := E; E := D; D := rol_10(C); C := B; B := T; + * T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)] + [+] K'(j)) [+] E'; + * A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T; + * } + * T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A'; + * h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T; + * } + */ + +/* Some examples: + * "" 9c1185a5c5e9fc54612808977ee8f548b2258d31 + * "a" 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe + * "abc" 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc + * "message digest" 5d0689ef49d2fae572b881b123a85ffa21595f36 + * "a...z" f71c27109c692c1b56bbdceb5b9d2865b3708dbc + * "abcdbcde...nopq" 12a053384a9c0c88e405a06c27dcf49ada62eb2b + * "A...Za...z0...9" b0e20b6e3116640286ed3a87a5713079b21f5189 + * 8 times "1234567890" 9b752e45573d4b39f4dbd3323cab82bf63326bfb + * 1 million times "a" 52783243c1697bdbe16d37f97f68f08325dc1528 + */ + + +static void +rmd160_init( RMD160_CONTEXT *hd ) +{ + hd->h0 = 0x67452301; + hd->h1 = 0xEFCDAB89; + hd->h2 = 0x98BADCFE; + hd->h3 = 0x10325476; + hd->h4 = 0xC3D2E1F0; + hd->nblocks = 0; + hd->count = 0; +} + + + +/**************** + * Transform the message X which consists of 16 32-bit-words + */ +static void +transform( RMD160_CONTEXT *hd, byte *data ) +{ + u32 a,b,c,d,e,aa,bb,cc,dd,ee,t; + #if BYTE_ORDER == BIG_ENDIAN + u32 x[16]; + { int i; + byte *p2, *p1; + for(i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 ) { + p2[3] = *p1++; + p2[2] = *p1++; + p2[1] = *p1++; + p2[0] = *p1++; + } + } + #else + #if 0 + u32 *x =(u32*)data; + #else + /* this version is better because it is always aligned; + * The performance penalty on a 586-100 is about 6% which + * is acceptable - because the data is more local it might + * also be possible that this is faster on some machines. + * This function (when compiled with -02 on gcc 2.7.2) + * executes on a 586-100 (39.73 bogomips) at about 1900kb/sec; + * [measured with a 4MB data and "gpgm --print-md rmd160"] */ + u32 x[16]; + memcpy( x, data, 64 ); + #endif + #endif + + +#define K0 0x00000000 +#define K1 0x5A827999 +#define K2 0x6ED9EBA1 +#define K3 0x8F1BBCDC +#define K4 0xA953FD4E +#define KK0 0x50A28BE6 +#define KK1 0x5C4DD124 +#define KK2 0x6D703EF3 +#define KK3 0x7A6D76E9 +#define KK4 0x00000000 +#define F0(x,y,z) ( (x) ^ (y) ^ (z) ) +#define F1(x,y,z) ( ((x) & (y)) | (~(x) & (z)) ) +#define F2(x,y,z) ( ((x) | ~(y)) ^ (z) ) +#define F3(x,y,z) ( ((x) & (z)) | ((y) & ~(z)) ) +#define F4(x,y,z) ( (x) ^ ((y) | ~(z)) ) +#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \ + a = rol(t,s) + e; \ + c = rol(c,10); \ + } while(0) + + /* left lane */ + a = hd->h0; + b = hd->h1; + c = hd->h2; + d = hd->h3; + e = hd->h4; + R( a, b, c, d, e, F0, K0, 0, 11 ); + R( e, a, b, c, d, F0, K0, 1, 14 ); + R( d, e, a, b, c, F0, K0, 2, 15 ); + R( c, d, e, a, b, F0, K0, 3, 12 ); + R( b, c, d, e, a, F0, K0, 4, 5 ); + R( a, b, c, d, e, F0, K0, 5, 8 ); + R( e, a, b, c, d, F0, K0, 6, 7 ); + R( d, e, a, b, c, F0, K0, 7, 9 ); + R( c, d, e, a, b, F0, K0, 8, 11 ); + R( b, c, d, e, a, F0, K0, 9, 13 ); + R( a, b, c, d, e, F0, K0, 10, 14 ); + R( e, a, b, c, d, F0, K0, 11, 15 ); + R( d, e, a, b, c, F0, K0, 12, 6 ); + R( c, d, e, a, b, F0, K0, 13, 7 ); + R( b, c, d, e, a, F0, K0, 14, 9 ); + R( a, b, c, d, e, F0, K0, 15, 8 ); + R( e, a, b, c, d, F1, K1, 7, 7 ); + R( d, e, a, b, c, F1, K1, 4, 6 ); + R( c, d, e, a, b, F1, K1, 13, 8 ); + R( b, c, d, e, a, F1, K1, 1, 13 ); + R( a, b, c, d, e, F1, K1, 10, 11 ); + R( e, a, b, c, d, F1, K1, 6, 9 ); + R( d, e, a, b, c, F1, K1, 15, 7 ); + R( c, d, e, a, b, F1, K1, 3, 15 ); + R( b, c, d, e, a, F1, K1, 12, 7 ); + R( a, b, c, d, e, F1, K1, 0, 12 ); + R( e, a, b, c, d, F1, K1, 9, 15 ); + R( d, e, a, b, c, F1, K1, 5, 9 ); + R( c, d, e, a, b, F1, K1, 2, 11 ); + R( b, c, d, e, a, F1, K1, 14, 7 ); + R( a, b, c, d, e, F1, K1, 11, 13 ); + R( e, a, b, c, d, F1, K1, 8, 12 ); + R( d, e, a, b, c, F2, K2, 3, 11 ); + R( c, d, e, a, b, F2, K2, 10, 13 ); + R( b, c, d, e, a, F2, K2, 14, 6 ); + R( a, b, c, d, e, F2, K2, 4, 7 ); + R( e, a, b, c, d, F2, K2, 9, 14 ); + R( d, e, a, b, c, F2, K2, 15, 9 ); + R( c, d, e, a, b, F2, K2, 8, 13 ); + R( b, c, d, e, a, F2, K2, 1, 15 ); + R( a, b, c, d, e, F2, K2, 2, 14 ); + R( e, a, b, c, d, F2, K2, 7, 8 ); + R( d, e, a, b, c, F2, K2, 0, 13 ); + R( c, d, e, a, b, F2, K2, 6, 6 ); + R( b, c, d, e, a, F2, K2, 13, 5 ); + R( a, b, c, d, e, F2, K2, 11, 12 ); + R( e, a, b, c, d, F2, K2, 5, 7 ); + R( d, e, a, b, c, F2, K2, 12, 5 ); + R( c, d, e, a, b, F3, K3, 1, 11 ); + R( b, c, d, e, a, F3, K3, 9, 12 ); + R( a, b, c, d, e, F3, K3, 11, 14 ); + R( e, a, b, c, d, F3, K3, 10, 15 ); + R( d, e, a, b, c, F3, K3, 0, 14 ); + R( c, d, e, a, b, F3, K3, 8, 15 ); + R( b, c, d, e, a, F3, K3, 12, 9 ); + R( a, b, c, d, e, F3, K3, 4, 8 ); + R( e, a, b, c, d, F3, K3, 13, 9 ); + R( d, e, a, b, c, F3, K3, 3, 14 ); + R( c, d, e, a, b, F3, K3, 7, 5 ); + R( b, c, d, e, a, F3, K3, 15, 6 ); + R( a, b, c, d, e, F3, K3, 14, 8 ); + R( e, a, b, c, d, F3, K3, 5, 6 ); + R( d, e, a, b, c, F3, K3, 6, 5 ); + R( c, d, e, a, b, F3, K3, 2, 12 ); + R( b, c, d, e, a, F4, K4, 4, 9 ); + R( a, b, c, d, e, F4, K4, 0, 15 ); + R( e, a, b, c, d, F4, K4, 5, 5 ); + R( d, e, a, b, c, F4, K4, 9, 11 ); + R( c, d, e, a, b, F4, K4, 7, 6 ); + R( b, c, d, e, a, F4, K4, 12, 8 ); + R( a, b, c, d, e, F4, K4, 2, 13 ); + R( e, a, b, c, d, F4, K4, 10, 12 ); + R( d, e, a, b, c, F4, K4, 14, 5 ); + R( c, d, e, a, b, F4, K4, 1, 12 ); + R( b, c, d, e, a, F4, K4, 3, 13 ); + R( a, b, c, d, e, F4, K4, 8, 14 ); + R( e, a, b, c, d, F4, K4, 11, 11 ); + R( d, e, a, b, c, F4, K4, 6, 8 ); + R( c, d, e, a, b, F4, K4, 15, 5 ); + R( b, c, d, e, a, F4, K4, 13, 6 ); + + aa = a; bb = b; cc = c; dd = d; ee = e; + + /* right lane */ + a = hd->h0; + b = hd->h1; + c = hd->h2; + d = hd->h3; + e = hd->h4; + R( a, b, c, d, e, F4, KK0, 5, 8); + R( e, a, b, c, d, F4, KK0, 14, 9); + R( d, e, a, b, c, F4, KK0, 7, 9); + R( c, d, e, a, b, F4, KK0, 0, 11); + R( b, c, d, e, a, F4, KK0, 9, 13); + R( a, b, c, d, e, F4, KK0, 2, 15); + R( e, a, b, c, d, F4, KK0, 11, 15); + R( d, e, a, b, c, F4, KK0, 4, 5); + R( c, d, e, a, b, F4, KK0, 13, 7); + R( b, c, d, e, a, F4, KK0, 6, 7); + R( a, b, c, d, e, F4, KK0, 15, 8); + R( e, a, b, c, d, F4, KK0, 8, 11); + R( d, e, a, b, c, F4, KK0, 1, 14); + R( c, d, e, a, b, F4, KK0, 10, 14); + R( b, c, d, e, a, F4, KK0, 3, 12); + R( a, b, c, d, e, F4, KK0, 12, 6); + R( e, a, b, c, d, F3, KK1, 6, 9); + R( d, e, a, b, c, F3, KK1, 11, 13); + R( c, d, e, a, b, F3, KK1, 3, 15); + R( b, c, d, e, a, F3, KK1, 7, 7); + R( a, b, c, d, e, F3, KK1, 0, 12); + R( e, a, b, c, d, F3, KK1, 13, 8); + R( d, e, a, b, c, F3, KK1, 5, 9); + R( c, d, e, a, b, F3, KK1, 10, 11); + R( b, c, d, e, a, F3, KK1, 14, 7); + R( a, b, c, d, e, F3, KK1, 15, 7); + R( e, a, b, c, d, F3, KK1, 8, 12); + R( d, e, a, b, c, F3, KK1, 12, 7); + R( c, d, e, a, b, F3, KK1, 4, 6); + R( b, c, d, e, a, F3, KK1, 9, 15); + R( a, b, c, d, e, F3, KK1, 1, 13); + R( e, a, b, c, d, F3, KK1, 2, 11); + R( d, e, a, b, c, F2, KK2, 15, 9); + R( c, d, e, a, b, F2, KK2, 5, 7); + R( b, c, d, e, a, F2, KK2, 1, 15); + R( a, b, c, d, e, F2, KK2, 3, 11); + R( e, a, b, c, d, F2, KK2, 7, 8); + R( d, e, a, b, c, F2, KK2, 14, 6); + R( c, d, e, a, b, F2, KK2, 6, 6); + R( b, c, d, e, a, F2, KK2, 9, 14); + R( a, b, c, d, e, F2, KK2, 11, 12); + R( e, a, b, c, d, F2, KK2, 8, 13); + R( d, e, a, b, c, F2, KK2, 12, 5); + R( c, d, e, a, b, F2, KK2, 2, 14); + R( b, c, d, e, a, F2, KK2, 10, 13); + R( a, b, c, d, e, F2, KK2, 0, 13); + R( e, a, b, c, d, F2, KK2, 4, 7); + R( d, e, a, b, c, F2, KK2, 13, 5); + R( c, d, e, a, b, F1, KK3, 8, 15); + R( b, c, d, e, a, F1, KK3, 6, 5); + R( a, b, c, d, e, F1, KK3, 4, 8); + R( e, a, b, c, d, F1, KK3, 1, 11); + R( d, e, a, b, c, F1, KK3, 3, 14); + R( c, d, e, a, b, F1, KK3, 11, 14); + R( b, c, d, e, a, F1, KK3, 15, 6); + R( a, b, c, d, e, F1, KK3, 0, 14); + R( e, a, b, c, d, F1, KK3, 5, 6); + R( d, e, a, b, c, F1, KK3, 12, 9); + R( c, d, e, a, b, F1, KK3, 2, 12); + R( b, c, d, e, a, F1, KK3, 13, 9); + R( a, b, c, d, e, F1, KK3, 9, 12); + R( e, a, b, c, d, F1, KK3, 7, 5); + R( d, e, a, b, c, F1, KK3, 10, 15); + R( c, d, e, a, b, F1, KK3, 14, 8); + R( b, c, d, e, a, F0, KK4, 12, 8); + R( a, b, c, d, e, F0, KK4, 15, 5); + R( e, a, b, c, d, F0, KK4, 10, 12); + R( d, e, a, b, c, F0, KK4, 4, 9); + R( c, d, e, a, b, F0, KK4, 1, 12); + R( b, c, d, e, a, F0, KK4, 5, 5); + R( a, b, c, d, e, F0, KK4, 8, 14); + R( e, a, b, c, d, F0, KK4, 7, 6); + R( d, e, a, b, c, F0, KK4, 6, 8); + R( c, d, e, a, b, F0, KK4, 2, 13); + R( b, c, d, e, a, F0, KK4, 13, 6); + R( a, b, c, d, e, F0, KK4, 14, 5); + R( e, a, b, c, d, F0, KK4, 0, 15); + R( d, e, a, b, c, F0, KK4, 3, 13); + R( c, d, e, a, b, F0, KK4, 9, 11); + R( b, c, d, e, a, F0, KK4, 11, 11); + + + t = hd->h1 + d + cc; + hd->h1 = hd->h2 + e + dd; + hd->h2 = hd->h3 + a + ee; + hd->h3 = hd->h4 + b + aa; + hd->h4 = hd->h0 + c + bb; + hd->h0 = t; +} + + +/* Update the message digest with the contents + * of INBUF with length INLEN. + */ +static void +rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen) +{ + if( hd->count == 64 ) { /* flush the buffer */ + transform( hd, hd->buf ); + hd->count = 0; + hd->nblocks++; + } + if( !inbuf ) + return; + if( hd->count ) { + for( ; inlen && hd->count < 64; inlen-- ) + hd->buf[hd->count++] = *inbuf++; + rmd160_write( hd, NULL, 0 ); + if( !inlen ) + return; + } + + while( inlen >= 64 ) { + transform( hd, inbuf ); + hd->count = 0; + hd->nblocks++; + inlen -= 64; + inbuf += 64; + } + for( ; inlen && hd->count < 64; inlen-- ) + hd->buf[hd->count++] = *inbuf++; +} + +/* The routine terminates the computation + */ + +static void +rmd160_final( RMD160_CONTEXT *hd ) +{ + u32 t, msb, lsb; + byte *p; + + rmd160_write(hd, NULL, 0); /* flush */; + + msb = 0; + t = hd->nblocks; + if( (lsb = t << 6) < t ) /* multiply by 64 to make a byte count */ + msb++; + msb += t >> 26; + t = lsb; + if( (lsb = t + hd->count) < t ) /* add the count */ + msb++; + t = lsb; + if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */ + msb++; + msb += t >> 29; + + if( hd->count < 56 ) { /* enough room */ + hd->buf[hd->count++] = 0x80; /* pad */ + while( hd->count < 56 ) + hd->buf[hd->count++] = 0; /* pad */ + } + else { /* need one extra block */ + hd->buf[hd->count++] = 0x80; /* pad character */ + while( hd->count < 64 ) + hd->buf[hd->count++] = 0; + rmd160_write(hd, NULL, 0); /* flush */; + memset(hd->buf, 0, 56 ); /* fill next block with zeroes */ + } + /* append the 64 bit count */ + hd->buf[56] = lsb ; + hd->buf[57] = lsb >> 8; + hd->buf[58] = lsb >> 16; + hd->buf[59] = lsb >> 24; + hd->buf[60] = msb ; + hd->buf[61] = msb >> 8; + hd->buf[62] = msb >> 16; + hd->buf[63] = msb >> 24; + transform( hd, hd->buf ); + + p = hd->buf; + #if BYTE_ORDER == BIG_ENDIAN + #define X(a) do { *p++ = hd->h##a ; *p++ = hd->h##a >> 8; \ + *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0) + #else /* little endian */ + #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0) + #endif + X(0); + X(1); + X(2); + X(3); + X(4); + #undef X +} + +/**************** + * Shortcut functions which puts the hash value of the supplied buffer + * into outbuf which must have a size of 20 bytes. + */ +void +rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length ) +{ + RMD160_CONTEXT hd; + + rmd160_init( &hd ); + rmd160_write( &hd, (byte*)buffer, length ); + rmd160_final( &hd ); + memcpy( outbuf, hd.buf, 20 ); +} diff -Nur util-linux-2.11zorg/mount/rmd160.h util-linux-2.11z/mount/rmd160.h --- util-linux-2.11zorg/mount/rmd160.h Thu Jan 1 00:00:00 1970 +++ util-linux-2.11z/mount/rmd160.h Fri Mar 28 21:43:00 2003 @@ -0,0 +1,9 @@ +#ifndef RMD160_H +#define RMD160_H + +#define RMD160_HASH_SIZE 20 + +void +rmd160_hash_buffer (char *outbuf, const char *buffer, size_t length); + +#endif /*RMD160_H*/ diff -Nur util-linux-2.11zorg/mount/sha512.c util-linux-2.11z/mount/sha512.c --- util-linux-2.11zorg/mount/sha512.c Thu Jan 1 00:00:00 1970 +++ util-linux-2.11z/mount/sha512.c Fri Mar 28 21:43:00 2003 @@ -0,0 +1,432 @@ +/* + * sha512.c + * + * Written by Jari Ruusu, April 16 2001 + * + * Copyright 2001 by Jari Ruusu. + * Redistribution of this file is permitted under the GNU Public License. + */ + +#include +#include +#include "sha512.h" + +/* Define one or more of these. If none is defined, you get all of them */ +#if !defined(SHA256_NEEDED)&&!defined(SHA512_NEEDED)&&!defined(SHA384_NEEDED) +# define SHA256_NEEDED 1 +# define SHA512_NEEDED 1 +# define SHA384_NEEDED 1 +#endif + +#if defined(SHA256_NEEDED) +static const u_int32_t sha256_hashInit[8] = { + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, + 0x1f83d9ab, 0x5be0cd19 +}; +static const u_int32_t sha256_K[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, + 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; +#endif + +#if defined(SHA512_NEEDED) +static const u_int64_t sha512_hashInit[8] = { + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; +#endif + +#if defined(SHA384_NEEDED) +static const u_int64_t sha384_hashInit[8] = { + 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL, + 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL, + 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL +}; +#endif + +#if defined(SHA512_NEEDED) || defined(SHA384_NEEDED) +static const u_int64_t sha512_K[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, + 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, + 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, + 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, + 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, + 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, + 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, + 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, + 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, + 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, + 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, + 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, + 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, + 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; +#endif + +#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +#define R(x,y) ((y) >> (x)) + +#if defined(SHA256_NEEDED) +void sha256_init(sha256_context *ctx) +{ + memcpy(&ctx->sha_H[0], &sha256_hashInit[0], sizeof(ctx->sha_H)); + ctx->sha_blocks = 0; + ctx->sha_bufCnt = 0; +} + +#define S(x,y) (((y) >> (x)) | ((y) << (32 - (x)))) +#define uSig0(x) ((S(2,(x))) ^ (S(13,(x))) ^ (S(22,(x)))) +#define uSig1(x) ((S(6,(x))) ^ (S(11,(x))) ^ (S(25,(x)))) +#define lSig0(x) ((S(7,(x))) ^ (S(18,(x))) ^ (R(3,(x)))) +#define lSig1(x) ((S(17,(x))) ^ (S(19,(x))) ^ (R(10,(x)))) + +static void sha256_transform(sha256_context *ctx, unsigned char *datap) +{ + register int j; + u_int32_t a, b, c, d, e, f, g, h; + u_int32_t T1, T2, W[64], Wm2, Wm15; + + /* read the data, big endian byte order */ + j = 0; + do { + W[j] = (((u_int32_t)(datap[0]))<<24) | (((u_int32_t)(datap[1]))<<16) | + (((u_int32_t)(datap[2]))<<8 ) | ((u_int32_t)(datap[3])); + datap += 4; + } while(++j < 16); + + /* initialize variables a...h */ + a = ctx->sha_H[0]; + b = ctx->sha_H[1]; + c = ctx->sha_H[2]; + d = ctx->sha_H[3]; + e = ctx->sha_H[4]; + f = ctx->sha_H[5]; + g = ctx->sha_H[6]; + h = ctx->sha_H[7]; + + /* apply compression function */ + j = 0; + do { + if(j >= 16) { + Wm2 = W[j - 2]; + Wm15 = W[j - 15]; + W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16]; + } + T1 = h + uSig1(e) + Ch(e,f,g) + sha256_K[j] + W[j]; + T2 = uSig0(a) + Maj(a,b,c); + h = g; g = f; f = e; + e = d + T1; + d = c; c = b; b = a; + a = T1 + T2; + } while(++j < 64); + + /* compute intermediate hash value */ + ctx->sha_H[0] += a; + ctx->sha_H[1] += b; + ctx->sha_H[2] += c; + ctx->sha_H[3] += d; + ctx->sha_H[4] += e; + ctx->sha_H[5] += f; + ctx->sha_H[6] += g; + ctx->sha_H[7] += h; + + ctx->sha_blocks++; +} + +void sha256_write(sha256_context *ctx, unsigned char *datap, int length) +{ + while(length > 0) { + if(!ctx->sha_bufCnt) { + while(length >= sizeof(ctx->sha_out)) { + sha256_transform(ctx, datap); + datap += sizeof(ctx->sha_out); + length -= sizeof(ctx->sha_out); + } + if(!length) return; + } + ctx->sha_out[ctx->sha_bufCnt] = *datap++; + length--; + if(++ctx->sha_bufCnt == sizeof(ctx->sha_out)) { + sha256_transform(ctx, &ctx->sha_out[0]); + ctx->sha_bufCnt = 0; + } + } +} + +void sha256_final(sha256_context *ctx) +{ + register int j; + u_int64_t bitLength; + u_int32_t i; + unsigned char padByte, *datap; + + bitLength = (ctx->sha_blocks << 9) | (ctx->sha_bufCnt << 3); + padByte = 0x80; + sha256_write(ctx, &padByte, 1); + + /* pad extra space with zeroes */ + padByte = 0; + while(ctx->sha_bufCnt != 56) { + sha256_write(ctx, &padByte, 1); + } + + /* write bit length, big endian byte order */ + ctx->sha_out[56] = bitLength >> 56; + ctx->sha_out[57] = bitLength >> 48; + ctx->sha_out[58] = bitLength >> 40; + ctx->sha_out[59] = bitLength >> 32; + ctx->sha_out[60] = bitLength >> 24; + ctx->sha_out[61] = bitLength >> 16; + ctx->sha_out[62] = bitLength >> 8; + ctx->sha_out[63] = bitLength; + sha256_transform(ctx, &ctx->sha_out[0]); + + /* return results in ctx->sha_out[0...31] */ + datap = &ctx->sha_out[0]; + j = 0; + do { + i = ctx->sha_H[j]; + datap[0] = i >> 24; + datap[1] = i >> 16; + datap[2] = i >> 8; + datap[3] = i; + datap += 4; + } while(++j < 8); + + /* clear sensitive information */ + memset(&ctx->sha_out[32], 0, sizeof(sha256_context) - 32); +} + +void sha256_hash_buffer(unsigned char *ib, int ile, unsigned char *ob, int ole) +{ + sha256_context ctx; + + if(ole < 1) return; + memset(ob, 0, ole); + if(ole > 32) ole = 32; + sha256_init(&ctx); + sha256_write(&ctx, ib, ile); + sha256_final(&ctx); + memcpy(ob, &ctx.sha_out[0], ole); + memset(&ctx, 0, sizeof(ctx)); +} + +#endif + +#if defined(SHA512_NEEDED) +void sha512_init(sha512_context *ctx) +{ + memcpy(&ctx->sha_H[0], &sha512_hashInit[0], sizeof(ctx->sha_H)); + ctx->sha_blocks = 0; + ctx->sha_blocksMSB = 0; + ctx->sha_bufCnt = 0; +} +#endif + +#if defined(SHA512_NEEDED) || defined(SHA384_NEEDED) +#undef S +#undef uSig0 +#undef uSig1 +#undef lSig0 +#undef lSig1 +#define S(x,y) (((y) >> (x)) | ((y) << (64 - (x)))) +#define uSig0(x) ((S(28,(x))) ^ (S(34,(x))) ^ (S(39,(x)))) +#define uSig1(x) ((S(14,(x))) ^ (S(18,(x))) ^ (S(41,(x)))) +#define lSig0(x) ((S(1,(x))) ^ (S(8,(x))) ^ (R(7,(x)))) +#define lSig1(x) ((S(19,(x))) ^ (S(61,(x))) ^ (R(6,(x)))) + +static void sha512_transform(sha512_context *ctx, unsigned char *datap) +{ + register int j; + u_int64_t a, b, c, d, e, f, g, h; + u_int64_t T1, T2, W[80], Wm2, Wm15; + + /* read the data, big endian byte order */ + j = 0; + do { + W[j] = (((u_int64_t)(datap[0]))<<56) | (((u_int64_t)(datap[1]))<<48) | + (((u_int64_t)(datap[2]))<<40) | (((u_int64_t)(datap[3]))<<32) | + (((u_int64_t)(datap[4]))<<24) | (((u_int64_t)(datap[5]))<<16) | + (((u_int64_t)(datap[6]))<<8 ) | ((u_int64_t)(datap[7])); + datap += 8; + } while(++j < 16); + + /* initialize variables a...h */ + a = ctx->sha_H[0]; + b = ctx->sha_H[1]; + c = ctx->sha_H[2]; + d = ctx->sha_H[3]; + e = ctx->sha_H[4]; + f = ctx->sha_H[5]; + g = ctx->sha_H[6]; + h = ctx->sha_H[7]; + + /* apply compression function */ + j = 0; + do { + if(j >= 16) { + Wm2 = W[j - 2]; + Wm15 = W[j - 15]; + W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16]; + } + T1 = h + uSig1(e) + Ch(e,f,g) + sha512_K[j] + W[j]; + T2 = uSig0(a) + Maj(a,b,c); + h = g; g = f; f = e; + e = d + T1; + d = c; c = b; b = a; + a = T1 + T2; + } while(++j < 80); + + /* compute intermediate hash value */ + ctx->sha_H[0] += a; + ctx->sha_H[1] += b; + ctx->sha_H[2] += c; + ctx->sha_H[3] += d; + ctx->sha_H[4] += e; + ctx->sha_H[5] += f; + ctx->sha_H[6] += g; + ctx->sha_H[7] += h; + + ctx->sha_blocks++; + if(!ctx->sha_blocks) ctx->sha_blocksMSB++; +} + +void sha512_write(sha512_context *ctx, unsigned char *datap, int length) +{ + while(length > 0) { + if(!ctx->sha_bufCnt) { + while(length >= sizeof(ctx->sha_out)) { + sha512_transform(ctx, datap); + datap += sizeof(ctx->sha_out); + length -= sizeof(ctx->sha_out); + } + if(!length) return; + } + ctx->sha_out[ctx->sha_bufCnt] = *datap++; + length--; + if(++ctx->sha_bufCnt == sizeof(ctx->sha_out)) { + sha512_transform(ctx, &ctx->sha_out[0]); + ctx->sha_bufCnt = 0; + } + } +} + +void sha512_final(sha512_context *ctx) +{ + register int j; + u_int64_t bitLength, bitLengthMSB; + u_int64_t i; + unsigned char padByte, *datap; + + bitLength = (ctx->sha_blocks << 10) | (ctx->sha_bufCnt << 3); + bitLengthMSB = (ctx->sha_blocksMSB << 10) | (ctx->sha_blocks >> 54); + padByte = 0x80; + sha512_write(ctx, &padByte, 1); + + /* pad extra space with zeroes */ + padByte = 0; + while(ctx->sha_bufCnt != 112) { + sha512_write(ctx, &padByte, 1); + } + + /* write bit length, big endian byte order */ + ctx->sha_out[112] = bitLengthMSB >> 56; + ctx->sha_out[113] = bitLengthMSB >> 48; + ctx->sha_out[114] = bitLengthMSB >> 40; + ctx->sha_out[115] = bitLengthMSB >> 32; + ctx->sha_out[116] = bitLengthMSB >> 24; + ctx->sha_out[117] = bitLengthMSB >> 16; + ctx->sha_out[118] = bitLengthMSB >> 8; + ctx->sha_out[119] = bitLengthMSB; + ctx->sha_out[120] = bitLength >> 56; + ctx->sha_out[121] = bitLength >> 48; + ctx->sha_out[122] = bitLength >> 40; + ctx->sha_out[123] = bitLength >> 32; + ctx->sha_out[124] = bitLength >> 24; + ctx->sha_out[125] = bitLength >> 16; + ctx->sha_out[126] = bitLength >> 8; + ctx->sha_out[127] = bitLength; + sha512_transform(ctx, &ctx->sha_out[0]); + + /* return results in ctx->sha_out[0...63] */ + datap = &ctx->sha_out[0]; + j = 0; + do { + i = ctx->sha_H[j]; + datap[0] = i >> 56; + datap[1] = i >> 48; + datap[2] = i >> 40; + datap[3] = i >> 32; + datap[4] = i >> 24; + datap[5] = i >> 16; + datap[6] = i >> 8; + datap[7] = i; + datap += 8; + } while(++j < 8); + + /* clear sensitive information */ + memset(&ctx->sha_out[64], 0, sizeof(sha512_context) - 64); +} + +void sha512_hash_buffer(unsigned char *ib, int ile, unsigned char *ob, int ole) +{ + sha512_context ctx; + + if(ole < 1) return; + memset(ob, 0, ole); + if(ole > 64) ole = 64; + sha512_init(&ctx); + sha512_write(&ctx, ib, ile); + sha512_final(&ctx); + memcpy(ob, &ctx.sha_out[0], ole); + memset(&ctx, 0, sizeof(ctx)); +} +#endif + +#if defined(SHA384_NEEDED) +void sha384_init(sha512_context *ctx) +{ + memcpy(&ctx->sha_H[0], &sha384_hashInit[0], sizeof(ctx->sha_H)); + ctx->sha_blocks = 0; + ctx->sha_blocksMSB = 0; + ctx->sha_bufCnt = 0; +} + +void sha384_hash_buffer(unsigned char *ib, int ile, unsigned char *ob, int ole) +{ + sha512_context ctx; + + if(ole < 1) return; + memset(ob, 0, ole); + if(ole > 48) ole = 48; + sha384_init(&ctx); + sha512_write(&ctx, ib, ile); + sha512_final(&ctx); + memcpy(ob, &ctx.sha_out[0], ole); + memset(&ctx, 0, sizeof(ctx)); +} +#endif diff -Nur util-linux-2.11zorg/mount/sha512.h util-linux-2.11z/mount/sha512.h --- util-linux-2.11zorg/mount/sha512.h Thu Jan 1 00:00:00 1970 +++ util-linux-2.11z/mount/sha512.h Fri Mar 28 21:43:00 2003 @@ -0,0 +1,45 @@ +/* + * sha512.h + * + * Written by Jari Ruusu, April 16 2001 + * + * Copyright 2001 by Jari Ruusu. + * Redistribution of this file is permitted under the GNU Public License. + */ + +#include + +typedef struct { + unsigned char sha_out[64]; /* results are here, bytes 0...31 */ + u_int32_t sha_H[8]; + u_int64_t sha_blocks; + int sha_bufCnt; +} sha256_context; + +typedef struct { + unsigned char sha_out[128]; /* results are here, bytes 0...63 */ + u_int64_t sha_H[8]; + u_int64_t sha_blocks; + u_int64_t sha_blocksMSB; + int sha_bufCnt; +} sha512_context; + +/* no sha384_context, use sha512_context */ + +/* 256 bit hash, provides 128 bits of security against collision attacks */ +extern void sha256_init(sha256_context *); +extern void sha256_write(sha256_context *, unsigned char *, int); +extern void sha256_final(sha256_context *); +extern void sha256_hash_buffer(unsigned char *, int, unsigned char *, int); + +/* 512 bit hash, provides 256 bits of security against collision attacks */ +extern void sha512_init(sha512_context *); +extern void sha512_write(sha512_context *, unsigned char *, int); +extern void sha512_final(sha512_context *); +extern void sha512_hash_buffer(unsigned char *, int, unsigned char *, int); + +/* 384 bit hash, provides 192 bits of security against collision attacks */ +extern void sha384_init(sha512_context *); +/* no sha384_write(), use sha512_write() */ +/* no sha384_final(), use sha512_final(), result in ctx->sha_out[0...47] */ +extern void sha384_hash_buffer(unsigned char *, int, unsigned char *, int); diff -Nur util-linux-2.11zorg/mount/sundries.c util-linux-2.11z/mount/sundries.c --- util-linux-2.11zorg/mount/sundries.c Fri Nov 1 01:00:50 2002 +++ util-linux-2.11z/mount/sundries.c Fri Mar 28 21:43:00 2003 @@ -162,7 +162,7 @@ return 1; no = 0; - if (!strncmp(types, "no", 2)) { + if (types && !strncmp(types, "no", 2)) { no = 1; types += 2; }