Marcus Meissner
85504300d7
OBS-URL: https://build.opensuse.org/package/show/Base:System/util-linux?expand=0&rev=18
1556 lines
52 KiB
Diff
1556 lines
52 KiB
Diff
From a062df268df66641ed94d5c0e968e92c67b585e4 Mon Sep 17 00:00:00 2001
|
|
From: Ludwig Nussel <ludwig.nussel@suse.de>
|
|
Date: Thu, 29 Nov 2007 17:46:36 +0100
|
|
Subject: [PATCH] losetup: support password hashing and specifying the key length
|
|
|
|
* add support for password hashing (sha512, sha384, sha256, rmd160).
|
|
* add support for loop-AES style strings like "twofish256" for
|
|
specifying the encryption algorithm and key length.
|
|
|
|
Based on the SUSE patch from Ludwig Nussel <ludwig.nussel@suse.de>,
|
|
this patch adds password hashing for cryptoloop devices. While
|
|
cryptoloop is deprecated, users may still wish to access existing
|
|
volumes.
|
|
|
|
Incompatible change:
|
|
Default is now to hash using sha256, sha384 or sha512 depending
|
|
on key length (16, 24, or 32 bytes). Debian users will need to
|
|
specify "--phash rmd160" to access existing Debian devices.
|
|
Others will need to specify '--phash none'.
|
|
|
|
sha512.c is from loop-AES.
|
|
|
|
Signed-off-by: Ludwig Nussel <ludwig.nussel@suse.de>
|
|
---
|
|
|
|
Makefile.am | 3
|
|
lomount.c | 174 +++++++++++++++++--
|
|
lomount.h | 5
|
|
losetup.8 | 11 +
|
|
mount.8 | 13 +
|
|
mount.c | 21 ++
|
|
rmd160.c | 532 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
rmd160.h | 11 +
|
|
sha512.c | 432 ++++++++++++++++++++++++++++++++++++++++++++++++
|
|
sha512.h | 45 +++++
|
|
10 files changed, 1219 insertions(+), 28 deletions(-)
|
|
|
|
Index: util-linux-ng-2.16/mount/Makefile.am
|
|
===================================================================
|
|
--- util-linux-ng-2.16.orig/mount/Makefile.am
|
|
+++ util-linux-ng-2.16/mount/Makefile.am
|
|
@@ -7,7 +7,8 @@ sbin_PROGRAMS = losetup swapon
|
|
dist_man_MANS = fstab.5 mount.8 swapoff.8 swapon.8 umount.8 losetup.8
|
|
|
|
# generic sources for all programs (mount, umount, losetup)
|
|
-srcs_common = sundries.c xmalloc.c ../lib/canonicalize.c sundries.h xmalloc.h
|
|
+srcs_common = sundries.c xmalloc.c ../lib/canonicalize.c sundries.h xmalloc.h \
|
|
+ rmd160.c sha512.c
|
|
|
|
# generic header for mount and umount
|
|
hdrs_mount = fstab.h mount_mntent.h mount_constants.h \
|
|
Index: util-linux-ng-2.16/mount/lomount.c
|
|
===================================================================
|
|
--- util-linux-ng-2.16.orig/mount/lomount.c
|
|
+++ util-linux-ng-2.16/mount/lomount.c
|
|
@@ -23,6 +23,12 @@
|
|
#include "sundries.h"
|
|
#include "xmalloc.h"
|
|
#include "pathnames.h"
|
|
+#include "rmd160.h"
|
|
+#include "sha512.h"
|
|
+
|
|
+#ifndef MIN
|
|
+#define MIN(a,b) ((a<b)?(a):(b))
|
|
+#endif
|
|
|
|
#define SIZE(a) (sizeof(a)/sizeof(a[0]))
|
|
|
|
@@ -392,12 +398,22 @@ show_loop_fd(int fd, char *device) {
|
|
|
|
if (loopinfo64.lo_encrypt_type ||
|
|
loopinfo64.lo_crypt_name[0]) {
|
|
- char *e = (char *)loopinfo64.lo_crypt_name;
|
|
+ const char *e = (const char*)loopinfo64.lo_crypt_name;
|
|
|
|
if (*e == 0 && loopinfo64.lo_encrypt_type == 1)
|
|
e = "XOR";
|
|
- printf(_(", encryption %s (type %" PRIu32 ")"),
|
|
- e, loopinfo64.lo_encrypt_type);
|
|
+ printf(_(", encryption %s (type %" PRIu32 "), key length %u"),
|
|
+ e, loopinfo64.lo_encrypt_type, loopinfo64.lo_encrypt_key_size);
|
|
+
|
|
+#if 0
|
|
+ if(loopinfo64.lo_encrypt_key_size) {
|
|
+ unsigned i;
|
|
+ printf("\nkey ");
|
|
+ for(i = 0; i < loopinfo64.lo_encrypt_key_size; ++i) {
|
|
+ printf("%hhx",loopinfo64.lo_encrypt_key[i]);
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
}
|
|
printf("\n");
|
|
return 0;
|
|
@@ -646,7 +662,7 @@ xgetpass(int pfd, const char *prompt) {
|
|
}
|
|
|
|
if (pass == NULL)
|
|
- return "";
|
|
+ return NULL;
|
|
|
|
pass[i] = 0;
|
|
return pass;
|
|
@@ -660,6 +676,24 @@ digits_only(const char *s) {
|
|
return 1;
|
|
}
|
|
|
|
+static void phash_none(const unsigned char *key, size_t keylen, unsigned char* buf, size_t buflen)
|
|
+{
|
|
+ memcpy(buf, key, MIN(buflen, keylen));
|
|
+}
|
|
+
|
|
+static void phash_rmd160(const unsigned char *key, size_t keylen, unsigned char* buf, size_t buflen)
|
|
+{
|
|
+ unsigned char tmpbuf[RMD160_HASH_SIZE*2];
|
|
+ unsigned char* tmp = malloc(keylen+1);
|
|
+ tmp[0]='A';
|
|
+ memcpy(tmp+1, key, keylen);
|
|
+ rmd160_hash_buffer(tmpbuf, key, keylen);
|
|
+ rmd160_hash_buffer(tmpbuf + RMD160_HASH_SIZE, tmp, keylen+1);
|
|
+ memset(tmp, 0, keylen+1);
|
|
+ free(tmp);
|
|
+ memcpy(buf, tmpbuf, MIN(buflen, sizeof(tmpbuf)));
|
|
+}
|
|
+
|
|
/*
|
|
* return codes:
|
|
* 0 - success
|
|
@@ -668,10 +702,11 @@ digits_only(const char *s) {
|
|
*/
|
|
int
|
|
set_loop(const char *device, const char *file, unsigned long long offset,
|
|
- unsigned long long sizelimit, const char *encryption, int pfd, int *options) {
|
|
+ unsigned long long sizelimit, const char *encryption, const char *phash,
|
|
+ int pfd, int *options, int keysz) {
|
|
struct loop_info64 loopinfo64;
|
|
int fd, ffd, mode, i;
|
|
- char *pass;
|
|
+ char *pass = NULL;
|
|
char *filename;
|
|
|
|
if (verbose) {
|
|
@@ -709,13 +744,37 @@ set_loop(const char *device, const char
|
|
filename = (char *) file;
|
|
xstrncpy((char *)loopinfo64.lo_file_name, filename, LO_NAME_SIZE);
|
|
|
|
+ loopinfo64.lo_encrypt_key_size = 0;
|
|
+
|
|
if (encryption && *encryption) {
|
|
- if (digits_only(encryption)) {
|
|
+ // a hint for suse users
|
|
+ if(!phash && (!strcmp(encryption, "twofishSL92") || (!strcmp(encryption, "twofish") && !keysz))) {
|
|
+ fprintf(stderr,"Switching to old S.u.S.E. loop_fish2 compatibility mode.\n");
|
|
+ fprintf(stderr, _("Warning: This mode is deprecated, support for it will be removed in the future.\n"));
|
|
+ loopinfo64.lo_encrypt_type = 3; // LO_CRYPT_FISH
|
|
+ } else if (digits_only(encryption)) {
|
|
loopinfo64.lo_encrypt_type = atoi(encryption);
|
|
} else {
|
|
loopinfo64.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
|
|
- snprintf((char *)loopinfo64.lo_crypt_name, LO_NAME_SIZE,
|
|
+ // check for something like twofish256
|
|
+ unsigned len = strlen(encryption);
|
|
+ snprintf((char*)loopinfo64.lo_crypt_name, LO_NAME_SIZE,
|
|
"%s", encryption);
|
|
+ if(len > 3) {
|
|
+ if(isdigit(loopinfo64.lo_crypt_name[len-3])
|
|
+ && isdigit(loopinfo64.lo_crypt_name[len-2])
|
|
+ && isdigit(loopinfo64.lo_crypt_name[len-1])) {
|
|
+ loopinfo64.lo_encrypt_key_size = atoi((char*)&loopinfo64.lo_crypt_name[len-3]) >> 3;
|
|
+ loopinfo64.lo_crypt_name[len-3] = 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if(keysz && loopinfo64.lo_encrypt_key_size && loopinfo64.lo_encrypt_key_size != keysz >> 3) {
|
|
+ fprintf(stderr, _("please either specify '%s%d' or -e '%s' -k '%d'\n"),
|
|
+ loopinfo64.lo_crypt_name, loopinfo64.lo_encrypt_key_size<<3,
|
|
+ loopinfo64.lo_crypt_name, keysz);
|
|
+ return 1;
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -736,20 +795,70 @@ set_loop(const char *device, const char
|
|
}
|
|
#endif
|
|
|
|
- switch (loopinfo64.lo_encrypt_type) {
|
|
- case LO_CRYPT_NONE:
|
|
- loopinfo64.lo_encrypt_key_size = 0;
|
|
- break;
|
|
- case LO_CRYPT_XOR:
|
|
- pass = getpass(_("Password: "));
|
|
- goto gotpass;
|
|
- default:
|
|
- pass = xgetpass(pfd, _("Password: "));
|
|
- gotpass:
|
|
+ if (loopinfo64.lo_encrypt_type != LO_CRYPT_NONE) {
|
|
+ void (*hfunc)(const unsigned char*, size_t, unsigned char*, size_t) = NULL;
|
|
+
|
|
memset(loopinfo64.lo_encrypt_key, 0, LO_KEY_SIZE);
|
|
- xstrncpy((char *)loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
|
|
+
|
|
+ pass = xgetpass(pfd, _("Password: "));
|
|
+ if(!pass)
|
|
+ return 1;
|
|
+
|
|
+ // set default hash functions, loop-AES compatible
|
|
+ if(loopinfo64.lo_encrypt_type == LO_CRYPT_CRYPTOAPI) {
|
|
+ hfunc = sha256_hash_buffer;
|
|
+ if(loopinfo64.lo_encrypt_key_size == 24) hfunc = sha384_hash_buffer;
|
|
+ if(loopinfo64.lo_encrypt_key_size == 32) hfunc = sha512_hash_buffer;
|
|
+ } else if(loopinfo64.lo_encrypt_type == 3 ) { // LO_CRYPT_FISH
|
|
+ if(!strcmp(encryption, "twofishSL92")) {
|
|
+ hfunc = sha512_hash_buffer;
|
|
+ loopinfo64.lo_encrypt_key_size = 32;
|
|
+ } else {
|
|
+ hfunc = phash_rmd160;
|
|
+ loopinfo64.lo_encrypt_key_size = 20;
|
|
+ }
|
|
+ } else {
|
|
+ hfunc = phash_none;
|
|
+ loopinfo64.lo_encrypt_key_size = keysz?keysz>>3:LO_KEY_SIZE;
|
|
+ }
|
|
+
|
|
+ if(!loopinfo64.lo_encrypt_key_size) {
|
|
+ if(!keysz) {
|
|
+ if(verbose)
|
|
+ fprintf(stderr, _("please specify a key length\n"));
|
|
+ return 1;
|
|
+ }
|
|
+ loopinfo64.lo_encrypt_key_size = keysz>>3;
|
|
+ }
|
|
+
|
|
+ if((unsigned)loopinfo64.lo_encrypt_key_size > sizeof(loopinfo64.lo_encrypt_key)) {
|
|
+ fprintf(stderr, _("invalid key length\n"));
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ if (phash) {
|
|
+ if(!strcasecmp(phash, "sha512")) {
|
|
+ hfunc = sha512_hash_buffer;
|
|
+ } else if(!strcasecmp(phash, "sha384")) {
|
|
+ hfunc = sha384_hash_buffer;
|
|
+ } else if(!strcasecmp(phash, "sha256")) {
|
|
+ hfunc = sha256_hash_buffer;
|
|
+ } else if(!strcasecmp(phash, "rmd160")) {
|
|
+ hfunc = phash_rmd160;
|
|
+ } else if(!strcasecmp(phash, "none")) {
|
|
+ hfunc = phash_none;
|
|
+ } else {
|
|
+ fprintf(stderr, _("unsupported hash method '%s'\n"), phash);
|
|
+ return 1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if(hfunc) {
|
|
+ hfunc((unsigned char*)pass, strlen(pass), loopinfo64.lo_encrypt_key, loopinfo64.lo_encrypt_key_size);
|
|
+ }
|
|
+
|
|
+ // zero buffer
|
|
memset(pass, 0, strlen(pass));
|
|
- loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;
|
|
}
|
|
|
|
if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
|
|
@@ -897,7 +1006,13 @@ usage(void) {
|
|
|
|
fprintf(stderr, _("\nOptions:\n"
|
|
" -e | --encryption <type> enable data encryption with specified <name/num>\n"
|
|
+ " -H | --phash <type> hash password using specified algorithm (sha512/sha256/sha384/rmd160/none)\n"
|
|
" -h | --help this help\n"
|
|
+ " -k | --keybits <num> specify number of bits in the hashed key given\n"
|
|
+ " to the cipher. Some ciphers support several key\n"
|
|
+ " sizes and might be more efficient with a smaller\n"
|
|
+ " key size. Key sizes < 128 are generally not\n"
|
|
+ " recommended\n"
|
|
" -o | --offset <num> start at offset <num> into file\n"
|
|
" --sizelimit <num> loop limited to only <num> bytes of the file\n"
|
|
" -p | --pass-fd <num> read passphrase from file descriptor <num>\n"
|
|
@@ -910,11 +1025,14 @@ usage(void) {
|
|
int
|
|
main(int argc, char **argv) {
|
|
char *p, *offset, *sizelimit, *encryption, *passfd, *device, *file, *assoc;
|
|
+ char *keysize;
|
|
+ char *phash = NULL;
|
|
int delete, find, c, all, capacity;
|
|
int res = 0;
|
|
int showdev = 0;
|
|
int ro = 0;
|
|
int pfd = -1;
|
|
+ int keysz = 0;
|
|
unsigned long long off, slimit;
|
|
struct option longopts[] = {
|
|
{ "all", 0, 0, 'a' },
|
|
@@ -923,6 +1041,8 @@ main(int argc, char **argv) {
|
|
{ "encryption", 1, 0, 'e' },
|
|
{ "find", 0, 0, 'f' },
|
|
{ "help", 0, 0, 'h' },
|
|
+ { "keybits", 1, 0, 'k' },
|
|
+ { "phash", 1, 0, 'H' },
|
|
{ "associated", 1, 0, 'j' },
|
|
{ "offset", 1, 0, 'o' },
|
|
{ "sizelimit", 1, 0, 128 },
|
|
@@ -941,12 +1061,13 @@ main(int argc, char **argv) {
|
|
off = 0;
|
|
slimit = 0;
|
|
assoc = offset = sizelimit = encryption = passfd = NULL;
|
|
+ keysize = NULL;
|
|
|
|
progname = argv[0];
|
|
if ((p = strrchr(progname, '/')) != NULL)
|
|
progname = p+1;
|
|
|
|
- while ((c = getopt_long(argc, argv, "acde:E:fhj:o:p:rsv",
|
|
+ while ((c = getopt_long(argc, argv, "ade:E:fhj:k:o:p:rsvH:",
|
|
longopts, NULL)) != -1) {
|
|
switch (c) {
|
|
case 'a':
|
|
@@ -971,6 +1092,12 @@ main(int argc, char **argv) {
|
|
case 'j':
|
|
assoc = optarg;
|
|
break;
|
|
+ case 'k':
|
|
+ keysize = optarg;
|
|
+ break;
|
|
+ case 'H':
|
|
+ phash = optarg;
|
|
+ break;
|
|
case 'o':
|
|
offset = optarg;
|
|
break;
|
|
@@ -1056,8 +1183,11 @@ main(int argc, char **argv) {
|
|
else {
|
|
if (passfd && sscanf(passfd, "%d", &pfd) != 1)
|
|
usage();
|
|
+ if (keysize && sscanf(keysize,"%d",&keysz) != 1)
|
|
+ usage();
|
|
do {
|
|
- res = set_loop(device, file, off, slimit, encryption, pfd, &ro);
|
|
+ res = set_loop(device, file, off, slimit, encryption, phash,
|
|
+ pfd, &ro, keysz);
|
|
if (res == 2 && find) {
|
|
if (verbose)
|
|
printf(_("stolen loop=%s...trying again\n"),
|
|
Index: util-linux-ng-2.16/mount/lomount.h
|
|
===================================================================
|
|
--- util-linux-ng-2.16.orig/mount/lomount.h
|
|
+++ util-linux-ng-2.16/mount/lomount.h
|
|
@@ -1,5 +1,6 @@
|
|
-extern int set_loop(const char *, const char *, unsigned long long, unsigned long long,
|
|
- const char *, int, int *);
|
|
+extern int set_loop(const char * device, const char * file, unsigned long long offset,
|
|
+ unsigned long long, const char *encryption, const char *phash,
|
|
+ int pfd, int *options, int keysz);
|
|
extern int del_loop(const char *);
|
|
extern int is_loop_device(const char *);
|
|
extern int is_loop_autoclear(const char *device);
|
|
Index: util-linux-ng-2.16/mount/losetup.8
|
|
===================================================================
|
|
--- util-linux-ng-2.16.orig/mount/losetup.8
|
|
+++ util-linux-ng-2.16/mount/losetup.8
|
|
@@ -94,9 +94,18 @@ find the first unused loop device. If a
|
|
argument is present, use this device. Otherwise, print its name
|
|
.IP "\fB\-h, \-\-help\fP"
|
|
print help
|
|
+.IP "\fB\-H, \-\-phash \fIhash_type\fP"
|
|
+Specify the password hash function. Valid values are:
|
|
+.BR sha512 (default),
|
|
+.BR sha256 ,
|
|
+.BR sha384 ,
|
|
+.BR rmd160 ,
|
|
+.BR none .
|
|
.IP "\fB\-j, \-\-associated \fIfile\fP"
|
|
show status of all loop devices associated with given
|
|
.I file
|
|
+.IP "\fB\-k, \-\-keybits \fInum\fP"
|
|
+set the number of bits to use in key to \fInum\fP.
|
|
.IP "\fB\-o, \-\-offset \fIoffset\fP"
|
|
the data start is moved \fIoffset\fP bytes into the specified file or
|
|
device
|
|
@@ -167,6 +176,8 @@ the command
|
|
.fi
|
|
.SH RESTRICTION
|
|
DES encryption is painfully slow. On the other hand, XOR is terribly weak.
|
|
+Both are insecure nowadays. Some ciphers may require a licence for you to be
|
|
+allowed to use them.
|
|
|
|
Cryptoloop is deprecated in favor of dm-crypt. For more details see
|
|
.B cryptsetup(8).
|
|
Index: util-linux-ng-2.16/mount/mount.8
|
|
===================================================================
|
|
--- util-linux-ng-2.16.orig/mount/mount.8
|
|
+++ util-linux-ng-2.16/mount/mount.8
|
|
@@ -782,6 +782,15 @@ Every time the inode is modified, the i_
|
|
.B noiversion
|
|
Do not increment the i_version inode field.
|
|
.TP
|
|
+.B encryption
|
|
+Specifies an encryption algorithm to use. Used in conjunction with the
|
|
+.BR loop " option."
|
|
+.TP
|
|
+.B keybits
|
|
+Specifies the key size to use for an encryption algorithm. Used in conjunction
|
|
+with the
|
|
+.BR loop " and " encryption " options."
|
|
+.TP
|
|
.B mand
|
|
Allow mandatory locks on this filesystem. See
|
|
.BR fcntl (2).
|
|
@@ -2390,6 +2399,10 @@ that are really options to
|
|
.BR \%losetup (8).
|
|
(These options can be used in addition to those specific
|
|
to the filesystem type.)
|
|
+If the mount requires a passphrase, you will be prompted for one unless
|
|
+you specify a file descriptor to read from instead with the
|
|
+.BR \-\-pass-fd
|
|
+option.
|
|
|
|
If no explicit loop device is mentioned
|
|
(but just an option `\fB\-o loop\fP' is given), then
|
|
Index: util-linux-ng-2.16/mount/mount.c
|
|
===================================================================
|
|
--- util-linux-ng-2.16.orig/mount/mount.c
|
|
+++ util-linux-ng-2.16/mount/mount.c
|
|
@@ -95,6 +95,9 @@ struct mountargs {
|
|
void *data;
|
|
};
|
|
|
|
+/* Contains the preferred keysize in bits we want to use */
|
|
+static int keysz = 0;
|
|
+
|
|
/* Map from -o and fstab option strings to the flag argument to mount(2). */
|
|
struct opt_map {
|
|
const char *opt; /* option name */
|
|
@@ -200,6 +203,7 @@ static int opt_nofail = 0;
|
|
|
|
static const char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_sizelimit,
|
|
*opt_encryption, *opt_speed, *opt_comment, *opt_uhelper;
|
|
+static const char *opt_keybits, *opt_phash;
|
|
|
|
static int mounted (const char *spec0, const char *node0);
|
|
static int check_special_mountprog(const char *spec, const char *node,
|
|
@@ -215,6 +219,8 @@ static struct string_opt_map {
|
|
{ "offset=", 0, &opt_offset },
|
|
{ "sizelimit=", 0, &opt_sizelimit },
|
|
{ "encryption=", 0, &opt_encryption },
|
|
+ { "phash=", 0, &opt_phash },
|
|
+ { "keybits=", 0, &opt_keybits },
|
|
{ "speed=", 0, &opt_speed },
|
|
{ "comment=", 1, &opt_comment },
|
|
{ "uhelper=", 0, &opt_uhelper },
|
|
@@ -1072,7 +1078,8 @@ loop_check(const char **spec, const char
|
|
*type = opt_vfstype;
|
|
}
|
|
|
|
- *loop = ((*flags & MS_LOOP) || *loopdev || opt_offset || opt_sizelimit || opt_encryption);
|
|
+ *loop = ((*flags & MS_LOOP) || *loopdev || opt_offset || opt_sizelimit ||
|
|
+ opt_encryption || opt_phash || opt_keybits);
|
|
*loopfile = *spec;
|
|
|
|
if (*loop) {
|
|
@@ -1104,7 +1111,7 @@ loop_check(const char **spec, const char
|
|
printf(_("mount: going to use the loop device %s\n"), *loopdev);
|
|
|
|
if ((res = set_loop(*loopdev, *loopfile, offset, sizelimit,
|
|
- opt_encryption, pfd, &loop_opts))) {
|
|
+ opt_encryption, opt_phash, pfd, &loop_opts, keysz))) {
|
|
if (res == 2) {
|
|
/* loop dev has been grabbed by some other process,
|
|
try again, if not given explicitly */
|
|
@@ -1865,6 +1872,7 @@ static struct option longopts[] = {
|
|
{ "options", 1, 0, 'o' },
|
|
{ "test-opts", 1, 0, 'O' },
|
|
{ "pass-fd", 1, 0, 'p' },
|
|
+ { "keybits", 1, 0, 'k' },
|
|
{ "types", 1, 0, 't' },
|
|
{ "bind", 0, 0, 'B' },
|
|
{ "move", 0, 0, 'M' },
|
|
@@ -2026,6 +2034,7 @@ main(int argc, char *argv[]) {
|
|
char *options = NULL, *test_opts = NULL, *node;
|
|
const char *spec = NULL;
|
|
char *label = NULL;
|
|
+ char *keysize = NULL;
|
|
char *uuid = NULL;
|
|
char *types = NULL;
|
|
char *p;
|
|
@@ -2056,7 +2065,7 @@ main(int argc, char *argv[]) {
|
|
initproctitle(argc, argv);
|
|
#endif
|
|
|
|
- while ((c = getopt_long (argc, argv, "aBfFhilL:Mno:O:p:rRsU:vVwt:",
|
|
+ while ((c = getopt_long (argc, argv, "aBfFhik:lL:Mno:O:p:rRsU:vVwt:",
|
|
longopts, NULL)) != -1) {
|
|
switch (c) {
|
|
case 'a': /* mount everything in fstab */
|
|
@@ -2077,6 +2086,9 @@ main(int argc, char *argv[]) {
|
|
case 'i':
|
|
external_allowed = 0;
|
|
break;
|
|
+ case 'k':
|
|
+ keysize = optarg;
|
|
+ break;
|
|
case 'l':
|
|
list_with_volumelabel = 1;
|
|
break;
|
|
@@ -2215,6 +2227,9 @@ main(int argc, char *argv[]) {
|
|
|
|
atexit(unlock_mtab);
|
|
|
|
+ if (keysize && sscanf(keysize,"%d",&keysz) != 1)
|
|
+ die (EX_USAGE, _("mount: argument to --keybits or -k must be a number"));
|
|
+
|
|
switch (argc+specseen) {
|
|
case 0:
|
|
/* mount -a */
|
|
Index: util-linux-ng-2.16/mount/rmd160.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ util-linux-ng-2.16/mount/rmd160.c
|
|
@@ -0,0 +1,532 @@
|
|
+/* rmd160.c - RIPE-MD160
|
|
+ * Copyright (C) 1998 Free Software Foundation, Inc.
|
|
+ */
|
|
+
|
|
+/* This file was part of GnuPG. Modified for use within the Linux
|
|
+ * mount utility by Marc Mutz <Marc@Mutz.com>. None of this code is
|
|
+ * by myself. I just removed everything that you don't need when all
|
|
+ * you want to do is to use rmd160_hash_buffer().
|
|
+ * My comments are marked with (mm). */
|
|
+
|
|
+/* GnuPG is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * GnuPG is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */
|
|
+
|
|
+#include <string.h> /* (mm) for memcpy */
|
|
+#include <endian.h> /* (mm) for BIG_ENDIAN and BYTE_ORDER */
|
|
+#include "rmd160.h"
|
|
+
|
|
+/* (mm) these are used by the original GnuPG file. In order to modify
|
|
+ * that file not too much, we keep the notations. maybe it would be
|
|
+ * better to include linux/types.h and typedef __u32 to u32 and __u8
|
|
+ * to byte? */
|
|
+typedef unsigned int u32; /* taken from e.g. util-linux's minix.h */
|
|
+typedef unsigned char byte;
|
|
+
|
|
+typedef struct {
|
|
+ u32 h0,h1,h2,h3,h4;
|
|
+ u32 nblocks;
|
|
+ byte buf[64];
|
|
+ int count;
|
|
+} RMD160_CONTEXT;
|
|
+
|
|
+/****************
|
|
+ * Rotate a 32 bit integer by n bytes
|
|
+ */
|
|
+#if defined(__GNUC__) && defined(__i386__)
|
|
+static inline u32
|
|
+rol( u32 x, int n)
|
|
+{
|
|
+ __asm__("roll %%cl,%0"
|
|
+ :"=r" (x)
|
|
+ :"0" (x),"c" (n));
|
|
+ return x;
|
|
+}
|
|
+#else
|
|
+ #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
|
|
+#endif
|
|
+
|
|
+/*********************************
|
|
+ * RIPEMD-160 is not patented, see (as of 25.10.97)
|
|
+ * http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
|
|
+ * Note that the code uses Little Endian byteorder, which is good for
|
|
+ * 386 etc, but we must add some conversion when used on a big endian box.
|
|
+ *
|
|
+ *
|
|
+ * Pseudo-code for RIPEMD-160
|
|
+ *
|
|
+ * RIPEMD-160 is an iterative hash function that operates on 32-bit words.
|
|
+ * The round function takes as input a 5-word chaining variable and a 16-word
|
|
+ * message block and maps this to a new chaining variable. All operations are
|
|
+ * defined on 32-bit words. Padding is identical to that of MD4.
|
|
+ *
|
|
+ *
|
|
+ * RIPEMD-160: definitions
|
|
+ *
|
|
+ *
|
|
+ * nonlinear functions at bit level: exor, mux, -, mux, -
|
|
+ *
|
|
+ * f(j, x, y, z) = x XOR y XOR z (0 <= j <= 15)
|
|
+ * f(j, x, y, z) = (x AND y) OR (NOT(x) AND z) (16 <= j <= 31)
|
|
+ * f(j, x, y, z) = (x OR NOT(y)) XOR z (32 <= j <= 47)
|
|
+ * f(j, x, y, z) = (x AND z) OR (y AND NOT(z)) (48 <= j <= 63)
|
|
+ * f(j, x, y, z) = x XOR (y OR NOT(z)) (64 <= j <= 79)
|
|
+ *
|
|
+ *
|
|
+ * added constants (hexadecimal)
|
|
+ *
|
|
+ * K(j) = 0x00000000 (0 <= j <= 15)
|
|
+ * K(j) = 0x5A827999 (16 <= j <= 31) int(2**30 x sqrt(2))
|
|
+ * K(j) = 0x6ED9EBA1 (32 <= j <= 47) int(2**30 x sqrt(3))
|
|
+ * K(j) = 0x8F1BBCDC (48 <= j <= 63) int(2**30 x sqrt(5))
|
|
+ * K(j) = 0xA953FD4E (64 <= j <= 79) int(2**30 x sqrt(7))
|
|
+ * K'(j) = 0x50A28BE6 (0 <= j <= 15) int(2**30 x cbrt(2))
|
|
+ * K'(j) = 0x5C4DD124 (16 <= j <= 31) int(2**30 x cbrt(3))
|
|
+ * K'(j) = 0x6D703EF3 (32 <= j <= 47) int(2**30 x cbrt(5))
|
|
+ * K'(j) = 0x7A6D76E9 (48 <= j <= 63) int(2**30 x cbrt(7))
|
|
+ * K'(j) = 0x00000000 (64 <= j <= 79)
|
|
+ *
|
|
+ *
|
|
+ * selection of message word
|
|
+ *
|
|
+ * r(j) = j (0 <= j <= 15)
|
|
+ * r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
|
|
+ * r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
|
|
+ * r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
|
|
+ * r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
|
|
+ * r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
|
|
+ * r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
|
|
+ * r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
|
|
+ * r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
|
|
+ * r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
|
|
+ *
|
|
+ *
|
|
+ * amount for rotate left (rol)
|
|
+ *
|
|
+ * s(0..15) = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
|
|
+ * s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
|
|
+ * s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
|
|
+ * s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
|
|
+ * s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
|
|
+ * s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
|
|
+ * s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
|
|
+ * s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
|
|
+ * s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
|
|
+ * s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
|
|
+ *
|
|
+ *
|
|
+ * initial value (hexadecimal)
|
|
+ *
|
|
+ * h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476;
|
|
+ * h4 = 0xC3D2E1F0;
|
|
+ *
|
|
+ *
|
|
+ * RIPEMD-160: pseudo-code
|
|
+ *
|
|
+ * It is assumed that the message after padding consists of t 16-word blocks
|
|
+ * that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15.
|
|
+ * The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left
|
|
+ * shift (rotate) over s positions.
|
|
+ *
|
|
+ *
|
|
+ * for i := 0 to t-1 {
|
|
+ * A := h0; B := h1; C := h2; D = h3; E = h4;
|
|
+ * A' := h0; B' := h1; C' := h2; D' = h3; E' = h4;
|
|
+ * for j := 0 to 79 {
|
|
+ * T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E;
|
|
+ * A := E; E := D; D := rol_10(C); C := B; B := T;
|
|
+ * T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)]
|
|
+ [+] K'(j)) [+] E';
|
|
+ * A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T;
|
|
+ * }
|
|
+ * T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A';
|
|
+ * h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T;
|
|
+ * }
|
|
+ */
|
|
+
|
|
+/* Some examples:
|
|
+ * "" 9c1185a5c5e9fc54612808977ee8f548b2258d31
|
|
+ * "a" 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe
|
|
+ * "abc" 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
|
|
+ * "message digest" 5d0689ef49d2fae572b881b123a85ffa21595f36
|
|
+ * "a...z" f71c27109c692c1b56bbdceb5b9d2865b3708dbc
|
|
+ * "abcdbcde...nopq" 12a053384a9c0c88e405a06c27dcf49ada62eb2b
|
|
+ * "A...Za...z0...9" b0e20b6e3116640286ed3a87a5713079b21f5189
|
|
+ * 8 times "1234567890" 9b752e45573d4b39f4dbd3323cab82bf63326bfb
|
|
+ * 1 million times "a" 52783243c1697bdbe16d37f97f68f08325dc1528
|
|
+ */
|
|
+
|
|
+
|
|
+static void
|
|
+rmd160_init( RMD160_CONTEXT *hd )
|
|
+{
|
|
+ hd->h0 = 0x67452301;
|
|
+ hd->h1 = 0xEFCDAB89;
|
|
+ hd->h2 = 0x98BADCFE;
|
|
+ hd->h3 = 0x10325476;
|
|
+ hd->h4 = 0xC3D2E1F0;
|
|
+ hd->nblocks = 0;
|
|
+ hd->count = 0;
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+/****************
|
|
+ * Transform the message X which consists of 16 32-bit-words
|
|
+ */
|
|
+static void
|
|
+transform( RMD160_CONTEXT *hd, const byte *data )
|
|
+{
|
|
+ u32 a,b,c,d,e,aa,bb,cc,dd,ee,t;
|
|
+ #if BYTE_ORDER == BIG_ENDIAN
|
|
+ u32 x[16];
|
|
+ { int i;
|
|
+ byte *p2, *p1;
|
|
+ for(i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 ) {
|
|
+ p2[3] = *p1++;
|
|
+ p2[2] = *p1++;
|
|
+ p2[1] = *p1++;
|
|
+ p2[0] = *p1++;
|
|
+ }
|
|
+ }
|
|
+ #else
|
|
+ #if 0
|
|
+ u32 *x =(u32*)data;
|
|
+ #else
|
|
+ /* this version is better because it is always aligned;
|
|
+ * The performance penalty on a 586-100 is about 6% which
|
|
+ * is acceptable - because the data is more local it might
|
|
+ * also be possible that this is faster on some machines.
|
|
+ * This function (when compiled with -02 on gcc 2.7.2)
|
|
+ * executes on a 586-100 (39.73 bogomips) at about 1900kb/sec;
|
|
+ * [measured with a 4MB data and "gpgm --print-md rmd160"] */
|
|
+ u32 x[16];
|
|
+ memcpy( x, data, 64 );
|
|
+ #endif
|
|
+ #endif
|
|
+
|
|
+
|
|
+#define K0 0x00000000
|
|
+#define K1 0x5A827999
|
|
+#define K2 0x6ED9EBA1
|
|
+#define K3 0x8F1BBCDC
|
|
+#define K4 0xA953FD4E
|
|
+#define KK0 0x50A28BE6
|
|
+#define KK1 0x5C4DD124
|
|
+#define KK2 0x6D703EF3
|
|
+#define KK3 0x7A6D76E9
|
|
+#define KK4 0x00000000
|
|
+#define F0(x,y,z) ( (x) ^ (y) ^ (z) )
|
|
+#define F1(x,y,z) ( ((x) & (y)) | (~(x) & (z)) )
|
|
+#define F2(x,y,z) ( ((x) | ~(y)) ^ (z) )
|
|
+#define F3(x,y,z) ( ((x) & (z)) | ((y) & ~(z)) )
|
|
+#define F4(x,y,z) ( (x) ^ ((y) | ~(z)) )
|
|
+#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \
|
|
+ a = rol(t,s) + e; \
|
|
+ c = rol(c,10); \
|
|
+ } while(0)
|
|
+
|
|
+ /* left lane */
|
|
+ a = hd->h0;
|
|
+ b = hd->h1;
|
|
+ c = hd->h2;
|
|
+ d = hd->h3;
|
|
+ e = hd->h4;
|
|
+ R( a, b, c, d, e, F0, K0, 0, 11 );
|
|
+ R( e, a, b, c, d, F0, K0, 1, 14 );
|
|
+ R( d, e, a, b, c, F0, K0, 2, 15 );
|
|
+ R( c, d, e, a, b, F0, K0, 3, 12 );
|
|
+ R( b, c, d, e, a, F0, K0, 4, 5 );
|
|
+ R( a, b, c, d, e, F0, K0, 5, 8 );
|
|
+ R( e, a, b, c, d, F0, K0, 6, 7 );
|
|
+ R( d, e, a, b, c, F0, K0, 7, 9 );
|
|
+ R( c, d, e, a, b, F0, K0, 8, 11 );
|
|
+ R( b, c, d, e, a, F0, K0, 9, 13 );
|
|
+ R( a, b, c, d, e, F0, K0, 10, 14 );
|
|
+ R( e, a, b, c, d, F0, K0, 11, 15 );
|
|
+ R( d, e, a, b, c, F0, K0, 12, 6 );
|
|
+ R( c, d, e, a, b, F0, K0, 13, 7 );
|
|
+ R( b, c, d, e, a, F0, K0, 14, 9 );
|
|
+ R( a, b, c, d, e, F0, K0, 15, 8 );
|
|
+ R( e, a, b, c, d, F1, K1, 7, 7 );
|
|
+ R( d, e, a, b, c, F1, K1, 4, 6 );
|
|
+ R( c, d, e, a, b, F1, K1, 13, 8 );
|
|
+ R( b, c, d, e, a, F1, K1, 1, 13 );
|
|
+ R( a, b, c, d, e, F1, K1, 10, 11 );
|
|
+ R( e, a, b, c, d, F1, K1, 6, 9 );
|
|
+ R( d, e, a, b, c, F1, K1, 15, 7 );
|
|
+ R( c, d, e, a, b, F1, K1, 3, 15 );
|
|
+ R( b, c, d, e, a, F1, K1, 12, 7 );
|
|
+ R( a, b, c, d, e, F1, K1, 0, 12 );
|
|
+ R( e, a, b, c, d, F1, K1, 9, 15 );
|
|
+ R( d, e, a, b, c, F1, K1, 5, 9 );
|
|
+ R( c, d, e, a, b, F1, K1, 2, 11 );
|
|
+ R( b, c, d, e, a, F1, K1, 14, 7 );
|
|
+ R( a, b, c, d, e, F1, K1, 11, 13 );
|
|
+ R( e, a, b, c, d, F1, K1, 8, 12 );
|
|
+ R( d, e, a, b, c, F2, K2, 3, 11 );
|
|
+ R( c, d, e, a, b, F2, K2, 10, 13 );
|
|
+ R( b, c, d, e, a, F2, K2, 14, 6 );
|
|
+ R( a, b, c, d, e, F2, K2, 4, 7 );
|
|
+ R( e, a, b, c, d, F2, K2, 9, 14 );
|
|
+ R( d, e, a, b, c, F2, K2, 15, 9 );
|
|
+ R( c, d, e, a, b, F2, K2, 8, 13 );
|
|
+ R( b, c, d, e, a, F2, K2, 1, 15 );
|
|
+ R( a, b, c, d, e, F2, K2, 2, 14 );
|
|
+ R( e, a, b, c, d, F2, K2, 7, 8 );
|
|
+ R( d, e, a, b, c, F2, K2, 0, 13 );
|
|
+ R( c, d, e, a, b, F2, K2, 6, 6 );
|
|
+ R( b, c, d, e, a, F2, K2, 13, 5 );
|
|
+ R( a, b, c, d, e, F2, K2, 11, 12 );
|
|
+ R( e, a, b, c, d, F2, K2, 5, 7 );
|
|
+ R( d, e, a, b, c, F2, K2, 12, 5 );
|
|
+ R( c, d, e, a, b, F3, K3, 1, 11 );
|
|
+ R( b, c, d, e, a, F3, K3, 9, 12 );
|
|
+ R( a, b, c, d, e, F3, K3, 11, 14 );
|
|
+ R( e, a, b, c, d, F3, K3, 10, 15 );
|
|
+ R( d, e, a, b, c, F3, K3, 0, 14 );
|
|
+ R( c, d, e, a, b, F3, K3, 8, 15 );
|
|
+ R( b, c, d, e, a, F3, K3, 12, 9 );
|
|
+ R( a, b, c, d, e, F3, K3, 4, 8 );
|
|
+ R( e, a, b, c, d, F3, K3, 13, 9 );
|
|
+ R( d, e, a, b, c, F3, K3, 3, 14 );
|
|
+ R( c, d, e, a, b, F3, K3, 7, 5 );
|
|
+ R( b, c, d, e, a, F3, K3, 15, 6 );
|
|
+ R( a, b, c, d, e, F3, K3, 14, 8 );
|
|
+ R( e, a, b, c, d, F3, K3, 5, 6 );
|
|
+ R( d, e, a, b, c, F3, K3, 6, 5 );
|
|
+ R( c, d, e, a, b, F3, K3, 2, 12 );
|
|
+ R( b, c, d, e, a, F4, K4, 4, 9 );
|
|
+ R( a, b, c, d, e, F4, K4, 0, 15 );
|
|
+ R( e, a, b, c, d, F4, K4, 5, 5 );
|
|
+ R( d, e, a, b, c, F4, K4, 9, 11 );
|
|
+ R( c, d, e, a, b, F4, K4, 7, 6 );
|
|
+ R( b, c, d, e, a, F4, K4, 12, 8 );
|
|
+ R( a, b, c, d, e, F4, K4, 2, 13 );
|
|
+ R( e, a, b, c, d, F4, K4, 10, 12 );
|
|
+ R( d, e, a, b, c, F4, K4, 14, 5 );
|
|
+ R( c, d, e, a, b, F4, K4, 1, 12 );
|
|
+ R( b, c, d, e, a, F4, K4, 3, 13 );
|
|
+ R( a, b, c, d, e, F4, K4, 8, 14 );
|
|
+ R( e, a, b, c, d, F4, K4, 11, 11 );
|
|
+ R( d, e, a, b, c, F4, K4, 6, 8 );
|
|
+ R( c, d, e, a, b, F4, K4, 15, 5 );
|
|
+ R( b, c, d, e, a, F4, K4, 13, 6 );
|
|
+
|
|
+ aa = a; bb = b; cc = c; dd = d; ee = e;
|
|
+
|
|
+ /* right lane */
|
|
+ a = hd->h0;
|
|
+ b = hd->h1;
|
|
+ c = hd->h2;
|
|
+ d = hd->h3;
|
|
+ e = hd->h4;
|
|
+ R( a, b, c, d, e, F4, KK0, 5, 8);
|
|
+ R( e, a, b, c, d, F4, KK0, 14, 9);
|
|
+ R( d, e, a, b, c, F4, KK0, 7, 9);
|
|
+ R( c, d, e, a, b, F4, KK0, 0, 11);
|
|
+ R( b, c, d, e, a, F4, KK0, 9, 13);
|
|
+ R( a, b, c, d, e, F4, KK0, 2, 15);
|
|
+ R( e, a, b, c, d, F4, KK0, 11, 15);
|
|
+ R( d, e, a, b, c, F4, KK0, 4, 5);
|
|
+ R( c, d, e, a, b, F4, KK0, 13, 7);
|
|
+ R( b, c, d, e, a, F4, KK0, 6, 7);
|
|
+ R( a, b, c, d, e, F4, KK0, 15, 8);
|
|
+ R( e, a, b, c, d, F4, KK0, 8, 11);
|
|
+ R( d, e, a, b, c, F4, KK0, 1, 14);
|
|
+ R( c, d, e, a, b, F4, KK0, 10, 14);
|
|
+ R( b, c, d, e, a, F4, KK0, 3, 12);
|
|
+ R( a, b, c, d, e, F4, KK0, 12, 6);
|
|
+ R( e, a, b, c, d, F3, KK1, 6, 9);
|
|
+ R( d, e, a, b, c, F3, KK1, 11, 13);
|
|
+ R( c, d, e, a, b, F3, KK1, 3, 15);
|
|
+ R( b, c, d, e, a, F3, KK1, 7, 7);
|
|
+ R( a, b, c, d, e, F3, KK1, 0, 12);
|
|
+ R( e, a, b, c, d, F3, KK1, 13, 8);
|
|
+ R( d, e, a, b, c, F3, KK1, 5, 9);
|
|
+ R( c, d, e, a, b, F3, KK1, 10, 11);
|
|
+ R( b, c, d, e, a, F3, KK1, 14, 7);
|
|
+ R( a, b, c, d, e, F3, KK1, 15, 7);
|
|
+ R( e, a, b, c, d, F3, KK1, 8, 12);
|
|
+ R( d, e, a, b, c, F3, KK1, 12, 7);
|
|
+ R( c, d, e, a, b, F3, KK1, 4, 6);
|
|
+ R( b, c, d, e, a, F3, KK1, 9, 15);
|
|
+ R( a, b, c, d, e, F3, KK1, 1, 13);
|
|
+ R( e, a, b, c, d, F3, KK1, 2, 11);
|
|
+ R( d, e, a, b, c, F2, KK2, 15, 9);
|
|
+ R( c, d, e, a, b, F2, KK2, 5, 7);
|
|
+ R( b, c, d, e, a, F2, KK2, 1, 15);
|
|
+ R( a, b, c, d, e, F2, KK2, 3, 11);
|
|
+ R( e, a, b, c, d, F2, KK2, 7, 8);
|
|
+ R( d, e, a, b, c, F2, KK2, 14, 6);
|
|
+ R( c, d, e, a, b, F2, KK2, 6, 6);
|
|
+ R( b, c, d, e, a, F2, KK2, 9, 14);
|
|
+ R( a, b, c, d, e, F2, KK2, 11, 12);
|
|
+ R( e, a, b, c, d, F2, KK2, 8, 13);
|
|
+ R( d, e, a, b, c, F2, KK2, 12, 5);
|
|
+ R( c, d, e, a, b, F2, KK2, 2, 14);
|
|
+ R( b, c, d, e, a, F2, KK2, 10, 13);
|
|
+ R( a, b, c, d, e, F2, KK2, 0, 13);
|
|
+ R( e, a, b, c, d, F2, KK2, 4, 7);
|
|
+ R( d, e, a, b, c, F2, KK2, 13, 5);
|
|
+ R( c, d, e, a, b, F1, KK3, 8, 15);
|
|
+ R( b, c, d, e, a, F1, KK3, 6, 5);
|
|
+ R( a, b, c, d, e, F1, KK3, 4, 8);
|
|
+ R( e, a, b, c, d, F1, KK3, 1, 11);
|
|
+ R( d, e, a, b, c, F1, KK3, 3, 14);
|
|
+ R( c, d, e, a, b, F1, KK3, 11, 14);
|
|
+ R( b, c, d, e, a, F1, KK3, 15, 6);
|
|
+ R( a, b, c, d, e, F1, KK3, 0, 14);
|
|
+ R( e, a, b, c, d, F1, KK3, 5, 6);
|
|
+ R( d, e, a, b, c, F1, KK3, 12, 9);
|
|
+ R( c, d, e, a, b, F1, KK3, 2, 12);
|
|
+ R( b, c, d, e, a, F1, KK3, 13, 9);
|
|
+ R( a, b, c, d, e, F1, KK3, 9, 12);
|
|
+ R( e, a, b, c, d, F1, KK3, 7, 5);
|
|
+ R( d, e, a, b, c, F1, KK3, 10, 15);
|
|
+ R( c, d, e, a, b, F1, KK3, 14, 8);
|
|
+ R( b, c, d, e, a, F0, KK4, 12, 8);
|
|
+ R( a, b, c, d, e, F0, KK4, 15, 5);
|
|
+ R( e, a, b, c, d, F0, KK4, 10, 12);
|
|
+ R( d, e, a, b, c, F0, KK4, 4, 9);
|
|
+ R( c, d, e, a, b, F0, KK4, 1, 12);
|
|
+ R( b, c, d, e, a, F0, KK4, 5, 5);
|
|
+ R( a, b, c, d, e, F0, KK4, 8, 14);
|
|
+ R( e, a, b, c, d, F0, KK4, 7, 6);
|
|
+ R( d, e, a, b, c, F0, KK4, 6, 8);
|
|
+ R( c, d, e, a, b, F0, KK4, 2, 13);
|
|
+ R( b, c, d, e, a, F0, KK4, 13, 6);
|
|
+ R( a, b, c, d, e, F0, KK4, 14, 5);
|
|
+ R( e, a, b, c, d, F0, KK4, 0, 15);
|
|
+ R( d, e, a, b, c, F0, KK4, 3, 13);
|
|
+ R( c, d, e, a, b, F0, KK4, 9, 11);
|
|
+ R( b, c, d, e, a, F0, KK4, 11, 11);
|
|
+
|
|
+
|
|
+ t = hd->h1 + d + cc;
|
|
+ hd->h1 = hd->h2 + e + dd;
|
|
+ hd->h2 = hd->h3 + a + ee;
|
|
+ hd->h3 = hd->h4 + b + aa;
|
|
+ hd->h4 = hd->h0 + c + bb;
|
|
+ hd->h0 = t;
|
|
+}
|
|
+
|
|
+
|
|
+/* Update the message digest with the contents
|
|
+ * of INBUF with length INLEN.
|
|
+ */
|
|
+static void
|
|
+rmd160_write( RMD160_CONTEXT *hd, const byte *inbuf, size_t inlen)
|
|
+{
|
|
+ if( hd->count == 64 ) { /* flush the buffer */
|
|
+ transform( hd, hd->buf );
|
|
+ hd->count = 0;
|
|
+ hd->nblocks++;
|
|
+ }
|
|
+ if( !inbuf )
|
|
+ return;
|
|
+ if( hd->count ) {
|
|
+ for( ; inlen && hd->count < 64; inlen-- )
|
|
+ hd->buf[hd->count++] = *inbuf++;
|
|
+ rmd160_write( hd, NULL, 0 );
|
|
+ if( !inlen )
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ while( inlen >= 64 ) {
|
|
+ transform( hd, inbuf );
|
|
+ hd->count = 0;
|
|
+ hd->nblocks++;
|
|
+ inlen -= 64;
|
|
+ inbuf += 64;
|
|
+ }
|
|
+ for( ; inlen && hd->count < 64; inlen-- )
|
|
+ hd->buf[hd->count++] = *inbuf++;
|
|
+}
|
|
+
|
|
+/* The routine terminates the computation
|
|
+ */
|
|
+
|
|
+static void
|
|
+rmd160_final( RMD160_CONTEXT *hd )
|
|
+{
|
|
+ u32 t, msb, lsb;
|
|
+ byte *p;
|
|
+
|
|
+ rmd160_write(hd, NULL, 0); /* flush */;
|
|
+
|
|
+ msb = 0;
|
|
+ t = hd->nblocks;
|
|
+ if( (lsb = t << 6) < t ) /* multiply by 64 to make a byte count */
|
|
+ msb++;
|
|
+ msb += t >> 26;
|
|
+ t = lsb;
|
|
+ if( (lsb = t + hd->count) < t ) /* add the count */
|
|
+ msb++;
|
|
+ t = lsb;
|
|
+ if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
|
|
+ msb++;
|
|
+ msb += t >> 29;
|
|
+
|
|
+ if( hd->count < 56 ) { /* enough room */
|
|
+ hd->buf[hd->count++] = 0x80; /* pad */
|
|
+ while( hd->count < 56 )
|
|
+ hd->buf[hd->count++] = 0; /* pad */
|
|
+ }
|
|
+ else { /* need one extra block */
|
|
+ hd->buf[hd->count++] = 0x80; /* pad character */
|
|
+ while( hd->count < 64 )
|
|
+ hd->buf[hd->count++] = 0;
|
|
+ rmd160_write(hd, NULL, 0); /* flush */;
|
|
+ memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
|
|
+ }
|
|
+ /* append the 64 bit count */
|
|
+ hd->buf[56] = lsb ;
|
|
+ hd->buf[57] = lsb >> 8;
|
|
+ hd->buf[58] = lsb >> 16;
|
|
+ hd->buf[59] = lsb >> 24;
|
|
+ hd->buf[60] = msb ;
|
|
+ hd->buf[61] = msb >> 8;
|
|
+ hd->buf[62] = msb >> 16;
|
|
+ hd->buf[63] = msb >> 24;
|
|
+ transform( hd, hd->buf );
|
|
+
|
|
+ p = hd->buf;
|
|
+ #if BYTE_ORDER == BIG_ENDIAN
|
|
+ #define X(a) do { *p++ = hd->h##a ; *p++ = hd->h##a >> 8; \
|
|
+ *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
|
|
+ #else /* little endian */
|
|
+ #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
|
|
+ #endif
|
|
+ X(0);
|
|
+ X(1);
|
|
+ X(2);
|
|
+ X(3);
|
|
+ X(4);
|
|
+ #undef X
|
|
+}
|
|
+
|
|
+/****************
|
|
+ * Shortcut functions which puts the hash value of the supplied buffer
|
|
+ * into outbuf which must have a size of 20 bytes.
|
|
+ */
|
|
+void
|
|
+rmd160_hash_buffer( unsigned char *outbuf, const unsigned char *buffer, size_t length )
|
|
+{
|
|
+ RMD160_CONTEXT hd;
|
|
+
|
|
+ rmd160_init( &hd );
|
|
+ rmd160_write( &hd, buffer, length );
|
|
+ rmd160_final( &hd );
|
|
+ memcpy( outbuf, hd.buf, 20 );
|
|
+}
|
|
Index: util-linux-ng-2.16/mount/rmd160.h
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ util-linux-ng-2.16/mount/rmd160.h
|
|
@@ -0,0 +1,11 @@
|
|
+#ifndef RMD160_H
|
|
+#define RMD160_H
|
|
+
|
|
+#define RMD160_HASH_SIZE 20
|
|
+
|
|
+void
|
|
+rmd160_hash_buffer( unsigned char *outbuf, const unsigned char *buffer, size_t length );
|
|
+
|
|
+#endif /*RMD160_H*/
|
|
+
|
|
+
|
|
Index: util-linux-ng-2.16/mount/sha512.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ util-linux-ng-2.16/mount/sha512.c
|
|
@@ -0,0 +1,432 @@
|
|
+/*
|
|
+ * sha512.c
|
|
+ *
|
|
+ * Written by Jari Ruusu, April 16 2001
|
|
+ *
|
|
+ * Copyright 2001 by Jari Ruusu.
|
|
+ * Redistribution of this file is permitted under the GNU Public License.
|
|
+ */
|
|
+
|
|
+#include <string.h>
|
|
+#include <sys/types.h>
|
|
+#include "sha512.h"
|
|
+
|
|
+/* Define one or more of these. If none is defined, you get all of them */
|
|
+#if !defined(SHA256_NEEDED)&&!defined(SHA512_NEEDED)&&!defined(SHA384_NEEDED)
|
|
+# define SHA256_NEEDED 1
|
|
+# define SHA512_NEEDED 1
|
|
+# define SHA384_NEEDED 1
|
|
+#endif
|
|
+
|
|
+#if defined(SHA256_NEEDED)
|
|
+static const u_int32_t sha256_hashInit[8] = {
|
|
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
|
|
+ 0x1f83d9ab, 0x5be0cd19
|
|
+};
|
|
+static const u_int32_t sha256_K[64] = {
|
|
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
|
|
+ 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
|
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
|
|
+ 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
|
|
+ 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
|
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
|
|
+ 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
|
|
+ 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
|
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
|
+};
|
|
+#endif
|
|
+
|
|
+#if defined(SHA512_NEEDED)
|
|
+static const u_int64_t sha512_hashInit[8] = {
|
|
+ 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
|
|
+ 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
|
|
+ 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
|
|
+};
|
|
+#endif
|
|
+
|
|
+#if defined(SHA384_NEEDED)
|
|
+static const u_int64_t sha384_hashInit[8] = {
|
|
+ 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL,
|
|
+ 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
|
|
+ 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL
|
|
+};
|
|
+#endif
|
|
+
|
|
+#if defined(SHA512_NEEDED) || defined(SHA384_NEEDED)
|
|
+static const u_int64_t sha512_K[80] = {
|
|
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
|
|
+ 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
|
|
+ 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
|
|
+ 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
|
|
+ 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
|
|
+ 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
|
|
+ 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
|
|
+ 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
|
|
+ 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
|
|
+ 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
|
|
+ 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
|
|
+ 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
|
|
+ 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
|
|
+ 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
|
|
+ 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
|
|
+ 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
|
|
+ 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
|
|
+ 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
|
|
+ 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
|
|
+ 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
|
|
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
|
|
+ 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
|
|
+ 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
|
|
+ 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
|
|
+ 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
|
|
+ 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
|
|
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
|
|
+};
|
|
+#endif
|
|
+
|
|
+#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
|
|
+#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
|
+#define R(x,y) ((y) >> (x))
|
|
+
|
|
+#if defined(SHA256_NEEDED)
|
|
+void sha256_init(sha256_context *ctx)
|
|
+{
|
|
+ memcpy(&ctx->sha_H[0], &sha256_hashInit[0], sizeof(ctx->sha_H));
|
|
+ ctx->sha_blocks = 0;
|
|
+ ctx->sha_bufCnt = 0;
|
|
+}
|
|
+
|
|
+#define S(x,y) (((y) >> (x)) | ((y) << (32 - (x))))
|
|
+#define uSig0(x) ((S(2,(x))) ^ (S(13,(x))) ^ (S(22,(x))))
|
|
+#define uSig1(x) ((S(6,(x))) ^ (S(11,(x))) ^ (S(25,(x))))
|
|
+#define lSig0(x) ((S(7,(x))) ^ (S(18,(x))) ^ (R(3,(x))))
|
|
+#define lSig1(x) ((S(17,(x))) ^ (S(19,(x))) ^ (R(10,(x))))
|
|
+
|
|
+static void sha256_transform(sha256_context *ctx, const unsigned char *datap)
|
|
+{
|
|
+ register int j;
|
|
+ u_int32_t a, b, c, d, e, f, g, h;
|
|
+ u_int32_t T1, T2, W[64], Wm2, Wm15;
|
|
+
|
|
+ /* read the data, big endian byte order */
|
|
+ j = 0;
|
|
+ do {
|
|
+ W[j] = (((u_int32_t)(datap[0]))<<24) | (((u_int32_t)(datap[1]))<<16) |
|
|
+ (((u_int32_t)(datap[2]))<<8 ) | ((u_int32_t)(datap[3]));
|
|
+ datap += 4;
|
|
+ } while(++j < 16);
|
|
+
|
|
+ /* initialize variables a...h */
|
|
+ a = ctx->sha_H[0];
|
|
+ b = ctx->sha_H[1];
|
|
+ c = ctx->sha_H[2];
|
|
+ d = ctx->sha_H[3];
|
|
+ e = ctx->sha_H[4];
|
|
+ f = ctx->sha_H[5];
|
|
+ g = ctx->sha_H[6];
|
|
+ h = ctx->sha_H[7];
|
|
+
|
|
+ /* apply compression function */
|
|
+ j = 0;
|
|
+ do {
|
|
+ if(j >= 16) {
|
|
+ Wm2 = W[j - 2];
|
|
+ Wm15 = W[j - 15];
|
|
+ W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
|
|
+ }
|
|
+ T1 = h + uSig1(e) + Ch(e,f,g) + sha256_K[j] + W[j];
|
|
+ T2 = uSig0(a) + Maj(a,b,c);
|
|
+ h = g; g = f; f = e;
|
|
+ e = d + T1;
|
|
+ d = c; c = b; b = a;
|
|
+ a = T1 + T2;
|
|
+ } while(++j < 64);
|
|
+
|
|
+ /* compute intermediate hash value */
|
|
+ ctx->sha_H[0] += a;
|
|
+ ctx->sha_H[1] += b;
|
|
+ ctx->sha_H[2] += c;
|
|
+ ctx->sha_H[3] += d;
|
|
+ ctx->sha_H[4] += e;
|
|
+ ctx->sha_H[5] += f;
|
|
+ ctx->sha_H[6] += g;
|
|
+ ctx->sha_H[7] += h;
|
|
+
|
|
+ ctx->sha_blocks++;
|
|
+}
|
|
+
|
|
+void sha256_write(sha256_context *ctx, const unsigned char *datap, int length)
|
|
+{
|
|
+ while(length > 0) {
|
|
+ if(!ctx->sha_bufCnt) {
|
|
+ while(length >= sizeof(ctx->sha_out)) {
|
|
+ sha256_transform(ctx, datap);
|
|
+ datap += sizeof(ctx->sha_out);
|
|
+ length -= sizeof(ctx->sha_out);
|
|
+ }
|
|
+ if(!length) return;
|
|
+ }
|
|
+ ctx->sha_out[ctx->sha_bufCnt] = *datap++;
|
|
+ length--;
|
|
+ if(++ctx->sha_bufCnt == sizeof(ctx->sha_out)) {
|
|
+ sha256_transform(ctx, &ctx->sha_out[0]);
|
|
+ ctx->sha_bufCnt = 0;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void sha256_final(sha256_context *ctx)
|
|
+{
|
|
+ register int j;
|
|
+ u_int64_t bitLength;
|
|
+ u_int32_t i;
|
|
+ unsigned char padByte, *datap;
|
|
+
|
|
+ bitLength = (ctx->sha_blocks << 9) | (ctx->sha_bufCnt << 3);
|
|
+ padByte = 0x80;
|
|
+ sha256_write(ctx, &padByte, 1);
|
|
+
|
|
+ /* pad extra space with zeroes */
|
|
+ padByte = 0;
|
|
+ while(ctx->sha_bufCnt != 56) {
|
|
+ sha256_write(ctx, &padByte, 1);
|
|
+ }
|
|
+
|
|
+ /* write bit length, big endian byte order */
|
|
+ ctx->sha_out[56] = bitLength >> 56;
|
|
+ ctx->sha_out[57] = bitLength >> 48;
|
|
+ ctx->sha_out[58] = bitLength >> 40;
|
|
+ ctx->sha_out[59] = bitLength >> 32;
|
|
+ ctx->sha_out[60] = bitLength >> 24;
|
|
+ ctx->sha_out[61] = bitLength >> 16;
|
|
+ ctx->sha_out[62] = bitLength >> 8;
|
|
+ ctx->sha_out[63] = bitLength;
|
|
+ sha256_transform(ctx, &ctx->sha_out[0]);
|
|
+
|
|
+ /* return results in ctx->sha_out[0...31] */
|
|
+ datap = &ctx->sha_out[0];
|
|
+ j = 0;
|
|
+ do {
|
|
+ i = ctx->sha_H[j];
|
|
+ datap[0] = i >> 24;
|
|
+ datap[1] = i >> 16;
|
|
+ datap[2] = i >> 8;
|
|
+ datap[3] = i;
|
|
+ datap += 4;
|
|
+ } while(++j < 8);
|
|
+
|
|
+ /* clear sensitive information */
|
|
+ memset(&ctx->sha_out[32], 0, sizeof(sha256_context) - 32);
|
|
+}
|
|
+
|
|
+void sha256_hash_buffer(const unsigned char *ib, size_t ile, unsigned char *ob, size_t ole)
|
|
+{
|
|
+ sha256_context ctx;
|
|
+
|
|
+ if(ole < 1) return;
|
|
+ memset(ob, 0, ole);
|
|
+ if(ole > 32) ole = 32;
|
|
+ sha256_init(&ctx);
|
|
+ sha256_write(&ctx, ib, ile);
|
|
+ sha256_final(&ctx);
|
|
+ memcpy(ob, &ctx.sha_out[0], ole);
|
|
+ memset(&ctx, 0, sizeof(ctx));
|
|
+}
|
|
+
|
|
+#endif
|
|
+
|
|
+#if defined(SHA512_NEEDED)
|
|
+void sha512_init(sha512_context *ctx)
|
|
+{
|
|
+ memcpy(&ctx->sha_H[0], &sha512_hashInit[0], sizeof(ctx->sha_H));
|
|
+ ctx->sha_blocks = 0;
|
|
+ ctx->sha_blocksMSB = 0;
|
|
+ ctx->sha_bufCnt = 0;
|
|
+}
|
|
+#endif
|
|
+
|
|
+#if defined(SHA512_NEEDED) || defined(SHA384_NEEDED)
|
|
+#undef S
|
|
+#undef uSig0
|
|
+#undef uSig1
|
|
+#undef lSig0
|
|
+#undef lSig1
|
|
+#define S(x,y) (((y) >> (x)) | ((y) << (64 - (x))))
|
|
+#define uSig0(x) ((S(28,(x))) ^ (S(34,(x))) ^ (S(39,(x))))
|
|
+#define uSig1(x) ((S(14,(x))) ^ (S(18,(x))) ^ (S(41,(x))))
|
|
+#define lSig0(x) ((S(1,(x))) ^ (S(8,(x))) ^ (R(7,(x))))
|
|
+#define lSig1(x) ((S(19,(x))) ^ (S(61,(x))) ^ (R(6,(x))))
|
|
+
|
|
+static void sha512_transform(sha512_context *ctx, const unsigned char *datap)
|
|
+{
|
|
+ register int j;
|
|
+ u_int64_t a, b, c, d, e, f, g, h;
|
|
+ u_int64_t T1, T2, W[80], Wm2, Wm15;
|
|
+
|
|
+ /* read the data, big endian byte order */
|
|
+ j = 0;
|
|
+ do {
|
|
+ W[j] = (((u_int64_t)(datap[0]))<<56) | (((u_int64_t)(datap[1]))<<48) |
|
|
+ (((u_int64_t)(datap[2]))<<40) | (((u_int64_t)(datap[3]))<<32) |
|
|
+ (((u_int64_t)(datap[4]))<<24) | (((u_int64_t)(datap[5]))<<16) |
|
|
+ (((u_int64_t)(datap[6]))<<8 ) | ((u_int64_t)(datap[7]));
|
|
+ datap += 8;
|
|
+ } while(++j < 16);
|
|
+
|
|
+ /* initialize variables a...h */
|
|
+ a = ctx->sha_H[0];
|
|
+ b = ctx->sha_H[1];
|
|
+ c = ctx->sha_H[2];
|
|
+ d = ctx->sha_H[3];
|
|
+ e = ctx->sha_H[4];
|
|
+ f = ctx->sha_H[5];
|
|
+ g = ctx->sha_H[6];
|
|
+ h = ctx->sha_H[7];
|
|
+
|
|
+ /* apply compression function */
|
|
+ j = 0;
|
|
+ do {
|
|
+ if(j >= 16) {
|
|
+ Wm2 = W[j - 2];
|
|
+ Wm15 = W[j - 15];
|
|
+ W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
|
|
+ }
|
|
+ T1 = h + uSig1(e) + Ch(e,f,g) + sha512_K[j] + W[j];
|
|
+ T2 = uSig0(a) + Maj(a,b,c);
|
|
+ h = g; g = f; f = e;
|
|
+ e = d + T1;
|
|
+ d = c; c = b; b = a;
|
|
+ a = T1 + T2;
|
|
+ } while(++j < 80);
|
|
+
|
|
+ /* compute intermediate hash value */
|
|
+ ctx->sha_H[0] += a;
|
|
+ ctx->sha_H[1] += b;
|
|
+ ctx->sha_H[2] += c;
|
|
+ ctx->sha_H[3] += d;
|
|
+ ctx->sha_H[4] += e;
|
|
+ ctx->sha_H[5] += f;
|
|
+ ctx->sha_H[6] += g;
|
|
+ ctx->sha_H[7] += h;
|
|
+
|
|
+ ctx->sha_blocks++;
|
|
+ if(!ctx->sha_blocks) ctx->sha_blocksMSB++;
|
|
+}
|
|
+
|
|
+void sha512_write(sha512_context *ctx, const unsigned char *datap, int length)
|
|
+{
|
|
+ while(length > 0) {
|
|
+ if(!ctx->sha_bufCnt) {
|
|
+ while(length >= sizeof(ctx->sha_out)) {
|
|
+ sha512_transform(ctx, datap);
|
|
+ datap += sizeof(ctx->sha_out);
|
|
+ length -= sizeof(ctx->sha_out);
|
|
+ }
|
|
+ if(!length) return;
|
|
+ }
|
|
+ ctx->sha_out[ctx->sha_bufCnt] = *datap++;
|
|
+ length--;
|
|
+ if(++ctx->sha_bufCnt == sizeof(ctx->sha_out)) {
|
|
+ sha512_transform(ctx, &ctx->sha_out[0]);
|
|
+ ctx->sha_bufCnt = 0;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void sha512_final(sha512_context *ctx)
|
|
+{
|
|
+ register int j;
|
|
+ u_int64_t bitLength, bitLengthMSB;
|
|
+ u_int64_t i;
|
|
+ unsigned char padByte, *datap;
|
|
+
|
|
+ bitLength = (ctx->sha_blocks << 10) | (ctx->sha_bufCnt << 3);
|
|
+ bitLengthMSB = (ctx->sha_blocksMSB << 10) | (ctx->sha_blocks >> 54);
|
|
+ padByte = 0x80;
|
|
+ sha512_write(ctx, &padByte, 1);
|
|
+
|
|
+ /* pad extra space with zeroes */
|
|
+ padByte = 0;
|
|
+ while(ctx->sha_bufCnt != 112) {
|
|
+ sha512_write(ctx, &padByte, 1);
|
|
+ }
|
|
+
|
|
+ /* write bit length, big endian byte order */
|
|
+ ctx->sha_out[112] = bitLengthMSB >> 56;
|
|
+ ctx->sha_out[113] = bitLengthMSB >> 48;
|
|
+ ctx->sha_out[114] = bitLengthMSB >> 40;
|
|
+ ctx->sha_out[115] = bitLengthMSB >> 32;
|
|
+ ctx->sha_out[116] = bitLengthMSB >> 24;
|
|
+ ctx->sha_out[117] = bitLengthMSB >> 16;
|
|
+ ctx->sha_out[118] = bitLengthMSB >> 8;
|
|
+ ctx->sha_out[119] = bitLengthMSB;
|
|
+ ctx->sha_out[120] = bitLength >> 56;
|
|
+ ctx->sha_out[121] = bitLength >> 48;
|
|
+ ctx->sha_out[122] = bitLength >> 40;
|
|
+ ctx->sha_out[123] = bitLength >> 32;
|
|
+ ctx->sha_out[124] = bitLength >> 24;
|
|
+ ctx->sha_out[125] = bitLength >> 16;
|
|
+ ctx->sha_out[126] = bitLength >> 8;
|
|
+ ctx->sha_out[127] = bitLength;
|
|
+ sha512_transform(ctx, &ctx->sha_out[0]);
|
|
+
|
|
+ /* return results in ctx->sha_out[0...63] */
|
|
+ datap = &ctx->sha_out[0];
|
|
+ j = 0;
|
|
+ do {
|
|
+ i = ctx->sha_H[j];
|
|
+ datap[0] = i >> 56;
|
|
+ datap[1] = i >> 48;
|
|
+ datap[2] = i >> 40;
|
|
+ datap[3] = i >> 32;
|
|
+ datap[4] = i >> 24;
|
|
+ datap[5] = i >> 16;
|
|
+ datap[6] = i >> 8;
|
|
+ datap[7] = i;
|
|
+ datap += 8;
|
|
+ } while(++j < 8);
|
|
+
|
|
+ /* clear sensitive information */
|
|
+ memset(&ctx->sha_out[64], 0, sizeof(sha512_context) - 64);
|
|
+}
|
|
+
|
|
+void sha512_hash_buffer(const unsigned char *ib, size_t ile, unsigned char *ob, size_t ole)
|
|
+{
|
|
+ sha512_context ctx;
|
|
+
|
|
+ if(ole < 1) return;
|
|
+ memset(ob, 0, ole);
|
|
+ if(ole > 64) ole = 64;
|
|
+ sha512_init(&ctx);
|
|
+ sha512_write(&ctx, ib, ile);
|
|
+ sha512_final(&ctx);
|
|
+ memcpy(ob, &ctx.sha_out[0], ole);
|
|
+ memset(&ctx, 0, sizeof(ctx));
|
|
+}
|
|
+#endif
|
|
+
|
|
+#if defined(SHA384_NEEDED)
|
|
+void sha384_init(sha512_context *ctx)
|
|
+{
|
|
+ memcpy(&ctx->sha_H[0], &sha384_hashInit[0], sizeof(ctx->sha_H));
|
|
+ ctx->sha_blocks = 0;
|
|
+ ctx->sha_blocksMSB = 0;
|
|
+ ctx->sha_bufCnt = 0;
|
|
+}
|
|
+
|
|
+void sha384_hash_buffer(const unsigned char *ib, size_t ile, unsigned char *ob, size_t ole)
|
|
+{
|
|
+ sha512_context ctx;
|
|
+
|
|
+ if(ole < 1) return;
|
|
+ memset(ob, 0, ole);
|
|
+ if(ole > 48) ole = 48;
|
|
+ sha384_init(&ctx);
|
|
+ sha512_write(&ctx, ib, ile);
|
|
+ sha512_final(&ctx);
|
|
+ memcpy(ob, &ctx.sha_out[0], ole);
|
|
+ memset(&ctx, 0, sizeof(ctx));
|
|
+}
|
|
+#endif
|
|
Index: util-linux-ng-2.16/mount/sha512.h
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ util-linux-ng-2.16/mount/sha512.h
|
|
@@ -0,0 +1,45 @@
|
|
+/*
|
|
+ * sha512.h
|
|
+ *
|
|
+ * Written by Jari Ruusu, April 16 2001
|
|
+ *
|
|
+ * Copyright 2001 by Jari Ruusu.
|
|
+ * Redistribution of this file is permitted under the GNU Public License.
|
|
+ */
|
|
+
|
|
+#include <sys/types.h>
|
|
+
|
|
+typedef struct {
|
|
+ unsigned char sha_out[64]; /* results are here, bytes 0...31 */
|
|
+ u_int32_t sha_H[8];
|
|
+ u_int64_t sha_blocks;
|
|
+ int sha_bufCnt;
|
|
+} sha256_context;
|
|
+
|
|
+typedef struct {
|
|
+ unsigned char sha_out[128]; /* results are here, bytes 0...63 */
|
|
+ u_int64_t sha_H[8];
|
|
+ u_int64_t sha_blocks;
|
|
+ u_int64_t sha_blocksMSB;
|
|
+ int sha_bufCnt;
|
|
+} sha512_context;
|
|
+
|
|
+/* no sha384_context, use sha512_context */
|
|
+
|
|
+/* 256 bit hash, provides 128 bits of security against collision attacks */
|
|
+extern void sha256_init(sha256_context *);
|
|
+extern void sha256_write(sha256_context *, const unsigned char *, int);
|
|
+extern void sha256_final(sha256_context *);
|
|
+extern void sha256_hash_buffer(const unsigned char *, size_t, unsigned char *, size_t);
|
|
+
|
|
+/* 512 bit hash, provides 256 bits of security against collision attacks */
|
|
+extern void sha512_init(sha512_context *);
|
|
+extern void sha512_write(sha512_context *, const unsigned char *, int);
|
|
+extern void sha512_final(sha512_context *);
|
|
+extern void sha512_hash_buffer(const unsigned char *, size_t, unsigned char *, size_t);
|
|
+
|
|
+/* 384 bit hash, provides 192 bits of security against collision attacks */
|
|
+extern void sha384_init(sha512_context *);
|
|
+/* no sha384_write(), use sha512_write() */
|
|
+/* no sha384_final(), use sha512_final(), result in ctx->sha_out[0...47] */
|
|
+extern void sha384_hash_buffer(const unsigned char *, size_t, unsigned char *, size_t);
|