]>
Commit | Line | Data |
---|---|---|
966ca26a JB |
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 user,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 | + |