progs/perftest.c: Use from Glibc syscall numbers.
[catacomb] / progs / cc.h
1 /* -*-c-*-
2 *
3 * Catcrypt common stuff
4 *
5 * (c) 2004 Straylight/Edgeware
6 */
7
8 /*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of Catacomb.
11 *
12 * Catacomb is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Library General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
16 *
17 * Catacomb is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with Catacomb; if not, write to the Free
24 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 * MA 02111-1307, USA.
26 */
27
28 #ifndef CATACOMB_CC_H
29 #define CATACOMB_CC_H
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 /*----- Header files ------------------------------------------------------*/
36
37 #if _FILE_OFFSET_BITS != 64
38 # error "Must set _FILE_OFFSET_BITS to 64."
39 #endif
40
41 #include <stdio.h>
42 #include <string.h>
43 #include <time.h>
44
45 #include <sys/types.h>
46 #include <sys/stat.h>
47
48 #include <mLib/dstr.h>
49
50 #include "buf.h"
51 #include "ct.h"
52 #include "key.h"
53 #include "gcipher.h"
54 #include "ghash.h"
55 #include "gmac.h"
56
57 /*----- Cryptographic object tables ---------------------------------------*/
58
59 typedef struct bulk {
60 const struct bulkops *ops;
61 } bulk;
62
63 typedef struct bulkops {
64 bulk *(*init)(key */*k*/, const char */*calg*/, const char */*halg*/);
65 int (*setup)(bulk */*b*/, gcipher */*cx*/);
66 size_t (*overhead)(bulk */*b*/);
67 const char *(*doit)(bulk */*b*/, uint32 /*seq*/, buf */*bb*/,
68 const void */*p*/, size_t /*sz*/);
69 void (*destroy)(bulk */*b*/);
70 } bulkops;
71
72 struct bulktab {
73 const char *name;
74 const bulkops *encops;
75 const bulkops *decops;
76 };
77
78 extern const struct bulktab bulktab[];
79
80 /* --- Key encapsulation --- */
81
82 typedef struct kem {
83 const struct kemops *ops;
84 key_packdef *kp;
85 void *kd;
86 const gchash *hc;
87 const gccipher *cxc;
88 gcipher *cx;
89 } kem;
90
91 typedef struct kemops {
92 const key_fetchdef *kf; /* Key fetching structure */
93 size_t kdsz; /* Size of the key-data structure */
94 kem *(*init)(key */*k*/, void */*kd*/);
95 int (*doit)(kem */*k*/, dstr */*d*/, ghash */*h*/);
96 const char *(*check)(kem */*k*/);
97 void (*destroy)(kem */*k*/);
98 } kemops;
99
100 struct kemtab {
101 const char *name;
102 const kemops *encops;
103 const kemops *decops;
104 };
105
106 extern const struct kemtab kemtab[];
107
108 /* --- @getkem@ --- *
109 *
110 * Arguments: @key *k@ = the key to load
111 * @const char *app@ = application name
112 * @int wantpriv@ = nonzero if we want to decrypt
113 * @bulk **bc@ = bulk crypto context to set up
114 *
115 * Returns: A key-encapsulating thing.
116 *
117 * Use: Loads a key.
118 */
119
120 extern kem *getkem(key */*k*/, const char */*app*/, int /*wantpriv*/,
121 bulk **/*bc*/);
122
123 /* --- @setupkem@ --- *
124 *
125 * Arguments: @kem *k@ = key-encapsulation thing
126 * @dstr *d@ = key-encapsulation data
127 * @bulk *bc@ = bulk crypto context to set up
128 *
129 * Returns: Zero for success, nonzero on faliure.
130 *
131 * Use: Initializes all the various symmetric things from a KEM.
132 */
133
134 extern int setupkem(kem */*k*/, dstr */*d*/, bulk */*bc*/);
135
136 /* --- @freekem@ --- *
137 *
138 * Arguments: @kem *k@ = key-encapsulation thing
139 *
140 * Returns: ---
141 *
142 * Use: Frees up a key-encapsulation thing.
143 */
144
145 extern void freekem(kem */*k*/);
146
147 /* --- Signing --- */
148
149 typedef struct sig {
150 const struct sigops *ops;
151 key_packdef *kp;
152 void *kd;
153 const gchash *ch;
154 ghash *h;
155 } sig;
156
157 typedef struct sigops {
158 const key_fetchdef *kf; /* Key fetching structure */
159 size_t kdsz; /* Size of the key-data structure */
160 sig *(*init)(key */*k*/, void */*kd*/, const gchash */*hc*/);
161 int (*doit)(sig */*s*/, dstr */*d*/);
162 const char *(*check)(sig */*s*/);
163 void (*destroy)(sig */*s*/);
164 } sigops;
165
166 struct sigtab {
167 const char *name;
168 const sigops *signops;
169 const sigops *verifyops;
170 const gchash *ch;
171 };
172
173 extern const struct sigtab sigtab[];
174
175 /* --- @getsig@ --- *
176 *
177 * Arguments: @key *k@ = the key to load
178 * @const char *app@ = application name
179 * @int wantpriv@ = nonzero if we want to sign
180 *
181 * Returns: A signature-making thing.
182 *
183 * Use: Loads a key and starts hashing.
184 */
185
186 extern sig *getsig(key */*k*/, const char */*app*/, int /*wantpriv*/);
187
188 /* --- @freesig@ --- *
189 *
190 * Arguments: @sig *s@ = signature-making thing
191 *
192 * Returns: ---
193 *
194 * Use: Frees up a signature-making thing
195 */
196
197 extern void freesig(sig */*s*/);
198
199 /*----- File encodings ----------------------------------------------------*/
200
201 /* --- Data encoding --- */
202
203 typedef struct enc {
204 const struct encops *ops;
205 FILE *fp;
206 } enc;
207
208 typedef struct encops {
209 const char *name;
210 const char *rmode, *wmode;
211 int nraw, ncook;
212 enc *(*initenc)(FILE */*fp*/, const char */*msg*/);
213 enc *(*initdec)(FILE */*fp*/,
214 int (*/*func*/)(const char *, void *), void */*p*/);
215 int (*read)(enc */*e*/, void */*p*/, size_t /*sz*/);
216 int (*write)(enc */*e*/, const void */*p*/, size_t /*sz*/);
217 int (*encdone)(enc */*e*/);
218 int (*decdone)(enc */*e*/);
219 void (*destroy)(enc */*e*/);
220 } encops;
221
222 extern const encops enctab[];
223
224 /* --- @getenc@ --- *
225 *
226 * Arguments: @const char *enc@ = name of wanted encoding
227 *
228 * Returns: Pointer to encoder operations.
229 *
230 * Use: Finds a named encoder or decoder.
231 */
232
233 extern const encops *getenc(const char */*enc*/);
234
235 /* --- @checkbdry@ --- *
236 *
237 * Arguments: @const char *b@ = boundary string found
238 * @void *p@ = boundary string wanted
239 *
240 * Returns: Nonzero if the boundary string is the one we wanted.
241 *
242 * Use: Pass as @func@ to @initdec@ if you just want a simple life.
243 */
244
245 extern int checkbdry(const char */*b*/, void */*p*/);
246
247 /* --- @initenc@ --- *
248 *
249 * Arguments: @const encops *eo@ = operations (from @getenc@)
250 * @FILE *fp@ = file handle to attach
251 * @const char *msg@ = banner message
252 *
253 * Returns: The encoder object.
254 *
255 * Use: Initializes an encoder.
256 */
257
258 extern enc *initenc(const encops */*eo*/, FILE */*fp*/, const char */*msg*/);
259
260 /* --- @initdec@ --- *
261 *
262 * Arguments: @const encops *eo@ = operations (from @getenc@)
263 * @FILE *fp@ = file handle to attach
264 * @int (*func)(const char *, void *)@ = banner check function
265 * @void *p@ = argument for @func@
266 *
267 * Returns: The encoder object.
268 *
269 * Use: Initializes an encoder.
270 */
271
272 extern enc *initdec(const encops */*eo*/, FILE */*fp*/,
273 int (*/*func*/)(const char *, void *), void */*p*/);
274
275 /* --- @freeenc@ --- *
276 *
277 * Arguments: @enc *e@ = encoder object
278 *
279 * Returns: ---
280 *
281 * Use: Frees an encoder object.
282 */
283
284 extern void freeenc(enc */*e*/);
285
286 /* --- @cmd_encode@, @cmd_decode@ --- */
287
288 #define CMD_ENCODE { \
289 "encode", cmd_encode, \
290 "encode [-p] [-f FORMAT] [-b LABEL] [-o OUTPUT] [FILE]", \
291 "\
292 Options:\n\
293 \n\
294 -f, --format=FORMAT Encode to FORMAT.\n\
295 -b, --boundary=LABEL PEM boundary is LABEL.\n\
296 -o, --output=FILE Write output to FILE.\n\
297 -p, --progress Show progress on large files.\n\
298 " }
299
300 #define CMD_DECODE { \
301 "decode", cmd_decode, \
302 "decode [-p] [-f FORMAT] [-b LABEL] [-o OUTPUT] [FILE]", \
303 "\
304 Options:\n\
305 \n\
306 -f, --format=FORMAT Decode from FORMAT.\n\
307 -b, --boundary=LABEL PEM boundary is LABEL.\n\
308 -o, --output=FILE Write output to FILE.\n\
309 -p, --progress Show progress on large files.\n\
310 " }
311
312 extern int cmd_encode(int /*argc*/, char */*argv*/[]);
313 extern int cmd_decode(int /*argc*/, char */*argv*/[]);
314
315 /*----- Hash encoding functions -------------------------------------------*/
316
317 /* --- Table --- */
318
319 #define ENCODINGS(_) \
320 _(HEX, hex) \
321 _(BASE64, base64) \
322 _(BASE32, base32)
323
324 enum {
325 #define ENUM(tag, name) ENC_##tag,
326 ENCODINGS(ENUM)
327 #undef ENUM
328 ENC_LIMIT
329 };
330
331 typedef struct encodeops {
332 const char *name;
333 void (*put)(const octet *, size_t, FILE *);
334 size_t (*get)(const char *, octet *, size_t, char **);
335 } encodeops;
336
337 extern const encodeops encodingtab[];
338
339 /* --- @getencoding@ --- *
340 *
341 * Arguments: @const char *ename@ = encoding name
342 *
343 * Returns: Pointer to encoding table entry, or null.
344 *
345 * Use: Finds an encoding entry given its name.
346 */
347
348 extern const encodeops *getencoding(const char */*ename*/);
349
350 /*----- File hashing ------------------------------------------------------*/
351
352 typedef struct fhashstate {
353 const gchash *gch;
354 unsigned f;
355 struct fhent *ents;
356 } fhashstate;
357
358 #define FHF_BINARY 0x100u
359 #define FHF_PROGRESS 0x200u
360 #define FHF_JUNK 0x400u
361
362 #define FHF_MASK 0xff00u
363
364 /* --- @gethash@ --- *
365 *
366 * Arguments: @const char *name@ = pointer to name string
367 *
368 * Returns: Pointer to appropriate hash class.
369 *
370 * Use: Chooses a hash function by name.
371 */
372
373 extern const gchash *gethash(const char */*name*/);
374
375 /* --- @describefile@ --- *
376 *
377 * Arguments: @const struct stat *st@ = pointer to file state
378 *
379 * Returns: A snappy one-word description of the file.
380 */
381
382 extern const char *describefile(const struct stat */*st*/);
383
384 /* --- @fhash_init@ ---*
385 *
386 * Arguments: @fhashstate *fh@ = pointer to fhash state to initialize
387 * @const gchash *gch@ = hash class to set
388 * @unsigned f@ initial flags to set
389 *
390 * Returns: ---
391 *
392 * Use: Initializes an @fhashstate@ structure.
393 */
394
395 extern void fhash_init(fhashstate */*fh*/,
396 const gchash */*gch*/, unsigned /*f*/);
397
398 /* --- @fhash_free@ --- *
399 *
400 * Arguments: @fhashstate *fh@ = pointer to fhash state to free
401 *
402 * Returns: ---
403 *
404 * Use: Frees an fhash state.
405 */
406
407 extern void fhash_free(fhashstate */*fh*/);
408
409 /* --- @fhash@ --- *
410 *
411 * Arguments: @fhashstate *fh@ = pointer to fhash state
412 * @const char *file@ = file name to be hashed (null for stdin)
413 * @void *buf@ = pointer to hash output buffer
414 *
415 * Returns: Zero if it worked, nonzero on error.
416 *
417 * Use: Hashes a file.
418 */
419
420 extern int fhash(fhashstate */*fh*/, const char */*file*/, void */*buf*/);
421
422 /* --- @fhash_junk@ --- *
423 *
424 * Arguments: @fhashstate *fh@ = pointer to fhash state
425 * @void (*func)(const char *, const struct stat *, void *)@
426 * @void *p@ = pointer to pass to function
427 *
428 * Returns: Positive if any junk was found, negative on error, zero if
429 * everything was fine.
430 *
431 * Use: Reports junk files in any directories covered by the hash
432 * state.
433 */
434
435 extern int fhash_junk(fhashstate */*fh*/,
436 int (*/*func*/)(const char *,
437 const struct stat *,
438 void *),
439 void */*p*/);
440
441 /* --- @hfparse@ --- *
442 *
443 * Arguments: @hfpctx *hfp@ = pointer to the context structure
444 *
445 * Returns: A code indicating what happened.
446 *
447 * Use: Parses a line from the input file.
448 */
449
450 enum { /* Meaning and members set */
451 HF_FILE, /* File hash: @dline@ and @hbuf@ */
452 HF_ENC, /* Encoding: @ee@ */
453 HF_HASH, /* Hash function: @gch@ */
454 HF_ESC, /* Name escape: @f@ */
455 HF_EOF, /* End of file */
456 HF_BAD /* Unrecognized line */
457 };
458
459 typedef struct hfpctx {
460 unsigned f; /* Flags to read */
461 #define HFF_ESCAPE 1u /* File names are escaped */
462 FILE *fp; /* Input file to read */
463 dstr *dline; /* Line contents, corrupted */
464 const gchash *gch; /* Hash function to use */
465 const encodeops *ee; /* Encoding to apply to hashes */
466 dstr *dfile; /* File name for @HF_FILE@ lines */
467 octet *hbuf; /* Output buffer for hash data */
468 } hfpctx;
469
470 extern int hfparse(hfpctx */*hfp*/);
471
472 /*----- String I/O --------------------------------------------------------*/
473
474 #define GSF_RAW 4096u
475 #define GSF_FILE 0u
476 #define GSF_STRING 8192u
477
478 #define GSF_MASK 61440u
479
480 /* --- @getstring@ --- *
481 *
482 * Arguments: @void *in@ = input source
483 * @dstr *d@ = destination string
484 * @unsigned f@ = input flags
485 *
486 * Returns: Zero if OK, nonzero on end-of-file.
487 *
488 * Use: Reads a filename (or something similar) from a stream.
489 */
490
491 extern int getstring(void */*in*/, dstr */*d*/, unsigned /*f*/);
492
493 /* --- @putstring@ --- *
494 *
495 * Arguments: @FILE *fp@ = stream to write on
496 * @const char *p@ = pointer to text
497 * @unsigned f@ = output flags
498 *
499 * Returns: ---
500 *
501 * Use: Emits a string to a stream.
502 */
503
504 extern void putstring(FILE */*fp*/, const char */*p*/, unsigned /*f*/);
505
506 /*----- Lists of things ---------------------------------------------------*/
507
508 /* --- @LIST(STRING, FP, END-TEST, NAME-EXPR)@ --- *
509 *
510 * Produce list of things. Requires @i@ and @w@ variables in scope.
511 * END-TEST and NAME-EXPR are in terms of @i@.
512 */
513
514 #define LIST(what, fp, end, name) do { \
515 fputs(what ":\n ", fp); \
516 w = 2; \
517 for (i = 0; end; i++) { \
518 if (w == 2) \
519 w += strlen(name); \
520 else { \
521 if (strlen(name) + w > 76) { \
522 fputs("\n ", fp); \
523 w = 2 + strlen(name); \
524 } else { \
525 fputc(' ', fp); \
526 w += strlen(name) + 1; \
527 } \
528 } \
529 fputs(name, fp); \
530 } \
531 fputc('\n', fp); \
532 } while (0)
533
534 #define STDLISTS(LI) \
535 LI("Hash functions", hash, \
536 ghashtab[i], ghashtab[i]->name) \
537 LI("Encryption schemes", enc, \
538 gciphertab[i], gciphertab[i]->name) \
539 LI("Message authentication schemes", mac, \
540 gmactab[i], gmactab[i]->name) \
541 LI("Elliptic curves", ec, \
542 ectab[i].name, ectab[i].name) \
543 LI("Diffie-Hellman groups", dh, \
544 ptab[i].name, ptab[i].name)
545
546 #define LIDECL(text, tag, test, name) \
547 static void show_##tag(void);
548
549 #define LIDEF(text, tag, test, name) \
550 static void show_##tag(void) \
551 { \
552 unsigned i, w; \
553 LIST(text, stdout, test, name); \
554 }
555
556 #define LIENT(text, tag, test, name) \
557 { #tag, show_##tag },
558
559 struct listent {
560 const char *name;
561 void (*list)(void);
562 };
563
564 #define MAKELISTTAB(listtab, LISTS) \
565 LISTS(LIDECL) \
566 static const struct listent listtab[] = { \
567 LISTS(LIENT) \
568 { 0, 0 } \
569 }; \
570 LISTS(LIDEF)
571
572 extern int displaylists(const struct listent */*listtab*/,
573 char *const /*argv*/[]);
574
575 /*----- Progress indicators -----------------------------------------------*/
576
577 typedef struct fprogress {
578 const char *bp;
579 off_t o, sz, olast;
580 time_t start, last;
581 char name[24];
582 } fprogress;
583
584 /* --- @fprogress_init@ --- *
585 *
586 * Arguments: @fprogress *f@ = progress context to be initialized
587 * @const char *name@ = file name string to show
588 * @FILE *fp@ = file we're reading from
589 *
590 * Returns: Zero on success, nonzero if the file's state is now broken.
591 *
592 * Use: Initializes a progress context. Nothing is actually
593 * displayed yet.
594 */
595
596 extern int fprogress_init(fprogress */*f*/,
597 const char */*name*/, FILE */*fp*/);
598
599 /* --- @fprogress_update@ --- *
600 *
601 * Arguments: @fprogress *f@ = progress context
602 * @size_t n@ = how much progress has been made
603 *
604 * Returns: ---
605 *
606 * Use: Maybe updates the display to show that some progress has been
607 * made.
608 */
609
610 extern void fprogress_update(fprogress */*f*/, size_t /*n*/);
611
612 /* --- @fprogress_clear@ --- *
613 *
614 * Arguments: @fprogress *f@ = progress context
615 *
616 * Returns: ---
617 *
618 * Use: Clears the progress display from the screen.
619 */
620
621 extern void fprogress_clear(fprogress */*f*/);
622
623 /* --- @fprogress_done@ --- *
624 *
625 * Arguments: @fprogress *f@ = progress context
626 *
627 * Returns: ---
628 *
629 * Use: Clear up the progress context and removes any display.
630 */
631
632 extern void fprogress_done(fprogress */*f*/);
633
634 /*----- Subcommand dispatch -----------------------------------------------*/
635
636 typedef struct cmd {
637 const char *name;
638 int (*cmd)(int /*argc*/, char */*argv*/[]);
639 const char *usage;
640 const char *help;
641 } cmd;
642
643 extern void version(FILE */*fp*/);
644 extern void help_global(FILE */*fp*/);
645
646 /* --- @findcmd@ --- *
647 *
648 * Arguments: @const cmd *cmds@ = pointer to command table
649 * @const char *name@ = a command name
650 *
651 * Returns: Pointer to the command structure.
652 *
653 * Use: Looks up a command by name. If the command isn't found, an
654 * error is reported and the program is terminated.
655 */
656
657 const cmd *findcmd(const cmd */*cmds*/, const char */*name*/);
658
659 /* --- @sc_help@ --- *
660 *
661 * Arguments: @const cmd *cmds@ = pointer to command table
662 * @FILE *fp@ = output file handle
663 * @char *const *argv@ = remaining arguments
664 *
665 * Returns: ---
666 *
667 * Use: Prints a help message, maybe with help about subcommands.
668 */
669
670 extern void sc_help(const cmd */*cmds*/, FILE */*fp*/,
671 char *const */*argv*/);
672
673 /*----- That's all, folks -------------------------------------------------*/
674
675 #ifdef __cplusplus
676 }
677 #endif
678
679 #endif