]> git.pld-linux.org Git - packages/util-linux.git/blob - util-linux-crypto-debian.patch
- adapterized (avoid macros with /usr/include/{ncurses,freetype}*)
[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/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
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 @@ -126,7 +191,8 @@
106                         printf(_(", offset %d"), loopinfo.lo_offset);
107  
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);
113  
114                 printf("\n");
115 @@ -189,10 +255,9 @@
116                 error(_("mount: could not find any device /dev/loop#"));
117         else if (!someloop) {
118                 error(_(
119 -                   "mount: Could not find any loop device. Maybe this kernel "
120 -                   "does not know\n"
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?"));
126         } else
127                 error(_("mount: could not find any free loop device"));
128         return 0;
129 @@ -247,10 +312,20 @@
130  
131  int
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;
136         int fd, ffd, mode;
137         char *pass;
138 +       int tried_old;
139 +
140 +       int kerneli=open("/proc/crypto/cipher",O_RDONLY);
141 +
142 +       if (kerneli>=0) {
143 +               close(kerneli);
144 +               kerneli=1;
145 +       } else {
146 +               kerneli=0;
147 +       }
148  
149         mode = (*loopro ? O_RDONLY : O_RDWR);
150         if ((ffd = open(file, mode)) < 0) {
151 @@ -276,8 +351,13 @@
152                         loopinfo64.lo_encrypt_type = atoi(encryption);
153                 } else {
154                         loopinfo64.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
155 -                       snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
156 +                       if (kerneli)
157 +                           snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
158 +                                "%s-cbc", encryption);
159 +                       else
160 +                           snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
161                                  "%s", encryption);
162 +                       loopinfo64.lo_crypt_name[LO_NAME_SIZE-1] = 0;
163                 }
164         }
165  
166 @@ -296,29 +376,98 @@
167         }
168  #endif
169  
170 +       if (keysz==0)
171 +               keysz=LO_KEY_SIZE*8;
172 +       tried_old=0;
173 +again:
174         switch (loopinfo64.lo_encrypt_type) {
175         case LO_CRYPT_NONE:
176                 loopinfo64.lo_encrypt_key_size = 0;
177                 break;
178         case LO_CRYPT_XOR:
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);
184                 break;
185 -       default:
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:
192 +       case LO_CRYPT_RC6:
193 +       case LO_CRYPT_3DES:
194 +       case LO_CRYPT_DFC:
195 +       case LO_CRYPT_RIJNDAEL:
196 +           {
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];
201 +               int keylength;
202 +               int i;
203 +
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);
213 +               keylength=0;
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;
217 +                                break;
218 +                        }
219 +               }
220 +               loopinfo64.lo_encrypt_key_size=keylength;
221 +               break;
222 +           }
223 +       default:
224 +               if (hash_password) {
225 +                   char keybits[2*HASHLENGTH]; 
226 +                   char passwdbuff[PASSWDBUFFLEN];
227 +
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);
235 +               } else {
236 +                   pass = xgetpass(pfd, _("Password: "));
237 +                   xstrncpy(loopinfo64.lo_encrypt_key, pass, keysz/8);
238 +               }
239 +               loopinfo64.lo_encrypt_key_size = keysz/8;
240         }
241  
242         if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
243                 perror("ioctl: LOOP_SET_FD");
244                 return 1;
245         }
246 -       close (ffd);
247 -
248 -       if (ioctl(fd, LOOP_SET_STATUS64, &loopinfo64) < 0) {
249 +       if (kerneli) {
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 */
255 +               if (tried_old) {
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");
259 +                       goto fail;
260 +               }
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);
264 +               tried_old = 1;
265 +               goto again;
266 +           }
267 +       } else {
268 +           if (ioctl(fd, LOOP_SET_STATUS64, &loopinfo64) < 0) {
269                 struct loop_info loopinfo;
270                 int errsv = errno;
271  
272 @@ -333,8 +482,10 @@
273                         perror("ioctl: LOOP_SET_STATUS");
274                         goto fail;
275                 }
276 +           }
277         }
278  
279 +       close (ffd);
280         close (fd);
281         if (verbose > 1)
282                 printf(_("set_loop(%s,%s,%d): success\n"),
283 @@ -343,6 +494,7 @@
284  
285   fail:
286         (void) ioctl (fd, LOOP_CLR_FD, 0);
287 +       close (ffd);
288         close (fd);
289         return 1;
290  }
291 @@ -411,8 +563,24 @@
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);
315         exit(1);
316  }
317  
318 @@ -445,20 +613,23 @@
319  
320  int
321  main(int argc, char **argv) {
322 -       char *offset, *encryption, *passfd;
323 +       char *offset, *encryption, *passfd, *keysize;
324         int delete, off, c;
325         int res = 0;
326         int ro = 0;
327         int pfd = -1;
328 +       int keysz = 0;
329 +       int hash_password = 1;
330  
331         setlocale(LC_ALL, "");
332         bindtextdomain(PACKAGE, LOCALEDIR);
333         textdomain(PACKAGE);
334  
335         delete = off = 0;
336 -       offset = encryption = passfd = NULL;
337 +       offset = encryption = passfd = keysize = NULL;
338         progname = argv[0];
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) {
342                 switch (c) {
343                 case 'd':
344                         delete = 1;
345 @@ -467,6 +638,12 @@
346                 case 'e':
347                         encryption = optarg;
348                         break;
349 +               case 'N':
350 +                       hash_password=0;
351 +                       break;
352 +               case 'k':
353 +                       keysize = optarg;
354 +                       break;
355                 case 'o':
356                         offset = optarg;
357                         break;
358 @@ -494,8 +671,10 @@
359                         usage();
360                 if (passfd && sscanf(passfd,"%d",&pfd) != 1)
361                         usage();
362 +               if (keysize && sscanf(keysize,"%d",&keysz) != 1)
363 +                       usage();
364                 res = set_loop(argv[optind], argv[optind+1], off,
365 -                              encryption, pfd, &ro);
366 +                              encryption, pfd, keysz, &ro, hash_password);
367         }
368         return res;
369  }
370 --- util-linux-2.12.orig/mount/lomount.h
371 +++ util-linux-2.12/mount/lomount.h
372 @@ -1,6 +1,6 @@
373  extern int verbose;
374  extern int set_loop(const char *, const char *, int, const char *,
375 -                   int, int *);
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
382 @@ -1,8 +1,39 @@
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
390  
391 +#ifndef LO_CRYPT_FISH2
392 +#define LO_CRYPT_FISH2 3
393 +#endif
394 +#ifndef LO_CRYPT_BLOW
395 +#define LO_CRYPT_BLOW 4
396 +#endif
397 +#ifndef LO_CRYPT_CAST128
398 +#define LO_CRYPT_CAST128 5
399 +#endif
400 +#ifndef LO_CRYPT_IDEA
401 +#define LO_CRYPT_IDEA 6
402 +#endif
403 +#ifndef LO_CRYPT_SERPENT
404 +#define LO_CRYPT_SERPENT 7
405 +#endif
406 +#ifndef LO_CRYPT_MARS
407 +#define LO_CRYPT_MARS 8
408 +#endif
409 +#ifndef LO_CRYPT_RC6
410 +#define LO_CRYPT_RC6 11
411 +#endif
412 +#ifndef LO_CRYPT_3DES
413 +#define LO_CRYPT_3DES 12
414 +#endif
415 +#ifndef LO_CRYPT_DFC
416 +#define LO_CRYPT_DFC 15
417 +#endif
418 +#ifndef LO_CRYPT_RIJNDAEL
419 +#define LO_CRYPT_RIJNDAEL 16
420 +#endif
421 +
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
427 @@ -50,19 +50,24 @@
428  .B \-e
429  option.)
430  .SH OPTIONS
431 -.IP \fB\-d\fP
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
446  device.
447 -.IP "\fB\-p \fInum\fP"
448 +.IP "\fB\-\-pass-fd, \-p \fInum\fP"
449  Read the passphrase from file descriptor with number
450  .I num
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.
454  .SH RETURN VALUE
455  .B losetup
456  returns 0 on success, nonzero on failure. When
457 @@ -109,6 +114,9 @@
458  .fi
459  .SH RESTRICTION
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.
463 +.fi
464  .\" .SH AUTHORS
465  .\" .nf
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
469 @@ -270,6 +270,12 @@
470  .B \-v
471  Verbose mode.
472  .TP
473 +.B \-p "\fInum\fP"
474 +If the mount requires a passphrase to be entered, read it from file
475 +descriptor
476 +.IR num\fP
477 +instead of from the terminal.
478 +.TP
479  .B \-a
480  Mount all filesystems (of the given types) mentioned in
481  .IR fstab .
482 @@ -633,6 +639,15 @@
483  .BR noexec ", " nosuid ", and " nodev
484  (unless overridden by subsequent options, as in the option line
485  .BR users,exec,dev,suid ).
486 +.TP
487 +.B encryption
488 +Specifies an encryption algorithm to use.  Used in conjunction with the
489 +.BR loop " option."
490 +.TP
491 +.B keybits
492 +Specifies the key size to use for an encryption algorithm. Used in conjunction
493 +with the
494 +.BR loop " and " encryption " options."
495  .RE
496  .TP
497  .B \-\-bind
498 @@ -1696,7 +1711,10 @@
499  .BR loop ", " offset " and " encryption ,
500  that are really options to
501  .BR losetup (8).
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 
505 +.BR \-\-pass-fd
506 +option. If no explicit loop device is mentioned
507  (but just an option `\fB\-o loop\fP' is given), then
508  .B mount
509  will try to find some unused loop device and use that.
510 @@ -1767,7 +1785,7 @@
511  .BR e2label (8),
512  .BR xfs_admin (8),
513  .BR mountd (8),
514 -.BR nfsd (8),
515 +.BR rpc.nfsd (8),
516  .BR mke2fs (8),
517  .BR tune2fs (8),
518  .BR losetup (8)
519 --- util-linux-2.12.orig/mount/mount.c
520 +++ util-linux-2.12/mount/mount.c
521 @@ -92,6 +92,9 @@
522  /* Nonzero for chatty (-v).  */
523  int verbose = 0;
524  
525 +/* Do we hash the password or not */
526 +int hash_password = 1;
527 +
528  /* Nonzero for sloppy (-s).  */
529  int sloppy = 0;
530  
531 @@ -116,6 +119,9 @@
532  /* Contains the fd to read the passphrase from, if any. */
533  static int pfd = -1;
534  
535 +/* Contains the preferred keysize in bits we want to use */
536 +static int keysz = 0;
537 +
538  /* Map from -o and fstab option strings to the flag argument to mount(2).  */
539  struct opt_map {
540    const char *opt;             /* option name */
541 @@ -195,7 +201,7 @@
542  };
543  
544  static char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption,
545 -  *opt_speed;
546 +  *opt_keybits, *opt_nohashpass, *opt_speed;
547  
548  static struct string_opt_map {
549    char *tag;
550 @@ -206,6 +212,8 @@
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 },
557    { NULL, 0, NULL }
558  };
559 @@ -586,7 +594,8 @@
560        *type = opt_vfstype;
561    }
562  
563 -  *loop = ((*flags & MS_LOOP) || *loopdev || opt_offset || opt_encryption);
564 +  *loop = ((*flags & MS_LOOP) || *loopdev || opt_offset || opt_encryption ||
565 +          opt_keybits);
566    *loopfile = *spec;
567  
568    if (*loop) {
569 @@ -604,8 +613,12 @@
570        if (verbose)
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)
578 +       hash_password=0;
579 +      if (set_loop (*loopdev, *loopfile, offset, opt_encryption, pfd, 
580 +                   keysz, &loopro, hash_password)) {
581         if (verbose)
582           printf(_("mount: failed setting up loop device\n"));
583         return EX_FAIL;
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;
598         char *uuid = NULL;
599         char *types = NULL;
600         struct mntentchn *mc;
601 @@ -1447,7 +1463,7 @@
602         initproctitle(argc, argv);
603  #endif
604  
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) {
608                 switch (c) {
609                 case 'a':              /* mount everything in fstab */
610 @@ -1471,6 +1487,9 @@
611                 case 'L':
612                         volumelabel = optarg;
613                         break;
614 +               case 'k':
615 +                       keysize = optarg;
616 +                       break;
617                 case 'n':               /* do not write /etc/mtab */
618                         ++nomtab;
619                         break;
620 @@ -1598,6 +1617,11 @@
621         } else
622                 spec = NULL;            /* just for gcc */
623  
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"));
628 +
629         switch (argc+specseen) {
630         case 0:
631                 /* mount -a */
632 --- util-linux-2.12.orig/mount/rmd160.c
633 +++ util-linux-2.12/mount/rmd160.c
634 @@ -0,0 +1,532 @@
635 +/* rmd160.c  - RIPE-MD160
636 + *     Copyright (C) 1998 Free Software Foundation, Inc.
637 + */
638 +
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).  */
644 +
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.
649 + *
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.
654 + *
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 */
658 +
659 +#include <string.h> /* (mm) for memcpy */
660 +#include <endian.h> /* (mm) for BIG_ENDIAN and BYTE_ORDER */
661 +#include "rmd160.h"
662 +
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
666 + * to byte?  */
667 +typedef unsigned int u32; /* taken from e.g. util-linux's minix.h */
668 +typedef unsigned char byte;
669 +
670 +typedef struct {
671 +    u32  h0,h1,h2,h3,h4;
672 +    u32  nblocks;
673 +    byte buf[64];
674 +    int  count;
675 +} RMD160_CONTEXT;
676 +
677 +/****************
678 + * Rotate a 32 bit integer by n bytes
679 + */
680 +#if defined(__GNUC__) && defined(__i386__)
681 +static inline u32
682 +rol( u32 x, int n)
683 +{
684 +       __asm__("roll %%cl,%0"
685 +               :"=r" (x)
686 +               :"0" (x),"c" (n));
687 +       return x;
688 +}
689 +#else
690 +  #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
691 +#endif
692 +
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.
698 + *
699 + *
700 + * Pseudo-code for RIPEMD-160
701 + *
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.
706 + *
707 + *
708 + * RIPEMD-160: definitions
709 + *
710 + *
711 + *   nonlinear functions at bit level: exor, mux, -, mux, -
712 + *
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)
718 + *
719 + *
720 + *   added constants (hexadecimal)
721 + *
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)
732 + *
733 + *
734 + *   selection of message word
735 + *
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
746 + *
747 + *
748 + *   amount for rotate left (rol)
749 + *
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
760 + *
761 + *
762 + *   initial value (hexadecimal)
763 + *
764 + *   h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476;
765 + *                                                     h4 = 0xC3D2E1F0;
766 + *
767 + *
768 + * RIPEMD-160: pseudo-code
769 + *
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.
774 + *
775 + *
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)]
783 +                                                      [+] K'(j)) [+] E';
784 + *          A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T;
785 + *      }
786 + *      T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A';
787 + *      h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T;
788 + *   }
789 + */
790 +
791 +/* Some examples:
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
801 + */
802 +
803 +
804 +static void
805 +rmd160_init( RMD160_CONTEXT *hd )
806 +{
807 +    hd->h0 = 0x67452301;
808 +    hd->h1 = 0xEFCDAB89;
809 +    hd->h2 = 0x98BADCFE;
810 +    hd->h3 = 0x10325476;
811 +    hd->h4 = 0xC3D2E1F0;
812 +    hd->nblocks = 0;
813 +    hd->count = 0;
814 +}
815 +
816 +
817 +
818 +/****************
819 + * Transform the message X which consists of 16 32-bit-words
820 + */
821 +static void
822 +transform( RMD160_CONTEXT *hd, byte *data )
823 +{
824 +    u32 a,b,c,d,e,aa,bb,cc,dd,ee,t;
825 +  #if BYTE_ORDER == BIG_ENDIAN
826 +    u32 x[16];
827 +    { int i;
828 +      byte *p2, *p1;
829 +      for(i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 ) {
830 +       p2[3] = *p1++;
831 +       p2[2] = *p1++;
832 +       p2[1] = *p1++;
833 +       p2[0] = *p1++;
834 +      }
835 +    }
836 +  #else
837 +   #if 0
838 +    u32 *x =(u32*)data;
839 +   #else
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"] */
847 +    u32 x[16];
848 +    memcpy( x, data, 64 );
849 +   #endif
850 +  #endif
851 +
852 +
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;            \
870 +                                 c = rol(c,10);               \
871 +                               } while(0)
872 +
873 +    /* left lane */
874 +    a = hd->h0;
875 +    b = hd->h1;
876 +    c = hd->h2;
877 +    d = hd->h3;
878 +    e = hd->h4;
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 );
959 +
960 +    aa = a; bb = b; cc = c; dd = d; ee = e;
961 +
962 +    /* right lane */
963 +    a = hd->h0;
964 +    b = hd->h1;
965 +    c = hd->h2;
966 +    d = hd->h3;
967 +    e = hd->h4;
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);
1048 +
1049 +
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;
1055 +    hd->h0 = t;
1056 +}
1057 +
1058 +
1059 +/* Update the message digest with the contents
1060 + * of INBUF with length INLEN.
1061 + */
1062 +static void
1063 +rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen)
1064 +{
1065 +    if( hd->count == 64 ) { /* flush the buffer */
1066 +       transform( hd, hd->buf );
1067 +       hd->count = 0;
1068 +       hd->nblocks++;
1069 +    }
1070 +    if( !inbuf )
1071 +       return;
1072 +    if( hd->count ) {
1073 +       for( ; inlen && hd->count < 64; inlen-- )
1074 +           hd->buf[hd->count++] = *inbuf++;
1075 +       rmd160_write( hd, NULL, 0 );
1076 +       if( !inlen )
1077 +           return;
1078 +    }
1079 +
1080 +    while( inlen >= 64 ) {
1081 +       transform( hd, inbuf );
1082 +       hd->count = 0;
1083 +       hd->nblocks++;
1084 +       inlen -= 64;
1085 +       inbuf += 64;
1086 +    }
1087 +    for( ; inlen && hd->count < 64; inlen-- )
1088 +       hd->buf[hd->count++] = *inbuf++;
1089 +}
1090 +
1091 +/* The routine terminates the computation
1092 + */
1093 +
1094 +static void
1095 +rmd160_final( RMD160_CONTEXT *hd )
1096 +{
1097 +    u32 t, msb, lsb;
1098 +    byte *p;
1099 +
1100 +    rmd160_write(hd, NULL, 0); /* flush */;
1101 +
1102 +    msb = 0;
1103 +    t = hd->nblocks;
1104 +    if( (lsb = t << 6) < t ) /* multiply by 64 to make a byte count */
1105 +       msb++;
1106 +    msb += t >> 26;
1107 +    t = lsb;
1108 +    if( (lsb = t + hd->count) < t ) /* add the count */
1109 +       msb++;
1110 +    t = lsb;
1111 +    if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
1112 +       msb++;
1113 +    msb += t >> 29;
1114 +
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 */
1119 +    }
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 */
1126 +    }
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 );
1137 +
1138 +    p = 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)
1144 +  #endif
1145 +    X(0);
1146 +    X(1);
1147 +    X(2);
1148 +    X(3);
1149 +    X(4);
1150 +  #undef X
1151 +}
1152 +
1153 +/****************
1154 + * Shortcut functions which puts the hash value of the supplied buffer
1155 + * into outbuf which must have a size of 20 bytes.
1156 + */
1157 +void
1158 +rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length )
1159 +{
1160 +    RMD160_CONTEXT hd;
1161 +
1162 +    rmd160_init( &hd );
1163 +    rmd160_write( &hd, (byte*)buffer, length );
1164 +    rmd160_final( &hd );
1165 +    memcpy( outbuf, hd.buf, 20 );
1166 +}
1167 --- util-linux-2.12.orig/mount/rmd160.h
1168 +++ util-linux-2.12/mount/rmd160.h
1169 @@ -0,0 +1,9 @@
1170 +#ifndef RMD160_H
1171 +#define RMD160_H
1172 +
1173 +void
1174 +rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length );
1175 +
1176 +#endif /*RMD160_H*/
1177 +
1178 +
1179
This page took 0.161778 seconds and 3 git commands to generate.