1 /* gc-gl-common.c --- Common gnulib internal crypto interface functions
2 * Copyright (C) 2002, 2003, 2004, 2005 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. */
35 #include <sys/types.h>
53 #ifdef GC_USE_HMAC_MD5
67 #ifdef GC_USE_RIJNDAEL
68 # include "rijndael-api-fst.h"
86 randomize (int level, char *data, size_t datalen)
96 device = NAME_OF_NONCE_DEVICE;
100 device = NAME_OF_PSEUDO_RANDOM_DEVICE;
104 device = NAME_OF_RANDOM_DEVICE;
108 fd = open (device, O_RDONLY);
110 return GC_RANDOM_ERROR;
116 tmp = read (fd, data, datalen);
120 int save_errno = errno;
123 return GC_RANDOM_ERROR;
128 while (len < datalen);
132 return GC_RANDOM_ERROR;
138 gc_nonce (char *data, size_t datalen)
140 return randomize (0, data, datalen);
144 gc_pseudo_random (char *data, size_t datalen)
146 return randomize (1, data, datalen);
150 gc_random (char *data, size_t datalen)
152 return randomize (2, data, datalen);
155 /* Memory allocation. */
158 gc_set_allocators (gc_malloc_t func_malloc,
159 gc_malloc_t secure_malloc,
160 gc_secure_check_t secure_check,
161 gc_realloc_t func_realloc, gc_free_t func_free)
167 typedef struct _gc_cipher_ctx {
171 arctwo_context arctwoContext;
172 char arctwoIV[ARCTWO_BLOCK_SIZE];
174 #ifdef GC_USE_ARCFOUR
175 arcfour_context arcfourContext;
180 #ifdef GC_USE_RIJNDAEL
181 rijndaelKeyInstance aesEncKey;
182 rijndaelKeyInstance aesDecKey;
183 rijndaelCipherInstance aesContext;
188 gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
189 gc_cipher_handle * outhandle)
194 ctx = calloc (sizeof (*ctx), 1);
196 return GC_MALLOC_ERROR;
212 rc = GC_INVALID_CIPHER;
217 #ifdef GC_USE_ARCFOUR
226 rc = GC_INVALID_CIPHER;
239 rc = GC_INVALID_CIPHER;
244 #ifdef GC_USE_RIJNDAEL
255 rc = GC_INVALID_CIPHER;
261 rc = GC_INVALID_CIPHER;
273 gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
275 _gc_cipher_ctx *ctx = handle;
281 arctwo_setkey (&ctx->arctwoContext, keylen, key);
285 #ifdef GC_USE_ARCFOUR
288 arcfour_setkey (&ctx->arcfourContext, key, keylen);
295 return GC_INVALID_CIPHER;
296 des_setkey (&ctx->desContext, key);
300 #ifdef GC_USE_RIJNDAEL
307 char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1];
309 for (i = 0; i < keylen; i++)
310 sprintf (&keyMaterial[2*i], "%02x", key[i] & 0xFF);
312 rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT,
313 keylen * 8, keyMaterial);
315 return GC_INVALID_CIPHER;
317 rc = rijndaelMakeKey (&ctx->aesDecKey, RIJNDAEL_DIR_DECRYPT,
318 keylen * 8, keyMaterial);
320 return GC_INVALID_CIPHER;
322 rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_ECB, NULL);
324 return GC_INVALID_CIPHER;
330 return GC_INVALID_CIPHER;
337 gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
339 _gc_cipher_ctx *ctx = handle;
345 if (ivlen != ARCTWO_BLOCK_SIZE)
346 return GC_INVALID_CIPHER;
347 memcpy (ctx->arctwoIV, iv, ivlen);
351 #ifdef GC_USE_RIJNDAEL
358 /* Doesn't use IV. */
365 char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1];
367 for (i = 0; i < ivlen; i++)
368 sprintf (&ivMaterial[2*i], "%02x", iv[i] & 0xFF);
370 rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC,
373 return GC_INVALID_CIPHER;
378 return GC_INVALID_CIPHER;
384 return GC_INVALID_CIPHER;
391 gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
393 _gc_cipher_ctx *ctx = handle;
402 arctwo_encrypt (&ctx->arctwoContext, data, data, len);
406 for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
407 data += ARCTWO_BLOCK_SIZE)
410 for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
411 data[i] ^= ctx->arctwoIV[i];
412 arctwo_encrypt (&ctx->arctwoContext, data, data,
414 memcpy (ctx->arctwoIV, data, ARCTWO_BLOCK_SIZE);
419 return GC_INVALID_CIPHER;
424 #ifdef GC_USE_ARCFOUR
427 arcfour_stream (&ctx->arcfourContext, data, data, len);
433 for (; len >= 8; len -= 8, data += 8)
434 des_ecb_encrypt (&ctx->desContext, data, data);
438 #ifdef GC_USE_RIJNDAEL
445 nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey,
446 data, 8 * len, data);
448 return GC_INVALID_CIPHER;
454 return GC_INVALID_CIPHER;
461 gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
463 _gc_cipher_ctx *ctx = handle;
472 arctwo_decrypt (&ctx->arctwoContext, data, data, len);
476 for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
477 data += ARCTWO_BLOCK_SIZE)
479 char tmpIV[ARCTWO_BLOCK_SIZE];
481 memcpy (tmpIV, data, ARCTWO_BLOCK_SIZE);
482 arctwo_decrypt (&ctx->arctwoContext, data, data,
484 for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
485 data[i] ^= ctx->arctwoIV[i];
486 memcpy (ctx->arctwoIV, tmpIV, ARCTWO_BLOCK_SIZE);
491 return GC_INVALID_CIPHER;
496 #ifdef GC_USE_ARCFOUR
499 arcfour_stream (&ctx->arcfourContext, data, data, len);
505 for (; len >= 8; len -= 8, data += 8)
506 des_ecb_decrypt (&ctx->desContext, data, data);
510 #ifdef GC_USE_RIJNDAEL
517 nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey,
518 data, 8 * len, data);
520 return GC_INVALID_CIPHER;
526 return GC_INVALID_CIPHER;
533 gc_cipher_close (gc_cipher_handle handle)
535 _gc_cipher_ctx *ctx = handle;
545 #define MAX_DIGEST_SIZE 20
547 typedef struct _gc_hash_ctx {
550 char hash[MAX_DIGEST_SIZE];
552 struct md2_ctx md2Context;
555 struct md4_ctx md4Context;
558 struct md5_ctx md5Context;
561 struct sha1_ctx sha1Context;
566 gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
571 ctx = calloc (sizeof (*ctx), 1);
580 md2_init_ctx (&ctx->md2Context);
586 md4_init_ctx (&ctx->md4Context);
592 md5_init_ctx (&ctx->md5Context);
598 sha1_init_ctx (&ctx->sha1Context);
603 rc = GC_INVALID_HASH;
613 rc = GC_INVALID_HASH;
626 gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
628 _gc_hash_ctx *in = handle;
631 *outhandle = out = calloc (sizeof (*out), 1);
633 return GC_MALLOC_ERROR;
635 memcpy (out, in, sizeof (*out));
641 gc_hash_digest_length (Gc_hash hash)
648 len = GC_MD2_DIGEST_SIZE;
652 len = GC_MD4_DIGEST_SIZE;
656 len = GC_MD5_DIGEST_SIZE;
660 len = GC_RMD160_DIGEST_SIZE;
664 len = GC_SHA1_DIGEST_SIZE;
675 gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
677 _gc_hash_ctx *ctx = handle;
683 md2_process_bytes (data, len, &ctx->md2Context);
689 md4_process_bytes (data, len, &ctx->md4Context);
695 md5_process_bytes (data, len, &ctx->md5Context);
701 sha1_process_bytes (data, len, &ctx->sha1Context);
711 gc_hash_read (gc_hash_handle handle)
713 _gc_hash_ctx *ctx = handle;
714 const char *ret = NULL;
720 md2_finish_ctx (&ctx->md2Context, ctx->hash);
727 md4_finish_ctx (&ctx->md4Context, ctx->hash);
734 md5_finish_ctx (&ctx->md5Context, ctx->hash);
741 sha1_finish_ctx (&ctx->sha1Context, ctx->hash);
754 gc_hash_close (gc_hash_handle handle)
756 _gc_hash_ctx *ctx = handle;
762 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
768 md2_buffer (in, inlen, resbuf);
774 md4_buffer (in, inlen, resbuf);
780 md5_buffer (in, inlen, resbuf);
786 sha1_buffer (in, inlen, resbuf);
791 return GC_INVALID_HASH;
799 gc_md2 (const void *in, size_t inlen, void *resbuf)
801 md2_buffer (in, inlen, resbuf);
808 gc_md4 (const void *in, size_t inlen, void *resbuf)
810 md4_buffer (in, inlen, resbuf);
817 gc_md5 (const void *in, size_t inlen, void *resbuf)
819 md5_buffer (in, inlen, resbuf);
826 gc_sha1 (const void *in, size_t inlen, void *resbuf)
828 sha1_buffer (in, inlen, resbuf);
833 #ifdef GC_USE_HMAC_MD5
835 gc_hmac_md5 (const void *key, size_t keylen,
836 const void *in, size_t inlen, char *resbuf)
838 hmac_md5 (key, keylen, in, inlen, resbuf);
843 #ifdef GC_USE_HMAC_SHA1
845 gc_hmac_sha1 (const void *key, size_t keylen,
846 const void *in, size_t inlen, char *resbuf)
848 hmac_sha1 (key, keylen, in, inlen, resbuf);