From 8c70060813ee8c46b1737af9a88575a68764f1b5 Mon Sep 17 00:00:00 2001 From: dankmeme01 <42031238+dankmeme01@users.noreply.github.com> Date: Sat, 9 Mar 2024 19:30:15 +0100 Subject: [PATCH] apparently secretbox is not unused --- src/crypto/chacha_secret_box.cpp | 83 ++++++++++++++++++++++++++++++++ src/crypto/chacha_secret_box.hpp | 41 ++++++++++++++++ src/crypto/secret_box.cpp | 22 ++++----- src/crypto/secret_box.hpp | 8 +-- 4 files changed, 136 insertions(+), 18 deletions(-) create mode 100644 src/crypto/chacha_secret_box.cpp create mode 100644 src/crypto/chacha_secret_box.hpp diff --git a/src/crypto/chacha_secret_box.cpp b/src/crypto/chacha_secret_box.cpp new file mode 100644 index 00000000..8aaf0d55 --- /dev/null +++ b/src/crypto/chacha_secret_box.cpp @@ -0,0 +1,83 @@ +#include "chacha_secret_box.hpp" + +#include // std::memcpy + +#include +#include +#include + +using namespace util::data; + +ChaChaSecretBox::ChaChaSecretBox(bytevector key) { + CRYPTO_REQUIRE(key.size() == KEY_LEN, "provided key is too long or too short for ChaChaSecretBox") + + this->key = reinterpret_cast(sodium_malloc( + KEY_LEN + )); + + CRYPTO_REQUIRE(this->key != nullptr, "sodium_malloc returned nullptr") + + std::memcpy(this->key, key.data(), KEY_LEN); +} + +ChaChaSecretBox ChaChaSecretBox::withPassword(const std::string_view pw) { + auto key = util::crypto::simpleHash(pw); + return ChaChaSecretBox(key); +} + +ChaChaSecretBox::~ChaChaSecretBox() { + if (this->key) { + sodium_free(this->key); + } +} + +constexpr size_t ChaChaSecretBox::nonceLength() { + return NONCE_LEN; +} + +constexpr size_t ChaChaSecretBox::macLength() { + return MAC_LEN; +} + +size_t ChaChaSecretBox::encryptInto(const byte* src, byte* dest, size_t size) { + byte nonce[NONCE_LEN]; + util::crypto::secureRandom(nonce, NONCE_LEN); + + byte* mac = dest + NONCE_LEN; + byte* ciphertext = mac + MAC_LEN; + + CRYPTO_ERR_CHECK(crypto_secretbox_xchacha20poly1305_detached(ciphertext, mac, src, size, nonce, key), "crypto_secretbox_xchacha20poly1305_detached failed") + + // prepend the nonce + std::memcpy(dest, nonce, NONCE_LEN); + + return size + PREFIX_LEN; +} + +size_t ChaChaSecretBox::decryptInto(const byte* src, byte* dest, size_t size) { + CRYPTO_REQUIRE(size >= PREFIX_LEN, "message is too short") + + size_t plaintextLength = size - PREFIX_LEN; + + const byte* nonce = src; + const byte* mac = src + NONCE_LEN; + const byte* ciphertext = mac + MAC_LEN; + + CRYPTO_ERR_CHECK(crypto_secretbox_xchacha20poly1305_open_detached(dest, ciphertext, mac, plaintextLength, nonce, key), "crypto_secretbox_xchacha20poly1305_open_detached failed") + + return plaintextLength; +} + +void ChaChaSecretBox::setKey(const util::data::bytevector& src) { + GLOBED_REQUIRE(src.size() == crypto_secretbox_KEYBYTES, "key size is too small or too big for ChaChaSecretBox") + setKey(src.data()); +} + +void ChaChaSecretBox::setKey(const util::data::byte* src) { + std::memcpy(this->key, src, crypto_secretbox_KEYBYTES); +} + +void ChaChaSecretBox::setPassword(const std::string_view pw) { + auto key = util::crypto::simpleHash(pw); + setKey(key); +} \ No newline at end of file diff --git a/src/crypto/chacha_secret_box.hpp b/src/crypto/chacha_secret_box.hpp new file mode 100644 index 00000000..5e784395 --- /dev/null +++ b/src/crypto/chacha_secret_box.hpp @@ -0,0 +1,41 @@ +#pragma once +#include "base_box.hpp" + +#include + +/* +* ChaChaSecretBox - SecretBox with prefix chacha algo +* +* Algorithm - XChaCha2020Poly1305 +* Tag implementation - prefix +*/ + +class ChaChaSecretBox final : public BaseCryptoBox { +public: + static const size_t NONCE_LEN = crypto_secretbox_xchacha20poly1305_NONCEBYTES; + static const size_t MAC_LEN = crypto_secretbox_xchacha20poly1305_MACBYTES; + static const size_t KEY_LEN = crypto_secretbox_xchacha20poly1305_KEYBYTES; + static const size_t PREFIX_LEN = NONCE_LEN + MAC_LEN; + + ChaChaSecretBox(util::data::bytevector key); + ChaChaSecretBox(const ChaChaSecretBox&) = delete; + ChaChaSecretBox& operator=(const ChaChaSecretBox&) = delete; + ~ChaChaSecretBox(); + + static ChaChaSecretBox withPassword(const std::string_view pw); + + constexpr size_t nonceLength() override; + constexpr size_t macLength() override; + using BaseCryptoBox::prefixLength; + + size_t encryptInto(const util::data::byte* src, util::data::byte* dest, size_t size) override; + size_t decryptInto(const util::data::byte* src, util::data::byte* dest, size_t size) override; + + void setKey(const util::data::bytevector& src); + void setKey(const util::data::byte* src); + // hashes the password and initializes the secret key with the hash + void setPassword(const std::string_view pw); + +private: + util::data::byte* key = nullptr; +}; diff --git a/src/crypto/secret_box.cpp b/src/crypto/secret_box.cpp index 61a6f110..f1b71abd 100644 --- a/src/crypto/secret_box.cpp +++ b/src/crypto/secret_box.cpp @@ -9,15 +9,15 @@ using namespace util::data; SecretBox::SecretBox(bytevector key) { - CRYPTO_REQUIRE(key.size() == KEY_LEN, "provided key is too long or too short for SecretBox") + CRYPTO_REQUIRE(key.size() == crypto_secretbox_KEYBYTES, "provided key is too long or too short for SecretBox") this->key = reinterpret_cast(sodium_malloc( - KEY_LEN + crypto_secretbox_KEYBYTES )); CRYPTO_REQUIRE(this->key != nullptr, "sodium_malloc returned nullptr") - std::memcpy(this->key, key.data(), KEY_LEN); + std::memcpy(this->key, key.data(), crypto_secretbox_KEYBYTES); } SecretBox SecretBox::withPassword(const std::string_view pw) { @@ -43,10 +43,8 @@ size_t SecretBox::encryptInto(const byte* src, byte* dest, size_t size) { byte nonce[NONCE_LEN]; util::crypto::secureRandom(nonce, NONCE_LEN); - byte* mac = dest + NONCE_LEN; - byte* ciphertext = mac + MAC_LEN; - - CRYPTO_ERR_CHECK(crypto_secretbox_xchacha20poly1305_detached(ciphertext, mac, src, size, nonce, key), "crypto_secretbox_detached failed") + byte* ciphertext = dest + NONCE_LEN; + CRYPTO_ERR_CHECK(crypto_secretbox_easy(ciphertext, src, size, nonce, key), "crypto_secretbox_easy failed") // prepend the nonce std::memcpy(dest, nonce, NONCE_LEN); @@ -57,13 +55,13 @@ size_t SecretBox::encryptInto(const byte* src, byte* dest, size_t size) { size_t SecretBox::decryptInto(const byte* src, byte* dest, size_t size) { CRYPTO_REQUIRE(size >= PREFIX_LEN, "message is too short") - size_t plaintextLength = size - PREFIX_LEN; - const byte* nonce = src; - const byte* mac = src + NONCE_LEN; - const byte* ciphertext = mac + MAC_LEN; + const byte* ciphertext = src + NONCE_LEN; + + size_t plaintextLength = size - PREFIX_LEN; + size_t ciphertextLength = size - NONCE_LEN; - CRYPTO_ERR_CHECK(crypto_secretbox_xchacha20poly1305_open_detached(dest, ciphertext, mac, plaintextLength, nonce, key), "crypto_secretbox_open_easy failed") + CRYPTO_ERR_CHECK(crypto_secretbox_open_easy(dest, ciphertext, ciphertextLength, nonce, key), "crypto_secretbox_open_easy failed") return plaintextLength; } diff --git a/src/crypto/secret_box.hpp b/src/crypto/secret_box.hpp index 827d3247..c644666e 100644 --- a/src/crypto/secret_box.hpp +++ b/src/crypto/secret_box.hpp @@ -6,16 +6,12 @@ /* * SecretBox - a class similar to CryptoBox, but instead of using public key cryptography, * uses a single secret key (or derives it from a passphrase) for data encryption. -* -* Algorithm - XChaCha2020Poly1305 -* Tag implementation - prefix */ class SecretBox final : public BaseCryptoBox { public: - static const size_t NONCE_LEN = crypto_secretbox_xchacha20poly1305_NONCEBYTES; - static const size_t MAC_LEN = crypto_secretbox_xchacha20poly1305_MACBYTES; - static const size_t KEY_LEN = crypto_secretbox_xchacha20poly1305_KEYBYTES; + static const size_t NONCE_LEN = crypto_secretbox_NONCEBYTES; + static const size_t MAC_LEN = crypto_secretbox_MACBYTES; static const size_t PREFIX_LEN = NONCE_LEN + MAC_LEN; SecretBox(util::data::bytevector key);