diff --git a/CMakeLists.txt b/CMakeLists.txt index 4453e15..25b338e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ set(CMAKE_AUTORCC ON) # Adding headers explicity so they are displayed in Qt Creator set(HEADERS config.h imagewriter.h networkaccessmanagerfactory.h nan.h drivelistitem.h drivelistmodel.h driveformatthread.h powersaveblocker.h - downloadthread.h downloadextractthread.h dependencies/mountutils/src/mountutils.hpp) + downloadthread.h downloadextractthread.h acceleratedcryptographichash.h dependencies/mountutils/src/mountutils.hpp) # Add 3rd-party dependencies if (APPLE) @@ -60,8 +60,9 @@ endif() set(SOURCES "main.cpp" "imagewriter.cpp" "networkaccessmanagerfactory.cpp" "drivelistitem.cpp" "drivelistmodel.cpp" "downloadthread.cpp" "downloadextractthread.cpp" - "driveformatthread.cpp" "powersaveblocker.cpp" "qml.qrc") + "driveformatthread.cpp" "powersaveblocker.cpp" "acceleratedcryptographichash.cpp" "qml.qrc") +find_package(OpenSSL REQUIRED) find_package(Qt5 COMPONENTS Core Quick Widgets LinguistTools REQUIRED) #qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} i18n/rpi-imager_nl.ts i18n/rpi-imager_zh_cn.ts) @@ -233,5 +234,5 @@ else() install(FILES linux/rpi-imager.desktop DESTINATION share/applications) endif() -include_directories(${CURL_INCLUDE_DIR} ${LibArchive_INCLUDE_DIR}) -target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Quick Qt5::Widgets ${CURL_LIBRARIES} ${LibArchive_LIBRARIES} ${ATOMIC_LIBRARY} ${EXTRALIBS}) +include_directories(${CURL_INCLUDE_DIR} ${LibArchive_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR}) +target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Quick Qt5::Widgets ${CURL_LIBRARIES} ${LibArchive_LIBRARIES} ${OPENSSL_LIBRARIES} ${ATOMIC_LIBRARY} ${EXTRALIBS}) diff --git a/acceleratedcryptographichash.cpp b/acceleratedcryptographichash.cpp new file mode 100644 index 0000000..cade939 --- /dev/null +++ b/acceleratedcryptographichash.cpp @@ -0,0 +1,37 @@ +/* + * Use OpenSSL for hashing as their code is more optimized than Qt's + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (C) 2020 Raspberry Pi (Trading) Limited + */ + +#include "acceleratedcryptographichash.h" + +AcceleratedCryptographicHash::AcceleratedCryptographicHash(QCryptographicHash::Algorithm method) +{ + if (method != QCryptographicHash::Sha256) + throw std::runtime_error("Only sha256 implemented"); + + SHA256_Init(&_sha256); +} + +AcceleratedCryptographicHash::~AcceleratedCryptographicHash() +{ +} + +void AcceleratedCryptographicHash::addData(const char *data, int length) +{ + SHA256_Update(&_sha256, data, length); +} + +void AcceleratedCryptographicHash::addData(const QByteArray &data) +{ + addData(data.constData(), data.size()); +} + +QByteArray AcceleratedCryptographicHash::result() +{ + unsigned char binhash[SHA256_DIGEST_LENGTH]; + SHA256_Final(binhash, &_sha256); + return QByteArray((char *) binhash, sizeof binhash); +} diff --git a/acceleratedcryptographichash.h b/acceleratedcryptographichash.h new file mode 100644 index 0000000..4e87227 --- /dev/null +++ b/acceleratedcryptographichash.h @@ -0,0 +1,25 @@ +#ifndef ACCELERATEDCRYPTOGRAPHICHASH_H +#define ACCELERATEDCRYPTOGRAPHICHASH_H + +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright (C) 2020 Raspberry Pi (Trading) Limited + */ + +#include +#include "openssl/sha.h" + +class AcceleratedCryptographicHash +{ +public: + explicit AcceleratedCryptographicHash(QCryptographicHash::Algorithm method); + virtual ~AcceleratedCryptographicHash(); + void addData(const char *data, int length); + void addData(const QByteArray &data); + QByteArray result(); + +protected: + SHA256_CTX _sha256; +}; + +#endif // ACCELERATEDCRYPTOGRAPHICHASH_H diff --git a/downloadextractthread.h b/downloadextractthread.h index 0fc7a07..1d7e6bf 100644 --- a/downloadextractthread.h +++ b/downloadextractthread.h @@ -41,7 +41,7 @@ protected: std::mutex _queueMutex; std::condition_variable _cv; bool _ethreadStarted, _isImage; - QCryptographicHash _inputHash; + AcceleratedCryptographicHash _inputHash; int _activeBuf; bool _writeThreadStarted; QFuture _writeFuture; diff --git a/downloadthread.cpp b/downloadthread.cpp index 2ed035b..8a62e4e 100644 --- a/downloadthread.cpp +++ b/downloadthread.cpp @@ -600,6 +600,8 @@ bool DownloadThread::_verify() char *verifyBuf = (char *) qMallocAligned(IMAGEWRITER_VERIFY_BLOCKSIZE, 4096); _lastVerifyNow = 0; _verifyTotal = _file.pos(); + QElapsedTimer t1; + t1.start(); if (!_firstBlock) { @@ -627,6 +629,7 @@ bool DownloadThread::_verify() } qFreeAligned(verifyBuf); + qDebug() << "Verify done in" << t1.elapsed() / 1000.0 << "seconds"; qDebug() << "Verify hash:" << _verifyhash.result().toHex(); if (_verifyhash.result() == _writehash.result() || !_verifyEnabled || _cancelled) diff --git a/downloadthread.h b/downloadthread.h index 98b3931..896ecf6 100644 --- a/downloadthread.h +++ b/downloadthread.h @@ -9,12 +9,12 @@ #include #include #include -#include #include #include #include #include #include +#include "acceleratedcryptographichash.h" #ifdef Q_OS_WIN #include "windows/winfile.h" @@ -172,7 +172,7 @@ protected: #endif QFile _cachefile; - QCryptographicHash _writehash, _verifyhash; + AcceleratedCryptographicHash _writehash, _verifyhash; }; #endif // DOWNLOADTHREAD_H