750 lines
16 KiB
C
750 lines
16 KiB
C
/*
|
|
* Copyright (C) 1998 Nikos Mavroyanopoulos
|
|
* Copyright (C) 1999,2000 Sascha Schumman, Nikos Mavroyanopoulos
|
|
* Copyright (C) 2001 Nikos Mavroyanopoulos
|
|
*
|
|
* This library is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Library General Public License as published
|
|
* by the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
|
|
/* $Id: mhash.c,v 1.42 2006/01/10 04:40:48 imipak Exp $ */
|
|
|
|
#include <libdefs.h>
|
|
|
|
#include <mhash_int.h>
|
|
|
|
#include <mhash_crc32.h>
|
|
#include <mhash_haval.h>
|
|
#include <mhash_md5.h>
|
|
#include <mhash_md4.h>
|
|
#include <mhash_md2.h>
|
|
#include <mhash_sha1.h>
|
|
#include <mhash_tiger.h>
|
|
#include <mhash_ripemd.h>
|
|
#include <mhash_sha256_sha224.h>
|
|
#include <mhash_sha512_sha384.h>
|
|
#include <mhash_adler32.h>
|
|
#include <mhash_gost.h>
|
|
#include <mhash_whirlpool.h>
|
|
#include <mhash_snefru.h>
|
|
|
|
/* 19/03/2000 Changes for better thread handling --nikos
|
|
* Actually it is thread safe.
|
|
*/
|
|
|
|
#define MAX_BLOCK_SIZE 128
|
|
|
|
#define MHASH_ENTRY(name, blksize, hash_pblock, state_size, \
|
|
init_func, hash_func, final_func, deinit_func) \
|
|
{ (mutils_word8 *) #name, name, blksize, hash_pblock, state_size, \
|
|
(INIT_FUNC) init_func, (HASH_FUNC) hash_func, \
|
|
(FINAL_FUNC) final_func, (DEINIT_FUNC) deinit_func }
|
|
|
|
struct mhash_hash_entry {
|
|
mutils_word8 *name;
|
|
hashid id;
|
|
mutils_word32 blocksize;
|
|
mutils_word32 hash_pblock;
|
|
|
|
mutils_word32 state_size;
|
|
INIT_FUNC init_func;
|
|
HASH_FUNC hash_func;
|
|
FINAL_FUNC final_func;
|
|
DEINIT_FUNC deinit_func;
|
|
};
|
|
|
|
static __const mhash_hash_entry algorithms[] = {
|
|
#if defined(ENABLE_CRC32)
|
|
MHASH_ENTRY(MHASH_CRC32, 4, 0, sizeof(mutils_word32), mhash_clear_crc32,
|
|
mhash_crc32, NULL, mhash_get_crc32),
|
|
MHASH_ENTRY(MHASH_CRC32B, 4, 0, sizeof(mutils_word32), mhash_clear_crc32,
|
|
mhash_crc32b, NULL, mhash_get_crc32),
|
|
#endif
|
|
|
|
#if defined(ENABLE_ADLER32)
|
|
MHASH_ENTRY(MHASH_ADLER32, 4, 0, sizeof(mutils_word32), mhash_clear_adler32,
|
|
mhash_adler32, NULL, mhash_get_adler32),
|
|
#endif
|
|
|
|
#if defined(ENABLE_MD5)
|
|
MHASH_ENTRY(MHASH_MD5, 16, 64, sizeof(MD5_CTX), MD5Init,
|
|
MD5Update, NULL, MD5Final),
|
|
#endif
|
|
|
|
#if defined(ENABLE_MD4)
|
|
MHASH_ENTRY(MHASH_MD4, 16, 64, sizeof(MD4_CTX), MD4Init,
|
|
MD4Update, NULL, MD4Final),
|
|
#endif
|
|
|
|
#if defined(ENABLE_MD2)
|
|
MHASH_ENTRY(MHASH_MD2, 16, 16, sizeof(MD2_CTX), md2_init,
|
|
md2_update, NULL, md2_digest),
|
|
#endif
|
|
|
|
#if defined(ENABLE_SHA1)
|
|
MHASH_ENTRY(MHASH_SHA1, 20, 64, sizeof(SHA_CTX), sha_init,
|
|
sha_update, sha_final, sha_digest),
|
|
#endif
|
|
|
|
#if defined(ENABLE_SHA256_SHA224)
|
|
MHASH_ENTRY(MHASH_SHA256, 32, 64, sizeof( SHA256_SHA224_CTX), sha256_init,
|
|
sha256_sha224_update, sha256_sha224_final, sha256_digest),
|
|
MHASH_ENTRY(MHASH_SHA224, 28, 64, sizeof( SHA256_SHA224_CTX), sha224_init,
|
|
sha256_sha224_update, sha256_sha224_final, sha224_digest),
|
|
#endif
|
|
|
|
#if defined(ENABLE_SHA512_SHA384)
|
|
MHASH_ENTRY(MHASH_SHA512, 64, 128, sizeof( SHA512_SHA384_CTX), sha512_init,
|
|
sha512_sha384_update, sha512_sha384_final, sha512_digest),
|
|
MHASH_ENTRY(MHASH_SHA384, 48, 128, sizeof( SHA512_SHA384_CTX), sha384_init,
|
|
sha512_sha384_update, sha512_sha384_final, sha384_digest),
|
|
#endif
|
|
|
|
#if defined(ENABLE_HAVAL)
|
|
MHASH_ENTRY(MHASH_HAVAL256, 32, 128, sizeof(havalContext), havalInit256,
|
|
havalUpdate, NULL, havalFinal),
|
|
MHASH_ENTRY(MHASH_HAVAL128, 16, 128, sizeof(havalContext), havalInit128,
|
|
havalUpdate, NULL, havalFinal),
|
|
MHASH_ENTRY(MHASH_HAVAL160, 20, 128, sizeof(havalContext), havalInit160,
|
|
havalUpdate, NULL, havalFinal),
|
|
MHASH_ENTRY(MHASH_HAVAL192, 24, 128, sizeof(havalContext), havalInit192,
|
|
havalUpdate, NULL, havalFinal),
|
|
MHASH_ENTRY(MHASH_HAVAL224, 28, 128, sizeof(havalContext), havalInit224,
|
|
havalUpdate, NULL, havalFinal),
|
|
#endif
|
|
|
|
#if defined(ENABLE_RIPEMD)
|
|
MHASH_ENTRY(MHASH_RIPEMD128, 16, 64, sizeof(RIPEMD_CTX), ripemd128_init,
|
|
ripemd_update, ripemd_final, ripemd_digest),
|
|
MHASH_ENTRY(MHASH_RIPEMD160, 20, 64, sizeof(RIPEMD_CTX), ripemd160_init,
|
|
ripemd_update, ripemd_final, ripemd_digest),
|
|
MHASH_ENTRY(MHASH_RIPEMD256, 32, 64, sizeof(RIPEMD_CTX), ripemd256_init,
|
|
ripemd_update, ripemd_final, ripemd_digest),
|
|
MHASH_ENTRY(MHASH_RIPEMD320, 40, 64, sizeof(RIPEMD_CTX), ripemd320_init,
|
|
ripemd_update, ripemd_final, ripemd_digest),
|
|
#endif
|
|
|
|
#if defined(ENABLE_TIGER)
|
|
MHASH_ENTRY(MHASH_TIGER, 24, 64, sizeof(TIGER_CTX), tiger_init,
|
|
tiger_update, tiger_final, tiger_digest),
|
|
MHASH_ENTRY(MHASH_TIGER128, 16, 64, sizeof(TIGER_CTX), tiger_init,
|
|
tiger_update, tiger_final, tiger128_digest),
|
|
MHASH_ENTRY(MHASH_TIGER160, 20, 64, sizeof(TIGER_CTX), tiger_init,
|
|
tiger_update, tiger_final, tiger160_digest),
|
|
#endif
|
|
|
|
#if defined(ENABLE_GOST)
|
|
MHASH_ENTRY(MHASH_GOST, 32, 0, sizeof(GostHashCtx), gosthash_reset,
|
|
gosthash_update, NULL, gosthash_final),
|
|
#endif
|
|
|
|
#if defined(ENABLE_WHIRLPOOL)
|
|
MHASH_ENTRY(MHASH_WHIRLPOOL, 64, 64, sizeof(WHIRLPOOL_CTX), whirlpool_init,
|
|
whirlpool_update, whirlpool_final, whirlpool_digest),
|
|
#endif
|
|
|
|
#if defined(ENABLE_SNEFRU)
|
|
MHASH_ENTRY(MHASH_SNEFRU128, 16, 64, sizeof(SNEFRU_CTX), snefru_init,
|
|
snefru128_update, snefru128_final, snefru128_digest),
|
|
MHASH_ENTRY(MHASH_SNEFRU256, 32, 64, sizeof(SNEFRU_CTX), snefru_init,
|
|
snefru256_update, snefru256_final, snefru256_digest),
|
|
#endif
|
|
|
|
{0}
|
|
};
|
|
|
|
#define MHASH_LOOP(b) \
|
|
__const mhash_hash_entry *p; \
|
|
for (p = algorithms; p->name != NULL; p++) { b ; }
|
|
|
|
#define MHASH_ALG_LOOP(a) \
|
|
MHASH_LOOP( if (p->id == type) { a; break; } )
|
|
|
|
#ifndef MMAX
|
|
# define MMAX(x,y) (x>y?x:y)
|
|
#endif
|
|
|
|
WIN32DLL_DEFINE mutils_word32 mhash_count(void)
|
|
{
|
|
hashid count = 0;
|
|
|
|
MHASH_LOOP( count = MMAX( p->id, count) );
|
|
|
|
return count;
|
|
}
|
|
|
|
WIN32DLL_DEFINE mutils_word32 mhash_get_block_size(hashid type)
|
|
{
|
|
mutils_word32 ret = 0;
|
|
|
|
MHASH_ALG_LOOP(ret = p->blocksize);
|
|
return ret;
|
|
}
|
|
|
|
WIN32DLL_DEFINE mutils_word32 _mhash_get_state_size(hashid type)
|
|
{
|
|
/* Fixed: Valid state sizes that exceeded maximum
|
|
positive value for integer would be returned as
|
|
an error.
|
|
*/
|
|
|
|
mutils_word32 size = 0;
|
|
|
|
MHASH_ALG_LOOP(size = p->state_size);
|
|
return size;
|
|
}
|
|
|
|
WIN32DLL_DEFINE INIT_FUNC _mhash_get_init_func(hashid type)
|
|
{
|
|
INIT_FUNC func = NULL;
|
|
|
|
MHASH_ALG_LOOP(func = p->init_func);
|
|
return func;
|
|
}
|
|
WIN32DLL_DEFINE HASH_FUNC _mhash_get_hash_func(hashid type)
|
|
{
|
|
HASH_FUNC func = NULL;
|
|
|
|
MHASH_ALG_LOOP(func = p->hash_func);
|
|
return func;
|
|
}
|
|
WIN32DLL_DEFINE FINAL_FUNC _mhash_get_final_func(hashid type)
|
|
{
|
|
FINAL_FUNC func = NULL;
|
|
|
|
MHASH_ALG_LOOP(func = p->final_func);
|
|
return func;
|
|
}
|
|
WIN32DLL_DEFINE DEINIT_FUNC _mhash_get_deinit_func(hashid type)
|
|
{
|
|
DEINIT_FUNC func = NULL;
|
|
|
|
MHASH_ALG_LOOP(func = p->deinit_func);
|
|
return func;
|
|
}
|
|
|
|
|
|
WIN32DLL_DEFINE hashid mhash_get_mhash_algo( MHASH tmp) {
|
|
return tmp->algorithm_given;
|
|
}
|
|
|
|
WIN32DLL_DEFINE mutils_word8 *mhash_get_hash_name(hashid type)
|
|
{
|
|
mutils_word8 *ret = NULL;
|
|
|
|
/* avoid prefix */
|
|
MHASH_ALG_LOOP(ret = p->name);
|
|
|
|
if (ret != NULL)
|
|
{
|
|
ret += sizeof("MHASH_") - 1;
|
|
}
|
|
|
|
return mutils_strdup(ret);
|
|
}
|
|
|
|
WIN32DLL_DEFINE __const mutils_word8 *mhash_get_hash_name_static(hashid type)
|
|
{
|
|
mutils_word8 *ret = NULL;
|
|
|
|
/* avoid prefix */
|
|
MHASH_ALG_LOOP( ret = p->name);
|
|
|
|
if ( ret != NULL)
|
|
{
|
|
ret += sizeof("MHASH_") - 1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
MHASH mhash_cp(MHASH from) {
|
|
MHASH ret;
|
|
|
|
ret = (MHASH) mutils_malloc(sizeof(MHASH_INSTANCE));
|
|
|
|
if (ret == NULL)
|
|
{
|
|
return(MHASH_FAILED);
|
|
}
|
|
|
|
mutils_memcpy(ret, from, sizeof(MHASH_INSTANCE));
|
|
|
|
/* copy the internal state also */
|
|
ret->state = (mutils_word8 *) mutils_malloc(ret->state_size);
|
|
|
|
if (ret->state == NULL)
|
|
{
|
|
mutils_free(ret);
|
|
return(MHASH_FAILED);
|
|
}
|
|
|
|
mutils_memcpy(ret->state, from->state, ret->state_size);
|
|
|
|
/* copy the key in case of hmac*/
|
|
if (ret->hmac_key_size != 0)
|
|
{
|
|
ret->hmac_key = (mutils_word8 *) mutils_malloc(ret->hmac_key_size);
|
|
|
|
if (ret == NULL)
|
|
{
|
|
mutils_free(ret->state);
|
|
mutils_free(ret);
|
|
return(MHASH_FAILED);
|
|
}
|
|
|
|
mutils_memcpy(ret->hmac_key, from->hmac_key, ret->hmac_key_size);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
MHASH mhash_init_int(__const hashid type)
|
|
{
|
|
MHASH ret;
|
|
INIT_FUNC func;
|
|
|
|
ret = (MHASH) mutils_malloc(sizeof(MHASH_INSTANCE));
|
|
if (ret == NULL)
|
|
{
|
|
return MHASH_FAILED;
|
|
}
|
|
|
|
mutils_memset(ret, 0, sizeof(MHASH_INSTANCE));
|
|
|
|
ret->algorithm_given = type;
|
|
|
|
ret->state_size = _mhash_get_state_size(type);
|
|
if (ret->state_size == 0)
|
|
{
|
|
mutils_free(ret);
|
|
return(MHASH_FAILED);
|
|
}
|
|
|
|
if ( (ret->state = mutils_malloc(ret->state_size)) == NULL)
|
|
{
|
|
mutils_free(ret);
|
|
return(MHASH_FAILED);
|
|
}
|
|
|
|
func = _mhash_get_init_func( type);
|
|
|
|
if (func != NULL)
|
|
{
|
|
func(ret->state);
|
|
}
|
|
else
|
|
{
|
|
mutils_free(ret->state);
|
|
mutils_free(ret);
|
|
return(MHASH_FAILED);
|
|
}
|
|
|
|
ret->hash_func = _mhash_get_hash_func( type);
|
|
ret->deinit_func = _mhash_get_deinit_func( type);
|
|
ret->final_func = _mhash_get_final_func( type);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
/* plaintext should be a multiple of the algorithm's block size */
|
|
|
|
mutils_boolean mhash(MHASH td, __const void *plaintext, mutils_word32 size)
|
|
{
|
|
|
|
if (td->hash_func!=NULL)
|
|
{
|
|
td->hash_func( td->state, plaintext, size);
|
|
}
|
|
|
|
return(MUTILS_OK);
|
|
}
|
|
|
|
WIN32DLL_DEFINE
|
|
void mhash_deinit(MHASH td, void *result)
|
|
{
|
|
|
|
if (td->final_func != NULL)
|
|
{
|
|
td->final_func( td->state);
|
|
}
|
|
|
|
if (td->deinit_func != NULL)
|
|
{
|
|
td->deinit_func( td->state, result);
|
|
}
|
|
|
|
if (NULL != td->state)
|
|
{
|
|
mutils_free(td->state);
|
|
}
|
|
|
|
mutils_free(td);
|
|
|
|
return;
|
|
}
|
|
|
|
WIN32DLL_DEFINE
|
|
void *mhash_end_m(MHASH td, void *(*hash_malloc) (mutils_word32))
|
|
{
|
|
void *digest;
|
|
mutils_word32 size;
|
|
|
|
size = mhash_get_block_size( td->algorithm_given);
|
|
|
|
digest = mutils_malloc(size);
|
|
|
|
if (digest==NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
mhash_deinit( td, digest);
|
|
|
|
return(digest);
|
|
}
|
|
|
|
WIN32DLL_DEFINE void *mhash_end(MHASH td)
|
|
{
|
|
return(mhash_end_m(td, mutils_malloc));
|
|
}
|
|
|
|
|
|
WIN32DLL_DEFINE MHASH mhash_init(__const hashid type)
|
|
{
|
|
MHASH ret = MHASH_FAILED;
|
|
|
|
ret = mhash_init_int(type);
|
|
|
|
return(ret);
|
|
}
|
|
|
|
/* HMAC functions */
|
|
|
|
WIN32DLL_DEFINE mutils_word32 mhash_get_hash_pblock(hashid type)
|
|
{
|
|
mutils_word32 ret = 0;
|
|
|
|
MHASH_ALG_LOOP(ret = p->hash_pblock);
|
|
return(ret);
|
|
}
|
|
|
|
WIN32DLL_DEFINE
|
|
mutils_error mhash_hmac_deinit(MHASH td, void *result)
|
|
{
|
|
mutils_word8 *opad;
|
|
mutils_word8 _opad[MAX_BLOCK_SIZE];
|
|
MHASH tmptd;
|
|
mutils_word32 i;
|
|
mutils_word32 opad_alloc = 0;
|
|
|
|
if (td->hmac_block > MAX_BLOCK_SIZE)
|
|
{
|
|
opad = mutils_malloc(td->hmac_block);
|
|
if (opad == NULL)
|
|
{
|
|
return(-MUTILS_SYSTEM_RESOURCE_ERROR);
|
|
}
|
|
opad_alloc = 1;
|
|
}
|
|
else
|
|
{
|
|
opad = _opad;
|
|
}
|
|
|
|
|
|
for (i = 0; i < td->hmac_key_size; i++)
|
|
{
|
|
opad[i] = (0x5C) ^ td->hmac_key[i];
|
|
}
|
|
|
|
for (; i < td->hmac_block; i++)
|
|
{
|
|
opad[i] = (0x5C);
|
|
}
|
|
|
|
tmptd = mhash_init(td->algorithm_given);
|
|
mhash(tmptd, opad, td->hmac_block);
|
|
|
|
if (td->final_func != NULL)
|
|
{
|
|
td->final_func(td->state);
|
|
}
|
|
|
|
if (td->deinit_func != NULL)
|
|
{
|
|
td->deinit_func(td->state, result);
|
|
}
|
|
|
|
if (result != NULL)
|
|
{
|
|
mhash(tmptd, result,
|
|
mhash_get_block_size(td->algorithm_given));
|
|
}
|
|
|
|
mutils_free(td->state);
|
|
|
|
if (opad_alloc!=0)
|
|
{
|
|
mutils_free(opad);
|
|
}
|
|
|
|
mutils_bzero(td->hmac_key, td->hmac_key_size);
|
|
mutils_free(td->hmac_key);
|
|
mutils_free(td);
|
|
|
|
mhash_deinit(tmptd, result);
|
|
|
|
return(MUTILS_OK);
|
|
}
|
|
|
|
|
|
WIN32DLL_DEFINE
|
|
void *mhash_hmac_end_m(MHASH td, void *(*hash_malloc) (mutils_word32))
|
|
{
|
|
void *digest;
|
|
|
|
digest =
|
|
hash_malloc(mhash_get_block_size
|
|
(td->algorithm_given));
|
|
|
|
if (digest == NULL)
|
|
{
|
|
return(NULL);
|
|
}
|
|
|
|
mhash_hmac_deinit(td, digest);
|
|
|
|
return(digest);
|
|
}
|
|
|
|
WIN32DLL_DEFINE void *mhash_hmac_end(MHASH td)
|
|
{
|
|
return mhash_hmac_end_m(td, mutils_malloc);
|
|
}
|
|
|
|
WIN32DLL_DEFINE
|
|
MHASH mhash_hmac_init(__const hashid type,
|
|
void *key, mutils_word32 keysize,
|
|
mutils_word32 block)
|
|
{
|
|
MHASH ret = MHASH_FAILED;
|
|
MHASH tmptd;
|
|
mutils_word8 *ipad;
|
|
mutils_word8 _ipad[MAX_BLOCK_SIZE];
|
|
mutils_word32 i;
|
|
mutils_boolean ipad_alloc = MUTILS_FALSE;
|
|
mutils_boolean res;
|
|
|
|
if (block == 0)
|
|
{
|
|
block = 64; /* the default for ripemd,md5,sha-1 */
|
|
}
|
|
|
|
ret = mhash_init_int(type);
|
|
|
|
if (ret != MHASH_FAILED)
|
|
{
|
|
/* Initial hmac calculations */
|
|
ret->hmac_block = block;
|
|
|
|
if ( ret->hmac_block > MAX_BLOCK_SIZE)
|
|
{
|
|
ipad = mutils_malloc(ret->hmac_block);
|
|
if (ipad == NULL)
|
|
{
|
|
return MHASH_FAILED;
|
|
}
|
|
ipad_alloc = MUTILS_TRUE;
|
|
}
|
|
else
|
|
{
|
|
ipad = _ipad;
|
|
}
|
|
|
|
if (keysize > ret->hmac_block)
|
|
{
|
|
tmptd = mhash_init(type);
|
|
mhash(tmptd, key, keysize);
|
|
ret->hmac_key_size = mhash_get_block_size(type);
|
|
ret->hmac_key = mhash_end(tmptd);
|
|
}
|
|
else
|
|
{
|
|
ret->hmac_key = mutils_malloc(ret->hmac_block);
|
|
mutils_bzero(ret->hmac_key, ret->hmac_block);
|
|
mutils_memcpy(ret->hmac_key, key, keysize);
|
|
ret->hmac_key_size = ret->hmac_block;
|
|
}
|
|
|
|
/* IPAD */
|
|
|
|
for (i = 0; i < ret->hmac_key_size; i++)
|
|
{
|
|
ipad[i] = (0x36) ^ ret->hmac_key[i];
|
|
}
|
|
|
|
for (; i < ret->hmac_block; i++)
|
|
{
|
|
ipad[i] = (0x36);
|
|
}
|
|
|
|
res = mhash(ret, ipad, ret->hmac_block);
|
|
|
|
if (ipad_alloc == MUTILS_TRUE)
|
|
{
|
|
mutils_free(ipad);
|
|
}
|
|
}
|
|
|
|
return(ret);
|
|
}
|
|
|
|
WIN32DLL_DEFINE void mhash_free(void *ptr)
|
|
{
|
|
mutils_free(ptr);
|
|
}
|
|
|
|
|
|
/*
|
|
Saves the state of a hashing algorithm such that it can be
|
|
restored at some later point in time using
|
|
mhash_restore_state().
|
|
|
|
mem_size should contain the size of the given _mem pointer.
|
|
Otherwise the required size will be copied there.
|
|
|
|
Original version and idea by Blake Stephen <Stephen.Blake@veritect.com>
|
|
*/
|
|
WIN32DLL_DEFINE mutils_error mhash_save_state_mem(MHASH td, void *_mem, mutils_word32 *mem_size )
|
|
{
|
|
mutils_word32 tot_size;
|
|
mutils_word32 pos;
|
|
mutils_word8 *mem = _mem;
|
|
|
|
tot_size = sizeof(td->algorithm_given) + sizeof(td->hmac_key_size)
|
|
+ sizeof(td->hmac_block) + td->hmac_key_size +
|
|
+ sizeof(td->state_size) + td->state_size;
|
|
|
|
if ( *mem_size < tot_size)
|
|
{
|
|
*mem_size = tot_size;
|
|
return(MUTILS_INVALID_INPUT_BUFFER);
|
|
}
|
|
|
|
if ( mem != NULL)
|
|
{
|
|
pos = 0;
|
|
mutils_memcpy( mem, &td->algorithm_given, sizeof(td->algorithm_given));
|
|
pos = sizeof( td->algorithm_given);
|
|
|
|
mutils_memcpy( &mem[pos], &td->hmac_key_size, sizeof(td->hmac_key_size));
|
|
pos += sizeof(td->hmac_key_size);
|
|
|
|
mutils_memcpy( &mem[pos], &td->hmac_block, sizeof(td->hmac_block));
|
|
pos += sizeof(td->hmac_block);
|
|
|
|
mutils_memcpy( &mem[pos], td->hmac_key, td->hmac_key_size);
|
|
pos += td->hmac_key_size;
|
|
|
|
mutils_memcpy( &mem[pos], &td->state_size, sizeof(td->state_size));
|
|
pos += sizeof(td->state_size);
|
|
|
|
mutils_memcpy( &mem[pos], td->state, td->state_size);
|
|
pos += td->state_size;
|
|
|
|
}
|
|
return(MUTILS_OK);
|
|
}
|
|
|
|
|
|
/*
|
|
Restores the state of a hashing algorithm that was saved
|
|
using mhash_save_state(). Use like mhash_init.
|
|
*/
|
|
WIN32DLL_DEFINE MHASH mhash_restore_state_mem(void* _mem)
|
|
{
|
|
mutils_word8 *mem = _mem;
|
|
hashid algorithm_given;
|
|
MHASH ret = MHASH_FAILED;
|
|
mutils_word32 pos;
|
|
|
|
if (mem==NULL)
|
|
{
|
|
return(ret);
|
|
}
|
|
|
|
mutils_memcpy( &algorithm_given, mem, sizeof(algorithm_given));
|
|
|
|
if ((ret = mhash_init(algorithm_given)) == MHASH_FAILED)
|
|
{
|
|
return(ret);
|
|
}
|
|
|
|
ret->algorithm_given = algorithm_given;
|
|
|
|
pos = sizeof(algorithm_given);
|
|
|
|
mutils_memcpy( &ret->hmac_key_size, &mem[pos], sizeof(ret->hmac_key_size));
|
|
pos += sizeof( ret->hmac_key_size);
|
|
|
|
mutils_memcpy( &ret->hmac_block, &mem[pos], sizeof(ret->hmac_block));
|
|
pos += sizeof(ret->hmac_block);
|
|
|
|
if (ret->hmac_key_size != 0)
|
|
{
|
|
ret->hmac_key = mutils_malloc(ret->hmac_key_size);
|
|
if (ret->hmac_key == NULL)
|
|
{
|
|
goto freeall;
|
|
}
|
|
|
|
mutils_memcpy( ret->hmac_key, &mem[pos], ret->hmac_key_size);
|
|
pos += sizeof(ret->hmac_key_size);
|
|
}
|
|
|
|
mutils_memcpy( &ret->state_size, &mem[pos], sizeof(ret->state_size));
|
|
pos += sizeof( ret->state_size);
|
|
|
|
ret->state = mutils_malloc(ret->state_size);
|
|
if (ret->state==NULL)
|
|
goto freeall;
|
|
|
|
mutils_memcpy( ret->state, &mem[pos], ret->state_size);
|
|
pos += ret->state_size;
|
|
|
|
ret->hash_func = _mhash_get_hash_func( algorithm_given);
|
|
ret->deinit_func = _mhash_get_deinit_func( algorithm_given);
|
|
ret->final_func = _mhash_get_final_func( algorithm_given);
|
|
|
|
return(ret);
|
|
|
|
freeall:
|
|
/* This uses too much internals
|
|
*/
|
|
mutils_free(ret->state);
|
|
mutils_free(ret->hmac_key);
|
|
mutils_free(ret);
|
|
return(MHASH_FAILED);
|
|
}
|
|
|
|
#if defined(WIN32) || defined (__CYGWIN__)
|
|
WIN32DLL_DEFINE int main (void)
|
|
{
|
|
/* empty main function to avoid linker error (see cygwin FAQ) */
|
|
}
|
|
#endif
|