Fixed WBFS reads with 64-bit addresses

This commit is contained in:
Jack Andersen 2015-07-13 16:24:17 -10:00
parent 83f29da294
commit 993b30e4a5
3 changed files with 202 additions and 158 deletions

View File

@ -1,4 +1,5 @@
#include "NOD/DiscGCN.hpp" #include "NOD/DiscGCN.hpp"
#define BUFFER_SZ 0x8000
namespace NOD namespace NOD
{ {
@ -33,15 +34,66 @@ public:
const PartitionGCN& m_parent; const PartitionGCN& m_parent;
std::unique_ptr<IDiscIO::IReadStream> m_dio; std::unique_ptr<IDiscIO::IReadStream> m_dio;
uint64_t m_offset;
size_t m_curBlock = SIZE_MAX;
uint8_t m_buf[BUFFER_SZ];
public: public:
PartReadStream(const PartitionGCN& parent, uint64_t offset) PartReadStream(const PartitionGCN& parent, uint64_t offset)
: m_parent(parent) : m_parent(parent), m_offset(offset)
{m_dio = m_parent.m_parent.getDiscIO().beginReadStream(offset);} {
size_t block = m_offset / BUFFER_SZ;
m_dio = m_parent.m_parent.getDiscIO().beginReadStream(block * BUFFER_SZ);
m_dio->read(m_buf, BUFFER_SZ);
m_curBlock = block;
}
void seek(int64_t offset, int whence) void seek(int64_t offset, int whence)
{m_dio->seek(offset, whence);} {
uint64_t position() const {return m_dio->position();} if (whence == SEEK_SET)
m_offset = offset;
else if (whence == SEEK_CUR)
m_offset += offset;
else
return;
size_t block = m_offset / BUFFER_SZ;
if (block != m_curBlock)
{
m_dio->seek(block * BUFFER_SZ);
m_dio->read(m_buf, BUFFER_SZ);
m_curBlock = block;
}
}
uint64_t position() const {return m_offset;}
uint64_t read(void* buf, uint64_t length) uint64_t read(void* buf, uint64_t length)
{return m_dio->read(buf, length);} {
size_t block = m_offset / BUFFER_SZ;
size_t cacheOffset = m_offset % BUFFER_SZ;
uint64_t cacheSize;
uint64_t rem = length;
uint8_t* dst = (uint8_t*)buf;
while (rem)
{
if (block != m_curBlock)
{
m_dio->read(m_buf, BUFFER_SZ);
m_curBlock = block;
}
cacheSize = rem;
if (cacheSize + cacheOffset > BUFFER_SZ)
cacheSize = BUFFER_SZ - cacheOffset;
memcpy(dst, m_buf + cacheOffset, cacheSize);
dst += cacheSize;
rem -= cacheSize;
cacheOffset = 0;
++block;
}
m_offset += length;
return dst - (uint8_t*)buf;
}
}; };
std::unique_ptr<IPartReadStream> beginReadStream(uint64_t offset) const std::unique_ptr<IPartReadStream> beginReadStream(uint64_t offset) const

View File

@ -251,15 +251,15 @@ public:
if (rem_offset) if (rem_offset)
{ {
uint64_t rem_rem = 4 - rem_offset; uint64_t rem_rem = 4 - rem_offset;
if (wbfsDiscRead((unsigned int)m_offset / 4, extra, 4)) if (wbfsDiscRead((uint32_t)(m_offset / 4), extra, 4))
return 0; return 0;
memcpy(buf, extra + rem_offset, rem_rem); memcpy(buf, extra + rem_offset, rem_rem);
if (wbfsDiscRead((unsigned int)m_offset / 4 + 1, (uint8_t*)buf + rem_rem, length - rem_rem)) if (wbfsDiscRead((uint32_t)(m_offset / 4 + 1), (uint8_t*)buf + rem_rem, length - rem_rem))
return 0; return 0;
} }
else else
{ {
if (wbfsDiscRead((unsigned int)m_offset / 4, (uint8_t*)buf, length)) if (wbfsDiscRead((uint32_t)(m_offset / 4), (uint8_t*)buf, length))
return 0; return 0;
} }
m_offset += length; m_offset += length;

View File

@ -16,8 +16,6 @@ namespace NOD
#define ROTL16(x) (((x)<<16)|((x)>>16)) #define ROTL16(x) (((x)<<16)|((x)>>16))
#define ROTL24(x) (((x)<<24)|((x)>>8)) #define ROTL24(x) (((x)<<24)|((x)>>8))
/* Fixed Data */
static const uint8_t InCo[4] = {0xB, 0xD, 0x9, 0xE}; /* Inverse Coefficients */ static const uint8_t InCo[4] = {0xB, 0xD, 0x9, 0xE}; /* Inverse Coefficients */
static inline uint32_t pack(const uint8_t* b) static inline uint32_t pack(const uint8_t* b)
@ -47,9 +45,8 @@ static inline uint8_t xtime(uint8_t a)
return a; return a;
} }
class SoftwareAES : public IAES static const struct SoftwareAESTables
{ {
protected:
uint8_t fbsub[256]; uint8_t fbsub[256];
uint8_t rbsub[256]; uint8_t rbsub[256];
uint8_t ptab[256], ltab[256]; uint8_t ptab[256], ltab[256];
@ -57,39 +54,15 @@ protected:
uint32_t rtable[256]; uint32_t rtable[256];
uint32_t rco[30]; uint32_t rco[30];
/* Parameter-dependent data */ uint8_t bmul(uint8_t x, uint8_t y) const
{
int Nk, Nb, Nr;
uint8_t fi[24], ri[24];
uint32_t fkey[120];
uint32_t rkey[120];
uint8_t bmul(uint8_t x, uint8_t y);
uint32_t SubByte(uint32_t a);
uint8_t product(uint32_t x, uint32_t y);
uint32_t InvMixCol(uint32_t x);
uint8_t ByteSub(uint8_t x);
void gentables(void);
void gkey(int nb, int nk, const uint8_t* key);
void _encrypt(uint8_t* buff);
void _decrypt(uint8_t* buff);
public:
void encrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len);
void decrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len);
void setKey(const uint8_t* key);
};
uint8_t SoftwareAES::bmul(uint8_t x, uint8_t y)
{
/* x.y= AntiLog(Log(x) + Log(y)) */ /* x.y= AntiLog(Log(x) + Log(y)) */
if (x && y) return ptab[(ltab[x] + ltab[y]) % 255]; if (x && y) return ptab[(ltab[x] + ltab[y]) % 255];
else return 0; else return 0;
} }
uint32_t SoftwareAES::SubByte(uint32_t a) uint32_t SubByte(uint32_t a) const
{ {
uint8_t b[4]; uint8_t b[4];
unpack(a, b); unpack(a, b);
b[0] = fbsub[b[0]]; b[0] = fbsub[b[0]];
@ -97,19 +70,19 @@ uint32_t SoftwareAES::SubByte(uint32_t a)
b[2] = fbsub[b[2]]; b[2] = fbsub[b[2]];
b[3] = fbsub[b[3]]; b[3] = fbsub[b[3]];
return pack(b); return pack(b);
} }
uint8_t SoftwareAES::product(uint32_t x, uint32_t y) uint8_t product(uint32_t x, uint32_t y) const
{ {
/* dot product of two 4-byte arrays */ /* dot product of two 4-byte arrays */
uint8_t xb[4], yb[4]; uint8_t xb[4], yb[4];
unpack(x, xb); unpack(x, xb);
unpack(y, yb); unpack(y, yb);
return bmul(xb[0], yb[0])^bmul(xb[1], yb[1])^bmul(xb[2], yb[2])^bmul(xb[3], yb[3]); return bmul(xb[0], yb[0])^bmul(xb[1], yb[1])^bmul(xb[2], yb[2])^bmul(xb[3], yb[3]);
} }
uint32_t SoftwareAES::InvMixCol(uint32_t x) uint32_t InvMixCol(uint32_t x) const
{ {
/* matrix Multiplication */ /* matrix Multiplication */
uint32_t y, m; uint32_t y, m;
uint8_t b[4]; uint8_t b[4];
@ -124,10 +97,10 @@ uint32_t SoftwareAES::InvMixCol(uint32_t x)
b[0] = product(m, x); b[0] = product(m, x);
y = pack(b); y = pack(b);
return y; return y;
} }
uint8_t SoftwareAES::ByteSub(uint8_t x) uint8_t ByteSub(uint8_t x) const
{ {
uint8_t y = ptab[255 - ltab[x]]; /* multiplicative inverse */ uint8_t y = ptab[255 - ltab[x]]; /* multiplicative inverse */
x = y; x = y;
x = ROTL(x); x = ROTL(x);
@ -140,10 +113,10 @@ uint8_t SoftwareAES::ByteSub(uint8_t x)
y ^= x; y ^= x;
y ^= 0x63; y ^= 0x63;
return y; return y;
} }
void SoftwareAES::gentables(void) SoftwareAESTables()
{ {
/* generate tables */ /* generate tables */
int i; int i;
uint8_t y, b[4]; uint8_t y, b[4];
@ -197,7 +170,27 @@ void SoftwareAES::gentables(void)
b[0] = bmul(InCo[3], y); b[0] = bmul(InCo[3], y);
rtable[i] = pack(b); rtable[i] = pack(b);
} }
} }
} AEStb;
class SoftwareAES : public IAES
{
protected:
/* Parameter-dependent data */
int Nk, Nb, Nr;
uint8_t fi[24], ri[24];
uint32_t fkey[120];
uint32_t rkey[120];
void gkey(int nb, int nk, const uint8_t* key);
void _encrypt(uint8_t* buff);
void _decrypt(uint8_t* buff);
public:
void encrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len);
void decrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len);
void setKey(const uint8_t* key);
};
void SoftwareAES::gkey(int nb, int nk, const uint8_t* key) void SoftwareAES::gkey(int nb, int nk, const uint8_t* key)
{ {
@ -243,7 +236,7 @@ void SoftwareAES::gkey(int nb, int nk, const uint8_t* key)
for (j = Nk, k = 0; j < N; j += Nk, k++) for (j = Nk, k = 0; j < N; j += Nk, k++)
{ {
fkey[j] = fkey[j - Nk] ^ SubByte(ROTL24(fkey[j - 1]))^rco[k]; fkey[j] = fkey[j - Nk] ^ AEStb.SubByte(ROTL24(fkey[j - 1]))^AEStb.rco[k];
if (Nk <= 6) if (Nk <= 6)
{ {
@ -255,7 +248,7 @@ void SoftwareAES::gkey(int nb, int nk, const uint8_t* key)
for (i = 1; i < 4 && (i + j) < N; i++) for (i = 1; i < 4 && (i + j) < N; i++)
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1]; fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
if ((j + 4) < N) fkey[j + 4] = fkey[j + 4 - Nk] ^ SubByte(fkey[j + 3]); if ((j + 4) < N) fkey[j + 4] = fkey[j + 4 - Nk] ^ AEStb.SubByte(fkey[j + 3]);
for (i = 5; i < Nk && (i + j) < N; i++) for (i = 5; i < Nk && (i + j) < N; i++)
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1]; fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
@ -271,7 +264,7 @@ void SoftwareAES::gkey(int nb, int nk, const uint8_t* key)
{ {
k = N - Nb - i; k = N - Nb - i;
for (j = 0; j < Nb; j++) rkey[k + j] = InvMixCol(fkey[i + j]); for (j = 0; j < Nb; j++) rkey[k + j] = AEStb.InvMixCol(fkey[i + j]);
} }
for (j = N - Nb; j < N; j++) rkey[j - N + Nb] = fkey[j]; for (j = N - Nb; j < N; j++) rkey[j - N + Nb] = fkey[j];
@ -309,10 +302,10 @@ void SoftwareAES::_encrypt(uint8_t* buff)
{ {
/* deal with each 32-bit element of the State */ /* deal with each 32-bit element of the State */
/* This is the time-critical bit */ /* This is the time-critical bit */
y[j] = fkey[k++] ^ ftable[(uint8_t)x[j]] ^ y[j] = fkey[k++] ^ AEStb.ftable[(uint8_t)x[j]] ^
ROTL8(ftable[(uint8_t)(x[fi[m]] >> 8)])^ ROTL8(AEStb.ftable[(uint8_t)(x[fi[m]] >> 8)])^
ROTL16(ftable[(uint8_t)(x[fi[m + 1]] >> 16)])^ ROTL16(AEStb.ftable[(uint8_t)(x[fi[m + 1]] >> 16)])^
ROTL24(ftable[(uint8_t)(x[fi[m + 2]] >> 24)]); ROTL24(AEStb.ftable[(uint8_t)(x[fi[m + 2]] >> 24)]);
} }
t = x; t = x;
@ -323,10 +316,10 @@ void SoftwareAES::_encrypt(uint8_t* buff)
/* Last Round - unroll if possible */ /* Last Round - unroll if possible */
for (m = j = 0; j < Nb; j++, m += 3) for (m = j = 0; j < Nb; j++, m += 3)
{ {
y[j] = fkey[k++] ^ (uint32_t)fbsub[(uint8_t)x[j]] ^ y[j] = fkey[k++] ^ (uint32_t)AEStb.fbsub[(uint8_t)x[j]] ^
ROTL8((uint32_t)fbsub[(uint8_t)(x[fi[m]] >> 8)])^ ROTL8((uint32_t)AEStb.fbsub[(uint8_t)(x[fi[m]] >> 8)])^
ROTL16((uint32_t)fbsub[(uint8_t)(x[fi[m + 1]] >> 16)])^ ROTL16((uint32_t)AEStb.fbsub[(uint8_t)(x[fi[m + 1]] >> 16)])^
ROTL24((uint32_t)fbsub[(uint8_t)(x[fi[m + 2]] >> 24)]); ROTL24((uint32_t)AEStb.fbsub[(uint8_t)(x[fi[m + 2]] >> 24)]);
} }
for (i = j = 0; i < Nb; i++, j += 4) for (i = j = 0; i < Nb; i++, j += 4)
@ -364,10 +357,10 @@ void SoftwareAES::_decrypt(uint8_t* buff)
for (m = j = 0; j < Nb; j++, m += 3) for (m = j = 0; j < Nb; j++, m += 3)
{ {
/* This is the time-critical bit */ /* This is the time-critical bit */
y[j] = rkey[k++] ^ rtable[(uint8_t)x[j]] ^ y[j] = rkey[k++] ^ AEStb.rtable[(uint8_t)x[j]] ^
ROTL8(rtable[(uint8_t)(x[ri[m]] >> 8)])^ ROTL8(AEStb.rtable[(uint8_t)(x[ri[m]] >> 8)])^
ROTL16(rtable[(uint8_t)(x[ri[m + 1]] >> 16)])^ ROTL16(AEStb.rtable[(uint8_t)(x[ri[m + 1]] >> 16)])^
ROTL24(rtable[(uint8_t)(x[ri[m + 2]] >> 24)]); ROTL24(AEStb.rtable[(uint8_t)(x[ri[m + 2]] >> 24)]);
} }
t = x; t = x;
@ -378,10 +371,10 @@ void SoftwareAES::_decrypt(uint8_t* buff)
/* Last Round - unroll if possible */ /* Last Round - unroll if possible */
for (m = j = 0; j < Nb; j++, m += 3) for (m = j = 0; j < Nb; j++, m += 3)
{ {
y[j] = rkey[k++] ^ (uint32_t)rbsub[(uint8_t)x[j]] ^ y[j] = rkey[k++] ^ (uint32_t)AEStb.rbsub[(uint8_t)x[j]] ^
ROTL8((uint32_t)rbsub[(uint8_t)(x[ri[m]] >> 8)])^ ROTL8((uint32_t)AEStb.rbsub[(uint8_t)(x[ri[m]] >> 8)])^
ROTL16((uint32_t)rbsub[(uint8_t)(x[ri[m + 1]] >> 16)])^ ROTL16((uint32_t)AEStb.rbsub[(uint8_t)(x[ri[m + 1]] >> 16)])^
ROTL24((uint32_t)rbsub[(uint8_t)(x[ri[m + 2]] >> 24)]); ROTL24((uint32_t)AEStb.rbsub[(uint8_t)(x[ri[m + 2]] >> 24)]);
} }
for (i = j = 0; i < Nb; i++, j += 4) for (i = j = 0; i < Nb; i++, j += 4)
@ -395,7 +388,6 @@ void SoftwareAES::_decrypt(uint8_t* buff)
void SoftwareAES::setKey(const uint8_t* key) void SoftwareAES::setKey(const uint8_t* key)
{ {
gentables();
gkey(4, 4, key); gkey(4, 4, key);
} }