diff --git a/include/blowfish/blowfish.h b/include/blowfish/blowfish.h index 7307cbe..83c9aa5 100644 --- a/include/blowfish/blowfish.h +++ b/include/blowfish/blowfish.h @@ -4,32 +4,34 @@ // Original Blowfish Algorithm copyright: // SPDX-FileCopyrightText: 1997 Paul Kocher -#include +#pragma once #include #include #include #define MAXKEYBYTES 56 // 448 bits max -#define N 16 +static constexpr uint32_t N = 16; #if !defined(BLOWFISH_BLOWFISH_H_) #define BLOWFISH_BLOWFISH_H_ class Blowfish { private: - std::array PArray; - std::array, 4> Sboxes; - uint32_t F(uint32_t x); + std::array PArray{}; + std::array, 4> Sboxes{}; + uint32_t F(uint32_t x) const noexcept; public: - Blowfish() {} - Blowfish(std::string const &key); + Blowfish() = default; + explicit Blowfish(std::string const &key); Blowfish(Blowfish const &) = delete; - void initialize(std::string const &key); + void initialize(const uint8_t *key, size_t keylen); + void initialize(const std::string &key); - void encrypt(uint32_t &xl, uint32_t &xr); - void decrypt(uint32_t &xl, uint32_t &xr); + void encrypt(uint32_t &xl, uint32_t &xr) noexcept; + void decrypt(uint32_t &xl, uint32_t &xr) noexcept; + ~Blowfish(); }; #endif // BLOWFISH_BLOWFISH_H_ diff --git a/include/blowfish/blowfish2.h b/include/blowfish/blowfish2.h index a03ef85..f38a8df 100644 --- a/include/blowfish/blowfish2.h +++ b/include/blowfish/blowfish2.h @@ -4,32 +4,35 @@ // Original Blowfish 2 Algorithm copyright: // SPDX-FileCopyrightText: 2005 Alexander Pukall -#include +#pragma once #include #include #include -#define MAXKEYBYTES 56 // 4224 bits max -#define N 64 +#define MAXKEYBYTES 56 // 448 bits max #if !defined(BLOWFISH_BLOWFISH2_H_) #define BLOWFISH_BLOWFISH2_H_ class Blowfish2 { private: - std::array PArray; - std::array, 8> Sboxes; - uint64_t F(uint64_t x); + static constexpr uint64_t N = 64; + std::array PArray{}; + std::array, 8> Sboxes{}; + uint64_t F(uint64_t x) const noexcept; public: - Blowfish2() {} - Blowfish2(std::string const &key); - Blowfish2(Blowfish2 const &) = delete; + Blowfish2() = default; + explicit Blowfish2(const std::string &key) { initialize(key); } + + Blowfish2(const Blowfish2 &) = delete; + Blowfish2 &operator=(const Blowfish2 &) = delete; void initialize(std::string const &key); + void initialize(const uint8_t *key, size_t keylen); - void encrypt(uint64_t &xl, uint64_t &xr); - void decrypt(uint64_t &xl, uint64_t &xr); + void encrypt(uint64_t &xl, uint64_t &xr) noexcept; + void decrypt(uint64_t &xl, uint64_t &xr) noexcept; }; #endif // BLOWFISH_BLOWFISH2_H_ diff --git a/src/blowfish.cc b/src/blowfish.cc index 3e94b68..7ca093c 100644 --- a/src/blowfish.cc +++ b/src/blowfish.cc @@ -225,22 +225,22 @@ static const std::array, 4> S = { 0x3F09252DL, 0xC208E69FL, 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L}}}; -void Blowfish::initialize(std::string const &key) { - uint32_t data, datal, datar; +void Blowfish::initialize(const uint8_t *key, size_t keylen) { + uint32_t data = 0; + uint32_t datal = 0; + uint32_t datar = 0; + Sboxes = S; - uint32_t j = 0, keylength = key.length(); + + size_t j = 0; for (uint32_t i = 0; i < N + 2; ++i) { - data = 0x00000000; + data = 0; for (uint32_t k = 0; k < 4; ++k) { data = (data << 8) | key[j]; - if (++j >= keylength) { - j = 0; - } + j = (j + 1) % keylen; } PArray[i] = P[i] ^ data; } - datal = 0x00000000; - datar = 0x00000000; for (uint32_t i = 0; i < N + 2; i += 2) { encrypt(datal, datar); @@ -257,29 +257,28 @@ void Blowfish::initialize(std::string const &key) { } } -Blowfish::Blowfish(std::string const &key) { initialize(key); } +void Blowfish::initialize(const std::string &key) { + initialize(reinterpret_cast(key.data()), key.size()); +} -uint32_t Blowfish::F(uint32_t x) { - uint16_t a, b, c, d; - uint32_t y; +Blowfish::Blowfish(const std::string &key) : PArray{}, Sboxes{} { + initialize(key); +} - d = (unsigned int)(x & 0xFF); - x >>= 8; - d = (unsigned int)(x & 0xFF); - x >>= 8; - c = (unsigned int)(x & 0xFF); - x >>= 8; - b = (unsigned int)(x & 0xFF); - x >>= 8; - a = (unsigned int)(x & 0xFF); +uint32_t Blowfish::F(uint32_t x) const noexcept { + uint8_t a = (x >> 24) & 0xFF; + uint8_t b = (x >> 16) & 0xFF; + uint8_t c = (x >> 8) & 0xFF; + uint8_t d = x & 0xFF; - y = Sboxes[0][a] + Sboxes[1][b]; + uint32_t y = Sboxes[0][a] + Sboxes[1][b]; y ^= Sboxes[2][c]; y += Sboxes[3][d]; + return y; } -void Blowfish::encrypt(uint32_t &xl, uint32_t &xr) { +void Blowfish::encrypt(uint32_t &xl, uint32_t &xr) noexcept { uint32_t Xl = xl; uint32_t Xr = xr; @@ -296,13 +295,13 @@ void Blowfish::encrypt(uint32_t &xl, uint32_t &xr) { xr = Xr; } -void Blowfish::decrypt(uint32_t &xl, uint32_t &xr) { +void Blowfish::decrypt(uint32_t &xl, uint32_t &xr) noexcept { uint32_t Xl = xl; uint32_t Xr = xr; - for (uint32_t i = N + 1; i > 1; --i) { + for (int i = N + 1; i >= 2; --i) { Xl ^= PArray[i]; - Xr = F(Xl) ^ Xr; + Xr ^= F(Xl); std::swap(Xl, Xr); } @@ -312,3 +311,9 @@ void Blowfish::decrypt(uint32_t &xl, uint32_t &xr) { xl = Xl; xr = Xr; } +Blowfish::~Blowfish() { + std::fill(PArray.begin(), PArray.end(), 0); + for (auto &row : Sboxes) { + std::fill(row.begin(), row.end(), 0); + } +} diff --git a/src/blowfish2.cc b/src/blowfish2.cc index 0dd9a56..8b6ea33 100644 --- a/src/blowfish2.cc +++ b/src/blowfish2.cc @@ -727,22 +727,27 @@ static const std::array, 8> S = { 0xBF2FAD7CDA8F11B8, 0x9B14B76D08EF72BE, 0x8A0E0EEC190EBEBA, 0x8CF97F6ECE339C68}}}; -void Blowfish2::initialize(std::string const &key) { - uint64_t data, datal, datar; - Sboxes = S; - uint64_t j = 0, keylength = key.length(); +void Blowfish2::initialize(const std::string &key) { + initialize(reinterpret_cast(key.data()), key.size()); +} + +void Blowfish2::initialize(const uint8_t *key, size_t keylen) { + uint64_t data = 0; + uint64_t datal = 0; + uint64_t datar = 0; + + Sboxes = S; // assumes static const S exists + + size_t j = 0; + for (uint64_t i = 0; i < N + 2; ++i) { - data = 0x00000000; + data = 0; for (uint64_t k = 0; k < 8; ++k) { data = (data << 8) | key[j]; - if (++j >= keylength) { - j = 0; - } + j = (j + 1) % keylen; } PArray[i] = P[i] ^ data; } - datal = 0x00000000; - datar = 0x00000000; for (uint64_t i = 0; i < N + 2; i += 2) { encrypt(datal, datar); @@ -759,9 +764,7 @@ void Blowfish2::initialize(std::string const &key) { } } -Blowfish2::Blowfish2(std::string const &key) { initialize(key); } - -uint64_t Blowfish2::F(uint64_t x) { +uint64_t Blowfish2::F(uint64_t x) const noexcept { unsigned int a, b, c, d, e, f, g, h; uint64_t y; @@ -791,7 +794,7 @@ uint64_t Blowfish2::F(uint64_t x) { return y; } -void Blowfish2::encrypt(uint64_t &xl, uint64_t &xr) { +void Blowfish2::encrypt(uint64_t &xl, uint64_t &xr) noexcept { uint64_t Xl = xl; uint64_t Xr = xr; @@ -808,7 +811,7 @@ void Blowfish2::encrypt(uint64_t &xl, uint64_t &xr) { xr = Xr; } -void Blowfish2::decrypt(uint64_t &xl, uint64_t &xr) { +void Blowfish2::decrypt(uint64_t &xl, uint64_t &xr) noexcept { uint64_t Xl = xl; uint64_t Xr = xr;