1 /* gc-gnulib.c --- Common gnulib internal crypto interface functions
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006 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
21 /* Note: This file is only built if GC uses internal functions. */
34 # include <sys/types.h>
35 # include <sys/stat.h>
53 #if defined(GC_USE_HMAC_MD5) || defined(GC_USE_HMAC_SHA1)
67 #ifdef GC_USE_RIJNDAEL
68 # include "rijndael-api-fst.h"
88 randomize (int level, char *data, size_t datalen)
98 device = NAME_OF_NONCE_DEVICE;
102 device = NAME_OF_PSEUDO_RANDOM_DEVICE;
106 device = NAME_OF_RANDOM_DEVICE;
110 if (strcmp (device, "no") == 0)
111 return GC_RANDOM_ERROR;
113 fd = open (device, O_RDONLY);
115 return GC_RANDOM_ERROR;
121 tmp = read (fd, data, datalen);
125 int save_errno = errno;
128 return GC_RANDOM_ERROR;
133 while (len < datalen);
137 return GC_RANDOM_ERROR;
143 gc_nonce (char *data, size_t datalen)
145 return randomize (0, data, datalen);
149 gc_pseudo_random (char *data, size_t datalen)
151 return randomize (1, data, datalen);
155 gc_random (char *data, size_t datalen)
157 return randomize (2, data, datalen);
162 /* Memory allocation. */
165 gc_set_allocators (gc_malloc_t func_malloc,
166 gc_malloc_t secure_malloc,
167 gc_secure_check_t secure_check,
168 gc_realloc_t func_realloc, gc_free_t func_free)
174 typedef struct _gc_cipher_ctx {
178 arctwo_context arctwoContext;
179 char arctwoIV[ARCTWO_BLOCK_SIZE];
181 #ifdef GC_USE_ARCFOUR
182 arcfour_context arcfourContext;
187 #ifdef GC_USE_RIJNDAEL
188 rijndaelKeyInstance aesEncKey;
189 rijndaelKeyInstance aesDecKey;
190 rijndaelCipherInstance aesContext;
195 gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
196 gc_cipher_handle * outhandle)
201 ctx = calloc (sizeof (*ctx), 1);
203 return GC_MALLOC_ERROR;
219 rc = GC_INVALID_CIPHER;
224 #ifdef GC_USE_ARCFOUR
233 rc = GC_INVALID_CIPHER;
246 rc = GC_INVALID_CIPHER;
251 #ifdef GC_USE_RIJNDAEL
262 rc = GC_INVALID_CIPHER;
268 rc = GC_INVALID_CIPHER;
280 gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
282 _gc_cipher_ctx *ctx = handle;
288 arctwo_setkey (&ctx->arctwoContext, keylen, key);
292 #ifdef GC_USE_ARCFOUR
295 arcfour_setkey (&ctx->arcfourContext, key, keylen);
302 return GC_INVALID_CIPHER;
303 des_setkey (&ctx->desContext, key);
307 #ifdef GC_USE_RIJNDAEL
314 char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1];
316 for (i = 0; i < keylen; i++)
317 sprintf (&keyMaterial[2*i], "%02x", key[i] & 0xFF);
319 rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT,
320 keylen * 8, keyMaterial);
322 return GC_INVALID_CIPHER;
324 rc = rijndaelMakeKey (&ctx->aesDecKey, RIJNDAEL_DIR_DECRYPT,
325 keylen * 8, keyMaterial);
327 return GC_INVALID_CIPHER;
329 rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_ECB, NULL);
331 return GC_INVALID_CIPHER;
337 return GC_INVALID_CIPHER;
344 gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
346 _gc_cipher_ctx *ctx = handle;
352 if (ivlen != ARCTWO_BLOCK_SIZE)
353 return GC_INVALID_CIPHER;
354 memcpy (ctx->arctwoIV, iv, ivlen);
358 #ifdef GC_USE_RIJNDAEL
365 /* Doesn't use IV. */
372 char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1];
374 for (i = 0; i < ivlen; i++)
375 sprintf (&ivMaterial[2*i], "%02x", iv[i] & 0xFF);
377 rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC,
380 return GC_INVALID_CIPHER;
385 return GC_INVALID_CIPHER;
391 return GC_INVALID_CIPHER;
398 gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
400 _gc_cipher_ctx *ctx = handle;
409 arctwo_encrypt (&ctx->arctwoContext, data, data, len);
413 for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
414 data += ARCTWO_BLOCK_SIZE)
417 for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
418 data[i] ^= ctx->arctwoIV[i];
419 arctwo_encrypt (&ctx->arctwoContext, data, data,
421 memcpy (ctx->arctwoIV, data, ARCTWO_BLOCK_SIZE);
426 return GC_INVALID_CIPHER;
431 #ifdef GC_USE_ARCFOUR
434 arcfour_stream (&ctx->arcfourContext, data, data, len);
440 for (; len >= 8; len -= 8, data += 8)
441 des_ecb_encrypt (&ctx->desContext, data, data);
445 #ifdef GC_USE_RIJNDAEL
452 nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey,
453 data, 8 * len, data);
455 return GC_INVALID_CIPHER;
461 return GC_INVALID_CIPHER;
468 gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
470 _gc_cipher_ctx *ctx = handle;
479 arctwo_decrypt (&ctx->arctwoContext, data, data, len);
483 for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
484 data += ARCTWO_BLOCK_SIZE)
486 char tmpIV[ARCTWO_BLOCK_SIZE];
488 memcpy (tmpIV, data, ARCTWO_BLOCK_SIZE);
489 arctwo_decrypt (&ctx->arctwoContext, data, data,
491 for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
492 data[i] ^= ctx->arctwoIV[i];
493 memcpy (ctx->arctwoIV, tmpIV, ARCTWO_BLOCK_SIZE);
498 return GC_INVALID_CIPHER;
503 #ifdef GC_USE_ARCFOUR
506 arcfour_stream (&ctx->arcfourContext, data, data, len);
512 for (; len >= 8; len -= 8, data += 8)
513 des_ecb_decrypt (&ctx->desContext, data, data);
517 #ifdef GC_USE_RIJNDAEL
524 nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey,
525 data, 8 * len, data);
527 return GC_INVALID_CIPHER;
533 return GC_INVALID_CIPHER;
540 gc_cipher_close (gc_cipher_handle handle)
542 _gc_cipher_ctx *ctx = handle;
552 #define MAX_DIGEST_SIZE 20
554 typedef struct _gc_hash_ctx {
557 char hash[MAX_DIGEST_SIZE];
559 struct md2_ctx md2Context;
562 struct md4_ctx md4Context;
565 struct md5_ctx md5Context;
568 struct sha1_ctx sha1Context;
573 gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
578 ctx = calloc (sizeof (*ctx), 1);
587 md2_init_ctx (&ctx->md2Context);
593 md4_init_ctx (&ctx->md4Context);
599 md5_init_ctx (&ctx->md5Context);
605 sha1_init_ctx (&ctx->sha1Context);
610 rc = GC_INVALID_HASH;
620 rc = GC_INVALID_HASH;
633 gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
635 _gc_hash_ctx *in = handle;
638 *outhandle = out = calloc (sizeof (*out), 1);
640 return GC_MALLOC_ERROR;
642 memcpy (out, in, sizeof (*out));
648 gc_hash_digest_length (Gc_hash hash)
655 len = GC_MD2_DIGEST_SIZE;
659 len = GC_MD4_DIGEST_SIZE;
663 len = GC_MD5_DIGEST_SIZE;
667 len = GC_RMD160_DIGEST_SIZE;
671 len = GC_SHA1_DIGEST_SIZE;
682 gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
684 _gc_hash_ctx *ctx = handle;
690 md2_process_bytes (data, len, &ctx->md2Context);
696 md4_process_bytes (data, len, &ctx->md4Context);
702 md5_process_bytes (data, len, &ctx->md5Context);
708 sha1_process_bytes (data, len, &ctx->sha1Context);
718 gc_hash_read (gc_hash_handle handle)
720 _gc_hash_ctx *ctx = handle;
721 const char *ret = NULL;
727 md2_finish_ctx (&ctx->md2Context, ctx->hash);
734 md4_finish_ctx (&ctx->md4Context, ctx->hash);
741 md5_finish_ctx (&ctx->md5Context, ctx->hash);
748 sha1_finish_ctx (&ctx->sha1Context, ctx->hash);
761 gc_hash_close (gc_hash_handle handle)
763 _gc_hash_ctx *ctx = handle;
769 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
775 md2_buffer (in, inlen, resbuf);
781 md4_buffer (in, inlen, resbuf);
787 md5_buffer (in, inlen, resbuf);
793 sha1_buffer (in, inlen, resbuf);
798 return GC_INVALID_HASH;
806 gc_md2 (const void *in, size_t inlen, void *resbuf)
808 md2_buffer (in, inlen, resbuf);
815 gc_md4 (const void *in, size_t inlen, void *resbuf)
817 md4_buffer (in, inlen, resbuf);
824 gc_md5 (const void *in, size_t inlen, void *resbuf)
826 md5_buffer (in, inlen, resbuf);
833 gc_sha1 (const void *in, size_t inlen, void *resbuf)
835 sha1_buffer (in, inlen, resbuf);
840 #ifdef GC_USE_HMAC_MD5
842 gc_hmac_md5 (const void *key, size_t keylen,
843 const void *in, size_t inlen, char *resbuf)
845 hmac_md5 (key, keylen, in, inlen, resbuf);
850 #ifdef GC_USE_HMAC_SHA1
852 gc_hmac_sha1 (const void *key, size_t keylen,
853 const void *in, size_t inlen, char *resbuf)
855 hmac_sha1 (key, keylen, in, inlen, resbuf);