chiark / gitweb /
Merge branch '2.4.x' into 2.5.x
[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