16040c386ce710fa7416976ca6a65b4b9e4ee292
[platform/upstream/nettle.git] / tools / nettle-pbkdf2.c
1 /* nettle-pbkdf2.c
2
3    Command-line tool for pbkdf2 hashing.
4
5    Copyright (C) 2013 Niels Möller
6
7    This file is part of GNU Nettle.
8
9    GNU Nettle is free software: you can redistribute it and/or
10    modify it under the terms of either:
11
12      * the GNU Lesser General Public License as published by the Free
13        Software Foundation; either version 3 of the License, or (at your
14        option) any later version.
15
16    or
17
18      * the GNU General Public License as published by the Free
19        Software Foundation; either version 2 of the License, or (at your
20        option) any later version.
21
22    or both in parallel, as here.
23
24    GNU Nettle is distributed in the hope that it will be useful,
25    but WITHOUT ANY WARRANTY; without even the implied warranty of
26    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27    General Public License for more details.
28
29    You should have received copies of the GNU General Public License and
30    the GNU Lesser General Public License along with this program.  If
31    not, see http://www.gnu.org/licenses/.
32 */
33
34 #if HAVE_CONFIG_H
35 # include "config.h"
36 #endif
37
38 #include <errno.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42
43 #include "pbkdf2.h"
44 #include "base16.h"
45
46 #include "getopt.h"
47 #include "misc.h"
48
49 #define DEFAULT_ITERATIONS 10000
50 #define DEFAULT_LENGTH 16
51 static void
52 usage (FILE *f)
53 {
54   fprintf(f, "Usage: nettle-pbkdf2 [OPTIONS] SALT\n"
55           "Options:\n"
56           "  --help                 Show this help.\n"
57           "  -V, --version          Show version information.\n"
58           "  -i, --iterations=COUNT Desired iteration count (default %d).\n"
59           "  -l, --length=LENGTH    Desired output length (octets, default %d)\n"
60           "  --raw                  Raw binary output.\n"
61           "  --hex-salt             Use hex encoding for the salt.\n",
62           DEFAULT_ITERATIONS, DEFAULT_LENGTH);
63 }
64
65 #define MAX_PASSWORD 1024
66
67 int
68 main (int argc, char **argv)
69 {
70   unsigned iterations = DEFAULT_ITERATIONS;
71   unsigned output_length = DEFAULT_LENGTH;
72   char password[MAX_PASSWORD];
73   size_t password_length;
74   char *output;
75   size_t salt_length;
76   char *salt;
77   int raw = 0;
78   int hex_salt = 0;
79   int c;
80
81   enum { OPT_HELP = 0x300, OPT_RAW, OPT_HEX_SALT };
82   static const struct option options[] =
83     {
84       /* Name, args, flag, val */
85       { "help", no_argument, NULL, OPT_HELP },
86       { "version", no_argument, NULL, 'V' },
87       { "length", required_argument, NULL, 'l' },
88       { "iterations", required_argument, NULL, 'i' },
89       { "raw", no_argument, NULL, OPT_RAW },
90       { "hex-salt", no_argument, NULL, OPT_HEX_SALT },
91
92       { NULL, 0, NULL, 0 }
93     };
94
95   while ( (c = getopt_long(argc, argv, "Vl:i:", options, NULL)) != -1)
96     switch (c)
97       {
98       default:
99         abort();
100       case '?':
101         usage (stderr);
102         return EXIT_FAILURE;
103       case OPT_HELP:
104         usage (stdout);
105         return EXIT_SUCCESS;
106       case 'V':
107         printf("nettle-pbkdf2 (" PACKAGE_STRING ")\n");
108         return EXIT_SUCCESS;
109       case 'l':
110         {
111           int arg;
112           arg = atoi (optarg);
113           if (arg <= 0)
114             die ("Invalid length argument: `%s'\n", optarg);
115
116           output_length = arg;
117         }
118         break;
119       case 'i':
120         {
121           int arg;
122           arg = atoi (optarg);
123           if (arg <= 0)
124             die ("Invalid iteration count: `%s'\n", optarg);
125           iterations = arg;
126         }
127         break;
128       case OPT_RAW:
129         raw = 1;
130         break;
131       case OPT_HEX_SALT:
132         hex_salt = 1;
133         break;
134       }
135   argv += optind;
136   argc -= optind;
137
138   if (argc != 1)
139     {
140       usage (stderr);
141       return EXIT_FAILURE;
142     }
143
144   salt = strdup (argv[0]);
145   salt_length = strlen(salt);
146   
147   if (hex_salt)
148     {
149       struct base16_decode_ctx base16;
150
151       base16_decode_init (&base16);
152       if (!base16_decode_update (&base16,
153                                  &salt_length,
154                                  salt, salt_length, salt)
155           || !base16_decode_final (&base16))
156         die ("Invalid salt (expecting hex encoding).\n");
157     }
158   
159   password_length = fread (password, 1, sizeof(password), stdin);
160   if (password_length == sizeof(password))
161     die ("Password input too long. Current limit is %d characters.\n",
162          (int) sizeof(password) - 1);
163   if (ferror (stdin))
164     die ("Reading password input failed: %s.\n", strerror (errno));
165
166   output = xalloc (output_length);
167   pbkdf2_hmac_sha256 (password_length, password, iterations, salt_length, salt,
168                       output_length, output);
169
170   free (salt);
171
172   if (raw)
173     fwrite (output, output_length, 1, stdout);
174   else
175     {
176       unsigned i;
177       char hex[BASE16_ENCODE_LENGTH(8) + 1];
178       for (i = 0; i + 8 < output_length; i += 8)
179         {
180           base16_encode_update(hex, 8, output + i);
181           hex[BASE16_ENCODE_LENGTH(8)] = 0;
182           printf("%s%c", hex, i % 64 == 56 ? '\n' : ' ');
183         }
184       base16_encode_update(hex, output_length - i, output + i);
185       hex[BASE16_ENCODE_LENGTH(output_length - i)] = 0;
186       printf("%s\n", hex);
187     }
188   free (output);
189
190   if (fflush(stdout) != 0 )
191     die("Write failed: %s\n", STRERROR(errno));
192
193   return EXIT_SUCCESS;
194 }