summaryrefslogtreecommitdiff
path: root/dll.cpp
blob: 63d5427553e142187a6554aff5192ba2a06c031d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// dll.cpp - written and placed in the public domain by Wei Dai

#define CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
#define CRYPTOPP_DEFAULT_NO_DLL

#include "dll.h"
#pragma warning(default: 4660)

#ifdef CRYPTOPP_WIN32_AVAILABLE
#include <windows.h>
#endif

#include "iterhash.cpp"
#include "strciphr.cpp"
#include "algebra.cpp"
#include "eprecomp.cpp"
#include "eccrypto.cpp"
#include "oaep.cpp"

#ifndef CRYPTOPP_IMPORTS

NAMESPACE_BEGIN(CryptoPP)

template<> const byte PKCS_DigestDecoration<SHA>::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14};
template<> const unsigned int PKCS_DigestDecoration<SHA>::length = sizeof(PKCS_DigestDecoration<SHA>::decoration);

static const byte s_moduleMac[CryptoPP::HMAC<CryptoPP::SHA1>::DIGESTSIZE] = "reserved for mac";
#ifdef CRYPTOPP_WIN32_AVAILABLE
static HMODULE s_hModule = NULL;
#endif

void DoDllPowerUpSelfTest()
{
#ifdef CRYPTOPP_WIN32_AVAILABLE
	char moduleFileName[MAX_PATH];
	GetModuleFileNameA(s_hModule, moduleFileName, sizeof(moduleFileName));
	CryptoPP::DoPowerUpSelfTest(moduleFileName, s_moduleMac);
#else
	throw NotImplemented("DoDllPowerUpSelfTest() only available on Windows");
#endif
}

NAMESPACE_END

#endif

#ifdef CRYPTOPP_EXPORTS

USING_NAMESPACE(CryptoPP)

#if !(defined(_MSC_VER) && (_MSC_VER < 1300))
using std::set_new_handler;
#endif

static PNew s_pNew = NULL;
static PDelete s_pDelete = NULL;

static void * _cdecl New (size_t size)
{
	new_handler newHandler = set_new_handler(NULL);
	if (newHandler)
		set_new_handler(newHandler);

	void *p;
	while (!(p = malloc(size)))
	{
		if (newHandler)
			newHandler();
		else
			throw std::bad_alloc();
	}

	return p;
}

static void SetNewAndDeleteFunctionPointers()
{
	void *p = NULL;
	HMODULE hModule = NULL;
	MEMORY_BASIC_INFORMATION mbi;

	while (true)
	{
		VirtualQuery(p, &mbi, sizeof(mbi));

		if (p >= (char *)mbi.BaseAddress + mbi.RegionSize)
			break;

		p = (char *)mbi.BaseAddress + mbi.RegionSize;

		if (!mbi.AllocationBase || mbi.AllocationBase == hModule)
			continue;

		hModule = HMODULE(mbi.AllocationBase);

		PGetNewAndDelete pGetNewAndDelete = (PGetNewAndDelete)GetProcAddress(hModule, "GetNewAndDeleteForCryptoPP");
		if (pGetNewAndDelete)
		{
			pGetNewAndDelete(s_pNew, s_pDelete);
			return;
		}

		PSetNewAndDelete pSetNewAndDelete = (PSetNewAndDelete)GetProcAddress(hModule, "SetNewAndDeleteFromCryptoPP");
		if (pSetNewAndDelete)
		{
			s_pNew = &New;
			s_pDelete = &free;
			pSetNewAndDelete(s_pNew, s_pDelete, &set_new_handler);
			return;
		}
	}

	hModule = GetModuleHandle("msvcrtd");
	if (!hModule)
		hModule = GetModuleHandle("msvcrt");
	if (hModule)
	{
		s_pNew = (PNew)GetProcAddress(hModule, "??2@YAPAXI@Z");		// operator new
		s_pDelete = (PDelete)GetProcAddress(hModule, "??3@YAXPAX@Z");	// operator delete
		return;
	}

	OutputDebugString("Crypto++ was not able to obtain new and delete function pointers.\n");
	throw 0;
}

void * _cdecl operator new (size_t size)
{
	if (!s_pNew)
		SetNewAndDeleteFunctionPointers();

	return s_pNew(size);
}

void _cdecl operator delete (void * p)
{
	s_pDelete(p);
}

BOOL APIENTRY DllMain(HANDLE hModule, 
                      DWORD  ul_reason_for_call, 
                      LPVOID lpReserved)
{
	if (ul_reason_for_call == DLL_PROCESS_ATTACH)
	{
		s_hModule = (HMODULE)hModule;
		DoDllPowerUpSelfTest();
	}
    return TRUE;
}

#endif	// #ifdef CRYPTOPP_EXPORTS