summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2013-06-25 13:47:08 +0200
committerNiels Möller <nisse@lysator.liu.se>2013-06-25 13:47:08 +0200
commit23f70ce95419258604c91ecc946b1164954ba990 (patch)
treead15c2778cad8d7de938b998702037df97aad1cc /tools
parent8d1d5d6de8cc9b66c318d2676b42a87e8f32ec96 (diff)
downloadnettle-23f70ce95419258604c91ecc946b1164954ba990.tar.gz
New program nettle-pbkdf2.
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile.in10
-rw-r--r--tools/nettle-pbkdf2.c180
2 files changed, 188 insertions, 2 deletions
diff --git a/tools/Makefile.in b/tools/Makefile.in
index 29d55e88..f7b33529 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -18,7 +18,8 @@ PRE_CPPFLAGS = -I.. -I$(top_srcdir)
PRE_LDFLAGS = -L..
HOGWEED_TARGETS = pkcs1-conv$(EXEEXT)
-TARGETS = sexp-conv$(EXEEXT) nettle-hash$(EXEEXT) nettle-lfib-stream$(EXEEXT) \
+TARGETS = sexp-conv$(EXEEXT) nettle-hash$(EXEEXT) nettle-pbkdf2$(EXEEXT) \
+ nettle-lfib-stream$(EXEEXT) \
@IF_HOGWEED@ $(HOGWEED_TARGETS)
all: $(TARGETS)
@@ -28,6 +29,7 @@ getopt_OBJS = ../getopt.$(OBJEXT) ../getopt1.$(OBJEXT)
sexp_conv_SOURCES = sexp-conv.c input.c output.c parse.c misc.c
pkcs1_conv_SOURCES = pkcs1-conv.c misc.c
nettle_hash_SOURCES = nettle-hash.c misc.c
+nettle_pbkdf2_SOURCES = nettle-pbkdf2.c misc.c
SOURCES = $(sexp_conv_SOURCES) nettle-hash.c nettle-lfib-stream.c pkcs1-conv.c
@@ -47,7 +49,11 @@ pkcs1-conv$(EXEEXT): $(pkcs1_conv_OBJS) ../libnettle.a ../libhogweed.a
# FIXME: Avoid linking with gmp
nettle_hash_OBJS = $(nettle_hash_SOURCES:.c=.$(OBJEXT)) $(getopt_OBJS)
nettle-hash$(EXEEXT): $(nettle_hash_OBJS) ../libnettle.a
- $(LINK) $(nettle_hash_OBJS) -lnettle $(LIBS) -o $@
+ $(LINK) $(nettle_hash_OBJS) -lnettle -o $@
+
+nettle_pbkdf2_OBJS = $(nettle_pbkdf2_SOURCES:.c=.$(OBJEXT)) $(getopt_OBJS)
+nettle-pbkdf2$(EXEEXT): $(nettle_pbkdf2_OBJS) ../libnettle.a
+ $(LINK) $(nettle_pbkdf2_OBJS) -lnettle -o $@
.c.$(OBJEXT):
diff --git a/tools/nettle-pbkdf2.c b/tools/nettle-pbkdf2.c
new file mode 100644
index 00000000..35c98707
--- /dev/null
+++ b/tools/nettle-pbkdf2.c
@@ -0,0 +1,180 @@
+/* nettle-pbkdf2.c
+ *
+ * Command-line tool for pbkdf2 hashing. */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2013 Niels Möller
+ *
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ *
+ * The nettle library 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pbkdf2.h"
+#include "base16.h"
+
+#include "getopt.h"
+#include "misc.h"
+
+#define DEFAULT_ITERATIONS 10000
+#define DEFAULT_LENGTH 16
+static void
+usage (FILE *f)
+{
+ fprintf(f, "nettle-pbkdf2 [OPTIONS] SALT\n"
+ "Options:\n"
+ " --help Show this help.\n"
+ " -V, --version Show version information.\n"
+ " -i, --iterations=COUNT Desired iteration count (default %d).\n"
+ " -l, --length=LENGTH Desired output length (octets, default %d)\n"
+ " --raw Raw binary output.\n"
+ " --hex-salt Use hex encoding for the salt.\n",
+ DEFAULT_ITERATIONS, DEFAULT_LENGTH);
+}
+
+#define MAX_PASSWORD 1024
+
+int
+main (int argc, char **argv)
+{
+ unsigned iterations = DEFAULT_ITERATIONS;
+ unsigned output_length = DEFAULT_LENGTH;
+ char password[MAX_PASSWORD];
+ size_t password_length;
+ char *output;
+ size_t salt_length;
+ char *salt;
+ int raw = 0;
+ int hex_salt = 0;
+ int c;
+
+ enum { OPT_HELP = 0x300, OPT_RAW, OPT_HEX_SALT };
+ static const struct option options[] =
+ {
+ /* Name, args, flag, val */
+ { "help", no_argument, NULL, OPT_HELP },
+ { "version", no_argument, NULL, 'V' },
+ { "length", required_argument, NULL, 'l' },
+ { "iterations", required_argument, NULL, 'i' },
+ { "raw", no_argument, NULL, OPT_RAW },
+ { "hex-salt", no_argument, NULL, OPT_HEX_SALT },
+
+ { NULL, 0, NULL, 0 }
+ };
+
+ while ( (c = getopt_long(argc, argv, "Vl:i:", options, NULL)) != -1)
+ switch (c)
+ {
+ default:
+ abort();
+ case OPT_HELP:
+ usage (stdout);
+ return EXIT_SUCCESS;
+ case 'V':
+ printf("nettle-pbkdf2 (" PACKAGE_STRING ")\n");
+ return EXIT_SUCCESS;
+ case 'l':
+ {
+ int arg;
+ arg = atoi (optarg);
+ if (arg <= 0)
+ die ("Invalid length argument: `%s'\n", optarg);
+
+ output_length = arg;
+ }
+ break;
+ case 'i':
+ {
+ int arg;
+ arg = atoi (optarg);
+ if (arg <= 0)
+ die ("Invalid iteration count: `%s'\n", optarg);
+ iterations = arg;
+ }
+ break;
+ case OPT_RAW:
+ raw = 1;
+ break;
+ case OPT_HEX_SALT:
+ hex_salt = 1;
+ break;
+ }
+ argv += optind;
+ argc -= optind;
+
+ if (argc != 1)
+ {
+ usage (stderr);
+ return EXIT_FAILURE;
+ }
+
+ salt = strdup (argv[0]);
+ salt_length = strlen(salt);
+
+ if (hex_salt)
+ {
+ struct base16_decode_ctx base16;
+
+ base16_decode_init (&base16);
+ if (!base16_decode_update (&base16,
+ &salt_length,
+ salt, salt_length, salt)
+ || !base16_decode_final (&base16))
+ die ("Invalid salt (expecting hex encoding).\n");
+ }
+
+ password_length = fread (password, 1, sizeof(password), stdin);
+ if (password_length == sizeof(password))
+ die ("Password input to long. Current limit is %d characters.\n",
+ (int) sizeof(password) - 1);
+ if (ferror (stdin))
+ die ("Reading password input failed: %s.\n", strerror (errno));
+
+ output = xalloc (output_length);
+ pbkdf2_hmac_sha256 (password_length, password, iterations, salt_length, salt,
+ output_length, output);
+
+ free (salt);
+
+ if (raw)
+ fwrite (output, output_length, 1, stdout);
+ else
+ {
+ unsigned i;
+ char hex[BASE16_ENCODE_LENGTH(8) + 1];
+ for (i = 0; i + 8 < output_length; i += 8)
+ {
+ base16_encode_update(hex, 8, output + i);
+ hex[BASE16_ENCODE_LENGTH(8)] = 0;
+ printf("%s%c", hex, i % 64 == 56 ? '\n' : ' ');
+ }
+ base16_encode_update(hex, output_length - i, output + i);
+ hex[BASE16_ENCODE_LENGTH(output_length - i)] = 0;
+ printf("%s\n", hex);
+ }
+ if (fflush(stdout) != 0 )
+ die("Write failed: %s\n", STRERROR(errno));
+
+ return EXIT_SUCCESS;
+}