1 /* gc-gnulib.c --- Common gnulib internal crypto interface functions
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Simon Josefsson
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 published
6 * by the Free Software Foundation; either version 2.1, 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 Lesser 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. */
32 #ifdef GNULIB_GC_RANDOM
34 # include <sys/types.h>
35 # include <sys/stat.h>
53 #if defined(GNULIB_GC_HMAC_MD5) || defined(GNULIB_GC_HMAC_SHA1)
58 #ifdef GNULIB_GC_ARCFOUR
61 #ifdef GNULIB_GC_ARCTWO
67 #ifdef GNULIB_GC_RIJNDAEL
68 # include "rijndael-api-fst.h"
71 /* The results of open() in this file are not used with fchdir,
72 therefore save some unnecessary work in fchdir.c. */
88 #ifdef GNULIB_GC_RANDOM
93 randomize (int level
, char *data
, size_t datalen
)
103 device
= NAME_OF_NONCE_DEVICE
;
107 device
= NAME_OF_PSEUDO_RANDOM_DEVICE
;
111 device
= NAME_OF_RANDOM_DEVICE
;
115 if (strcmp (device
, "no") == 0)
116 return GC_RANDOM_ERROR
;
118 fd
= open (device
, O_RDONLY
);
120 return GC_RANDOM_ERROR
;
126 tmp
= read (fd
, data
, datalen
);
130 int save_errno
= errno
;
133 return GC_RANDOM_ERROR
;
138 while (len
< datalen
);
142 return GC_RANDOM_ERROR
;
148 gc_nonce (char *data
, size_t datalen
)
150 return randomize (0, data
, datalen
);
154 gc_pseudo_random (char *data
, size_t datalen
)
156 return randomize (1, data
, datalen
);
160 gc_random (char *data
, size_t datalen
)
162 return randomize (2, data
, datalen
);
167 /* Memory allocation. */
170 gc_set_allocators (gc_malloc_t func_malloc
,
171 gc_malloc_t secure_malloc
,
172 gc_secure_check_t secure_check
,
173 gc_realloc_t func_realloc
, gc_free_t func_free
)
179 typedef struct _gc_cipher_ctx
{
182 #ifdef GNULIB_GC_ARCTWO
183 arctwo_context arctwoContext
;
184 char arctwoIV
[ARCTWO_BLOCK_SIZE
];
186 #ifdef GNULIB_GC_ARCFOUR
187 arcfour_context arcfourContext
;
190 gl_des_ctx desContext
;
192 #ifdef GNULIB_GC_RIJNDAEL
193 rijndaelKeyInstance aesEncKey
;
194 rijndaelKeyInstance aesDecKey
;
195 rijndaelCipherInstance aesContext
;
200 gc_cipher_open (Gc_cipher alg
, Gc_cipher_mode mode
,
201 gc_cipher_handle
* outhandle
)
206 ctx
= calloc (sizeof (*ctx
), 1);
208 return GC_MALLOC_ERROR
;
215 #ifdef GNULIB_GC_ARCTWO
224 rc
= GC_INVALID_CIPHER
;
229 #ifdef GNULIB_GC_ARCFOUR
238 rc
= GC_INVALID_CIPHER
;
251 rc
= GC_INVALID_CIPHER
;
256 #ifdef GNULIB_GC_RIJNDAEL
267 rc
= GC_INVALID_CIPHER
;
273 rc
= GC_INVALID_CIPHER
;
285 gc_cipher_setkey (gc_cipher_handle handle
, size_t keylen
, const char *key
)
287 _gc_cipher_ctx
*ctx
= handle
;
291 #ifdef GNULIB_GC_ARCTWO
293 arctwo_setkey (&ctx
->arctwoContext
, keylen
, key
);
297 #ifdef GNULIB_GC_ARCFOUR
300 arcfour_setkey (&ctx
->arcfourContext
, key
, keylen
);
307 return GC_INVALID_CIPHER
;
308 gl_des_setkey (&ctx
->desContext
, key
);
312 #ifdef GNULIB_GC_RIJNDAEL
319 char keyMaterial
[RIJNDAEL_MAX_KEY_SIZE
+ 1];
321 for (i
= 0; i
< keylen
; i
++)
322 sprintf (&keyMaterial
[2*i
], "%02x", key
[i
] & 0xFF);
324 rc
= rijndaelMakeKey (&ctx
->aesEncKey
, RIJNDAEL_DIR_ENCRYPT
,
325 keylen
* 8, keyMaterial
);
327 return GC_INVALID_CIPHER
;
329 rc
= rijndaelMakeKey (&ctx
->aesDecKey
, RIJNDAEL_DIR_DECRYPT
,
330 keylen
* 8, keyMaterial
);
332 return GC_INVALID_CIPHER
;
334 rc
= rijndaelCipherInit (&ctx
->aesContext
, RIJNDAEL_MODE_ECB
, NULL
);
336 return GC_INVALID_CIPHER
;
342 return GC_INVALID_CIPHER
;
349 gc_cipher_setiv (gc_cipher_handle handle
, size_t ivlen
, const char *iv
)
351 _gc_cipher_ctx
*ctx
= handle
;
355 #ifdef GNULIB_GC_ARCTWO
357 if (ivlen
!= ARCTWO_BLOCK_SIZE
)
358 return GC_INVALID_CIPHER
;
359 memcpy (ctx
->arctwoIV
, iv
, ivlen
);
363 #ifdef GNULIB_GC_RIJNDAEL
370 /* Doesn't use IV. */
377 char ivMaterial
[2 * RIJNDAEL_MAX_IV_SIZE
+ 1];
379 for (i
= 0; i
< ivlen
; i
++)
380 sprintf (&ivMaterial
[2*i
], "%02x", iv
[i
] & 0xFF);
382 rc
= rijndaelCipherInit (&ctx
->aesContext
, RIJNDAEL_MODE_CBC
,
385 return GC_INVALID_CIPHER
;
390 return GC_INVALID_CIPHER
;
396 return GC_INVALID_CIPHER
;
403 gc_cipher_encrypt_inline (gc_cipher_handle handle
, size_t len
, char *data
)
405 _gc_cipher_ctx
*ctx
= handle
;
409 #ifdef GNULIB_GC_ARCTWO
414 arctwo_encrypt (&ctx
->arctwoContext
, data
, data
, len
);
418 for (; len
>= ARCTWO_BLOCK_SIZE
; len
-= ARCTWO_BLOCK_SIZE
,
419 data
+= ARCTWO_BLOCK_SIZE
)
422 for (i
= 0; i
< ARCTWO_BLOCK_SIZE
; i
++)
423 data
[i
] ^= ctx
->arctwoIV
[i
];
424 arctwo_encrypt (&ctx
->arctwoContext
, data
, data
,
426 memcpy (ctx
->arctwoIV
, data
, ARCTWO_BLOCK_SIZE
);
431 return GC_INVALID_CIPHER
;
436 #ifdef GNULIB_GC_ARCFOUR
439 arcfour_stream (&ctx
->arcfourContext
, data
, data
, len
);
445 for (; len
>= 8; len
-= 8, data
+= 8)
446 gl_des_ecb_encrypt (&ctx
->desContext
, data
, data
);
450 #ifdef GNULIB_GC_RIJNDAEL
457 nblocks
= rijndaelBlockEncrypt (&ctx
->aesContext
, &ctx
->aesEncKey
,
458 data
, 8 * len
, data
);
460 return GC_INVALID_CIPHER
;
466 return GC_INVALID_CIPHER
;
473 gc_cipher_decrypt_inline (gc_cipher_handle handle
, size_t len
, char *data
)
475 _gc_cipher_ctx
*ctx
= handle
;
479 #ifdef GNULIB_GC_ARCTWO
484 arctwo_decrypt (&ctx
->arctwoContext
, data
, data
, len
);
488 for (; len
>= ARCTWO_BLOCK_SIZE
; len
-= ARCTWO_BLOCK_SIZE
,
489 data
+= ARCTWO_BLOCK_SIZE
)
491 char tmpIV
[ARCTWO_BLOCK_SIZE
];
493 memcpy (tmpIV
, data
, ARCTWO_BLOCK_SIZE
);
494 arctwo_decrypt (&ctx
->arctwoContext
, data
, data
,
496 for (i
= 0; i
< ARCTWO_BLOCK_SIZE
; i
++)
497 data
[i
] ^= ctx
->arctwoIV
[i
];
498 memcpy (ctx
->arctwoIV
, tmpIV
, ARCTWO_BLOCK_SIZE
);
503 return GC_INVALID_CIPHER
;
508 #ifdef GNULIB_GC_ARCFOUR
511 arcfour_stream (&ctx
->arcfourContext
, data
, data
, len
);
517 for (; len
>= 8; len
-= 8, data
+= 8)
518 gl_des_ecb_decrypt (&ctx
->desContext
, data
, data
);
522 #ifdef GNULIB_GC_RIJNDAEL
529 nblocks
= rijndaelBlockDecrypt (&ctx
->aesContext
, &ctx
->aesDecKey
,
530 data
, 8 * len
, data
);
532 return GC_INVALID_CIPHER
;
538 return GC_INVALID_CIPHER
;
545 gc_cipher_close (gc_cipher_handle handle
)
547 _gc_cipher_ctx
*ctx
= handle
;
556 #define MAX_DIGEST_SIZE 20
558 typedef struct _gc_hash_ctx
{
561 char hash
[MAX_DIGEST_SIZE
];
563 struct md2_ctx md2Context
;
566 struct md4_ctx md4Context
;
569 struct md5_ctx md5Context
;
571 #ifdef GNULIB_GC_SHA1
572 struct sha1_ctx sha1Context
;
577 gc_hash_open (Gc_hash hash
, Gc_hash_mode mode
, gc_hash_handle
* outhandle
)
582 ctx
= calloc (sizeof (*ctx
), 1);
584 return GC_MALLOC_ERROR
;
593 md2_init_ctx (&ctx
->md2Context
);
599 md4_init_ctx (&ctx
->md4Context
);
605 md5_init_ctx (&ctx
->md5Context
);
609 #ifdef GNULIB_GC_SHA1
611 sha1_init_ctx (&ctx
->sha1Context
);
616 rc
= GC_INVALID_HASH
;
626 rc
= GC_INVALID_HASH
;
639 gc_hash_clone (gc_hash_handle handle
, gc_hash_handle
* outhandle
)
641 _gc_hash_ctx
*in
= handle
;
644 *outhandle
= out
= calloc (sizeof (*out
), 1);
646 return GC_MALLOC_ERROR
;
648 memcpy (out
, in
, sizeof (*out
));
654 gc_hash_digest_length (Gc_hash hash
)
661 len
= GC_MD2_DIGEST_SIZE
;
665 len
= GC_MD4_DIGEST_SIZE
;
669 len
= GC_MD5_DIGEST_SIZE
;
673 len
= GC_RMD160_DIGEST_SIZE
;
677 len
= GC_SHA1_DIGEST_SIZE
;
688 gc_hash_write (gc_hash_handle handle
, size_t len
, const char *data
)
690 _gc_hash_ctx
*ctx
= handle
;
696 md2_process_bytes (data
, len
, &ctx
->md2Context
);
702 md4_process_bytes (data
, len
, &ctx
->md4Context
);
708 md5_process_bytes (data
, len
, &ctx
->md5Context
);
712 #ifdef GNULIB_GC_SHA1
714 sha1_process_bytes (data
, len
, &ctx
->sha1Context
);
724 gc_hash_read (gc_hash_handle handle
)
726 _gc_hash_ctx
*ctx
= handle
;
727 const char *ret
= NULL
;
733 md2_finish_ctx (&ctx
->md2Context
, ctx
->hash
);
740 md4_finish_ctx (&ctx
->md4Context
, ctx
->hash
);
747 md5_finish_ctx (&ctx
->md5Context
, ctx
->hash
);
752 #ifdef GNULIB_GC_SHA1
754 sha1_finish_ctx (&ctx
->sha1Context
, ctx
->hash
);
767 gc_hash_close (gc_hash_handle handle
)
769 _gc_hash_ctx
*ctx
= handle
;
775 gc_hash_buffer (Gc_hash hash
, const void *in
, size_t inlen
, char *resbuf
)
781 md2_buffer (in
, inlen
, resbuf
);
787 md4_buffer (in
, inlen
, resbuf
);
793 md5_buffer (in
, inlen
, resbuf
);
797 #ifdef GNULIB_GC_SHA1
799 sha1_buffer (in
, inlen
, resbuf
);
804 return GC_INVALID_HASH
;
812 gc_md2 (const void *in
, size_t inlen
, void *resbuf
)
814 md2_buffer (in
, inlen
, resbuf
);
821 gc_md4 (const void *in
, size_t inlen
, void *resbuf
)
823 md4_buffer (in
, inlen
, resbuf
);
830 gc_md5 (const void *in
, size_t inlen
, void *resbuf
)
832 md5_buffer (in
, inlen
, resbuf
);
837 #ifdef GNULIB_GC_SHA1
839 gc_sha1 (const void *in
, size_t inlen
, void *resbuf
)
841 sha1_buffer (in
, inlen
, resbuf
);
846 #ifdef GNULIB_GC_HMAC_MD5
848 gc_hmac_md5 (const void *key
, size_t keylen
,
849 const void *in
, size_t inlen
, char *resbuf
)
851 hmac_md5 (key
, keylen
, in
, inlen
, resbuf
);
856 #ifdef GNULIB_GC_HMAC_SHA1
858 gc_hmac_sha1 (const void *key
, size_t keylen
,
859 const void *in
, size_t inlen
, char *resbuf
)
861 hmac_sha1 (key
, keylen
, in
, inlen
, resbuf
);