Add generic crypto module.
[gnulib.git] / lib / gc.h
1 /* gc.h --- Header file for implementation agnostic crypto wrapper API.
2  * Copyright (C) 2002, 2003, 2004, 2005  Simon Josefsson
3  *
4  * This file is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published
6  * by the Free Software Foundation; either version 2, or (at your
7  * option) any later version.
8  *
9  * This file is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this file; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  */
20
21 #ifndef GC_H
22 # define GC_H
23
24 /* Get size_t. */
25 # include <stddef.h>
26
27 #define GC_MD5_DIGEST_SIZE 16
28
29 enum Gc_rc
30   {
31     GC_OK = 0,
32     GC_MALLOC_ERROR,
33     GC_INIT_ERROR,
34     GC_RANDOM_ERROR,
35     GC_INVALID_CIPHER,
36     GC_INVALID_HASH,
37     GC_PKCS5_INVALID_ITERATION_COUNT,
38     GC_PKCS5_INVALID_DERIVED_KEY_LENGTH,
39     GC_PKCS5_DERIVED_KEY_TOO_LONG
40   };
41 typedef enum Gc_rc Gc_rc;
42
43 extern int gc_init (void);
44 extern void gc_done (void);
45
46 /* Memory allocation (avoid). */
47 typedef void *(*gc_malloc_t) (size_t n);
48 typedef int (*gc_secure_check_t) (const void *);
49 typedef void *(*gc_realloc_t) (void *p, size_t n);
50 typedef void (*gc_free_t) (void *);
51 extern void gc_set_allocators (gc_malloc_t func_malloc,
52                                gc_malloc_t secure_malloc,
53                                gc_secure_check_t secure_check,
54                                gc_realloc_t func_realloc,
55                                gc_free_t func_free);
56
57 /* One-call interface. */
58 extern int gc_md5 (const void *in, size_t inlen, void *resbuf);
59 extern int gc_hmac_md5 (const void *key, size_t keylen,
60                         const void *in, size_t inlen,
61                         char *resbuf);
62
63 /*
64   TODO:
65
66   From: Simon Josefsson <jas@extundo.com>
67   Subject: Re: generic crypto
68   Newsgroups: gmane.comp.lib.gnulib.bugs
69   Cc: bug-gnulib@gnu.org
70   Date: Fri, 07 Oct 2005 12:50:57 +0200
71   Mail-Copies-To: nobody
72
73   Paul Eggert <eggert@CS.UCLA.EDU> writes:
74
75   > Simon Josefsson <jas@extundo.com> writes:
76   >
77   >> * Perhaps the /dev/*random reading should be separated into a separate
78   >>   module?  It might be useful outside of the gc layer too.
79   >
80   > Absolutely.  I've been meaning to do that for months (for a "shuffle"
81   > program I want to add to coreutils), but hadn't gotten around to it.
82   > It would have to be generalized a bit.  I'd like to have the file
83   > descriptor cached, for example.
84
85   I'll write a separate module for that part.
86
87   I think we should even add a good PRNG that is re-seeded from
88   /dev/*random frequently.  GnuTLS can need a lot of random data on a
89   big server, more than /dev/random can supply.  And /dev/urandom might
90   not be strong enough.  Further, the security of /dev/*random can also
91   be questionable.
92
93   >>   I'm also not sure about the names of those functions, they suggest
94   >>   a more higher-level API than what is really offered (i.e., the
95   >>   names "nonce" and "pseudo_random" and "random" imply certain
96   >>   cryptographic properties).
97   >
98   > Could you expand a bit more on that?  What is the relationship between
99   > nonce/pseudorandom/random and the /dev/ values you are using?
100
101   There is none, that is the problem.
102
103   Applications generally need different kind of "random" numbers.
104   Sometimes they just need some random data and doesn't care whether it
105   is possible for an attacker to compute the string (aka a "nonce").
106   Sometimes they need data that is very difficult to compute (i.e.,
107   computing it require inverting SHA1 or similar).  Sometimes they need
108   data that is not possible to compute, i.e., it wants real entropy
109   collected over time on the system.  Collecting the last kind of random
110   data is very expensive, so it must not be used too often.  The second
111   kind of random data ("pseudo random") is typically generated by
112   seeding a good PRNG with a couple of hundred bytes of real entropy
113   from the "real random" data pool.  The "nonce" is usually computed
114   using the PRNG as well, because PRNGs are usually fast.
115
116   Pseudo-random data is typically used for session keys.  Strong random
117   data is often used to generate long-term keys (e.g., private RSA
118   keys).
119
120   Of course, there are many subtleties.  There are several different
121   kind of nonce:s.  Sometimes a nonce is just an ever-increasing
122   integer, starting from 0.  Sometimes it is assumed to be unlikely to
123   be the same as previous nonces, but without a requirement that the
124   nonce is possible to guess.  MD5(system clock) would thus suffice, if
125   it isn't called too often.  You can guess what the next value will be,
126   but it will always be different.
127
128   The problem is that /dev/*random doesn't offer any kind of semantic
129   guarantees.  But applications need an API that make that promise.
130
131   I think we should do this in several steps:
132
133   1) Write a module that can read from /dev/*random.
134
135   2) Add a module for a known-good PRNG suitable for random number
136   generation, that can be continuously re-seeded.
137
138   3) Add a high-level module that provide various different randomness
139   functions.  One for nonces, perhaps even different kind of nonces,
140   one for pseudo random data, and one for strong random data.  It is
141   not clear whether we can hope to achieve the last one in a portable
142   way.
143
144   Further, it would be useful to allow users to provide their own
145   entropy source as a file, used to seed the PRNG or initialize the
146   strong randomness pool.  This is used on embedded platforms that
147   doesn't have enough interrupts to hope to generate good random data.
148
149   > For example, why not use OpenBSD's /dev/arandom?
150
151   I don't trust ARC4.  For example, recent cryptographic efforts
152   indicate that you must throw away the first 512 bytes generated from
153   the PRNG for it to be secure.  I don't know whether OpenBSD do this.
154   Further, I recall some eprint paper on RC4 security that didn't
155   inspire confidence.
156
157   While I trust the random devices in OpenBSD more than
158   Solaris/AIX/HPUX/etc, I think that since we need something better on
159   Solaris/AIX/HPUX we'd might as well use it on OpenBSD or even Linux
160   too.
161
162   > Here is one thought.  The user could specify a desired quality level
163   > range, and the implementation then would supply random data that is at
164   > least as good as the lower bound of the range.  I.e., ihe
165   > implementation refuses to produce any random data if it can't generate
166   > data that is at least as good as the lower end of the range.  The
167   > upper bound of the range is advice from the user not to be any more
168   > expensive than that, but the implementation can ignore the advice if
169   > it doesn't have anything cheaper.
170
171   I'm not sure this is a good idea.  Users can't really be expected to
172   understand this.  Further, applications need many different kind of
173   random data.  Selecting the randomness level for each by the user will
174   be too complicated.
175
176   I think it is better if the application decide, from its cryptographic
177   requirement, what entropy quality it require, and call the proper API.
178   Meeting the implied semantic properties should be the job for gnulib.
179
180   >> Perhaps gc_dev_random and gc_dev_urandom?
181   >
182   > To some extent.  I'd rather insulate the user from the details of
183   > where the random numbers come from.  On the other hand we need to
184   > provide a way for applications to specify a file that contains
185   > random bits, so that people can override the defaults.
186
187   Agreed.
188
189   This may require some thinking before it is finalized.  Is it ok to
190   install the GC module as-is meanwhile?  Then I can continue to add the
191   stuff that GnuTLS need, and then come back to re-working the
192   randomness module.  That way, we have two different projects that use
193   the code.  GnuTLS includes the same randomness code that was in GNU
194   SASL and that is in the current gc module.  I feel much more
195   comfortable working in small steps at a time, rather then working on
196   this for a long time in gnulib and only later integrate the stuff in
197   GnuTLS.
198
199   Thanks,
200   Simon
201  */
202
203 #endif /* GC_H */