]>
Commit | Line | Data |
---|---|---|
0c1f3509 MG |
1 | /*- |
2 | * Copyright 2009 Colin Percival | |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | |
13 | * | |
14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |
15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
24 | * SUCH DAMAGE. | |
25 | */ | |
26 | #include "scrypt_platform.h" | |
27 | ||
28 | #include <stdint.h> | |
29 | #include <stdio.h> | |
30 | #include <stdlib.h> | |
31 | #include <string.h> | |
32 | ||
33 | #include "getopt.h" | |
34 | #include "humansize.h" | |
35 | #include "insecure_memzero.h" | |
36 | #include "readpass.h" | |
37 | #include "scryptenc.h" | |
38 | #include "warnp.h" | |
39 | ||
40 | static void | |
41 | usage(void) | |
42 | { | |
43 | ||
44 | fprintf(stderr, | |
45 | "usage: scrypt {enc | dec} [-f] [-M maxmem]" | |
46 | " [-m maxmemfrac]\n" | |
47 | " [-t maxtime] [-v] [-P] infile [outfile]\n" | |
48 | " scrypt --version\n"); | |
49 | exit(1); | |
50 | } | |
51 | ||
52 | int | |
53 | main(int argc, char *argv[]) | |
54 | { | |
55 | FILE * infile; | |
56 | FILE * outfile; | |
57 | int devtty = 1; | |
58 | int dec = 0; | |
59 | size_t maxmem = 0; | |
60 | int force_resources = 0; | |
61 | uint64_t maxmem64; | |
62 | double maxmemfrac = 0.5; | |
63 | double maxtime = 300.0; | |
64 | const char * ch; | |
65 | char * passwd; | |
66 | int rc; | |
67 | int verbose = 0; | |
68 | ||
69 | WARNP_INIT; | |
70 | ||
71 | /* We should have "enc" or "dec" first. */ | |
72 | if (argc < 2) | |
73 | usage(); | |
74 | if (strcmp(argv[1], "enc") == 0) { | |
75 | maxmem = 0; | |
76 | maxmemfrac = 0.125; | |
77 | maxtime = 5.0; | |
78 | } else if (strcmp(argv[1], "dec") == 0) { | |
79 | dec = 1; | |
80 | } else if (strcmp(argv[1], "--version") == 0) { | |
81 | fprintf(stdout, "scrypt %s\n", PACKAGE_VERSION); | |
82 | exit(0); | |
83 | } else { | |
84 | warn0("First argument must be 'enc' or 'dec'.\n"); | |
85 | usage(); | |
86 | } | |
87 | argc--; | |
88 | argv++; | |
89 | ||
90 | /* Parse arguments. */ | |
91 | while ((ch = GETOPT(argc, argv)) != NULL) { | |
92 | GETOPT_SWITCH(ch) { | |
93 | GETOPT_OPT("-f"): | |
94 | force_resources = 1; | |
95 | break; | |
96 | GETOPT_OPTARG("-M"): | |
97 | if (humansize_parse(optarg, &maxmem64)) { | |
98 | warn0("Could not parse the parameter to -M."); | |
99 | exit(1); | |
100 | } | |
101 | if (maxmem64 > SIZE_MAX) { | |
102 | warn0("The parameter to -M is too large."); | |
103 | exit(1); | |
104 | } | |
105 | maxmem = (size_t)maxmem64; | |
106 | break; | |
107 | GETOPT_OPTARG("-m"): | |
108 | maxmemfrac = strtod(optarg, NULL); | |
109 | break; | |
110 | GETOPT_OPTARG("-t"): | |
111 | maxtime = strtod(optarg, NULL); | |
112 | break; | |
113 | GETOPT_OPT("-v"): | |
114 | verbose = 1; | |
115 | break; | |
116 | GETOPT_OPT("-P"): | |
117 | devtty = 0; | |
118 | break; | |
119 | GETOPT_MISSING_ARG: | |
120 | warn0("Missing argument to %s\n", ch); | |
121 | usage(); | |
122 | GETOPT_DEFAULT: | |
123 | warn0("illegal option -- %s\n", ch); | |
124 | usage(); | |
125 | } | |
126 | } | |
127 | argc -= optind; | |
128 | argv += optind; | |
129 | ||
130 | /* We must have one or two parameters left. */ | |
131 | if ((argc < 1) || (argc > 2)) | |
132 | usage(); | |
133 | ||
134 | /* If the input isn't stdin, open the file. */ | |
135 | if (strcmp(argv[0], "-")) { | |
136 | if ((infile = fopen(argv[0], "rb")) == NULL) { | |
137 | warnp("Cannot open input file: %s", argv[0]); | |
138 | exit(1); | |
139 | } | |
140 | } else { | |
141 | infile = stdin; | |
142 | } | |
143 | ||
144 | /* If we have an output file, open it. */ | |
145 | if (argc > 1) { | |
146 | if ((outfile = fopen(argv[1], "wb")) == NULL) { | |
147 | warnp("Cannot open output file: %s", argv[1]); | |
148 | exit(1); | |
149 | } | |
150 | } else { | |
151 | outfile = stdout; | |
152 | } | |
153 | ||
154 | /* Prompt for a password. */ | |
155 | if (readpass(&passwd, "Please enter passphrase", | |
156 | (dec || !devtty) ? NULL : "Please confirm passphrase", devtty)) | |
157 | exit(1); | |
158 | ||
159 | /* Encrypt or decrypt. */ | |
160 | if (dec) | |
161 | rc = scryptdec_file(infile, outfile, (uint8_t *)passwd, | |
162 | strlen(passwd), maxmem, maxmemfrac, maxtime, verbose, | |
163 | force_resources); | |
164 | else | |
165 | rc = scryptenc_file(infile, outfile, (uint8_t *)passwd, | |
166 | strlen(passwd), maxmem, maxmemfrac, maxtime, verbose); | |
167 | ||
168 | /* Zero and free the password. */ | |
169 | insecure_memzero(passwd, strlen(passwd)); | |
170 | free(passwd); | |
171 | ||
172 | /* Close any files we opened. */ | |
173 | if (infile != stdin) | |
174 | fclose(infile); | |
175 | if (outfile != stdout) | |
176 | fclose(outfile); | |
177 | ||
178 | /* If we failed, print the right error message and exit. */ | |
179 | if (rc != 0) { | |
180 | switch (rc) { | |
181 | case 1: | |
182 | warnp("Error determining amount of available memory"); | |
183 | break; | |
184 | case 2: | |
185 | warnp("Error reading clocks"); | |
186 | break; | |
187 | case 3: | |
188 | warnp("Error computing derived key"); | |
189 | break; | |
190 | case 4: | |
191 | warnp("Error reading salt"); | |
192 | break; | |
193 | case 5: | |
194 | warnp("OpenSSL error"); | |
195 | break; | |
196 | case 6: | |
197 | warnp("Error allocating memory"); | |
198 | break; | |
199 | case 7: | |
200 | warn0("Input is not valid scrypt-encrypted block"); | |
201 | break; | |
202 | case 8: | |
203 | warn0("Unrecognized scrypt format version"); | |
204 | break; | |
205 | case 9: | |
206 | warn0("Decrypting file would require too much memory"); | |
207 | break; | |
208 | case 10: | |
209 | warn0("Decrypting file would take too much CPU time"); | |
210 | break; | |
211 | case 11: | |
212 | warn0("Passphrase is incorrect"); | |
213 | break; | |
214 | case 12: | |
215 | warnp("Error writing file: %s", | |
216 | (argc > 1) ? argv[1] : "standard output"); | |
217 | break; | |
218 | case 13: | |
219 | warnp("Error reading file: %s", argv[0]); | |
220 | break; | |
221 | } | |
222 | exit(1); | |
223 | } | |
224 | ||
225 | return (0); | |
226 | } |