mirror of
https://github.com/DarkStore-3DS/Project_CTR.git
synced 2026-07-05 16:59:02 +00:00
Add source code for ctrtool
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user