File hashalot-libgcrypt.diff of Package cryptsetup
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);