diff --git a/CMakeLists.txt b/CMakeLists.txt index f81e25d..851d13d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) find_package(Qt6 REQUIRED COMPONENTS Core Widgets) +pkg_check_modules(BOTAN REQUIRED botan-3) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) @@ -14,6 +15,6 @@ qt6_wrap_ui(UI_HEADERS src/mainwindow.ui) add_executable(${PROJECT_NAME} src/main.cc src/mainwindow.cc src/vault.cc ${UI_HEADERS}) -target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${BOTAN_INCLUDE_DIRS}) -target_link_libraries(${PROJECT_NAME} Qt6::Core Qt6::Widgets) +target_link_libraries(${PROJECT_NAME} Qt6::Core Qt6::Widgets ${BOTAN_LIBRARIES}) diff --git a/src/common.h b/src/common.h index f448e9d..c06d4c5 100644 --- a/src/common.h +++ b/src/common.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #define ASSERT(cond) \ diff --git a/src/crypto.h b/src/crypto.h new file mode 100644 index 0000000..f97c256 --- /dev/null +++ b/src/crypto.h @@ -0,0 +1,61 @@ +#pragma once +#include "common.h" +#include +#include +#include +#include +#include + +namespace Crypto { + +inline Botan::secure_vector +encrypt_xchacha20_poly1305(const Botan::secure_vector &plaintext, + const Botan::secure_vector &key, + const std::vector &nonce) { + ASSERT(key.size() == 32); + ASSERT(nonce.size() == 24); + + auto cipher = Botan::AEAD_Mode::create_or_throw( + "ChaCha20Poly1305", Botan::Cipher_Dir::Encryption); + + cipher->set_key(key); + cipher->start(nonce); + + Botan::secure_vector ciphertext = plaintext; + cipher->finish(ciphertext); + + return ciphertext; +} + +inline Botan::secure_vector +decrypt_xchacha20_poly1305(const Botan::secure_vector &ciphertext, + const Botan::secure_vector &key, + const std::vector &nonce) { + ASSERT(key.size() == 32); + ASSERT(nonce.size() == 24); + ASSERT(ciphertext.size() >= 16); + + auto cipher = Botan::AEAD_Mode::create_or_throw( + "ChaCha20Poly1305", Botan::Cipher_Dir::Decryption); + + cipher->set_key(key); + cipher->start(nonce); + + Botan::secure_vector plaintext = ciphertext; + cipher->finish(plaintext); + + return plaintext; +} + +inline Botan::secure_vector +derive_key_argon2id(const std::string &password, const std::vector &salt) { + auto pwdhash = Botan::PasswordHashFamily::create_or_throw("Argon2id") + ->from_params(static_cast(1024 * 1024), 6, 4); + + Botan::secure_vector key(32); + pwdhash->derive_key(key.data(), key.size(), password.data(), password.size(), + salt.data(), salt.size()); + return key; +} + +}; // namespace Crypto \ No newline at end of file diff --git a/src/mainwindow.cc b/src/mainwindow.cc index fd495d0..14c2d1d 100644 --- a/src/mainwindow.cc +++ b/src/mainwindow.cc @@ -4,7 +4,6 @@ #include #include #include -#include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { diff --git a/src/vault.cc b/src/vault.cc index ccd7bfd..763fa0f 100644 --- a/src/vault.cc +++ b/src/vault.cc @@ -2,7 +2,6 @@ #include "common.h" #include #include -#include Vault::Vault(std::string path) : m_path(std::move(path)) { m_file.open(m_path, std::ios::in | std::ios::out | std::ios::binary);