1 --- util-linux-2.12.orig/mount/Makefile
2 +++ util-linux-2.12/mount/Makefile
5 MAYBE = pivot_root swapoff
7 -LO_OBJS = lomount.o $(LIB)/xstrncpy.o
8 +LO_OBJS = lomount.o $(LIB)/xstrncpy.o rmd160.o
9 NFS_OBJS = nfsmount.o nfsmount_xdr.o nfsmount_clnt.o
10 GEN_FILES = nfsmount.h nfsmount_xdr.c nfsmount_clnt.c
13 main_losetup.o: lomount.c
14 $(COMPILE) -DMAIN lomount.c -o $@
16 -losetup: main_losetup.o $(LIB)/xstrncpy.o
17 +losetup: main_losetup.o $(LIB)/xstrncpy.o rmd160.o
20 mount.o umount.o nfsmount.o losetup.o fstab.o realpath.o sundries.o: sundries.h
21 --- util-linux-2.12/mount/lomount.c.orig 2003-07-17 01:56:53.000000000 +0200
22 +++ util-linux-2.12/mount/lomount.c 2004-08-04 19:27:23.000000000 +0200
32 -extern char *xstrdup (const char *s); /* not: #include "sundries.h" */
33 +extern char *xstrdup (const char *s); /* not: #include "sundries.h" */
34 extern void error (const char *fmt, ...); /* idem */
41 +struct crypt_type_struct {
45 +} crypt_type_tbl[] = {
46 + { LO_CRYPT_NONE, "none", 0 },
47 + { LO_CRYPT_XOR, "xor", 0 },
48 + { LO_CRYPT_DES, "des", 8 },
49 + { LO_CRYPT_FISH2, "twofish", 20 },
50 + { LO_CRYPT_BLOW, "blowfish", 20 },
51 + { LO_CRYPT_CAST128, "cast", 16 },
52 + { LO_CRYPT_SERPENT, "serpent", 16 },
53 + { LO_CRYPT_MARS, "mars", 16 },
54 + { LO_CRYPT_RC6, "rc6", 16 },
55 + { LO_CRYPT_3DES, "des-ede3", 24 },
56 + { LO_CRYPT_DFC, "dfc", 16 },
57 + { LO_CRYPT_IDEA, "idea", 16 },
58 + { LO_CRYPT_RIJNDAEL, "rijndael", 16 },
62 +static struct option longopts[] = {
63 + { "delete", 0, 0, 'd' },
64 + { "detach", 0, 0, 'd' },
65 + { "encryption", 1, 0, 'e' },
66 + { "help", 0, 0, 'h' },
67 + { "nopasshash", 1, 0, 'N' },
68 + { "offset", 1, 0, 'o' },
69 + { "pass-fd", 1, 0, 'p' },
70 + { "verbose", 0, 0, 'v' },
71 + { "keybits", 1, 0, 'k' },
76 +name_to_id(const char *name)
81 + for (i = 0; crypt_type_tbl[i].id != -1; i++)
82 + if (!strcasecmp (name, crypt_type_tbl[i].name))
83 + return crypt_type_tbl[i].id;
85 + return LO_CRYPT_NONE;
86 + return LO_CRYPT_CRYPTOAPI;
94 + for (i = 0; crypt_type_tbl[i].id != -1; i++)
95 + if (id == crypt_type_tbl[i].id)
96 + return crypt_type_tbl[i].name;
103 loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info)
106 printf(_(", offset %d"), loopinfo.lo_offset);
108 if (loopinfo.lo_encrypt_type)
109 - printf(_(", encryption type %d\n"),
110 + printf(_(", encryption %s (type %d)\n"),
111 + id_to_name(loopinfo.lo_encrypt_type),
112 loopinfo.lo_encrypt_type);
116 error(_("mount: could not find any device /dev/loop#"));
117 else if (!someloop) {
119 - "mount: Could not find any loop device. Maybe this kernel "
121 - " about the loop device? (If so, recompile or "
122 - "`modprobe loop'.)"));
123 + "mount: Could not find any loop device. Maybe this kernel does not know\n"
124 + " about the loop device? (If so, recompile or `modprobe loop'), or\n"
125 + " maybe /dev/loop# has the wrong major number?"));
127 error(_("mount: could not find any free loop device"));
129 @@ -247,10 +312,20 @@
132 set_loop(const char *device, const char *file, int offset,
133 - const char *encryption, int pfd, int *loopro) {
134 + const char *encryption, int pfd, int keysz, int *loopro, int hash_password) {
135 struct loop_info64 loopinfo64;
140 + int kerneli=open("/proc/crypto/cipher",O_RDONLY);
149 mode = (*loopro ? O_RDONLY : O_RDWR);
150 if ((ffd = open(file, mode)) < 0) {
152 loopinfo64.lo_encrypt_type = atoi(encryption);
154 loopinfo64.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
155 - snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
157 + snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
158 + "%s-cbc", encryption);
160 + snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
162 + loopinfo64.lo_crypt_name[LO_NAME_SIZE-1] = 0;
166 @@ -296,29 +376,98 @@
171 + keysz=LO_KEY_SIZE*8;
174 switch (loopinfo64.lo_encrypt_type) {
176 loopinfo64.lo_encrypt_key_size = 0;
179 pass = getpass(_("Password: "));
180 - xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
181 + xstrncpy(loopinfo64.lo_encrypt_key, pass, keysz/8);
182 loopinfo64.lo_encrypt_key_size =
183 strlen(loopinfo64.lo_encrypt_key);
186 + case LO_CRYPT_FISH2:
187 + case LO_CRYPT_BLOW:
188 + case LO_CRYPT_IDEA:
189 + case LO_CRYPT_CAST128:
190 + case LO_CRYPT_SERPENT:
191 + case LO_CRYPT_MARS:
193 + case LO_CRYPT_3DES:
195 + case LO_CRYPT_RIJNDAEL:
197 +#define HASHLENGTH 20
198 +#define PASSWDBUFFLEN 130 /* getpass returns only max. 128 bytes, see man getpass */
199 + char keybits[2*HASHLENGTH];
200 + char passwdbuff[PASSWDBUFFLEN];
204 pass = xgetpass(pfd, _("Password: "));
205 - xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
206 - loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;
207 + strncpy(passwdbuff+1,pass,PASSWDBUFFLEN-1);
208 + passwdbuff[PASSWDBUFFLEN-1] = '\0';
209 + passwdbuff[0] = 'A';
210 + rmd160_hash_buffer(keybits,pass,strlen(pass));
211 + rmd160_hash_buffer(keybits+HASHLENGTH,passwdbuff,strlen(pass)+1);
212 + memcpy((char*)loopinfo64.lo_encrypt_key,keybits,2*HASHLENGTH);
214 + for(i=0; crypt_type_tbl[i].id != -1; i++){
215 + if(loopinfo64.lo_encrypt_type == crypt_type_tbl[i].id){
216 + keylength = crypt_type_tbl[i].keylength;
220 + loopinfo64.lo_encrypt_key_size=keylength;
224 + if (hash_password) {
225 + char keybits[2*HASHLENGTH];
226 + char passwdbuff[PASSWDBUFFLEN];
228 + pass = xgetpass(pfd, _("Password: "));
229 + strncpy(passwdbuff+1,pass,PASSWDBUFFLEN-1);
230 + passwdbuff[PASSWDBUFFLEN-1] = '\0';
231 + passwdbuff[0] = 'A';
232 + rmd160_hash_buffer(keybits,pass,strlen(pass));
233 + rmd160_hash_buffer(keybits+HASHLENGTH,passwdbuff,strlen(pass)+1);
234 + memcpy((char*)loopinfo64.lo_encrypt_key,keybits,keysz/8);
236 + pass = xgetpass(pfd, _("Password: "));
237 + xstrncpy(loopinfo64.lo_encrypt_key, pass, keysz/8);
239 + loopinfo64.lo_encrypt_key_size = keysz/8;
242 if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
243 perror("ioctl: LOOP_SET_FD");
248 - if (ioctl(fd, LOOP_SET_STATUS64, &loopinfo64) < 0) {
250 + struct loop_info loopinfo;
251 + loop_info64_to_old(&loopinfo64,&loopinfo);
252 + if (ioctl (fd, LOOP_SET_STATUS, &loopinfo) < 0) {
253 + /* Try again with old-style LO_CRYPT_XX if
254 + new-style LO_CRYPT_CRYPTOAPI ioctl didn't work */
256 + error("The cipher does not exist, or a cipher module "
257 + "needs to be loaded into the kernel");
258 + perror ("ioctl: LOOP_SET_STATUS");
261 + strncpy (loopinfo64.lo_file_name, file, LO_NAME_SIZE);
262 + loopinfo64.lo_file_name[LO_NAME_SIZE - 1] = 0;
263 + loopinfo64.lo_encrypt_type = name_to_id (encryption);
268 + if (ioctl(fd, LOOP_SET_STATUS64, &loopinfo64) < 0) {
269 struct loop_info loopinfo;
273 perror("ioctl: LOOP_SET_STATUS");
282 printf(_("set_loop(%s,%s,%d): success\n"),
286 (void) ioctl (fd, LOOP_CLR_FD, 0);
292 fprintf(stderr, _("usage:\n\
293 %s loop_device # give info\n\
294 %s -d loop_device # delete\n\
295 - %s [ -e encryption ] [ -o offset ] loop_device file # setup\n"),
296 - progname, progname, progname);
297 + %s [ options ] loop_device file # setup\n\
298 + where options include\n\
299 + --offset <num>, -o <num>\n\
300 + start at offset <num> into file.\n\
301 + --pass-fd <num>, -p <num>\n\
302 + read passphrase from file descriptor <num>\n\
303 + instead of the terminal.\n\
304 + --encryption <cipher>, -e <cipher>\n\
305 + encrypt with <cipher>.\n\
306 + Check /proc/crypto or /proc/crypto/cipher for available ciphers.\n\
307 + --nohashpass, -N\n\
308 + Don't hash the password given. (previous versions hash, non-debian doesn't.\n\
309 + --keybits <num>, -k <num>\n\
310 + specify number of bits in the hashed key given\n\
311 + to the cipher. Some ciphers support several key\n\
312 + sizes and might be more efficient with a smaller\n\
313 + key size. Key sizes < 128 are generally not\n\
314 + recommended\n"), progname, progname, progname);
318 @@ -445,20 +613,23 @@
321 main(int argc, char **argv) {
322 - char *offset, *encryption, *passfd;
323 + char *offset, *encryption, *passfd, *keysize;
329 + int hash_password = 1;
331 setlocale(LC_ALL, "");
332 bindtextdomain(PACKAGE, LOCALEDIR);
336 - offset = encryption = passfd = NULL;
337 + offset = encryption = passfd = keysize = NULL;
339 - while ((c = getopt(argc,argv,"de:E:o:p:v")) != -1) {
340 + while ((c = getopt_long(argc,argv,"de:E:hk:No:p:v",
341 + longopts, NULL)) != EOF) {
360 if (passfd && sscanf(passfd,"%d",&pfd) != 1)
362 + if (keysize && sscanf(keysize,"%d",&keysz) != 1)
364 res = set_loop(argv[optind], argv[optind+1], off,
365 - encryption, pfd, &ro);
366 + encryption, pfd, keysz, &ro, hash_password);
370 --- util-linux-2.12.orig/mount/lomount.h
371 +++ util-linux-2.12/mount/lomount.h
374 extern int set_loop(const char *, const char *, int, const char *,
376 + int, int, int *, int);
377 extern int del_loop(const char *);
378 extern int is_loop_device(const char *);
379 extern char * find_unused_loop_device(void);
380 --- util-linux-2.12.orig/mount/loop.h
381 +++ util-linux-2.12/mount/loop.h
383 -#define LO_CRYPT_NONE 0
384 -#define LO_CRYPT_XOR 1
385 -#define LO_CRYPT_DES 2
386 +#define LO_CRYPT_NONE 0
387 +#define LO_CRYPT_XOR 1
388 +#define LO_CRYPT_DES 2
389 #define LO_CRYPT_CRYPTOAPI 18
391 +#ifndef LO_CRYPT_FISH2
392 +#define LO_CRYPT_FISH2 3
394 +#ifndef LO_CRYPT_BLOW
395 +#define LO_CRYPT_BLOW 4
397 +#ifndef LO_CRYPT_CAST128
398 +#define LO_CRYPT_CAST128 5
400 +#ifndef LO_CRYPT_IDEA
401 +#define LO_CRYPT_IDEA 6
403 +#ifndef LO_CRYPT_SERPENT
404 +#define LO_CRYPT_SERPENT 7
406 +#ifndef LO_CRYPT_MARS
407 +#define LO_CRYPT_MARS 8
409 +#ifndef LO_CRYPT_RC6
410 +#define LO_CRYPT_RC6 11
412 +#ifndef LO_CRYPT_3DES
413 +#define LO_CRYPT_3DES 12
415 +#ifndef LO_CRYPT_DFC
416 +#define LO_CRYPT_DFC 15
418 +#ifndef LO_CRYPT_RIJNDAEL
419 +#define LO_CRYPT_RIJNDAEL 16
422 #define LOOP_SET_FD 0x4C00
423 #define LOOP_CLR_FD 0x4C01
424 #define LOOP_SET_STATUS 0x4C02
425 --- util-linux-2.12.orig/mount/losetup.8
426 +++ util-linux-2.12/mount/losetup.8
432 -Detach the file or device associated with the specified loop device.
433 +.IP "\fB\-\-delete, \-\-detach, \-d\fP"
434 +detach the file or device associated with the specified loop device.
435 .IP "\fB\-E \fIencryption_type\fP"
436 Enable data encryption with specified number.
437 -.IP "\fB\-e \fIencryption_name\fP"
438 +.IP "\fB\-\-encryption, \-e \fIencryption\fP"
439 Enable data encryption with specified name.
440 -.IP "\fB\-o \fIoffset\fP"
441 +.IP "\fB\-\-nohashpass, \-N\fP"
442 +Do not hash the password. Many previous Debian releases run the password through a
443 +hash function, non-Debian systems appear to.
444 +.IP "\fB\-\-offset, \-o \fIoffset\fP"
445 The data start is moved \fIoffset\fP bytes into the specified file or
447 -.IP "\fB\-p \fInum\fP"
448 +.IP "\fB\-\-pass-fd, \-p \fInum\fP"
449 Read the passphrase from file descriptor with number
451 instead of from the terminal.
452 +.IP "\fB\-\-keybits, \-k \fInum\fP"
453 +set the number of bits to use in key to \fInum\fP.
456 returns 0 on success, nonzero on failure. When
460 DES encryption is painfully slow. On the other hand, XOR is terribly weak.
461 +Both are insecure nowadays. Some ciphers may require a licence for you to be
462 +allowed to use them.
466 .\" Original version: Theodore Ts'o <tytso@athena.mit.edu>
467 --- util-linux-2.12.orig/mount/mount.8
468 +++ util-linux-2.12/mount/mount.8
474 +If the mount requires a passphrase to be entered, read it from file
477 +instead of from the terminal.
480 Mount all filesystems (of the given types) mentioned in
483 .BR noexec ", " nosuid ", and " nodev
484 (unless overridden by subsequent options, as in the option line
485 .BR users,exec,dev,suid ).
488 +Specifies an encryption algorithm to use. Used in conjunction with the
492 +Specifies the key size to use for an encryption algorithm. Used in conjunction
494 +.BR loop " and " encryption " options."
498 @@ -1696,7 +1711,10 @@
499 .BR loop ", " offset " and " encryption ,
500 that are really options to
502 -If no explicit loop device is mentioned
503 +If the mount requires a passphrase, you will be prompted for one unless
504 +you specify a file descriptor to read from instead with the
506 +option. If no explicit loop device is mentioned
507 (but just an option `\fB\-o loop\fP' is given), then
509 will try to find some unused loop device and use that.
510 @@ -1767,7 +1785,7 @@
519 --- util-linux-2.12.orig/mount/mount.c
520 +++ util-linux-2.12/mount/mount.c
522 /* Nonzero for chatty (-v). */
525 +/* Do we hash the password or not */
526 +int hash_password = 1;
528 /* Nonzero for sloppy (-s). */
532 /* Contains the fd to read the passphrase from, if any. */
535 +/* Contains the preferred keysize in bits we want to use */
536 +static int keysz = 0;
538 /* Map from -o and fstab option strings to the flag argument to mount(2). */
540 const char *opt; /* option name */
544 static char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption,
546 + *opt_keybits, *opt_nohashpass, *opt_speed;
548 static struct string_opt_map {
551 { "vfs=", 1, &opt_vfstype },
552 { "offset=", 0, &opt_offset },
553 { "encryption=", 0, &opt_encryption },
554 + { "keybits=", 0, &opt_keybits },
555 + { "nohashpass", 0, &opt_nohashpass },
556 { "speed=", 0, &opt_speed },
563 - *loop = ((*flags & MS_LOOP) || *loopdev || opt_offset || opt_encryption);
564 + *loop = ((*flags & MS_LOOP) || *loopdev || opt_offset || opt_encryption ||
571 printf(_("mount: going to use the loop device %s\n"), *loopdev);
572 offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0;
573 - if (set_loop(*loopdev, *loopfile, offset,
574 - opt_encryption, pfd, &loopro)) {
575 + if (!keysz && opt_keybits)
576 + keysz = strtoul(opt_keybits, NULL, 0);
577 + if (opt_nohashpass)
579 + if (set_loop (*loopdev, *loopfile, offset, opt_encryption, pfd,
580 + keysz, &loopro, hash_password)) {
582 printf(_("mount: failed setting up loop device\n"));
584 @@ -1371,6 +1384,7 @@
585 { "options", 1, 0, 'o' },
586 { "test-opts", 1, 0, 'O' },
587 { "pass-fd", 1, 0, 'p' },
588 + { "keybits", 1, 0, 'k' },
589 { "types", 1, 0, 't' },
590 { "bind", 0, 0, 128 },
591 { "replace", 0, 0, 129 },
592 @@ -1424,6 +1438,8 @@
593 int c, result = 0, specseen;
594 char *options = NULL, *test_opts = NULL, *spec, *node;
595 char *volumelabel = NULL;
596 + char *passfd = NULL;
597 + char *keysize = NULL;
600 struct mntentchn *mc;
601 @@ -1447,7 +1463,7 @@
602 initproctitle(argc, argv);
605 - while ((c = getopt_long (argc, argv, "afFhilL:no:O:p:rsU:vVwt:",
606 + while ((c = getopt_long (argc, argv, "afFhilL:k:no:O:p:rsU:vVwt:",
607 longopts, NULL)) != -1) {
609 case 'a': /* mount everything in fstab */
610 @@ -1471,6 +1487,9 @@
612 volumelabel = optarg;
617 case 'n': /* do not write /etc/mtab */
620 @@ -1598,6 +1617,11 @@
622 spec = NULL; /* just for gcc */
624 + if (passfd && sscanf(passfd,"%d",&pfd) != 1)
625 + die (EX_USAGE, _("mount: argument to --pass-fd or -p must be a number"));
626 + if (keysize && sscanf(keysize,"%d",&keysz) != 1)
627 + die (EX_USAGE, _("mount: argument to --keybits or -k must be a number"));
629 switch (argc+specseen) {
632 --- util-linux-2.12.orig/mount/rmd160.c
633 +++ util-linux-2.12/mount/rmd160.c
635 +/* rmd160.c - RIPE-MD160
636 + * Copyright (C) 1998 Free Software Foundation, Inc.
639 +/* This file was part of GnuPG. Modified for use within the Linux
640 + * mount utility by Marc Mutz <Marc@Mutz.com>. None of this code is
641 + * by myself. I just removed everything that you don't need when all
642 + * you want to do is to use rmd160_hash_buffer().
643 + * My comments are marked with (mm). */
645 +/* GnuPG is free software; you can redistribute it and/or modify
646 + * it under the terms of the GNU General Public License as published by
647 + * the Free Software Foundation; either version 2 of the License, or
648 + * (at your option) any later version.
650 + * GnuPG is distributed in the hope that it will be useful,
651 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
652 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
653 + * GNU General Public License for more details.
655 + * You should have received a copy of the GNU General Public License
656 + * along with this program; if not, write to the Free Software
657 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */
659 +#include <string.h> /* (mm) for memcpy */
660 +#include <endian.h> /* (mm) for BIG_ENDIAN and BYTE_ORDER */
663 +/* (mm) these are used by the original GnuPG file. In order to modify
664 + * that file not too much, we keep the notations. maybe it would be
665 + * better to include linux/types.h and typedef __u32 to u32 and __u8
667 +typedef unsigned int u32; /* taken from e.g. util-linux's minix.h */
668 +typedef unsigned char byte;
671 + u32 h0,h1,h2,h3,h4;
678 + * Rotate a 32 bit integer by n bytes
680 +#if defined(__GNUC__) && defined(__i386__)
684 + __asm__("roll %%cl,%0"
690 + #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
693 +/*********************************
694 + * RIPEMD-160 is not patented, see (as of 25.10.97)
695 + * http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
696 + * Note that the code uses Little Endian byteorder, which is good for
697 + * 386 etc, but we must add some conversion when used on a big endian box.
700 + * Pseudo-code for RIPEMD-160
702 + * RIPEMD-160 is an iterative hash function that operates on 32-bit words.
703 + * The round function takes as input a 5-word chaining variable and a 16-word
704 + * message block and maps this to a new chaining variable. All operations are
705 + * defined on 32-bit words. Padding is identical to that of MD4.
708 + * RIPEMD-160: definitions
711 + * nonlinear functions at bit level: exor, mux, -, mux, -
713 + * f(j, x, y, z) = x XOR y XOR z (0 <= j <= 15)
714 + * f(j, x, y, z) = (x AND y) OR (NOT(x) AND z) (16 <= j <= 31)
715 + * f(j, x, y, z) = (x OR NOT(y)) XOR z (32 <= j <= 47)
716 + * f(j, x, y, z) = (x AND z) OR (y AND NOT(z)) (48 <= j <= 63)
717 + * f(j, x, y, z) = x XOR (y OR NOT(z)) (64 <= j <= 79)
720 + * added constants (hexadecimal)
722 + * K(j) = 0x00000000 (0 <= j <= 15)
723 + * K(j) = 0x5A827999 (16 <= j <= 31) int(2**30 x sqrt(2))
724 + * K(j) = 0x6ED9EBA1 (32 <= j <= 47) int(2**30 x sqrt(3))
725 + * K(j) = 0x8F1BBCDC (48 <= j <= 63) int(2**30 x sqrt(5))
726 + * K(j) = 0xA953FD4E (64 <= j <= 79) int(2**30 x sqrt(7))
727 + * K'(j) = 0x50A28BE6 (0 <= j <= 15) int(2**30 x cbrt(2))
728 + * K'(j) = 0x5C4DD124 (16 <= j <= 31) int(2**30 x cbrt(3))
729 + * K'(j) = 0x6D703EF3 (32 <= j <= 47) int(2**30 x cbrt(5))
730 + * K'(j) = 0x7A6D76E9 (48 <= j <= 63) int(2**30 x cbrt(7))
731 + * K'(j) = 0x00000000 (64 <= j <= 79)
734 + * selection of message word
736 + * r(j) = j (0 <= j <= 15)
737 + * r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
738 + * r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
739 + * r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
740 + * r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
741 + * r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
742 + * r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
743 + * r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
744 + * r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
745 + * r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
748 + * amount for rotate left (rol)
750 + * s(0..15) = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
751 + * s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
752 + * s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
753 + * s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
754 + * s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
755 + * s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
756 + * s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
757 + * s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
758 + * s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
759 + * s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
762 + * initial value (hexadecimal)
764 + * h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476;
768 + * RIPEMD-160: pseudo-code
770 + * It is assumed that the message after padding consists of t 16-word blocks
771 + * that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15.
772 + * The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left
773 + * shift (rotate) over s positions.
776 + * for i := 0 to t-1 {
777 + * A := h0; B := h1; C := h2; D = h3; E = h4;
778 + * A' := h0; B' := h1; C' := h2; D' = h3; E' = h4;
779 + * for j := 0 to 79 {
780 + * T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E;
781 + * A := E; E := D; D := rol_10(C); C := B; B := T;
782 + * T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)]
784 + * A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T;
786 + * T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A';
787 + * h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T;
792 + * "" 9c1185a5c5e9fc54612808977ee8f548b2258d31
793 + * "a" 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe
794 + * "abc" 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
795 + * "message digest" 5d0689ef49d2fae572b881b123a85ffa21595f36
796 + * "a...z" f71c27109c692c1b56bbdceb5b9d2865b3708dbc
797 + * "abcdbcde...nopq" 12a053384a9c0c88e405a06c27dcf49ada62eb2b
798 + * "A...Za...z0...9" b0e20b6e3116640286ed3a87a5713079b21f5189
799 + * 8 times "1234567890" 9b752e45573d4b39f4dbd3323cab82bf63326bfb
800 + * 1 million times "a" 52783243c1697bdbe16d37f97f68f08325dc1528
805 +rmd160_init( RMD160_CONTEXT *hd )
807 + hd->h0 = 0x67452301;
808 + hd->h1 = 0xEFCDAB89;
809 + hd->h2 = 0x98BADCFE;
810 + hd->h3 = 0x10325476;
811 + hd->h4 = 0xC3D2E1F0;
819 + * Transform the message X which consists of 16 32-bit-words
822 +transform( RMD160_CONTEXT *hd, byte *data )
824 + u32 a,b,c,d,e,aa,bb,cc,dd,ee,t;
825 + #if BYTE_ORDER == BIG_ENDIAN
829 + for(i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 ) {
838 + u32 *x =(u32*)data;
840 + /* this version is better because it is always aligned;
841 + * The performance penalty on a 586-100 is about 6% which
842 + * is acceptable - because the data is more local it might
843 + * also be possible that this is faster on some machines.
844 + * This function (when compiled with -02 on gcc 2.7.2)
845 + * executes on a 586-100 (39.73 bogomips) at about 1900kb/sec;
846 + * [measured with a 4MB data and "gpgm --print-md rmd160"] */
848 + memcpy( x, data, 64 );
853 +#define K0 0x00000000
854 +#define K1 0x5A827999
855 +#define K2 0x6ED9EBA1
856 +#define K3 0x8F1BBCDC
857 +#define K4 0xA953FD4E
858 +#define KK0 0x50A28BE6
859 +#define KK1 0x5C4DD124
860 +#define KK2 0x6D703EF3
861 +#define KK3 0x7A6D76E9
862 +#define KK4 0x00000000
863 +#define F0(x,y,z) ( (x) ^ (y) ^ (z) )
864 +#define F1(x,y,z) ( ((x) & (y)) | (~(x) & (z)) )
865 +#define F2(x,y,z) ( ((x) | ~(y)) ^ (z) )
866 +#define F3(x,y,z) ( ((x) & (z)) | ((y) & ~(z)) )
867 +#define F4(x,y,z) ( (x) ^ ((y) | ~(z)) )
868 +#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \
869 + a = rol(t,s) + e; \
879 + R( a, b, c, d, e, F0, K0, 0, 11 );
880 + R( e, a, b, c, d, F0, K0, 1, 14 );
881 + R( d, e, a, b, c, F0, K0, 2, 15 );
882 + R( c, d, e, a, b, F0, K0, 3, 12 );
883 + R( b, c, d, e, a, F0, K0, 4, 5 );
884 + R( a, b, c, d, e, F0, K0, 5, 8 );
885 + R( e, a, b, c, d, F0, K0, 6, 7 );
886 + R( d, e, a, b, c, F0, K0, 7, 9 );
887 + R( c, d, e, a, b, F0, K0, 8, 11 );
888 + R( b, c, d, e, a, F0, K0, 9, 13 );
889 + R( a, b, c, d, e, F0, K0, 10, 14 );
890 + R( e, a, b, c, d, F0, K0, 11, 15 );
891 + R( d, e, a, b, c, F0, K0, 12, 6 );
892 + R( c, d, e, a, b, F0, K0, 13, 7 );
893 + R( b, c, d, e, a, F0, K0, 14, 9 );
894 + R( a, b, c, d, e, F0, K0, 15, 8 );
895 + R( e, a, b, c, d, F1, K1, 7, 7 );
896 + R( d, e, a, b, c, F1, K1, 4, 6 );
897 + R( c, d, e, a, b, F1, K1, 13, 8 );
898 + R( b, c, d, e, a, F1, K1, 1, 13 );
899 + R( a, b, c, d, e, F1, K1, 10, 11 );
900 + R( e, a, b, c, d, F1, K1, 6, 9 );
901 + R( d, e, a, b, c, F1, K1, 15, 7 );
902 + R( c, d, e, a, b, F1, K1, 3, 15 );
903 + R( b, c, d, e, a, F1, K1, 12, 7 );
904 + R( a, b, c, d, e, F1, K1, 0, 12 );
905 + R( e, a, b, c, d, F1, K1, 9, 15 );
906 + R( d, e, a, b, c, F1, K1, 5, 9 );
907 + R( c, d, e, a, b, F1, K1, 2, 11 );
908 + R( b, c, d, e, a, F1, K1, 14, 7 );
909 + R( a, b, c, d, e, F1, K1, 11, 13 );
910 + R( e, a, b, c, d, F1, K1, 8, 12 );
911 + R( d, e, a, b, c, F2, K2, 3, 11 );
912 + R( c, d, e, a, b, F2, K2, 10, 13 );
913 + R( b, c, d, e, a, F2, K2, 14, 6 );
914 + R( a, b, c, d, e, F2, K2, 4, 7 );
915 + R( e, a, b, c, d, F2, K2, 9, 14 );
916 + R( d, e, a, b, c, F2, K2, 15, 9 );
917 + R( c, d, e, a, b, F2, K2, 8, 13 );
918 + R( b, c, d, e, a, F2, K2, 1, 15 );
919 + R( a, b, c, d, e, F2, K2, 2, 14 );
920 + R( e, a, b, c, d, F2, K2, 7, 8 );
921 + R( d, e, a, b, c, F2, K2, 0, 13 );
922 + R( c, d, e, a, b, F2, K2, 6, 6 );
923 + R( b, c, d, e, a, F2, K2, 13, 5 );
924 + R( a, b, c, d, e, F2, K2, 11, 12 );
925 + R( e, a, b, c, d, F2, K2, 5, 7 );
926 + R( d, e, a, b, c, F2, K2, 12, 5 );
927 + R( c, d, e, a, b, F3, K3, 1, 11 );
928 + R( b, c, d, e, a, F3, K3, 9, 12 );
929 + R( a, b, c, d, e, F3, K3, 11, 14 );
930 + R( e, a, b, c, d, F3, K3, 10, 15 );
931 + R( d, e, a, b, c, F3, K3, 0, 14 );
932 + R( c, d, e, a, b, F3, K3, 8, 15 );
933 + R( b, c, d, e, a, F3, K3, 12, 9 );
934 + R( a, b, c, d, e, F3, K3, 4, 8 );
935 + R( e, a, b, c, d, F3, K3, 13, 9 );
936 + R( d, e, a, b, c, F3, K3, 3, 14 );
937 + R( c, d, e, a, b, F3, K3, 7, 5 );
938 + R( b, c, d, e, a, F3, K3, 15, 6 );
939 + R( a, b, c, d, e, F3, K3, 14, 8 );
940 + R( e, a, b, c, d, F3, K3, 5, 6 );
941 + R( d, e, a, b, c, F3, K3, 6, 5 );
942 + R( c, d, e, a, b, F3, K3, 2, 12 );
943 + R( b, c, d, e, a, F4, K4, 4, 9 );
944 + R( a, b, c, d, e, F4, K4, 0, 15 );
945 + R( e, a, b, c, d, F4, K4, 5, 5 );
946 + R( d, e, a, b, c, F4, K4, 9, 11 );
947 + R( c, d, e, a, b, F4, K4, 7, 6 );
948 + R( b, c, d, e, a, F4, K4, 12, 8 );
949 + R( a, b, c, d, e, F4, K4, 2, 13 );
950 + R( e, a, b, c, d, F4, K4, 10, 12 );
951 + R( d, e, a, b, c, F4, K4, 14, 5 );
952 + R( c, d, e, a, b, F4, K4, 1, 12 );
953 + R( b, c, d, e, a, F4, K4, 3, 13 );
954 + R( a, b, c, d, e, F4, K4, 8, 14 );
955 + R( e, a, b, c, d, F4, K4, 11, 11 );
956 + R( d, e, a, b, c, F4, K4, 6, 8 );
957 + R( c, d, e, a, b, F4, K4, 15, 5 );
958 + R( b, c, d, e, a, F4, K4, 13, 6 );
960 + aa = a; bb = b; cc = c; dd = d; ee = e;
968 + R( a, b, c, d, e, F4, KK0, 5, 8);
969 + R( e, a, b, c, d, F4, KK0, 14, 9);
970 + R( d, e, a, b, c, F4, KK0, 7, 9);
971 + R( c, d, e, a, b, F4, KK0, 0, 11);
972 + R( b, c, d, e, a, F4, KK0, 9, 13);
973 + R( a, b, c, d, e, F4, KK0, 2, 15);
974 + R( e, a, b, c, d, F4, KK0, 11, 15);
975 + R( d, e, a, b, c, F4, KK0, 4, 5);
976 + R( c, d, e, a, b, F4, KK0, 13, 7);
977 + R( b, c, d, e, a, F4, KK0, 6, 7);
978 + R( a, b, c, d, e, F4, KK0, 15, 8);
979 + R( e, a, b, c, d, F4, KK0, 8, 11);
980 + R( d, e, a, b, c, F4, KK0, 1, 14);
981 + R( c, d, e, a, b, F4, KK0, 10, 14);
982 + R( b, c, d, e, a, F4, KK0, 3, 12);
983 + R( a, b, c, d, e, F4, KK0, 12, 6);
984 + R( e, a, b, c, d, F3, KK1, 6, 9);
985 + R( d, e, a, b, c, F3, KK1, 11, 13);
986 + R( c, d, e, a, b, F3, KK1, 3, 15);
987 + R( b, c, d, e, a, F3, KK1, 7, 7);
988 + R( a, b, c, d, e, F3, KK1, 0, 12);
989 + R( e, a, b, c, d, F3, KK1, 13, 8);
990 + R( d, e, a, b, c, F3, KK1, 5, 9);
991 + R( c, d, e, a, b, F3, KK1, 10, 11);
992 + R( b, c, d, e, a, F3, KK1, 14, 7);
993 + R( a, b, c, d, e, F3, KK1, 15, 7);
994 + R( e, a, b, c, d, F3, KK1, 8, 12);
995 + R( d, e, a, b, c, F3, KK1, 12, 7);
996 + R( c, d, e, a, b, F3, KK1, 4, 6);
997 + R( b, c, d, e, a, F3, KK1, 9, 15);
998 + R( a, b, c, d, e, F3, KK1, 1, 13);
999 + R( e, a, b, c, d, F3, KK1, 2, 11);
1000 + R( d, e, a, b, c, F2, KK2, 15, 9);
1001 + R( c, d, e, a, b, F2, KK2, 5, 7);
1002 + R( b, c, d, e, a, F2, KK2, 1, 15);
1003 + R( a, b, c, d, e, F2, KK2, 3, 11);
1004 + R( e, a, b, c, d, F2, KK2, 7, 8);
1005 + R( d, e, a, b, c, F2, KK2, 14, 6);
1006 + R( c, d, e, a, b, F2, KK2, 6, 6);
1007 + R( b, c, d, e, a, F2, KK2, 9, 14);
1008 + R( a, b, c, d, e, F2, KK2, 11, 12);
1009 + R( e, a, b, c, d, F2, KK2, 8, 13);
1010 + R( d, e, a, b, c, F2, KK2, 12, 5);
1011 + R( c, d, e, a, b, F2, KK2, 2, 14);
1012 + R( b, c, d, e, a, F2, KK2, 10, 13);
1013 + R( a, b, c, d, e, F2, KK2, 0, 13);
1014 + R( e, a, b, c, d, F2, KK2, 4, 7);
1015 + R( d, e, a, b, c, F2, KK2, 13, 5);
1016 + R( c, d, e, a, b, F1, KK3, 8, 15);
1017 + R( b, c, d, e, a, F1, KK3, 6, 5);
1018 + R( a, b, c, d, e, F1, KK3, 4, 8);
1019 + R( e, a, b, c, d, F1, KK3, 1, 11);
1020 + R( d, e, a, b, c, F1, KK3, 3, 14);
1021 + R( c, d, e, a, b, F1, KK3, 11, 14);
1022 + R( b, c, d, e, a, F1, KK3, 15, 6);
1023 + R( a, b, c, d, e, F1, KK3, 0, 14);
1024 + R( e, a, b, c, d, F1, KK3, 5, 6);
1025 + R( d, e, a, b, c, F1, KK3, 12, 9);
1026 + R( c, d, e, a, b, F1, KK3, 2, 12);
1027 + R( b, c, d, e, a, F1, KK3, 13, 9);
1028 + R( a, b, c, d, e, F1, KK3, 9, 12);
1029 + R( e, a, b, c, d, F1, KK3, 7, 5);
1030 + R( d, e, a, b, c, F1, KK3, 10, 15);
1031 + R( c, d, e, a, b, F1, KK3, 14, 8);
1032 + R( b, c, d, e, a, F0, KK4, 12, 8);
1033 + R( a, b, c, d, e, F0, KK4, 15, 5);
1034 + R( e, a, b, c, d, F0, KK4, 10, 12);
1035 + R( d, e, a, b, c, F0, KK4, 4, 9);
1036 + R( c, d, e, a, b, F0, KK4, 1, 12);
1037 + R( b, c, d, e, a, F0, KK4, 5, 5);
1038 + R( a, b, c, d, e, F0, KK4, 8, 14);
1039 + R( e, a, b, c, d, F0, KK4, 7, 6);
1040 + R( d, e, a, b, c, F0, KK4, 6, 8);
1041 + R( c, d, e, a, b, F0, KK4, 2, 13);
1042 + R( b, c, d, e, a, F0, KK4, 13, 6);
1043 + R( a, b, c, d, e, F0, KK4, 14, 5);
1044 + R( e, a, b, c, d, F0, KK4, 0, 15);
1045 + R( d, e, a, b, c, F0, KK4, 3, 13);
1046 + R( c, d, e, a, b, F0, KK4, 9, 11);
1047 + R( b, c, d, e, a, F0, KK4, 11, 11);
1050 + t = hd->h1 + d + cc;
1051 + hd->h1 = hd->h2 + e + dd;
1052 + hd->h2 = hd->h3 + a + ee;
1053 + hd->h3 = hd->h4 + b + aa;
1054 + hd->h4 = hd->h0 + c + bb;
1059 +/* Update the message digest with the contents
1060 + * of INBUF with length INLEN.
1063 +rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen)
1065 + if( hd->count == 64 ) { /* flush the buffer */
1066 + transform( hd, hd->buf );
1073 + for( ; inlen && hd->count < 64; inlen-- )
1074 + hd->buf[hd->count++] = *inbuf++;
1075 + rmd160_write( hd, NULL, 0 );
1080 + while( inlen >= 64 ) {
1081 + transform( hd, inbuf );
1087 + for( ; inlen && hd->count < 64; inlen-- )
1088 + hd->buf[hd->count++] = *inbuf++;
1091 +/* The routine terminates the computation
1095 +rmd160_final( RMD160_CONTEXT *hd )
1100 + rmd160_write(hd, NULL, 0); /* flush */;
1104 + if( (lsb = t << 6) < t ) /* multiply by 64 to make a byte count */
1108 + if( (lsb = t + hd->count) < t ) /* add the count */
1111 + if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
1115 + if( hd->count < 56 ) { /* enough room */
1116 + hd->buf[hd->count++] = 0x80; /* pad */
1117 + while( hd->count < 56 )
1118 + hd->buf[hd->count++] = 0; /* pad */
1120 + else { /* need one extra block */
1121 + hd->buf[hd->count++] = 0x80; /* pad character */
1122 + while( hd->count < 64 )
1123 + hd->buf[hd->count++] = 0;
1124 + rmd160_write(hd, NULL, 0); /* flush */;
1125 + memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
1127 + /* append the 64 bit count */
1128 + hd->buf[56] = lsb ;
1129 + hd->buf[57] = lsb >> 8;
1130 + hd->buf[58] = lsb >> 16;
1131 + hd->buf[59] = lsb >> 24;
1132 + hd->buf[60] = msb ;
1133 + hd->buf[61] = msb >> 8;
1134 + hd->buf[62] = msb >> 16;
1135 + hd->buf[63] = msb >> 24;
1136 + transform( hd, hd->buf );
1139 + #if BYTE_ORDER == BIG_ENDIAN
1140 + #define X(a) do { *p++ = hd->h##a ; *p++ = hd->h##a >> 8; \
1141 + *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
1142 + #else /* little endian */
1143 + #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
1154 + * Shortcut functions which puts the hash value of the supplied buffer
1155 + * into outbuf which must have a size of 20 bytes.
1158 +rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length )
1160 + RMD160_CONTEXT hd;
1162 + rmd160_init( &hd );
1163 + rmd160_write( &hd, (byte*)buffer, length );
1164 + rmd160_final( &hd );
1165 + memcpy( outbuf, hd.buf, 20 );
1167 --- util-linux-2.12.orig/mount/rmd160.h
1168 +++ util-linux-2.12/mount/rmd160.h
1174 +rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length );
1176 +#endif /*RMD160_H*/