NEWS.stable: log cherry-pick [e446f25]->[c092018] relocatable-shell: Update suggested...
[gnulib.git] / lib / gc.h
index f9b66d1..f08260c 100644 (file)
--- a/lib/gc.h
+++ b/lib/gc.h
@@ -1,5 +1,5 @@
 /* gc.h --- Header file for implementation agnostic crypto wrapper API.
 /* gc.h --- Header file for implementation agnostic crypto wrapper API.
- * Copyright (C) 2002, 2003, 2004, 2005  Simon Josefsson
+ * Copyright (C) 2002-2005, 2007-2008, 2011-2014 Free Software Foundation, Inc.
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published
@@ -12,9 +12,7 @@
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this file; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
+ * along with this file; if not, see <http://www.gnu.org/licenses/>.
  *
  */
 
  *
  */
 
 # include <stddef.h>
 
 enum Gc_rc
 # include <stddef.h>
 
 enum Gc_rc
-  {
-    GC_OK = 0,
-    GC_MALLOC_ERROR,
-    GC_INIT_ERROR,
-    GC_RANDOM_ERROR,
-    GC_INVALID_CIPHER,
-    GC_INVALID_HASH,
-    GC_PKCS5_INVALID_ITERATION_COUNT,
-    GC_PKCS5_INVALID_DERIVED_KEY_LENGTH,
-    GC_PKCS5_DERIVED_KEY_TOO_LONG
-  };
+{
+  GC_OK = 0,
+  GC_MALLOC_ERROR,
+  GC_INIT_ERROR,
+  GC_RANDOM_ERROR,
+  GC_INVALID_CIPHER,
+  GC_INVALID_HASH,
+  GC_PKCS5_INVALID_ITERATION_COUNT,
+  GC_PKCS5_INVALID_DERIVED_KEY_LENGTH,
+  GC_PKCS5_DERIVED_KEY_TOO_LONG
+};
 typedef enum Gc_rc Gc_rc;
 
 /* Hash types. */
 enum Gc_hash
 typedef enum Gc_rc Gc_rc;
 
 /* Hash types. */
 enum Gc_hash
-  {
-    GC_MD5
-  };
+{
+  GC_MD4,
+  GC_MD5,
+  GC_SHA1,
+  GC_MD2,
+  GC_RMD160,
+  GC_SHA256,
+  GC_SHA384,
+  GC_SHA512,
+  GC_SHA224
+};
 typedef enum Gc_hash Gc_hash;
 
 typedef enum Gc_hash Gc_hash;
 
+enum Gc_hash_mode
+{
+  GC_HMAC = 1
+};
+typedef enum Gc_hash_mode Gc_hash_mode;
+
+typedef void *gc_hash_handle;
+
+#define GC_MD2_DIGEST_SIZE 16
+#define GC_MD4_DIGEST_SIZE 16
 #define GC_MD5_DIGEST_SIZE 16
 #define GC_MD5_DIGEST_SIZE 16
+#define GC_RMD160_DIGEST_SIZE 20
+#define GC_SHA1_DIGEST_SIZE 20
+#define GC_SHA256_DIGEST_SIZE 32
+#define GC_SHA384_DIGEST_SIZE 48
+#define GC_SHA512_DIGEST_SIZE 64
+#define GC_SHA224_DIGEST_SIZE 24
+
+/* Cipher types. */
+enum Gc_cipher
+{
+  GC_AES128,
+  GC_AES192,
+  GC_AES256,
+  GC_3DES,
+  GC_DES,
+  GC_ARCFOUR128,
+  GC_ARCFOUR40,
+  GC_ARCTWO40,
+  GC_CAMELLIA128,
+  GC_CAMELLIA256
+};
+typedef enum Gc_cipher Gc_cipher;
+
+enum Gc_cipher_mode
+{
+  GC_ECB,
+  GC_CBC,
+  GC_STREAM
+};
+typedef enum Gc_cipher_mode Gc_cipher_mode;
+
+typedef void *gc_cipher_handle;
 
 /* Call before respectively after any other functions. */
 
 /* Call before respectively after any other functions. */
-extern int gc_init (void);
+extern Gc_rc gc_init (void);
 extern void gc_done (void);
 
 /* Memory allocation (avoid). */
 extern void gc_done (void);
 
 /* Memory allocation (avoid). */
@@ -57,20 +105,76 @@ typedef int (*gc_secure_check_t) (const void *);
 typedef void *(*gc_realloc_t) (void *p, size_t n);
 typedef void (*gc_free_t) (void *);
 extern void gc_set_allocators (gc_malloc_t func_malloc,
 typedef void *(*gc_realloc_t) (void *p, size_t n);
 typedef void (*gc_free_t) (void *);
 extern void gc_set_allocators (gc_malloc_t func_malloc,
-                              gc_malloc_t secure_malloc,
-                              gc_secure_check_t secure_check,
-                              gc_realloc_t func_realloc,
-                              gc_free_t func_free);
+                               gc_malloc_t secure_malloc,
+                               gc_secure_check_t secure_check,
+                               gc_realloc_t func_realloc,
+                               gc_free_t func_free);
+
+/* Randomness. */
+extern Gc_rc gc_nonce (char *data, size_t datalen);
+extern Gc_rc gc_pseudo_random (char *data, size_t datalen);
+extern Gc_rc gc_random (char *data, size_t datalen);
+
+/* Ciphers. */
+extern Gc_rc gc_cipher_open (Gc_cipher cipher, Gc_cipher_mode mode,
+                             gc_cipher_handle *outhandle);
+extern Gc_rc gc_cipher_setkey (gc_cipher_handle handle,
+                               size_t keylen, const char *key);
+extern Gc_rc gc_cipher_setiv (gc_cipher_handle handle,
+                              size_t ivlen, const char *iv);
+extern Gc_rc gc_cipher_encrypt_inline (gc_cipher_handle handle,
+                                       size_t len, char *data);
+extern Gc_rc gc_cipher_decrypt_inline (gc_cipher_handle handle,
+                                       size_t len, char *data);
+extern Gc_rc gc_cipher_close (gc_cipher_handle handle);
 
 /* Hashes. */
 
 /* Hashes. */
-extern int
-gc_hash_buffer (int hash, const void *in, size_t inlen, char *out);
+
+extern Gc_rc gc_hash_open (Gc_hash hash, Gc_hash_mode mode,
+                           gc_hash_handle *outhandle);
+extern Gc_rc gc_hash_clone (gc_hash_handle handle, gc_hash_handle *outhandle);
+extern size_t gc_hash_digest_length (Gc_hash hash);
+extern void gc_hash_hmac_setkey (gc_hash_handle handle,
+                                 size_t len, const char *key);
+extern void gc_hash_write (gc_hash_handle handle,
+                           size_t len, const char *data);
+extern const char *gc_hash_read (gc_hash_handle handle);
+extern void gc_hash_close (gc_hash_handle handle);
+
+/* Compute a hash value over buffer IN of INLEN bytes size using the
+   algorithm HASH, placing the result in the pre-allocated buffer OUT.
+   The required size of OUT depends on HASH, and is generally
+   GC_<HASH>_DIGEST_SIZE.  For example, for GC_MD5 the output buffer
+   must be 16 bytes.  The return value is 0 (GC_OK) on success, or
+   another Gc_rc error code. */
+extern Gc_rc
+gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *out);
 
 /* One-call interface. */
 
 /* One-call interface. */
-extern int gc_md5 (const void *in, size_t inlen, void *resbuf);
-extern int gc_hmac_md5 (const void *key, size_t keylen,
-                       const void *in, size_t inlen,
-                       char *resbuf);
+extern Gc_rc gc_md2 (const void *in, size_t inlen, void *resbuf);
+extern Gc_rc gc_md4 (const void *in, size_t inlen, void *resbuf);
+extern Gc_rc gc_md5 (const void *in, size_t inlen, void *resbuf);
+extern Gc_rc gc_sha1 (const void *in, size_t inlen, void *resbuf);
+extern Gc_rc gc_hmac_md5 (const void *key, size_t keylen,
+                          const void *in, size_t inlen, char *resbuf);
+extern Gc_rc gc_hmac_sha1 (const void *key, size_t keylen,
+                           const void *in, size_t inlen, char *resbuf);
+extern Gc_rc gc_hmac_sha256 (const void *key, size_t keylen,
+                             const void *in, size_t inlen, char *resbuf);
+extern Gc_rc gc_hmac_sha512 (const void *key, size_t keylen,
+                             const void *in, size_t inlen, char *resbuf);
+
+/* Derive cryptographic keys from a password P of length PLEN, with
+   salt S of length SLEN, placing the result in pre-allocated buffer
+   DK of length DKLEN.  An iteration count is specified in C, where a
+   larger value means this function take more time (typical iteration
+   counts are 1000-20000).  This function "stretches" the key to be
+   exactly dkLen bytes long.  GC_OK is returned on success, otherwise
+   a Gc_rc error code is returned.  */
+extern Gc_rc
+gc_pbkdf2_sha1 (const char *P, size_t Plen,
+                const char *S, size_t Slen,
+                unsigned int c, char *DK, size_t dkLen);
 
 /*
   TODO:
 
 /*
   TODO:
@@ -86,7 +190,7 @@ extern int gc_hmac_md5 (const void *key, size_t keylen,
 
   > Simon Josefsson <jas@extundo.com> writes:
   >
 
   > Simon Josefsson <jas@extundo.com> writes:
   >
-  >> * Perhaps the /dev/*random reading should be separated into a separate
+  >> * Perhaps the /dev/?random reading should be separated into a separate
   >>   module?  It might be useful outside of the gc layer too.
   >
   > Absolutely.  I've been meaning to do that for months (for a "shuffle"
   >>   module?  It might be useful outside of the gc layer too.
   >
   > Absolutely.  I've been meaning to do that for months (for a "shuffle"
@@ -97,9 +201,9 @@ extern int gc_hmac_md5 (const void *key, size_t keylen,
   I'll write a separate module for that part.
 
   I think we should even add a good PRNG that is re-seeded from
   I'll write a separate module for that part.
 
   I think we should even add a good PRNG that is re-seeded from
-  /dev/*random frequently.  GnuTLS can need a lot of random data on a
+  /dev/?random frequently.  GnuTLS can need a lot of random data on a
   big server, more than /dev/random can supply.  And /dev/urandom might
   big server, more than /dev/random can supply.  And /dev/urandom might
-  not be strong enough.  Further, the security of /dev/*random can also
+  not be strong enough.  Further, the security of /dev/?random can also
   be questionable.
 
   >>   I'm also not sure about the names of those functions, they suggest
   be questionable.
 
   >>   I'm also not sure about the names of those functions, they suggest
@@ -137,12 +241,12 @@ extern int gc_hmac_md5 (const void *key, size_t keylen,
   it isn't called too often.  You can guess what the next value will be,
   but it will always be different.
 
   it isn't called too often.  You can guess what the next value will be,
   but it will always be different.
 
-  The problem is that /dev/*random doesn't offer any kind of semantic
+  The problem is that /dev/?random doesn't offer any kind of semantic
   guarantees.  But applications need an API that make that promise.
 
   I think we should do this in several steps:
 
   guarantees.  But applications need an API that make that promise.
 
   I think we should do this in several steps:
 
-  1) Write a module that can read from /dev/*random.
+  1) Write a module that can read from /dev/?random.
 
   2) Add a module for a known-good PRNG suitable for random number
   generation, that can be continuously re-seeded.
 
   2) Add a module for a known-good PRNG suitable for random number
   generation, that can be continuously re-seeded.