forked from pool/cryptsetup
157 lines
4.5 KiB
Diff
157 lines
4.5 KiB
Diff
add support for -C (itercountk) option of loop-AES if libgcrypt is available
|
|
|
|
Signed-off-by: Ludwig Nussel <ludwig.nussel@suse.de>
|
|
|
|
Index: hashalot-0.3/Makefile.am
|
|
===================================================================
|
|
--- hashalot-0.3/Makefile.am.orig
|
|
+++ hashalot-0.3/Makefile.am
|
|
@@ -3,6 +3,9 @@ sbin_PROGRAMS = hashalot
|
|
|
|
man_MANS = hashalot.1
|
|
|
|
+hashalot_CFLAGS = $(LIBGCRYPT_CFLAGS)
|
|
+hashalot_LDFLAGS = $(LIBGCRYPT_LIBS)
|
|
+
|
|
hashalot_SOURCES = hashalot.c rmd160.c rmd160.h sha512.c sha512.h
|
|
|
|
install-exec-hook:
|
|
Index: hashalot-0.3/configure.ac
|
|
===================================================================
|
|
--- hashalot-0.3/configure.ac.orig
|
|
+++ hashalot-0.3/configure.ac
|
|
@@ -8,5 +8,6 @@ AC_PROG_LN_S
|
|
AC_HEADER_STDC
|
|
AC_CHECK_HEADERS(libgen.h stdio.h stdlib.h string.h unistd.h assert.h sys/types.h sys/mman.h endian.h , , [ AC_MSG_ERROR(required header not found)])
|
|
AC_CHECK_FUNCS(getopt snprintf , , [ AC_MSG_ERROR(required function not found)])
|
|
+AM_PATH_LIBGCRYPT(,[AC_DEFINE([HAVE_LIBGCRYPT], 1)])
|
|
|
|
AC_OUTPUT(Makefile)
|
|
Index: hashalot-0.3/hashalot.c
|
|
===================================================================
|
|
--- hashalot-0.3/hashalot.c.orig
|
|
+++ hashalot-0.3/hashalot.c
|
|
@@ -25,6 +25,10 @@
|
|
#include <sys/types.h>
|
|
#include <sys/mman.h>
|
|
|
|
+#if HAVE_LIBGCRYPT
|
|
+#include <gcrypt.h>
|
|
+#endif
|
|
+
|
|
#include "rmd160.h"
|
|
#include "sha512.h"
|
|
|
|
@@ -97,9 +101,9 @@ show_usage(const char argv0[])
|
|
|
|
fprintf (stdout,
|
|
"usage:\n"
|
|
- " hashalot [ -x ] [ -s SALT ] [ -n _#bytes_ ] HASHTYPE\n"
|
|
+ " hashalot [ -x ] [ -s SALT ] [ -n _#bytes_ ] [ -C itercountk ] HASHTYPE\n"
|
|
" or\n"
|
|
- " HASHTYPE [ -x ] [ -s SALT ] [ -n _#bytes_ ]\n"
|
|
+ " HASHTYPE [ -x ] [ -s SALT ] [ -n _#bytes_ ] [ -C itercountk ]\n"
|
|
"\n"
|
|
"supported values for HASHTYPE: ");
|
|
|
|
@@ -214,8 +218,9 @@ main(int argc, char *argv[])
|
|
size_t hashlen = 0;
|
|
phash_func_t func;
|
|
int hex_output = 0, c;
|
|
+ unsigned long itercountk = 0;
|
|
|
|
- while ((c = getopt(argc, argv, "n:s:x")) != -1) {
|
|
+ while ((c = getopt(argc, argv, "n:s:xC:")) != -1) {
|
|
switch (c) {
|
|
case 'n':
|
|
hashlen = strtoul(optarg, &p, 0);
|
|
@@ -233,6 +238,9 @@ main(int argc, char *argv[])
|
|
case 'x':
|
|
hex_output++;
|
|
break;
|
|
+ case 'C':
|
|
+ itercountk = atoi(optarg);
|
|
+ break;
|
|
default:
|
|
show_usage(argv[0]);
|
|
exit(EXIT_FAILURE);
|
|
@@ -257,6 +265,8 @@ main(int argc, char *argv[])
|
|
* plus a newline, plus a null */
|
|
passhash = xmalloc(2*hashlen + 2);
|
|
|
|
+ memset(passhash, 0, 2*hashlen+2);
|
|
+
|
|
/* try to lock memory so it doesn't get swapped out for sure */
|
|
if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
|
|
perror("mlockall");
|
|
@@ -268,6 +278,69 @@ main(int argc, char *argv[])
|
|
if (salt)
|
|
pass = salt_passphrase(pass, salt);
|
|
hashlen = func(passhash, hashlen, pass, strlen(pass));
|
|
+
|
|
+ if(itercountk) /* from loop-AES */
|
|
+ {
|
|
+#if HAVE_LIBGCRYPT
|
|
+ gcry_cipher_hd_t ctx;
|
|
+ gcry_error_t err;
|
|
+ char tmp[32];
|
|
+ char out[32];
|
|
+
|
|
+ if(hashlen > 32) {
|
|
+ fprintf(stderr, "WARNING: hashlen truncated to 32\n");
|
|
+ hashlen = 32;
|
|
+ }
|
|
+
|
|
+ if(!gcry_check_version("1.1.0")) {
|
|
+ fprintf(stderr, "libgcrypt initialization failed\n");
|
|
+ exit(EXIT_FAILURE);
|
|
+ }
|
|
+
|
|
+ memset(out, 0, sizeof(out));
|
|
+ memcpy(out, passhash, hashlen);
|
|
+
|
|
+ err = gcry_cipher_open(&ctx, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0);
|
|
+ if(err)
|
|
+ {
|
|
+ fprintf(stderr, "can't initialize AES: %s\n", gcry_strerror (err));
|
|
+ exit(EXIT_FAILURE);
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Set up AES-256 encryption key using same password and hash function
|
|
+ * as before but with password bit 0 flipped before hashing. That key
|
|
+ * is then used to encrypt actual loop key 'itercountk' thousand times.
|
|
+ */
|
|
+ pass[0] ^= 1;
|
|
+ func(&tmp[0], 32, pass, strlen(pass));
|
|
+ gcry_cipher_setkey(ctx, &tmp[0], 32);
|
|
+ itercountk *= 1000;
|
|
+ while(itercountk > 0) {
|
|
+ gcry_cipher_reset(ctx);
|
|
+ gcry_cipher_setiv(ctx, NULL, 0);
|
|
+ /* encrypt both 128bit blocks with AES-256 */
|
|
+ gcry_cipher_encrypt(ctx, &out[ 0], 16, &out[ 0], 16);
|
|
+ gcry_cipher_reset(ctx);
|
|
+ gcry_cipher_setiv(ctx, NULL, 0);
|
|
+ gcry_cipher_encrypt(ctx, &out[16], 16, &out[16], 16);
|
|
+ /* exchange upper half of first block with lower half of second block */
|
|
+ memcpy(&tmp[0], &out[8], 8);
|
|
+ memcpy(&out[8], &out[16], 8);
|
|
+ memcpy(&out[16], &tmp[0], 8);
|
|
+ itercountk--;
|
|
+ }
|
|
+ memset(&tmp[0], 0, sizeof(tmp));
|
|
+
|
|
+ memcpy(passhash, out, hashlen);
|
|
+
|
|
+ gcry_cipher_close(ctx);
|
|
+#else
|
|
+ fprintf(stderr, "libgcrypt support is required for option -C\n");
|
|
+ exit(EXIT_FAILURE);
|
|
+#endif
|
|
+
|
|
+ }
|
|
memset (pass, 0, strlen (pass)); /* paranoia */
|
|
free(pass);
|
|
|