]> git.pld-linux.org Git - packages/util-linux.git/blob - util-linux-kerneli-2.4.patch
- release 2: updated kerneli-2.4 patch
[packages/util-linux.git] / util-linux-kerneli-2.4.patch
1 diff -Nur util-linux-2.11b.orig/mount/Makefile util-linux-2.11b/mount/Makefile
2 --- util-linux-2.11b.orig/mount/Makefile        Mon Mar  5 01:38:53 2001
3 +++ util-linux-2.11b/mount/Makefile     Wed Mar 28 11:41:40 2001
4 @@ -24,7 +24,7 @@
5  
6  MAYBE = pivot_root swapoff
7  
8 -LO_OBJS = lomount.o $(LIB)/xstrncpy.o
9 +LO_OBJS = lomount.o rmd160.o $(LIB)/xstrncpy.o
10  NFS_OBJS = nfsmount.o nfsmount_xdr.o nfsmount_clnt.o
11  GEN_FILES = nfsmount.h nfsmount_xdr.c nfsmount_clnt.c
12  
13 @@ -57,7 +57,7 @@
14  main_losetup.o: lomount.c
15         $(COMPILE) -DMAIN lomount.c -o $@
16  
17 -losetup: main_losetup.o $(LIB)/xstrncpy.o
18 +losetup: main_losetup.o rmd160.o $(LIB)/xstrncpy.o
19         $(LINK) $^ -o $@
20  
21  mount.o umount.o nfsmount.o losetup.o fstab.o realpath.o sundries.o: sundries.h
22 diff -Nur util-linux-2.11b.orig/mount/lomount.c util-linux-2.11b/mount/lomount.c
23 --- util-linux-2.11b.orig/mount/lomount.c       Thu Mar 15 11:09:58 2001
24 +++ util-linux-2.11b/mount/lomount.c    Wed Mar 28 12:09:33 2001
25 @@ -6,6 +6,11 @@
26   * - added Native Language Support
27   * Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
28   * - fixed strerr(errno) in gettext calls
29 + * 2000-09-24 Marc Mutz <Marc@Mutz.com>
30 + * - added long option names and the --pass-fd option to pass
31 + *   passphrases via fd's to losetup/mount. Used for encryption in
32 + *   non-interactive environments. The idea behind xgetpass() is stolen
33 + *   from GnuPG, v.1.0.3 (http://www.gnupg.org/).
34   */
35  
36  #define PROC_DEVICES   "/proc/devices"
37 @@ -21,54 +26,60 @@
38  #include <errno.h>
39  #include <stdlib.h>
40  #include <unistd.h>
41 +#include <limits.h>
42  #include <sys/ioctl.h>
43  #include <sys/stat.h>
44  #include <sys/mman.h>
45  
46  #include "loop.h"
47  #include "lomount.h"
48 +#include "rmd160.h"
49  #include "xstrncpy.h"
50  #include "nls.h"
51  
52 +#ifndef LO_CRYPT_CRYPTOAPI
53 +#define LO_CRYPT_CRYPTOAPI 18
54 +#endif
55 +
56  extern int verbose;
57  extern char *xstrdup (const char *s);  /* not: #include "sundries.h" */
58  extern void error (const char *fmt, ...);      /* idem */
59  
60 +struct cipher_info
61 +{
62 +       const char *name;
63 +       int blocksize;
64 +       int keysize_mask;
65 +       int ivsize;
66 +       int key_schedule_size;
67 +};
68 +
69 +static int set_loop_passwd(struct loop_info *_loopinfo, int pfd, int keysz,
70 +                       const char *encryption, int fd, int ffd);
71 +static int get_cipher_info(const char *name, struct cipher_info *res);
72 +static int name_to_id(const char *name);
73 +#ifdef MAIN
74 +static char *id_to_name(int fd);
75 +#endif
76 +
77  #ifdef LOOP_SET_FD
78  struct crypt_type_struct {
79         int id;
80         char *name;
81 +       int keylength;
82  } crypt_type_tbl[] = {
83 -       { LO_CRYPT_NONE, "no" },
84 -       { LO_CRYPT_NONE, "none" },
85 -       { LO_CRYPT_XOR, "xor" },
86 -       { LO_CRYPT_DES, "DES" },
87 -       { -1, NULL   }
88 +       { LO_CRYPT_NONE, "no",0 },
89 +       { LO_CRYPT_NONE, "none",0 },
90 +       { LO_CRYPT_XOR, "xor",0 },
91 +       { LO_CRYPT_DES, "DES",8 },
92 +       { LO_CRYPT_FISH2, "twofish",20 },
93 +       { LO_CRYPT_BLOW, "blowfish",20 },
94 +       { LO_CRYPT_CAST128, "cast128",16 },
95 +       { LO_CRYPT_IDEA, "idea",16 },
96 +       { -1, NULL,0   }
97  };
98  
99 -static int 
100 -crypt_type (const char *name) {
101 -       int i;
102 -
103 -       if (name) {
104 -               for (i = 0; crypt_type_tbl[i].id != -1; i++)
105 -                       if (!strcasecmp (name, crypt_type_tbl[i].name))
106 -                               return crypt_type_tbl[i].id;
107 -       }
108 -       return -1;
109 -}
110 -
111  #ifdef MAIN
112 -static char *
113 -crypt_name (int id) {
114 -       int i;
115 -
116 -       for (i = 0; crypt_type_tbl[i].id != -1; i++)
117 -               if (id == crypt_type_tbl[i].id)
118 -                       return crypt_type_tbl[i].name;
119 -       return "undefined";
120 -}
121 -
122  static int
123  show_loop (char *device) {
124         struct loop_info loopinfo;
125 @@ -90,7 +101,7 @@
126         printf (_("%s: [%04x]:%ld (%s) offset %d, %s encryption\n"),
127                 device, loopinfo.lo_device, loopinfo.lo_inode,
128                 loopinfo.lo_name, loopinfo.lo_offset,
129 -               crypt_name (loopinfo.lo_encrypt_type));
130 +               id_to_name(loopinfo.lo_encrypt_type));
131         close (fd);
132  
133         return 0;
134 @@ -183,24 +194,64 @@
135                 error(_(
136                     "mount: Could not find any loop device, and, according to %s,\n"
137                     "       this kernel does not know about the loop device.\n"
138 -                   "       (If so, then recompile or `insmod loop.o'.)"),
139 +                   "       (If so, then recompile or `modprobe loop'.)"),
140                       PROC_DEVICES);
141             else
142                 error(_(
143                     "mount: Could not find any loop device. Maybe this kernel does not know\n"
144 -                   "       about the loop device (then recompile or `insmod loop.o'), or\n"
145 +                   "       about the loop device (then recompile or `modprobe loop'), or\n"
146                     "       maybe /dev/loop# has the wrong major number?"));
147         } else
148                 error(_("mount: could not find any free loop device"));
149         return 0;
150  }
151  
152 +#define HASHLENGTH 20
153 +#define PASSWDBUFFLEN 130 /* getpass returns only max. 128 bytes, see man getpass */
154 +
155 +/* A function to read the passphrase either from the terminal or from
156 + * an open file descriptor */
157 +static char *
158 +xgetpass (int pfd, const char *prompt)
159 +{
160 +        if (pfd < 0) /* terminal */
161 +               return (getpass(prompt));
162 +       else {       /* file descriptor */
163 +               char *pass = NULL;
164 +               int buflen, i;
165 +
166 +               buflen=0;
167 +               for (i=0; ; i++) {
168 +                       if (i >= buflen-1) {
169 +                               /* we're running out of space in the buffer. 
170 +                                * Make it bigger: */
171 +                               char *tmppass = pass;
172 +                               buflen += 128;
173 +                               pass = realloc(tmppass,buflen);
174 +                               if (pass == NULL) {
175 +                                       /* realloc failed. Stop reading _now_. */
176 +                                       error("not enough memory while reading passphrase");
177 +                                       pass = tmppass; /* the old buffer hasn't changed */
178 +                                       break;
179 +                               }
180 +                       };
181 +                       if ( read(pfd,pass+i, 1) != 1 || pass[i] == '\n' )
182 +                               break;
183 +               }
184 +               if (pass == NULL)
185 +                       return "";
186 +               else {
187 +                       pass[i] = 0;
188 +                       return pass;
189 +               }
190 +       }
191 +}
192 +
193  int
194  set_loop (const char *device, const char *file, int offset,
195 -         const char *encryption, int *loopro) {
196 +         const char *encryption, int pfd, int keysz, int *loopro) {
197         struct loop_info loopinfo;
198 -       int fd, ffd, mode, i;
199 -       char *pass;
200 +       int fd, ffd, mode, tried_old;
201  
202         mode = (*loopro ? O_RDONLY : O_RDWR);
203         if ((ffd = open (file, mode)) < 0) {
204 @@ -218,13 +269,10 @@
205         *loopro = (mode == O_RDONLY);
206  
207         memset (&loopinfo, 0, sizeof (loopinfo));
208 -       xstrncpy (loopinfo.lo_name, file, LO_NAME_SIZE);
209 -       if (encryption && (loopinfo.lo_encrypt_type = crypt_type (encryption))
210 -           < 0) {
211 -               fprintf (stderr, _("Unsupported encryption type %s\n"),
212 -                        encryption);
213 -               return 1;
214 -       }
215 +       snprintf(loopinfo.lo_name, sizeof(loopinfo.lo_name),
216 +               "%s-cbc", encryption);
217 +       loopinfo.lo_name[LO_NAME_SIZE - 1] = 0;
218 +       loopinfo.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
219         loopinfo.lo_offset = offset;
220  
221  #ifdef MCL_FUTURE  
222 @@ -240,24 +288,74 @@
223         }
224  #endif
225  
226 -       switch (loopinfo.lo_encrypt_type) {
227 +       if (ioctl (fd, LOOP_SET_FD, ffd) < 0) {
228 +               perror ("ioctl: LOOP_SET_FD");
229 +               return 1;
230 +       }
231 +
232 +       tried_old = 0;
233 +again:
234 +       set_loop_passwd(&loopinfo, pfd, keysz, encryption, fd, ffd);
235 +
236 +       if (ioctl (fd, LOOP_SET_STATUS, &loopinfo) < 0) {
237 +               /* Try again with old-style LO_CRYPT_XX if
238 +                    new style LO_CRYPT_CRYPTOAPI ioctl didn't work */
239 +               if (tried_old) {
240 +                       error("The cipher does not exist, or a cipher module "
241 +                             "needs to be loaded into the kernel");
242 +                       perror ("ioctl: LOOP_SET_STATUS");
243 +                       goto out_ioctl;
244 +               }
245 +               strncpy (loopinfo.lo_name, file, LO_NAME_SIZE);
246 +               loopinfo.lo_name[LO_NAME_SIZE - 1] = 0;
247 +               loopinfo.lo_encrypt_type = name_to_id (encryption);
248 +               tried_old = 1;
249 +               goto again;
250 +       }
251 +       close (fd);
252 +       close (ffd);
253 +       if (verbose > 1)
254 +               printf(_("set_loop(%s,%s,%d): success\n"),
255 +                      device, file, offset);
256 +       return 0;
257 +out_ioctl:
258 +       (void) ioctl (fd, LOOP_CLR_FD, 0);
259 +       return 1;
260 +}
261 +
262 +int
263 +set_loop_passwd(struct loop_info *loopinfo, int pfd, int keysz,
264 +               const char *encryption, int fd, int ffd)
265 +{
266 +       int i;
267 +       int keylength;
268 +       char *pass;
269 +       char keybits[2*HASHLENGTH];
270 +       char passwdbuff[PASSWDBUFFLEN];
271 +       struct cipher_info info;
272 +
273 +       switch (loopinfo->lo_encrypt_type) {
274         case LO_CRYPT_NONE:
275 -               loopinfo.lo_encrypt_key_size = 0;
276 +               loopinfo->lo_encrypt_key_size = 0;
277                 break;
278         case LO_CRYPT_XOR:
279 -               pass = getpass (_("Password: "));
280 -               xstrncpy (loopinfo.lo_encrypt_key, pass, LO_KEY_SIZE);
281 -               loopinfo.lo_encrypt_key_size = strlen(loopinfo.lo_encrypt_key);
282 +           /* WARNING: xgetpass() can return massive amounts of data,
283 +            * not only 128 bytes like the original getpass(3) */
284 +               pass = xgetpass (pfd,_("Password: "));
285 +               strncpy (loopinfo->lo_encrypt_key, pass, LO_KEY_SIZE);
286 +               loopinfo->lo_encrypt_key[LO_KEY_SIZE - 1] = 0;
287 +               loopinfo->lo_encrypt_key_size = strlen(loopinfo->lo_encrypt_key);
288                 break;
289         case LO_CRYPT_DES:
290 -               pass = getpass (_("Password: "));
291 -               strncpy (loopinfo.lo_encrypt_key, pass, 8);
292 -               loopinfo.lo_encrypt_key[8] = 0;
293 -               loopinfo.lo_encrypt_key_size = 8;
294 +               printf(_("WARNING: Use of DES is depreciated.\n"));
295 +               pass = xgetpass (pfd,_("Password: "));
296 +               strncpy (loopinfo->lo_encrypt_key, pass, 8);
297 +               loopinfo->lo_encrypt_key[8] = 0;
298 +               loopinfo->lo_encrypt_key_size = 8;
299                 pass = getpass (_("Init (up to 16 hex digits): "));
300                 for (i = 0; i < 16 && pass[i]; i++)
301                         if (isxdigit (pass[i])) {
302 -                               loopinfo.lo_init[i >> 3] |= (pass[i] > '9' ?
303 +                               loopinfo->lo_init[i >> 3] |= (pass[i] > '9' ?
304                                   (islower (pass[i]) ? toupper (pass[i]) :
305                                    pass[i])-'A'+10 : pass[i]-'0') << (i&7) * 4;
306                         } else {
307 @@ -266,29 +364,82 @@
308                                 return 1;
309                         }
310                 break;
311 +       case LO_CRYPT_FISH2:
312 +       case LO_CRYPT_BLOW:
313 +       case LO_CRYPT_IDEA:
314 +       case LO_CRYPT_CAST128:
315 +               pass = xgetpass(pfd, _("Password :"));
316 +               strncpy(passwdbuff+1,pass,PASSWDBUFFLEN-1);
317 +               passwdbuff[PASSWDBUFFLEN-1] = '\0';
318 +               passwdbuff[0] = 'A';
319 +               rmd160_hash_buffer(keybits,pass,strlen(pass));
320 +               rmd160_hash_buffer(keybits+HASHLENGTH,passwdbuff,strlen(pass)+1);
321 +               memcpy((char*)loopinfo->lo_encrypt_key,keybits,2*HASHLENGTH);
322 +               keylength=0;
323 +               for(i=0; crypt_type_tbl[i].id != -1; i++){
324 +                        if(loopinfo->lo_encrypt_type == crypt_type_tbl[i].id){
325 +                                keylength = crypt_type_tbl[i].keylength;
326 +                                break;
327 +                        }
328 +               }
329 +               loopinfo->lo_encrypt_key_size=keylength;
330 +               break;
331 +       case LO_CRYPT_CRYPTOAPI:
332 +               /* Give the kernel an opportunity to load the cipher */
333 +               (void) ioctl (fd, LOOP_SET_STATUS, loopinfo);
334 +               if (get_cipher_info(loopinfo->lo_name, &info) < 0) {
335 +                       return 1;
336 +               }
337 +               if (keysz > 0 &&
338 +                   !((1 << ((keysz / 8) - 1)) & info.keysize_mask)) {
339 +                       error("The specified keysize is not supported by "
340 +                             "the selected cipher");
341 +                       keysz = 0;
342 +               }
343 +
344 +               while (keysz <= 0 ||
345 +                      !((1 << ((keysz / 8) - 1)) & info.keysize_mask)) {
346 +                       int i = 0;
347 +                       int available = 0;
348 +                       char keysize[200];
349 +                       printf("Available keysizes (bits): ");
350 +                       for (; i < 32; i++) {
351 +                               if (info.keysize_mask & (1 << i)) {
352 +                                       printf("%d ", 8*(i+1));
353 +                                       available = 1;
354 +                               }
355 +                       }
356 +                       if (!available) {
357 +                               printf("none");
358 +                       }
359 +                       printf("\nKeysize: ");
360 +                       fgets(keysize, sizeof(keysize), stdin);
361 +                       keysz = atoi(keysize);
362 +               }
363 +
364 +               pass = xgetpass(pfd, _("Password :"));
365 +               strncpy(passwdbuff+1,pass,PASSWDBUFFLEN-1);
366 +               passwdbuff[PASSWDBUFFLEN-1] = '\0';
367 +               passwdbuff[0] = 'A';
368 +               rmd160_hash_buffer(keybits,pass,strlen(pass));
369 +               rmd160_hash_buffer(keybits+HASHLENGTH,passwdbuff,strlen(pass)+1);
370 +               memcpy((char*)loopinfo->lo_encrypt_key,keybits,2*HASHLENGTH);
371 +
372 +               loopinfo->lo_encrypt_key_size=keysz/8;
373 +
374 +               break;
375         default:
376                 fprintf (stderr,
377                          _("Don't know how to get key for encryption system %d\n"),
378 -                        loopinfo.lo_encrypt_type);
379 -               return 1;
380 -       }
381 -       if (ioctl (fd, LOOP_SET_FD, ffd) < 0) {
382 -               perror ("ioctl: LOOP_SET_FD");
383 +                        loopinfo->lo_encrypt_type);
384                 return 1;
385         }
386 -       if (ioctl (fd, LOOP_SET_STATUS, &loopinfo) < 0) {
387 -               (void) ioctl (fd, LOOP_CLR_FD, 0);
388 -               perror ("ioctl: LOOP_SET_STATUS");
389 -               return 1;
390 -       }
391 -       close (fd);
392 -       close (ffd);
393 -       if (verbose > 1)
394 -               printf(_("set_loop(%s,%s,%d): success\n"),
395 -                      device, file, offset);
396 -       return 0;
397 +        return 0;
398  }
399  
400 +
401 +
402 +
403  int 
404  del_loop (const char *device) {
405         int fd;
406 @@ -319,7 +470,7 @@
407  
408  int
409  set_loop (const char *device, const char *file, int offset,
410 -         const char *encryption, int *loopro) {
411 +         const char *encryption, int pfd, int *loopro) {
412         mutter();
413         return 1;
414  }
415 @@ -348,13 +499,40 @@
416  int verbose = 0;
417  static char *progname;
418  
419 +static struct option longopts[] = {
420 +       { "delete", 0, 0, 'd' },
421 +       { "detach", 0, 0, 'd' },
422 +       { "encryption", 1, 0, 'e' },
423 +       { "help", 0, 0, 'h' },
424 +       { "offset", 1, 0, 'o' },
425 +       { "pass-fd", 1, 0, 'p' },
426 +       { "verbose", 0, 0, 'v' },
427 +       { "keybits", 1, 0, 'k' },
428 +       { NULL, 0, 0, 0 }
429 +};
430 +
431 +
432  static void
433  usage(void) {
434         fprintf(stderr, _("usage:\n\
435    %s loop_device                                      # give info\n\
436    %s -d loop_device                                   # delete\n\
437 -  %s [ -e encryption ] [ -o offset ] loop_device file # setup\n"),
438 -               progname, progname, progname);
439 +  %s [ options ] loop_device file                     # setup\n\
440 +    where options include\n\
441 +    --offset <num>, -o <num>\n\
442 +        start at offset <num> into file.\n\
443 +    --pass-fd <num>, -p <num>\n\
444 +        read passphrase from file descriptor <num>\n\
445 +        instead of the terminal.\n\
446 +    --encryption <cipher>, -e <cipher>\n\
447 +        encrypt with <cipher>.\n\
448 +        Check /proc/cipher for available ciphers.\n\
449 +    --keybits <num>, -k <num>\n\
450 +        specify number of bits in the hashed key given\n\
451 +        to the cipher.  Some ciphers support several key\n\
452 +        sizes and might be more efficient with a smaller\n\
453 +        key size.  Key sizes < 128 are generally not\n\
454 +        recommended\n"), progname, progname, progname);
455         exit(1);
456  }
457  
458 @@ -387,19 +565,22 @@
459  
460  int
461  main(int argc, char **argv) {
462 -       char *offset, *encryption;
463 +       char *offset, *encryption, *passfd, *keysize;
464         int delete,off,c;
465 +       int pfd = -1; 
466         int res = 0;
467         int ro = 0;
468 +       int keysz = 0;
469  
470         setlocale(LC_ALL, "");
471         bindtextdomain(PACKAGE, LOCALEDIR);
472         textdomain(PACKAGE);
473  
474         delete = off = 0;
475 -       offset = encryption = NULL;
476 +       offset = encryption = passfd = keysize = NULL;
477         progname = argv[0];
478 -       while ((c = getopt(argc,argv,"de:o:v")) != EOF) {
479 +       while ((c = getopt_long(argc,argv,"de:hk:o:p:v",
480 +                               longopts, NULL)) != EOF) {
481                 switch (c) {
482                 case 'd':
483                         delete = 1;
484 @@ -407,9 +588,15 @@
485                 case 'e':
486                         encryption = optarg;
487                         break;
488 +               case 'k':
489 +                       keysize = optarg;
490 +                       break;
491                 case 'o':
492                         offset = optarg;
493                         break;
494 +               case 'p':
495 +                       passfd = optarg;
496 +                       break;
497                 case 'v':
498                         verbose = 1;
499                         break;
500 @@ -418,7 +605,7 @@
501                 }
502         }
503         if (argc == 1) usage();
504 -       if ((delete && (argc != optind+1 || encryption || offset)) ||
505 +       if ((delete && (argc != optind+1 || encryption || offset || passfd)) ||
506             (!delete && (argc < optind+1 || argc > optind+2)))
507                 usage();
508         if (argc == optind+1) {
509 @@ -429,7 +616,12 @@
510         } else {
511                 if (offset && sscanf(offset,"%d",&off) != 1)
512                         usage();
513 -               res = set_loop(argv[optind],argv[optind+1],off,encryption,&ro);
514 +               if (passfd && sscanf(passfd,"%d",&pfd) != 1)
515 +                       usage();
516 +               if (keysize && sscanf(keysize,"%d",&keysz) != 1)
517 +                       usage();
518 +               res = set_loop(argv[optind], argv[optind+1], off,
519 +                              encryption, pfd, keysz, &ro);
520         }
521         return res;
522  }
523 @@ -445,3 +637,61 @@
524  }
525  #endif
526  #endif
527 +
528 +static int get_cipher_info(const char *name, struct cipher_info *res)
529 +{
530 +       char path[PATH_MAX];
531 +       char buf[2000];
532 +       FILE *f;
533 +       struct {
534 +               int *out;
535 +               const char *prefix;
536 +       } fields[] = {{&res->blocksize, "blocksize:"},
537 +                     {&res->keysize_mask, "keysize_mask:"},
538 +                     {&res->ivsize, "ivsize:"},
539 +                     {&res->key_schedule_size, "key_schedule_size:"}};
540 +       snprintf(path, sizeof(path), "/proc/crypto/cipher/%s", name);
541 +       f = fopen(path, "r");
542 +       while(f && fgets(buf, sizeof(buf), f)) {
543 +               int i;
544 +               for (i = 0; i < sizeof(fields)/sizeof(fields[0]); i++) {
545 +                       int len = strlen(fields[i].prefix);
546 +                       if (strncmp(buf, fields[i].prefix, len) == 0) {
547 +                               *fields[i].out = strtoul(&buf[len+1], NULL, 0);
548 +                               break;
549 +                       }
550 +               }
551 +               
552 +       }
553 +       if (!f) 
554 +               return -1;
555 +       return 0;
556 +}
557 +
558 +
559 +static int 
560 +name_to_id(const char *name) 
561 +{
562 +       int i;
563 +
564 +       if (name) {
565 +               for (i = 0; crypt_type_tbl[i].id != -1; i++)
566 +                       if (!strcasecmp (name, crypt_type_tbl[i].name))
567 +                               return crypt_type_tbl[i].id;
568 +       } else
569 +               return LO_CRYPT_NONE;
570 +       return LO_CRYPT_CRYPTOAPI;
571 +}
572 +
573 +#ifdef MAIN
574 +static char *
575 +id_to_name(int id) {
576 +       int i;
577 +
578 +       for (i = 0; crypt_type_tbl[i].id != -1; i++)
579 +               if (id == crypt_type_tbl[i].id)
580 +                       return crypt_type_tbl[i].name;
581 +       return "undefined";
582 +}
583 +#endif
584 +
585 diff -Nur util-linux-2.11b.orig/mount/lomount.h util-linux-2.11b/mount/lomount.h
586 --- util-linux-2.11b.orig/mount/lomount.h       Fri Dec  8 19:08:02 2000
587 +++ util-linux-2.11b/mount/lomount.h    Wed Mar 28 11:38:53 2001
588 @@ -1,5 +1,6 @@
589  extern int verbose;
590 -extern int set_loop (const char *, const char *, int, const char *, int *);
591 +extern int set_loop (const char *, const char *, int, const char *, 
592 +                     int, int, int *);
593  extern int del_loop (const char *);
594  extern int is_loop_device (const char *);
595  extern char * find_unused_loop_device (void);
596 diff -Nur util-linux-2.11b.orig/mount/losetup.8 util-linux-2.11b/mount/losetup.8
597 --- util-linux-2.11b.orig/mount/losetup.8       Fri Aug 11 13:11:30 2000
598 +++ util-linux-2.11b/mount/losetup.8    Wed Mar 28 11:38:53 2001
599 @@ -10,6 +10,9 @@
600  ] [
601  .B \-o
602  .I offset
603 +] [
604 +.B \-p
605 +.I num
606  ]
607  .I loop_device file
608  .br
609 @@ -26,9 +29,9 @@
610  \fIloop_device\fP argument is given, the status of the corresponding loop
611  device is shown.
612  .SH OPTIONS
613 -.IP \fB\-d\fP
614 +.IP "\fB\-\-delete, \-\-detach, \-d\fP"
615  detach the file or device associated with the specified loop device.
616 -.IP "\fB\-e \fIencryption\fP"
617 +.IP "\fB\-\-encryption, \-e \fIencryption\fP"
618  .RS
619  enable data encryption. The following keywords are recognized:
620  .IP \fBNONE\fP
621 @@ -36,16 +39,62 @@
622  .PD 0
623  .IP \fBXOR\fP
624  use a simple XOR encryption.
625 +.IP \fBAES\fP
626 +use Advanced Encryption Standard encryption. AES encryption is only available 
627 +if you are using the international kernel and AES encryption has been enabled 
628 +in the Crypto API.
629 +enabled in the Crypto API.
630 +.IP \fBBlowfish\fP
631 +use Blowfish encryption. Blowfish encryption is only available if you
632 +are using the international kernel and Blowfish encryption has been
633 +enabled in the Crypto API.
634 +.IP \fBTwofish\fP
635 +use Twofish encryption. Twofish encryption is only available if you
636 +are using the international kernel and Twofish encryption has been
637 +enabled in the Crypto API.
638 +.IP \fBCAST\fP
639 +use CAST encryption. CAST encryption is only available if you
640 +are using the international kernel and CAST encryption has been
641 +enabled in the Crypto API.
642  .IP \fBDES\fP
643  use DES encryption. DES encryption is only available if the optional
644  DES package has been added to the kernel. DES encryption uses an additional
645  start value that is used to protect passwords against dictionary
646 -attacks.
647 +attacks. Use of DES is deprecated.
648 +.IP \fBDFC\fP
649 +use DFC encryption. DFC encryption is only available if you
650 +are using the international kernel and DFC encryption has been
651 +enabled in the Crypto API.
652 +.IP \fBIDEA\fP
653 +use IDEA encryption. IDEA encryption is only available if you
654 +are using the international kernel and IDEA encryption has been
655 +enabled in the Crypto API.
656 +.IP \fBMARS\fP
657 +use MARS encryption. MARS encryption is only available if you
658 +are using the international kernel and MARS encryption has been
659 +enabled in the Crypto API.
660 +.IP \fBRC5\fP
661 +use RC5 encryption. RC5 encryption is only available if you
662 +are using the international kernel and RC5 encryption has been
663 +enabled in the Crypto API.
664 +.IP \fBRC6\fP
665 +use RC6 encryption. RC6 encryption is only available if you
666 +are using the international kernel and RC6 encryption has been
667 +enabled in the Crypto API.
668 +.IP \fBSerpent\fP
669 +use Serpent encryption. Serpent encryption is only available if you
670 +are using the international kernel and Serpent encryption has been
671 +enabled in the Crypto API.
672  .PD
673  .RE
674 -.IP "\fB\-o \fIoffset\fP"
675 +.IP "\fB\-\-offset, \-o \fIoffset\fP"
676  the data start is moved \fIoffset\fP bytes into the specified file or
677  device.
678 +.IP "\fB\-\-pass-fd, \-p \fInum\fP"
679 +read the passphrase from file descriptor \fInum\fP instead of the
680 +terminal.
681 +.IP "\fB\-\-keybits, \-k \fInum\fP"
682 +set the number of bits to use in key to \fInum\fP.
683  .SH RETURN VALUE
684  .B losetup
685  returns 0 on success, nonzero on failure. When
686 @@ -58,6 +107,7 @@
687  .SH FILES
688  .nf
689  /dev/loop0,/dev/loop1,...   loop devices (major=7)
690 +/proc/cipher/*              available ciphers
691  .fi
692  .SH EXAMPLE
693  If you are using the loadable module you must have the module loaded
694 @@ -69,9 +119,8 @@
695  .nf
696  .IP
697  dd if=/dev/zero of=/file bs=1k count=100
698 -losetup -e des /dev/loop0 /file
699 -Password:
700 -Init (up to 16 hex digits):
701 +losetup -e blowfish /dev/loop0 /file
702 +Password :
703  mkfs -t ext2 /dev/loop0 100
704  mount -t ext2 /dev/loop0 /mnt
705   ...
706 @@ -85,8 +134,12 @@
707  # rmmod loop
708  .LP
709  .fi
710 -.SH RESTRICTION
711 -DES encryption is painfully slow. On the other hand, XOR is terribly weak.
712 +.SH RESTRICTIONS
713 +DES encryption is painfully slow. On the other hand, XOR is terribly
714 +weak. Both are insecure nowadays. Some ciphers require a licence for
715 +you to be allowed to use them.
716 +.SH BUGS
717 +CAST, DES, RC5 and Twofish are currently broken and cannot be used.
718  .SH AUTHORS
719  .nf
720  Original version: Theodore Ts'o <tytso@athena.mit.edu>
721 diff -Nur util-linux-2.11b.orig/mount/mount.8 util-linux-2.11b/mount/mount.8
722 --- util-linux-2.11b.orig/mount/mount.8 Mon Mar 19 22:21:28 2001
723 +++ util-linux-2.11b/mount/mount.8      Wed Mar 28 11:38:53 2001
724 @@ -252,6 +252,12 @@
725  .B \-v
726  Verbose mode.
727  .TP
728 +.B \-p "\fInum\fP"
729 +If the mount requires a passphrase to be entered, read it from file
730 +descriptor
731 +.IR num\fP
732 +instead of from the terminal.
733 +.TP
734  .B \-a
735  Mount all filesystems (of the given types) mentioned in
736  .IR fstab .
737 @@ -517,6 +523,15 @@
738  .BR noexec ", " nosuid ", and " nodev
739  (unless overridden by subsequent options, as in the option line
740  .BR users,exec,dev,suid ).
741 +.TP
742 +.B encryption
743 +Specifies an encryption algorithm to use.  Used in conjunction with the
744 +.BR loop " option."
745 +.TP
746 +.B keybits
747 +Specifies the key size to use for an encryption algorithm. Used in conjunction
748 +with the
749 +.BR loop " and " encryption " options."
750  .RE
751  
752  .SH "FILESYSTEM SPECIFIC MOUNT OPTIONS"
753 @@ -1349,7 +1364,10 @@
754  .BR loop ", " offset " and " encryption ,
755  that are really options to
756  .BR losetup (8).
757 -If no explicit loop device is mentioned
758 +If the mount requires a passphrase, you will be prompted for one unless
759 +you specify a file descriptor to read from instead with the 
760 +.BR \-\-pass-fd
761 +option. If no explicit loop device is mentioned
762  (but just an option `\fB\-o loop\fP' is given), then
763  .B mount
764  will try to find some unused loop device and use that.
765 diff -Nur util-linux-2.11b.orig/mount/mount.c util-linux-2.11b/mount/mount.c
766 --- util-linux-2.11b.orig/mount/mount.c Thu Mar 15 11:09:59 2001
767 +++ util-linux-2.11b/mount/mount.c      Wed Mar 28 12:10:45 2001
768 @@ -107,6 +107,12 @@
769  /* True if ruid != euid.  */
770  static int suid = 0;
771  
772 +/* Contains the fd no. to read the passphrase from, if any */
773 +static int pfd = -1;
774 +
775 +/* Contains the preferred keysize in bits we want to use */
776 +static int keysz = 0;
777 +
778  /* Map from -o and fstab option strings to the flag argument to mount(2).  */
779  struct opt_map {
780    const char *opt;             /* option name */
781 @@ -568,7 +574,8 @@
782        if (verbose)
783         printf(_("mount: going to use the loop device %s\n"), *loopdev);
784        offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0;
785 -      if (set_loop (*loopdev, *loopfile, offset, opt_encryption, &loopro)) {
786 +      if (set_loop (*loopdev, *loopfile, offset, opt_encryption, pfd, 
787 +                   keysz, &loopro)) {
788         if (verbose)
789           printf(_("mount: failed setting up loop device\n"));
790         return EX_FAIL;
791 @@ -1281,6 +1288,8 @@
792         { "read-write", 0, 0, 'w' },
793         { "rw", 0, 0, 'w' },
794         { "options", 1, 0, 'o' },
795 +       { "pass-fd", 1, 0, 'p' },
796 +       { "keybits", 1, 0, 'k' },
797         { "types", 1, 0, 't' },
798         { "bind", 0, 0, 128 },
799         { "replace", 0, 0, 129 },
800 @@ -1313,7 +1322,7 @@
801           "       mount --bind olddir newdir\n"
802           "A device can be given by name, say /dev/hda1 or /dev/cdrom,\n"
803           "or by label, using  -L label  or by uuid, using  -U uuid .\n"
804 -         "Other options: [-nfFrsvw] [-o options].\n"
805 +         "Other options: [-nfFrsvw] [-o options] [-p num].\n"
806           "For many more details, say  man 8 mount .\n"
807         ));
808  /*
809 @@ -1329,6 +1338,8 @@
810         int c, result = 0, specseen;
811         char *options = NULL, *spec, *node;
812         char *volumelabel = NULL;
813 +       char *passfd = NULL;
814 +       char *keysize = NULL;
815         char *uuid = NULL;
816         string_list types = NULL;
817         struct mntentchn *mc;
818 @@ -1349,7 +1360,7 @@
819         initproctitle(argc, argv);
820  #endif
821  
822 -       while ((c = getopt_long (argc, argv, "afFhlL:no:rsU:vVwt:",
823 +       while ((c = getopt_long (argc, argv, "afFhlL:no:p:rsU:vVwt:",
824                                  longopts, NULL)) != EOF) {
825                 switch (c) {
826                 case 'a':               /* mount everything in fstab */
827 @@ -1364,6 +1375,9 @@
828                 case 'h':               /* help */
829                         usage (stdout, 0);
830                         break;
831 +               case 'k':
832 +                       keysize = optarg;
833 +                       break;
834                 case 'l':
835                         list_with_volumelabel = 1;
836                         break;
837 @@ -1379,6 +1393,9 @@
838                         else
839                                 options = xstrdup(optarg);
840                         break;
841 +               case 'p':               /* read passphrase from given fd */
842 +                       passfd = optarg;
843 +                       break;
844                 case 'r':               /* mount readonly */
845                         readonly = 1;
846                         readwrite = 0;
847 @@ -1466,6 +1483,11 @@
848                         printf(_("mount: mounting %s\n"), spec);
849         } else
850                 spec = NULL;            /* just for gcc */
851 +
852 +       if (passfd && sscanf(passfd,"%d",&pfd) != 1)
853 +               die (EX_USAGE, _("mount: argument to --pass-fd or -p must be a number"));
854 +       if (keysize && sscanf(keysize,"%d",&keysz) != 1)
855 +               die (EX_USAGE, _("mount: argument to --keybits or -k must be a number"));
856  
857         switch (argc+specseen) {
858         case 0:
859 diff -Nur util-linux-2.11b.orig/mount/rmd160.c util-linux-2.11b/mount/rmd160.c
860 --- util-linux-2.11b.orig/mount/rmd160.c        Thu Jan  1 01:00:00 1970
861 +++ util-linux-2.11b/mount/rmd160.c     Wed Mar 28 11:38:53 2001
862 @@ -0,0 +1,532 @@
863 +/* rmd160.c  - RIPE-MD160
864 + *     Copyright (C) 1998 Free Software Foundation, Inc.
865 + */
866 +
867 +/* This file was part of GnuPG. Modified for use within the Linux
868 + * mount utility by Marc Mutz <Marc@Mutz.com>. None of this code is
869 + * by myself. I just removed everything that you don't need when all
870 + * you want to do is to use rmd160_hash_buffer().
871 + * My comments are marked with (mm).  */
872 +
873 +/* GnuPG is free software; you can redistribute it and/or modify
874 + * it under the terms of the GNU General Public License as published by
875 + * the Free Software Foundation; either version 2 of the License, or
876 + * (at your option) any later version.
877 + *
878 + * GnuPG is distributed in the hope that it will be useful,
879 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
880 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
881 + * GNU General Public License for more details.
882 + *
883 + * You should have received a copy of the GNU General Public License
884 + * along with this program; if not, write to the Free Software
885 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */
886 +
887 +#include <string.h> /* (mm) for memcpy */
888 +#include <endian.h> /* (mm) for BIG_ENDIAN and BYTE_ORDER */
889 +#include "rmd160.h"
890 +
891 +/* (mm) these are used by the original GnuPG file. In order to modify
892 + * that file not too much, we keep the notations. maybe it would be
893 + * better to include linux/types.h and typedef __u32 to u32 and __u8
894 + * to byte?  */
895 +typedef unsigned int u32; /* taken from e.g. util-linux's minix.h */
896 +typedef unsigned char byte;
897 +
898 +typedef struct {
899 +    u32  h0,h1,h2,h3,h4;
900 +    u32  nblocks;
901 +    byte buf[64];
902 +    int  count;
903 +} RMD160_CONTEXT;
904 +
905 +/****************
906 + * Rotate a 32 bit integer by n bytes
907 + */
908 +#if defined(__GNUC__) && defined(__i386__)
909 +static inline u32
910 +rol( u32 x, int n)
911 +{
912 +       __asm__("roll %%cl,%0"
913 +               :"=r" (x)
914 +               :"0" (x),"c" (n));
915 +       return x;
916 +}
917 +#else
918 +  #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
919 +#endif
920 +
921 +/*********************************
922 + * RIPEMD-160 is not patented, see (as of 25.10.97)
923 + *   http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
924 + * Note that the code uses Little Endian byteorder, which is good for
925 + * 386 etc, but we must add some conversion when used on a big endian box.
926 + *
927 + *
928 + * Pseudo-code for RIPEMD-160
929 + *
930 + * RIPEMD-160 is an iterative hash function that operates on 32-bit words.
931 + * The round function takes as input a 5-word chaining variable and a 16-word
932 + * message block and maps this to a new chaining variable. All operations are
933 + * defined on 32-bit words. Padding is identical to that of MD4.
934 + *
935 + *
936 + * RIPEMD-160: definitions
937 + *
938 + *
939 + *   nonlinear functions at bit level: exor, mux, -, mux, -
940 + *
941 + *   f(j, x, y, z) = x XOR y XOR z               (0 <= j <= 15)
942 + *   f(j, x, y, z) = (x AND y) OR (NOT(x) AND z)  (16 <= j <= 31)
943 + *   f(j, x, y, z) = (x OR NOT(y)) XOR z         (32 <= j <= 47)
944 + *   f(j, x, y, z) = (x AND z) OR (y AND NOT(z))  (48 <= j <= 63)
945 + *   f(j, x, y, z) = x XOR (y OR NOT(z))         (64 <= j <= 79)
946 + *
947 + *
948 + *   added constants (hexadecimal)
949 + *
950 + *   K(j) = 0x00000000     (0 <= j <= 15)
951 + *   K(j) = 0x5A827999    (16 <= j <= 31)      int(2**30 x sqrt(2))
952 + *   K(j) = 0x6ED9EBA1    (32 <= j <= 47)      int(2**30 x sqrt(3))
953 + *   K(j) = 0x8F1BBCDC    (48 <= j <= 63)      int(2**30 x sqrt(5))
954 + *   K(j) = 0xA953FD4E    (64 <= j <= 79)      int(2**30 x sqrt(7))
955 + *   K'(j) = 0x50A28BE6     (0 <= j <= 15)      int(2**30 x cbrt(2))
956 + *   K'(j) = 0x5C4DD124    (16 <= j <= 31)      int(2**30 x cbrt(3))
957 + *   K'(j) = 0x6D703EF3    (32 <= j <= 47)      int(2**30 x cbrt(5))
958 + *   K'(j) = 0x7A6D76E9    (48 <= j <= 63)      int(2**30 x cbrt(7))
959 + *   K'(j) = 0x00000000    (64 <= j <= 79)
960 + *
961 + *
962 + *   selection of message word
963 + *
964 + *   r(j)      = j                   (0 <= j <= 15)
965 + *   r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
966 + *   r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
967 + *   r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
968 + *   r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
969 + *   r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
970 + *   r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
971 + *   r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
972 + *   r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
973 + *   r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
974 + *
975 + *
976 + *   amount for rotate left (rol)
977 + *
978 + *   s(0..15)  = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
979 + *   s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
980 + *   s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
981 + *   s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
982 + *   s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
983 + *   s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
984 + *   s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
985 + *   s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
986 + *   s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
987 + *   s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
988 + *
989 + *
990 + *   initial value (hexadecimal)
991 + *
992 + *   h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476;
993 + *                                                     h4 = 0xC3D2E1F0;
994 + *
995 + *
996 + * RIPEMD-160: pseudo-code
997 + *
998 + *   It is assumed that the message after padding consists of t 16-word blocks
999 + *   that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15.
1000 + *   The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left
1001 + *   shift (rotate) over s positions.
1002 + *
1003 + *
1004 + *   for i := 0 to t-1 {
1005 + *      A := h0; B := h1; C := h2; D = h3; E = h4;
1006 + *      A' := h0; B' := h1; C' := h2; D' = h3; E' = h4;
1007 + *      for j := 0 to 79 {
1008 + *          T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E;
1009 + *          A := E; E := D; D := rol_10(C); C := B; B := T;
1010 + *          T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)]
1011 +                                                      [+] K'(j)) [+] E';
1012 + *          A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T;
1013 + *      }
1014 + *      T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A';
1015 + *      h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T;
1016 + *   }
1017 + */
1018 +
1019 +/* Some examples:
1020 + * ""                    9c1185a5c5e9fc54612808977ee8f548b2258d31
1021 + * "a"                   0bdc9d2d256b3ee9daae347be6f4dc835a467ffe
1022 + * "abc"                 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
1023 + * "message digest"      5d0689ef49d2fae572b881b123a85ffa21595f36
1024 + * "a...z"               f71c27109c692c1b56bbdceb5b9d2865b3708dbc
1025 + * "abcdbcde...nopq"     12a053384a9c0c88e405a06c27dcf49ada62eb2b
1026 + * "A...Za...z0...9"     b0e20b6e3116640286ed3a87a5713079b21f5189
1027 + * 8 times "1234567890"  9b752e45573d4b39f4dbd3323cab82bf63326bfb
1028 + * 1 million times "a"   52783243c1697bdbe16d37f97f68f08325dc1528
1029 + */
1030 +
1031 +
1032 +static void
1033 +rmd160_init( RMD160_CONTEXT *hd )
1034 +{
1035 +    hd->h0 = 0x67452301;
1036 +    hd->h1 = 0xEFCDAB89;
1037 +    hd->h2 = 0x98BADCFE;
1038 +    hd->h3 = 0x10325476;
1039 +    hd->h4 = 0xC3D2E1F0;
1040 +    hd->nblocks = 0;
1041 +    hd->count = 0;
1042 +}
1043 +
1044 +
1045 +
1046 +/****************
1047 + * Transform the message X which consists of 16 32-bit-words
1048 + */
1049 +static void
1050 +transform( RMD160_CONTEXT *hd, byte *data )
1051 +{
1052 +    u32 a,b,c,d,e,aa,bb,cc,dd,ee,t;
1053 +  #if BYTE_ORDER == BIG_ENDIAN
1054 +    u32 x[16];
1055 +    { int i;
1056 +      byte *p2, *p1;
1057 +      for(i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 ) {
1058 +       p2[3] = *p1++;
1059 +       p2[2] = *p1++;
1060 +       p2[1] = *p1++;
1061 +       p2[0] = *p1++;
1062 +      }
1063 +    }
1064 +  #else
1065 +   #if 0
1066 +    u32 *x =(u32*)data;
1067 +   #else
1068 +    /* this version is better because it is always aligned;
1069 +     * The performance penalty on a 586-100 is about 6% which
1070 +     * is acceptable - because the data is more local it might
1071 +     * also be possible that this is faster on some machines.
1072 +     * This function (when compiled with -02 on gcc 2.7.2)
1073 +     * executes on a 586-100 (39.73 bogomips) at about 1900kb/sec;
1074 +     * [measured with a 4MB data and "gpgm --print-md rmd160"] */
1075 +    u32 x[16];
1076 +    memcpy( x, data, 64 );
1077 +   #endif
1078 +  #endif
1079 +
1080 +
1081 +#define K0  0x00000000
1082 +#define K1  0x5A827999
1083 +#define K2  0x6ED9EBA1
1084 +#define K3  0x8F1BBCDC
1085 +#define K4  0xA953FD4E
1086 +#define KK0 0x50A28BE6
1087 +#define KK1 0x5C4DD124
1088 +#define KK2 0x6D703EF3
1089 +#define KK3 0x7A6D76E9
1090 +#define KK4 0x00000000
1091 +#define F0(x,y,z)   ( (x) ^ (y) ^ (z) )
1092 +#define F1(x,y,z)   ( ((x) & (y)) | (~(x) & (z)) )
1093 +#define F2(x,y,z)   ( ((x) | ~(y)) ^ (z) )
1094 +#define F3(x,y,z)   ( ((x) & (z)) | ((y) & ~(z)) )
1095 +#define F4(x,y,z)   ( (x) ^ ((y) | ~(z)) )
1096 +#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \
1097 +                                 a = rol(t,s) + e;            \
1098 +                                 c = rol(c,10);               \
1099 +                               } while(0)
1100 +
1101 +    /* left lane */
1102 +    a = hd->h0;
1103 +    b = hd->h1;
1104 +    c = hd->h2;
1105 +    d = hd->h3;
1106 +    e = hd->h4;
1107 +    R( a, b, c, d, e, F0, K0,  0, 11 );
1108 +    R( e, a, b, c, d, F0, K0,  1, 14 );
1109 +    R( d, e, a, b, c, F0, K0,  2, 15 );
1110 +    R( c, d, e, a, b, F0, K0,  3, 12 );
1111 +    R( b, c, d, e, a, F0, K0,  4,  5 );
1112 +    R( a, b, c, d, e, F0, K0,  5,  8 );
1113 +    R( e, a, b, c, d, F0, K0,  6,  7 );
1114 +    R( d, e, a, b, c, F0, K0,  7,  9 );
1115 +    R( c, d, e, a, b, F0, K0,  8, 11 );
1116 +    R( b, c, d, e, a, F0, K0,  9, 13 );
1117 +    R( a, b, c, d, e, F0, K0, 10, 14 );
1118 +    R( e, a, b, c, d, F0, K0, 11, 15 );
1119 +    R( d, e, a, b, c, F0, K0, 12,  6 );
1120 +    R( c, d, e, a, b, F0, K0, 13,  7 );
1121 +    R( b, c, d, e, a, F0, K0, 14,  9 );
1122 +    R( a, b, c, d, e, F0, K0, 15,  8 );
1123 +    R( e, a, b, c, d, F1, K1,  7,  7 );
1124 +    R( d, e, a, b, c, F1, K1,  4,  6 );
1125 +    R( c, d, e, a, b, F1, K1, 13,  8 );
1126 +    R( b, c, d, e, a, F1, K1,  1, 13 );
1127 +    R( a, b, c, d, e, F1, K1, 10, 11 );
1128 +    R( e, a, b, c, d, F1, K1,  6,  9 );
1129 +    R( d, e, a, b, c, F1, K1, 15,  7 );
1130 +    R( c, d, e, a, b, F1, K1,  3, 15 );
1131 +    R( b, c, d, e, a, F1, K1, 12,  7 );
1132 +    R( a, b, c, d, e, F1, K1,  0, 12 );
1133 +    R( e, a, b, c, d, F1, K1,  9, 15 );
1134 +    R( d, e, a, b, c, F1, K1,  5,  9 );
1135 +    R( c, d, e, a, b, F1, K1,  2, 11 );
1136 +    R( b, c, d, e, a, F1, K1, 14,  7 );
1137 +    R( a, b, c, d, e, F1, K1, 11, 13 );
1138 +    R( e, a, b, c, d, F1, K1,  8, 12 );
1139 +    R( d, e, a, b, c, F2, K2,  3, 11 );
1140 +    R( c, d, e, a, b, F2, K2, 10, 13 );
1141 +    R( b, c, d, e, a, F2, K2, 14,  6 );
1142 +    R( a, b, c, d, e, F2, K2,  4,  7 );
1143 +    R( e, a, b, c, d, F2, K2,  9, 14 );
1144 +    R( d, e, a, b, c, F2, K2, 15,  9 );
1145 +    R( c, d, e, a, b, F2, K2,  8, 13 );
1146 +    R( b, c, d, e, a, F2, K2,  1, 15 );
1147 +    R( a, b, c, d, e, F2, K2,  2, 14 );
1148 +    R( e, a, b, c, d, F2, K2,  7,  8 );
1149 +    R( d, e, a, b, c, F2, K2,  0, 13 );
1150 +    R( c, d, e, a, b, F2, K2,  6,  6 );
1151 +    R( b, c, d, e, a, F2, K2, 13,  5 );
1152 +    R( a, b, c, d, e, F2, K2, 11, 12 );
1153 +    R( e, a, b, c, d, F2, K2,  5,  7 );
1154 +    R( d, e, a, b, c, F2, K2, 12,  5 );
1155 +    R( c, d, e, a, b, F3, K3,  1, 11 );
1156 +    R( b, c, d, e, a, F3, K3,  9, 12 );
1157 +    R( a, b, c, d, e, F3, K3, 11, 14 );
1158 +    R( e, a, b, c, d, F3, K3, 10, 15 );
1159 +    R( d, e, a, b, c, F3, K3,  0, 14 );
1160 +    R( c, d, e, a, b, F3, K3,  8, 15 );
1161 +    R( b, c, d, e, a, F3, K3, 12,  9 );
1162 +    R( a, b, c, d, e, F3, K3,  4,  8 );
1163 +    R( e, a, b, c, d, F3, K3, 13,  9 );
1164 +    R( d, e, a, b, c, F3, K3,  3, 14 );
1165 +    R( c, d, e, a, b, F3, K3,  7,  5 );
1166 +    R( b, c, d, e, a, F3, K3, 15,  6 );
1167 +    R( a, b, c, d, e, F3, K3, 14,  8 );
1168 +    R( e, a, b, c, d, F3, K3,  5,  6 );
1169 +    R( d, e, a, b, c, F3, K3,  6,  5 );
1170 +    R( c, d, e, a, b, F3, K3,  2, 12 );
1171 +    R( b, c, d, e, a, F4, K4,  4,  9 );
1172 +    R( a, b, c, d, e, F4, K4,  0, 15 );
1173 +    R( e, a, b, c, d, F4, K4,  5,  5 );
1174 +    R( d, e, a, b, c, F4, K4,  9, 11 );
1175 +    R( c, d, e, a, b, F4, K4,  7,  6 );
1176 +    R( b, c, d, e, a, F4, K4, 12,  8 );
1177 +    R( a, b, c, d, e, F4, K4,  2, 13 );
1178 +    R( e, a, b, c, d, F4, K4, 10, 12 );
1179 +    R( d, e, a, b, c, F4, K4, 14,  5 );
1180 +    R( c, d, e, a, b, F4, K4,  1, 12 );
1181 +    R( b, c, d, e, a, F4, K4,  3, 13 );
1182 +    R( a, b, c, d, e, F4, K4,  8, 14 );
1183 +    R( e, a, b, c, d, F4, K4, 11, 11 );
1184 +    R( d, e, a, b, c, F4, K4,  6,  8 );
1185 +    R( c, d, e, a, b, F4, K4, 15,  5 );
1186 +    R( b, c, d, e, a, F4, K4, 13,  6 );
1187 +
1188 +    aa = a; bb = b; cc = c; dd = d; ee = e;
1189 +
1190 +    /* right lane */
1191 +    a = hd->h0;
1192 +    b = hd->h1;
1193 +    c = hd->h2;
1194 +    d = hd->h3;
1195 +    e = hd->h4;
1196 +    R( a, b, c, d, e, F4, KK0, 5,  8);
1197 +    R( e, a, b, c, d, F4, KK0, 14,  9);
1198 +    R( d, e, a, b, c, F4, KK0, 7,  9);
1199 +    R( c, d, e, a, b, F4, KK0, 0, 11);
1200 +    R( b, c, d, e, a, F4, KK0, 9, 13);
1201 +    R( a, b, c, d, e, F4, KK0, 2, 15);
1202 +    R( e, a, b, c, d, F4, KK0, 11, 15);
1203 +    R( d, e, a, b, c, F4, KK0, 4,  5);
1204 +    R( c, d, e, a, b, F4, KK0, 13,  7);
1205 +    R( b, c, d, e, a, F4, KK0, 6,  7);
1206 +    R( a, b, c, d, e, F4, KK0, 15,  8);
1207 +    R( e, a, b, c, d, F4, KK0, 8, 11);
1208 +    R( d, e, a, b, c, F4, KK0, 1, 14);
1209 +    R( c, d, e, a, b, F4, KK0, 10, 14);
1210 +    R( b, c, d, e, a, F4, KK0, 3, 12);
1211 +    R( a, b, c, d, e, F4, KK0, 12,  6);
1212 +    R( e, a, b, c, d, F3, KK1, 6,  9);
1213 +    R( d, e, a, b, c, F3, KK1, 11, 13);
1214 +    R( c, d, e, a, b, F3, KK1, 3, 15);
1215 +    R( b, c, d, e, a, F3, KK1, 7,  7);
1216 +    R( a, b, c, d, e, F3, KK1, 0, 12);
1217 +    R( e, a, b, c, d, F3, KK1, 13,  8);
1218 +    R( d, e, a, b, c, F3, KK1, 5,  9);
1219 +    R( c, d, e, a, b, F3, KK1, 10, 11);
1220 +    R( b, c, d, e, a, F3, KK1, 14,  7);
1221 +    R( a, b, c, d, e, F3, KK1, 15,  7);
1222 +    R( e, a, b, c, d, F3, KK1, 8, 12);
1223 +    R( d, e, a, b, c, F3, KK1, 12,  7);
1224 +    R( c, d, e, a, b, F3, KK1, 4,  6);
1225 +    R( b, c, d, e, a, F3, KK1, 9, 15);
1226 +    R( a, b, c, d, e, F3, KK1, 1, 13);
1227 +    R( e, a, b, c, d, F3, KK1, 2, 11);
1228 +    R( d, e, a, b, c, F2, KK2, 15,  9);
1229 +    R( c, d, e, a, b, F2, KK2, 5,  7);
1230 +    R( b, c, d, e, a, F2, KK2, 1, 15);
1231 +    R( a, b, c, d, e, F2, KK2, 3, 11);
1232 +    R( e, a, b, c, d, F2, KK2, 7,  8);
1233 +    R( d, e, a, b, c, F2, KK2, 14,  6);
1234 +    R( c, d, e, a, b, F2, KK2, 6,  6);
1235 +    R( b, c, d, e, a, F2, KK2, 9, 14);
1236 +    R( a, b, c, d, e, F2, KK2, 11, 12);
1237 +    R( e, a, b, c, d, F2, KK2, 8, 13);
1238 +    R( d, e, a, b, c, F2, KK2, 12,  5);
1239 +    R( c, d, e, a, b, F2, KK2, 2, 14);
1240 +    R( b, c, d, e, a, F2, KK2, 10, 13);
1241 +    R( a, b, c, d, e, F2, KK2, 0, 13);
1242 +    R( e, a, b, c, d, F2, KK2, 4,  7);
1243 +    R( d, e, a, b, c, F2, KK2, 13,  5);
1244 +    R( c, d, e, a, b, F1, KK3, 8, 15);
1245 +    R( b, c, d, e, a, F1, KK3, 6,  5);
1246 +    R( a, b, c, d, e, F1, KK3, 4,  8);
1247 +    R( e, a, b, c, d, F1, KK3, 1, 11);
1248 +    R( d, e, a, b, c, F1, KK3, 3, 14);
1249 +    R( c, d, e, a, b, F1, KK3, 11, 14);
1250 +    R( b, c, d, e, a, F1, KK3, 15,  6);
1251 +    R( a, b, c, d, e, F1, KK3, 0, 14);
1252 +    R( e, a, b, c, d, F1, KK3, 5,  6);
1253 +    R( d, e, a, b, c, F1, KK3, 12,  9);
1254 +    R( c, d, e, a, b, F1, KK3, 2, 12);
1255 +    R( b, c, d, e, a, F1, KK3, 13,  9);
1256 +    R( a, b, c, d, e, F1, KK3, 9, 12);
1257 +    R( e, a, b, c, d, F1, KK3, 7,  5);
1258 +    R( d, e, a, b, c, F1, KK3, 10, 15);
1259 +    R( c, d, e, a, b, F1, KK3, 14,  8);
1260 +    R( b, c, d, e, a, F0, KK4, 12,  8);
1261 +    R( a, b, c, d, e, F0, KK4, 15,  5);
1262 +    R( e, a, b, c, d, F0, KK4, 10, 12);
1263 +    R( d, e, a, b, c, F0, KK4, 4,  9);
1264 +    R( c, d, e, a, b, F0, KK4, 1, 12);
1265 +    R( b, c, d, e, a, F0, KK4, 5,  5);
1266 +    R( a, b, c, d, e, F0, KK4, 8, 14);
1267 +    R( e, a, b, c, d, F0, KK4, 7,  6);
1268 +    R( d, e, a, b, c, F0, KK4, 6,  8);
1269 +    R( c, d, e, a, b, F0, KK4, 2, 13);
1270 +    R( b, c, d, e, a, F0, KK4, 13,  6);
1271 +    R( a, b, c, d, e, F0, KK4, 14,  5);
1272 +    R( e, a, b, c, d, F0, KK4, 0, 15);
1273 +    R( d, e, a, b, c, F0, KK4, 3, 13);
1274 +    R( c, d, e, a, b, F0, KK4, 9, 11);
1275 +    R( b, c, d, e, a, F0, KK4, 11, 11);
1276 +
1277 +
1278 +    t     = hd->h1 + d + cc;
1279 +    hd->h1 = hd->h2 + e + dd;
1280 +    hd->h2 = hd->h3 + a + ee;
1281 +    hd->h3 = hd->h4 + b + aa;
1282 +    hd->h4 = hd->h0 + c + bb;
1283 +    hd->h0 = t;
1284 +}
1285 +
1286 +
1287 +/* Update the message digest with the contents
1288 + * of INBUF with length INLEN.
1289 + */
1290 +static void
1291 +rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen)
1292 +{
1293 +    if( hd->count == 64 ) { /* flush the buffer */
1294 +       transform( hd, hd->buf );
1295 +       hd->count = 0;
1296 +       hd->nblocks++;
1297 +    }
1298 +    if( !inbuf )
1299 +       return;
1300 +    if( hd->count ) {
1301 +       for( ; inlen && hd->count < 64; inlen-- )
1302 +           hd->buf[hd->count++] = *inbuf++;
1303 +       rmd160_write( hd, NULL, 0 );
1304 +       if( !inlen )
1305 +           return;
1306 +    }
1307 +
1308 +    while( inlen >= 64 ) {
1309 +       transform( hd, inbuf );
1310 +       hd->count = 0;
1311 +       hd->nblocks++;
1312 +       inlen -= 64;
1313 +       inbuf += 64;
1314 +    }
1315 +    for( ; inlen && hd->count < 64; inlen-- )
1316 +       hd->buf[hd->count++] = *inbuf++;
1317 +}
1318 +
1319 +/* The routine terminates the computation
1320 + */
1321 +
1322 +static void
1323 +rmd160_final( RMD160_CONTEXT *hd )
1324 +{
1325 +    u32 t, msb, lsb;
1326 +    byte *p;
1327 +
1328 +    rmd160_write(hd, NULL, 0); /* flush */;
1329 +
1330 +    msb = 0;
1331 +    t = hd->nblocks;
1332 +    if( (lsb = t << 6) < t ) /* multiply by 64 to make a byte count */
1333 +       msb++;
1334 +    msb += t >> 26;
1335 +    t = lsb;
1336 +    if( (lsb = t + hd->count) < t ) /* add the count */
1337 +       msb++;
1338 +    t = lsb;
1339 +    if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
1340 +       msb++;
1341 +    msb += t >> 29;
1342 +
1343 +    if( hd->count < 56 ) { /* enough room */
1344 +       hd->buf[hd->count++] = 0x80; /* pad */
1345 +       while( hd->count < 56 )
1346 +           hd->buf[hd->count++] = 0;  /* pad */
1347 +    }
1348 +    else { /* need one extra block */
1349 +       hd->buf[hd->count++] = 0x80; /* pad character */
1350 +       while( hd->count < 64 )
1351 +           hd->buf[hd->count++] = 0;
1352 +       rmd160_write(hd, NULL, 0);  /* flush */;
1353 +       memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
1354 +    }
1355 +    /* append the 64 bit count */
1356 +    hd->buf[56] = lsb     ;
1357 +    hd->buf[57] = lsb >>  8;
1358 +    hd->buf[58] = lsb >> 16;
1359 +    hd->buf[59] = lsb >> 24;
1360 +    hd->buf[60] = msb     ;
1361 +    hd->buf[61] = msb >>  8;
1362 +    hd->buf[62] = msb >> 16;
1363 +    hd->buf[63] = msb >> 24;
1364 +    transform( hd, hd->buf );
1365 +
1366 +    p = hd->buf;
1367 +  #if BYTE_ORDER == BIG_ENDIAN
1368 +    #define X(a) do { *p++ = hd->h##a     ; *p++ = hd->h##a >> 8;      \
1369 +                     *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
1370 +  #else /* little endian */
1371 +    #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
1372 +  #endif
1373 +    X(0);
1374 +    X(1);
1375 +    X(2);
1376 +    X(3);
1377 +    X(4);
1378 +  #undef X
1379 +}
1380 +
1381 +/****************
1382 + * Shortcut functions which puts the hash value of the supplied buffer
1383 + * into outbuf which must have a size of 20 bytes.
1384 + */
1385 +void
1386 +rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length )
1387 +{
1388 +    RMD160_CONTEXT hd;
1389 +
1390 +    rmd160_init( &hd );
1391 +    rmd160_write( &hd, (byte*)buffer, length );
1392 +    rmd160_final( &hd );
1393 +    memcpy( outbuf, hd.buf, 20 );
1394 +}
1395 diff -Nur util-linux-2.11b.orig/mount/rmd160.h util-linux-2.11b/mount/rmd160.h
1396 --- util-linux-2.11b.orig/mount/rmd160.h        Thu Jan  1 01:00:00 1970
1397 +++ util-linux-2.11b/mount/rmd160.h     Wed Mar 28 11:38:53 2001
1398 @@ -0,0 +1,9 @@
1399 +#ifndef RMD160_H
1400 +#define RMD160_H
1401 +
1402 +void
1403 +rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length );
1404 +
1405 +#endif /*RMD160_H*/
1406 +
1407 +
This page took 0.139039 seconds and 3 git commands to generate.