RSA encryption replaced with RSA session key exchange and AES data encryption; BLOBs are encrypted again

This commit is contained in:
Simon Rozman 2016-06-23 00:47:38 +02:00
parent 922d0ac3d0
commit d15b7066cd
3 changed files with 44 additions and 26 deletions

View File

@ -269,32 +269,37 @@ namespace eap
{ {
assert(ppEapError); assert(ppEapError);
// Import the private key. // Import the private RSA key.
HRSRC res = FindResource(m_instance, MAKEINTRESOURCE(IDR_EAP_KEY_PRIVATE), RT_RCDATA); HRSRC res = FindResource(m_instance, MAKEINTRESOURCE(IDR_EAP_KEY_PRIVATE), RT_RCDATA);
assert(res); assert(res);
HGLOBAL res_handle = LoadResource(m_instance, res); HGLOBAL res_handle = LoadResource(m_instance, res);
assert(res_handle); assert(res_handle);
crypt_key key; crypt_key key_rsa;
unique_ptr<unsigned char[], LocalFree_delete<unsigned char[]> > keyinfo_data; unique_ptr<unsigned char[], LocalFree_delete<unsigned char[]> > keyinfo_data;
DWORD keyinfo_size = 0; DWORD keyinfo_size = 0;
if (!CryptDecodeObjectEx(X509_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, (const BYTE*)::LockResource(res_handle), ::SizeofResource(m_instance, res), CRYPT_DECODE_ALLOC_FLAG, NULL, &keyinfo_data, &keyinfo_size)) { if (!CryptDecodeObjectEx(X509_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, (const BYTE*)::LockResource(res_handle), ::SizeofResource(m_instance, res), CRYPT_DECODE_ALLOC_FLAG, NULL, &keyinfo_data, &keyinfo_size)) {
*ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" CryptDecodeObjectEx failed.")); *ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" CryptDecodeObjectEx failed."));
return false; return false;
} }
if (!key_rsa.import(hProv, keyinfo_data.get(), keyinfo_size, NULL, 0)) {
if (!key.import(hProv, keyinfo_data.get(), keyinfo_size, NULL, 0)) {
*ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" Private key import failed.")); *ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" Private key import failed."));
return false; return false;
} }
// Decrypt the data using our private key. // Import the 256-bit AES session key.
vector<unsigned char, sanitizing_allocator<unsigned char> > buf(size); crypt_key key_aes;
memcpy(buf.data(), data, size); if (!CryptImportKey(hProv, (LPCBYTE)data, 268, key_rsa, 0, &key_aes)) {
if (!CryptDecrypt(key, hHash, TRUE, 0, buf)) { *ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" CryptImportKey failed."));
*ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" CryptDecrypt failed."));
return false; return false;
} }
// Decrypt the data using AES session key.
vector<unsigned char, sanitizing_allocator<unsigned char> > buf;
buf.assign((const unsigned char*)data + 268, (const unsigned char*)data + size);
if (!CryptDecrypt(key_aes, hHash, TRUE, 0, buf)) {
*ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" CryptDecrypt failed."));
return false;
}
dec.assign(buf.begin(), buf.end()); dec.assign(buf.begin(), buf.end());
return true; return true;
@ -475,7 +480,7 @@ namespace eap
_In_ DWORD dwDataInSize, _In_ DWORD dwDataInSize,
_Out_ EAP_ERROR **ppEapError) _Out_ EAP_ERROR **ppEapError)
{ {
#if 0 #if 1
// Prepare cryptographics provider. // Prepare cryptographics provider.
winstd::crypt_prov cp; winstd::crypt_prov cp;
if (!cp.create(NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { if (!cp.create(NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
@ -522,7 +527,7 @@ namespace eap
_Out_ DWORD *pdwDataOutSize, _Out_ DWORD *pdwDataOutSize,
_Out_ EAP_ERROR **ppEapError) _Out_ EAP_ERROR **ppEapError)
{ {
#if 0 #if 1
// Allocate BLOB. // Allocate BLOB.
std::vector<unsigned char, winstd::sanitizing_allocator<unsigned char> > data; std::vector<unsigned char, winstd::sanitizing_allocator<unsigned char> > data;
data.resize(eapserial::get_pk_size(record)); data.resize(eapserial::get_pk_size(record));

View File

@ -129,39 +129,52 @@ bool eap::module::encrypt(_In_ HCRYPTPROV hProv, _In_bytecount_(size) const void
{ {
assert(ppEapError); assert(ppEapError);
// Import the public key. // Generate 256-bit AES session key.
crypt_key key_aes;
if (!CryptGenKey(hProv, CALG_AES_256, MAKELONG(CRYPT_EXPORTABLE, 256), &key_aes)) {
*ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" CryptGenKey failed."));
return false;
}
// Import the public RSA key.
HRSRC res = FindResource(m_instance, MAKEINTRESOURCE(IDR_EAP_KEY_PUBLIC), RT_RCDATA); HRSRC res = FindResource(m_instance, MAKEINTRESOURCE(IDR_EAP_KEY_PUBLIC), RT_RCDATA);
assert(res); assert(res);
HGLOBAL res_handle = LoadResource(m_instance, res); HGLOBAL res_handle = LoadResource(m_instance, res);
assert(res_handle); assert(res_handle);
crypt_key key; crypt_key key_rsa;
unique_ptr<CERT_PUBLIC_KEY_INFO, LocalFree_delete<CERT_PUBLIC_KEY_INFO> > keyinfo_data; unique_ptr<CERT_PUBLIC_KEY_INFO, LocalFree_delete<CERT_PUBLIC_KEY_INFO> > keyinfo_data;
DWORD keyinfo_size = 0; DWORD keyinfo_size = 0;
if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, (const BYTE*)::LockResource(res_handle), ::SizeofResource(m_instance, res), CRYPT_DECODE_ALLOC_FLAG, NULL, &keyinfo_data, &keyinfo_size)) { if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, (const BYTE*)::LockResource(res_handle), ::SizeofResource(m_instance, res), CRYPT_DECODE_ALLOC_FLAG, NULL, &keyinfo_data, &keyinfo_size)) {
*ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" CryptDecodeObjectEx failed.")); *ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" CryptDecodeObjectEx failed."));
return false; return false;
} }
if (!key_rsa.import_public(hProv, X509_ASN_ENCODING, keyinfo_data.get())) {
if (!key.import_public(hProv, X509_ASN_ENCODING, keyinfo_data.get())) {
*ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" Public key import failed.")); *ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" Public key import failed."));
return false; return false;
} }
// Pre-allocate memory to allow space, as encryption will grow the data. // Export AES session key encrypted with public RSA key.
DWORD dwBlockLen; vector<unsigned char, sanitizing_allocator<unsigned char> > buf;
vector<unsigned char, sanitizing_allocator<unsigned char> > buf(size); if (!CryptExportKey(key_aes, key_rsa, SIMPLEBLOB, 0, buf)) {
memcpy(buf.data(), data, size); *ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" CryptExportKey failed."));
if (!CryptGetKeyParam(key, KP_BLOCKLEN, dwBlockLen, 0)) dwBlockLen = 0; return false;
buf.reserve(std::max<size_t>((size + dwBlockLen - 1) / dwBlockLen, 1) * dwBlockLen); }
enc.assign(buf.begin(), buf.end());
// Encrypt the data using our public key. // Pre-allocate memory to allow space, as encryption will grow the data.
if (!CryptEncrypt(key, hHash, TRUE, 0, buf)) { buf.assign((const unsigned char*)data, (const unsigned char*)data + size);
DWORD dwBlockLen;
if (!CryptGetKeyParam(key_aes, KP_BLOCKLEN, dwBlockLen, 0)) dwBlockLen = 0;
buf.reserve((size + dwBlockLen) / dwBlockLen * dwBlockLen);
// Encrypt the data using AES key.
if (!CryptEncrypt(key_aes, hHash, TRUE, 0, buf)) {
*ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" CryptEncrypt failed.")); *ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" CryptEncrypt failed."));
return false; return false;
} }
// Copy encrypted data. // Append encrypted data.
enc.assign(buf.begin(), buf.end()); enc.insert(enc.cend(), buf.begin(), buf.end());
return true; return true;
} }

@ -1 +1 @@
Subproject commit f9c05814094ea0855b780106db6a34fdb03a83f3 Subproject commit b7e21e972fe4f154a4d9f92a04f8ca08f0a00ad8