gc-libgcrypt.c

Go to the documentation of this file.
00001 /* gc-libgcrypt.c --- Crypto wrappers around Libgcrypt for GC.
00002  * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007  Simon Josefsson
00003  *
00004  * This file is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU Lesser General Public License as published
00006  * by the Free Software Foundation; either version 2.1, or (at your
00007  * option) any later version.
00008  *
00009  * This file is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public License
00015  * along with this file; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017  * 02110-1301, USA.
00018  *
00019  */
00020 
00021 /* Note: This file is only built if GC uses Libgcrypt. */
00022 
00023 #include "MHD_config.h"
00024 
00025 /* Get prototype. */
00026 #include "gc.h"
00027 
00028 #include <stdlib.h>
00029 #include <string.h>
00030 
00031 /* Get libgcrypt API. */
00032 #include <gcrypt.h>
00033 
00034 #include <assert.h>
00035 
00036 /* Initialization. */
00037 
00038 Gc_rc
00039 MHD_gc_init (void)
00040 {
00041   gcry_error_t err;
00042 
00043   err = gcry_control (GCRYCTL_ANY_INITIALIZATION_P);
00044   if (err == GPG_ERR_NO_ERROR)
00045     {
00046       if (gcry_check_version (GCRYPT_VERSION) == NULL)
00047         return GC_INIT_ERROR;
00048 
00049       err = gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
00050       if (err != GPG_ERR_NO_ERROR)
00051         return GC_INIT_ERROR;
00052     }
00053   return GC_OK;
00054 }
00055 
00056 void
00057 MHD_gc_done (void)
00058 {
00059   return;
00060 }
00061 
00062 #ifdef GNULIB_GC_RANDOM
00063 
00064 /* Randomness. */
00065 
00066 Gc_rc
00067 MHD_gc_nonce (char *data, size_t datalen)
00068 {
00069   gcry_create_nonce ((unsigned char *) data, datalen);
00070   return GC_OK;
00071 }
00072 
00073 Gc_rc
00074 MHD_gc_pseudo_random (char *data, size_t datalen)
00075 {
00076   gcry_randomize ((unsigned char *) data, datalen, GCRY_STRONG_RANDOM);
00077   return GC_OK;
00078 }
00079 
00080 #endif
00081 
00082 /* Memory allocation. */
00083 
00084 /* Ciphers. */
00085 
00086 Gc_rc
00087 MHD_gc_cipher_open (Gc_cipher alg,
00088                     Gc_cipher_mode mode, MHD_gc_cipher_handle * outhandle)
00089 {
00090   int gcryalg, gcrymode;
00091   gcry_error_t err;
00092 
00093   switch (alg)
00094     {
00095     case GC_AES128:
00096       gcryalg = GCRY_CIPHER_RIJNDAEL;
00097       break;
00098 
00099     case GC_AES192:
00100       gcryalg = GCRY_CIPHER_RIJNDAEL;
00101       break;
00102 
00103     case GC_AES256:
00104       gcryalg = GCRY_CIPHER_RIJNDAEL256;
00105       break;
00106 
00107     case GC_3DES:
00108       gcryalg = GCRY_CIPHER_3DES;
00109       break;
00110 
00111     case GC_DES:
00112       gcryalg = GCRY_CIPHER_DES;
00113       break;
00114 
00115     case GC_ARCFOUR128:
00116     case GC_ARCFOUR40:
00117       gcryalg = GCRY_CIPHER_ARCFOUR;
00118       break;
00119 
00120     case GC_ARCTWO40:
00121       gcryalg = GCRY_CIPHER_RFC2268_40;
00122       break;
00123 
00124     default:
00125       return GC_INVALID_CIPHER;
00126     }
00127 
00128   switch (mode)
00129     {
00130     case GC_ECB:
00131       gcrymode = GCRY_CIPHER_MODE_ECB;
00132       break;
00133 
00134     case GC_CBC:
00135       gcrymode = GCRY_CIPHER_MODE_CBC;
00136       break;
00137 
00138     case GC_STREAM:
00139       gcrymode = GCRY_CIPHER_MODE_STREAM;
00140       break;
00141 
00142     default:
00143       return GC_INVALID_CIPHER;
00144     }
00145 
00146   err =
00147     gcry_cipher_open ((gcry_cipher_hd_t *) outhandle, gcryalg, gcrymode, 0);
00148   if (gcry_err_code (err))
00149     return GC_INVALID_CIPHER;
00150 
00151   return GC_OK;
00152 }
00153 
00154 Gc_rc
00155 MHD_gc_cipher_setkey (MHD_gc_cipher_handle handle, size_t keylen,
00156                       const char *key)
00157 {
00158   gcry_error_t err;
00159 
00160   err = gcry_cipher_setkey ((gcry_cipher_hd_t) handle, key, keylen);
00161   if (gcry_err_code (err))
00162     return GC_INVALID_CIPHER;
00163 
00164   return GC_OK;
00165 }
00166 
00167 Gc_rc
00168 MHD_gc_cipher_setiv (MHD_gc_cipher_handle handle, size_t ivlen,
00169                      const char *iv)
00170 {
00171   gcry_error_t err;
00172 
00173   err = gcry_cipher_setiv ((gcry_cipher_hd_t) handle, iv, ivlen);
00174   if (gcry_err_code (err))
00175     return GC_INVALID_CIPHER;
00176 
00177   return GC_OK;
00178 }
00179 
00180 Gc_rc
00181 MHD_gc_cipher_encrypt_inline (MHD_gc_cipher_handle handle, size_t len,
00182                               char *data)
00183 {
00184   if (gcry_cipher_encrypt ((gcry_cipher_hd_t) handle, data, len, NULL, len) !=
00185       0)
00186     return GC_INVALID_CIPHER;
00187 
00188   return GC_OK;
00189 }
00190 
00191 Gc_rc
00192 MHD_gc_cipher_decrypt_inline (MHD_gc_cipher_handle handle, size_t len,
00193                               char *data)
00194 {
00195   if (gcry_cipher_decrypt ((gcry_cipher_hd_t) handle, data, len, NULL, len) !=
00196       0)
00197     return GC_INVALID_CIPHER;
00198 
00199   return GC_OK;
00200 }
00201 
00202 Gc_rc
00203 MHD_gc_cipher_close (MHD_gc_cipher_handle handle)
00204 {
00205   gcry_cipher_close (handle);
00206 
00207   return GC_OK;
00208 }
00209 
00210 /* Hashes. */
00211 
00212 typedef struct _MHD_gc_hash_ctx
00213 {
00214   Gc_hash alg;
00215   Gc_hash_mode mode;
00216   gcry_md_hd_t gch;
00217 } _MHD_gc_hash_ctx;
00218 
00219 Gc_rc
00220 MHD_gc_hash_open (Gc_hash hash, Gc_hash_mode mode,
00221                   MHD_gc_hash_handle * outhandle)
00222 {
00223   _MHD_gc_hash_ctx *ctx;
00224   int gcryalg = 0, gcrymode = 0;
00225   gcry_error_t err;
00226   Gc_rc rc = GC_OK;
00227 
00228   ctx = calloc (sizeof (*ctx), 1);
00229   if (!ctx)
00230     return GC_MALLOC_ERROR;
00231 
00232   ctx->alg = hash;
00233   ctx->mode = mode;
00234 
00235   switch (hash)
00236     {
00237     case GC_MD2:
00238       gcryalg = GCRY_MD_NONE;
00239       break;
00240 
00241     case GC_MD4:
00242       gcryalg = GCRY_MD_MD4;
00243       break;
00244 
00245     case GC_MD5:
00246       gcryalg = GCRY_MD_MD5;
00247       break;
00248 
00249     case GC_SHA1:
00250       gcryalg = GCRY_MD_SHA1;
00251       break;
00252 
00253     case GC_SHA256:
00254       gcryalg = GCRY_MD_SHA256;
00255       break;
00256 
00257     case GC_SHA384:
00258       gcryalg = GCRY_MD_SHA384;
00259       break;
00260 
00261     case GC_SHA512:
00262       gcryalg = GCRY_MD_SHA512;
00263       break;
00264 
00265     case GC_RMD160:
00266       gcryalg = GCRY_MD_RMD160;
00267       break;
00268 
00269     default:
00270       rc = GC_INVALID_HASH;
00271     }
00272 
00273   switch (mode)
00274     {
00275     case 0:
00276       gcrymode = 0;
00277       break;
00278 
00279     case GC_HMAC:
00280       gcrymode = GCRY_MD_FLAG_HMAC;
00281       break;
00282 
00283     default:
00284       rc = GC_INVALID_HASH;
00285     }
00286 
00287   if (rc == GC_OK && gcryalg != GCRY_MD_NONE)
00288     {
00289       err = gcry_md_open (&ctx->gch, gcryalg, gcrymode);
00290       if (gcry_err_code (err))
00291         rc = GC_INVALID_HASH;
00292     }
00293 
00294   if (rc == GC_OK)
00295     *outhandle = ctx;
00296   else
00297     free (ctx);
00298 
00299   return rc;
00300 }
00301 
00302 Gc_rc
00303 MHD_gc_hash_clone (MHD_gc_hash_handle handle, MHD_gc_hash_handle * outhandle)
00304 {
00305   _MHD_gc_hash_ctx *in = handle;
00306   _MHD_gc_hash_ctx *out;
00307   int err;
00308 
00309   *outhandle = out = calloc (sizeof (*out), 1);
00310   if (!out)
00311     return GC_MALLOC_ERROR;
00312 
00313   memcpy (out, in, sizeof (*out));
00314 
00315   err = gcry_md_copy (&out->gch, in->gch);
00316   if (err)
00317     {
00318       free (out);
00319       return GC_INVALID_HASH;
00320     }
00321 
00322   return GC_OK;
00323 }
00324 
00325 size_t
00326 MHD_gc_hash_digest_length (Gc_hash hash)
00327 {
00328   size_t len;
00329 
00330   switch (hash)
00331     {
00332     case GC_MD2:
00333       len = GC_MD2_DIGEST_SIZE;
00334       break;
00335 
00336     case GC_MD4:
00337       len = GC_MD4_DIGEST_SIZE;
00338       break;
00339 
00340     case GC_MD5:
00341       len = GC_MD5_DIGEST_SIZE;
00342       break;
00343 
00344     case GC_RMD160:
00345       len = GC_RMD160_DIGEST_SIZE;
00346       break;
00347 
00348     case GC_SHA1:
00349       len = GC_SHA1_DIGEST_SIZE;
00350       break;
00351 
00352     case GC_SHA256:
00353       len = GC_SHA256_DIGEST_SIZE;
00354       break;
00355 
00356     case GC_SHA384:
00357       len = GC_SHA384_DIGEST_SIZE;
00358       break;
00359 
00360     case GC_SHA512:
00361       len = GC_SHA512_DIGEST_SIZE;
00362       break;
00363 
00364     default:
00365       return 0;
00366     }
00367 
00368   return len;
00369 }
00370 
00371 void
00372 MHD_gc_hash_MHD_hmac_setkey (MHD_gc_hash_handle handle, size_t len,
00373                              const char *key)
00374 {
00375   _MHD_gc_hash_ctx *ctx = handle;
00376   gcry_md_setkey (ctx->gch, key, len);
00377 }
00378 
00379 void
00380 MHD_gc_hash_write (MHD_gc_hash_handle handle, size_t len, const char *data)
00381 {
00382   _MHD_gc_hash_ctx *ctx = handle;
00383   gcry_md_write (ctx->gch, data, len);
00384 }
00385 
00386 const char *
00387 MHD_gc_hash_read (MHD_gc_hash_handle handle)
00388 {
00389   _MHD_gc_hash_ctx *ctx = handle;
00390   const char *digest;
00391   {
00392     gcry_md_final (ctx->gch);
00393     digest = (const char *) gcry_md_read (ctx->gch, 0);
00394   }
00395 
00396   return digest;
00397 }
00398 
00399 void
00400 MHD_gc_hash_close (MHD_gc_hash_handle handle)
00401 {
00402   _MHD_gc_hash_ctx *ctx = handle;
00403 
00404   gcry_md_close (ctx->gch);
00405 
00406   free (ctx);
00407 }

Generated by  doxygen 1.6.2