#include "aes_crypt.h" #include #include #include #include namespace LtsLicence { struct AesCryptPrivate { AesCryptPrivate() : passPhrase(QLatin1String("LTS " LTS_VERSION_MAJOR "." LTS_VERSION_MINOR)) , logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("LtsLicenceLib.AesCrypt")) { qsrand(time(nullptr)); #if OPENSSL_VERSION_NUMBER < 0x1010000fL ERR_load_crypto_strings(); #endif } ~AesCryptPrivate() { #if OPENSSL_VERSION_NUMBER < 0x1010000fL ERR_free_strings(); #endif } QString passPhrase; NGL::INGLLogger &logger; }; Q_GLOBAL_STATIC(AesCryptPrivate, s_Private) void setPassPhrase(const QString &passPhrase) { s_Private->passPhrase = passPhrase; } QString passPhrase() { return s_Private->passPhrase; } QByteArray decryptData(const QByteArray &dataToDecrypt, const QString &pw, bool *bOk) { if (bOk) *bOk = false; int ret; int outSize1 = 0; int outSize2 = 0; unsigned char key[32]; const QByteArray baPassword = pw.toUtf8(); const unsigned char *dataPw = reinterpret_cast(baPassword.data()); int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), nullptr, dataPw, baPassword.size(), 5, key, nullptr); if (i != 32) { ERROR_LOG(s_Private->logger) << "Wrong key size - should be 256 bits" ; return QByteArray(); } const QByteArray baSalt = dataToDecrypt.left(EVP_MAX_IV_LENGTH); const unsigned char *salt = reinterpret_cast(baSalt.data()); const QByteArray bufEncrypted = dataToDecrypt.mid(EVP_MAX_IV_LENGTH); EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); ret = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, key, salt); if (ret == 0) { EVP_CIPHER_CTX_free(ctx); char errbuf[256]; ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); ERROR_LOG(s_Private->logger) << "EVP_DecryptInit_ex failed" ; return QByteArray(); } QByteArray bufDecrypted; bufDecrypted.resize(bufEncrypted.size() + EVP_CIPHER_CTX_block_size(ctx)); const unsigned char *dataIn = reinterpret_cast(bufEncrypted.data()); unsigned char *dataOut = reinterpret_cast(bufDecrypted.data()); ret = EVP_DecryptUpdate(ctx, dataOut, &outSize1, dataIn, bufEncrypted.size()); if (ret == 0) { EVP_CIPHER_CTX_free(ctx); char errbuf[256]; ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); ERROR_LOG(s_Private->logger) << "EVP_DecryptUpdate failed" ; return QByteArray(); } ret = EVP_DecryptFinal_ex(ctx, dataOut + outSize1, &outSize2); if (ret == 0) { EVP_CIPHER_CTX_free(ctx); char errbuf[256]; ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); ERROR_LOG(s_Private->logger) << "EVP_DecryptFinal_ex failed" ; return QByteArray(); } EVP_CIPHER_CTX_free(ctx); bufDecrypted.resize(outSize1 + outSize2); if (bOk) *bOk = true; return bufDecrypted; } QByteArray encryptData(const QByteArray &dataToEncrypt, const QString &pw, bool *bOk) { if (bOk) *bOk = false; int ret; int outSize1 = 0; int outSize2 = 0; unsigned char key[32]; QByteArray bufEncrypted; const QByteArray baPassword = pw.toUtf8(); const unsigned char *dataPw = reinterpret_cast(baPassword.data()); int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), nullptr, dataPw, baPassword.size(), 5, key, nullptr); if (i != 32) { ERROR_LOG(s_Private->logger) << "Wrong key size - should be 256 bits" ; return QByteArray(); } QByteArray baSalt(EVP_MAX_IV_LENGTH, 0); for (int i = 0; i < EVP_MAX_IV_LENGTH; ++i) baSalt[i] = qrand(); const unsigned char *salt = reinterpret_cast(baSalt.data()); EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, key, salt); if (ret == 0) { EVP_CIPHER_CTX_free(ctx); char errbuf[256]; ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); ERROR_LOG(s_Private->logger) << "EVP_EncryptInit_ex failed" ; return QByteArray(); } bufEncrypted = QByteArray::fromRawData(reinterpret_cast(salt), EVP_MAX_IV_LENGTH); bufEncrypted.resize(bufEncrypted.size() + dataToEncrypt.size() + EVP_CIPHER_CTX_block_size(ctx)); const unsigned char *dataIn = reinterpret_cast(dataToEncrypt.data()); unsigned char *dataOut = reinterpret_cast(bufEncrypted.data()); dataOut += baSalt.size(); ret = EVP_EncryptUpdate(ctx, dataOut, &outSize1, dataIn, dataToEncrypt.size()); if (ret == 0) { EVP_CIPHER_CTX_free(ctx); char errbuf[256]; ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); ERROR_LOG(s_Private->logger) << "EVP_EncryptUpdate failed" ; return QByteArray(); } ret = EVP_EncryptFinal_ex(ctx, dataOut + outSize1, &outSize2); if (ret == 0) { EVP_CIPHER_CTX_free(ctx); char errbuf[256]; ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); ERROR_LOG(s_Private->logger) << "EVP_EncryptFinal_ex failed" ; return QByteArray(); } EVP_CIPHER_CTX_free(ctx); bufEncrypted.resize(outSize1 + outSize2 + baSalt.size()); if (bOk) *bOk = true; return bufEncrypted; } }