]> git.pld-linux.org Git - packages/util-linux.git/blob - util-linux-crypto-debian.patch
- s,/lib/security,,
[packages/util-linux.git] / util-linux-crypto-debian.patch
1 --- util-linux-2.12.orig/mount/Makefile
2 +++ util-linux-2.12/mount/Makefile
3 @@ -24,7 +26,7 @@
4  
5  MAYBE = pivot_root swapoff
6  
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
11  
12 @@ -57,7 +59,7 @@
13  main_losetup.o: lomount.c
14         $(COMPILE) -DMAIN lomount.c -o $@
15  
16 -losetup: main_losetup.o $(LIB)/xstrncpy.o
17 +losetup: main_losetup.o $(LIB)/xstrncpy.o rmd160.o
18         $(LINK) $^ -o $@
19  
20  mount.o umount.o nfsmount.o losetup.o fstab.o realpath.o sundries.o: sundries.h
21 --- util-linux-2.12.orig/mount/lomount.c
22 +++ util-linux-2.12/mount/lomount.c
23 @@ -33,15 +33,80 @@
24  
25  #include "loop.h"
26  #include "lomount.h"
27 +#include "rmd160.h"
28  #include "xstrncpy.h"
29  #include "nls.h"
30  
31  extern int verbose;
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 */
35  
36  #ifdef LOOP_SET_FD
37  
38 +#include <getopt.h>
39 +#include <stdarg.h>
40 +
41 +struct crypt_type_struct {
42 +       int id;
43 +       char *name;
44 +       int keylength;
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 },
59 +       { -1, NULL,0   }
60 +};
61 +
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' },
72 +       { NULL, 0, 0, 0 }
73 +};
74 +
75 +static int 
76 +name_to_id(const char *name) 
77 +{
78 +       int i;
79 +
80 +       if (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;
84 +       } else
85 +               return LO_CRYPT_NONE;
86 +       return LO_CRYPT_CRYPTOAPI;
87 +}
88 +
89 +#ifdef MAIN
90 +static char *
91 +id_to_name(int id) {
92 +       int i;
93 +
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;
97 +       return "undefined";
98 +}
99 +#endif
100 +
101 +
102  static int
103  loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info)
104  {
105 @@ -135,6 +200,10 @@
106         }
107  
108         errsv = errno;
109 +       printf (_("%s: [%04x]:%ld (%s) offset %d, %s encryption\n"),
110 +               device, loopinfo.lo_device, loopinfo.lo_inode,
111 +               loopinfo.lo_name, loopinfo.lo_offset,
112 +               id_to_name(loopinfo.lo_encrypt_type));
113         fprintf(stderr, _("loop: can't get info on device %s: %s\n"),
114                 device, strerror (errsv));
115         close (fd);
116 @@ -189,10 +258,9 @@
117                 error(_("mount: could not find any device /dev/loop#"));
118         else if (!someloop) {
119                 error(_(
120 -                   "mount: Could not find any loop device. Maybe this kernel "
121 -                   "does not know\n"
122 -                   "       about the loop device? (If so, recompile or "
123 -                   "`modprobe loop'.)"));
124 +                   "mount: Could not find any loop device. Maybe this kernel does not know\n"
125 +                   "       about the loop device? (If so, recompile or `modprobe loop'), or\n"
126 +                   "       maybe /dev/loop# has the wrong major number?"));
127         } else
128                 error(_("mount: could not find any free loop device"));
129         return 0;
130 @@ -247,10 +315,20 @@
131  
132  int
133  set_loop(const char *device, const char *file, int offset,
134 -        const char *encryption, int pfd, int *loopro) {
135 +        const char *encryption, int pfd, int keysz, int *loopro, int hash_password) {
136         struct loop_info64 loopinfo64;
137         int fd, ffd, mode;
138         char *pass;
139 +       int tried_old;
140 +
141 +       int kerneli=open("/proc/crypto/cipher",O_RDONLY);
142 +
143 +       if (kerneli>=0) {
144 +               close(kerneli);
145 +               kerneli=1;
146 +       } else {
147 +               kerneli=0;
148 +       }
149  
150         mode = (*loopro ? O_RDONLY : O_RDWR);
151         if ((ffd = open(file, mode)) < 0) {
152 @@ -276,8 +354,13 @@
153                         loopinfo64.lo_encrypt_type = atoi(encryption);
154                 } else {
155                         loopinfo64.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
156 -                       snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
157 +                       if (kerneli)
158 +                           snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
159 +                                "%s-cbc", encryption);
160 +                       else
161 +                           snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
162                                  "%s", encryption);
163 +                       loopinfo64.lo_crypt_name[LO_NAME_SIZE-1] = 0;
164                 }
165         }
166  
167 @@ -296,29 +379,98 @@
168         }
169  #endif
170  
171 +       if (keysz==0)
172 +               keysz=LO_KEY_SIZE*8;
173 +       tried_old=0;
174 +again:
175         switch (loopinfo64.lo_encrypt_type) {
176         case LO_CRYPT_NONE:
177                 loopinfo64.lo_encrypt_key_size = 0;
178                 break;
179         case LO_CRYPT_XOR:
180                 pass = getpass(_("Password: "));
181 -               xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
182 +               xstrncpy(loopinfo64.lo_encrypt_key, pass, keysz/8);
183                 loopinfo64.lo_encrypt_key_size =
184                         strlen(loopinfo64.lo_encrypt_key);
185                 break;
186 -       default:
187 +       case LO_CRYPT_FISH2:
188 +       case LO_CRYPT_BLOW:
189 +       case LO_CRYPT_IDEA:
190 +       case LO_CRYPT_CAST128:
191 +       case LO_CRYPT_SERPENT:
192 +       case LO_CRYPT_MARS:
193 +       case LO_CRYPT_RC6:
194 +       case LO_CRYPT_3DES:
195 +       case LO_CRYPT_DFC:
196 +       case LO_CRYPT_RIJNDAEL:
197 +           {
198 +#define HASHLENGTH 20
199 +#define PASSWDBUFFLEN 130 /* getpass returns only max. 128 bytes, see man getpass */
200 +               char keybits[2*HASHLENGTH]; 
201 +               char passwdbuff[PASSWDBUFFLEN];
202 +               int keylength;
203 +               int i;
204 +
205                 pass = xgetpass(pfd, _("Password: "));
206 -               xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
207 -               loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;
208 +               strncpy(passwdbuff+1,pass,PASSWDBUFFLEN-1);
209 +               passwdbuff[PASSWDBUFFLEN-1] = '\0';
210 +               passwdbuff[0] = 'A';
211 +               rmd160_hash_buffer(keybits,pass,strlen(pass));
212 +               rmd160_hash_buffer(keybits+HASHLENGTH,passwdbuff,strlen(pass)+1);
213 +               memcpy((char*)loopinfo64.lo_encrypt_key,keybits,2*HASHLENGTH);
214 +               keylength=0;
215 +               for(i=0; crypt_type_tbl[i].id != -1; i++){
216 +                        if(loopinfo64.lo_encrypt_type == crypt_type_tbl[i].id){
217 +                                keylength = crypt_type_tbl[i].keylength;
218 +                                break;
219 +                        }
220 +               }
221 +               loopinfo64.lo_encrypt_key_size=keylength;
222 +               break;
223 +           }
224 +       default:
225 +               if (hash_password) {
226 +                   char keybits[2*HASHLENGTH]; 
227 +                   char passwdbuff[PASSWDBUFFLEN];
228 +
229 +                   pass = xgetpass(pfd, _("Password: "));
230 +                   strncpy(passwdbuff+1,pass,PASSWDBUFFLEN-1);
231 +                   passwdbuff[PASSWDBUFFLEN-1] = '\0';
232 +                   passwdbuff[0] = 'A';
233 +                   rmd160_hash_buffer(keybits,pass,strlen(pass));
234 +                   rmd160_hash_buffer(keybits+HASHLENGTH,passwdbuff,strlen(pass)+1);
235 +                   memcpy((char*)loopinfo64.lo_encrypt_key,keybits,keysz/8);
236 +               } else {
237 +                   pass = xgetpass(pfd, _("Password: "));
238 +                   xstrncpy(loopinfo64.lo_encrypt_key, pass, keysz/8);
239 +               }
240 +               loopinfo64.lo_encrypt_key_size = keysz/8;
241         }
242  
243         if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
244                 perror("ioctl: LOOP_SET_FD");
245                 return 1;
246         }
247 -       close (ffd);
248 -
249 -       if (ioctl(fd, LOOP_SET_STATUS64, &loopinfo64) < 0) {
250 +       if (kerneli) {
251 +           struct loop_info loopinfo;
252 +           loop_info64_to_old(&loopinfo64,&loopinfo);
253 +           if (ioctl (fd, LOOP_SET_STATUS, &loopinfo) < 0) {
254 +               /* Try again with old-style LO_CRYPT_XX if
255 +                  new-style LO_CRYPT_CRYPTOAPI ioctl didn't work */
256 +               if (tried_old) {
257 +                       error("The cipher does not exist, or a cipher module "
258 +                             "needs to be loaded into the kernel");
259 +                       perror ("ioctl: LOOP_SET_STATUS");
260 +                       goto fail;
261 +               }
262 +               strncpy (loopinfo64.lo_file_name, file, LO_NAME_SIZE);
263 +               loopinfo64.lo_file_name[LO_NAME_SIZE - 1] = 0;
264 +               loopinfo64.lo_encrypt_type = name_to_id (encryption);
265 +               tried_old = 1;
266 +               goto again;
267 +           }
268 +       } else {
269 +           if (ioctl(fd, LOOP_SET_STATUS64, &loopinfo64) < 0) {
270                 struct loop_info loopinfo;
271                 int errsv = errno;
272  
273 @@ -333,8 +485,10 @@
274                         perror("ioctl: LOOP_SET_STATUS");
275                         goto fail;
276                 }
277 +           }
278         }
279  
280 +       close (ffd);
281         close (fd);
282         if (verbose > 1)
283                 printf(_("set_loop(%s,%s,%d): success\n"),
284 @@ -343,6 +497,7 @@
285  
286   fail:
287         (void) ioctl (fd, LOOP_CLR_FD, 0);
288 +       close (ffd);
289         close (fd);
290         return 1;
291  }
292 @@ -411,8 +566,24 @@
293         fprintf(stderr, _("usage:\n\
294    %s loop_device                                      # give info\n\
295    %s -d loop_device                                   # delete\n\
296 -  %s [ -e encryption ] [ -o offset ] loop_device file # setup\n"),
297 -               progname, progname, progname);
298 +  %s [ options ] loop_device file                     # setup\n\
299 +    where options include\n\
300 +    --offset <num>, -o <num>\n\
301 +        start at offset <num> into file.\n\
302 +    --pass-fd <num>, -p <num>\n\
303 +        read passphrase from file descriptor <num>\n\
304 +        instead of the terminal.\n\
305 +    --encryption <cipher>, -e <cipher>\n\
306 +        encrypt with <cipher>.\n\
307 +        Check /proc/crypto or /proc/crypto/cipher for available ciphers.\n\
308 +    --nohashpass, -N\n\
309 +       Don't hash the password given.  (previous versions hash, non-debian doesn't.\n\
310 +    --keybits <num>, -k <num>\n\
311 +        specify number of bits in the hashed key given\n\
312 +        to the cipher.  Some ciphers support several key\n\
313 +        sizes and might be more efficient with a smaller\n\
314 +        key size.  Key sizes < 128 are generally not\n\
315 +        recommended\n"), progname, progname, progname);
316         exit(1);
317  }
318  
319 @@ -445,20 +616,23 @@
320  
321  int
322  main(int argc, char **argv) {
323 -       char *offset, *encryption, *passfd;
324 +       char *offset, *encryption, *passfd, *keysize;
325         int delete, off, c;
326         int res = 0;
327         int ro = 0;
328         int pfd = -1;
329 +       int keysz = 0;
330 +       int hash_password = 1;
331  
332         setlocale(LC_ALL, "");
333         bindtextdomain(PACKAGE, LOCALEDIR);
334         textdomain(PACKAGE);
335  
336         delete = off = 0;
337 -       offset = encryption = passfd = NULL;
338 +       offset = encryption = passfd = keysize = NULL;
339         progname = argv[0];
340 -       while ((c = getopt(argc,argv,"de:E:o:p:v")) != -1) {
341 +       while ((c = getopt_long(argc,argv,"de:E:hk:No:p:v",
342 +                               longopts, NULL)) != EOF) {
343                 switch (c) {
344                 case 'd':
345                         delete = 1;
346 @@ -467,6 +641,12 @@
347                 case 'e':
348                         encryption = optarg;
349                         break;
350 +               case 'N':
351 +                       hash_password=0;
352 +                       break;
353 +               case 'k':
354 +                       keysize = optarg;
355 +                       break;
356                 case 'o':
357                         offset = optarg;
358                         break;
359 @@ -494,8 +674,10 @@
360                         usage();
361                 if (passfd && sscanf(passfd,"%d",&pfd) != 1)
362                         usage();
363 +               if (keysize && sscanf(keysize,"%d",&keysz) != 1)
364 +                       usage();
365                 res = set_loop(argv[optind], argv[optind+1], off,
366 -                              encryption, pfd, &ro);
367 +                              encryption, pfd, keysz, &ro, hash_password);
368         }
369         return res;
370  }
371 --- util-linux-2.12.orig/mount/lomount.h
372 +++ util-linux-2.12/mount/lomount.h
373 @@ -1,6 +1,6 @@
374  extern int verbose;
375  extern int set_loop(const char *, const char *, int, const char *,
376 -                   int, int *);
377 +                   int, int, int *, int);
378  extern int del_loop(const char *);
379  extern int is_loop_device(const char *);
380  extern char * find_unused_loop_device(void);
381 --- util-linux-2.12.orig/mount/loop.h
382 +++ util-linux-2.12/mount/loop.h
383 @@ -1,8 +1,39 @@
384 -#define LO_CRYPT_NONE  0
385 -#define LO_CRYPT_XOR   1
386 -#define LO_CRYPT_DES   2
387 +#define LO_CRYPT_NONE  0
388 +#define LO_CRYPT_XOR   1
389 +#define LO_CRYPT_DES   2
390  #define LO_CRYPT_CRYPTOAPI 18
391  
392 +#ifndef LO_CRYPT_FISH2
393 +#define LO_CRYPT_FISH2 3
394 +#endif
395 +#ifndef LO_CRYPT_BLOW
396 +#define LO_CRYPT_BLOW 4
397 +#endif
398 +#ifndef LO_CRYPT_CAST128
399 +#define LO_CRYPT_CAST128 5
400 +#endif
401 +#ifndef LO_CRYPT_IDEA
402 +#define LO_CRYPT_IDEA 6
403 +#endif
404 +#ifndef LO_CRYPT_SERPENT
405 +#define LO_CRYPT_SERPENT 7
406 +#endif
407 +#ifndef LO_CRYPT_MARS
408 +#define LO_CRYPT_MARS 8
409 +#endif
410 +#ifndef LO_CRYPT_RC6
411 +#define LO_CRYPT_RC6 11
412 +#endif
413 +#ifndef LO_CRYPT_3DES
414 +#define LO_CRYPT_3DES 12
415 +#endif
416 +#ifndef LO_CRYPT_DFC
417 +#define LO_CRYPT_DFC 15
418 +#endif
419 +#ifndef LO_CRYPT_RIJNDAEL
420 +#define LO_CRYPT_RIJNDAEL 16
421 +#endif
422 +
423  #define LOOP_SET_FD            0x4C00
424  #define LOOP_CLR_FD            0x4C01
425  #define LOOP_SET_STATUS                0x4C02
426 --- util-linux-2.12.orig/mount/losetup.8
427 +++ util-linux-2.12/mount/losetup.8
428 @@ -50,19 +50,24 @@
429  .B \-e
430  option.)
431  .SH OPTIONS
432 -.IP \fB\-d\fP
433 -Detach the file or device associated with the specified loop device.
434 +.IP "\fB\-\-delete, \-\-detach, \-d\fP"
435 +detach the file or device associated with the specified loop device.
436  .IP "\fB\-E \fIencryption_type\fP"
437  Enable data encryption with specified number.
438 -.IP "\fB\-e \fIencryption_name\fP"
439 +.IP "\fB\-\-encryption, \-e \fIencryption\fP"
440  Enable data encryption with specified name.
441 -.IP "\fB\-o \fIoffset\fP"
442 +.IP "\fB\-\-nohashpass, \-N\fP"
443 +Do not hash the password.  Many previous Debian releases run the password through a
444 +hash function, non-Debian systems appear to.
445 +.IP "\fB\-\-offset, \-o \fIoffset\fP"
446  The data start is moved \fIoffset\fP bytes into the specified file or
447  device.
448 -.IP "\fB\-p \fInum\fP"
449 +.IP "\fB\-\-pass-fd, \-p \fInum\fP"
450  Read the passphrase from file descriptor with number
451  .I num
452  instead of from the terminal.
453 +.IP "\fB\-\-keybits, \-k \fInum\fP"
454 +set the number of bits to use in key to \fInum\fP.
455  .SH RETURN VALUE
456  .B losetup
457  returns 0 on success, nonzero on failure. When
458 @@ -109,6 +114,9 @@
459  .fi
460  .SH RESTRICTION
461  DES encryption is painfully slow. On the other hand, XOR is terribly weak.
462 +Both are insecure nowadays. Some ciphers may require a licence for you to be
463 +allowed to use them.
464 +.fi
465  .\" .SH AUTHORS
466  .\" .nf
467  .\" Original version: Theodore Ts'o <tytso@athena.mit.edu>
468 --- util-linux-2.12.orig/mount/mount.8
469 +++ util-linux-2.12/mount/mount.8
470 @@ -270,6 +270,12 @@
471  .B \-v
472  Verbose mode.
473  .TP
474 +.B \-p "\fInum\fP"
475 +If the mount requires a passphrase to be entered, read it from file
476 +descriptor
477 +.IR num\fP
478 +instead of from the terminal.
479 +.TP
480  .B \-a
481  Mount all filesystems (of the given types) mentioned in
482  .IR fstab .
483 @@ -633,6 +639,15 @@
484  .BR noexec ", " nosuid ", and " nodev
485  (unless overridden by subsequent options, as in the option line
486  .BR users,exec,dev,suid ).
487 +.TP
488 +.B encryption
489 +Specifies an encryption algorithm to use.  Used in conjunction with the
490 +.BR loop " option."
491 +.TP
492 +.B keybits
493 +Specifies the key size to use for an encryption algorithm. Used in conjunction
494 +with the
495 +.BR loop " and " encryption " options."
496  .RE
497  .TP
498  .B \-\-bind
499 @@ -1696,7 +1711,10 @@
500  .BR loop ", " offset " and " encryption ,
501  that are really options to
502  .BR losetup (8).
503 -If no explicit loop device is mentioned
504 +If the mount requires a passphrase, you will be prompted for one unless
505 +you specify a file descriptor to read from instead with the 
506 +.BR \-\-pass-fd
507 +option. If no explicit loop device is mentioned
508  (but just an option `\fB\-o loop\fP' is given), then
509  .B mount
510  will try to find some unused loop device and use that.
511 @@ -1767,7 +1785,7 @@
512  .BR e2label (8),
513  .BR xfs_admin (8),
514  .BR mountd (8),
515 -.BR nfsd (8),
516 +.BR rpc.nfsd (8),
517  .BR mke2fs (8),
518  .BR tune2fs (8),
519  .BR losetup (8)
520 --- util-linux-2.12.orig/mount/mount.c
521 +++ util-linux-2.12/mount/mount.c
522 @@ -92,6 +92,9 @@
523  /* Nonzero for chatty (-v).  */
524  int verbose = 0;
525  
526 +/* Do we hash the password or not */
527 +int hash_password = 1;
528 +
529  /* Nonzero for sloppy (-s).  */
530  int sloppy = 0;
531  
532 @@ -116,6 +119,9 @@
533  /* Contains the fd to read the passphrase from, if any. */
534  static int pfd = -1;
535  
536 +/* Contains the preferred keysize in bits we want to use */
537 +static int keysz = 0;
538 +
539  /* Map from -o and fstab option strings to the flag argument to mount(2).  */
540  struct opt_map {
541    const char *opt;             /* option name */
542 @@ -195,7 +201,7 @@
543  };
544  
545  static char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption,
546 -  *opt_speed;
547 +  *opt_keybits, *opt_nohashpass, *opt_speed;
548  
549  static struct string_opt_map {
550    char *tag;
551 @@ -206,6 +212,8 @@
552    { "vfs=",    1, &opt_vfstype },
553    { "offset=", 0, &opt_offset },
554    { "encryption=", 0, &opt_encryption },
555 +  { "keybits=", 0, &opt_keybits },
556 +  { "nohashpass", 0, &opt_nohashpass },
557    { "speed=", 0, &opt_speed },
558    { NULL, 0, NULL }
559  };
560 @@ -586,7 +594,8 @@
561        *type = opt_vfstype;
562    }
563  
564 -  *loop = ((*flags & MS_LOOP) || *loopdev || opt_offset || opt_encryption);
565 +  *loop = ((*flags & MS_LOOP) || *loopdev || opt_offset || opt_encryption ||
566 +          opt_keybits);
567    *loopfile = *spec;
568  
569    if (*loop) {
570 @@ -604,8 +613,12 @@
571        if (verbose)
572         printf(_("mount: going to use the loop device %s\n"), *loopdev);
573        offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0;
574 -      if (set_loop(*loopdev, *loopfile, offset,
575 -                  opt_encryption, pfd, &loopro)) {
576 +      if (!keysz && opt_keybits)
577 +       keysz  = strtoul(opt_keybits, NULL, 0);
578 +      if (opt_nohashpass)
579 +       hash_password=0;
580 +      if (set_loop (*loopdev, *loopfile, offset, opt_encryption, pfd, 
581 +                   keysz, &loopro, hash_password)) {
582         if (verbose)
583           printf(_("mount: failed setting up loop device\n"));
584         return EX_FAIL;
585 @@ -1371,6 +1384,7 @@
586         { "options", 1, 0, 'o' },
587         { "test-opts", 1, 0, 'O' },
588         { "pass-fd", 1, 0, 'p' },
589 +       { "keybits", 1, 0, 'k' },
590         { "types", 1, 0, 't' },
591         { "bind", 0, 0, 128 },
592         { "replace", 0, 0, 129 },
593 @@ -1424,6 +1438,8 @@
594         int c, result = 0, specseen;
595         char *options = NULL, *test_opts = NULL, *spec, *node;
596         char *volumelabel = NULL;
597 +       char *passfd = NULL;
598 +       char *keysize = NULL;
599         char *uuid = NULL;
600         char *types = NULL;
601         struct mntentchn *mc;
602 @@ -1447,7 +1463,7 @@
603         initproctitle(argc, argv);
604  #endif
605  
606 -       while ((c = getopt_long (argc, argv, "afFhilL:no:O:p:rsU:vVwt:",
607 +       while ((c = getopt_long (argc, argv, "afFhilL:k:no:O:p:rsU:vVwt:",
608                                  longopts, NULL)) != -1) {
609                 switch (c) {
610                 case 'a':              /* mount everything in fstab */
611 @@ -1471,6 +1487,9 @@
612                 case 'L':
613                         volumelabel = optarg;
614                         break;
615 +               case 'k':
616 +                       keysize = optarg;
617 +                       break;
618                 case 'n':               /* do not write /etc/mtab */
619                         ++nomtab;
620                         break;
621 @@ -1598,6 +1617,11 @@
622         } else
623                 spec = NULL;            /* just for gcc */
624  
625 +       if (passfd && sscanf(passfd,"%d",&pfd) != 1)
626 +               die (EX_USAGE, _("mount: argument to --pass-fd or -p must be a number"));
627 +       if (keysize && sscanf(keysize,"%d",&keysz) != 1)
628 +               die (EX_USAGE, _("mount: argument to --keybits or -k must be a number"));
629 +
630         switch (argc+specseen) {
631         case 0:
632                 /* mount -a */
633 --- util-linux-2.12.orig/mount/rmd160.c
634 +++ util-linux-2.12/mount/rmd160.c
635 @@ -0,0 +1,532 @@
636 +/* rmd160.c  - RIPE-MD160
637 + *     Copyright (C) 1998 Free Software Foundation, Inc.
638 + */
639 +
640 +/* This file was part of GnuPG. Modified for use within the Linux
641 + * mount utility by Marc Mutz <Marc@Mutz.com>. None of this code is
642 + * by myself. I just removed everything that you don't need when all
643 + * you want to do is to use rmd160_hash_buffer().
644 + * My comments are marked with (mm).  */
645 +
646 +/* GnuPG is free software; you can redistribute it and/or modify
647 + * it under the terms of the GNU General Public License as published by
648 + * the Free Software Foundation; either version 2 of the License, or
649 + * (at your option) any later version.
650 + *
651 + * GnuPG is distributed in the hope that it will be useful,
652 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
653 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
654 + * GNU General Public License for more details.
655 + *
656 + * You should have received a copy of the GNU General Public License
657 + * along with this program; if not, write to the Free Software
658 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */
659 +
660 +#include <string.h> /* (mm) for memcpy */
661 +#include <endian.h> /* (mm) for BIG_ENDIAN and BYTE_ORDER */
662 +#include "rmd160.h"
663 +
664 +/* (mm) these are used by the original GnuPG file. In order to modify
665 + * that file not too much, we keep the notations. maybe it would be
666 + * better to include linux/types.h and typedef __u32 to u32 and __u8
667 + * to byte?  */
668 +typedef unsigned int u32; /* taken from e.g. util-linux's minix.h */
669 +typedef unsigned char byte;
670 +
671 +typedef struct {
672 +    u32  h0,h1,h2,h3,h4;
673 +    u32  nblocks;
674 +    byte buf[64];
675 +    int  count;
676 +} RMD160_CONTEXT;
677 +
678 +/****************
679 + * Rotate a 32 bit integer by n bytes
680 + */
681 +#if defined(__GNUC__) && defined(__i386__)
682 +static inline u32
683 +rol( u32 x, int n)
684 +{
685 +       __asm__("roll %%cl,%0"
686 +               :"=r" (x)
687 +               :"0" (x),"c" (n));
688 +       return x;
689 +}
690 +#else
691 +  #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
692 +#endif
693 +
694 +/*********************************
695 + * RIPEMD-160 is not patented, see (as of 25.10.97)
696 + *   http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
697 + * Note that the code uses Little Endian byteorder, which is good for
698 + * 386 etc, but we must add some conversion when used on a big endian box.
699 + *
700 + *
701 + * Pseudo-code for RIPEMD-160
702 + *
703 + * RIPEMD-160 is an iterative hash function that operates on 32-bit words.
704 + * The round function takes as input a 5-word chaining variable and a 16-word
705 + * message block and maps this to a new chaining variable. All operations are
706 + * defined on 32-bit words. Padding is identical to that of MD4.
707 + *
708 + *
709 + * RIPEMD-160: definitions
710 + *
711 + *
712 + *   nonlinear functions at bit level: exor, mux, -, mux, -
713 + *
714 + *   f(j, x, y, z) = x XOR y XOR z               (0 <= j <= 15)
715 + *   f(j, x, y, z) = (x AND y) OR (NOT(x) AND z)  (16 <= j <= 31)
716 + *   f(j, x, y, z) = (x OR NOT(y)) XOR z         (32 <= j <= 47)
717 + *   f(j, x, y, z) = (x AND z) OR (y AND NOT(z))  (48 <= j <= 63)
718 + *   f(j, x, y, z) = x XOR (y OR NOT(z))         (64 <= j <= 79)
719 + *
720 + *
721 + *   added constants (hexadecimal)
722 + *
723 + *   K(j) = 0x00000000     (0 <= j <= 15)
724 + *   K(j) = 0x5A827999    (16 <= j <= 31)      int(2**30 x sqrt(2))
725 + *   K(j) = 0x6ED9EBA1    (32 <= j <= 47)      int(2**30 x sqrt(3))
726 + *   K(j) = 0x8F1BBCDC    (48 <= j <= 63)      int(2**30 x sqrt(5))
727 + *   K(j) = 0xA953FD4E    (64 <= j <= 79)      int(2**30 x sqrt(7))
728 + *   K'(j) = 0x50A28BE6     (0 <= j <= 15)      int(2**30 x cbrt(2))
729 + *   K'(j) = 0x5C4DD124    (16 <= j <= 31)      int(2**30 x cbrt(3))
730 + *   K'(j) = 0x6D703EF3    (32 <= j <= 47)      int(2**30 x cbrt(5))
731 + *   K'(j) = 0x7A6D76E9    (48 <= j <= 63)      int(2**30 x cbrt(7))
732 + *   K'(j) = 0x00000000    (64 <= j <= 79)
733 + *
734 + *
735 + *   selection of message word
736 + *
737 + *   r(j)      = j                   (0 <= j <= 15)
738 + *   r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
739 + *   r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
740 + *   r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
741 + *   r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
742 + *   r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
743 + *   r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
744 + *   r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
745 + *   r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
746 + *   r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
747 + *
748 + *
749 + *   amount for rotate left (rol)
750 + *
751 + *   s(0..15)  = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
752 + *   s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
753 + *   s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
754 + *   s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
755 + *   s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
756 + *   s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
757 + *   s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
758 + *   s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
759 + *   s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
760 + *   s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
761 + *
762 + *
763 + *   initial value (hexadecimal)
764 + *
765 + *   h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476;
766 + *                                                     h4 = 0xC3D2E1F0;
767 + *
768 + *
769 + * RIPEMD-160: pseudo-code
770 + *
771 + *   It is assumed that the message after padding consists of t 16-word blocks
772 + *   that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15.
773 + *   The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left
774 + *   shift (rotate) over s positions.
775 + *
776 + *
777 + *   for i := 0 to t-1 {
778 + *      A := h0; B := h1; C := h2; D = h3; E = h4;
779 + *      A' := h0; B' := h1; C' := h2; D' = h3; E' = h4;
780 + *      for j := 0 to 79 {
781 + *          T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E;
782 + *          A := E; E := D; D := rol_10(C); C := B; B := T;
783 + *          T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)]
784 +                                                      [+] K'(j)) [+] E';
785 + *          A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T;
786 + *      }
787 + *      T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A';
788 + *      h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T;
789 + *   }
790 + */
791 +
792 +/* Some examples:
793 + * ""                    9c1185a5c5e9fc54612808977ee8f548b2258d31
794 + * "a"                   0bdc9d2d256b3ee9daae347be6f4dc835a467ffe
795 + * "abc"                 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
796 + * "message digest"      5d0689ef49d2fae572b881b123a85ffa21595f36
797 + * "a...z"               f71c27109c692c1b56bbdceb5b9d2865b3708dbc
798 + * "abcdbcde...nopq"     12a053384a9c0c88e405a06c27dcf49ada62eb2b
799 + * "A...Za...z0...9"     b0e20b6e3116640286ed3a87a5713079b21f5189
800 + * 8 times "1234567890"  9b752e45573d4b39f4dbd3323cab82bf63326bfb
801 + * 1 million times "a"   52783243c1697bdbe16d37f97f68f08325dc1528
802 + */
803 +
804 +
805 +static void
806 +rmd160_init( RMD160_CONTEXT *hd )
807 +{
808 +    hd->h0 = 0x67452301;
809 +    hd->h1 = 0xEFCDAB89;
810 +    hd->h2 = 0x98BADCFE;
811 +    hd->h3 = 0x10325476;
812 +    hd->h4 = 0xC3D2E1F0;
813 +    hd->nblocks = 0;
814 +    hd->count = 0;
815 +}
816 +
817 +
818 +
819 +/****************
820 + * Transform the message X which consists of 16 32-bit-words
821 + */
822 +static void
823 +transform( RMD160_CONTEXT *hd, byte *data )
824 +{
825 +    u32 a,b,c,d,e,aa,bb,cc,dd,ee,t;
826 +  #if BYTE_ORDER == BIG_ENDIAN
827 +    u32 x[16];
828 +    { int i;
829 +      byte *p2, *p1;
830 +      for(i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 ) {
831 +       p2[3] = *p1++;
832 +       p2[2] = *p1++;
833 +       p2[1] = *p1++;
834 +       p2[0] = *p1++;
835 +      }
836 +    }
837 +  #else
838 +   #if 0
839 +    u32 *x =(u32*)data;
840 +   #else
841 +    /* this version is better because it is always aligned;
842 +     * The performance penalty on a 586-100 is about 6% which
843 +     * is acceptable - because the data is more local it might
844 +     * also be possible that this is faster on some machines.
845 +     * This function (when compiled with -02 on gcc 2.7.2)
846 +     * executes on a 586-100 (39.73 bogomips) at about 1900kb/sec;
847 +     * [measured with a 4MB data and "gpgm --print-md rmd160"] */
848 +    u32 x[16];
849 +    memcpy( x, data, 64 );
850 +   #endif
851 +  #endif
852 +
853 +
854 +#define K0  0x00000000
855 +#define K1  0x5A827999
856 +#define K2  0x6ED9EBA1
857 +#define K3  0x8F1BBCDC
858 +#define K4  0xA953FD4E
859 +#define KK0 0x50A28BE6
860 +#define KK1 0x5C4DD124
861 +#define KK2 0x6D703EF3
862 +#define KK3 0x7A6D76E9
863 +#define KK4 0x00000000
864 +#define F0(x,y,z)   ( (x) ^ (y) ^ (z) )
865 +#define F1(x,y,z)   ( ((x) & (y)) | (~(x) & (z)) )
866 +#define F2(x,y,z)   ( ((x) | ~(y)) ^ (z) )
867 +#define F3(x,y,z)   ( ((x) & (z)) | ((y) & ~(z)) )
868 +#define F4(x,y,z)   ( (x) ^ ((y) | ~(z)) )
869 +#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \
870 +                                 a = rol(t,s) + e;            \
871 +                                 c = rol(c,10);               \
872 +                               } while(0)
873 +
874 +    /* left lane */
875 +    a = hd->h0;
876 +    b = hd->h1;
877 +    c = hd->h2;
878 +    d = hd->h3;
879 +    e = hd->h4;
880 +    R( a, b, c, d, e, F0, K0,  0, 11 );
881 +    R( e, a, b, c, d, F0, K0,  1, 14 );
882 +    R( d, e, a, b, c, F0, K0,  2, 15 );
883 +    R( c, d, e, a, b, F0, K0,  3, 12 );
884 +    R( b, c, d, e, a, F0, K0,  4,  5 );
885 +    R( a, b, c, d, e, F0, K0,  5,  8 );
886 +    R( e, a, b, c, d, F0, K0,  6,  7 );
887 +    R( d, e, a, b, c, F0, K0,  7,  9 );
888 +    R( c, d, e, a, b, F0, K0,  8, 11 );
889 +    R( b, c, d, e, a, F0, K0,  9, 13 );
890 +    R( a, b, c, d, e, F0, K0, 10, 14 );
891 +    R( e, a, b, c, d, F0, K0, 11, 15 );
892 +    R( d, e, a, b, c, F0, K0, 12,  6 );
893 +    R( c, d, e, a, b, F0, K0, 13,  7 );
894 +    R( b, c, d, e, a, F0, K0, 14,  9 );
895 +    R( a, b, c, d, e, F0, K0, 15,  8 );
896 +    R( e, a, b, c, d, F1, K1,  7,  7 );
897 +    R( d, e, a, b, c, F1, K1,  4,  6 );
898 +    R( c, d, e, a, b, F1, K1, 13,  8 );
899 +    R( b, c, d, e, a, F1, K1,  1, 13 );
900 +    R( a, b, c, d, e, F1, K1, 10, 11 );
901 +    R( e, a, b, c, d, F1, K1,  6,  9 );
902 +    R( d, e, a, b, c, F1, K1, 15,  7 );
903 +    R( c, d, e, a, b, F1, K1,  3, 15 );
904 +    R( b, c, d, e, a, F1, K1, 12,  7 );
905 +    R( a, b, c, d, e, F1, K1,  0, 12 );
906 +    R( e, a, b, c, d, F1, K1,  9, 15 );
907 +    R( d, e, a, b, c, F1, K1,  5,  9 );
908 +    R( c, d, e, a, b, F1, K1,  2, 11 );
909 +    R( b, c, d, e, a, F1, K1, 14,  7 );
910 +    R( a, b, c, d, e, F1, K1, 11, 13 );
911 +    R( e, a, b, c, d, F1, K1,  8, 12 );
912 +    R( d, e, a, b, c, F2, K2,  3, 11 );
913 +    R( c, d, e, a, b, F2, K2, 10, 13 );
914 +    R( b, c, d, e, a, F2, K2, 14,  6 );
915 +    R( a, b, c, d, e, F2, K2,  4,  7 );
916 +    R( e, a, b, c, d, F2, K2,  9, 14 );
917 +    R( d, e, a, b, c, F2, K2, 15,  9 );
918 +    R( c, d, e, a, b, F2, K2,  8, 13 );
919 +    R( b, c, d, e, a, F2, K2,  1, 15 );
920 +    R( a, b, c, d, e, F2, K2,  2, 14 );
921 +    R( e, a, b, c, d, F2, K2,  7,  8 );
922 +    R( d, e, a, b, c, F2, K2,  0, 13 );
923 +    R( c, d, e, a, b, F2, K2,  6,  6 );
924 +    R( b, c, d, e, a, F2, K2, 13,  5 );
925 +    R( a, b, c, d, e, F2, K2, 11, 12 );
926 +    R( e, a, b, c, d, F2, K2,  5,  7 );
927 +    R( d, e, a, b, c, F2, K2, 12,  5 );
928 +    R( c, d, e, a, b, F3, K3,  1, 11 );
929 +    R( b, c, d, e, a, F3, K3,  9, 12 );
930 +    R( a, b, c, d, e, F3, K3, 11, 14 );
931 +    R( e, a, b, c, d, F3, K3, 10, 15 );
932 +    R( d, e, a, b, c, F3, K3,  0, 14 );
933 +    R( c, d, e, a, b, F3, K3,  8, 15 );
934 +    R( b, c, d, e, a, F3, K3, 12,  9 );
935 +    R( a, b, c, d, e, F3, K3,  4,  8 );
936 +    R( e, a, b, c, d, F3, K3, 13,  9 );
937 +    R( d, e, a, b, c, F3, K3,  3, 14 );
938 +    R( c, d, e, a, b, F3, K3,  7,  5 );
939 +    R( b, c, d, e, a, F3, K3, 15,  6 );
940 +    R( a, b, c, d, e, F3, K3, 14,  8 );
941 +    R( e, a, b, c, d, F3, K3,  5,  6 );
942 +    R( d, e, a, b, c, F3, K3,  6,  5 );
943 +    R( c, d, e, a, b, F3, K3,  2, 12 );
944 +    R( b, c, d, e, a, F4, K4,  4,  9 );
945 +    R( a, b, c, d, e, F4, K4,  0, 15 );
946 +    R( e, a, b, c, d, F4, K4,  5,  5 );
947 +    R( d, e, a, b, c, F4, K4,  9, 11 );
948 +    R( c, d, e, a, b, F4, K4,  7,  6 );
949 +    R( b, c, d, e, a, F4, K4, 12,  8 );
950 +    R( a, b, c, d, e, F4, K4,  2, 13 );
951 +    R( e, a, b, c, d, F4, K4, 10, 12 );
952 +    R( d, e, a, b, c, F4, K4, 14,  5 );
953 +    R( c, d, e, a, b, F4, K4,  1, 12 );
954 +    R( b, c, d, e, a, F4, K4,  3, 13 );
955 +    R( a, b, c, d, e, F4, K4,  8, 14 );
956 +    R( e, a, b, c, d, F4, K4, 11, 11 );
957 +    R( d, e, a, b, c, F4, K4,  6,  8 );
958 +    R( c, d, e, a, b, F4, K4, 15,  5 );
959 +    R( b, c, d, e, a, F4, K4, 13,  6 );
960 +
961 +    aa = a; bb = b; cc = c; dd = d; ee = e;
962 +
963 +    /* right lane */
964 +    a = hd->h0;
965 +    b = hd->h1;
966 +    c = hd->h2;
967 +    d = hd->h3;
968 +    e = hd->h4;
969 +    R( a, b, c, d, e, F4, KK0, 5,  8);
970 +    R( e, a, b, c, d, F4, KK0, 14,  9);
971 +    R( d, e, a, b, c, F4, KK0, 7,  9);
972 +    R( c, d, e, a, b, F4, KK0, 0, 11);
973 +    R( b, c, d, e, a, F4, KK0, 9, 13);
974 +    R( a, b, c, d, e, F4, KK0, 2, 15);
975 +    R( e, a, b, c, d, F4, KK0, 11, 15);
976 +    R( d, e, a, b, c, F4, KK0, 4,  5);
977 +    R( c, d, e, a, b, F4, KK0, 13,  7);
978 +    R( b, c, d, e, a, F4, KK0, 6,  7);
979 +    R( a, b, c, d, e, F4, KK0, 15,  8);
980 +    R( e, a, b, c, d, F4, KK0, 8, 11);
981 +    R( d, e, a, b, c, F4, KK0, 1, 14);
982 +    R( c, d, e, a, b, F4, KK0, 10, 14);
983 +    R( b, c, d, e, a, F4, KK0, 3, 12);
984 +    R( a, b, c, d, e, F4, KK0, 12,  6);
985 +    R( e, a, b, c, d, F3, KK1, 6,  9);
986 +    R( d, e, a, b, c, F3, KK1, 11, 13);
987 +    R( c, d, e, a, b, F3, KK1, 3, 15);
988 +    R( b, c, d, e, a, F3, KK1, 7,  7);
989 +    R( a, b, c, d, e, F3, KK1, 0, 12);
990 +    R( e, a, b, c, d, F3, KK1, 13,  8);
991 +    R( d, e, a, b, c, F3, KK1, 5,  9);
992 +    R( c, d, e, a, b, F3, KK1, 10, 11);
993 +    R( b, c, d, e, a, F3, KK1, 14,  7);
994 +    R( a, b, c, d, e, F3, KK1, 15,  7);
995 +    R( e, a, b, c, d, F3, KK1, 8, 12);
996 +    R( d, e, a, b, c, F3, KK1, 12,  7);
997 +    R( c, d, e, a, b, F3, KK1, 4,  6);
998 +    R( b, c, d, e, a, F3, KK1, 9, 15);
999 +    R( a, b, c, d, e, F3, KK1, 1, 13);
1000 +    R( e, a, b, c, d, F3, KK1, 2, 11);
1001 +    R( d, e, a, b, c, F2, KK2, 15,  9);
1002 +    R( c, d, e, a, b, F2, KK2, 5,  7);
1003 +    R( b, c, d, e, a, F2, KK2, 1, 15);
1004 +    R( a, b, c, d, e, F2, KK2, 3, 11);
1005 +    R( e, a, b, c, d, F2, KK2, 7,  8);
1006 +    R( d, e, a, b, c, F2, KK2, 14,  6);
1007 +    R( c, d, e, a, b, F2, KK2, 6,  6);
1008 +    R( b, c, d, e, a, F2, KK2, 9, 14);
1009 +    R( a, b, c, d, e, F2, KK2, 11, 12);
1010 +    R( e, a, b, c, d, F2, KK2, 8, 13);
1011 +    R( d, e, a, b, c, F2, KK2, 12,  5);
1012 +    R( c, d, e, a, b, F2, KK2, 2, 14);
1013 +    R( b, c, d, e, a, F2, KK2, 10, 13);
1014 +    R( a, b, c, d, e, F2, KK2, 0, 13);
1015 +    R( e, a, b, c, d, F2, KK2, 4,  7);
1016 +    R( d, e, a, b, c, F2, KK2, 13,  5);
1017 +    R( c, d, e, a, b, F1, KK3, 8, 15);
1018 +    R( b, c, d, e, a, F1, KK3, 6,  5);
1019 +    R( a, b, c, d, e, F1, KK3, 4,  8);
1020 +    R( e, a, b, c, d, F1, KK3, 1, 11);
1021 +    R( d, e, a, b, c, F1, KK3, 3, 14);
1022 +    R( c, d, e, a, b, F1, KK3, 11, 14);
1023 +    R( b, c, d, e, a, F1, KK3, 15,  6);
1024 +    R( a, b, c, d, e, F1, KK3, 0, 14);
1025 +    R( e, a, b, c, d, F1, KK3, 5,  6);
1026 +    R( d, e, a, b, c, F1, KK3, 12,  9);
1027 +    R( c, d, e, a, b, F1, KK3, 2, 12);
1028 +    R( b, c, d, e, a, F1, KK3, 13,  9);
1029 +    R( a, b, c, d, e, F1, KK3, 9, 12);
1030 +    R( e, a, b, c, d, F1, KK3, 7,  5);
1031 +    R( d, e, a, b, c, F1, KK3, 10, 15);
1032 +    R( c, d, e, a, b, F1, KK3, 14,  8);
1033 +    R( b, c, d, e, a, F0, KK4, 12,  8);
1034 +    R( a, b, c, d, e, F0, KK4, 15,  5);
1035 +    R( e, a, b, c, d, F0, KK4, 10, 12);
1036 +    R( d, e, a, b, c, F0, KK4, 4,  9);
1037 +    R( c, d, e, a, b, F0, KK4, 1, 12);
1038 +    R( b, c, d, e, a, F0, KK4, 5,  5);
1039 +    R( a, b, c, d, e, F0, KK4, 8, 14);
1040 +    R( e, a, b, c, d, F0, KK4, 7,  6);
1041 +    R( d, e, a, b, c, F0, KK4, 6,  8);
1042 +    R( c, d, e, a, b, F0, KK4, 2, 13);
1043 +    R( b, c, d, e, a, F0, KK4, 13,  6);
1044 +    R( a, b, c, d, e, F0, KK4, 14,  5);
1045 +    R( e, a, b, c, d, F0, KK4, 0, 15);
1046 +    R( d, e, a, b, c, F0, KK4, 3, 13);
1047 +    R( c, d, e, a, b, F0, KK4, 9, 11);
1048 +    R( b, c, d, e, a, F0, KK4, 11, 11);
1049 +
1050 +
1051 +    t     = hd->h1 + d + cc;
1052 +    hd->h1 = hd->h2 + e + dd;
1053 +    hd->h2 = hd->h3 + a + ee;
1054 +    hd->h3 = hd->h4 + b + aa;
1055 +    hd->h4 = hd->h0 + c + bb;
1056 +    hd->h0 = t;
1057 +}
1058 +
1059 +
1060 +/* Update the message digest with the contents
1061 + * of INBUF with length INLEN.
1062 + */
1063 +static void
1064 +rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen)
1065 +{
1066 +    if( hd->count == 64 ) { /* flush the buffer */
1067 +       transform( hd, hd->buf );
1068 +       hd->count = 0;
1069 +       hd->nblocks++;
1070 +    }
1071 +    if( !inbuf )
1072 +       return;
1073 +    if( hd->count ) {
1074 +       for( ; inlen && hd->count < 64; inlen-- )
1075 +           hd->buf[hd->count++] = *inbuf++;
1076 +       rmd160_write( hd, NULL, 0 );
1077 +       if( !inlen )
1078 +           return;
1079 +    }
1080 +
1081 +    while( inlen >= 64 ) {
1082 +       transform( hd, inbuf );
1083 +       hd->count = 0;
1084 +       hd->nblocks++;
1085 +       inlen -= 64;
1086 +       inbuf += 64;
1087 +    }
1088 +    for( ; inlen && hd->count < 64; inlen-- )
1089 +       hd->buf[hd->count++] = *inbuf++;
1090 +}
1091 +
1092 +/* The routine terminates the computation
1093 + */
1094 +
1095 +static void
1096 +rmd160_final( RMD160_CONTEXT *hd )
1097 +{
1098 +    u32 t, msb, lsb;
1099 +    byte *p;
1100 +
1101 +    rmd160_write(hd, NULL, 0); /* flush */;
1102 +
1103 +    msb = 0;
1104 +    t = hd->nblocks;
1105 +    if( (lsb = t << 6) < t ) /* multiply by 64 to make a byte count */
1106 +       msb++;
1107 +    msb += t >> 26;
1108 +    t = lsb;
1109 +    if( (lsb = t + hd->count) < t ) /* add the count */
1110 +       msb++;
1111 +    t = lsb;
1112 +    if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
1113 +       msb++;
1114 +    msb += t >> 29;
1115 +
1116 +    if( hd->count < 56 ) { /* enough room */
1117 +       hd->buf[hd->count++] = 0x80; /* pad */
1118 +       while( hd->count < 56 )
1119 +           hd->buf[hd->count++] = 0;  /* pad */
1120 +    }
1121 +    else { /* need one extra block */
1122 +       hd->buf[hd->count++] = 0x80; /* pad character */
1123 +       while( hd->count < 64 )
1124 +           hd->buf[hd->count++] = 0;
1125 +       rmd160_write(hd, NULL, 0);  /* flush */;
1126 +       memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
1127 +    }
1128 +    /* append the 64 bit count */
1129 +    hd->buf[56] = lsb     ;
1130 +    hd->buf[57] = lsb >>  8;
1131 +    hd->buf[58] = lsb >> 16;
1132 +    hd->buf[59] = lsb >> 24;
1133 +    hd->buf[60] = msb     ;
1134 +    hd->buf[61] = msb >>  8;
1135 +    hd->buf[62] = msb >> 16;
1136 +    hd->buf[63] = msb >> 24;
1137 +    transform( hd, hd->buf );
1138 +
1139 +    p = hd->buf;
1140 +  #if BYTE_ORDER == BIG_ENDIAN
1141 +    #define X(a) do { *p++ = hd->h##a     ; *p++ = hd->h##a >> 8;      \
1142 +                     *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
1143 +  #else /* little endian */
1144 +    #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
1145 +  #endif
1146 +    X(0);
1147 +    X(1);
1148 +    X(2);
1149 +    X(3);
1150 +    X(4);
1151 +  #undef X
1152 +}
1153 +
1154 +/****************
1155 + * Shortcut functions which puts the hash value of the supplied buffer
1156 + * into outbuf which must have a size of 20 bytes.
1157 + */
1158 +void
1159 +rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length )
1160 +{
1161 +    RMD160_CONTEXT hd;
1162 +
1163 +    rmd160_init( &hd );
1164 +    rmd160_write( &hd, (byte*)buffer, length );
1165 +    rmd160_final( &hd );
1166 +    memcpy( outbuf, hd.buf, 20 );
1167 +}
1168 --- util-linux-2.12.orig/mount/rmd160.h
1169 +++ util-linux-2.12/mount/rmd160.h
1170 @@ -0,0 +1,9 @@
1171 +#ifndef RMD160_H
1172 +#define RMD160_H
1173 +
1174 +void
1175 +rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length );
1176 +
1177 +#endif /*RMD160_H*/
1178 +
1179 +
1180
This page took 0.14505 seconds and 3 git commands to generate.