chiark / gitweb /
mpint: Fix misbehaviour on larger-than-mpw integer types.
[catacomb] / cc.h
1 /* -*-c-*-
2  *
3  * $Id$
4  *
5  * Catcrypt common stuff
6  *
7  * (c) 2004 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of Catacomb.
13  *
14  * Catacomb is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Library General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  * 
19  * Catacomb is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Library General Public License for more details.
23  * 
24  * You should have received a copy of the GNU Library General Public
25  * License along with Catacomb; if not, write to the Free
26  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27  * MA 02111-1307, USA.
28  */
29
30 #ifndef CATACOMB_CC_H
31 #define CATACOMB_CC_H
32
33 #ifdef __cplusplus
34   extern "C" {
35 #endif
36
37 /*----- Header files ------------------------------------------------------*/
38
39 #include <stdio.h>
40 #include <string.h>
41
42 #include <mLib/dstr.h>
43
44 #include "key.h"
45 #include "gcipher.h"
46 #include "ghash.h"
47 #include "gmac.h"
48
49 /*----- Data structures ---------------------------------------------------*/
50
51 /* --- Key encapsulation --- */
52
53 typedef struct kem {
54   const struct kemops *ops;
55   key_packdef *kp;
56   void *kd;
57   const gchash *h;
58   const gccipher *c, *cx;
59   const gcmac *m;
60 } kem;
61
62 typedef struct kemops {
63   const key_fetchdef *kf;               /* Key fetching structure */
64   size_t kdsz;                          /* Size of the key-data structure */
65   kem *(*init)(key */*k*/, void */*kd*/);
66   int (*doit)(kem */*k*/, dstr */*d*/, ghash */*h*/);
67   const char *(*check)(kem */*k*/);
68   void (*destroy)(kem */*k*/);
69 } kemops;
70
71 struct kemtab {
72   const char *name;
73   const kemops *encops;
74   const kemops *decops;
75 };
76
77 extern const struct kemtab kemtab[];
78
79 /* --- Signing --- */
80
81 typedef struct sig {
82   const struct sigops *ops;
83   key_packdef *kp;
84   void *kd;
85   ghash *h;
86 } sig;
87
88 typedef struct sigops {
89   const key_fetchdef *kf;               /* Key fetching structure */
90   size_t kdsz;                          /* Size of the key-data structure */
91   sig *(*init)(key */*k*/, void */*kd*/, const gchash */*hc*/);
92   int (*doit)(sig */*s*/, dstr */*d*/);
93   const char *(*check)(sig */*s*/);
94   void (*destroy)(sig */*s*/);
95 } sigops;
96
97 struct sigtab {
98   const char *name;
99   const sigops *signops;
100   const sigops *verifyops;
101   const gchash *ch;
102 };
103     
104 extern const struct sigtab sigtab[];
105
106 /* --- Data encoding --- */
107
108 typedef struct enc {
109   const struct encops *ops;
110   FILE *fp;
111 } enc;
112
113 typedef struct encops {
114   const char *name;
115   const char *rmode, *wmode;
116   enc *(*initenc)(FILE */*fp*/, const char */*msg*/);
117   enc *(*initdec)(FILE */*fp*/,
118                   int (*/*func*/)(const char *, void *), void */*p*/);
119   int (*read)(enc */*e*/, void */*p*/, size_t /*sz*/);
120   int (*write)(enc */*e*/, const void */*p*/, size_t /*sz*/);
121   int (*encdone)(enc */*e*/);
122   int (*decdone)(enc */*e*/);
123   void (*destroy)(enc */*e*/);
124 } encops;
125
126 extern const encops enctab[];
127
128 /*----- Functions provided ------------------------------------------------*/
129
130 /* --- @getkem@ --- *
131  *
132  * Arguments:   @key *k@ = the key to load
133  *              @const char *app@ = application name
134  *              @int wantpriv@ = nonzero if we want to decrypt
135  *
136  * Returns:     A key-encapsulating thing.
137  *
138  * Use:         Loads a key.
139  */
140
141 extern kem *getkem(key */*k*/, const char */*app*/, int /*wantpriv*/);
142
143 /* --- @setupkem@ --- *
144  *
145  * Arguments:   @kem *k@ = key-encapsulation thing
146  *              @dstr *d@ = key-encapsulation data
147  *              @gcipher **cx@ = key-expansion function (for IVs)
148  *              @gcipher **c@ = where to put initialized encryption scheme
149  *              @gmac **m@ = where to put initialized MAC
150  *
151  * Returns:     Zero for success, nonzero on faliure.
152  *
153  * Use:         Initializes all the various symmetric things from a KEM.
154  */
155
156 extern int setupkem(kem */*k*/, dstr */*d*/,
157                     gcipher **/*cx*/, gcipher **/*c*/, gmac **/*m*/);
158
159 /* --- @freekem@ --- *
160  *
161  * Arguments:   @kem *k@ = key-encapsulation thing
162  *
163  * Returns:     ---
164  *
165  * Use:         Frees up a key-encapsulation thing.
166  */
167
168 extern void freekem(kem */*k*/);
169
170 /* --- @getsig@ --- *
171  *
172  * Arguments:   @key *k@ = the key to load
173  *              @const char *app@ = application name
174  *              @int wantpriv@ = nonzero if we want to sign
175  *
176  * Returns:     A signature-making thing.
177  *
178  * Use:         Loads a key and starts hashing.
179  */
180
181 extern sig *getsig(key */*k*/, const char */*app*/, int /*wantpriv*/);
182
183 /* --- @freesig@ --- *
184  *
185  * Arguments:   @sig *s@ = signature-making thing
186  *
187  * Returns:     ---
188  *
189  * Use:         Frees up a signature-making thing
190  */
191
192 extern void freesig(sig */*s*/);
193
194 /* --- @getenc@ --- *
195  *
196  * Arguments:   @const char *enc@ = name of wanted encoding
197  *
198  * Returns:     Pointer to encoder operations.
199  *
200  * Use:         Finds a named encoder or decoder.
201  */
202
203 extern const encops *getenc(const char */*enc*/);
204
205 /* --- @checkbdry@ --- *
206  *
207  * Arguments:   @const char *b@ = boundary string found
208  *              @void *p@ = boundary string wanted
209  *
210  * Returns:     Nonzero if the boundary string is the one we wanted.
211  *
212  * Use:         Pass as @func@ to @initdec@ if you just want a simple life.
213  */
214
215 extern int checkbdry(const char */*b*/, void */*p*/);
216
217 /* --- @initenc@ --- *
218  *
219  * Arguments:   @const encops *eo@ = operations (from @getenc@)
220  *              @FILE *fp@ = file handle to attach
221  *              @const char *msg@ = banner message
222  *
223  * Returns:     The encoder object.
224  *
225  * Use:         Initializes an encoder.
226  */
227
228 extern enc *initenc(const encops */*eo*/, FILE */*fp*/, const char */*msg*/);
229
230 /* --- @initdec@ --- *
231  *
232  * Arguments:   @const encops *eo@ = operations (from @getenc@)
233  *              @FILE *fp@ = file handle to attach
234  *              @int (*func)(const char *, void *)@ = banner check function
235  *              @void *p@ = argument for @func@
236  *
237  * Returns:     The encoder object.
238  *
239  * Use:         Initializes an encoder.
240  */
241
242 extern enc *initdec(const encops */*eo*/, FILE */*fp*/,
243                     int (*/*func*/)(const char *, void *), void */*p*/);
244
245 /* --- @freeenc@ --- *
246  *
247  * Arguments:   @enc *e@ = encoder object
248  *
249  * Returns:     ---
250  *
251  * Use:         Frees an encoder object.
252  */
253
254 extern void freeenc(enc */*e*/);
255
256 /* --- @cmd_encode@, @cmd_decode@ --- */
257
258 #define CMD_ENCODE {                                                    \
259   "encode", cmd_encode,                                                 \
260     "encode [-f FORMAT] [-b LABEL] [-o OUTPUT] [FILE]",                 \
261     "\
262 Options:\n\
263 \n\
264 -f, --format=FORMAT     Encode to FORMAT.\n\
265 -b, --boundary=LABEL    PEM boundary is LABEL.\n\
266 -o, --output=FILE       Write output to FILE.\n\
267 " }
268
269 #define CMD_DECODE {                                                    \
270   "decode", cmd_decode,                                                 \
271     "decode [-f FORMAT] [-b LABEL] [-o OUTPUT] [FILE]",                 \
272     "\
273 Options:\n\
274 \n\
275 -f, --format=FORMAT     Decode from FORMAT.\n\
276 -b, --boundary=LABEL    PEM boundary is LABEL.\n\
277 -o, --output=FILE       Write output to FILE.\n\
278 " }
279
280 extern int cmd_encode(int /*argc*/, char */*argv*/[]);
281 extern int cmd_decode(int /*argc*/, char */*argv*/[]);
282
283 /* --- @LIST(STRING, FP, END-TEST, NAME-EXPR)@ --- *
284  *
285  * Produce list of things.  Requires @i@ and @w@ variables in scope.
286  * END-TEST and NAME-EXPR are in terms of @i@.
287  */
288
289 #define LIST(what, fp, end, name) do {                                  \
290   fputs(what ":\n  ", fp);                                              \
291   w = 2;                                                                \
292   for (i = 0; end; i++) {                                               \
293     if (w == 2)                                                         \
294       w += strlen(name);                                                \
295     else {                                                              \
296       if (strlen(name) + w > 76) {                                      \
297         fputs("\n  ", fp);                                              \
298         w = 2 + strlen(name);                                           \
299       } else {                                                          \
300         fputc(' ', fp);                                                 \
301         w += strlen(name) + 1;                                          \
302       }                                                                 \
303     }                                                                   \
304     fputs(name, fp);                                                    \
305   }                                                                     \
306   fputc('\n', fp);                                                      \
307 } while (0)
308
309 #define STDLISTS(LI)                                                    \
310   LI("Hash functions", hash,                                            \
311      ghashtab[i], ghashtab[i]->name)                                    \
312   LI("Encryption schemes", enc,                                         \
313      gciphertab[i], gciphertab[i]->name)                                \
314   LI("Message authentication schemes", mac,                             \
315      gmactab[i], gmactab[i]->name)                                      \
316   LI("Elliptic curves", ec,                                             \
317      ectab[i].name, ectab[i].name)                                      \
318   LI("Diffie-Hellman groups", dh,                                       \
319      ptab[i].name, ptab[i].name)
320
321 #define LIDECL(text, tag, test, name)                                   \
322   static void show_##tag(void);
323
324 #define LIDEF(text, tag, test, name)                                    \
325   static void show_##tag(void)                                          \
326   {                                                                     \
327     unsigned i, w;                                                      \
328     LIST(text, stdout, test, name);                                     \
329   }
330
331 #define LIENT(text, tag, test, name)                                    \
332   { #tag, show_##tag },
333
334 struct listent {
335   const char *name;
336   void (*list)(void);
337 };
338
339 #define MAKELISTTAB(listtab, LISTS)                                     \
340   LISTS(LIDECL)                                                         \
341   static const struct listent listtab[] = {                             \
342     LISTS(LIENT)                                                        \
343     { 0, 0 }                                                            \
344   };                                                                    \
345   LISTS(LIDEF)
346
347 extern int displaylists(const struct listent */*listtab*/,
348                         char *const /*argv*/[]);
349
350 /*----- Subcommand dispatch -----------------------------------------------*/
351
352 typedef struct cmd {
353   const char *name;
354   int (*cmd)(int /*argc*/, char */*argv*/[]);
355   const char *usage;
356   const char *help;
357 } cmd;
358
359 extern void version(FILE */*fp*/);
360 extern void help_global(FILE */*fp*/);
361
362 /* --- @findcmd@ --- *
363  *
364  * Arguments:   @const cmd *cmds@ = pointer to command table
365  *              @const char *name@ = a command name
366  *
367  * Returns:     Pointer to the command structure.
368  *
369  * Use:         Looks up a command by name.  If the command isn't found, an
370  *              error is reported and the program is terminated.
371  */
372
373 const cmd *findcmd(const cmd */*cmds*/, const char */*name*/);
374
375 /* --- @sc_help@ --- *
376  *
377  * Arguments:   @const cmd *cmds@ = pointer to command table
378  *              @FILE *fp@ = output file handle
379  *              @char *const *argv@ = remaining arguments
380  *
381  * Returns:     ---
382  *
383  * Use:         Prints a help message, maybe with help about subcommands.
384  */
385
386 extern void sc_help(const cmd */*cmds*/, FILE */*fp*/,
387                     char *const */*argv*/);
388
389 /*----- That's all, folks -------------------------------------------------*/
390
391 #ifdef __cplusplus
392   }
393 #endif
394
395 #endif