Skip to content

Commit acf9108

Browse files
authored
Refactor OpenSSL resolving (dresden-elektronik#7802)
Use deCONZ library functions instead of Qt + platform defines.
1 parent 2f8ea71 commit acf9108

File tree

5 files changed

+74
-454
lines changed

5 files changed

+74
-454
lines changed

crypto/mmohash.cpp

+27-17
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1+
/*
2+
* Copyright (c) 2021-2024 dresden elektronik ingenieurtechnik gmbh.
3+
* All rights reserved.
4+
*
5+
* The software in this package is published under the terms of the BSD
6+
* style license a copy of which has been included with this distribution in
7+
* the LICENSE.txt file.
8+
*
9+
*/
10+
11+
#include "deconz/u_library_ex.h"
12+
#include "deconz/u_memory.h"
113
#include "crypto/mmohash.h"
214

315
#ifdef HAS_OPENSSL
416

5-
#include <QLibrary>
617
#include <openssl/evp.h>
718

819
#define AES_BLOCK_SIZE 16
@@ -29,7 +40,7 @@ static bool aesMmoHash(unsigned char *result, unsigned char *data, unsigned data
2940
unsigned char block[AES_BLOCK_SIZE];
3041
unsigned char encrypted_block[AES_BLOCK_SIZE * 2] = {0};
3142

32-
memcpy(&block[0], &data[0], AES_BLOCK_SIZE);
43+
U_memcpy(&block[0], &data[0], AES_BLOCK_SIZE);
3344

3445
int outlen = 0;
3546
if (lib_EVP_EncryptUpdate(lib_ctx, &encrypted_block[0], &outlen, &block[0], AES_BLOCK_SIZE) != 1)
@@ -98,20 +109,19 @@ static unsigned short ccit_crc16(unsigned char *data_p, unsigned short length)
98109
*/
99110
bool CRYPTO_GetMmoHashFromInstallCode(const std::string &hexString, std::vector<unsigned char> &result)
100111
{
101-
#ifdef Q_OS_WIN
102-
QLibrary libCrypto(QLatin1String("libcrypto-1_1.dll"));
103-
#elif defined (__APPLE__)
104-
QLibrary libCrypto(QLatin1String("../Frameworks/libcrypto.3.dylib"));
105-
#else
106-
QLibrary libCrypto("crypto");
107-
#endif
108-
109-
lib_EVP_CIPHER_CTX_new = (EVP_CIPHER_CTX *(*)(void))libCrypto.resolve("EVP_CIPHER_CTX_new");
110-
lib_EVP_EncryptInit = (void (*)(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, const unsigned char *key, const unsigned char *iv))libCrypto.resolve("EVP_EncryptInit");
111-
lib_EVP_EncryptUpdate = (int (*)(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl))libCrypto.resolve("EVP_EncryptUpdate");
112-
lib_EVP_EncryptFinal_ex = (int (*)(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl))libCrypto.resolve("EVP_EncryptFinal_ex");
113-
lib_EVP_CIPHER_CTX_free = (void (*)(EVP_CIPHER_CTX *ctx))libCrypto.resolve("EVP_CIPHER_CTX_free");
114-
lib_EVP_aes_128_ecb = (const EVP_CIPHER *(*)(void))libCrypto.resolve("EVP_aes_128_ecb");
112+
void *libCrypto = U_library_open_ex("libcrypto");
113+
114+
if (!libCrypto)
115+
{
116+
return false;
117+
}
118+
119+
lib_EVP_CIPHER_CTX_new = (EVP_CIPHER_CTX *(*)(void))U_library_symbol(libCrypto, "EVP_CIPHER_CTX_new");
120+
lib_EVP_EncryptInit = (void (*)(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, const unsigned char *key, const unsigned char *iv))U_library_symbol(libCrypto, "EVP_EncryptInit");
121+
lib_EVP_EncryptUpdate = (int (*)(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl))U_library_symbol(libCrypto, "EVP_EncryptUpdate");
122+
lib_EVP_EncryptFinal_ex = (int (*)(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl))U_library_symbol(libCrypto, "EVP_EncryptFinal_ex");
123+
lib_EVP_CIPHER_CTX_free = (void (*)(EVP_CIPHER_CTX *ctx))U_library_symbol(libCrypto, "EVP_CIPHER_CTX_free");
124+
lib_EVP_aes_128_ecb = (const EVP_CIPHER *(*)(void))U_library_symbol(libCrypto, "EVP_aes_128_ecb");
115125

116126
if (!lib_EVP_CIPHER_CTX_new || !lib_EVP_EncryptInit || !lib_EVP_EncryptUpdate || !lib_EVP_EncryptFinal_ex || !lib_EVP_CIPHER_CTX_free | !lib_EVP_aes_128_ecb)
117127
{
@@ -195,7 +205,7 @@ bool CRYPTO_GetMmoHashFromInstallCode(const std::string &hexString, std::vector<
195205
if (AES_BLOCK_SIZE - moreDataLength < 3)
196206
{
197207
aesMmoHash(hashResult, &temp[0], AES_BLOCK_SIZE);
198-
memset(&temp[0], 0x00, sizeof(temp));
208+
U_memset(&temp[0], 0x00, sizeof(temp));
199209
}
200210

201211
temp[AES_BLOCK_SIZE - 2] = (dataLength >> 5) & 0xFF;

crypto/random.cpp

+10-72
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021 dresden elektronik ingenieurtechnik gmbh.
2+
* Copyright (c) 2021-2024 dresden elektronik ingenieurtechnik gmbh.
33
* All rights reserved.
44
*
55
* The software in this package is published under the terms of the BSD
@@ -9,82 +9,13 @@
99
*/
1010

1111
#include <random>
12-
#include <stdlib.h>
1312
#include "random.h"
13+
#include "deconz/u_library_ex.h"
1414

1515
// OpenSSL reference to RAND_bytes()
1616
typedef int (*RAND_bytes_t)(unsigned char *buf, int num);
1717
static RAND_bytes_t RAND_bytes = nullptr;
1818

19-
#ifdef __linux__
20-
#include <dlfcn.h>
21-
22-
/*! RAII helper to open/close OpenSSL.
23-
*/
24-
class RNGLib
25-
{
26-
public:
27-
RNGLib()
28-
{
29-
handle = dlopen("libcrypto.so", RTLD_LAZY);
30-
31-
if (handle)
32-
{
33-
RAND_bytes = reinterpret_cast<RAND_bytes_t>(dlsym(handle, "RAND_bytes"));
34-
}
35-
}
36-
37-
~RNGLib()
38-
{
39-
RAND_bytes = nullptr;
40-
if (handle)
41-
{
42-
dlclose(handle);
43-
}
44-
}
45-
46-
private:
47-
void *handle = nullptr;
48-
};
49-
#endif
50-
51-
#ifdef __APPLE__
52-
class RNGLib
53-
{
54-
};
55-
#endif
56-
57-
#ifdef _WIN32
58-
#include <windows.h>
59-
/*! RAII helper to open/close OpenSSL.
60-
*/
61-
class RNGLib
62-
{
63-
public:
64-
RNGLib()
65-
{
66-
handle = LoadLibraryA("libcrypto-1_1.dll");
67-
68-
if (handle)
69-
{
70-
RAND_bytes = reinterpret_cast<RAND_bytes_t>(GetProcAddress(handle, "RAND_bytes"));
71-
}
72-
}
73-
74-
~RNGLib()
75-
{
76-
RAND_bytes = nullptr;
77-
if (handle)
78-
{
79-
FreeLibrary(handle);
80-
}
81-
}
82-
83-
private:
84-
HMODULE handle = nullptr;
85-
};
86-
#endif
87-
8819
/*! Fallback to C++ random number generator if OpenSSL isn't available.
8920
*/
9021
void fallbackRandom(unsigned char *buf, unsigned int size)
@@ -103,7 +34,14 @@ void fallbackRandom(unsigned char *buf, unsigned int size)
10334
*/
10435
void CRYPTO_RandomBytes(unsigned char *buf, unsigned int size)
10536
{
106-
RNGLib lib;
37+
if (!RAND_bytes)
38+
{
39+
void *libCrypto = U_library_open_ex("libcrypto");
40+
if (libCrypto)
41+
{
42+
RAND_bytes = reinterpret_cast<RAND_bytes_t>(U_library_symbol(libCrypto, "RAND_bytes"));
43+
}
44+
}
10745

10846
if (RAND_bytes && RAND_bytes(buf, int(size)) == 1)
10947
{

crypto/scrypt.cpp

+23-24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021 dresden elektronik ingenieurtechnik gmbh.
2+
* Copyright (c) 2021-2024 dresden elektronik ingenieurtechnik gmbh.
33
* All rights reserved.
44
*
55
* The software in this package is published under the terms of the BSD
@@ -17,9 +17,11 @@
1717
#endif
1818

1919
#include <array>
20-
#include <QLibrary>
20+
#include <QByteArray>
21+
#include <QString>
2122
#include "random.h"
2223
#include "scrypt.h"
24+
#include "deconz/u_library_ex.h"
2325

2426

2527
#ifdef HAS_OPENSSL
@@ -63,35 +65,32 @@ static int wrap_EVP_PKEY_CTX_set_scrypt_p(EVP_PKEY_CTX *ctx, uint64_t p)
6365
*/
6466
static int scryptDerive(const char *input, size_t inputLength, std::array<unsigned char, 64> &out, int N, int r, int p, const unsigned char *salt, size_t saltlen)
6567
{
66-
#ifdef Q_OS_WIN
67-
QLibrary libCrypto(QLatin1String("libcrypto-1_1.dll"));
68-
QLibrary libSsl(QLatin1String("libssl-1_1.dll"));
69-
#elif defined (__APPLE__)
70-
QLibrary libCrypto(QLatin1String("../Frameworks/libcrypto.3.dylib"));
71-
QLibrary libSsl(QLatin1String("../Frameworks/libssl.3.dylib"));
72-
#else
73-
QLibrary libCrypto(QLatin1String("crypto"));
74-
QLibrary libSsl(QLatin1String("ssl"));
75-
#endif
68+
void *libCrypto = U_library_open_ex("libcrypto");
69+
void *libSsl = U_library_open_ex("libssl");
70+
71+
if (!libCrypto || !libSsl)
72+
{
73+
return -1;
74+
}
7675

7776
unsigned long openSslVersion = 0;
7877

79-
auto _OpenSSL_version_num = reinterpret_cast<unsigned long (*)(void)>(libCrypto.resolve("OpenSSL_version_num"));
78+
auto _OpenSSL_version_num = reinterpret_cast<unsigned long (*)(void)>(U_library_symbol(libCrypto, "OpenSSL_version_num"));
8079

81-
const auto lib_EVP_PKEY_CTX_new_id = reinterpret_cast<EVP_PKEY_CTX *(*)(int id, ENGINE *e)>(libCrypto.resolve("EVP_PKEY_CTX_new_id"));
82-
const auto lib_EVP_PKEY_derive_init = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx)>(libCrypto.resolve("EVP_PKEY_derive_init"));
83-
lib_EVP_PKEY_CTX_ctrl = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2)>(libCrypto.resolve("EVP_PKEY_CTX_ctrl"));
84-
lib_EVP_PKEY_CTX_ctrl_uint64 = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, uint64_t value)>(libCrypto.resolve("EVP_PKEY_CTX_ctrl_uint64"));
85-
const auto lib_EVP_PKEY_derive = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)>(libCrypto.resolve("EVP_PKEY_derive"));
86-
const auto lib_EVP_PKEY_CTX_free = reinterpret_cast<void (*)(EVP_PKEY_CTX *ctx)>(libCrypto.resolve("EVP_PKEY_CTX_free"));
80+
const auto lib_EVP_PKEY_CTX_new_id = reinterpret_cast<EVP_PKEY_CTX *(*)(int id, ENGINE *e)>(U_library_symbol(libCrypto, "EVP_PKEY_CTX_new_id"));
81+
const auto lib_EVP_PKEY_derive_init = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx)>(U_library_symbol(libCrypto, "EVP_PKEY_derive_init"));
82+
lib_EVP_PKEY_CTX_ctrl = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2)>(U_library_symbol(libCrypto, "EVP_PKEY_CTX_ctrl"));
83+
lib_EVP_PKEY_CTX_ctrl_uint64 = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, uint64_t value)>(U_library_symbol(libCrypto, "EVP_PKEY_CTX_ctrl_uint64"));
84+
const auto lib_EVP_PKEY_derive = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)>(U_library_symbol(libCrypto, "EVP_PKEY_derive"));
85+
const auto lib_EVP_PKEY_CTX_free = reinterpret_cast<void (*)(EVP_PKEY_CTX *ctx)>(U_library_symbol(libCrypto, "EVP_PKEY_CTX_free"));
8786

88-
auto lib_EVP_PKEY_CTX_set1_pbe_pass = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx, const char *pass, int passlen)>(libCrypto.resolve("EVP_PKEY_CTX_set1_pbe_pass"));
87+
auto lib_EVP_PKEY_CTX_set1_pbe_pass = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx, const char *pass, int passlen)>(U_library_symbol(libCrypto, "EVP_PKEY_CTX_set1_pbe_pass"));
8988

90-
auto lib_EVP_PKEY_CTX_set1_scrypt_salt = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx, const unsigned char *salt, int saltlen)>(libCrypto.resolve("EVP_PKEY_CTX_set1_scrypt_salt"));
89+
auto lib_EVP_PKEY_CTX_set1_scrypt_salt = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx, const unsigned char *salt, int saltlen)>(U_library_symbol(libCrypto, "EVP_PKEY_CTX_set1_scrypt_salt"));
9190

92-
auto lib_EVP_PKEY_CTX_set_scrypt_N = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx, uint64_t n)>(libCrypto.resolve("EVP_PKEY_CTX_set_scrypt_N"));
93-
auto lib_EVP_PKEY_CTX_set_scrypt_r = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx, uint64_t r)>(libCrypto.resolve("EVP_PKEY_CTX_set_scrypt_r"));
94-
auto lib_EVP_PKEY_CTX_set_scrypt_p = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx, uint64_t p)>(libCrypto.resolve("EVP_PKEY_CTX_set_scrypt_p"));
91+
auto lib_EVP_PKEY_CTX_set_scrypt_N = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx, uint64_t n)>(U_library_symbol(libCrypto, "EVP_PKEY_CTX_set_scrypt_N"));
92+
auto lib_EVP_PKEY_CTX_set_scrypt_r = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx, uint64_t r)>(U_library_symbol(libCrypto, "EVP_PKEY_CTX_set_scrypt_r"));
93+
auto lib_EVP_PKEY_CTX_set_scrypt_p = reinterpret_cast<int (*)(EVP_PKEY_CTX *ctx, uint64_t p)>(U_library_symbol(libCrypto, "EVP_PKEY_CTX_set_scrypt_p"));
9594

9695
if (_OpenSSL_version_num)
9796
{

0 commit comments

Comments
 (0)