1 diff -Nur util-linux-2.11b.orig/mount/Makefile util-linux-2.11b/mount/Makefile
2 --- util-linux-2.11b.orig/mount/Makefile Mon Mar 5 01:38:53 2001
3 +++ util-linux-2.11b/mount/Makefile Wed Mar 28 11:41:40 2001
6 MAYBE = pivot_root swapoff
8 -LO_OBJS = lomount.o $(LIB)/xstrncpy.o
9 +LO_OBJS = lomount.o rmd160.o $(LIB)/xstrncpy.o
10 NFS_OBJS = nfsmount.o nfsmount_xdr.o nfsmount_clnt.o
11 GEN_FILES = nfsmount.h nfsmount_xdr.c nfsmount_clnt.c
14 main_losetup.o: lomount.c
15 $(COMPILE) -DMAIN lomount.c -o $@
17 -losetup: main_losetup.o $(LIB)/xstrncpy.o
18 +losetup: main_losetup.o rmd160.o $(LIB)/xstrncpy.o
21 mount.o umount.o nfsmount.o losetup.o fstab.o realpath.o sundries.o: sundries.h
22 diff -Nur util-linux-2.11b.orig/mount/lomount.c util-linux-2.11b/mount/lomount.c
23 --- util-linux-2.11b.orig/mount/lomount.c Thu Mar 15 11:09:58 2001
24 +++ util-linux-2.11b/mount/lomount.c Wed Mar 28 12:09:33 2001
26 * - added Native Language Support
27 * Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
28 * - fixed strerr(errno) in gettext calls
29 + * 2000-09-24 Marc Mutz <Marc@Mutz.com>
30 + * - added long option names and the --pass-fd option to pass
31 + * passphrases via fd's to losetup/mount. Used for encryption in
32 + * non-interactive environments. The idea behind xgetpass() is stolen
33 + * from GnuPG, v.1.0.3 (http://www.gnupg.org/).
36 #define PROC_DEVICES "/proc/devices"
42 #include <sys/ioctl.h>
52 +#ifndef LO_CRYPT_CRYPTOAPI
53 +#define LO_CRYPT_CRYPTOAPI 18
57 extern char *xstrdup (const char *s); /* not: #include "sundries.h" */
58 extern void error (const char *fmt, ...); /* idem */
66 + int key_schedule_size;
69 +static int set_loop_passwd(struct loop_info *_loopinfo, int pfd, int keysz,
70 + const char *encryption, int fd, int ffd);
71 +static int get_cipher_info(const char *name, struct cipher_info *res);
72 +static int name_to_id(const char *name);
74 +static char *id_to_name(int fd);
78 struct crypt_type_struct {
82 } crypt_type_tbl[] = {
83 - { LO_CRYPT_NONE, "no" },
84 - { LO_CRYPT_NONE, "none" },
85 - { LO_CRYPT_XOR, "xor" },
86 - { LO_CRYPT_DES, "DES" },
88 + { LO_CRYPT_NONE, "no",0 },
89 + { LO_CRYPT_NONE, "none",0 },
90 + { LO_CRYPT_XOR, "xor",0 },
91 + { LO_CRYPT_DES, "DES",8 },
92 + { LO_CRYPT_FISH2, "twofish",20 },
93 + { LO_CRYPT_BLOW, "blowfish",20 },
94 + { LO_CRYPT_CAST128, "cast128",16 },
95 + { LO_CRYPT_IDEA, "idea",16 },
100 -crypt_type (const char *name) {
104 - for (i = 0; crypt_type_tbl[i].id != -1; i++)
105 - if (!strcasecmp (name, crypt_type_tbl[i].name))
106 - return crypt_type_tbl[i].id;
113 -crypt_name (int id) {
116 - for (i = 0; crypt_type_tbl[i].id != -1; i++)
117 - if (id == crypt_type_tbl[i].id)
118 - return crypt_type_tbl[i].name;
119 - return "undefined";
123 show_loop (char *device) {
124 struct loop_info loopinfo;
126 printf (_("%s: [%04x]:%ld (%s) offset %d, %s encryption\n"),
127 device, loopinfo.lo_device, loopinfo.lo_inode,
128 loopinfo.lo_name, loopinfo.lo_offset,
129 - crypt_name (loopinfo.lo_encrypt_type));
130 + id_to_name(loopinfo.lo_encrypt_type));
134 @@ -183,24 +194,64 @@
136 "mount: Could not find any loop device, and, according to %s,\n"
137 " this kernel does not know about the loop device.\n"
138 - " (If so, then recompile or `insmod loop.o'.)"),
139 + " (If so, then recompile or `modprobe loop'.)"),
143 "mount: Could not find any loop device. Maybe this kernel does not know\n"
144 - " about the loop device (then recompile or `insmod loop.o'), or\n"
145 + " about the loop device (then recompile or `modprobe loop'), or\n"
146 " maybe /dev/loop# has the wrong major number?"));
148 error(_("mount: could not find any free loop device"));
152 +#define HASHLENGTH 20
153 +#define PASSWDBUFFLEN 130 /* getpass returns only max. 128 bytes, see man getpass */
155 +/* A function to read the passphrase either from the terminal or from
156 + * an open file descriptor */
158 +xgetpass (int pfd, const char *prompt)
160 + if (pfd < 0) /* terminal */
161 + return (getpass(prompt));
162 + else { /* file descriptor */
168 + if (i >= buflen-1) {
169 + /* we're running out of space in the buffer.
170 + * Make it bigger: */
171 + char *tmppass = pass;
173 + pass = realloc(tmppass,buflen);
174 + if (pass == NULL) {
175 + /* realloc failed. Stop reading _now_. */
176 + error("not enough memory while reading passphrase");
177 + pass = tmppass; /* the old buffer hasn't changed */
181 + if ( read(pfd,pass+i, 1) != 1 || pass[i] == '\n' )
194 set_loop (const char *device, const char *file, int offset,
195 - const char *encryption, int *loopro) {
196 + const char *encryption, int pfd, int keysz, int *loopro) {
197 struct loop_info loopinfo;
198 - int fd, ffd, mode, i;
200 + int fd, ffd, mode, tried_old;
202 mode = (*loopro ? O_RDONLY : O_RDWR);
203 if ((ffd = open (file, mode)) < 0) {
204 @@ -218,13 +269,10 @@
205 *loopro = (mode == O_RDONLY);
207 memset (&loopinfo, 0, sizeof (loopinfo));
208 - xstrncpy (loopinfo.lo_name, file, LO_NAME_SIZE);
209 - if (encryption && (loopinfo.lo_encrypt_type = crypt_type (encryption))
211 - fprintf (stderr, _("Unsupported encryption type %s\n"),
215 + snprintf(loopinfo.lo_name, sizeof(loopinfo.lo_name),
216 + "%s-cbc", encryption);
217 + loopinfo.lo_name[LO_NAME_SIZE - 1] = 0;
218 + loopinfo.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
219 loopinfo.lo_offset = offset;
222 @@ -240,24 +288,74 @@
226 - switch (loopinfo.lo_encrypt_type) {
227 + if (ioctl (fd, LOOP_SET_FD, ffd) < 0) {
228 + perror ("ioctl: LOOP_SET_FD");
234 + set_loop_passwd(&loopinfo, pfd, keysz, encryption, fd, ffd);
236 + if (ioctl (fd, LOOP_SET_STATUS, &loopinfo) < 0) {
237 + /* Try again with old-style LO_CRYPT_XX if
238 + new style LO_CRYPT_CRYPTOAPI ioctl didn't work */
240 + error("The cipher does not exist, or a cipher module "
241 + "needs to be loaded into the kernel");
242 + perror ("ioctl: LOOP_SET_STATUS");
245 + strncpy (loopinfo.lo_name, file, LO_NAME_SIZE);
246 + loopinfo.lo_name[LO_NAME_SIZE - 1] = 0;
247 + loopinfo.lo_encrypt_type = name_to_id (encryption);
254 + printf(_("set_loop(%s,%s,%d): success\n"),
255 + device, file, offset);
258 + (void) ioctl (fd, LOOP_CLR_FD, 0);
263 +set_loop_passwd(struct loop_info *loopinfo, int pfd, int keysz,
264 + const char *encryption, int fd, int ffd)
269 + char keybits[2*HASHLENGTH];
270 + char passwdbuff[PASSWDBUFFLEN];
271 + struct cipher_info info;
273 + switch (loopinfo->lo_encrypt_type) {
275 - loopinfo.lo_encrypt_key_size = 0;
276 + loopinfo->lo_encrypt_key_size = 0;
279 - pass = getpass (_("Password: "));
280 - xstrncpy (loopinfo.lo_encrypt_key, pass, LO_KEY_SIZE);
281 - loopinfo.lo_encrypt_key_size = strlen(loopinfo.lo_encrypt_key);
282 + /* WARNING: xgetpass() can return massive amounts of data,
283 + * not only 128 bytes like the original getpass(3) */
284 + pass = xgetpass (pfd,_("Password: "));
285 + strncpy (loopinfo->lo_encrypt_key, pass, LO_KEY_SIZE);
286 + loopinfo->lo_encrypt_key[LO_KEY_SIZE - 1] = 0;
287 + loopinfo->lo_encrypt_key_size = strlen(loopinfo->lo_encrypt_key);
290 - pass = getpass (_("Password: "));
291 - strncpy (loopinfo.lo_encrypt_key, pass, 8);
292 - loopinfo.lo_encrypt_key[8] = 0;
293 - loopinfo.lo_encrypt_key_size = 8;
294 + printf(_("WARNING: Use of DES is depreciated.\n"));
295 + pass = xgetpass (pfd,_("Password: "));
296 + strncpy (loopinfo->lo_encrypt_key, pass, 8);
297 + loopinfo->lo_encrypt_key[8] = 0;
298 + loopinfo->lo_encrypt_key_size = 8;
299 pass = getpass (_("Init (up to 16 hex digits): "));
300 for (i = 0; i < 16 && pass[i]; i++)
301 if (isxdigit (pass[i])) {
302 - loopinfo.lo_init[i >> 3] |= (pass[i] > '9' ?
303 + loopinfo->lo_init[i >> 3] |= (pass[i] > '9' ?
304 (islower (pass[i]) ? toupper (pass[i]) :
305 pass[i])-'A'+10 : pass[i]-'0') << (i&7) * 4;
307 @@ -266,29 +364,82 @@
311 + case LO_CRYPT_FISH2:
312 + case LO_CRYPT_BLOW:
313 + case LO_CRYPT_IDEA:
314 + case LO_CRYPT_CAST128:
315 + pass = xgetpass(pfd, _("Password :"));
316 + strncpy(passwdbuff+1,pass,PASSWDBUFFLEN-1);
317 + passwdbuff[PASSWDBUFFLEN-1] = '\0';
318 + passwdbuff[0] = 'A';
319 + rmd160_hash_buffer(keybits,pass,strlen(pass));
320 + rmd160_hash_buffer(keybits+HASHLENGTH,passwdbuff,strlen(pass)+1);
321 + memcpy((char*)loopinfo->lo_encrypt_key,keybits,2*HASHLENGTH);
323 + for(i=0; crypt_type_tbl[i].id != -1; i++){
324 + if(loopinfo->lo_encrypt_type == crypt_type_tbl[i].id){
325 + keylength = crypt_type_tbl[i].keylength;
329 + loopinfo->lo_encrypt_key_size=keylength;
331 + case LO_CRYPT_CRYPTOAPI:
332 + /* Give the kernel an opportunity to load the cipher */
333 + (void) ioctl (fd, LOOP_SET_STATUS, loopinfo);
334 + if (get_cipher_info(loopinfo->lo_name, &info) < 0) {
338 + !((1 << ((keysz / 8) - 1)) & info.keysize_mask)) {
339 + error("The specified keysize is not supported by "
340 + "the selected cipher");
344 + while (keysz <= 0 ||
345 + !((1 << ((keysz / 8) - 1)) & info.keysize_mask)) {
349 + printf("Available keysizes (bits): ");
350 + for (; i < 32; i++) {
351 + if (info.keysize_mask & (1 << i)) {
352 + printf("%d ", 8*(i+1));
359 + printf("\nKeysize: ");
360 + fgets(keysize, sizeof(keysize), stdin);
361 + keysz = atoi(keysize);
364 + pass = xgetpass(pfd, _("Password :"));
365 + strncpy(passwdbuff+1,pass,PASSWDBUFFLEN-1);
366 + passwdbuff[PASSWDBUFFLEN-1] = '\0';
367 + passwdbuff[0] = 'A';
368 + rmd160_hash_buffer(keybits,pass,strlen(pass));
369 + rmd160_hash_buffer(keybits+HASHLENGTH,passwdbuff,strlen(pass)+1);
370 + memcpy((char*)loopinfo->lo_encrypt_key,keybits,2*HASHLENGTH);
372 + loopinfo->lo_encrypt_key_size=keysz/8;
377 _("Don't know how to get key for encryption system %d\n"),
378 - loopinfo.lo_encrypt_type);
381 - if (ioctl (fd, LOOP_SET_FD, ffd) < 0) {
382 - perror ("ioctl: LOOP_SET_FD");
383 + loopinfo->lo_encrypt_type);
386 - if (ioctl (fd, LOOP_SET_STATUS, &loopinfo) < 0) {
387 - (void) ioctl (fd, LOOP_CLR_FD, 0);
388 - perror ("ioctl: LOOP_SET_STATUS");
394 - printf(_("set_loop(%s,%s,%d): success\n"),
395 - device, file, offset);
404 del_loop (const char *device) {
409 set_loop (const char *device, const char *file, int offset,
410 - const char *encryption, int *loopro) {
411 + const char *encryption, int pfd, int *loopro) {
415 @@ -348,13 +499,40 @@
417 static char *progname;
419 +static struct option longopts[] = {
420 + { "delete", 0, 0, 'd' },
421 + { "detach", 0, 0, 'd' },
422 + { "encryption", 1, 0, 'e' },
423 + { "help", 0, 0, 'h' },
424 + { "offset", 1, 0, 'o' },
425 + { "pass-fd", 1, 0, 'p' },
426 + { "verbose", 0, 0, 'v' },
427 + { "keybits", 1, 0, 'k' },
434 fprintf(stderr, _("usage:\n\
435 %s loop_device # give info\n\
436 %s -d loop_device # delete\n\
437 - %s [ -e encryption ] [ -o offset ] loop_device file # setup\n"),
438 - progname, progname, progname);
439 + %s [ options ] loop_device file # setup\n\
440 + where options include\n\
441 + --offset <num>, -o <num>\n\
442 + start at offset <num> into file.\n\
443 + --pass-fd <num>, -p <num>\n\
444 + read passphrase from file descriptor <num>\n\
445 + instead of the terminal.\n\
446 + --encryption <cipher>, -e <cipher>\n\
447 + encrypt with <cipher>.\n\
448 + Check /proc/cipher for available ciphers.\n\
449 + --keybits <num>, -k <num>\n\
450 + specify number of bits in the hashed key given\n\
451 + to the cipher. Some ciphers support several key\n\
452 + sizes and might be more efficient with a smaller\n\
453 + key size. Key sizes < 128 are generally not\n\
454 + recommended\n"), progname, progname, progname);
458 @@ -387,19 +565,22 @@
461 main(int argc, char **argv) {
462 - char *offset, *encryption;
463 + char *offset, *encryption, *passfd, *keysize;
470 setlocale(LC_ALL, "");
471 bindtextdomain(PACKAGE, LOCALEDIR);
475 - offset = encryption = NULL;
476 + offset = encryption = passfd = keysize = NULL;
478 - while ((c = getopt(argc,argv,"de:o:v")) != EOF) {
479 + while ((c = getopt_long(argc,argv,"de:hk:o:p:v",
480 + longopts, NULL)) != EOF) {
503 if (argc == 1) usage();
504 - if ((delete && (argc != optind+1 || encryption || offset)) ||
505 + if ((delete && (argc != optind+1 || encryption || offset || passfd)) ||
506 (!delete && (argc < optind+1 || argc > optind+2)))
508 if (argc == optind+1) {
511 if (offset && sscanf(offset,"%d",&off) != 1)
513 - res = set_loop(argv[optind],argv[optind+1],off,encryption,&ro);
514 + if (passfd && sscanf(passfd,"%d",&pfd) != 1)
516 + if (keysize && sscanf(keysize,"%d",&keysz) != 1)
518 + res = set_loop(argv[optind], argv[optind+1], off,
519 + encryption, pfd, keysz, &ro);
528 +static int get_cipher_info(const char *name, struct cipher_info *res)
530 + char path[PATH_MAX];
535 + const char *prefix;
536 + } fields[] = {{&res->blocksize, "blocksize:"},
537 + {&res->keysize_mask, "keysize_mask:"},
538 + {&res->ivsize, "ivsize:"},
539 + {&res->key_schedule_size, "key_schedule_size:"}};
540 + snprintf(path, sizeof(path), "/proc/crypto/cipher/%s", name);
541 + f = fopen(path, "r");
542 + while(f && fgets(buf, sizeof(buf), f)) {
544 + for (i = 0; i < sizeof(fields)/sizeof(fields[0]); i++) {
545 + int len = strlen(fields[i].prefix);
546 + if (strncmp(buf, fields[i].prefix, len) == 0) {
547 + *fields[i].out = strtoul(&buf[len+1], NULL, 0);
560 +name_to_id(const char *name)
565 + for (i = 0; crypt_type_tbl[i].id != -1; i++)
566 + if (!strcasecmp (name, crypt_type_tbl[i].name))
567 + return crypt_type_tbl[i].id;
569 + return LO_CRYPT_NONE;
570 + return LO_CRYPT_CRYPTOAPI;
575 +id_to_name(int id) {
578 + for (i = 0; crypt_type_tbl[i].id != -1; i++)
579 + if (id == crypt_type_tbl[i].id)
580 + return crypt_type_tbl[i].name;
581 + return "undefined";
585 diff -Nur util-linux-2.11b.orig/mount/lomount.h util-linux-2.11b/mount/lomount.h
586 --- util-linux-2.11b.orig/mount/lomount.h Fri Dec 8 19:08:02 2000
587 +++ util-linux-2.11b/mount/lomount.h Wed Mar 28 11:38:53 2001
590 -extern int set_loop (const char *, const char *, int, const char *, int *);
591 +extern int set_loop (const char *, const char *, int, const char *,
593 extern int del_loop (const char *);
594 extern int is_loop_device (const char *);
595 extern char * find_unused_loop_device (void);
596 diff -Nur util-linux-2.11b.orig/mount/losetup.8 util-linux-2.11b/mount/losetup.8
597 --- util-linux-2.11b.orig/mount/losetup.8 Fri Aug 11 13:11:30 2000
598 +++ util-linux-2.11b/mount/losetup.8 Wed Mar 28 11:38:53 2001
610 \fIloop_device\fP argument is given, the status of the corresponding loop
614 +.IP "\fB\-\-delete, \-\-detach, \-d\fP"
615 detach the file or device associated with the specified loop device.
616 -.IP "\fB\-e \fIencryption\fP"
617 +.IP "\fB\-\-encryption, \-e \fIencryption\fP"
619 enable data encryption. The following keywords are recognized:
624 use a simple XOR encryption.
626 +use Advanced Encryption Standard encryption. AES encryption is only available
627 +if you are using the international kernel and AES encryption has been enabled
629 +enabled in the Crypto API.
631 +use Blowfish encryption. Blowfish encryption is only available if you
632 +are using the international kernel and Blowfish encryption has been
633 +enabled in the Crypto API.
635 +use Twofish encryption. Twofish encryption is only available if you
636 +are using the international kernel and Twofish encryption has been
637 +enabled in the Crypto API.
639 +use CAST encryption. CAST encryption is only available if you
640 +are using the international kernel and CAST encryption has been
641 +enabled in the Crypto API.
643 use DES encryption. DES encryption is only available if the optional
644 DES package has been added to the kernel. DES encryption uses an additional
645 start value that is used to protect passwords against dictionary
647 +attacks. Use of DES is deprecated.
649 +use DFC encryption. DFC encryption is only available if you
650 +are using the international kernel and DFC encryption has been
651 +enabled in the Crypto API.
653 +use IDEA encryption. IDEA encryption is only available if you
654 +are using the international kernel and IDEA encryption has been
655 +enabled in the Crypto API.
657 +use MARS encryption. MARS encryption is only available if you
658 +are using the international kernel and MARS encryption has been
659 +enabled in the Crypto API.
661 +use RC5 encryption. RC5 encryption is only available if you
662 +are using the international kernel and RC5 encryption has been
663 +enabled in the Crypto API.
665 +use RC6 encryption. RC6 encryption is only available if you
666 +are using the international kernel and RC6 encryption has been
667 +enabled in the Crypto API.
669 +use Serpent encryption. Serpent encryption is only available if you
670 +are using the international kernel and Serpent encryption has been
671 +enabled in the Crypto API.
674 -.IP "\fB\-o \fIoffset\fP"
675 +.IP "\fB\-\-offset, \-o \fIoffset\fP"
676 the data start is moved \fIoffset\fP bytes into the specified file or
678 +.IP "\fB\-\-pass-fd, \-p \fInum\fP"
679 +read the passphrase from file descriptor \fInum\fP instead of the
681 +.IP "\fB\-\-keybits, \-k \fInum\fP"
682 +set the number of bits to use in key to \fInum\fP.
685 returns 0 on success, nonzero on failure. When
689 /dev/loop0,/dev/loop1,... loop devices (major=7)
690 +/proc/cipher/* available ciphers
693 If you are using the loadable module you must have the module loaded
697 dd if=/dev/zero of=/file bs=1k count=100
698 -losetup -e des /dev/loop0 /file
700 -Init (up to 16 hex digits):
701 +losetup -e blowfish /dev/loop0 /file
703 mkfs -t ext2 /dev/loop0 100
704 mount -t ext2 /dev/loop0 /mnt
711 -DES encryption is painfully slow. On the other hand, XOR is terribly weak.
713 +DES encryption is painfully slow. On the other hand, XOR is terribly
714 +weak. Both are insecure nowadays. Some ciphers require a licence for
715 +you to be allowed to use them.
717 +CAST, DES, RC5 and Twofish are currently broken and cannot be used.
720 Original version: Theodore Ts'o <tytso@athena.mit.edu>
721 diff -Nur util-linux-2.11b.orig/mount/mount.8 util-linux-2.11b/mount/mount.8
722 --- util-linux-2.11b.orig/mount/mount.8 Mon Mar 19 22:21:28 2001
723 +++ util-linux-2.11b/mount/mount.8 Wed Mar 28 11:38:53 2001
729 +If the mount requires a passphrase to be entered, read it from file
732 +instead of from the terminal.
735 Mount all filesystems (of the given types) mentioned in
738 .BR noexec ", " nosuid ", and " nodev
739 (unless overridden by subsequent options, as in the option line
740 .BR users,exec,dev,suid ).
743 +Specifies an encryption algorithm to use. Used in conjunction with the
747 +Specifies the key size to use for an encryption algorithm. Used in conjunction
749 +.BR loop " and " encryption " options."
752 .SH "FILESYSTEM SPECIFIC MOUNT OPTIONS"
753 @@ -1349,7 +1364,10 @@
754 .BR loop ", " offset " and " encryption ,
755 that are really options to
757 -If no explicit loop device is mentioned
758 +If the mount requires a passphrase, you will be prompted for one unless
759 +you specify a file descriptor to read from instead with the
761 +option. If no explicit loop device is mentioned
762 (but just an option `\fB\-o loop\fP' is given), then
764 will try to find some unused loop device and use that.
765 diff -Nur util-linux-2.11b.orig/mount/mount.c util-linux-2.11b/mount/mount.c
766 --- util-linux-2.11b.orig/mount/mount.c Thu Mar 15 11:09:59 2001
767 +++ util-linux-2.11b/mount/mount.c Wed Mar 28 12:10:45 2001
769 /* True if ruid != euid. */
772 +/* Contains the fd no. to read the passphrase from, if any */
773 +static int pfd = -1;
775 +/* Contains the preferred keysize in bits we want to use */
776 +static int keysz = 0;
778 /* Map from -o and fstab option strings to the flag argument to mount(2). */
780 const char *opt; /* option name */
783 printf(_("mount: going to use the loop device %s\n"), *loopdev);
784 offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0;
785 - if (set_loop (*loopdev, *loopfile, offset, opt_encryption, &loopro)) {
786 + if (set_loop (*loopdev, *loopfile, offset, opt_encryption, pfd,
789 printf(_("mount: failed setting up loop device\n"));
791 @@ -1281,6 +1288,8 @@
792 { "read-write", 0, 0, 'w' },
794 { "options", 1, 0, 'o' },
795 + { "pass-fd", 1, 0, 'p' },
796 + { "keybits", 1, 0, 'k' },
797 { "types", 1, 0, 't' },
798 { "bind", 0, 0, 128 },
799 { "replace", 0, 0, 129 },
800 @@ -1313,7 +1322,7 @@
801 " mount --bind olddir newdir\n"
802 "A device can be given by name, say /dev/hda1 or /dev/cdrom,\n"
803 "or by label, using -L label or by uuid, using -U uuid .\n"
804 - "Other options: [-nfFrsvw] [-o options].\n"
805 + "Other options: [-nfFrsvw] [-o options] [-p num].\n"
806 "For many more details, say man 8 mount .\n"
809 @@ -1329,6 +1338,8 @@
810 int c, result = 0, specseen;
811 char *options = NULL, *spec, *node;
812 char *volumelabel = NULL;
813 + char *passfd = NULL;
814 + char *keysize = NULL;
816 string_list types = NULL;
817 struct mntentchn *mc;
818 @@ -1349,7 +1360,7 @@
819 initproctitle(argc, argv);
822 - while ((c = getopt_long (argc, argv, "afFhlL:no:rsU:vVwt:",
823 + while ((c = getopt_long (argc, argv, "afFhlL:no:p:rsU:vVwt:",
824 longopts, NULL)) != EOF) {
826 case 'a': /* mount everything in fstab */
827 @@ -1364,6 +1375,9 @@
835 list_with_volumelabel = 1;
837 @@ -1379,6 +1393,9 @@
839 options = xstrdup(optarg);
841 + case 'p': /* read passphrase from given fd */
844 case 'r': /* mount readonly */
847 @@ -1466,6 +1483,11 @@
848 printf(_("mount: mounting %s\n"), spec);
850 spec = NULL; /* just for gcc */
852 + if (passfd && sscanf(passfd,"%d",&pfd) != 1)
853 + die (EX_USAGE, _("mount: argument to --pass-fd or -p must be a number"));
854 + if (keysize && sscanf(keysize,"%d",&keysz) != 1)
855 + die (EX_USAGE, _("mount: argument to --keybits or -k must be a number"));
857 switch (argc+specseen) {
859 diff -Nur util-linux-2.11b.orig/mount/rmd160.c util-linux-2.11b/mount/rmd160.c
860 --- util-linux-2.11b.orig/mount/rmd160.c Thu Jan 1 01:00:00 1970
861 +++ util-linux-2.11b/mount/rmd160.c Wed Mar 28 11:38:53 2001
863 +/* rmd160.c - RIPE-MD160
864 + * Copyright (C) 1998 Free Software Foundation, Inc.
867 +/* This file was part of GnuPG. Modified for use within the Linux
868 + * mount utility by Marc Mutz <Marc@Mutz.com>. None of this code is
869 + * by myself. I just removed everything that you don't need when all
870 + * you want to do is to use rmd160_hash_buffer().
871 + * My comments are marked with (mm). */
873 +/* GnuPG is free software; you can redistribute it and/or modify
874 + * it under the terms of the GNU General Public License as published by
875 + * the Free Software Foundation; either version 2 of the License, or
876 + * (at your option) any later version.
878 + * GnuPG is distributed in the hope that it will be useful,
879 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
880 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
881 + * GNU General Public License for more details.
883 + * You should have received a copy of the GNU General Public License
884 + * along with this program; if not, write to the Free Software
885 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */
887 +#include <string.h> /* (mm) for memcpy */
888 +#include <endian.h> /* (mm) for BIG_ENDIAN and BYTE_ORDER */
891 +/* (mm) these are used by the original GnuPG file. In order to modify
892 + * that file not too much, we keep the notations. maybe it would be
893 + * better to include linux/types.h and typedef __u32 to u32 and __u8
895 +typedef unsigned int u32; /* taken from e.g. util-linux's minix.h */
896 +typedef unsigned char byte;
899 + u32 h0,h1,h2,h3,h4;
906 + * Rotate a 32 bit integer by n bytes
908 +#if defined(__GNUC__) && defined(__i386__)
912 + __asm__("roll %%cl,%0"
918 + #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
921 +/*********************************
922 + * RIPEMD-160 is not patented, see (as of 25.10.97)
923 + * http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
924 + * Note that the code uses Little Endian byteorder, which is good for
925 + * 386 etc, but we must add some conversion when used on a big endian box.
928 + * Pseudo-code for RIPEMD-160
930 + * RIPEMD-160 is an iterative hash function that operates on 32-bit words.
931 + * The round function takes as input a 5-word chaining variable and a 16-word
932 + * message block and maps this to a new chaining variable. All operations are
933 + * defined on 32-bit words. Padding is identical to that of MD4.
936 + * RIPEMD-160: definitions
939 + * nonlinear functions at bit level: exor, mux, -, mux, -
941 + * f(j, x, y, z) = x XOR y XOR z (0 <= j <= 15)
942 + * f(j, x, y, z) = (x AND y) OR (NOT(x) AND z) (16 <= j <= 31)
943 + * f(j, x, y, z) = (x OR NOT(y)) XOR z (32 <= j <= 47)
944 + * f(j, x, y, z) = (x AND z) OR (y AND NOT(z)) (48 <= j <= 63)
945 + * f(j, x, y, z) = x XOR (y OR NOT(z)) (64 <= j <= 79)
948 + * added constants (hexadecimal)
950 + * K(j) = 0x00000000 (0 <= j <= 15)
951 + * K(j) = 0x5A827999 (16 <= j <= 31) int(2**30 x sqrt(2))
952 + * K(j) = 0x6ED9EBA1 (32 <= j <= 47) int(2**30 x sqrt(3))
953 + * K(j) = 0x8F1BBCDC (48 <= j <= 63) int(2**30 x sqrt(5))
954 + * K(j) = 0xA953FD4E (64 <= j <= 79) int(2**30 x sqrt(7))
955 + * K'(j) = 0x50A28BE6 (0 <= j <= 15) int(2**30 x cbrt(2))
956 + * K'(j) = 0x5C4DD124 (16 <= j <= 31) int(2**30 x cbrt(3))
957 + * K'(j) = 0x6D703EF3 (32 <= j <= 47) int(2**30 x cbrt(5))
958 + * K'(j) = 0x7A6D76E9 (48 <= j <= 63) int(2**30 x cbrt(7))
959 + * K'(j) = 0x00000000 (64 <= j <= 79)
962 + * selection of message word
964 + * r(j) = j (0 <= j <= 15)
965 + * r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
966 + * r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
967 + * r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
968 + * r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
969 + * r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
970 + * r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
971 + * r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
972 + * r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
973 + * r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
976 + * amount for rotate left (rol)
978 + * s(0..15) = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
979 + * s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
980 + * s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
981 + * s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
982 + * s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
983 + * s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
984 + * s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
985 + * s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
986 + * s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
987 + * s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
990 + * initial value (hexadecimal)
992 + * h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476;
996 + * RIPEMD-160: pseudo-code
998 + * It is assumed that the message after padding consists of t 16-word blocks
999 + * that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15.
1000 + * The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left
1001 + * shift (rotate) over s positions.
1004 + * for i := 0 to t-1 {
1005 + * A := h0; B := h1; C := h2; D = h3; E = h4;
1006 + * A' := h0; B' := h1; C' := h2; D' = h3; E' = h4;
1007 + * for j := 0 to 79 {
1008 + * T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E;
1009 + * A := E; E := D; D := rol_10(C); C := B; B := T;
1010 + * T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)]
1011 + [+] K'(j)) [+] E';
1012 + * A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T;
1014 + * T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A';
1015 + * h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T;
1020 + * "" 9c1185a5c5e9fc54612808977ee8f548b2258d31
1021 + * "a" 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe
1022 + * "abc" 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
1023 + * "message digest" 5d0689ef49d2fae572b881b123a85ffa21595f36
1024 + * "a...z" f71c27109c692c1b56bbdceb5b9d2865b3708dbc
1025 + * "abcdbcde...nopq" 12a053384a9c0c88e405a06c27dcf49ada62eb2b
1026 + * "A...Za...z0...9" b0e20b6e3116640286ed3a87a5713079b21f5189
1027 + * 8 times "1234567890" 9b752e45573d4b39f4dbd3323cab82bf63326bfb
1028 + * 1 million times "a" 52783243c1697bdbe16d37f97f68f08325dc1528
1033 +rmd160_init( RMD160_CONTEXT *hd )
1035 + hd->h0 = 0x67452301;
1036 + hd->h1 = 0xEFCDAB89;
1037 + hd->h2 = 0x98BADCFE;
1038 + hd->h3 = 0x10325476;
1039 + hd->h4 = 0xC3D2E1F0;
1047 + * Transform the message X which consists of 16 32-bit-words
1050 +transform( RMD160_CONTEXT *hd, byte *data )
1052 + u32 a,b,c,d,e,aa,bb,cc,dd,ee,t;
1053 + #if BYTE_ORDER == BIG_ENDIAN
1057 + for(i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 ) {
1066 + u32 *x =(u32*)data;
1068 + /* this version is better because it is always aligned;
1069 + * The performance penalty on a 586-100 is about 6% which
1070 + * is acceptable - because the data is more local it might
1071 + * also be possible that this is faster on some machines.
1072 + * This function (when compiled with -02 on gcc 2.7.2)
1073 + * executes on a 586-100 (39.73 bogomips) at about 1900kb/sec;
1074 + * [measured with a 4MB data and "gpgm --print-md rmd160"] */
1076 + memcpy( x, data, 64 );
1081 +#define K0 0x00000000
1082 +#define K1 0x5A827999
1083 +#define K2 0x6ED9EBA1
1084 +#define K3 0x8F1BBCDC
1085 +#define K4 0xA953FD4E
1086 +#define KK0 0x50A28BE6
1087 +#define KK1 0x5C4DD124
1088 +#define KK2 0x6D703EF3
1089 +#define KK3 0x7A6D76E9
1090 +#define KK4 0x00000000
1091 +#define F0(x,y,z) ( (x) ^ (y) ^ (z) )
1092 +#define F1(x,y,z) ( ((x) & (y)) | (~(x) & (z)) )
1093 +#define F2(x,y,z) ( ((x) | ~(y)) ^ (z) )
1094 +#define F3(x,y,z) ( ((x) & (z)) | ((y) & ~(z)) )
1095 +#define F4(x,y,z) ( (x) ^ ((y) | ~(z)) )
1096 +#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \
1097 + a = rol(t,s) + e; \
1107 + R( a, b, c, d, e, F0, K0, 0, 11 );
1108 + R( e, a, b, c, d, F0, K0, 1, 14 );
1109 + R( d, e, a, b, c, F0, K0, 2, 15 );
1110 + R( c, d, e, a, b, F0, K0, 3, 12 );
1111 + R( b, c, d, e, a, F0, K0, 4, 5 );
1112 + R( a, b, c, d, e, F0, K0, 5, 8 );
1113 + R( e, a, b, c, d, F0, K0, 6, 7 );
1114 + R( d, e, a, b, c, F0, K0, 7, 9 );
1115 + R( c, d, e, a, b, F0, K0, 8, 11 );
1116 + R( b, c, d, e, a, F0, K0, 9, 13 );
1117 + R( a, b, c, d, e, F0, K0, 10, 14 );
1118 + R( e, a, b, c, d, F0, K0, 11, 15 );
1119 + R( d, e, a, b, c, F0, K0, 12, 6 );
1120 + R( c, d, e, a, b, F0, K0, 13, 7 );
1121 + R( b, c, d, e, a, F0, K0, 14, 9 );
1122 + R( a, b, c, d, e, F0, K0, 15, 8 );
1123 + R( e, a, b, c, d, F1, K1, 7, 7 );
1124 + R( d, e, a, b, c, F1, K1, 4, 6 );
1125 + R( c, d, e, a, b, F1, K1, 13, 8 );
1126 + R( b, c, d, e, a, F1, K1, 1, 13 );
1127 + R( a, b, c, d, e, F1, K1, 10, 11 );
1128 + R( e, a, b, c, d, F1, K1, 6, 9 );
1129 + R( d, e, a, b, c, F1, K1, 15, 7 );
1130 + R( c, d, e, a, b, F1, K1, 3, 15 );
1131 + R( b, c, d, e, a, F1, K1, 12, 7 );
1132 + R( a, b, c, d, e, F1, K1, 0, 12 );
1133 + R( e, a, b, c, d, F1, K1, 9, 15 );
1134 + R( d, e, a, b, c, F1, K1, 5, 9 );
1135 + R( c, d, e, a, b, F1, K1, 2, 11 );
1136 + R( b, c, d, e, a, F1, K1, 14, 7 );
1137 + R( a, b, c, d, e, F1, K1, 11, 13 );
1138 + R( e, a, b, c, d, F1, K1, 8, 12 );
1139 + R( d, e, a, b, c, F2, K2, 3, 11 );
1140 + R( c, d, e, a, b, F2, K2, 10, 13 );
1141 + R( b, c, d, e, a, F2, K2, 14, 6 );
1142 + R( a, b, c, d, e, F2, K2, 4, 7 );
1143 + R( e, a, b, c, d, F2, K2, 9, 14 );
1144 + R( d, e, a, b, c, F2, K2, 15, 9 );
1145 + R( c, d, e, a, b, F2, K2, 8, 13 );
1146 + R( b, c, d, e, a, F2, K2, 1, 15 );
1147 + R( a, b, c, d, e, F2, K2, 2, 14 );
1148 + R( e, a, b, c, d, F2, K2, 7, 8 );
1149 + R( d, e, a, b, c, F2, K2, 0, 13 );
1150 + R( c, d, e, a, b, F2, K2, 6, 6 );
1151 + R( b, c, d, e, a, F2, K2, 13, 5 );
1152 + R( a, b, c, d, e, F2, K2, 11, 12 );
1153 + R( e, a, b, c, d, F2, K2, 5, 7 );
1154 + R( d, e, a, b, c, F2, K2, 12, 5 );
1155 + R( c, d, e, a, b, F3, K3, 1, 11 );
1156 + R( b, c, d, e, a, F3, K3, 9, 12 );
1157 + R( a, b, c, d, e, F3, K3, 11, 14 );
1158 + R( e, a, b, c, d, F3, K3, 10, 15 );
1159 + R( d, e, a, b, c, F3, K3, 0, 14 );
1160 + R( c, d, e, a, b, F3, K3, 8, 15 );
1161 + R( b, c, d, e, a, F3, K3, 12, 9 );
1162 + R( a, b, c, d, e, F3, K3, 4, 8 );
1163 + R( e, a, b, c, d, F3, K3, 13, 9 );
1164 + R( d, e, a, b, c, F3, K3, 3, 14 );
1165 + R( c, d, e, a, b, F3, K3, 7, 5 );
1166 + R( b, c, d, e, a, F3, K3, 15, 6 );
1167 + R( a, b, c, d, e, F3, K3, 14, 8 );
1168 + R( e, a, b, c, d, F3, K3, 5, 6 );
1169 + R( d, e, a, b, c, F3, K3, 6, 5 );
1170 + R( c, d, e, a, b, F3, K3, 2, 12 );
1171 + R( b, c, d, e, a, F4, K4, 4, 9 );
1172 + R( a, b, c, d, e, F4, K4, 0, 15 );
1173 + R( e, a, b, c, d, F4, K4, 5, 5 );
1174 + R( d, e, a, b, c, F4, K4, 9, 11 );
1175 + R( c, d, e, a, b, F4, K4, 7, 6 );
1176 + R( b, c, d, e, a, F4, K4, 12, 8 );
1177 + R( a, b, c, d, e, F4, K4, 2, 13 );
1178 + R( e, a, b, c, d, F4, K4, 10, 12 );
1179 + R( d, e, a, b, c, F4, K4, 14, 5 );
1180 + R( c, d, e, a, b, F4, K4, 1, 12 );
1181 + R( b, c, d, e, a, F4, K4, 3, 13 );
1182 + R( a, b, c, d, e, F4, K4, 8, 14 );
1183 + R( e, a, b, c, d, F4, K4, 11, 11 );
1184 + R( d, e, a, b, c, F4, K4, 6, 8 );
1185 + R( c, d, e, a, b, F4, K4, 15, 5 );
1186 + R( b, c, d, e, a, F4, K4, 13, 6 );
1188 + aa = a; bb = b; cc = c; dd = d; ee = e;
1196 + R( a, b, c, d, e, F4, KK0, 5, 8);
1197 + R( e, a, b, c, d, F4, KK0, 14, 9);
1198 + R( d, e, a, b, c, F4, KK0, 7, 9);
1199 + R( c, d, e, a, b, F4, KK0, 0, 11);
1200 + R( b, c, d, e, a, F4, KK0, 9, 13);
1201 + R( a, b, c, d, e, F4, KK0, 2, 15);
1202 + R( e, a, b, c, d, F4, KK0, 11, 15);
1203 + R( d, e, a, b, c, F4, KK0, 4, 5);
1204 + R( c, d, e, a, b, F4, KK0, 13, 7);
1205 + R( b, c, d, e, a, F4, KK0, 6, 7);
1206 + R( a, b, c, d, e, F4, KK0, 15, 8);
1207 + R( e, a, b, c, d, F4, KK0, 8, 11);
1208 + R( d, e, a, b, c, F4, KK0, 1, 14);
1209 + R( c, d, e, a, b, F4, KK0, 10, 14);
1210 + R( b, c, d, e, a, F4, KK0, 3, 12);
1211 + R( a, b, c, d, e, F4, KK0, 12, 6);
1212 + R( e, a, b, c, d, F3, KK1, 6, 9);
1213 + R( d, e, a, b, c, F3, KK1, 11, 13);
1214 + R( c, d, e, a, b, F3, KK1, 3, 15);
1215 + R( b, c, d, e, a, F3, KK1, 7, 7);
1216 + R( a, b, c, d, e, F3, KK1, 0, 12);
1217 + R( e, a, b, c, d, F3, KK1, 13, 8);
1218 + R( d, e, a, b, c, F3, KK1, 5, 9);
1219 + R( c, d, e, a, b, F3, KK1, 10, 11);
1220 + R( b, c, d, e, a, F3, KK1, 14, 7);
1221 + R( a, b, c, d, e, F3, KK1, 15, 7);
1222 + R( e, a, b, c, d, F3, KK1, 8, 12);
1223 + R( d, e, a, b, c, F3, KK1, 12, 7);
1224 + R( c, d, e, a, b, F3, KK1, 4, 6);
1225 + R( b, c, d, e, a, F3, KK1, 9, 15);
1226 + R( a, b, c, d, e, F3, KK1, 1, 13);
1227 + R( e, a, b, c, d, F3, KK1, 2, 11);
1228 + R( d, e, a, b, c, F2, KK2, 15, 9);
1229 + R( c, d, e, a, b, F2, KK2, 5, 7);
1230 + R( b, c, d, e, a, F2, KK2, 1, 15);
1231 + R( a, b, c, d, e, F2, KK2, 3, 11);
1232 + R( e, a, b, c, d, F2, KK2, 7, 8);
1233 + R( d, e, a, b, c, F2, KK2, 14, 6);
1234 + R( c, d, e, a, b, F2, KK2, 6, 6);
1235 + R( b, c, d, e, a, F2, KK2, 9, 14);
1236 + R( a, b, c, d, e, F2, KK2, 11, 12);
1237 + R( e, a, b, c, d, F2, KK2, 8, 13);
1238 + R( d, e, a, b, c, F2, KK2, 12, 5);
1239 + R( c, d, e, a, b, F2, KK2, 2, 14);
1240 + R( b, c, d, e, a, F2, KK2, 10, 13);
1241 + R( a, b, c, d, e, F2, KK2, 0, 13);
1242 + R( e, a, b, c, d, F2, KK2, 4, 7);
1243 + R( d, e, a, b, c, F2, KK2, 13, 5);
1244 + R( c, d, e, a, b, F1, KK3, 8, 15);
1245 + R( b, c, d, e, a, F1, KK3, 6, 5);
1246 + R( a, b, c, d, e, F1, KK3, 4, 8);
1247 + R( e, a, b, c, d, F1, KK3, 1, 11);
1248 + R( d, e, a, b, c, F1, KK3, 3, 14);
1249 + R( c, d, e, a, b, F1, KK3, 11, 14);
1250 + R( b, c, d, e, a, F1, KK3, 15, 6);
1251 + R( a, b, c, d, e, F1, KK3, 0, 14);
1252 + R( e, a, b, c, d, F1, KK3, 5, 6);
1253 + R( d, e, a, b, c, F1, KK3, 12, 9);
1254 + R( c, d, e, a, b, F1, KK3, 2, 12);
1255 + R( b, c, d, e, a, F1, KK3, 13, 9);
1256 + R( a, b, c, d, e, F1, KK3, 9, 12);
1257 + R( e, a, b, c, d, F1, KK3, 7, 5);
1258 + R( d, e, a, b, c, F1, KK3, 10, 15);
1259 + R( c, d, e, a, b, F1, KK3, 14, 8);
1260 + R( b, c, d, e, a, F0, KK4, 12, 8);
1261 + R( a, b, c, d, e, F0, KK4, 15, 5);
1262 + R( e, a, b, c, d, F0, KK4, 10, 12);
1263 + R( d, e, a, b, c, F0, KK4, 4, 9);
1264 + R( c, d, e, a, b, F0, KK4, 1, 12);
1265 + R( b, c, d, e, a, F0, KK4, 5, 5);
1266 + R( a, b, c, d, e, F0, KK4, 8, 14);
1267 + R( e, a, b, c, d, F0, KK4, 7, 6);
1268 + R( d, e, a, b, c, F0, KK4, 6, 8);
1269 + R( c, d, e, a, b, F0, KK4, 2, 13);
1270 + R( b, c, d, e, a, F0, KK4, 13, 6);
1271 + R( a, b, c, d, e, F0, KK4, 14, 5);
1272 + R( e, a, b, c, d, F0, KK4, 0, 15);
1273 + R( d, e, a, b, c, F0, KK4, 3, 13);
1274 + R( c, d, e, a, b, F0, KK4, 9, 11);
1275 + R( b, c, d, e, a, F0, KK4, 11, 11);
1278 + t = hd->h1 + d + cc;
1279 + hd->h1 = hd->h2 + e + dd;
1280 + hd->h2 = hd->h3 + a + ee;
1281 + hd->h3 = hd->h4 + b + aa;
1282 + hd->h4 = hd->h0 + c + bb;
1287 +/* Update the message digest with the contents
1288 + * of INBUF with length INLEN.
1291 +rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen)
1293 + if( hd->count == 64 ) { /* flush the buffer */
1294 + transform( hd, hd->buf );
1301 + for( ; inlen && hd->count < 64; inlen-- )
1302 + hd->buf[hd->count++] = *inbuf++;
1303 + rmd160_write( hd, NULL, 0 );
1308 + while( inlen >= 64 ) {
1309 + transform( hd, inbuf );
1315 + for( ; inlen && hd->count < 64; inlen-- )
1316 + hd->buf[hd->count++] = *inbuf++;
1319 +/* The routine terminates the computation
1323 +rmd160_final( RMD160_CONTEXT *hd )
1328 + rmd160_write(hd, NULL, 0); /* flush */;
1332 + if( (lsb = t << 6) < t ) /* multiply by 64 to make a byte count */
1336 + if( (lsb = t + hd->count) < t ) /* add the count */
1339 + if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
1343 + if( hd->count < 56 ) { /* enough room */
1344 + hd->buf[hd->count++] = 0x80; /* pad */
1345 + while( hd->count < 56 )
1346 + hd->buf[hd->count++] = 0; /* pad */
1348 + else { /* need one extra block */
1349 + hd->buf[hd->count++] = 0x80; /* pad character */
1350 + while( hd->count < 64 )
1351 + hd->buf[hd->count++] = 0;
1352 + rmd160_write(hd, NULL, 0); /* flush */;
1353 + memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
1355 + /* append the 64 bit count */
1356 + hd->buf[56] = lsb ;
1357 + hd->buf[57] = lsb >> 8;
1358 + hd->buf[58] = lsb >> 16;
1359 + hd->buf[59] = lsb >> 24;
1360 + hd->buf[60] = msb ;
1361 + hd->buf[61] = msb >> 8;
1362 + hd->buf[62] = msb >> 16;
1363 + hd->buf[63] = msb >> 24;
1364 + transform( hd, hd->buf );
1367 + #if BYTE_ORDER == BIG_ENDIAN
1368 + #define X(a) do { *p++ = hd->h##a ; *p++ = hd->h##a >> 8; \
1369 + *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
1370 + #else /* little endian */
1371 + #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
1382 + * Shortcut functions which puts the hash value of the supplied buffer
1383 + * into outbuf which must have a size of 20 bytes.
1386 +rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length )
1388 + RMD160_CONTEXT hd;
1390 + rmd160_init( &hd );
1391 + rmd160_write( &hd, (byte*)buffer, length );
1392 + rmd160_final( &hd );
1393 + memcpy( outbuf, hd.buf, 20 );
1395 diff -Nur util-linux-2.11b.orig/mount/rmd160.h util-linux-2.11b/mount/rmd160.h
1396 --- util-linux-2.11b.orig/mount/rmd160.h Thu Jan 1 01:00:00 1970
1397 +++ util-linux-2.11b/mount/rmd160.h Wed Mar 28 11:38:53 2001
1403 +rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length );
1405 +#endif /*RMD160_H*/