Add source code for ctrtool

This commit is contained in:
jakcron
2022-03-12 16:00:33 +08:00
parent 6ad2f13c50
commit 800f5776bc
681 changed files with 219734 additions and 0 deletions
@@ -0,0 +1,328 @@
#include <tc/crypto/Aes128CbcEncryptedStream.h>
#include <tc/io/IOUtil.h>
#include <tc/io/StreamUtil.h>
/*
#include <fmt/core.h>
#include <tc/cli/FormatUtil.h>
*/
// inline utils
inline uint64_t castInt64ToUint64(int64_t val) { return val < 0 ? 0 : uint64_t(val); }
inline int64_t castUint64ToInt64(uint64_t val) { return (int64_t)std::min<uint64_t>(val, uint64_t(std::numeric_limits<int64_t>::max())); }
inline uint64_t offsetToBlockIndex(int64_t offset) { return castInt64ToUint64(offset / tc::io::IOUtil::castSizeToInt64(tc::crypto::Aes128CbcEncryptor::kBlockSize)); };
inline int64_t blockIndexToOffset(uint64_t block_index) { return castUint64ToInt64(block_index) * tc::io::IOUtil::castSizeToInt64(tc::crypto::Aes128CbcEncryptor::kBlockSize); };
inline size_t lengthToBlockNum(int64_t length) { return tc::io::IOUtil::castInt64ToSize(length / tc::io::IOUtil::castSizeToInt64(tc::crypto::Aes128CbcEncryptor::kBlockSize)); };
inline size_t offsetInBlock(int64_t offset) { return tc::io::IOUtil::castInt64ToSize(offset % tc::io::IOUtil::castSizeToInt64(tc::crypto::Aes128CbcEncryptor::kBlockSize)); };
const std::string tc::crypto::Aes128CbcEncryptedStream::kClassName = "tc::crypto::Aes128CbcEncryptedStream";
tc::crypto::Aes128CbcEncryptedStream::Aes128CbcEncryptedStream() :
mBaseStream(),
mCryptor(std::shared_ptr<tc::crypto::Aes128CbcEncryptor>(new tc::crypto::Aes128CbcEncryptor()))
{
memset(mBaseIv.data(), 0, mBaseIv.size());
}
tc::crypto::Aes128CbcEncryptedStream::Aes128CbcEncryptedStream(const std::shared_ptr<tc::io::IStream>& stream, const key_t& key, const iv_t& iv) :
Aes128CbcEncryptedStream()
{
mBaseStream = stream;
// validate stream properties
if (mBaseStream == nullptr)
{
throw tc::ObjectDisposedException(kClassName, "stream is null.");
}
if (mBaseStream->canRead() == false)
{
throw tc::NotSupportedException(kClassName, "stream does not support reading.");
}
if (mBaseStream->canSeek() == false)
{
throw tc::NotSupportedException(kClassName, "stream does not support seeking.");
}
if ((mBaseStream->length() % sizeof(block_t)) != 0)
{
throw tc::NotSupportedException(kClassName, "stream does is not block aligned.");
}
// initialize cryptor
mCryptor->initialize(key.data(), key.size(), iv.data(), iv.size());
mBaseIv = iv;
}
bool tc::crypto::Aes128CbcEncryptedStream::canRead() const
{
return mBaseStream == nullptr ? false : mBaseStream->canRead();
}
bool tc::crypto::Aes128CbcEncryptedStream::canWrite() const
{
return false; // always false this is a read-only stream
}
bool tc::crypto::Aes128CbcEncryptedStream::canSeek() const
{
return mBaseStream == nullptr ? false : mBaseStream->canSeek();
}
int64_t tc::crypto::Aes128CbcEncryptedStream::length()
{
return mBaseStream == nullptr ? 0 : mBaseStream->length();
}
int64_t tc::crypto::Aes128CbcEncryptedStream::position()
{
return mBaseStream == nullptr ? 0 : mBaseStream->position();
}
size_t tc::crypto::Aes128CbcEncryptedStream::read(byte_t* ptr, size_t count)
{
if (mBaseStream == nullptr)
{
throw tc::ObjectDisposedException(kClassName+"::read()", "Failed to read from stream (stream is disposed)");
}
// track read_count
size_t data_read_count = 0;
// get predicted read count
count = tc::io::IOUtil::getReadableCount(this->length(), this->position(), count);
// if count is 0 just return
if (count == 0) return data_read_count;
// get current position
int64_t current_pos = mBaseStream->position();
if (current_pos < 0)
{
throw tc::InvalidOperationException(kClassName+"::read()", "Current stream position is negative.");
}
// determine begin & end offsets
int64_t begin_read_offset = current_pos;
int64_t end_read_offset = begin_read_offset + tc::io::IOUtil::castSizeToInt64(count);
int64_t begin_aligned_offset = begin_read_offset - tc::io::IOUtil::castSizeToInt64(offsetInBlock(begin_read_offset));
int64_t end_aligned_offset = end_read_offset - tc::io::IOUtil::castSizeToInt64(offsetInBlock(end_read_offset)) + tc::io::IOUtil::castSizeToInt64(offsetInBlock(end_read_offset) ? sizeof(block_t) : 0x0);
size_t block_num = lengthToBlockNum(end_aligned_offset - begin_aligned_offset);
bool read_partial_begin_block = false;
uint64_t partial_begin_block_index = offsetToBlockIndex(begin_read_offset);
size_t partial_begin_block_offset = 0;
size_t partial_begin_block_size = sizeof(block_t);
bool read_partial_end_block = false;
uint64_t partial_end_block_index = offsetToBlockIndex(end_read_offset);
size_t partial_end_block_offset = 0;
size_t partial_end_block_size = sizeof(block_t);
if (offsetInBlock(begin_read_offset) != 0)
{
read_partial_begin_block = true;
partial_begin_block_offset += offsetInBlock(begin_read_offset);
partial_begin_block_size -= partial_begin_block_offset;
}
if (offsetInBlock(end_read_offset) != 0)
{
if (partial_begin_block_index == partial_end_block_index)
{
read_partial_begin_block = true;
partial_begin_block_size -= (sizeof(block_t) - offsetInBlock(end_read_offset));
}
else
{
read_partial_end_block = true;
partial_end_block_size = offsetInBlock(end_read_offset);
}
}
size_t continuous_block_num = block_num - (size_t)read_partial_begin_block - (size_t)read_partial_end_block;
uint64_t continuous_begin_block_index = (continuous_block_num == 0) ? 0 : (offsetToBlockIndex(begin_aligned_offset) + (uint64_t)read_partial_begin_block);
/*
fmt::print("##############################################\n");
fmt::print("count: 0x{:x}\n", count);
fmt::print("begin_read_offset: 0x{:x}\n", begin_read_offset);
fmt::print("end_read_offset: 0x{:x}\n", end_read_offset);
fmt::print("begin_aligned_offset: 0x{:x}\n", begin_aligned_offset);
fmt::print("end_aligned_offset: 0x{:x}\n", end_aligned_offset);
fmt::print("block_num: 0x{:x}\n", block_num);
fmt::print("partial_begin:\n");
fmt::print(" read_block: {}\n", read_partial_begin_block);
fmt::print(" block_index: 0x{:x}\n", partial_begin_block_index);
fmt::print(" offset: 0x{:x}\n", partial_begin_block_offset);
fmt::print(" size: 0x{:x}\n", partial_begin_block_size);
fmt::print("partial_end:\n");
fmt::print(" read_block: {}\n", read_partial_end_block);
fmt::print(" block_index: 0x{:x}\n", partial_end_block_index);
fmt::print(" offset: 0x{:x}\n", partial_end_block_offset);
fmt::print(" size: 0x{:x}\n", partial_end_block_size);
fmt::print("continuous:\n");
fmt::print(" block_index: 0x{:x}\n", continuous_begin_block_index);
fmt::print(" block_num: 0x{:x}\n", continuous_block_num);
*/
if (block_num == 0)
{
tc::InvalidOperationException(kClassName+"::read()", "Invalid block number (0 blocks, would have returned before now if count==0)");
}
if (block_num < continuous_block_num)
{
tc::InvalidOperationException(kClassName+"::read()", "Invalid block number (underflow error)");
}
// allocate memory for partial block
tc::ByteData partial_block = tc::ByteData(sizeof(block_t));
// read un-aligned begin block
if (read_partial_begin_block)
{
// read iv
iv_t iv;
if (partial_begin_block_index == 0)
{
iv = mBaseIv;
}
else
{
this->seek(blockIndexToOffset(partial_begin_block_index-1), tc::io::SeekOrigin::Begin);
mBaseStream->read(iv.data(), iv.size());
}
mCryptor->update_iv(iv.data(), iv.size());
// read block
this->seek(blockIndexToOffset(partial_begin_block_index), tc::io::SeekOrigin::Begin);
mBaseStream->read(partial_block.data(), partial_block.size());
// decrypt block
mCryptor->decrypt(partial_block.data(), partial_block.data(), partial_block.size());
// copy out block carving
memcpy(ptr + data_read_count, partial_block.data() + partial_begin_block_offset, partial_begin_block_size);
// increment data read count
data_read_count += partial_begin_block_size;
}
// read continous blocks
if (continuous_block_num > 0)
{
// read iv
iv_t iv;
if (continuous_begin_block_index == 0)
{
iv = mBaseIv;
}
else
{
this->seek(blockIndexToOffset(continuous_begin_block_index-1), tc::io::SeekOrigin::Begin);
mBaseStream->read(iv.data(), iv.size());
}
mCryptor->update_iv(iv.data(), iv.size());
// read blocks
this->seek(blockIndexToOffset(continuous_begin_block_index), tc::io::SeekOrigin::Begin);
mBaseStream->read(ptr + data_read_count, continuous_block_num * sizeof(block_t));
// decrypt blocks
mCryptor->decrypt(ptr + data_read_count, ptr + data_read_count, continuous_block_num * sizeof(block_t));
// increment data read count
data_read_count += continuous_block_num * sizeof(block_t);
}
// read un-aligned end block
if (read_partial_end_block)
{
// read iv
iv_t iv;
if (partial_end_block_index == 0)
{
iv = mBaseIv;
}
else
{
this->seek(blockIndexToOffset(partial_end_block_index-1), tc::io::SeekOrigin::Begin);
mBaseStream->read(iv.data(), iv.size());
}
mCryptor->update_iv(iv.data(), iv.size());
// read block
this->seek(blockIndexToOffset(partial_end_block_index), tc::io::SeekOrigin::Begin);
mBaseStream->read(partial_block.data(), partial_block.size());
// decrypt block
mCryptor->decrypt(partial_block.data(), partial_block.data(), partial_block.size());
// copy out block carving
memcpy(ptr + data_read_count, partial_block.data() + partial_end_block_offset, partial_end_block_size);
// increment
data_read_count += partial_end_block_size;
}
// restore expected logical position
this->seek(begin_read_offset + tc::io::IOUtil::castSizeToInt64(data_read_count), tc::io::SeekOrigin::Begin);
// return data read count
return data_read_count;
}
size_t tc::crypto::Aes128CbcEncryptedStream::write(const byte_t* ptr, size_t count)
{
if (mBaseStream == nullptr)
{
throw tc::ObjectDisposedException(kClassName+"::write()", "Failed to set stream position (stream is disposed)");
}
throw tc::NotImplementedException(kClassName+"::write()", "write is not implemented for Aes128CbcEncryptedStream");
}
int64_t tc::crypto::Aes128CbcEncryptedStream::seek(int64_t offset, tc::io::SeekOrigin origin)
{
if (mBaseStream == nullptr)
{
throw tc::ObjectDisposedException(kClassName+"::seek()", "Failed to set stream position (stream is disposed)");
}
return mBaseStream->seek(offset, origin);
}
void tc::crypto::Aes128CbcEncryptedStream::setLength(int64_t length)
{
if (mBaseStream == nullptr)
{
throw tc::ObjectDisposedException(kClassName+"::setLength()", "Failed to set stream length (stream is disposed)");
}
throw tc::NotImplementedException(kClassName+"::setLength()", "setLength is not implemented for Aes128CbcEncryptedStream");
}
void tc::crypto::Aes128CbcEncryptedStream::flush()
{
if (mBaseStream == nullptr)
{
throw tc::ObjectDisposedException(kClassName+"::seek()", "Failed to flush stream (stream is disposed)");
}
mBaseStream->flush();
}
void tc::crypto::Aes128CbcEncryptedStream::dispose()
{
if (mBaseStream.get() != nullptr)
{
// dispose base stream
mBaseStream->dispose();
// release ptr
mBaseStream.reset();
}
}
@@ -0,0 +1,15 @@
#include <tc/crypto/Aes128CbcEncryptor.h>
void tc::crypto::EncryptAes128Cbc(byte_t* dst, const byte_t* src, size_t size, const byte_t* key, size_t key_size, const byte_t* iv, size_t iv_size)
{
tc::crypto::Aes128CbcEncryptor crypt;
crypt.initialize(key, key_size, iv, iv_size);
crypt.encrypt(dst, src, size);
}
void tc::crypto::DecryptAes128Cbc(byte_t* dst, const byte_t* src, size_t size, const byte_t* key, size_t key_size, const byte_t* iv, size_t iv_size)
{
tc::crypto::Aes128CbcEncryptor crypt;
crypt.initialize(key, key_size, iv, iv_size);
crypt.decrypt(dst, src, size);
}
@@ -0,0 +1,284 @@
#include <tc/crypto/Aes128CtrEncryptedStream.h>
#include <tc/io/IOUtil.h>
#include <tc/io/StreamUtil.h>
/*
#include <fmt/core.h>
#include <tc/cli/FormatUtil.h>
*/
// inline utils
inline uint64_t castInt64ToUint64(int64_t val) { return val < 0 ? 0 : uint64_t(val); }
inline int64_t castUint64ToInt64(uint64_t val) { return (int64_t)std::min<uint64_t>(val, uint64_t(std::numeric_limits<int64_t>::max())); }
inline uint64_t offsetToBlockIndex(int64_t offset) { return castInt64ToUint64(offset / tc::io::IOUtil::castSizeToInt64(tc::crypto::Aes128CtrEncryptor::kBlockSize)); };
inline int64_t blockIndexToOffset(uint64_t block_index) { return castUint64ToInt64(block_index) * tc::io::IOUtil::castSizeToInt64(tc::crypto::Aes128CtrEncryptor::kBlockSize); };
inline size_t lengthToBlockNum(int64_t length) { return tc::io::IOUtil::castInt64ToSize(length / tc::io::IOUtil::castSizeToInt64(tc::crypto::Aes128CtrEncryptor::kBlockSize)); };
inline size_t offsetInBlock(int64_t offset) { return tc::io::IOUtil::castInt64ToSize(offset % tc::io::IOUtil::castSizeToInt64(tc::crypto::Aes128CtrEncryptor::kBlockSize)); };
const std::string tc::crypto::Aes128CtrEncryptedStream::kClassName = "tc::crypto::Aes128CtrEncryptedStream";
tc::crypto::Aes128CtrEncryptedStream::Aes128CtrEncryptedStream() :
mBaseStream(),
mCryptor(std::shared_ptr<tc::crypto::Aes128CtrEncryptor>(new tc::crypto::Aes128CtrEncryptor()))
{
}
tc::crypto::Aes128CtrEncryptedStream::Aes128CtrEncryptedStream(const std::shared_ptr<tc::io::IStream>& stream, const key_t& key, const counter_t& counter) :
Aes128CtrEncryptedStream()
{
mBaseStream = stream;
// validate stream properties
if (mBaseStream == nullptr)
{
throw tc::ObjectDisposedException(kClassName, "stream is null.");
}
if (mBaseStream->canRead() == false)
{
throw tc::NotSupportedException(kClassName, "stream does not support reading.");
}
if (mBaseStream->canSeek() == false)
{
throw tc::NotSupportedException(kClassName, "stream does not support seeking.");
}
// initialize cryptor
mCryptor->initialize(key.data(), key.size(), counter.data(), counter.size());
}
bool tc::crypto::Aes128CtrEncryptedStream::canRead() const
{
return mBaseStream == nullptr ? false : mBaseStream->canRead();
}
bool tc::crypto::Aes128CtrEncryptedStream::canWrite() const
{
return false; // always false this is a read-only stream
}
bool tc::crypto::Aes128CtrEncryptedStream::canSeek() const
{
return mBaseStream == nullptr ? false : mBaseStream->canSeek();
}
int64_t tc::crypto::Aes128CtrEncryptedStream::length()
{
return mBaseStream == nullptr ? 0 : mBaseStream->length();
}
int64_t tc::crypto::Aes128CtrEncryptedStream::position()
{
return mBaseStream == nullptr ? 0 : mBaseStream->position();
}
size_t tc::crypto::Aes128CtrEncryptedStream::read(byte_t* ptr, size_t count)
{
if (mBaseStream == nullptr)
{
throw tc::ObjectDisposedException(kClassName+"::read()", "Failed to read from stream (stream is disposed)");
}
// track read_count
size_t data_read_count = 0;
// get predicted read count
count = tc::io::IOUtil::getReadableCount(this->length(), this->position(), count);
// if count is 0 just return
if (count == 0) return data_read_count;
// get current position
int64_t current_pos = mBaseStream->position();
if (current_pos < 0)
{
throw tc::InvalidOperationException(kClassName+"::read()", "Current stream position is negative.");
}
// determine begin & end offsets
int64_t begin_read_offset = current_pos;
int64_t end_read_offset = begin_read_offset + tc::io::IOUtil::castSizeToInt64(count);
int64_t begin_aligned_offset = begin_read_offset - tc::io::IOUtil::castSizeToInt64(offsetInBlock(begin_read_offset));
int64_t end_aligned_offset = end_read_offset - tc::io::IOUtil::castSizeToInt64(offsetInBlock(end_read_offset)) + tc::io::IOUtil::castSizeToInt64(offsetInBlock(end_read_offset) ? sizeof(block_t) : 0x0);
size_t block_num = lengthToBlockNum(end_aligned_offset - begin_aligned_offset);
bool read_partial_begin_block = false;
uint64_t partial_begin_block_index = offsetToBlockIndex(begin_read_offset);
size_t partial_begin_block_offset = 0;
size_t partial_begin_block_size = sizeof(block_t);
bool read_partial_end_block = false;
uint64_t partial_end_block_index = offsetToBlockIndex(end_read_offset);
size_t partial_end_block_offset = 0;
size_t partial_end_block_size = sizeof(block_t);
if (offsetInBlock(begin_read_offset) != 0)
{
read_partial_begin_block = true;
partial_begin_block_offset += offsetInBlock(begin_read_offset);
partial_begin_block_size -= partial_begin_block_offset;
}
if (offsetInBlock(end_read_offset) != 0)
{
if (partial_begin_block_index == partial_end_block_index)
{
read_partial_begin_block = true;
partial_begin_block_size -= (sizeof(block_t) - offsetInBlock(end_read_offset));
}
else
{
read_partial_end_block = true;
partial_end_block_size = offsetInBlock(end_read_offset);
}
}
size_t continuous_block_num = block_num - (size_t)read_partial_begin_block - (size_t)read_partial_end_block;
uint64_t continuous_begin_block_index = (continuous_block_num == 0) ? 0 : (offsetToBlockIndex(begin_aligned_offset) + (uint64_t)read_partial_begin_block);
/*
fmt::print("##############################################\n");
fmt::print("count: 0x{:x}\n", count);
fmt::print("begin_read_offset: 0x{:x}\n", begin_read_offset);
fmt::print("end_read_offset: 0x{:x}\n", end_read_offset);
fmt::print("begin_aligned_offset: 0x{:x}\n", begin_aligned_offset);
fmt::print("end_aligned_offset: 0x{:x}\n", end_aligned_offset);
fmt::print("block_num: 0x{:x}\n", block_num);
fmt::print("partial_begin:\n");
fmt::print(" read_block: {}\n", read_partial_begin_block);
fmt::print(" block_index: 0x{:x}\n", partial_begin_block_index);
fmt::print(" offset: 0x{:x}\n", partial_begin_block_offset);
fmt::print(" size: 0x{:x}\n", partial_begin_block_size);
fmt::print("partial_end:\n");
fmt::print(" read_block: {}\n", read_partial_end_block);
fmt::print(" block_index: 0x{:x}\n", partial_end_block_index);
fmt::print(" offset: 0x{:x}\n", partial_end_block_offset);
fmt::print(" size: 0x{:x}\n", partial_end_block_size);
fmt::print("continuous:\n");
fmt::print(" block_index: 0x{:x}\n", continuous_begin_block_index);
fmt::print(" block_num: 0x{:x}\n", continuous_block_num);
*/
if (block_num == 0)
{
tc::InvalidOperationException(kClassName+"::read()", "Invalid block number (0 blocks, would have returned before now if count==0)");
}
if (block_num < continuous_block_num)
{
tc::InvalidOperationException(kClassName+"::read()", "Invalid block number (underflow error)");
}
// allocate memory for partial block
tc::ByteData partial_block = tc::ByteData(sizeof(block_t));
// read un-aligned begin block
if (read_partial_begin_block)
{
// read block
this->seek(blockIndexToOffset(partial_begin_block_index), tc::io::SeekOrigin::Begin);
mBaseStream->read(partial_block.data(), partial_block.size());
// decrypt block
mCryptor->decrypt(partial_block.data(), partial_block.data(), partial_block.size(), partial_begin_block_index);
// copy out block carving
memcpy(ptr + data_read_count, partial_block.data() + partial_begin_block_offset, partial_begin_block_size);
// increment data read count
data_read_count += partial_begin_block_size;
}
// read continous blocks
if (continuous_block_num > 0)
{
// read blocks
this->seek(blockIndexToOffset(continuous_begin_block_index), tc::io::SeekOrigin::Begin);
mBaseStream->read(ptr + data_read_count, continuous_block_num * sizeof(block_t));
// decrypt blocks
mCryptor->decrypt(ptr + data_read_count, ptr + data_read_count, continuous_block_num * sizeof(block_t), continuous_begin_block_index);
// increment data read count
data_read_count += continuous_block_num * sizeof(block_t);
}
// read un-aligned end block
if (read_partial_end_block)
{
// read block
this->seek(blockIndexToOffset(partial_end_block_index), tc::io::SeekOrigin::Begin);
mBaseStream->read(partial_block.data(), partial_block.size());
// decrypt block
mCryptor->decrypt(partial_block.data(), partial_block.data(), partial_block.size(), partial_end_block_index);
// copy out block carving
memcpy(ptr + data_read_count, partial_block.data() + partial_end_block_offset, partial_end_block_size);
// increment
data_read_count += partial_end_block_size;
}
// restore expected logical position
this->seek(begin_read_offset + tc::io::IOUtil::castSizeToInt64(data_read_count), tc::io::SeekOrigin::Begin);
// return data read count
return data_read_count;
}
size_t tc::crypto::Aes128CtrEncryptedStream::write(const byte_t* ptr, size_t count)
{
if (mBaseStream == nullptr)
{
throw tc::ObjectDisposedException(kClassName+"::write()", "Failed to set stream position (stream is disposed)");
}
throw tc::NotImplementedException(kClassName+"::write()", "write is not implemented for Aes128CtrEncryptedStream");
}
int64_t tc::crypto::Aes128CtrEncryptedStream::seek(int64_t offset, tc::io::SeekOrigin origin)
{
if (mBaseStream == nullptr)
{
throw tc::ObjectDisposedException(kClassName+"::seek()", "Failed to set stream position (stream is disposed)");
}
return mBaseStream->seek(offset, origin);
}
void tc::crypto::Aes128CtrEncryptedStream::setLength(int64_t length)
{
if (mBaseStream == nullptr)
{
throw tc::ObjectDisposedException(kClassName+"::setLength()", "Failed to set stream length (stream is disposed)");
}
throw tc::NotImplementedException(kClassName+"::setLength()", "setLength is not implemented for Aes128CtrEncryptedStream");
}
void tc::crypto::Aes128CtrEncryptedStream::flush()
{
if (mBaseStream == nullptr)
{
throw tc::ObjectDisposedException(kClassName+"::seek()", "Failed to flush stream (stream is disposed)");
}
mBaseStream->flush();
}
void tc::crypto::Aes128CtrEncryptedStream::dispose()
{
if (mBaseStream != nullptr)
{
// dispose base stream
mBaseStream->dispose();
// release ptr
mBaseStream.reset();
}
if (mCryptor != nullptr)
mCryptor.reset();
}
@@ -0,0 +1,24 @@
#include <tc/crypto/Aes128CtrEncryptor.h>
void tc::crypto::EncryptAes128Ctr(byte_t* dst, const byte_t* src, size_t size, uint64_t block_number, const byte_t* key, size_t key_size, const byte_t* iv, size_t iv_size)
{
tc::crypto::Aes128CtrEncryptor crypt;
crypt.initialize(key, key_size, iv, iv_size);
crypt.encrypt(dst, src, size, block_number);
}
void tc::crypto::DecryptAes128Ctr(byte_t* dst, const byte_t* src, size_t size, uint64_t block_number, const byte_t* key, size_t key_size, const byte_t* iv, size_t iv_size)
{
tc::crypto::Aes128CtrEncryptor crypt;
crypt.initialize(key, key_size, iv, iv_size);
crypt.decrypt(dst, src, size, block_number);
}
void tc::crypto::IncrementCounterAes128Ctr(byte_t* counter, uint64_t incr)
{
if (counter == nullptr)
{
throw tc::ArgumentOutOfRangeException("counter was null.");
}
tc::crypto::detail::incr_counter<16>(counter, incr);
}
@@ -0,0 +1,15 @@
#include <tc/crypto/Aes128EcbEncryptor.h>
void tc::crypto::EncryptAes128Ecb(byte_t* dst, const byte_t* src, size_t size, const byte_t* key, size_t key_size)
{
tc::crypto::Aes128EcbEncryptor crypt;
crypt.initialize(key, key_size);
crypt.encrypt(dst, src, size);
}
void tc::crypto::DecryptAes128Ecb(byte_t* dst, const byte_t* src, size_t size, const byte_t* key, size_t key_size)
{
tc::crypto::Aes128EcbEncryptor crypt;
crypt.initialize(key, key_size);
crypt.decrypt(dst, src, size);
}
@@ -0,0 +1,15 @@
#include <tc/crypto/Aes128XtsEncryptor.h>
void tc::crypto::EncryptAes128Xts(byte_t* dst, const byte_t* src, size_t size, uint64_t sector_number, const byte_t* key1, size_t key1_size, const byte_t* key2, size_t key2_size, size_t sector_size, bool tweak_word_order)
{
tc::crypto::Aes128XtsEncryptor crypt;
crypt.initialize(key1, key1_size, key2, key2_size, sector_size, tweak_word_order);
crypt.encrypt(dst, src, size, sector_number);
}
void tc::crypto::DecryptAes128Xts(byte_t* dst, const byte_t* src, size_t size, uint64_t sector_number, const byte_t* key1, size_t key1_size, const byte_t* key2, size_t key2_size, size_t sector_size, bool tweak_word_order)
{
tc::crypto::Aes128XtsEncryptor crypt;
crypt.initialize(key1, key1_size, key2, key2_size, sector_size, tweak_word_order);
crypt.decrypt(dst, src, size, sector_number);
}
@@ -0,0 +1,15 @@
#include <tc/crypto/Aes192CbcEncryptor.h>
void tc::crypto::EncryptAes192Cbc(byte_t* dst, const byte_t* src, size_t size, const byte_t* key, size_t key_size, const byte_t* iv, size_t iv_size)
{
tc::crypto::Aes192CbcEncryptor crypt;
crypt.initialize(key, key_size, iv, iv_size);
crypt.encrypt(dst, src, size);
}
void tc::crypto::DecryptAes192Cbc(byte_t* dst, const byte_t* src, size_t size, const byte_t* key, size_t key_size, const byte_t* iv, size_t iv_size)
{
tc::crypto::Aes192CbcEncryptor crypt;
crypt.initialize(key, key_size, iv, iv_size);
crypt.decrypt(dst, src, size);
}
@@ -0,0 +1,24 @@
#include <tc/crypto/Aes192CtrEncryptor.h>
void tc::crypto::EncryptAes192Ctr(byte_t* dst, const byte_t* src, size_t size, uint64_t block_number, const byte_t* key, size_t key_size, const byte_t* iv, size_t iv_size)
{
tc::crypto::Aes192CtrEncryptor crypt;
crypt.initialize(key, key_size, iv, iv_size);
crypt.encrypt(dst, src, size, block_number);
}
void tc::crypto::DecryptAes192Ctr(byte_t* dst, const byte_t* src, size_t size, uint64_t block_number, const byte_t* key, size_t key_size, const byte_t* iv, size_t iv_size)
{
tc::crypto::Aes192CtrEncryptor crypt;
crypt.initialize(key, key_size, iv, iv_size);
crypt.decrypt(dst, src, size, block_number);
}
void tc::crypto::IncrementCounterAes192Ctr(byte_t* counter, uint64_t incr)
{
if (counter == nullptr)
{
throw tc::ArgumentOutOfRangeException("counter was null.");
}
tc::crypto::detail::incr_counter<16>(counter, incr);
}
@@ -0,0 +1,15 @@
#include <tc/crypto/Aes192EcbEncryptor.h>
void tc::crypto::EncryptAes192Ecb(byte_t* dst, const byte_t* src, size_t size, const byte_t* key, size_t key_size)
{
tc::crypto::Aes192EcbEncryptor crypt;
crypt.initialize(key, key_size);
crypt.encrypt(dst, src, size);
}
void tc::crypto::DecryptAes192Ecb(byte_t* dst, const byte_t* src, size_t size, const byte_t* key, size_t key_size)
{
tc::crypto::Aes192EcbEncryptor crypt;
crypt.initialize(key, key_size);
crypt.decrypt(dst, src, size);
}
@@ -0,0 +1,15 @@
#include <tc/crypto/Aes256CbcEncryptor.h>
void tc::crypto::EncryptAes256Cbc(byte_t* dst, const byte_t* src, size_t size, const byte_t* key, size_t key_size, const byte_t* iv, size_t iv_size)
{
tc::crypto::Aes256CbcEncryptor crypt;
crypt.initialize(key, key_size, iv, iv_size);
crypt.encrypt(dst, src, size);
}
void tc::crypto::DecryptAes256Cbc(byte_t* dst, const byte_t* src, size_t size, const byte_t* key, size_t key_size, const byte_t* iv, size_t iv_size)
{
tc::crypto::Aes256CbcEncryptor crypt;
crypt.initialize(key, key_size, iv, iv_size);
crypt.decrypt(dst, src, size);
}
@@ -0,0 +1,24 @@
#include <tc/crypto/Aes256CtrEncryptor.h>
void tc::crypto::EncryptAes256Ctr(byte_t* dst, const byte_t* src, size_t size, uint64_t block_number, const byte_t* key, size_t key_size, const byte_t* iv, size_t iv_size)
{
tc::crypto::Aes256CtrEncryptor crypt;
crypt.initialize(key, key_size, iv, iv_size);
crypt.encrypt(dst, src, size, block_number);
}
void tc::crypto::DecryptAes256Ctr(byte_t* dst, const byte_t* src, size_t size, uint64_t block_number, const byte_t* key, size_t key_size, const byte_t* iv, size_t iv_size)
{
tc::crypto::Aes256CtrEncryptor crypt;
crypt.initialize(key, key_size, iv, iv_size);
crypt.decrypt(dst, src, size, block_number);
}
void tc::crypto::IncrementCounterAes256Ctr(byte_t* counter, uint64_t incr)
{
if (counter == nullptr)
{
throw tc::ArgumentOutOfRangeException("counter was null.");
}
tc::crypto::detail::incr_counter<16>(counter, incr);
}
@@ -0,0 +1,15 @@
#include <tc/crypto/Aes256EcbEncryptor.h>
void tc::crypto::EncryptAes256Ecb(byte_t* dst, const byte_t* src, size_t size, const byte_t* key, size_t key_size)
{
tc::crypto::Aes256EcbEncryptor crypt;
crypt.initialize(key, key_size);
crypt.encrypt(dst, src, size);
}
void tc::crypto::DecryptAes256Ecb(byte_t* dst, const byte_t* src, size_t size, const byte_t* key, size_t key_size)
{
tc::crypto::Aes256EcbEncryptor crypt;
crypt.initialize(key, key_size);
crypt.decrypt(dst, src, size);
}
@@ -0,0 +1,15 @@
#include <tc/crypto/Aes256XtsEncryptor.h>
void tc::crypto::EncryptAes256Xts(byte_t* dst, const byte_t* src, size_t size, uint64_t sector_number, const byte_t* key1, size_t key1_size, const byte_t* key2, size_t key2_size, size_t sector_size, bool tweak_word_order)
{
tc::crypto::Aes256XtsEncryptor crypt;
crypt.initialize(key1, key1_size, key2, key2_size, sector_size, tweak_word_order);
crypt.encrypt(dst, src, size, sector_number);
}
void tc::crypto::DecryptAes256Xts(byte_t* dst, const byte_t* src, size_t size, uint64_t sector_number, const byte_t* key1, size_t key1_size, const byte_t* key2, size_t key2_size, size_t sector_size, bool tweak_word_order)
{
tc::crypto::Aes256XtsEncryptor crypt;
crypt.initialize(key1, key1_size, key2, key2_size, sector_size, tweak_word_order);
crypt.decrypt(dst, src, size, sector_number);
}
@@ -0,0 +1,9 @@
#include <tc/crypto/HmacMd5Generator.h>
void tc::crypto::GenerateHmacMd5Mac(byte_t* mac, const byte_t* data, size_t data_size, const byte_t* key, size_t key_size)
{
tc::crypto::HmacMd5Generator impl;
impl.initialize(key, key_size);
impl.update(data, data_size);
impl.getMac(mac);
}
@@ -0,0 +1,9 @@
#include <tc/crypto/HmacSha1Generator.h>
void tc::crypto::GenerateHmacSha1Mac(byte_t* mac, const byte_t* data, size_t data_size, const byte_t* key, size_t key_size)
{
tc::crypto::HmacSha1Generator impl;
impl.initialize(key, key_size);
impl.update(data, data_size);
impl.getMac(mac);
}
@@ -0,0 +1,9 @@
#include <tc/crypto/HmacSha256Generator.h>
void tc::crypto::GenerateHmacSha256Mac(byte_t* mac, const byte_t* data, size_t data_size, const byte_t* key, size_t key_size)
{
tc::crypto::HmacSha256Generator impl;
impl.initialize(key, key_size);
impl.update(data, data_size);
impl.getMac(mac);
}
@@ -0,0 +1,9 @@
#include <tc/crypto/HmacSha512Generator.h>
void tc::crypto::GenerateHmacSha512Mac(byte_t* mac, const byte_t* data, size_t data_size, const byte_t* key, size_t key_size)
{
tc::crypto::HmacSha512Generator impl;
impl.initialize(key, key_size);
impl.update(data, data_size);
impl.getMac(mac);
}
@@ -0,0 +1,11 @@
#include <tc/crypto/Md5Generator.h>
const std::array<byte_t, tc::crypto::Md5Generator::kAsn1OidDataSize> tc::crypto::Md5Generator::kAsn1OidData = {0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10};
void tc::crypto::GenerateMd5Hash(byte_t* hash, const byte_t* data, size_t data_size)
{
tc::crypto::Md5Generator impl;
impl.initialize();
impl.update(data, data_size);
impl.getHash(hash);
}
@@ -0,0 +1,8 @@
#include <tc/crypto/Pbkdf1Md5KeyDeriver.h>
void tc::crypto::DeriveKeyPbkdf1Md5(byte_t* key, size_t key_size, const byte_t* password, size_t password_size, const byte_t* salt, size_t salt_size, size_t n_rounds)
{
tc::crypto::Pbkdf1Md5KeyDeriver impl;
impl.initialize(password, password_size, salt, salt_size, n_rounds);
impl.getBytes(key, key_size);
}
@@ -0,0 +1,8 @@
#include <tc/crypto/Pbkdf1Sha1KeyDeriver.h>
void tc::crypto::DeriveKeyPbkdf1Sha1(byte_t* key, size_t key_size, const byte_t* password, size_t password_size, const byte_t* salt, size_t salt_size, size_t n_rounds)
{
tc::crypto::Pbkdf1Sha1KeyDeriver impl;
impl.initialize(password, password_size, salt, salt_size, n_rounds);
impl.getBytes(key, key_size);
}
@@ -0,0 +1,8 @@
#include <tc/crypto/Pbkdf2Sha1KeyDeriver.h>
void tc::crypto::DeriveKeyPbkdf2Sha1(byte_t* key, size_t key_size, const byte_t* password, size_t password_size, const byte_t* salt, size_t salt_size, size_t n_rounds)
{
tc::crypto::Pbkdf2Sha1KeyDeriver impl;
impl.initialize(password, password_size, salt, salt_size, n_rounds);
impl.getBytes(key, key_size);
}
@@ -0,0 +1,8 @@
#include <tc/crypto/Pbkdf2Sha256KeyDeriver.h>
void tc::crypto::DeriveKeyPbkdf2Sha256(byte_t* key, size_t key_size, const byte_t* password, size_t password_size, const byte_t* salt, size_t salt_size, size_t n_rounds)
{
tc::crypto::Pbkdf2Sha256KeyDeriver impl;
impl.initialize(password, password_size, salt, salt_size, n_rounds);
impl.getBytes(key, key_size);
}
@@ -0,0 +1,8 @@
#include <tc/crypto/Pbkdf2Sha512KeyDeriver.h>
void tc::crypto::DeriveKeyPbkdf2Sha512(byte_t* key, size_t key_size, const byte_t* password, size_t password_size, const byte_t* salt, size_t salt_size, size_t n_rounds)
{
tc::crypto::Pbkdf2Sha512KeyDeriver impl;
impl.initialize(password, password_size, salt, salt_size, n_rounds);
impl.getBytes(key, key_size);
}
@@ -0,0 +1,7 @@
#include <tc/crypto/PseudoRandomByteGenerator.h>
void tc::crypto::GeneratePseudoRandomBytes(byte_t* data, size_t data_size)
{
tc::crypto::PseudoRandomByteGenerator impl;
impl.getBytes(data, data_size);
}
@@ -0,0 +1,29 @@
#include <tc/crypto/RsaKey.h>
tc::crypto::RsaPublicKey::RsaPublicKey(const byte_t* modulus, size_t modulus_size)
{
static const byte_t kPublicExponent[3] = { 0x01, 0x00, 0x01 };
if (modulus != nullptr && modulus_size != 0)
{
this->n = tc::ByteData(modulus, modulus_size);
this->e = tc::ByteData(kPublicExponent, sizeof(kPublicExponent));
}
}
tc::crypto::RsaPrivateKey::RsaPrivateKey(const byte_t* modulus, size_t modulus_size, const byte_t* private_exponent, size_t private_exponent_size)
{
static const byte_t kPublicExponent[3] = { 0x01, 0x00, 0x01 };
if (modulus != nullptr && modulus_size != 0 && private_exponent != nullptr && private_exponent_size != 0)
{
this->n = tc::ByteData(modulus, modulus_size);
this->d = tc::ByteData(private_exponent, private_exponent_size);
this->e = tc::ByteData(kPublicExponent, sizeof(kPublicExponent));
}
}
tc::crypto::RsaKey tc::crypto::RsaPrivateKey::getPublicKey()
{
return RsaPublicKey(this->n.data(), this->n.size());
}
@@ -0,0 +1,7 @@
#include <tc/crypto/RsaKeyGenerator.h>
void tc::crypto::GenerateRsaKey(RsaKey& key, size_t key_bit_size)
{
tc::crypto::RsaKeyGenerator impl;
impl.generateKey(key, key_bit_size);
}
@@ -0,0 +1,43 @@
#include <tc/crypto/RsaOaepSha256Encryptor.h>
bool tc::crypto::EncryptRsa1024OaepSha256(byte_t* block, const byte_t* message, size_t message_size, const RsaKey& key, const byte_t* label, size_t label_size, bool isLabelDigested)
{
tc::crypto::Rsa1024OaepSha256Encryptor impl;
impl.initialize(key, label, label_size, isLabelDigested);
return impl.encrypt(block, message, message_size);
}
bool tc::crypto::DecryptRsa1024OaepSha256(byte_t* message, size_t& message_size, size_t message_capacity, const byte_t* block, const RsaKey& key, const byte_t* label, size_t label_size, bool isLabelDigested)
{
tc::crypto::Rsa1024OaepSha256Encryptor impl;
impl.initialize(key, label, label_size, isLabelDigested);
return impl.decrypt(message, message_size, message_capacity, block);
}
bool tc::crypto::EncryptRsa2048OaepSha256(byte_t* block, const byte_t* message, size_t message_size, const RsaKey& key, const byte_t* label, size_t label_size, bool isLabelDigested)
{
tc::crypto::Rsa2048OaepSha256Encryptor impl;
impl.initialize(key, label, label_size, isLabelDigested);
return impl.encrypt(block, message, message_size);
}
bool tc::crypto::DecryptRsa2048OaepSha256(byte_t* message, size_t& message_size, size_t message_capacity, const byte_t* block, const RsaKey& key, const byte_t* label, size_t label_size, bool isLabelDigested)
{
tc::crypto::Rsa2048OaepSha256Encryptor impl;
impl.initialize(key, label, label_size, isLabelDigested);
return impl.decrypt(message, message_size, message_capacity, block);
}
bool tc::crypto::EncryptRsa4096OaepSha256(byte_t* block, const byte_t* message, size_t message_size, const RsaKey& key, const byte_t* label, size_t label_size, bool isLabelDigested)
{
tc::crypto::Rsa4096OaepSha256Encryptor impl;
impl.initialize(key, label, label_size, isLabelDigested);
return impl.encrypt(block, message, message_size);
}
bool tc::crypto::DecryptRsa4096OaepSha256(byte_t* message, size_t& message_size, size_t message_capacity, const byte_t* block, const RsaKey& key, const byte_t* label, size_t label_size, bool isLabelDigested)
{
tc::crypto::Rsa4096OaepSha256Encryptor impl;
impl.initialize(key, label, label_size, isLabelDigested);
return impl.decrypt(message, message_size, message_capacity, block);
}
@@ -0,0 +1,29 @@
#include <tc/crypto/RsaOaepSha512Encryptor.h>
bool tc::crypto::EncryptRsa2048OaepSha512(byte_t* block, const byte_t* message, size_t message_size, const RsaKey& key, const byte_t* label, size_t label_size, bool isLabelDigested)
{
tc::crypto::Rsa2048OaepSha512Encryptor impl;
impl.initialize(key, label, label_size, isLabelDigested);
return impl.encrypt(block, message, message_size);
}
bool tc::crypto::DecryptRsa2048OaepSha512(byte_t* message, size_t& message_size, size_t message_capacity, const byte_t* block, const RsaKey& key, const byte_t* label, size_t label_size, bool isLabelDigested)
{
tc::crypto::Rsa2048OaepSha512Encryptor impl;
impl.initialize(key, label, label_size, isLabelDigested);
return impl.decrypt(message, message_size, message_capacity, block);
}
bool tc::crypto::EncryptRsa4096OaepSha512(byte_t* block, const byte_t* message, size_t message_size, const RsaKey& key, const byte_t* label, size_t label_size, bool isLabelDigested)
{
tc::crypto::Rsa4096OaepSha512Encryptor impl;
impl.initialize(key, label, label_size, isLabelDigested);
return impl.encrypt(block, message, message_size);
}
bool tc::crypto::DecryptRsa4096OaepSha512(byte_t* message, size_t& message_size, size_t message_capacity, const byte_t* block, const RsaKey& key, const byte_t* label, size_t label_size, bool isLabelDigested)
{
tc::crypto::Rsa4096OaepSha512Encryptor impl;
impl.initialize(key, label, label_size, isLabelDigested);
return impl.decrypt(message, message_size, message_capacity, block);
}
@@ -0,0 +1,43 @@
#include <tc/crypto/RsaPkcs1Md5Signer.h>
bool tc::crypto::SignRsa1024Pkcs1Md5(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa1024Pkcs1Md5Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa1024Pkcs1Md5(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa1024Pkcs1Md5Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
bool tc::crypto::SignRsa2048Pkcs1Md5(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa2048Pkcs1Md5Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa2048Pkcs1Md5(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa2048Pkcs1Md5Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
bool tc::crypto::SignRsa4096Pkcs1Md5(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa4096Pkcs1Md5Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa4096Pkcs1Md5(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa4096Pkcs1Md5Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
@@ -0,0 +1,43 @@
#include <tc/crypto/RsaPkcs1Sha1Signer.h>
bool tc::crypto::SignRsa1024Pkcs1Sha1(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa1024Pkcs1Sha1Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa1024Pkcs1Sha1(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa1024Pkcs1Sha1Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
bool tc::crypto::SignRsa2048Pkcs1Sha1(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa2048Pkcs1Sha1Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa2048Pkcs1Sha1(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa2048Pkcs1Sha1Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
bool tc::crypto::SignRsa4096Pkcs1Sha1(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa4096Pkcs1Sha1Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa4096Pkcs1Sha1(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa4096Pkcs1Sha1Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
@@ -0,0 +1,43 @@
#include <tc/crypto/RsaPkcs1Sha256Signer.h>
bool tc::crypto::SignRsa1024Pkcs1Sha256(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa1024Pkcs1Sha256Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa1024Pkcs1Sha256(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa1024Pkcs1Sha256Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
bool tc::crypto::SignRsa2048Pkcs1Sha256(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa2048Pkcs1Sha256Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa2048Pkcs1Sha256(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa2048Pkcs1Sha256Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
bool tc::crypto::SignRsa4096Pkcs1Sha256(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa4096Pkcs1Sha256Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa4096Pkcs1Sha256(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa4096Pkcs1Sha256Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
@@ -0,0 +1,43 @@
#include <tc/crypto/RsaPkcs1Sha512Signer.h>
bool tc::crypto::SignRsa1024Pkcs1Sha512(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa1024Pkcs1Sha512Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa1024Pkcs1Sha512(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa1024Pkcs1Sha512Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
bool tc::crypto::SignRsa2048Pkcs1Sha512(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa2048Pkcs1Sha512Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa2048Pkcs1Sha512(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa2048Pkcs1Sha512Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
bool tc::crypto::SignRsa4096Pkcs1Sha512(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa4096Pkcs1Sha512Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa4096Pkcs1Sha512(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa4096Pkcs1Sha512Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
@@ -0,0 +1,43 @@
#include <tc/crypto/RsaPssSha256Signer.h>
bool tc::crypto::SignRsa1024PssSha256(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa1024PssSha256Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa1024PssSha256(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa1024PssSha256Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
bool tc::crypto::SignRsa2048PssSha256(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa2048PssSha256Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa2048PssSha256(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa2048PssSha256Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
bool tc::crypto::SignRsa4096PssSha256(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa4096PssSha256Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa4096PssSha256(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa4096PssSha256Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
@@ -0,0 +1,43 @@
#include <tc/crypto/RsaPssSha512Signer.h>
bool tc::crypto::SignRsa1024PssSha512(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa1024PssSha512Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa1024PssSha512(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa1024PssSha512Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
bool tc::crypto::SignRsa2048PssSha512(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa2048PssSha512Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa2048PssSha512(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa2048PssSha512Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
bool tc::crypto::SignRsa4096PssSha512(byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa4096PssSha512Signer impl;
impl.initialize(key);
return impl.sign(signature, message_digest);
}
bool tc::crypto::VerifyRsa4096PssSha512(const byte_t* signature, const byte_t* message_digest, const RsaKey& key)
{
tc::crypto::Rsa4096PssSha512Signer impl;
impl.initialize(key);
return impl.verify(signature, message_digest);
}
@@ -0,0 +1,12 @@
#include <tc/crypto/Sha1Generator.h>
const std::array<byte_t, tc::crypto::Sha1Generator::kAsn1OidDataSize> tc::crypto::Sha1Generator::kAsn1OidData = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14};
void tc::crypto::GenerateSha1Hash(byte_t* hash, const byte_t* data, size_t data_size)
{
tc::crypto::Sha1Generator impl;
impl.initialize();
impl.update(data, data_size);
impl.getHash(hash);
}
@@ -0,0 +1,11 @@
#include <tc/crypto/Sha256Generator.h>
const std::array<byte_t, tc::crypto::Sha256Generator::kAsn1OidDataSize> tc::crypto::Sha256Generator::kAsn1OidData = {0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
void tc::crypto::GenerateSha256Hash(byte_t* hash, const byte_t* data, size_t data_size)
{
tc::crypto::Sha256Generator impl;
impl.initialize();
impl.update(data, data_size);
impl.getHash(hash);
}
@@ -0,0 +1,11 @@
#include <tc/crypto/Sha512Generator.h>
const std::array<byte_t, tc::crypto::Sha512Generator::kAsn1OidDataSize> tc::crypto::Sha512Generator::kAsn1OidData = {0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
void tc::crypto::GenerateSha512Hash(byte_t* hash, const byte_t* data, size_t data_size)
{
tc::crypto::Sha512Generator impl;
impl.initialize();
impl.update(data, data_size);
impl.getHash(hash);
}
@@ -0,0 +1,51 @@
#include <tc/crypto/detail/AesImpl.h>
#include <mbedtls/aes.h>
struct tc::crypto::detail::AesImpl::ImplCtx
{
mbedtls_aes_context mEncContext;
mbedtls_aes_context mDecContext;
};
tc::crypto::detail::AesImpl::AesImpl() :
mState(State::None),
mImplCtx(new ImplCtx())
{
mbedtls_aes_init(&(mImplCtx->mEncContext));
mbedtls_aes_init(&(mImplCtx->mDecContext));
}
tc::crypto::detail::AesImpl::~AesImpl()
{
mbedtls_aes_free(&(mImplCtx->mEncContext));
mbedtls_aes_free(&(mImplCtx->mDecContext));
}
void tc::crypto::detail::AesImpl::initialize(const byte_t* key, size_t key_size)
{
if (key == nullptr) { throw tc::ArgumentNullException("AesImpl::initialize()", "key was null."); }
if (key_size != 16 && key_size != 24 && key_size != 32) { throw tc::ArgumentOutOfRangeException("AesImpl::initialize()", "key_size did not equal 16, 24 or 32."); }
mbedtls_aes_setkey_enc(&(mImplCtx->mEncContext), key, uint32_t(key_size) * 8);
mbedtls_aes_setkey_dec(&(mImplCtx->mDecContext), key, uint32_t(key_size) * 8);
mState = State::Initialized;
}
void tc::crypto::detail::AesImpl::encrypt(byte_t* dst, const byte_t* src)
{
if (mState != State::Initialized) { return; }
if (dst == nullptr) { throw tc::ArgumentNullException("AesImpl::encrypt()", "dst was null."); }
if (src == nullptr) { throw tc::ArgumentNullException("AesImpl::encrypt()", "src was null."); }
mbedtls_aes_crypt_ecb(&(mImplCtx->mEncContext), MBEDTLS_AES_ENCRYPT, src, dst);
}
void tc::crypto::detail::AesImpl::decrypt(byte_t* dst, const byte_t* src)
{
if (mState != State::Initialized) { return; }
if (dst == nullptr) { throw tc::ArgumentNullException("AesImpl::decrypt()", "dst was null."); }
if (src == nullptr) { throw tc::ArgumentNullException("AesImpl::decrypt()", "src was null."); }
mbedtls_aes_crypt_ecb(&(mImplCtx->mDecContext), MBEDTLS_AES_DECRYPT, src, dst);
}
@@ -0,0 +1,44 @@
#include <tc/crypto/detail/Md5Impl.h>
#include <mbedtls/md.h>
struct tc::crypto::detail::Md5Impl::ImplCtx
{
mbedtls_md_context_t mMdContext;
};
tc::crypto::detail::Md5Impl::Md5Impl() :
mState(State::None),
mImplCtx(new ImplCtx())
{
mbedtls_md_init(&(mImplCtx->mMdContext));
mbedtls_md_setup(&(mImplCtx->mMdContext), mbedtls_md_info_from_type(MBEDTLS_MD_MD5), 0);
}
tc::crypto::detail::Md5Impl::~Md5Impl()
{
mbedtls_md_free(&(mImplCtx->mMdContext));
}
void tc::crypto::detail::Md5Impl::initialize()
{
mbedtls_md_starts(&(mImplCtx->mMdContext));
mState = State::Initialized;
}
void tc::crypto::detail::Md5Impl::update(const byte_t* src, size_t src_size)
{
mbedtls_md_update(&(mImplCtx->mMdContext), src, src_size);
}
void tc::crypto::detail::Md5Impl::getHash(byte_t* hash)
{
if (mState == State::Initialized)
{
mbedtls_md_finish(&(mImplCtx->mMdContext), mHash.data());
mState = State::Done;
}
if (mState == State::Done)
{
memcpy(hash, mHash.data(), mHash.size());
}
}
@@ -0,0 +1,50 @@
#include <tc/crypto/detail/PrbgImpl.h>
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
const std::string tc::crypto::detail::PrbgImpl::kClassName = "tc::crypto::detail::PrbgImpl";
struct tc::crypto::detail::PrbgImpl::ImplCtx
{
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_context entropy;
};
tc::crypto::detail::PrbgImpl::PrbgImpl() :
mImplCtx(new ImplCtx())
{
mbedtls_ctr_drbg_init(&(mImplCtx->ctr_drbg));
mbedtls_entropy_init(&(mImplCtx->entropy));
int ret = mbedtls_ctr_drbg_seed(&(mImplCtx->ctr_drbg), mbedtls_entropy_func, &(mImplCtx->entropy), (const unsigned char *)kClassName.c_str(), kClassName.size());
switch (ret)
{
case (0):
break;
case (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED):
throw tc::crypto::CryptoException(kClassName, "Entropy source failed");
default:
throw tc::crypto::CryptoException(kClassName, "An unexpected error occurred");
}
}
tc::crypto::detail::PrbgImpl::~PrbgImpl()
{
mbedtls_ctr_drbg_free(&(mImplCtx->ctr_drbg));
mbedtls_entropy_free(&(mImplCtx->entropy));
}
void tc::crypto::detail::PrbgImpl::getBytes(byte_t* data, size_t data_size)
{
int ret = mbedtls_ctr_drbg_random(&(mImplCtx->ctr_drbg), data, data_size);
switch (ret)
{
case (0):
break;
case (MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG):
throw tc::crypto::CryptoException(kClassName, "Request too big");
case (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED):
throw tc::crypto::CryptoException(kClassName, "Entropy source failed");
default:
throw tc::crypto::CryptoException(kClassName, "An unexpected error occurred");
}
}
@@ -0,0 +1,140 @@
#include <tc/crypto/detail/RsaImpl.h>
#include <mbedtls/rsa.h>
struct tc::crypto::detail::RsaImpl::ImplCtx
{
mbedtls_rsa_context mContext;
};
tc::crypto::detail::RsaImpl::RsaImpl() :
mState(State::None),
mImplCtx(new ImplCtx())
{
mbedtls_rsa_init(&(mImplCtx->mContext), MBEDTLS_RSA_PKCS_V15, 0);
}
tc::crypto::detail::RsaImpl::~RsaImpl()
{
mbedtls_rsa_free(&(mImplCtx->mContext));
}
void tc::crypto::detail::RsaImpl::initialize(size_t key_bit_size, const byte_t* n, size_t n_size, const byte_t* p, size_t p_size, const byte_t* q, size_t q_size, const byte_t* d, size_t d_size, const byte_t* e, size_t e_size)
{
if ((key_bit_size % 8) != 0) { throw tc::ArgumentOutOfRangeException("RsaImpl::initialize()", "key_bit_size was not a multiple of 8 bits."); }
if (n == nullptr && n_size != 0) { throw tc::ArgumentNullException("RsaImpl::initialize()", "n was null when n_size was not 0."); }
if (p == nullptr && p_size != 0) { throw tc::ArgumentNullException("RsaImpl::initialize()", "p was null when p_size was not 0."); }
if (q == nullptr && q_size != 0) { throw tc::ArgumentNullException("RsaImpl::initialize()", "q was null when q_size was not 0."); }
if (d == nullptr && d_size != 0) { throw tc::ArgumentNullException("RsaImpl::initialize()", "d was null when d_size was not 0."); }
if (e == nullptr && e_size != 0) { throw tc::ArgumentNullException("RsaImpl::initialize()", "e was null when e_size was not 0."); }
if (n != nullptr && n_size == 0) { throw tc::ArgumentNullException("RsaImpl::initialize()", "n was not null but n_size was 0."); }
if (p != nullptr && p_size == 0) { throw tc::ArgumentNullException("RsaImpl::initialize()", "p was not null but p_size was 0."); }
if (q != nullptr && q_size == 0) { throw tc::ArgumentNullException("RsaImpl::initialize()", "q was not null but q_size was 0."); }
if (d != nullptr && d_size == 0) { throw tc::ArgumentNullException("RsaImpl::initialize()", "d was not null but d_size was 0."); }
if (e != nullptr && e_size == 0) { throw tc::ArgumentNullException("RsaImpl::initialize()", "e was not null but e_size was 0."); }
if (n_size > 0 && n_size != (key_bit_size/8)) { throw tc::ArgumentNullException("RsaImpl::initialize()", "n_size was non-zero but not expected size."); }
if (p_size > 0 && p_size != (key_bit_size/8)/2) { throw tc::ArgumentNullException("RsaImpl::initialize()", "p_size was non-zero but not expected size."); }
if (q_size > 0 && q_size != (key_bit_size/8)/2) { throw tc::ArgumentNullException("RsaImpl::initialize()", "q_size was non-zero but not expected size."); }
if (d_size > 0 && d_size != (key_bit_size/8)) { throw tc::ArgumentNullException("RsaImpl::initialize()", "d_size was non-zero but not expected size."); }
if (e_size > 0 && e_size != 3 && e_size != 4) { throw tc::ArgumentNullException("RsaImpl::initialize()", "e_size was non-zero but not expected size."); }
mImplCtx->mContext.len = key_bit_size / 8;
int ret = mbedtls_rsa_import_raw(&(mImplCtx->mContext), n, n_size, p, p_size, q, q_size, d, d_size, e, e_size);
// TODO: Confirm these error codes
if (ret != 0)
{
if (ret < MBEDTLS_ERR_RSA_BAD_INPUT_DATA) { throw tc::crypto::CryptoException("RsaImpl::initialize()", "Bad input parameters to function."); }
else { throw tc::crypto::CryptoException("RsaImpl::initialize()", "An unexpected error occurred."); }
}
mState = State::Initialized;
}
void tc::crypto::detail::RsaImpl::publicTransform(byte_t* dst, const byte_t* src)
{
if (mState != State::Initialized) { return; }
if (dst == nullptr) { throw tc::ArgumentNullException("RsaImpl::publicTransform()", "dst was null."); }
if (src == nullptr) { throw tc::ArgumentNullException("RsaImpl::publicTransform()", "src was null."); }
int ret = mbedtls_rsa_public(&(mImplCtx->mContext), src, dst);
switch (ret)
{
case (0):
break;
case (MBEDTLS_ERR_RSA_BAD_INPUT_DATA):
throw tc::crypto::CryptoException("RsaImpl::publicTransform()", "Bad input parameters to function.");
break;
case (MBEDTLS_ERR_RSA_INVALID_PADDING):
throw tc::crypto::CryptoException("RsaImpl::publicTransform()", "Input data contains invalid padding and is rejected.");
break;
case (MBEDTLS_ERR_RSA_KEY_GEN_FAILED):
throw tc::crypto::CryptoException("RsaImpl::publicTransform()", "Something failed during generation of a key.");
break;
case (MBEDTLS_ERR_RSA_KEY_CHECK_FAILED):
throw tc::crypto::CryptoException("RsaImpl::publicTransform()", "Key failed to pass the validity check of the library.");
break;
case (MBEDTLS_ERR_RSA_PUBLIC_FAILED):
throw tc::crypto::CryptoException("RsaImpl::publicTransform()", "The public key operation failed.");
break;
case (MBEDTLS_ERR_RSA_PRIVATE_FAILED):
throw tc::crypto::CryptoException("RsaImpl::publicTransform()", "The private key operation failed.");
break;
case (MBEDTLS_ERR_RSA_VERIFY_FAILED):
throw tc::crypto::CryptoException("RsaImpl::publicTransform()", "The PKCS#1 verification failed.");
break;
case (MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE):
throw tc::crypto::CryptoException("RsaImpl::publicTransform()", "The output buffer for decryption is not large enough.");
break;
case (MBEDTLS_ERR_RSA_RNG_FAILED):
throw tc::crypto::CryptoException("RsaImpl::publicTransform()", "The random generator failed to generate non-zeros.");
break;
default:
throw tc::crypto::CryptoException("RsaImpl::publicTransform()", "An unexpected error occurred.");
}
}
void tc::crypto::detail::RsaImpl::privateTransform(byte_t* dst, const byte_t* src)
{
if (mState != State::Initialized) { return; }
if (dst == nullptr) { throw tc::ArgumentNullException("RsaImpl::privateTransform()", "dst was null."); }
if (src == nullptr) { throw tc::ArgumentNullException("RsaImpl::privateTransform()", "src was null."); }
int ret = mbedtls_rsa_private(&(mImplCtx->mContext), nullptr, nullptr, src, dst);
switch (ret)
{
case (0):
break;
case (MBEDTLS_ERR_RSA_BAD_INPUT_DATA):
throw tc::crypto::CryptoException("RsaImpl::privateTransform()", "Bad input parameters to function.");
break;
case (MBEDTLS_ERR_RSA_INVALID_PADDING):
throw tc::crypto::CryptoException("RsaImpl::privateTransform()", "Input data contains invalid padding and is rejected.");
break;
case (MBEDTLS_ERR_RSA_KEY_GEN_FAILED):
throw tc::crypto::CryptoException("RsaImpl::privateTransform()", "Something failed during generation of a key.");
break;
case (MBEDTLS_ERR_RSA_KEY_CHECK_FAILED):
throw tc::crypto::CryptoException("RsaImpl::privateTransform()", "Key failed to pass the validity check of the library.");
break;
case (MBEDTLS_ERR_RSA_PUBLIC_FAILED):
throw tc::crypto::CryptoException("RsaImpl::privateTransform()", "The public key operation failed.");
break;
case (MBEDTLS_ERR_RSA_PRIVATE_FAILED):
throw tc::crypto::CryptoException("RsaImpl::privateTransform()", "The private key operation failed.");
break;
case (MBEDTLS_ERR_RSA_VERIFY_FAILED):
throw tc::crypto::CryptoException("RsaImpl::privateTransform()", "The PKCS#1 verification failed.");
break;
case (MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE):
throw tc::crypto::CryptoException("RsaImpl::privateTransform()", "The output buffer for decryption is not large enough.");
break;
case (MBEDTLS_ERR_RSA_RNG_FAILED):
throw tc::crypto::CryptoException("RsaImpl::privateTransform()", "The random generator failed to generate non-zeros.");
break;
default:
throw tc::crypto::CryptoException("RsaImpl::privateTransform()", "An unexpected error occurred.");
}
}
@@ -0,0 +1,85 @@
#include <tc/crypto/detail/RsaKeyGeneratorImpl.h>
#include <mbedtls/rsa.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>
const std::string tc::crypto::detail::RsaKeyGeneratorImpl::kClassName = "tc::crypto::detail::RsaKeyGeneratorImpl";
struct tc::crypto::detail::RsaKeyGeneratorImpl::ImplCtx
{
mbedtls_rsa_context rsa;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_context entropy;
};
tc::crypto::detail::RsaKeyGeneratorImpl::RsaKeyGeneratorImpl() :
mImplCtx(new ImplCtx())
{
mbedtls_entropy_init( &(mImplCtx->entropy) );
mbedtls_ctr_drbg_init( &(mImplCtx->ctr_drbg) );
mbedtls_rsa_init( &(mImplCtx->rsa), 0, 0 );
int ret = mbedtls_ctr_drbg_seed(&(mImplCtx->ctr_drbg), mbedtls_entropy_func, &(mImplCtx->entropy), (const unsigned char *)kClassName.c_str(), kClassName.size());
switch (ret)
{
case (0):
break;
case (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED):
throw tc::crypto::CryptoException(kClassName, "mbedtls_ctr_drbg_seed() Entropy source failed");
default:
throw tc::crypto::CryptoException(kClassName, "mbedtls_ctr_drbg_seed() An unexpected error occurred");
}
}
tc::crypto::detail::RsaKeyGeneratorImpl::~RsaKeyGeneratorImpl()
{
mbedtls_rsa_free( &(mImplCtx->rsa) );
mbedtls_ctr_drbg_free( &(mImplCtx->ctr_drbg) );
mbedtls_entropy_free( &(mImplCtx->entropy) );
}
void tc::crypto::detail::RsaKeyGeneratorImpl::generateKey(size_t key_bit_size, byte_t* n, size_t n_size, byte_t* p, size_t p_size, byte_t* q, size_t q_size, byte_t* d, size_t d_size, byte_t* e, size_t e_size)
{
if ((key_bit_size % 8) != 0) { throw tc::ArgumentOutOfRangeException(kClassName, "key_bit_size was not a multiple of 8 bits."); }
if (n != nullptr && n_size < (key_bit_size/8)) { throw tc::ArgumentNullException(kClassName, "n was not null, but n_size was not large enough"); }
if (p != nullptr && p_size < (key_bit_size/8)/2) { throw tc::ArgumentNullException(kClassName, "p was not null, but p_size was not large enough"); }
if (q != nullptr && q_size < (key_bit_size/8)/2) { throw tc::ArgumentNullException(kClassName, "q was not null, but q_size was not large enough"); }
if (d != nullptr && d_size < (key_bit_size/8)) { throw tc::ArgumentNullException(kClassName, "d was not null, but d_size was not large enough"); }
if (e != nullptr && e_size < 3) { throw tc::ArgumentNullException(kClassName, "e was not null, but e_size was not large enough"); }
int ret = 1;
// generate key
ret = mbedtls_rsa_gen_key(&(mImplCtx->rsa), mbedtls_ctr_drbg_random, &(mImplCtx->ctr_drbg), uint32_t(key_bit_size), 0x10001);
switch (ret)
{
case (0):
break;
case (MBEDTLS_ERR_RSA_KEY_GEN_FAILED):
throw tc::crypto::CryptoException(kClassName, "mbedtls_rsa_gen_key() Something failed during generation of a key.");
case (MBEDTLS_ERR_RSA_RNG_FAILED):
throw tc::crypto::CryptoException(kClassName, "mbedtls_rsa_gen_key() The random generator failed to generate non-zeros.");
default:
throw tc::crypto::CryptoException(kClassName, "mbedtls_rsa_gen_key() An unexpected error occurred.");
}
// export key from mbedtls context
ret = mbedtls_rsa_export_raw(&(mImplCtx->rsa), \
n, n_size, \
p, p_size, \
q, q_size, \
d, d_size, \
e, e_size \
);
switch (ret)
{
case (0):
break;
default:
throw tc::crypto::CryptoException(kClassName, "mbedtls_rsa_export_raw() An unexpected error occurred.");
}
// clear key from mbedtls context
mbedtls_rsa_init( &(mImplCtx->rsa), 0, 0 );
}
@@ -0,0 +1,44 @@
#include <tc/crypto/detail/Sha1Impl.h>
#include <mbedtls/md.h>
struct tc::crypto::detail::Sha1Impl::ImplCtx
{
mbedtls_md_context_t mMdContext;
};
tc::crypto::detail::Sha1Impl::Sha1Impl() :
mState(State::None),
mImplCtx(new ImplCtx())
{
mbedtls_md_init(&(mImplCtx->mMdContext));
mbedtls_md_setup(&(mImplCtx->mMdContext), mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 0);
}
tc::crypto::detail::Sha1Impl::~Sha1Impl()
{
mbedtls_md_free(&(mImplCtx->mMdContext));
}
void tc::crypto::detail::Sha1Impl::initialize()
{
mbedtls_md_starts(&(mImplCtx->mMdContext));
mState = State::Initialized;
}
void tc::crypto::detail::Sha1Impl::update(const byte_t* src, size_t src_size)
{
mbedtls_md_update(&(mImplCtx->mMdContext), src, src_size);
}
void tc::crypto::detail::Sha1Impl::getHash(byte_t* hash)
{
if (mState == State::Initialized)
{
mbedtls_md_finish(&(mImplCtx->mMdContext), mHash.data());
mState = State::Done;
}
if (mState == State::Done)
{
memcpy(hash, mHash.data(), mHash.size());
}
}
@@ -0,0 +1,58 @@
#include <tc/crypto/detail/Sha2Impl.h>
#include <mbedtls/md.h>
struct tc::crypto::detail::Sha2Impl::ImplCtx
{
mbedtls_md_context_t mMdContext;
};
tc::crypto::detail::Sha2Impl::Sha2Impl(SHA2BitSize algo) :
mState(State::None),
mHashSize(0),
mImplCtx(new ImplCtx())
{
mbedtls_md_init(&(mImplCtx->mMdContext));
switch(algo)
{
case (SHA2BitSize_256):
mHashSize = kSha2_256_HashSize;
mbedtls_md_setup(&(mImplCtx->mMdContext), mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 0);
break;
case (SHA2BitSize_512):
mHashSize = kSha2_512_HashSize;
mbedtls_md_setup(&(mImplCtx->mMdContext), mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), 0);
break;
default:
throw tc::crypto::CryptoException("tc::crypto::detail::Sha2Impl", "Invalid value for SHA2BitSize");
}
}
tc::crypto::detail::Sha2Impl::~Sha2Impl()
{
mbedtls_md_free(&(mImplCtx->mMdContext));
}
void tc::crypto::detail::Sha2Impl::initialize()
{
mbedtls_md_starts(&(mImplCtx->mMdContext));
mState = State::Initialized;
}
void tc::crypto::detail::Sha2Impl::update(const byte_t* src, size_t src_size)
{
mbedtls_md_update(&(mImplCtx->mMdContext), src, src_size);
}
void tc::crypto::detail::Sha2Impl::getHash(byte_t* hash)
{
if (mState == State::Initialized)
{
mbedtls_md_finish(&(mImplCtx->mMdContext), mHash.data());
mState = State::Done;
}
if (mState == State::Done)
{
memcpy(hash, mHash.data(), mHashSize);
}
}