#include #include typedef uint64_t ulong64; typedef uint32_t ulong32; #define CRYPT_OK 0 #define CRYPT_INVALID_ARG 1 #define CRYPT_NOP 2 #define CRYPT_FAIL_TESTVECTOR 3 #define XMEMCMP memcmp #define LTC_ARGCHK(x) struct sha1_state { ulong64 length; ulong32 state[5], curlen; unsigned char buf[64]; }; struct md5_state { ulong64 length; ulong32 state[4], curlen; unsigned char buf[64]; }; typedef union Hash_state { struct sha1_state sha1; struct md5_state md5; void *data; } hash_state; int sha1_init(hash_state * md); int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen); int sha1_done(hash_state * md, unsigned char *hash); int sha1_test(void); int md5_init(hash_state * md); int md5_process(hash_state * md, const unsigned char *in, unsigned long inlen); int md5_done(hash_state * md, unsigned char *hash); int md5_test(void); /* a simple macro for making hash "process" functions */ #define HASH_PROCESS(func_name, compress_name, state_var, block_size) \ int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) \ { \ unsigned long n; \ int err; \ LTC_ARGCHK(md != NULL); \ LTC_ARGCHK(in != NULL); \ if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \ return CRYPT_INVALID_ARG; \ } \ while (inlen > 0) { \ if (md-> state_var .curlen == 0 && inlen >= block_size) { \ if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \ return err; \ } \ md-> state_var .length += block_size * 8; \ in += block_size; \ inlen -= block_size; \ } else { \ n = MIN(inlen, (block_size - md-> state_var .curlen)); \ memcpy(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n); \ md-> state_var .curlen += n; \ in += n; \ inlen -= n; \ if (md-> state_var .curlen == block_size) { \ if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) { \ return err; \ } \ md-> state_var .length += 8*block_size; \ md-> state_var .curlen = 0; \ } \ } \ } \ return CRYPT_OK; \ }