hash-set, linkedhash-set: Reduce code duplication.
[gnulib.git] / lib / gc.h
blobfbfde3d82229c546ae36fc02f15c016dd3d03d01
1 /* gc.h --- Header file for implementation agnostic crypto wrapper API.
2 * Copyright (C) 2002-2005, 2007-2008, 2011-2018 Free Software Foundation, Inc.
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, see <https://www.gnu.org/licenses/>.
19 #ifndef GC_H
20 # define GC_H
22 /* Get size_t. */
23 # include <stddef.h>
25 enum Gc_rc
27 GC_OK = 0,
28 GC_MALLOC_ERROR,
29 GC_INIT_ERROR,
30 GC_RANDOM_ERROR,
31 GC_INVALID_CIPHER,
32 GC_INVALID_HASH,
33 GC_PKCS5_INVALID_ITERATION_COUNT,
34 GC_PKCS5_INVALID_DERIVED_KEY_LENGTH,
35 GC_PKCS5_DERIVED_KEY_TOO_LONG
37 typedef enum Gc_rc Gc_rc;
39 /* Hash types. */
40 enum Gc_hash
42 GC_MD4,
43 GC_MD5,
44 GC_SHA1,
45 GC_MD2,
46 GC_RMD160,
47 GC_SHA256,
48 GC_SHA384,
49 GC_SHA512,
50 GC_SHA224,
51 GC_SM3
53 typedef enum Gc_hash Gc_hash;
55 enum Gc_hash_mode
57 GC_NULL,
58 GC_HMAC
60 typedef enum Gc_hash_mode Gc_hash_mode;
62 typedef void *gc_hash_handle;
64 #define GC_MD2_DIGEST_SIZE 16
65 #define GC_MD4_DIGEST_SIZE 16
66 #define GC_MD5_DIGEST_SIZE 16
67 #define GC_RMD160_DIGEST_SIZE 20
68 #define GC_SHA1_DIGEST_SIZE 20
69 #define GC_SHA256_DIGEST_SIZE 32
70 #define GC_SHA384_DIGEST_SIZE 48
71 #define GC_SHA512_DIGEST_SIZE 64
72 #define GC_SHA224_DIGEST_SIZE 24
73 #define GC_SM3_DIGEST_SIZE 32
75 /* Cipher types. */
76 enum Gc_cipher
78 GC_AES128,
79 GC_AES192,
80 GC_AES256,
81 GC_3DES,
82 GC_DES,
83 GC_ARCFOUR128,
84 GC_ARCFOUR40,
85 GC_ARCTWO40,
86 GC_CAMELLIA128,
87 GC_CAMELLIA256
89 typedef enum Gc_cipher Gc_cipher;
91 enum Gc_cipher_mode
93 GC_ECB,
94 GC_CBC,
95 GC_STREAM
97 typedef enum Gc_cipher_mode Gc_cipher_mode;
99 typedef void *gc_cipher_handle;
101 /* Call before respectively after any other functions. */
102 extern Gc_rc gc_init (void);
103 extern void gc_done (void);
105 /* Memory allocation (avoid). */
106 typedef void *(*gc_malloc_t) (size_t n);
107 typedef int (*gc_secure_check_t) (const void *);
108 typedef void *(*gc_realloc_t) (void *p, size_t n);
109 typedef void (*gc_free_t) (void *);
110 extern void gc_set_allocators (gc_malloc_t func_malloc,
111 gc_malloc_t secure_malloc,
112 gc_secure_check_t secure_check,
113 gc_realloc_t func_realloc,
114 gc_free_t func_free);
116 /* Randomness. */
117 extern Gc_rc gc_nonce (char *data, size_t datalen);
118 extern Gc_rc gc_pseudo_random (char *data, size_t datalen);
119 extern Gc_rc gc_random (char *data, size_t datalen);
121 /* Ciphers. */
122 extern Gc_rc gc_cipher_open (Gc_cipher cipher, Gc_cipher_mode mode,
123 gc_cipher_handle *outhandle);
124 extern Gc_rc gc_cipher_setkey (gc_cipher_handle handle,
125 size_t keylen, const char *key);
126 extern Gc_rc gc_cipher_setiv (gc_cipher_handle handle,
127 size_t ivlen, const char *iv);
128 extern Gc_rc gc_cipher_encrypt_inline (gc_cipher_handle handle,
129 size_t len, char *data);
130 extern Gc_rc gc_cipher_decrypt_inline (gc_cipher_handle handle,
131 size_t len, char *data);
132 extern Gc_rc gc_cipher_close (gc_cipher_handle handle);
134 /* Hashes. */
136 extern Gc_rc gc_hash_open (Gc_hash hash, Gc_hash_mode mode,
137 gc_hash_handle *outhandle);
138 extern Gc_rc gc_hash_clone (gc_hash_handle handle, gc_hash_handle *outhandle);
139 extern size_t gc_hash_digest_length (Gc_hash hash)
140 _GL_ATTRIBUTE_CONST;
141 extern void gc_hash_hmac_setkey (gc_hash_handle handle,
142 size_t len, const char *key);
143 extern void gc_hash_write (gc_hash_handle handle,
144 size_t len, const char *data);
145 extern const char *gc_hash_read (gc_hash_handle handle);
146 extern void gc_hash_close (gc_hash_handle handle);
148 /* Compute a hash value over buffer IN of INLEN bytes size using the
149 algorithm HASH, placing the result in the pre-allocated buffer OUT.
150 The required size of OUT depends on HASH, and is generally
151 GC_<HASH>_DIGEST_SIZE. For example, for GC_MD5 the output buffer
152 must be 16 bytes. The return value is 0 (GC_OK) on success, or
153 another Gc_rc error code. */
154 extern Gc_rc
155 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *out);
157 /* One-call interface. */
158 extern Gc_rc gc_md2 (const void *in, size_t inlen, void *resbuf);
159 extern Gc_rc gc_md4 (const void *in, size_t inlen, void *resbuf);
160 extern Gc_rc gc_md5 (const void *in, size_t inlen, void *resbuf);
161 extern Gc_rc gc_sha1 (const void *in, size_t inlen, void *resbuf);
162 extern Gc_rc gc_sm3 (const void *in, size_t inlen, void *resbuf);
163 extern Gc_rc gc_hmac_md5 (const void *key, size_t keylen,
164 const void *in, size_t inlen, char *resbuf);
165 extern Gc_rc gc_hmac_sha1 (const void *key, size_t keylen,
166 const void *in, size_t inlen, char *resbuf);
167 extern Gc_rc gc_hmac_sha256 (const void *key, size_t keylen,
168 const void *in, size_t inlen, char *resbuf);
169 extern Gc_rc gc_hmac_sha512 (const void *key, size_t keylen,
170 const void *in, size_t inlen, char *resbuf);
172 /* Derive cryptographic keys from a password P of length PLEN, with
173 salt S of length SLEN, placing the result in pre-allocated buffer
174 DK of length DKLEN. An iteration count is specified in C, where a
175 larger value means this function take more time (typical iteration
176 counts are 1000-20000). This function "stretches" the key to be
177 exactly dkLen bytes long. GC_OK is returned on success, otherwise
178 a Gc_rc error code is returned. */
179 extern Gc_rc
180 gc_pbkdf2_sha1 (const char *P, size_t Plen,
181 const char *S, size_t Slen,
182 unsigned int c, char *DK, size_t dkLen);
185 TODO:
187 From: Simon Josefsson <jas@extundo.com>
188 Subject: Re: generic crypto
189 Newsgroups: gmane.comp.lib.gnulib.bugs
190 Cc: bug-gnulib@gnu.org
191 Date: Fri, 07 Oct 2005 12:50:57 +0200
192 Mail-Copies-To: nobody
194 Paul Eggert <eggert@CS.UCLA.EDU> writes:
196 > Simon Josefsson <jas@extundo.com> writes:
198 >> * Perhaps the /dev/?random reading should be separated into a separate
199 >> module? It might be useful outside of the gc layer too.
201 > Absolutely. I've been meaning to do that for months (for a "shuffle"
202 > program I want to add to coreutils), but hadn't gotten around to it.
203 > It would have to be generalized a bit. I'd like to have the file
204 > descriptor cached, for example.
206 I'll write a separate module for that part.
208 I think we should even add a good PRNG that is re-seeded from
209 /dev/?random frequently. GnuTLS can need a lot of random data on a
210 big server, more than /dev/random can supply. And /dev/urandom might
211 not be strong enough. Further, the security of /dev/?random can also
212 be questionable.
214 >> I'm also not sure about the names of those functions, they suggest
215 >> a more higher-level API than what is really offered (i.e., the
216 >> names "nonce" and "pseudo_random" and "random" imply certain
217 >> cryptographic properties).
219 > Could you expand a bit more on that? What is the relationship between
220 > nonce/pseudorandom/random and the /dev/ values you are using?
222 There is none, that is the problem.
224 Applications generally need different kind of "random" numbers.
225 Sometimes they just need some random data and doesn't care whether it
226 is possible for an attacker to compute the string (aka a "nonce").
227 Sometimes they need data that is very difficult to compute (i.e.,
228 computing it require inverting SHA1 or similar). Sometimes they need
229 data that is not possible to compute, i.e., it wants real entropy
230 collected over time on the system. Collecting the last kind of random
231 data is very expensive, so it must not be used too often. The second
232 kind of random data ("pseudo random") is typically generated by
233 seeding a good PRNG with a couple of hundred bytes of real entropy
234 from the "real random" data pool. The "nonce" is usually computed
235 using the PRNG as well, because PRNGs are usually fast.
237 Pseudo-random data is typically used for session keys. Strong random
238 data is often used to generate long-term keys (e.g., private RSA
239 keys).
241 Of course, there are many subtleties. There are several different
242 kind of nonce:s. Sometimes a nonce is just an ever-increasing
243 integer, starting from 0. Sometimes it is assumed to be unlikely to
244 be the same as previous nonces, but without a requirement that the
245 nonce is possible to guess. MD5(system clock) would thus suffice, if
246 it isn't called too often. You can guess what the next value will be,
247 but it will always be different.
249 The problem is that /dev/?random doesn't offer any kind of semantic
250 guarantees. But applications need an API that make that promise.
252 I think we should do this in several steps:
254 1) Write a module that can read from /dev/?random.
256 2) Add a module for a known-good PRNG suitable for random number
257 generation, that can be continuously re-seeded.
259 3) Add a high-level module that provide various different randomness
260 functions. One for nonces, perhaps even different kind of nonces,
261 one for pseudo random data, and one for strong random data. It is
262 not clear whether we can hope to achieve the last one in a portable
263 way.
265 Further, it would be useful to allow users to provide their own
266 entropy source as a file, used to seed the PRNG or initialize the
267 strong randomness pool. This is used on embedded platforms that
268 doesn't have enough interrupts to hope to generate good random data.
270 > For example, why not use OpenBSD's /dev/arandom?
272 I don't trust ARC4. For example, recent cryptographic efforts
273 indicate that you must throw away the first 512 bytes generated from
274 the PRNG for it to be secure. I don't know whether OpenBSD do this.
275 Further, I recall some eprint paper on RC4 security that didn't
276 inspire confidence.
278 While I trust the random devices in OpenBSD more than
279 Solaris/AIX/HPUX/etc, I think that since we need something better on
280 Solaris/AIX/HPUX we'd might as well use it on OpenBSD or even Linux
281 too.
283 > Here is one thought. The user could specify a desired quality level
284 > range, and the implementation then would supply random data that is at
285 > least as good as the lower bound of the range. I.e., ihe
286 > implementation refuses to produce any random data if it can't generate
287 > data that is at least as good as the lower end of the range. The
288 > upper bound of the range is advice from the user not to be any more
289 > expensive than that, but the implementation can ignore the advice if
290 > it doesn't have anything cheaper.
292 I'm not sure this is a good idea. Users can't really be expected to
293 understand this. Further, applications need many different kind of
294 random data. Selecting the randomness level for each by the user will
295 be too complicated.
297 I think it is better if the application decide, from its cryptographic
298 requirement, what entropy quality it require, and call the proper API.
299 Meeting the implied semantic properties should be the job for gnulib.
301 >> Perhaps gc_dev_random and gc_dev_urandom?
303 > To some extent. I'd rather insulate the user from the details of
304 > where the random numbers come from. On the other hand we need to
305 > provide a way for applications to specify a file that contains
306 > random bits, so that people can override the defaults.
308 Agreed.
310 This may require some thinking before it is finalized. Is it ok to
311 install the GC module as-is meanwhile? Then I can continue to add the
312 stuff that GnuTLS need, and then come back to re-working the
313 randomness module. That way, we have two different projects that use
314 the code. GnuTLS includes the same randomness code that was in GNU
315 SASL and that is in the current gc module. I feel much more
316 comfortable working in small steps at a time, rather then working on
317 this for a long time in gnulib and only later integrate the stuff in
318 GnuTLS.
320 Thanks,
321 Simon
324 #endif /* GC_H */