From 82cf551a4c9d1a9897d07ea90e3da68728bec44e Mon Sep 17 00:00:00 2001 From: Toni Date: Tue, 4 Nov 2025 19:47:16 +0100 Subject: [PATCH] std::array for nonces --- src/crypto.h | 8 ++++---- src/mainwindow.cc | 2 +- src/vault.cc | 42 +++++++++++++++++++----------------------- src/vault.h | 10 ++++++---- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/crypto.h b/src/crypto.h index 1fcdd00..60cd641 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -3,14 +3,13 @@ #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) { + const std::array &nonce) { ASSERT(key.size() == 32); ASSERT(nonce.size() == 24); @@ -31,7 +30,7 @@ encrypt_xchacha20_poly1305(const Botan::secure_vector &plaintext, inline Botan::secure_vector decrypt_xchacha20_poly1305(const Botan::secure_vector &ciphertext, const Botan::secure_vector &key, - const std::vector &nonce) { + const std::array &nonce) { ASSERT(ciphertext.size() >= 16); ASSERT(key.size() == 32); ASSERT(nonce.size() == 24); @@ -49,7 +48,8 @@ decrypt_xchacha20_poly1305(const Botan::secure_vector &ciphertext, } inline Botan::secure_vector -derive_key_argon2id(const std::string &password, const std::vector &salt) { +derive_key_argon2id(const std::string &password, + const std::array &salt) { // thousands of years to crack a random 8 char password on a 100 GPUs auto pwdhash = Botan::PasswordHashFamily::create_or_throw("Argon2id") ->from_params(static_cast(1024 * 1024), 8, 4); diff --git a/src/mainwindow.cc b/src/mainwindow.cc index 69d5fc1..e889330 100644 --- a/src/mainwindow.cc +++ b/src/mainwindow.cc @@ -106,7 +106,7 @@ void MainWindow::reload_fs_tree() { for (const auto &header : headers) { auto *item = new QTreeWidgetItem(ui->fsTreeWidget); item->setText(0, QString::fromStdString(header.name)); - item->setText(1, QString::number(header.content_size)); + item->setText(1, QString::number(header.content_ciphertext_size)); } for (int i = 0; i < ui->fsTreeWidget->columnCount(); ++i) { ui->fsTreeWidget->resizeColumnToContents(i); diff --git a/src/vault.cc b/src/vault.cc index 6dd0b22..5ad7dc0 100644 --- a/src/vault.cc +++ b/src/vault.cc @@ -18,8 +18,7 @@ Vault::Vault(std::string path, const std::string &password) ASSERT(m_file.read(to_char_ptr(&version), sizeof(version))); ASSERT(version == VERSION); - std::vector salt{}; - salt.resize(16); + std::array salt{}; ASSERT(m_file.read(to_char_ptr(salt.data()), 16)); m_key = Crypto::derive_key_argon2id(password, salt); @@ -35,7 +34,8 @@ std::vector Vault::read_file_headers() { auto header = read_file_header(); if (header) { headers.push_back(header.value()); - m_file.seekg(static_cast(header->content_size), std::ios::cur); + m_file.seekg(static_cast(header->content_ciphertext_size), + std::ios::cur); } else { break; } @@ -56,9 +56,9 @@ std::optional Vault::read_file(const std::string &filename) { if (header->name == filename) { Botan::secure_vector ciphertext; - ciphertext.resize(header->content_size); + ciphertext.resize(header->content_ciphertext_size); if (!m_file.read(to_char_ptr(ciphertext.data()), - static_cast(header->content_size))) { + static_cast(header->content_ciphertext_size))) { break; } @@ -67,7 +67,8 @@ std::optional Vault::read_file(const std::string &filename) { return std::string(to_char_ptr(plaintext.data()), plaintext.size()); } - m_file.seekg(static_cast(header->content_size), std::ios::cur); + m_file.seekg(static_cast(header->content_ciphertext_size), + std::ios::cur); } return std::nullopt; @@ -79,12 +80,8 @@ void Vault::create_file(const std::string &filename, m_file.seekp(0, std::ios::end); static Botan::AutoSeeded_RNG rng; - auto name_nonce_sv = rng.random_vec(24); - std::vector name_nonce(name_nonce_sv.begin(), name_nonce_sv.end()); - - auto content_nonce_sv = rng.random_vec(24); - std::vector content_nonce(content_nonce_sv.begin(), - content_nonce_sv.end()); + auto name_nonce = rng.random_array<24>(); + auto content_nonce = rng.random_array<24>(); Botan::secure_vector filename_sv(filename.begin(), filename.end()); auto filename_ciphertext = @@ -124,13 +121,15 @@ void Vault::delete_file(const std::string &filename) { if (header->name == filename) { entry_start = current_pos; - entry_total_size = 24 + sizeof(u64) + header->name_ciphertext_size + - sizeof(u64) + header->content_size; - m_file.seekg(static_cast(header->content_size), std::ios::cur); + entry_total_size = 24 + sizeof(u64) + header->name_ciphertext_size + 24 + + sizeof(u64) + header->content_ciphertext_size; + m_file.seekg(static_cast(header->content_ciphertext_size), + std::ios::cur); break; } - m_file.seekg(static_cast(header->content_size), std::ios::cur); + m_file.seekg(static_cast(header->content_ciphertext_size), + std::ios::cur); } if (entry_start != -1) { @@ -166,9 +165,7 @@ void Vault::update_file(const std::string &filename, std::optional Vault::read_file_header() { FileHeader header{}; - std::vector name_nonce; - name_nonce.resize(24); - if (!m_file.read(to_char_ptr(name_nonce.data()), 24)) { + if (!m_file.read(to_char_ptr(header.name_nonce.data()), 24)) { return std::nullopt; } @@ -185,16 +182,15 @@ std::optional Vault::read_file_header() { return std::nullopt; } - auto name = - Crypto::decrypt_xchacha20_poly1305(name_ciphertext, m_key, name_nonce); + auto name = Crypto::decrypt_xchacha20_poly1305(name_ciphertext, m_key, + header.name_nonce); header.name = std::string(name.begin(), name.end()); - header.content_nonce.resize(24); if (!m_file.read(to_char_ptr(header.content_nonce.data()), 24)) { return std::nullopt; } - if (!m_file.read(to_char_ptr(&header.content_size), sizeof(u64))) { + if (!m_file.read(to_char_ptr(&header.content_ciphertext_size), sizeof(u64))) { return std::nullopt; } return header; diff --git a/src/vault.h b/src/vault.h index e680767..6262a5e 100644 --- a/src/vault.h +++ b/src/vault.h @@ -1,19 +1,21 @@ #pragma once #include "common.h" +#include #include #include #include -#include constexpr i16 VERSION = 1; constexpr u64 AFTER_HEADER_OFFSET = 22; +// !!! REMEMBER TO UPDATE entry_total_size IN Vault::delete_file struct FileHeader { - std::string name; + std::array name_nonce; u64 name_ciphertext_size; - u64 content_size; - std::vector content_nonce; + std::string name; + std::array content_nonce; + u64 content_ciphertext_size; }; class Vault {