root/maint/gnulib/lib/gc.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


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

/* [previous][next][first][last][top][bottom][index][help] */