// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- /* * Ceph - scalable distributed file system * * Copyright (C) 2019 Red Hat, Inc. * * This is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software * Foundation. See file COPYING. * */ #pragma once #include #include #include "common/ceph_crypto.h" #include "rgw_blake3_digest.h" #include "rgw_crc_digest.h" #include "rgw_xxh_digest.h" #include "rgw_cksum.h" namespace rgw { namespace cksum { class Digest { public: virtual void Restart() = 0; virtual void Update (const unsigned char *input, size_t length) = 0; virtual void Update(const ceph::buffer::list& bl) = 0; virtual void Final (unsigned char *digest) = 0; virtual ~Digest() {} }; template class TDigest : public Digest { T d; public: TDigest() {} TDigest(TDigest&& rhs) noexcept : d(std::move(rhs.d)) {} void Restart() override { d.Restart(); } void Update(const unsigned char* data, uint64_t len) override { d.Update(data, len); } void Update(const ceph::buffer::list& bl) { for (auto& p : bl.buffers()) { d.Update((const unsigned char *)p.c_str(), p.length()); } } void Final(unsigned char* digest) override { d.Final(digest); } }; typedef TDigest Blake3; typedef TDigest Crc32; typedef TDigest Crc32c; typedef TDigest XXH3; typedef TDigest SHA1; typedef TDigest SHA256; typedef TDigest SHA512; typedef boost::variant DigestVariant; struct get_digest_ptr : public boost::static_visitor { get_digest_ptr() {}; Digest* operator()(const boost::blank& b) const { return nullptr; } Digest* operator()(Blake3& digest) const { return &digest; } Digest* operator()(Crc32& digest) const { return &digest; } Digest* operator()(Crc32c& digest) const { return &digest; } Digest* operator()(XXH3& digest) const { return &digest; } Digest* operator()(SHA1& digest) const { return &digest; } Digest* operator()(SHA256& digest) const { return &digest; } Digest* operator()(SHA512& digest) const { return &digest; } }; static inline Digest* get_digest(DigestVariant& ev) { return boost::apply_visitor(get_digest_ptr{}, ev); } static inline DigestVariant digest_factory(const Type cksum_type) { switch (cksum_type) { case Type::blake3: return Blake3(); break; case Type::sha256: return SHA256(); break; case Type::crc32: return Crc32(); break; case Type::crc32c: return Crc32c(); break; case Type::xxh3: return XXH3(); break; case Type::sha512: return SHA512(); break; case Type::sha1: return SHA1(); break; case Type::none: break; }; return boost::blank(); } /* digest_factory */ static inline Cksum finalize_digest(Digest* digest, Type type) { Cksum cksum(type); if (digest) { auto data = cksum.digest.data(); digest->Final(data); } return cksum; } }} /* namespace */