/* * InspIRCd -- Internet Relay Chat Daemon * * Copyright (C) 2025 Sadie Powell * * This file is part of InspIRCd. InspIRCd is free software: you can * redistribute it and/or modify it under the terms of the GNU General Public * License as published by the Free Software Foundation, version 2. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /// BEGIN CMAKE /// target_link_libraries(${TARGET} PRIVATE "vendored_sha2") /// END CMAKE // Fix a collision between the Haiku uint64 typedef and the // one from the sha2 library. #ifdef __HAIKU__ # define uint64 sha2_uint64 #endif #include #ifdef __HAIKU__ # undef uint64 #endif #include "inspircd.h" #include "modules/hash.h" template class SHA2Context final : public Hash::Context { private: SHAContext context; const size_t digest_size; public: SHA2Context(size_t ds) : digest_size(ds) { SHAInit(&context); } void Update(const unsigned char *data, size_t len) override { SHAUpdate(&context, data, static_cast(len)); } std::string Finalize() override { std::vector digest(digest_size); SHAFinal(&context, digest.data()); return std::string(reinterpret_cast(digest.data()), digest.size()); } }; template class SHA2Provider final : public Hash::Provider { private: Hash::HMACProvider hmacsha2algo; public: SHA2Provider(const WeakModulePtr& mod, const std::string& algorithm, size_t ds, size_t bs) : Hash::Provider(mod, algorithm, ds, bs) , hmacsha2algo(mod, algorithm) { } bool IsPasswordSafe() const override { // Plain SHA-2 is not safe for password use as it can be decoded via the // use of a rainbow table. You should use HMAC-SHA-2 instead as it is not // vulnerable to this attack. return false; } std::unique_ptr CreateContext() override { return std::make_unique>(this->digest_size); } }; class ModuleHashSHA2 final : public Module { private: SHA2Provider sha224algo; SHA2Provider sha256algo; SHA2Provider sha384algo; SHA2Provider sha512algo; public: ModuleHashSHA2() : Module(VF_VENDOR, "Allows other modules to generate SHA-2 hashes.") , sha224algo(weak_from_this(), "sha224", SHA224_DIGEST_SIZE, SHA224_BLOCK_SIZE) , sha256algo(weak_from_this(), "sha256", SHA256_DIGEST_SIZE, SHA256_BLOCK_SIZE) , sha384algo(weak_from_this(), "sha384", SHA384_DIGEST_SIZE, SHA384_BLOCK_SIZE) , sha512algo(weak_from_this(), "sha512", SHA512_DIGEST_SIZE, SHA512_BLOCK_SIZE) { } void init() override { sha224algo.Check({ { "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", "" }, { "730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525", "The quick brown fox jumps over the lazy dog" }, }); sha256algo.Check({ { "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "" }, { "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", "The quick brown fox jumps over the lazy dog" }, }); sha384algo.Check({ { "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", "" }, { "ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1", "The quick brown fox jumps over the lazy dog" }, }); sha512algo.Check({ { "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", "" }, { "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6", "The quick brown fox jumps over the lazy dog" }, }); } }; MODULE_INIT(ModuleHashSHA2)