mirror of
https://github.com/vgough/encfs.git
synced 2025-04-24 11:18:22 +02:00
Implement more Botan support.
git-svn-id: http://encfs.googlecode.com/svn/trunk@99 db9cf616-1c43-0410-9cb8-a902689de0d6
This commit is contained in:
parent
95750d4539
commit
bd182db260
@ -91,6 +91,7 @@ find_program (POD2MAN pod2man)
|
|||||||
|
|
||||||
find_package (GTest)
|
find_package (GTest)
|
||||||
if (GTEST_FOUND)
|
if (GTEST_FOUND)
|
||||||
|
include_directories(${GTEST_INCLUDE_DIR})
|
||||||
enable_testing()
|
enable_testing()
|
||||||
endif (GTEST_FOUND)
|
endif (GTEST_FOUND)
|
||||||
|
|
||||||
|
@ -31,10 +31,6 @@
|
|||||||
|
|
||||||
#include <tinyxml.h>
|
#include <tinyxml.h>
|
||||||
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
#include <openssl/bio.h>
|
|
||||||
#include <openssl/buffer.h>
|
|
||||||
|
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include "base/base64.h"
|
#include "base/base64.h"
|
||||||
#include "base/Interface.h"
|
#include "base/Interface.h"
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "base/config.h"
|
#include "base/config.h"
|
||||||
#include "base/shared_ptr.h"
|
#include "base/shared_ptr.h"
|
||||||
#include "cipher/BlockCipher.h"
|
#include "cipher/BlockCipher.h"
|
||||||
|
#include "cipher/CipherV1.h"
|
||||||
#include "cipher/MemoryPool.h"
|
#include "cipher/MemoryPool.h"
|
||||||
#include "cipher/PBKDF.h"
|
#include "cipher/PBKDF.h"
|
||||||
#include "cipher/testing.h"
|
#include "cipher/testing.h"
|
||||||
@ -40,6 +41,13 @@ using std::string;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
class BlockCipherTest : public testing::Test {
|
||||||
|
public:
|
||||||
|
virtual void SetUp() {
|
||||||
|
CipherV1::init(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void compare(const byte *a, const byte *b, int size) {
|
void compare(const byte *a, const byte *b, int size) {
|
||||||
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
||||||
ASSERT_EQ(0, VALGRIND_CHECK_MEM_IS_DEFINED(a, size));
|
ASSERT_EQ(0, VALGRIND_CHECK_MEM_IS_DEFINED(a, size));
|
||||||
@ -54,7 +62,7 @@ void compare(const byte *a, const byte *b, int size) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(RequiredBlockCiphers, BlockCipher) {
|
TEST_F(BlockCipherTest, RequiredBlockCiphers) {
|
||||||
auto aes_cbc = BlockCipher::GetRegistry().CreateForMatch(NAME_AES_CBC);
|
auto aes_cbc = BlockCipher::GetRegistry().CreateForMatch(NAME_AES_CBC);
|
||||||
ASSERT_TRUE(aes_cbc != NULL);
|
ASSERT_TRUE(aes_cbc != NULL);
|
||||||
|
|
||||||
@ -62,7 +70,7 @@ TEST(RequiredBlockCiphers, BlockCipher) {
|
|||||||
ASSERT_TRUE(bf_cbc != NULL);
|
ASSERT_TRUE(bf_cbc != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(RequiredStreamCiphers, StreamCipher) {
|
TEST_F(BlockCipherTest, RequiredStreamCiphers) {
|
||||||
auto aes_cfb = StreamCipher::GetRegistry().CreateForMatch(NAME_AES_CFB);
|
auto aes_cfb = StreamCipher::GetRegistry().CreateForMatch(NAME_AES_CFB);
|
||||||
ASSERT_TRUE(aes_cfb != NULL);
|
ASSERT_TRUE(aes_cfb != NULL);
|
||||||
|
|
||||||
@ -84,6 +92,7 @@ void checkTestVector(const char *cipherName,
|
|||||||
|
|
||||||
CipherKey key(strlen(hexKey)/2);
|
CipherKey key(strlen(hexKey)/2);
|
||||||
setDataFromHex(key.data(), key.size(), hexKey);
|
setDataFromHex(key.data(), key.size(), hexKey);
|
||||||
|
|
||||||
ASSERT_TRUE(cipher->setKey(key));
|
ASSERT_TRUE(cipher->setKey(key));
|
||||||
|
|
||||||
byte iv[strlen(hexIv)/2];
|
byte iv[strlen(hexIv)/2];
|
||||||
@ -93,6 +102,9 @@ void checkTestVector(const char *cipherName,
|
|||||||
setDataFromHex(plaintext, sizeof(plaintext), hexPlaintext);
|
setDataFromHex(plaintext, sizeof(plaintext), hexPlaintext);
|
||||||
|
|
||||||
byte ciphertext[sizeof(plaintext)];
|
byte ciphertext[sizeof(plaintext)];
|
||||||
|
|
||||||
|
// Run test in a loop with the same cipher, since that's how we use it later.
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
ASSERT_TRUE(cipher->encrypt(iv, plaintext, ciphertext, sizeof(ciphertext)));
|
ASSERT_TRUE(cipher->encrypt(iv, plaintext, ciphertext, sizeof(ciphertext)));
|
||||||
|
|
||||||
ASSERT_EQ(hexCipher, stringToHex(ciphertext, sizeof(ciphertext)));
|
ASSERT_EQ(hexCipher, stringToHex(ciphertext, sizeof(ciphertext)));
|
||||||
@ -103,9 +115,10 @@ void checkTestVector(const char *cipherName,
|
|||||||
for (unsigned int i = 0; i < sizeof(plaintext); ++i) {
|
for (unsigned int i = 0; i < sizeof(plaintext); ++i) {
|
||||||
ASSERT_EQ(plaintext[i], decypered[i]);
|
ASSERT_EQ(plaintext[i], decypered[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TestVectors, BlockCipher) {
|
TEST_F(BlockCipherTest, TestVectors) {
|
||||||
// BF128 CBC
|
// BF128 CBC
|
||||||
checkTestVector<BlockCipher>(NAME_BLOWFISH_CBC,
|
checkTestVector<BlockCipher>(NAME_BLOWFISH_CBC,
|
||||||
"0123456789abcdeff0e1d2c3b4a59687",
|
"0123456789abcdeff0e1d2c3b4a59687",
|
||||||
@ -149,7 +162,7 @@ TEST(TestVectors, BlockCipher) {
|
|||||||
"dc7e84bfda79164b7ecd8486985d3860");
|
"dc7e84bfda79164b7ecd8486985d3860");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BlockEncryptionTest, BlockCipher) {
|
TEST_F(BlockCipherTest, BlockEncryptionTest) {
|
||||||
Registry<BlockCipher> registry = BlockCipher::GetRegistry();
|
Registry<BlockCipher> registry = BlockCipher::GetRegistry();
|
||||||
|
|
||||||
shared_ptr<PBKDF> pbkdf(
|
shared_ptr<PBKDF> pbkdf(
|
||||||
|
@ -15,6 +15,7 @@ elseif (WITH_BOTAN)
|
|||||||
find_package (Botan REQUIRED)
|
find_package (Botan REQUIRED)
|
||||||
set (EXTRA_LIBS ${BOTAN_LIBRARIES})
|
set (EXTRA_LIBS ${BOTAN_LIBRARIES})
|
||||||
set (EXTRA_SOURCE botan.cpp)
|
set (EXTRA_SOURCE botan.cpp)
|
||||||
|
include_directories (${BOTAN_INCLUDE_DIR})
|
||||||
endif (WITH_COMMON_CRYPTO)
|
endif (WITH_COMMON_CRYPTO)
|
||||||
|
|
||||||
add_library (encfs-cipher
|
add_library (encfs-cipher
|
||||||
|
@ -19,9 +19,17 @@ using std::string;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
TEST(CipherKey, ReadWrite) {
|
class CipherKeyTest : public testing::Test {
|
||||||
|
protected:
|
||||||
|
virtual void SetUp() {
|
||||||
|
CipherV1::init(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(CipherKeyTest, ReadWrite) {
|
||||||
for (auto alg : CipherV1::GetAlgorithmList()) {
|
for (auto alg : CipherV1::GetAlgorithmList()) {
|
||||||
auto cipher = CipherV1::New(alg.iface);
|
auto cipher = CipherV1::New(alg.iface);
|
||||||
|
ASSERT_FALSE(!cipher);
|
||||||
|
|
||||||
CipherKey masterKey = cipher->newRandomKey();
|
CipherKey masterKey = cipher->newRandomKey();
|
||||||
CipherKey volumeKey = cipher->newRandomKey();
|
CipherKey volumeKey = cipher->newRandomKey();
|
||||||
|
@ -297,6 +297,8 @@ bool CipherV1::initCiphers(const Interface &iface, const Interface &realIface,
|
|||||||
else
|
else
|
||||||
_keySize = keyRange.closest(keyLength) / 8;
|
_keySize = keyRange.closest(keyLength) / 8;
|
||||||
|
|
||||||
|
LOG_IF(ERROR, _keySize == 0) << "invalid key size";
|
||||||
|
|
||||||
_pbkdf.reset(PBKDF::GetRegistry().CreateForMatch(
|
_pbkdf.reset(PBKDF::GetRegistry().CreateForMatch(
|
||||||
NAME_PBKDF2_HMAC_SHA1));
|
NAME_PBKDF2_HMAC_SHA1));
|
||||||
if (!_pbkdf) {
|
if (!_pbkdf) {
|
||||||
@ -405,6 +407,9 @@ bool CipherV1::pseudoRandomize( byte *buf, int len )
|
|||||||
bool CipherV1::setKey(const CipherKey &keyIv) {
|
bool CipherV1::setKey(const CipherKey &keyIv) {
|
||||||
Lock l(_hmacMutex);
|
Lock l(_hmacMutex);
|
||||||
|
|
||||||
|
LOG_IF(ERROR, _keySize != keyIv.size()) << "Mismatched key size: passed "
|
||||||
|
<< keyIv.size() << ", expecting " << _keySize;
|
||||||
|
|
||||||
// Key is actually key plus iv, so extract the different parts.
|
// Key is actually key plus iv, so extract the different parts.
|
||||||
CipherKey key(_keySize);
|
CipherKey key(_keySize);
|
||||||
memcpy(key.data(), keyIv.data(), _keySize);
|
memcpy(key.data(), keyIv.data(), _keySize);
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
|
|
||||||
#ifdef WITH_BOTAN
|
#ifdef WITH_BOTAN
|
||||||
# include <botan/botan.h>
|
# include <botan/botan.h>
|
||||||
|
# include <botan/version.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace encfs {
|
namespace encfs {
|
||||||
@ -104,13 +105,33 @@ MemBlock::~MemBlock()
|
|||||||
delete[] data;
|
delete[] data;
|
||||||
}
|
}
|
||||||
|
|
||||||
SecureMem::SecureMem(int len)
|
|
||||||
#ifdef WITH_BOTAN
|
#ifdef WITH_BOTAN
|
||||||
: data_(len)
|
SecureMem::SecureMem(int len)
|
||||||
#endif
|
: data_(new Botan::SecureVector<unsigned char>(len))
|
||||||
|
{
|
||||||
|
rAssert(len > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SecureMem::~SecureMem()
|
||||||
|
{
|
||||||
|
# if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
|
||||||
|
data_->destroy();
|
||||||
|
# endif
|
||||||
|
delete data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte* SecureMem::data() const {
|
||||||
|
return const_cast<byte*>(data_->begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
int SecureMem::size() const {
|
||||||
|
return data_->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
SecureMem::SecureMem(int len)
|
||||||
{
|
{
|
||||||
rAssert(len > 0);
|
rAssert(len > 0);
|
||||||
#ifndef WITH_BOTAN
|
|
||||||
data_ = allocBlock(len);
|
data_ = allocBlock(len);
|
||||||
if (data_)
|
if (data_)
|
||||||
{
|
{
|
||||||
@ -120,14 +141,10 @@ SecureMem::SecureMem(int len)
|
|||||||
{
|
{
|
||||||
size_ = 0;
|
size_ = 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SecureMem::~SecureMem()
|
SecureMem::~SecureMem()
|
||||||
{
|
{
|
||||||
#ifdef WITH_BOTAN
|
|
||||||
data_.destroy();
|
|
||||||
#else
|
|
||||||
if (size_)
|
if (size_)
|
||||||
{
|
{
|
||||||
cleanBlock(data_, size_);
|
cleanBlock(data_, size_);
|
||||||
@ -137,8 +154,8 @@ SecureMem::~SecureMem()
|
|||||||
data_ = NULL;
|
data_ = NULL;
|
||||||
size_ = 0;
|
size_ = 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool operator == (const SecureMem &a, const SecureMem &b) {
|
bool operator == (const SecureMem &a, const SecureMem &b) {
|
||||||
return (a.size() == b.size()) &&
|
return (a.size() == b.size()) &&
|
||||||
|
@ -25,7 +25,9 @@
|
|||||||
#include "base/types.h"
|
#include "base/types.h"
|
||||||
|
|
||||||
#ifdef WITH_BOTAN
|
#ifdef WITH_BOTAN
|
||||||
#include <botan/secmem.h>
|
namespace Botan {
|
||||||
|
template <typename T> class SecureVector;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace encfs {
|
namespace encfs {
|
||||||
@ -69,21 +71,14 @@ class SecureMem
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef WITH_BOTAN
|
#ifdef WITH_BOTAN
|
||||||
Botan::SecureVector<Botan::byte> data_;
|
Botan::SecureVector<unsigned char> *data_;
|
||||||
#else
|
#else
|
||||||
byte *data_;
|
byte *data_;
|
||||||
int size_;
|
int size_;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef WITH_BOTAN
|
#ifndef WITH_BOTAN
|
||||||
inline byte* SecureMem::data() const {
|
|
||||||
return const_cast<byte*>(data_.begin());
|
|
||||||
}
|
|
||||||
inline int SecureMem::size() const {
|
|
||||||
return data_.size();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
inline byte* SecureMem::data() const {
|
inline byte* SecureMem::data() const {
|
||||||
return data_;
|
return data_;
|
||||||
}
|
}
|
||||||
|
197
cipher/botan.cpp
197
cipher/botan.cpp
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "cipher/botan.h"
|
#include "cipher/botan.h"
|
||||||
#include "base/config.h"
|
#include "base/config.h"
|
||||||
|
#include "base/shared_ptr.h"
|
||||||
|
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
#include <botan/botan.h>
|
#include <botan/botan.h>
|
||||||
@ -35,9 +36,14 @@
|
|||||||
#include "cipher/PBKDF.h"
|
#include "cipher/PBKDF.h"
|
||||||
#include "cipher/StreamCipher.h"
|
#include "cipher/StreamCipher.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
||||||
|
#include <valgrind/memcheck.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
using namespace Botan;
|
using namespace Botan;
|
||||||
|
using std::string;
|
||||||
|
|
||||||
namespace encfs {
|
namespace encfs {
|
||||||
namespace botan {
|
namespace botan {
|
||||||
@ -115,6 +121,197 @@ class PbkdfPkcs5HmacSha256 : public PbkdfPkcs5Hmac {
|
|||||||
REGISTER_CLASS(PbkdfPkcs5HmacSha256, PBKDF);
|
REGISTER_CLASS(PbkdfPkcs5HmacSha256, PBKDF);
|
||||||
|
|
||||||
|
|
||||||
|
class BotanBlockCipher : public BlockCipher {
|
||||||
|
Keyed_Filter *encryption; // Not owned.
|
||||||
|
Keyed_Filter *decryption; // Not owned.
|
||||||
|
shared_ptr<Pipe> encryptor;
|
||||||
|
shared_ptr<Pipe> decryptor;
|
||||||
|
public:
|
||||||
|
BotanBlockCipher() {}
|
||||||
|
virtual ~BotanBlockCipher() {}
|
||||||
|
|
||||||
|
bool rekey(const CipherKey& key, const string& cipherMode) {
|
||||||
|
SymmetricKey bkey(key.data(), key.size());
|
||||||
|
OctetString iv;
|
||||||
|
encryption = Botan::get_cipher(cipherMode, bkey, iv, Botan::ENCRYPTION);
|
||||||
|
decryption = Botan::get_cipher(cipherMode, bkey, iv, Botan::DECRYPTION);
|
||||||
|
if (encryption == nullptr || decryption == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
encryptor.reset(new Pipe(encryption));
|
||||||
|
decryptor.reset(new Pipe(decryption));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool encrypt(const byte* iv, const byte* in, byte* out, int size) {
|
||||||
|
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
||||||
|
if (VALGRIND_CHECK_MEM_IS_ADDRESSABLE(in, size) != 0 ||
|
||||||
|
VALGRIND_CHECK_MEM_IS_ADDRESSABLE(out, size) != 0 ||
|
||||||
|
VALGRIND_CHECK_MEM_IS_ADDRESSABLE(iv, blockSize())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
encryption->set_iv(OctetString(iv, blockSize()));
|
||||||
|
encryptor->process_msg(in, size);
|
||||||
|
auto written = encryptor->read(out, size, Pipe::LAST_MESSAGE);
|
||||||
|
LOG_IF(ERROR, (int)written != size) << "expected output size " << size
|
||||||
|
<< ", got " << written;
|
||||||
|
LOG_IF(ERROR, encryptor->remaining() > 0) << "unread bytes in pipe: "
|
||||||
|
<< encryptor->remaining();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool decrypt(const byte* iv, const byte* in, byte* out, int size) {
|
||||||
|
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
||||||
|
if (VALGRIND_CHECK_MEM_IS_ADDRESSABLE(in, size) != 0 ||
|
||||||
|
VALGRIND_CHECK_MEM_IS_ADDRESSABLE(out, size) != 0 ||
|
||||||
|
VALGRIND_CHECK_MEM_IS_ADDRESSABLE(iv, blockSize())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
decryption->set_iv(OctetString(iv, blockSize()));
|
||||||
|
decryptor->process_msg(in, size);
|
||||||
|
auto written = decryptor->read(out, size, Pipe::LAST_MESSAGE);
|
||||||
|
LOG_IF(ERROR, (int)written != size) << "expected output size " << size
|
||||||
|
<< ", got " << written;
|
||||||
|
LOG_IF(ERROR, encryptor->remaining() > 0) << "unread bytes in pipe: "
|
||||||
|
<< encryptor->remaining();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class BotanAesCbc : public BotanBlockCipher {
|
||||||
|
public:
|
||||||
|
BotanAesCbc() {}
|
||||||
|
virtual ~BotanAesCbc() {}
|
||||||
|
|
||||||
|
virtual bool setKey(const CipherKey& key) {
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << "AES-" << (key.size() * 8) << "/CBC/NoPadding";
|
||||||
|
return rekey(key, ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int blockSize() const {
|
||||||
|
return 128 >> 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Properties GetProperties() {
|
||||||
|
return Properties(Range(128,256,64), "AES", "CBC", "Botan");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
REGISTER_CLASS(BotanAesCbc, BlockCipher);
|
||||||
|
|
||||||
|
class BotanAesCfb : public BotanBlockCipher {
|
||||||
|
public:
|
||||||
|
BotanAesCfb() {}
|
||||||
|
virtual ~BotanAesCfb() {}
|
||||||
|
|
||||||
|
virtual bool setKey(const CipherKey& key) {
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << "AES-" << (key.size() * 8) << "/CFB";
|
||||||
|
return rekey(key, ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int blockSize() const {
|
||||||
|
return 128 >> 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Properties GetProperties() {
|
||||||
|
return Properties(Range(128,256,64), "AES", "CFB", "Botan");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
REGISTER_CLASS(BotanAesCfb, StreamCipher);
|
||||||
|
|
||||||
|
class BotanBlowfishCbc : public BotanBlockCipher {
|
||||||
|
public:
|
||||||
|
BotanBlowfishCbc() {}
|
||||||
|
virtual ~BotanBlowfishCbc() {}
|
||||||
|
|
||||||
|
virtual bool setKey(const CipherKey& key) {
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << "Blowfish" << "/CBC/NoPadding";
|
||||||
|
return rekey(key, ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int blockSize() const {
|
||||||
|
return 64 >> 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Properties GetProperties() {
|
||||||
|
return Properties(Range(128,256,32), "Blowfish", "CBC", "Botan");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
REGISTER_CLASS(BotanBlowfishCbc, BlockCipher);
|
||||||
|
|
||||||
|
class BotanBlowfishCfb : public BotanBlockCipher {
|
||||||
|
public:
|
||||||
|
BotanBlowfishCfb() {}
|
||||||
|
virtual ~BotanBlowfishCfb() {}
|
||||||
|
|
||||||
|
virtual bool setKey(const CipherKey& key) {
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << "Blowfish" << "/CFB";
|
||||||
|
return rekey(key, ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int blockSize() const {
|
||||||
|
return 64 >> 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Properties GetProperties() {
|
||||||
|
return Properties(Range(128,256,32), "Blowfish", "CFB", "Botan");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
REGISTER_CLASS(BotanBlowfishCfb, StreamCipher);
|
||||||
|
|
||||||
|
|
||||||
|
class Sha1HMac : public MAC {
|
||||||
|
MessageAuthenticationCode *mac;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Sha1HMac() : mac(Botan::get_mac("HMAC(SHA-1)")) {}
|
||||||
|
virtual ~Sha1HMac() {
|
||||||
|
delete mac;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int outputSize() const {
|
||||||
|
return mac->output_length();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool setKey(const CipherKey &key) {
|
||||||
|
SymmetricKey bkey(key.data(), key.size());
|
||||||
|
mac->set_key(bkey);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void init() {
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool update(const byte *in, int length) {
|
||||||
|
mac->update(in, length);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool write(byte *out) {
|
||||||
|
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
||||||
|
if (VALGRIND_CHECK_MEM_IS_ADDRESSABLE(out, outputSize()) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
mac->final(out);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Properties GetProperties() {
|
||||||
|
Properties props;
|
||||||
|
props.blockSize = 160 >> 3;
|
||||||
|
props.hashFunction = "SHA-1";
|
||||||
|
props.mode = "HMAC";
|
||||||
|
props.library = "Botan";
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
REGISTER_CLASS(Sha1HMac, MAC);
|
||||||
|
|
||||||
} // namespace botan
|
} // namespace botan
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user