]> Pileus Git - ~andy/crypt/blob - main.c
Add some initial code
[~andy/crypt] / main.c
1 #include <stdint.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include <getopt.h>
7
8 #include "util.h"
9
10 #include "none.h"
11 #include "sha2.h"
12 #include "scrypt.h"
13
14 /* Options */
15 #define OPT(flag, opt, name, desc) \
16         { name "\0" desc, flag, NULL, opt }
17
18 #define OPT_OPT(opt)  ((opt).val)
19 #define OPT_LEN(opt)  ((int)strlen((opt).name))
20 #define OPT_NAME(opt) ((opt).name)
21 #define OPT_DESC(opt) (&(opt).name[OPT_LEN(opt)])
22
23 /* Crypto functions */
24 typedef enum {
25         NONE,
26         SHA256,
27         SCRYPT,
28 } crypt_t;
29
30 /* Options */
31 static struct option long_options[] = {
32         OPT( 0, 'e', "encrypt",  "Encrypt data"            ),
33         OPT( 0, 'd', "decrypt",  "Decrypt data"            ),
34         OPT( 0, 't', "test",     "Run self tests"          ),
35         OPT( 1, 'f', "function", "Specify crypto function" ),
36         OPT( 1, 'i', "input",    "Input file"              ),
37         OPT( 1, 'o', "output",   "Output file"             ),
38         OPT( 0, 'q', "quiet",    "Decrease verbosity"      ),
39         OPT( 0, 'v', "verbose",  "Increase verbosity"      ),
40         OPT( 0, 'h', "help",     "Print usage information" ),
41         { },
42 };
43
44 static struct {
45         const char *name;
46         const char *desc;
47 } crypt_info[] = {
48         [NONE  ] { "none",   "No-op encryption/decryption" },
49         [SHA256] { "sha256", "SHA-256 hash function" },
50         [SCRYPT] { "scrypt", "Memory intensive hash function" },
51 };
52
53 /* Settings */
54 static int      opt_decrypt;
55 static int      opt_encrypt;
56 static crypt_t  opt_crypt;
57 static char    *opt_instr;
58 static char    *opt_outstr;
59 static FILE    *opt_input;
60 static FILE    *opt_output;
61 static int      opt_level;
62 static int      opt_test;
63
64 /* Helpers */
65 static const char *crypt_name(crypt_t id)
66 {
67         if (id < 0 || id >= N_ELEM(crypt_info))
68                 error("invalid crypt id %d", id);
69         return crypt_info[id].name;
70 }
71
72 static crypt_t crypt_id(const char *name)
73 {
74         for (int i = 0; i < N_ELEM(crypt_info); i++)
75                 if (!strcmp(name, crypt_info[i].name))
76                         return (crypt_t)i;
77         error("invalid crypt function %s", name);
78         return NONE;
79 }
80
81 static void usage(const char *name)
82 {
83         printf("Usage:\n");
84         printf("  %s [OPTION...]\n", name);
85         printf("\n");
86         printf("Options:\n");
87         for (int i = 0; long_options[i].name; i++)
88                 printf("  -%c, --%-10s  %s\n",
89                         long_options[i].val,
90                         long_options[i].name,
91                         long_options[i].name + 1 +
92                                 strlen(long_options[i].name));
93         printf("\n");
94         printf("Crypto functions:\n");
95         for (int i = 0; i < N_ELEM(crypt_info); i++)
96                 printf("  %-16s  %s\n",
97                         crypt_info[i].name,
98                         crypt_info[i].desc);
99 }
100
101 static void parse(int argc, char **argv)
102 {
103         while (1) {
104                 int c = getopt_long(argc, argv, "edf:i:o:qvth", long_options, NULL);
105                 if (c == -1)
106                         break;
107                 switch (c) {
108                         case 'e':
109                                 opt_encrypt = 1;
110                                 break;
111                         case 'd':
112                                 opt_decrypt = 1;
113                                 break;
114                         case 't':
115                                 opt_test = 1;
116                                 break;
117                         case 'f':
118                                 opt_crypt = crypt_id(optarg);
119                                 break;
120                         case 'i':
121                                 opt_input  = fopen(optarg, "rb");
122                                 opt_instr  = optarg;
123                                 break;
124                         case 'o':
125                                 opt_output = fopen(optarg, "wb+");
126                                 opt_outstr = optarg;
127                                 break;
128                         case 'q':
129                                 opt_level--;
130                                 break;
131                         case 'v':
132                                 opt_level++;
133                                 break;
134                         case 'h':
135                                 usage(argv[0]);
136                                 exit(0);
137                         case '?':
138                                 exit(1);
139                         default:
140                                 exit(2);
141                 }
142         }
143 }
144
145 void run(crypt_t id, FILE *in, FILE *out)
146 {
147         uint8_t dec[512], enc[512];
148         uint8_t sum[512];
149         int len;
150
151         switch (id) {
152                 case NONE:
153                         while ((len = fread(&dec, 1, 512, in)) > 0) {
154                                 //debug("<< [%s]:%d", dec, len);
155                                 none_enc(dec, enc, len);
156                                 //debug(">> [%s]:%d", enc, len);
157                                 fwrite(enc, 1, len, out);
158                         }
159                         break;
160                 case SHA256:
161                         break;
162                 case SCRYPT:
163                         while ((len = fread(&dec, 1, 512, in)) > 0) {
164                                 scrypt_hash(dec, sum);
165                         }
166                         break;
167         }
168 }
169
170 /* Test */
171 static void test(crypt_t id)
172 {
173         if (!opt_test)
174                 return;
175
176         switch (id) {
177                 case NONE:   none_test();   break;
178                 case SHA256: sha256_test(); break;
179                 case SCRYPT: scrypt_test(); break;
180         }
181 }
182
183 /* Main */
184 int main(int argc, char **argv)
185 {
186         /* Parse arguments */
187         opt_instr  = "stdin";
188         opt_outstr = "stdout";
189         opt_input  = stdin;
190         opt_output = stdout;
191         parse(argc, argv);
192         loglevel = opt_level;
193
194         /* Debug output */
195         debug("encrypt:  %s", opt_encrypt ? "true" : "false");
196         debug("decrypt:  %s", opt_decrypt ? "true" : "false");
197         debug("crypto:   %s", crypt_name(opt_crypt));
198         debug("loglevel: %d", opt_level);
199         debug("input:    %s", opt_instr);
200         debug("output:   %s", opt_outstr);
201
202         /* Run tests */
203         test(opt_crypt);
204
205         /* Main loop */
206         run(opt_crypt, opt_input, opt_output);
207
208         return 0;
209 };
210