1 /* gc.h --- Header file for implementation agnostic crypto wrapper API.
2 * Copyright (C) 2002, 2003, 2004, 2005 Simon Josefsson
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.
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.
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
35 GC_PKCS5_INVALID_ITERATION_COUNT,
36 GC_PKCS5_INVALID_DERIVED_KEY_LENGTH,
37 GC_PKCS5_DERIVED_KEY_TOO_LONG
39 typedef enum Gc_rc Gc_rc;
47 typedef enum Gc_hash Gc_hash;
49 #define GC_MD5_DIGEST_SIZE 16
50 #define GC_SHA1_DIGEST_SIZE 20
52 /* Call before respectively after any other functions. */
53 extern Gc_rc gc_init (void);
54 extern void gc_done (void);
56 /* Memory allocation (avoid). */
57 typedef void *(*gc_malloc_t) (size_t n);
58 typedef int (*gc_secure_check_t) (const void *);
59 typedef void *(*gc_realloc_t) (void *p, size_t n);
60 typedef void (*gc_free_t) (void *);
61 extern void gc_set_allocators (gc_malloc_t func_malloc,
62 gc_malloc_t secure_malloc,
63 gc_secure_check_t secure_check,
64 gc_realloc_t func_realloc,
69 /* Compute a hash value over buffer IN of INLEN bytes size using the
70 algorithm HASH, placing the result in the pre-allocated buffer OUT.
71 The required size of OUT depends on HASH, and is generally
72 GC_<HASH>_DIGEST_SIZE. For example, for GC_MD5 the output buffer
73 must be 16 bytes. The return value is 0 (GC_OK) on success, or
74 another Gc_rc error code. */
76 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *out);
78 /* One-call interface. */
79 extern Gc_rc gc_md5 (const void *in, size_t inlen, void *resbuf);
80 extern Gc_rc gc_sha1 (const void *in, size_t inlen, void *resbuf);
81 extern Gc_rc gc_hmac_md5 (const void *key, size_t keylen,
82 const void *in, size_t inlen,
84 extern Gc_rc gc_hmac_sha1 (const void *key, size_t keylen,
85 const void *in, size_t inlen,
88 /* Derive cryptographic keys from a password P of length PLEN, with
89 salt S of length SLEN, placing the result in pre-allocated buffer
90 DK of length DKLEN. An iteration count is specified in C, where a
91 larger value means this function take more time (typical iteration
92 counts are 1000-20000). This function "stretches" the key to be
93 exactly dkLen bytes long. GC_OK is returned on success, otherwise
94 an Gc_rc error code is returned. */
96 gc_pbkdf2_sha1 (const char *P, size_t Plen,
97 const char *S, size_t Slen,
99 char *DK, size_t dkLen);
104 From: Simon Josefsson <jas@extundo.com>
105 Subject: Re: generic crypto
106 Newsgroups: gmane.comp.lib.gnulib.bugs
107 Cc: bug-gnulib@gnu.org
108 Date: Fri, 07 Oct 2005 12:50:57 +0200
109 Mail-Copies-To: nobody
111 Paul Eggert <eggert@CS.UCLA.EDU> writes:
113 > Simon Josefsson <jas@extundo.com> writes:
115 >> * Perhaps the /dev/*random reading should be separated into a separate
116 >> module? It might be useful outside of the gc layer too.
118 > Absolutely. I've been meaning to do that for months (for a "shuffle"
119 > program I want to add to coreutils), but hadn't gotten around to it.
120 > It would have to be generalized a bit. I'd like to have the file
121 > descriptor cached, for example.
123 I'll write a separate module for that part.
125 I think we should even add a good PRNG that is re-seeded from
126 /dev/*random frequently. GnuTLS can need a lot of random data on a
127 big server, more than /dev/random can supply. And /dev/urandom might
128 not be strong enough. Further, the security of /dev/*random can also
131 >> I'm also not sure about the names of those functions, they suggest
132 >> a more higher-level API than what is really offered (i.e., the
133 >> names "nonce" and "pseudo_random" and "random" imply certain
134 >> cryptographic properties).
136 > Could you expand a bit more on that? What is the relationship between
137 > nonce/pseudorandom/random and the /dev/ values you are using?
139 There is none, that is the problem.
141 Applications generally need different kind of "random" numbers.
142 Sometimes they just need some random data and doesn't care whether it
143 is possible for an attacker to compute the string (aka a "nonce").
144 Sometimes they need data that is very difficult to compute (i.e.,
145 computing it require inverting SHA1 or similar). Sometimes they need
146 data that is not possible to compute, i.e., it wants real entropy
147 collected over time on the system. Collecting the last kind of random
148 data is very expensive, so it must not be used too often. The second
149 kind of random data ("pseudo random") is typically generated by
150 seeding a good PRNG with a couple of hundred bytes of real entropy
151 from the "real random" data pool. The "nonce" is usually computed
152 using the PRNG as well, because PRNGs are usually fast.
154 Pseudo-random data is typically used for session keys. Strong random
155 data is often used to generate long-term keys (e.g., private RSA
158 Of course, there are many subtleties. There are several different
159 kind of nonce:s. Sometimes a nonce is just an ever-increasing
160 integer, starting from 0. Sometimes it is assumed to be unlikely to
161 be the same as previous nonces, but without a requirement that the
162 nonce is possible to guess. MD5(system clock) would thus suffice, if
163 it isn't called too often. You can guess what the next value will be,
164 but it will always be different.
166 The problem is that /dev/*random doesn't offer any kind of semantic
167 guarantees. But applications need an API that make that promise.
169 I think we should do this in several steps:
171 1) Write a module that can read from /dev/*random.
173 2) Add a module for a known-good PRNG suitable for random number
174 generation, that can be continuously re-seeded.
176 3) Add a high-level module that provide various different randomness
177 functions. One for nonces, perhaps even different kind of nonces,
178 one for pseudo random data, and one for strong random data. It is
179 not clear whether we can hope to achieve the last one in a portable
182 Further, it would be useful to allow users to provide their own
183 entropy source as a file, used to seed the PRNG or initialize the
184 strong randomness pool. This is used on embedded platforms that
185 doesn't have enough interrupts to hope to generate good random data.
187 > For example, why not use OpenBSD's /dev/arandom?
189 I don't trust ARC4. For example, recent cryptographic efforts
190 indicate that you must throw away the first 512 bytes generated from
191 the PRNG for it to be secure. I don't know whether OpenBSD do this.
192 Further, I recall some eprint paper on RC4 security that didn't
195 While I trust the random devices in OpenBSD more than
196 Solaris/AIX/HPUX/etc, I think that since we need something better on
197 Solaris/AIX/HPUX we'd might as well use it on OpenBSD or even Linux
200 > Here is one thought. The user could specify a desired quality level
201 > range, and the implementation then would supply random data that is at
202 > least as good as the lower bound of the range. I.e., ihe
203 > implementation refuses to produce any random data if it can't generate
204 > data that is at least as good as the lower end of the range. The
205 > upper bound of the range is advice from the user not to be any more
206 > expensive than that, but the implementation can ignore the advice if
207 > it doesn't have anything cheaper.
209 I'm not sure this is a good idea. Users can't really be expected to
210 understand this. Further, applications need many different kind of
211 random data. Selecting the randomness level for each by the user will
214 I think it is better if the application decide, from its cryptographic
215 requirement, what entropy quality it require, and call the proper API.
216 Meeting the implied semantic properties should be the job for gnulib.
218 >> Perhaps gc_dev_random and gc_dev_urandom?
220 > To some extent. I'd rather insulate the user from the details of
221 > where the random numbers come from. On the other hand we need to
222 > provide a way for applications to specify a file that contains
223 > random bits, so that people can override the defaults.
227 This may require some thinking before it is finalized. Is it ok to
228 install the GC module as-is meanwhile? Then I can continue to add the
229 stuff that GnuTLS need, and then come back to re-working the
230 randomness module. That way, we have two different projects that use
231 the code. GnuTLS includes the same randomness code that was in GNU
232 SASL and that is in the current gc module. I feel much more
233 comfortable working in small steps at a time, rather then working on
234 this for a long time in gnulib and only later integrate the stuff in