mirror of
https://github.com/jakcron/nstool.git
synced 2024-12-22 10:45:28 +00:00
[crypto] Removed AesCtrStream
This commit is contained in:
parent
acc8494224
commit
a4d52b3495
|
@ -121,7 +121,6 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\crypto\aes.h" />
|
||||
<ClInclude Include="include\crypto\AesCtrStream.h" />
|
||||
<ClInclude Include="include\crypto\rsa.h" />
|
||||
<ClInclude Include="include\crypto\sha.h" />
|
||||
<ClInclude Include="source\libpolarssl\include\polarssl\aes.h" />
|
||||
|
@ -137,7 +136,6 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="source\aes.cpp" />
|
||||
<ClCompile Include="source\AesCtrStream.cpp" />
|
||||
<ClCompile Include="source\libpolarssl\source\polar_aes.c" />
|
||||
<ClCompile Include="source\libpolarssl\source\polar_base64.c" />
|
||||
<ClCompile Include="source\libpolarssl\source\polar_bignum.c" />
|
||||
|
|
|
@ -27,9 +27,6 @@
|
|||
<ClInclude Include="include\crypto\aes.h">
|
||||
<Filter>Header Files\crypto</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\crypto\AesCtrStream.h">
|
||||
<Filter>Header Files\crypto</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\crypto\rsa.h">
|
||||
<Filter>Header Files\crypto</Filter>
|
||||
</ClInclude>
|
||||
|
@ -71,9 +68,6 @@
|
|||
<ClCompile Include="source\aes.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\AesCtrStream.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\rsa.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
@ -1,165 +0,0 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <fnd/Exception.h>
|
||||
#include <crypto/aes.h>
|
||||
|
||||
namespace crypto
|
||||
{
|
||||
namespace aes
|
||||
{
|
||||
class AesCtrStream
|
||||
{
|
||||
public:
|
||||
AesCtrStream();
|
||||
~AesCtrStream();
|
||||
|
||||
void seek(size_t offset);
|
||||
void read(size_t size, uint8_t* out);
|
||||
void read(size_t offset, size_t size, uint8_t* out);
|
||||
void write(size_t size, const uint8_t* in);
|
||||
void write(size_t offset, size_t size, const uint8_t* in);
|
||||
|
||||
void AddRegion(size_t start, size_t end, const uint8_t aes_key[kAes128KeySize], const uint8_t aes_ctr[kAesBlockSize]);
|
||||
|
||||
protected:
|
||||
// Virtual methods for implementation of seek/read/write
|
||||
virtual void seek_internal(size_t offset) = 0;
|
||||
virtual void read_internal(size_t size, size_t& read_len, uint8_t* out) = 0;
|
||||
virtual void write_internal(size_t size, size_t& write_len, const uint8_t* in) = 0;
|
||||
|
||||
private:
|
||||
const std::string kModuleName = "AES_CTR_STREAM";
|
||||
static const size_t kIoBufferLen = 0x10000;
|
||||
|
||||
// private implementation of crypto region
|
||||
class CryptRegion
|
||||
{
|
||||
public:
|
||||
// stubbed constructor
|
||||
CryptRegion() :
|
||||
start_(0),
|
||||
end_(0),
|
||||
is_plaintext_(true)
|
||||
{
|
||||
CleanUp();
|
||||
}
|
||||
|
||||
// plaintext constructor
|
||||
CryptRegion(size_t start, size_t end) :
|
||||
start_(start),
|
||||
end_(end),
|
||||
is_plaintext_(true)
|
||||
{
|
||||
CleanUp();
|
||||
}
|
||||
|
||||
// encrypted constructor
|
||||
CryptRegion(size_t start, size_t end, const uint8_t aes_key[kAes128KeySize], const uint8_t aes_ctr[kAesBlockSize]) :
|
||||
start_(start),
|
||||
end_(end),
|
||||
is_plaintext_(false)
|
||||
{
|
||||
CleanUp();
|
||||
memcpy(aes_key_, aes_key, kAes128KeySize);
|
||||
memcpy(ctr_init_, aes_ctr, kAesBlockSize);
|
||||
memcpy(ctr_, ctr_init_, kAesBlockSize);
|
||||
}
|
||||
|
||||
// destructor
|
||||
~CryptRegion()
|
||||
{
|
||||
CleanUp();
|
||||
}
|
||||
|
||||
size_t start() const { return start_; }
|
||||
size_t end() const { return end_; }
|
||||
size_t size() const { return end_ - start_; }
|
||||
size_t remaining_size(size_t start) const { return end_ - start; }
|
||||
const uint8_t* aes_key() const { return aes_key_; }
|
||||
uint8_t* aes_ctr() { return ctr_; }
|
||||
|
||||
bool is_in_region(size_t start) const { return start >= start_ && start < end_; }
|
||||
bool is_in_region(size_t start, size_t end) const { return is_in_region(start) && end > start_ && end <= end_; }
|
||||
|
||||
void UpdateAesCtr(size_t start)
|
||||
{
|
||||
if (is_in_region(start))
|
||||
AesIncrementCounter(ctr_init_, ((start - start_) >> 4), ctr_);
|
||||
}
|
||||
|
||||
void GenerateXorpad(size_t start, size_t size, uint8_t* out)
|
||||
{
|
||||
// don't operate if requested size exceeds region size
|
||||
if (is_in_region(start, start + size) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_plaintext_ == true)
|
||||
{
|
||||
memset(out, 0, size);
|
||||
return;
|
||||
}
|
||||
|
||||
// parameters
|
||||
size_t block_offset = (start - start_) & 0xf;
|
||||
size_t block_num = size >> 4;
|
||||
for (size_t pos = 0; pos < block_num; pos += (kPadBufferLen >> 4))
|
||||
{
|
||||
// clear pad buffer
|
||||
memset(pad_buffer_, 0, kPadBufferCapacity);
|
||||
|
||||
// encrypt pad buffer to create xorpad
|
||||
UpdateAesCtr(start + (pos << 4));
|
||||
AesCtr(pad_buffer_, kPadBufferCapacity, aes_key(), aes_ctr(), pad_buffer_);
|
||||
|
||||
// determine the number of blocks to copy to xorpad
|
||||
size_t copy_size = kPadBufferLen < ((block_num - pos) << 4) ? kPadBufferLen : ((block_num - pos) << 4);
|
||||
|
||||
// copy
|
||||
memcpy(out + (pos << 4), pad_buffer_ + block_offset, copy_size);
|
||||
}
|
||||
}
|
||||
private:
|
||||
static const size_t kPadBufferLen = 0x10000;
|
||||
static const size_t kPadBufferCapacity = kPadBufferLen + kAesBlockSize; // has an extra block to accomodate non block aligned starts
|
||||
|
||||
size_t start_;
|
||||
size_t end_;
|
||||
bool is_plaintext_;
|
||||
uint8_t aes_key_[kAes128KeySize];
|
||||
uint8_t ctr_init_[kAesBlockSize];
|
||||
uint8_t ctr_[kAesBlockSize];
|
||||
uint8_t pad_buffer_[kPadBufferCapacity];
|
||||
|
||||
void CleanUp()
|
||||
{
|
||||
memset(aes_key_, 0, kAes128KeySize);
|
||||
memset(ctr_init_, 0, kAesBlockSize);
|
||||
memset(ctr_, 0, kAesBlockSize);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline void xor_data(size_t size, const uint8_t* data1, const uint8_t* data2, uint8_t* out)
|
||||
{
|
||||
for (size_t idx = 0; idx < size; idx++)
|
||||
{
|
||||
out[idx] = data1[idx] ^ data2[idx];
|
||||
}
|
||||
}
|
||||
|
||||
// Crypto Regions
|
||||
size_t offset_;
|
||||
std::vector<CryptRegion> regions_;
|
||||
|
||||
// IO Buffer
|
||||
uint8_t io_buffer_[kIoBufferLen];
|
||||
uint8_t pad_buffer_[kIoBufferLen];
|
||||
|
||||
void GenerateXorPad(size_t start);
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
#include <crypto/AesCtrStream.h>
|
||||
|
||||
using namespace crypto::aes;
|
||||
|
||||
AesCtrStream::AesCtrStream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AesCtrStream::~AesCtrStream()
|
||||
{
|
||||
}
|
||||
|
||||
void AesCtrStream::seek(size_t offset)
|
||||
{
|
||||
offset_ = offset;
|
||||
seek_internal(offset_);
|
||||
}
|
||||
|
||||
void AesCtrStream::read(size_t size, uint8_t * out)
|
||||
{
|
||||
size_t read_len = 0;
|
||||
size_t read_size = 0;
|
||||
for (size_t pos = 0; pos < size; pos += read_size, offset_ += read_size)
|
||||
{
|
||||
// calculate read size
|
||||
read_size = (size - pos) < kIoBufferLen ? (size - pos) : kIoBufferLen;
|
||||
|
||||
// read data
|
||||
read_internal(read_size, read_len, io_buffer_);
|
||||
if (read_size != read_len)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Stream read length unexpected");
|
||||
}
|
||||
|
||||
// crypt data
|
||||
GenerateXorPad(offset_);
|
||||
xor_data(read_size, pad_buffer_, io_buffer_, out + pos);
|
||||
}
|
||||
}
|
||||
|
||||
void AesCtrStream::read(size_t offset, size_t size, uint8_t * out)
|
||||
{
|
||||
seek(offset);
|
||||
read(size, out);
|
||||
}
|
||||
|
||||
void AesCtrStream::write(size_t size, const uint8_t * in)
|
||||
{
|
||||
size_t write_len = 0;
|
||||
size_t write_size = 0;
|
||||
for (size_t pos = 0; pos < size; pos += write_size, offset_ += write_size)
|
||||
{
|
||||
// calculate write size
|
||||
write_size = (size - pos) < kIoBufferLen ? (size - pos) : kIoBufferLen;
|
||||
|
||||
// crypt data
|
||||
GenerateXorPad(offset_);
|
||||
xor_data(write_size, pad_buffer_, in + pos, io_buffer_);
|
||||
|
||||
// write data
|
||||
write_internal(write_size, write_len, io_buffer_);
|
||||
if (write_size != write_len)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Stream write length unexpected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AesCtrStream::write(size_t offset, size_t size, const uint8_t * in)
|
||||
{
|
||||
seek(offset);
|
||||
write(size, in);
|
||||
}
|
||||
|
||||
void AesCtrStream::AddRegion(size_t start, size_t end, const uint8_t aes_key[kAes128KeySize], const uint8_t aes_ctr[kAesBlockSize])
|
||||
{
|
||||
if (start >= end)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Illegal start/end position");
|
||||
}
|
||||
if (aes_key == nullptr || aes_ctr == nullptr)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Illegal aes configuration (nullptr)");
|
||||
}
|
||||
|
||||
regions_.push_back(CryptRegion(start, end, aes_key, aes_ctr));
|
||||
}
|
||||
|
||||
void AesCtrStream::GenerateXorPad(size_t start)
|
||||
{
|
||||
size_t pad_size = 0;
|
||||
for (size_t pos = 0; pos < kIoBufferLen; pos += pad_size)
|
||||
{
|
||||
CryptRegion* cur_region = nullptr;
|
||||
CryptRegion* next_region = nullptr;
|
||||
for (size_t idx = 0; idx < regions_.size(); idx++)
|
||||
{
|
||||
if (regions_[idx].is_in_region(start + pos))
|
||||
{
|
||||
cur_region = ®ions_[idx];
|
||||
}
|
||||
else if (regions_[idx].start() > (start + pos) && (next_region == nullptr || next_region->start() > regions_[idx].start()))
|
||||
{
|
||||
next_region = ®ions_[idx];
|
||||
}
|
||||
}
|
||||
|
||||
// if this exists in the a crypto region
|
||||
if (cur_region != nullptr)
|
||||
{
|
||||
pad_size = cur_region->remaining_size(start + pos);
|
||||
if (pad_size > kIoBufferLen - pos)
|
||||
{
|
||||
pad_size = kIoBufferLen - pos;
|
||||
}
|
||||
cur_region->GenerateXorpad(start + pos, pad_size, pad_buffer_ + pos);
|
||||
}
|
||||
|
||||
// there is a crypto region ahead, bridge the gap
|
||||
else if (next_region != nullptr)
|
||||
{
|
||||
pad_size = next_region->start() - (start + pos);
|
||||
if (pad_size > kIoBufferLen - pos)
|
||||
{
|
||||
pad_size = kIoBufferLen - pos;
|
||||
}
|
||||
memset(pad_buffer_ + pos, 0, pad_size);
|
||||
}
|
||||
// there are no more crypto regions
|
||||
else
|
||||
{
|
||||
pad_size = kIoBufferLen - pos;
|
||||
memset(pad_buffer_ + pos, 0, pad_size);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue