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
);