Crypt-RHash

 view release on metacpan or  search on metacpan

librhash/plug_openssl.c  view on Meta::CPAN

#else
	NO_HASH_INFO, NO_HASH_INFO, NO_HASH_INFO, NO_HASH_INFO, NO_HASH_INFO,
#endif
#ifndef OPENSSL_NO_RIPEMD
	{ &info_rmd160, sizeof(RIPEMD160_CTX), offsetof(RIPEMD160_CTX, A), HASH_INFO_METHODS(RIPEMD160) }, /* 160 bit */
#else
	NO_HASH_INFO,
#endif
#ifndef OPENSSL_NO_WHIRLPOOL
	{ &info_ossl_whirlpool, sizeof(WHIRLPOOL_CTX), offsetof(WHIRLPOOL_CTX, H.c), HASH_INFO_METHODS(WHIRLPOOL) }, /* 512 bit */
#else
	NO_HASH_INFO,
#endif
};

/* The rhash_updated_hash_info static array initialized by rhash_plug_openssl() replaces
 * rhash internal algorithms table. It is kept in an uninitialized-data segment
 * taking no space in the executable. */
rhash_hash_info rhash_updated_hash_info[RHASH_HASH_COUNT];

#ifdef OPENSSL_RUNTIME

#if (defined(_WIN32) || defined(__CYGWIN__)) /* __CYGWIN__ is also defined in MSYS */
# define GET_DLSYM(name) (void(*)(void))GetProcAddress(handle, name)
#else  /* _WIN32 */
# define GET_DLSYM(name) dlsym(handle, name)
#endif /* _WIN32 */
#define LOAD_ADDR(n, name) \
	p##name##_final = (os_fin_t)GET_DLSYM(#name "_Final"); \
	rhash_openssl_hash_info[n].update = (pupdate_t)GET_DLSYM(#name "_Update"); \
	rhash_openssl_hash_info[n].init = (rhash_openssl_hash_info[n].update && p##name##_final ? \
		(pinit_t)GET_DLSYM(#name "_Init") : 0);

/**
 * Load OpenSSL DLL at runtime, store pointers to functions of all
 * supported hash algorithms.
 *
 * @return 1 on success, 0 if the library not found
 */
static int load_openssl_runtime(void)
{
#if defined(_WIN32) || defined(__CYGWIN__)
	HMODULE handle = 0;
	size_t i;

# if defined(_WIN32)
	static const char* libNames[] = {
		"libeay32.dll",
	};
# elif defined(__MSYS__) /*  MSYS also defines __CYGWIN__ */
	static const char* libNames[] = {
		"msys-crypto-1.1.dll",
		"msys-crypto-1.0.0.dll",
	};
# elif defined(__CYGWIN__)
	static const char* libNames[] = {
		"cygcrypto-1.1.dll",
		"cygcrypto-1.0.0.dll",
	};
# endif
	/* suppress the error popup dialogs */
	UINT oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
	SetErrorMode(oldErrorMode | SEM_FAILCRITICALERRORS);

	for (i = 0; !handle && i < (sizeof(libNames) / sizeof(*libNames)); i++)
		handle = LoadLibraryA(libNames[i]);

	SetErrorMode(oldErrorMode); /* restore error mode */
#else
	static const char* libNames[] = {
		"libcrypto.so.3",
		"libcrypto.so.1.1",
		"libcrypto.so.1.0.2",
		"libcrypto.so.1.0.0",
		"libcrypto.so.0.9.8",
		"libcrypto.so",
	};
	void* handle = 0;
	size_t i;
	for (i = 0; !handle && i < (sizeof(libNames) / sizeof(*libNames)); i++)
		handle = dlopen(libNames[i], RTLD_NOW);
#endif /* defined(_WIN32) || defined(__CYGWIN__) */

	if (!handle)
		return 0; /* could not load OpenSSL */

#ifndef OPENSSL_NO_MD4
	LOAD_ADDR(0, MD4)
#endif
#ifndef OPENSSL_NO_MD5
	LOAD_ADDR(1, MD5);
#endif
#ifndef OPENSSL_NO_SHA
	LOAD_ADDR(2, SHA1);
	LOAD_ADDR(3, SHA224);
	LOAD_ADDR(4, SHA256);
	LOAD_ADDR(5, SHA384);
	LOAD_ADDR(6, SHA512);
#endif
#ifndef OPENSSL_NO_RIPEMD
	LOAD_ADDR(7, RIPEMD160);
#endif
#ifndef OPENSSL_NO_WHIRLPOOL
	LOAD_ADDR(8, WHIRLPOOL);
#endif
	return 1;
}
#endif /* OPENSSL_RUNTIME */

/**
 * Replace several RHash internal algorithms with the OpenSSL ones.
 * It can replace MD4/MD5, SHA1/SHA2, RIPEMD, WHIRLPOOL.
 *
 * @return 1 on success, 0 if OpenSSL library not found
 */
int rhash_plug_openssl(void)
{
	size_t i;
	unsigned bit_index;

	assert(rhash_info_size <= RHASH_HASH_COUNT); /* buffer-overflow protection */



( run in 0.979 second using v1.01-cache-2.11-cpan-364913b4093 )