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. */
36 # include <sys/types.h>
37 # include <sys/stat.h>
55 #ifdef GC_USE_HMAC_MD5
69 #ifdef GC_USE_RIJNDAEL
70 # include "rijndael-api-fst.h"
90 randomize (int level, char *data, size_t datalen)
100 device = NAME_OF_NONCE_DEVICE;
104 device = NAME_OF_PSEUDO_RANDOM_DEVICE;
108 device = NAME_OF_RANDOM_DEVICE;
112 if (strcmp (device, "no") == 0)
113 return GC_RANDOM_ERROR;
115 fd = open (device, O_RDONLY);
117 return GC_RANDOM_ERROR;
123 tmp = read (fd, data, datalen);
127 int save_errno = errno;
130 return GC_RANDOM_ERROR;
135 while (len < datalen);
139 return GC_RANDOM_ERROR;
145 gc_nonce (char *data, size_t datalen)
147 return randomize (0, data, datalen);
151 gc_pseudo_random (char *data, size_t datalen)
153 return randomize (1, data, datalen);
157 gc_random (char *data, size_t datalen)
159 return randomize (2, data, datalen);
164 /* Memory allocation. */
167 gc_set_allocators (gc_malloc_t func_malloc,
168 gc_malloc_t secure_malloc,
169 gc_secure_check_t secure_check,
170 gc_realloc_t func_realloc, gc_free_t func_free)
176 typedef struct _gc_cipher_ctx {
180 arctwo_context arctwoContext;
181 char arctwoIV[ARCTWO_BLOCK_SIZE];
183 #ifdef GC_USE_ARCFOUR
184 arcfour_context arcfourContext;
189 #ifdef GC_USE_RIJNDAEL
190 rijndaelKeyInstance aesEncKey;
191 rijndaelKeyInstance aesDecKey;
192 rijndaelCipherInstance aesContext;
197 gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
198 gc_cipher_handle * outhandle)
203 ctx = calloc (sizeof (*ctx), 1);
205 return GC_MALLOC_ERROR;
221 rc = GC_INVALID_CIPHER;
226 #ifdef GC_USE_ARCFOUR
235 rc = GC_INVALID_CIPHER;
248 rc = GC_INVALID_CIPHER;
253 #ifdef GC_USE_RIJNDAEL
264 rc = GC_INVALID_CIPHER;
270 rc = GC_INVALID_CIPHER;
282 gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
284 _gc_cipher_ctx *ctx = handle;
290 arctwo_setkey (&ctx->arctwoContext, keylen, key);
294 #ifdef GC_USE_ARCFOUR
297 arcfour_setkey (&ctx->arcfourContext, key, keylen);
304 return GC_INVALID_CIPHER;
305 des_setkey (&ctx->desContext, key);
309 #ifdef GC_USE_RIJNDAEL
316 char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1];
318 for (i = 0; i < keylen; i++)
319 sprintf (&keyMaterial[2*i], "%02x", key[i] & 0xFF);
321 rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT,
322 keylen * 8, keyMaterial);
324 return GC_INVALID_CIPHER;
326 rc = rijndaelMakeKey (&ctx->aesDecKey, RIJNDAEL_DIR_DECRYPT,
327 keylen * 8, keyMaterial);
329 return GC_INVALID_CIPHER;
331 rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_ECB, NULL);
333 return GC_INVALID_CIPHER;
339 return GC_INVALID_CIPHER;
346 gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
348 _gc_cipher_ctx *ctx = handle;
354 if (ivlen != ARCTWO_BLOCK_SIZE)
355 return GC_INVALID_CIPHER;
356 memcpy (ctx->arctwoIV, iv, ivlen);
360 #ifdef GC_USE_RIJNDAEL
367 /* Doesn't use IV. */
374 char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1];
376 for (i = 0; i < ivlen; i++)
377 sprintf (&ivMaterial[2*i], "%02x", iv[i] & 0xFF);
379 rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC,
382 return GC_INVALID_CIPHER;
387 return GC_INVALID_CIPHER;
393 return GC_INVALID_CIPHER;
400 gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
402 _gc_cipher_ctx *ctx = handle;
411 arctwo_encrypt (&ctx->arctwoContext, data, data, len);
415 for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
416 data += ARCTWO_BLOCK_SIZE)
419 for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
420 data[i] ^= ctx->arctwoIV[i];
421 arctwo_encrypt (&ctx->arctwoContext, data, data,
423 memcpy (ctx->arctwoIV, data, ARCTWO_BLOCK_SIZE);
428 return GC_INVALID_CIPHER;
433 #ifdef GC_USE_ARCFOUR
436 arcfour_stream (&ctx->arcfourContext, data, data, len);
442 for (; len >= 8; len -= 8, data += 8)
443 des_ecb_encrypt (&ctx->desContext, data, data);
447 #ifdef GC_USE_RIJNDAEL
454 nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey,
455 data, 8 * len, data);
457 return GC_INVALID_CIPHER;
463 return GC_INVALID_CIPHER;
470 gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
472 _gc_cipher_ctx *ctx = handle;
481 arctwo_decrypt (&ctx->arctwoContext, data, data, len);
485 for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
486 data += ARCTWO_BLOCK_SIZE)
488 char tmpIV[ARCTWO_BLOCK_SIZE];
490 memcpy (tmpIV, data, ARCTWO_BLOCK_SIZE);
491 arctwo_decrypt (&ctx->arctwoContext, data, data,
493 for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
494 data[i] ^= ctx->arctwoIV[i];
495 memcpy (ctx->arctwoIV, tmpIV, ARCTWO_BLOCK_SIZE);
500 return GC_INVALID_CIPHER;
505 #ifdef GC_USE_ARCFOUR
508 arcfour_stream (&ctx->arcfourContext, data, data, len);
514 for (; len >= 8; len -= 8, data += 8)
515 des_ecb_decrypt (&ctx->desContext, data, data);
519 #ifdef GC_USE_RIJNDAEL
526 nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey,
527 data, 8 * len, data);
529 return GC_INVALID_CIPHER;
535 return GC_INVALID_CIPHER;
542 gc_cipher_close (gc_cipher_handle handle)
544 _gc_cipher_ctx *ctx = handle;
554 #define MAX_DIGEST_SIZE 20
556 typedef struct _gc_hash_ctx {
559 char hash[MAX_DIGEST_SIZE];
561 struct md2_ctx md2Context;
564 struct md4_ctx md4Context;
567 struct md5_ctx md5Context;
570 struct sha1_ctx sha1Context;
575 gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
580 ctx = calloc (sizeof (*ctx), 1);
589 md2_init_ctx (&ctx->md2Context);
595 md4_init_ctx (&ctx->md4Context);
601 md5_init_ctx (&ctx->md5Context);
607 sha1_init_ctx (&ctx->sha1Context);
612 rc = GC_INVALID_HASH;
622 rc = GC_INVALID_HASH;
635 gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
637 _gc_hash_ctx *in = handle;
640 *outhandle = out = calloc (sizeof (*out), 1);
642 return GC_MALLOC_ERROR;
644 memcpy (out, in, sizeof (*out));
650 gc_hash_digest_length (Gc_hash hash)
657 len = GC_MD2_DIGEST_SIZE;
661 len = GC_MD4_DIGEST_SIZE;
665 len = GC_MD5_DIGEST_SIZE;
669 len = GC_RMD160_DIGEST_SIZE;
673 len = GC_SHA1_DIGEST_SIZE;
684 gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
686 _gc_hash_ctx *ctx = handle;
692 md2_process_bytes (data, len, &ctx->md2Context);
698 md4_process_bytes (data, len, &ctx->md4Context);
704 md5_process_bytes (data, len, &ctx->md5Context);
710 sha1_process_bytes (data, len, &ctx->sha1Context);
720 gc_hash_read (gc_hash_handle handle)
722 _gc_hash_ctx *ctx = handle;
723 const char *ret = NULL;
729 md2_finish_ctx (&ctx->md2Context, ctx->hash);
736 md4_finish_ctx (&ctx->md4Context, ctx->hash);
743 md5_finish_ctx (&ctx->md5Context, ctx->hash);
750 sha1_finish_ctx (&ctx->sha1Context, ctx->hash);
763 gc_hash_close (gc_hash_handle handle)
765 _gc_hash_ctx *ctx = handle;
771 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
777 md2_buffer (in, inlen, resbuf);
783 md4_buffer (in, inlen, resbuf);
789 md5_buffer (in, inlen, resbuf);
795 sha1_buffer (in, inlen, resbuf);
800 return GC_INVALID_HASH;
808 gc_md2 (const void *in, size_t inlen, void *resbuf)
810 md2_buffer (in, inlen, resbuf);
817 gc_md4 (const void *in, size_t inlen, void *resbuf)
819 md4_buffer (in, inlen, resbuf);
826 gc_md5 (const void *in, size_t inlen, void *resbuf)
828 md5_buffer (in, inlen, resbuf);
835 gc_sha1 (const void *in, size_t inlen, void *resbuf)
837 sha1_buffer (in, inlen, resbuf);
842 #ifdef GC_USE_HMAC_MD5
844 gc_hmac_md5 (const void *key, size_t keylen,
845 const void *in, size_t inlen, char *resbuf)
847 hmac_md5 (key, keylen, in, inlen, resbuf);
852 #ifdef GC_USE_HMAC_SHA1
854 gc_hmac_sha1 (const void *key, size_t keylen,
855 const void *in, size_t inlen, char *resbuf)
857 hmac_sha1 (key, keylen, in, inlen, resbuf);