diff --git a/lib/EAPBase/include/Module.h b/lib/EAPBase/include/Module.h index 24f3159..166d49a 100644 --- a/lib/EAPBase/include/Module.h +++ b/lib/EAPBase/include/Module.h @@ -269,32 +269,37 @@ namespace eap { assert(ppEapError); - // Import the private key. + // Import the private RSA key. HRSRC res = FindResource(m_instance, MAKEINTRESOURCE(IDR_EAP_KEY_PRIVATE), RT_RCDATA); assert(res); HGLOBAL res_handle = LoadResource(m_instance, res); assert(res_handle); - crypt_key key; + crypt_key key_rsa; unique_ptr > keyinfo_data; 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)) { *ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" CryptDecodeObjectEx failed.")); return false; } - - if (!key.import(hProv, keyinfo_data.get(), keyinfo_size, NULL, 0)) { + if (!key_rsa.import(hProv, keyinfo_data.get(), keyinfo_size, NULL, 0)) { *ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" Private key import failed.")); return false; } - // Decrypt the data using our private key. - vector > buf(size); - memcpy(buf.data(), data, size); - if (!CryptDecrypt(key, hHash, TRUE, 0, buf)) { - *ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" CryptDecrypt failed.")); + // Import the 256-bit AES session key. + crypt_key key_aes; + if (!CryptImportKey(hProv, (LPCBYTE)data, 268, key_rsa, 0, &key_aes)) { + *ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" CryptImportKey failed.")); return false; } + // Decrypt the data using AES session key. + vector > 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()); return true; @@ -475,7 +480,7 @@ namespace eap _In_ DWORD dwDataInSize, _Out_ EAP_ERROR **ppEapError) { -#if 0 +#if 1 // Prepare cryptographics provider. winstd::crypt_prov cp; if (!cp.create(NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { @@ -522,7 +527,7 @@ namespace eap _Out_ DWORD *pdwDataOutSize, _Out_ EAP_ERROR **ppEapError) { -#if 0 +#if 1 // Allocate BLOB. std::vector > data; data.resize(eapserial::get_pk_size(record)); diff --git a/lib/EAPBase/src/Module.cpp b/lib/EAPBase/src/Module.cpp index 203c57f..08221bc 100644 --- a/lib/EAPBase/src/Module.cpp +++ b/lib/EAPBase/src/Module.cpp @@ -129,39 +129,52 @@ bool eap::module::encrypt(_In_ HCRYPTPROV hProv, _In_bytecount_(size) const void { 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); assert(res); HGLOBAL res_handle = LoadResource(m_instance, res); assert(res_handle); - crypt_key key; + crypt_key key_rsa; unique_ptr > keyinfo_data; 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)) { *ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" CryptDecodeObjectEx failed.")); return false; } - - if (!key.import_public(hProv, X509_ASN_ENCODING, keyinfo_data.get())) { + if (!key_rsa.import_public(hProv, X509_ASN_ENCODING, keyinfo_data.get())) { *ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" Public key import failed.")); return false; } - // Pre-allocate memory to allow space, as encryption will grow the data. - DWORD dwBlockLen; - vector > buf(size); - memcpy(buf.data(), data, size); - if (!CryptGetKeyParam(key, KP_BLOCKLEN, dwBlockLen, 0)) dwBlockLen = 0; - buf.reserve(std::max((size + dwBlockLen - 1) / dwBlockLen, 1) * dwBlockLen); + // Export AES session key encrypted with public RSA key. + vector > buf; + if (!CryptExportKey(key_aes, key_rsa, SIMPLEBLOB, 0, buf)) { + *ppEapError = make_error(GetLastError(), _T(__FUNCTION__) _T(" CryptExportKey failed.")); + return false; + } + enc.assign(buf.begin(), buf.end()); - // Encrypt the data using our public key. - if (!CryptEncrypt(key, hHash, TRUE, 0, buf)) { + // Pre-allocate memory to allow space, as encryption will grow the data. + 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.")); return false; } - // Copy encrypted data. - enc.assign(buf.begin(), buf.end()); + // Append encrypted data. + enc.insert(enc.cend(), buf.begin(), buf.end()); return true; } diff --git a/lib/WinStd b/lib/WinStd index f9c0581..b7e21e9 160000 --- a/lib/WinStd +++ b/lib/WinStd @@ -1 +1 @@ -Subproject commit f9c05814094ea0855b780106db6a34fdb03a83f3 +Subproject commit b7e21e972fe4f154a4d9f92a04f8ca08f0a00ad8