Source code

Revision control

Copy as Markdown

Other Tools

/*
* Copyright (c) 2017-2022 Ribose Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "hash_botan.hpp"
#include "logging.h"
#include <cassert>
static const id_str_pair botan_alg_map[] = {
{PGP_HASH_MD5, "MD5"},
{PGP_HASH_SHA1, "SHA-1"},
{PGP_HASH_RIPEMD, "RIPEMD-160"},
{PGP_HASH_SHA256, "SHA-256"},
{PGP_HASH_SHA384, "SHA-384"},
{PGP_HASH_SHA512, "SHA-512"},
{PGP_HASH_SHA224, "SHA-224"},
#if defined(ENABLE_SM2)
{PGP_HASH_SM3, "SM3"},
#endif
{PGP_HASH_SHA3_256, "SHA-3(256)"},
{PGP_HASH_SHA3_512, "SHA-3(512)"},
{0, NULL},
};
namespace rnp {
Hash_Botan::Hash_Botan(pgp_hash_alg_t alg) : Hash(alg)
{
auto name = Hash_Botan::name_backend(alg);
if (!name) {
throw rnp_exception(RNP_ERROR_BAD_PARAMETERS);
}
fn_ = Botan::HashFunction::create(name);
if (!fn_) {
RNP_LOG("Error creating hash object for '%s'", name);
throw rnp_exception(RNP_ERROR_BAD_PARAMETERS);
}
assert(size_ == fn_->output_length());
}
Hash_Botan::Hash_Botan(const Hash_Botan &src) : Hash(src.alg_)
{
if (!src.fn_) {
throw rnp_exception(RNP_ERROR_BAD_PARAMETERS);
}
fn_ = src.fn_->copy_state();
}
Hash_Botan::~Hash_Botan()
{
}
std::unique_ptr<Hash_Botan>
Hash_Botan::create(pgp_hash_alg_t alg)
{
return std::unique_ptr<Hash_Botan>(new Hash_Botan(alg));
}
std::unique_ptr<Hash>
Hash_Botan::clone() const
{
return std::unique_ptr<Hash>(new Hash_Botan(*this));
}
void
Hash_Botan::add(const void *buf, size_t len)
{
if (!fn_) {
throw rnp_exception(RNP_ERROR_NULL_POINTER);
}
fn_->update(static_cast<const uint8_t *>(buf), len);
}
size_t
Hash_Botan::finish(uint8_t *digest)
{
if (!fn_) {
return 0;
}
size_t outlen = size_;
if (digest) {
fn_->final(digest);
}
fn_ = nullptr;
size_ = 0;
return outlen;
}
const char *
Hash_Botan::name_backend(pgp_hash_alg_t alg)
{
return id_str_pair::lookup(botan_alg_map, alg);
}
CRC24_Botan::CRC24_Botan()
{
fn_ = Botan::HashFunction::create("CRC24");
if (!fn_) {
RNP_LOG("Error creating CRC24 object");
throw rnp_exception(RNP_ERROR_BAD_PARAMETERS);
}
assert(3 == fn_->output_length());
}
CRC24_Botan::~CRC24_Botan()
{
}
std::unique_ptr<CRC24_Botan>
CRC24_Botan::create()
{
return std::unique_ptr<CRC24_Botan>(new CRC24_Botan());
}
void
CRC24_Botan::add(const void *buf, size_t len)
{
if (!fn_) {
throw rnp_exception(RNP_ERROR_NULL_POINTER);
}
fn_->update(static_cast<const uint8_t *>(buf), len);
}
std::array<uint8_t, 3>
CRC24_Botan::finish()
{
if (!fn_) {
throw rnp_exception(RNP_ERROR_NULL_POINTER);
}
std::array<uint8_t, 3> crc{};
fn_->final(crc.data());
fn_ = nullptr;
return crc;
}
} // namespace rnp