Пример #1
0
void CData::CryptBlock(Byte *buf, bool encrypt)
{
  Byte inBuf[16];
  UInt32 A, B, C, D, T, TA, TB;

  A = GetUi32(buf +  0) ^ Keys[0];
  B = GetUi32(buf +  4) ^ Keys[1];
  C = GetUi32(buf +  8) ^ Keys[2];
  D = GetUi32(buf + 12) ^ Keys[3];

  if (!encrypt)
    memcpy(inBuf, buf, sizeof(inBuf));
  
  for (int i = 0; i < kNumRounds; i++)
  {
    UInt32 key = Keys[(encrypt ? i : (kNumRounds - 1 - i)) & 3];
    T = ((C + rotlFixed(D, 11)) ^ key);
    TA = A ^ SubstLong(T);
    T = ((D ^ rotlFixed(C, 17)) + key);
    TB = B ^ SubstLong(T);
    A = C;
    B = D;
    C = TA;
    D = TB;
  }

  SetUi32(buf +  0, C ^ Keys[0]);
  SetUi32(buf +  4, D ^ Keys[1]);
  SetUi32(buf +  8, A ^ Keys[2]);
  SetUi32(buf + 12, B ^ Keys[3]);

  UpdateKeys(encrypt ? buf : inBuf);
}
Пример #2
0
UInt32 MY_FAST_CALL AesCbcDecode(CAesCbc *cbc, Byte *data, UInt32 size)
{
  UInt32 i;
  UInt32 in[4], out[4];
  if (size == 0)
    return 0;
  if (size < AES_BLOCK_SIZE)
    return AES_BLOCK_SIZE;
  size -= AES_BLOCK_SIZE;
  for (i = 0; i <= size; i += AES_BLOCK_SIZE, data += AES_BLOCK_SIZE)
  {
    in[0] = GetUi32(data);
    in[1] = GetUi32(data + 4);
    in[2] = GetUi32(data + 8);
    in[3] = GetUi32(data + 12);
    
    AesDecode32(in, out, cbc->aes.rkey, cbc->aes.numRounds2);
    
    SetUi32(data,      cbc->prev[0] ^ out[0]);
    SetUi32(data + 4,  cbc->prev[1] ^ out[1]);
    SetUi32(data + 8,  cbc->prev[2] ^ out[2]);
    SetUi32(data + 12, cbc->prev[3] ^ out[3]);
    
    cbc->prev[0] = in[0];
    cbc->prev[1] = in[1];
    cbc->prev[2] = in[2];
    cbc->prev[3] = in[3];
  }
  return i;
}
Пример #3
0
SizeT AesCbc_Decode(CAesCbc *p, Byte *data, SizeT size)
{
  if (size == 0)
    return 0;
  if (size < AES_BLOCK_SIZE)
    return AES_BLOCK_SIZE;
  size -= AES_BLOCK_SIZE;

  SizeT i;
  UInt32 in[4], out[4];

  for (i = 0; i <= size; i += AES_BLOCK_SIZE, data += AES_BLOCK_SIZE)
  {
    in[0] = GetUi32(data);
    in[1] = GetUi32(data + 4);
    in[2] = GetUi32(data + 8);
    in[3] = GetUi32(data + 12);
    
    AesDecode32(out, in, p->aes.rkey, p->aes.numRounds2);
    
    SetUi32(data,      p->prev[0] ^ out[0]);
    SetUi32(data + 4,  p->prev[1] ^ out[1]);
    SetUi32(data + 8,  p->prev[2] ^ out[2]);
    SetUi32(data + 12, p->prev[3] ^ out[3]);
    
    p->prev[0] = in[0];
    p->prev[1] = in[1];
    p->prev[2] = in[2];
    p->prev[3] = in[3];
  }

  return i;
}
Пример #4
0
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{
  Byte *p;
  const Byte *lim;
  size &= ~(size_t)3;
  ip += 4;
  p = data;
  lim = data + size;

  if (encoding)

  for (;;)
  {
    for (;;)
    {
      if (p >= lim)
        return p - data;
      p += 4;
      if (p[-1] == 0xEB)
        break;
    }
    {
      UInt32 v = GetUi32(p - 4);
      v <<= 2;
        v += ip + (UInt32)(p - data);
      v >>= 2;
      v &= 0x00FFFFFF;
      v |= 0xEB000000;
      SetUi32(p - 4, v);
    }
  }

  for (;;)
  {
    for (;;)
    {
      if (p >= lim)
        return p - data;
      p += 4;
      if (p[-1] == 0xEB)
        break;
    }
    {
      UInt32 v = GetUi32(p - 4);
      v <<= 2;
        v -= ip + (UInt32)(p - data);
      v >>= 2;
      v &= 0x00FFFFFF;
      v |= 0xEB000000;
      SetUi32(p - 4, v);
    }
  }
}
Пример #5
0
static Bool FindSignature(CSzFile *stream, UInt64 *resPos)
{
  Byte buf[kBufferSize];
  size_t numPrevBytes = 0;
  *resPos = 0;
  for (;;)
  {
    size_t processed, pos;
    if (*resPos > kSignatureSearchLimit)
      return False;
    processed = kBufferSize - numPrevBytes;
    if (File_Read(stream, buf + numPrevBytes, &processed) != 0)
      return False;
    processed += numPrevBytes;
    if (processed < k7zStartHeaderSize ||
        (processed == k7zStartHeaderSize && numPrevBytes != 0))
      return False;
    processed -= k7zStartHeaderSize;
    for (pos = 0; pos <= processed; pos++)
    {
      for (; pos <= processed && buf[pos] != '7'; pos++);
      if (pos > processed)
        break;
      if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0)
        if (CrcCalc(buf + pos + 12, 20) == GetUi32(buf + pos + 8))
        {
          *resPos += pos;
          return True;
        }
    }
    *resPos += processed;
    numPrevBytes = k7zStartHeaderSize;
    memmove(buf, buf + processed, k7zStartHeaderSize);
  }
}
Пример #6
0
HRESULT CCabBlockInStream::PreRead(ISequentialInStream *stream, UInt32 &packSize, UInt32 &unpackSize)
{
  const UInt32 kHeaderSize = 8;
  const UInt32 kReservedMax = 256;
  Byte header[kHeaderSize + kReservedMax];
  RINOK(ReadStream_FALSE(stream, header, kHeaderSize + ReservedSize))
  packSize = GetUi16(header + 4);
  unpackSize = GetUi16(header + 6);
  if (packSize > kBlockSize - _size)
    return S_FALSE;
  RINOK(ReadStream_FALSE(stream, _buf + _size, packSize));
  
  if (MsZip)
  {
    if (_size == 0)
    {
      if (packSize < 2 || _buf[0] != 0x43 || _buf[1] != 0x4B)
        return S_FALSE;
      _pos = 2;
    }
    if (_size + packSize > ((UInt32)1 << 15) + 12) /* v9.31 fix. MSZIP specification */
      return S_FALSE;
  }

  if (GetUi32(header) != 0) // checkSum
    if (CheckSum(header, kHeaderSize + ReservedSize) != CheckSum(_buf + _size, packSize))
      return S_FALSE;

  _size += packSize;
  return S_OK;
}
Пример #7
0
HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream, UInt32 crc, UInt64 unpackSize)
{
  Byte temp[4];
  RINOK(ReadStream_FALSE(inStream, temp, 2));
  _ivSize = GetUi16(temp);
  if (_ivSize == 0)
  {
    memset(_iv, 0, 16);
    SetUi32(_iv + 0, crc);
    SetUi64(_iv + 4, unpackSize);
    _ivSize = 12;
  }
  else if (_ivSize == 16)
  {
    RINOK(ReadStream_FALSE(inStream, _iv, _ivSize));
  }
  else
    return E_NOTIMPL;
  RINOK(ReadStream_FALSE(inStream, temp, 4));
  _remSize = GetUi32(temp);
  const UInt32 kAlign = 16;
  if (_remSize < 16 || _remSize > (1 << 18))
    return E_NOTIMPL;
  if (_remSize + kAlign > _buf.Size())
  {
    _buf.Alloc(_remSize + kAlign);
    _bufAligned = (Byte *)((ptrdiff_t)((Byte *)_buf + kAlign - 1) & ~(ptrdiff_t)(kAlign - 1));
  }
  return ReadStream_FALSE(inStream, _bufAligned, _remSize);
}
Пример #8
0
HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream, UInt32 crc, UInt64 unpackSize)
{
  Byte temp[4];
  RINOK(ReadStream_FALSE(inStream, temp, 2));
  _ivSize = GetUi16(temp);
  if (_ivSize == 0)
  {
    memset(_iv, 0, 16);
    SetUi32(_iv + 0, crc);
    SetUi64(_iv + 4, unpackSize);
    _ivSize = 12;
  }
  else if (_ivSize == 16)
  {
    RINOK(ReadStream_FALSE(inStream, _iv, _ivSize));
  }
  else
    return E_NOTIMPL;
  RINOK(ReadStream_FALSE(inStream, temp, 4));
  _remSize = GetUi32(temp);
  // const UInt32 kAlign = 16;
  if (_remSize < 16 || _remSize > (1 << 18))
    return E_NOTIMPL;
  if (_remSize > _bufAligned.Size())
  {
    _bufAligned.AllocAtLeast(_remSize);
    if (!(Byte *)_bufAligned)
      return E_OUTOFMEMORY;
  }
  return ReadStream_FALSE(inStream, _bufAligned, _remSize);
}
Пример #9
0
static inline bool TestSignature(const Byte *p)
{
  for (int i = 0; i < kSignatureSize; i++)
    if (p[i] != kSignature[i])
      return false;
  return CrcCalc(p + 12, 20) == GetUi32(p + 8);
}
Пример #10
0
Файл: Aes.c Проект: Dabil/puNES
void MY_FAST_CALL AesCbc_Encode(UInt32 *p, Byte *data, size_t numBlocks)
{
  for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE)
  {
    p[0] ^= GetUi32(data);
    p[1] ^= GetUi32(data + 4);
    p[2] ^= GetUi32(data + 8);
    p[3] ^= GetUi32(data + 12);
    
    Aes_Encode(p + 4, p, p);
    
    SetUi32(data,      p[0]);
    SetUi32(data + 4,  p[1]);
    SetUi32(data + 8,  p[2]);
    SetUi32(data + 12, p[3]);
  }
}
Пример #11
0
static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
{
  CPpmd7 ppmd;
  CByteInToLook s;
  SRes res = SZ_OK;

  s.p.Read = ReadByte;
  s.inStream = inStream;
  s.begin = s.end = s.cur = NULL;
  s.extra = False;
  s.res = SZ_OK;
  s.processed = 0;

  if (coder->Props.size != 5)
    return SZ_ERROR_UNSUPPORTED;

  {
    unsigned order = coder->Props.data[0];
    UInt32 memSize = GetUi32(coder->Props.data + 1);
    if (order < PPMD7_MIN_ORDER ||
        order > PPMD7_MAX_ORDER ||
        memSize < PPMD7_MIN_MEM_SIZE ||
        memSize > PPMD7_MAX_MEM_SIZE)
      return SZ_ERROR_UNSUPPORTED;
    Ppmd7_Construct(&ppmd);
    if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
      return SZ_ERROR_MEM;
    Ppmd7_Init(&ppmd, order);
  }
  {
    CPpmd7z_RangeDec rc;
    Ppmd7z_RangeDec_CreateVTable(&rc);
    rc.Stream = &s.p;
    if (!Ppmd7z_RangeDec_Init(&rc))
      res = SZ_ERROR_DATA;
    else if (s.extra)
      res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
    else
    {
      SizeT i;
      for (i = 0; i < outSize; i++)
      {
        int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);
        if (s.extra || sym < 0)
          break;
        outBuffer[i] = (Byte)sym;
      }
      if (i != outSize)
        res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
      else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))
        res = SZ_ERROR_DATA;
    }
  }
  Ppmd7_Free(&ppmd, allocMain);
  return res;
}
Пример #12
0
static bool ParseInt64_MTime(const char *p, Int64 &val)
{
  // rare case tar : ZEROs in Docker-Windows TARs
  // rare case tar : spaces
  if (GetUi32(p) != 0)
  for (unsigned i = 0; i < 12; i++)
    if (p[i] != ' ')
      return ParseInt64(p, val);
  val = 0;
  return true;
}
Пример #13
0
static inline bool TestSignature2(const Byte *p)
{
  int i;
  for (i = 0; i < kSignatureSize; i++)
    if (p[i] != kSignature[i])
      return false;
  if (CrcCalc(p + 12, 20) == GetUi32(p + 8))
    return true;
  for (i = 8; i < kHeaderSize; i++)
    if (p[i] != 0)
      return false;
  return (p[6] != 0 || p[7] != 0);
}
Пример #14
0
API_FUNC_static_IsArc IsArc_Swfc(const Byte *p, size_t size)
{
  if (size < kHeaderBaseSize + 2 + 1) // 2 + 1 (for zlib check)
    return k_IsArc_Res_NEED_MORE;
  if ((p[0] != SWF_COMPRESSED_ZLIB &&
      p[0] != SWF_COMPRESSED_LZMA) ||
      p[1] != 'W' ||
      p[2] != 'S' ||
      p[3] >= kVerLim)
    return k_IsArc_Res_NO;
  UInt32 uncompressedSize = GetUi32(p + 4);
  if (uncompressedSize > kFileSizeMax)
    return k_IsArc_Res_NO;

  if (p[0] == SWF_COMPRESSED_ZLIB)
  {
    if (!NCompress::NZlib::IsZlib_3bytes(p + 8))
      return k_IsArc_Res_NO;
  }
  else
  {
    if (size < kHeaderLzmaSize + 2)
      return k_IsArc_Res_NEED_MORE;
    if (p[kHeaderLzmaSize] != 0 ||
        (p[kHeaderLzmaSize + 1] & 0x80) != 0)
      return k_IsArc_Res_NO;
    UInt32 lzmaPackSize = GetUi32(p + 8);
    UInt32 lzmaProp = p[12];
    UInt32 lzmaDicSize = GetUi32(p + 13);
    if (lzmaProp > 5 * 5 * 9 ||
        lzmaDicSize > ((UInt32)1 << 28) ||
        lzmaPackSize < 5 ||
        lzmaPackSize > ((UInt32)1 << 28))
      return k_IsArc_Res_NO;
  }

  return k_IsArc_Res_YES;
}
Пример #15
0
Файл: Aes.c Проект: Dabil/puNES
void MY_FAST_CALL AesCbc_Decode(UInt32 *p, Byte *data, size_t numBlocks)
{
  UInt32 in[4], out[4];
  for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE)
  {
    in[0] = GetUi32(data);
    in[1] = GetUi32(data + 4);
    in[2] = GetUi32(data + 8);
    in[3] = GetUi32(data + 12);

    Aes_Decode(p + 4, out, in);

    SetUi32(data,      p[0] ^ out[0]);
    SetUi32(data + 4,  p[1] ^ out[1]);
    SetUi32(data + 8,  p[2] ^ out[2]);
    SetUi32(data + 12, p[3] ^ out[3]);
    
    p[0] = in[0];
    p[1] = in[1];
    p[2] = in[2];
    p[3] = in[3];
  }
}
Пример #16
0
static UInt32 CheckSum(const Byte *p, UInt32 size)
{
  UInt32 sum = 0;
  
  for (; size >= 8; size -= 8)
  {
    sum ^= GetUi32(p) ^ GetUi32(p + 4);
    p += 8;
  }
  
  if (size >= 4)
  {
    sum ^= GetUi32(p);
    p += 4;
  }
  
  size &= 3;
  if (size > 2) sum ^= (UInt32)(*p++) << 16;
  if (size > 1) sum ^= (UInt32)(*p++) << 8;
  if (size > 0) sum ^= (UInt32)(*p++);
  
  return sum;
}
Пример #17
0
API_FUNC_static_IsArc IsArc_Swf(const Byte *p, size_t size)
{
  if (size < kHeaderBaseSize)
    return k_IsArc_Res_NEED_MORE;
  if (p[0] != SWF_UNCOMPRESSED ||
      p[1] != 'W' ||
      p[2] != 'S' ||
      p[3] >= kVerLim)
    return k_IsArc_Res_NO;
  UInt32 uncompressedSize = GetUi32(p + 4);
  if (uncompressedSize > kFileSizeMax)
    return k_IsArc_Res_NO;
  return k_IsArc_Res_YES;
}
Пример #18
0
SizeT AesCbc_Encode(CAesCbc *p, Byte *data, SizeT size)
{
  SizeT i;
  if (size == 0)
    return 0;
  if (size < AES_BLOCK_SIZE)
    return AES_BLOCK_SIZE;
  size -= AES_BLOCK_SIZE;
  for (i = 0; i <= size; i += AES_BLOCK_SIZE, data += AES_BLOCK_SIZE)
  {
    p->prev[0] ^= GetUi32(data);
    p->prev[1] ^= GetUi32(data + 4);
    p->prev[2] ^= GetUi32(data + 8);
    p->prev[3] ^= GetUi32(data + 12);
    
    AesEncode32(p->prev, p->prev, p->aes.rkey, p->aes.numRounds2);
    
    SetUi32(data,      p->prev[0]);
    SetUi32(data + 4,  p->prev[1]);
    SetUi32(data + 8,  p->prev[2]);
    SetUi32(data + 12, p->prev[3]);
  }
  return i;
}
Пример #19
0
UInt32 MY_FAST_CALL AesCbcEncode(CAesCbc *cbc, Byte *data, UInt32 size)
{
  UInt32 i;
  if (size == 0)
    return 0;
  if (size < AES_BLOCK_SIZE)
    return AES_BLOCK_SIZE;
  size -= AES_BLOCK_SIZE;
  for (i = 0; i <= size; i += AES_BLOCK_SIZE, data += AES_BLOCK_SIZE)
  {
    cbc->prev[0] ^= GetUi32(data);
    cbc->prev[1] ^= GetUi32(data + 4);
    cbc->prev[2] ^= GetUi32(data + 8);
    cbc->prev[3] ^= GetUi32(data + 12);
    
    AesEncode32(cbc->prev, cbc->prev, cbc->aes.rkey, cbc->aes.numRounds2);
    
    SetUi32(data,      cbc->prev[0]);
    SetUi32(data + 4,  cbc->prev[1]);
    SetUi32(data + 8,  cbc->prev[2]);
    SetUi32(data + 12, cbc->prev[3]);
  }
  return i;
}
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)
{
  if (size < 5)
    return E_INVALIDARG;
  _order = props[0];
  UInt32 memSize = GetUi32(props + 1);
  if (_order < PPMD7_MIN_ORDER ||
      _order > PPMD7_MAX_ORDER ||
      memSize < PPMD7_MIN_MEM_SIZE ||
      memSize > PPMD7_MAX_MEM_SIZE)
    return E_NOTIMPL;
  if (!_inStream.Alloc(1 << 20))
    return E_OUTOFMEMORY;
  if (!Ppmd7_Alloc(&_ppmd, memSize, &g_BigAlloc))
    return E_OUTOFMEMORY;
  return S_OK;
}
Пример #21
0
static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc)
{
  size_t i, numBlocks, crcStartPos, pos = 1;
  UInt32 crc;

  if (size < 5 || buf[0] != 0)
    return SZ_ERROR_ARCHIVE;

  size -= 4;
  crc = CrcCalc(buf, size);
  if (crc != GetUi32(buf + size))
    return SZ_ERROR_ARCHIVE;

  {
    UInt64 numBlocks64;
    READ_VARINT_AND_CHECK(buf, pos, size, &numBlocks64);
    numBlocks = (size_t)numBlocks64;
    if (numBlocks != numBlocks64 || numBlocks * 2 > size)
      return SZ_ERROR_ARCHIVE;
  }

  crcStartPos = pos;
  Xz_Free(p, alloc);
  if (numBlocks != 0)
  {
    p->numBlocks = numBlocks;
    p->numBlocksAllocated = numBlocks;
    p->blocks = alloc->Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks);
    if (p->blocks == 0)
      return SZ_ERROR_MEM;
    for (i = 0; i < numBlocks; i++)
    {
      CXzBlockSizes *block = &p->blocks[i];
      READ_VARINT_AND_CHECK(buf, pos, size, &block->totalSize);
      READ_VARINT_AND_CHECK(buf, pos, size, &block->unpackSize);
      if (block->totalSize == 0)
        return SZ_ERROR_ARCHIVE;
    }
  }
  while ((pos & 3) != 0)
    if (buf[pos++] != 0)
      return SZ_ERROR_ARCHIVE;
  return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;
}
Пример #22
0
bool CExtraSubBlock::ExtractInfoZipUnicodePath(AString &name, AString &res) const
{
  res.Empty();

  if (ID != NFileHeader::NExtraID::kInfoZipUnicodePath ||
      (UInt32)Data.Size() < 5 ||
      *(const Byte *)Data < 1 ||
      GetUi32((const Byte *)Data + 1) != CrcCalc(name, name.Len()))
    return false;

  int size = (int)Data.Size() - sizeof(short) * 2 - sizeof(Byte);
  if (size > 0)
  {
    char *p = res.GetBuffer(size + 1);
    memcpy(p, (const Byte *)Data + sizeof(short) * 2 + sizeof(Byte), size);
    p[size] = '\0';
    res.ReleaseBuffer();
  }
  return true;
}
Пример #23
0
	static Bool FindSignature(CInBuf *stream, UInt64 *resPos)
	{
		Byte buf[kBufferSize];
		size_t numPrevBytes = 0;
		*resPos = 0;
		for (;;)
		{
			size_t numTests, pos;
			if (*resPos > kSignatureSearchLimit)
				return False;

			do
			{
				size_t processed = kBufferSize - numPrevBytes;
				if (InBuf_Read(stream, buf + numPrevBytes, &processed) != 0)
					return False;
				if (processed == 0)
					return False;
				numPrevBytes += processed;
			}
			while (numPrevBytes <= k7zStartHeaderSize);

			numTests = numPrevBytes - k7zStartHeaderSize;
			for (pos = 0; pos < numTests; pos++)
			{
				for (; buf[pos] != '7' && pos < numTests; pos++);
				if (pos == numTests)
					break;
				if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0)
					if (CrcCalc(buf + pos + 12, 20) == GetUi32(buf + pos + 8))
					{
						*resPos += pos;
						return True;
					}
			}
			*resPos += numTests;
			numPrevBytes -= numTests;
			memmove(buf, buf + numTests, numPrevBytes);
		}
	}
Пример #24
0
Файл: Aes.c Проект: Dabil/puNES
void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize)
{
  unsigned i, wSize;
  wSize = keySize + 28;
  keySize /= 4;
  w[0] = ((UInt32)keySize / 2) + 3;
  w += 4;

  for (i = 0; i < keySize; i++, key += 4)
    w[i] = GetUi32(key);

  for (; i < wSize; i++)
  {
    UInt32 t = w[i - 1];
    unsigned rem = i % keySize;
    if (rem == 0)
      t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]);
    else if (keySize > 6 && rem == 4)
      t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]);
    w[i] = w[i - keySize] ^ t;
  }
}
Пример #25
0
static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAlloc *alloc)
{
  UInt64 indexSize;
  Byte buf[XZ_STREAM_FOOTER_SIZE];

  if ((*startOffset & 3) != 0 || *startOffset < XZ_STREAM_FOOTER_SIZE)
    return SZ_ERROR_NO_ARCHIVE;
  *startOffset = -XZ_STREAM_FOOTER_SIZE;
  RINOK(SeekFromCur(stream, startOffset));

  RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));

  if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
  {
    UInt32 total = 0;
    *startOffset += XZ_STREAM_FOOTER_SIZE;
    for (;;)
    {
      size_t i;
      #define TEMP_BUF_SIZE (1 << 10)
      Byte tempBuf[TEMP_BUF_SIZE];
      if (*startOffset < XZ_STREAM_FOOTER_SIZE || total > (1 << 16))
        return SZ_ERROR_NO_ARCHIVE;
      i = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset;
      total += (UInt32)i;
      *startOffset = -(Int64)i;
      RINOK(SeekFromCur(stream, startOffset));
      RINOK(LookInStream_Read2(stream, tempBuf, i, SZ_ERROR_NO_ARCHIVE));
      for (; i != 0; i--)
        if (tempBuf[i - 1] != 0)
          break;
      if (i != 0)
      {
        if ((i & 3) != 0)
          return SZ_ERROR_NO_ARCHIVE;
        *startOffset += i;
        break;
      }
    }
    if (*startOffset < XZ_STREAM_FOOTER_SIZE)
      return SZ_ERROR_NO_ARCHIVE;
    *startOffset -= XZ_STREAM_FOOTER_SIZE;
    RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));
    RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
    if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
      return SZ_ERROR_NO_ARCHIVE;
  }

  p->flags = (CXzStreamFlags)GetBe16(buf + 8);

  if (!XzFlags_IsSupported(p->flags))
    return SZ_ERROR_UNSUPPORTED;

  if (GetUi32(buf) != CrcCalc(buf + 4, 6))
    return SZ_ERROR_ARCHIVE;

  indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2;

  *startOffset = -(Int64)(indexSize + XZ_STREAM_FOOTER_SIZE);
  RINOK(SeekFromCur(stream, startOffset));

  RINOK(Xz_ReadIndex(p, stream, indexSize, alloc));

  {
    UInt64 totalSize = Xz_GetPackSize(p);
    UInt64 sum = XZ_STREAM_HEADER_SIZE + totalSize + indexSize;
    if (totalSize == XZ_SIZE_OVERFLOW ||
      sum >= ((UInt64)1 << 63) ||
      totalSize >= ((UInt64)1 << 63))
      return SZ_ERROR_ARCHIVE;
    *startOffset = -(Int64)sum;
    RINOK(SeekFromCur(stream, startOffset));
  }
  {
    CXzStreamFlags headerFlags;
    CSecToRead secToRead;
    SecToRead_CreateVTable(&secToRead);
    secToRead.realStream = stream;

    RINOK(Xz_ReadHeader(&headerFlags, &secToRead.s));
    return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE;
  }
}
Пример #26
0
void AesCbc_Init(CAesCbc *p, const Byte *iv)
{
  unsigned i;
  for (i = 0; i < 4; i++)
    p->prev[i] = GetUi32(iv + i * 4);
}
Пример #27
0
static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAllocPtr alloc)
{
  UInt64 indexSize;
  Byte buf[XZ_STREAM_FOOTER_SIZE];
  UInt64 pos = *startOffset;

  if ((pos & 3) != 0 || pos < XZ_STREAM_FOOTER_SIZE)
    return SZ_ERROR_NO_ARCHIVE;

  pos -= XZ_STREAM_FOOTER_SIZE;
  RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE));
  
  if (!XZ_FOOTER_SIG_CHECK(buf + 10))
  {
    UInt32 total = 0;
    pos += XZ_STREAM_FOOTER_SIZE;
    
    for (;;)
    {
      size_t i;
      #define TEMP_BUF_SIZE (1 << 10)
      Byte temp[TEMP_BUF_SIZE];
      
      i = (pos > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)pos;
      pos -= i;
      RINOK(LookInStream_SeekRead_ForArc(stream, pos, temp, i));
      total += (UInt32)i;
      for (; i != 0; i--)
        if (temp[i - 1] != 0)
          break;
      if (i != 0)
      {
        if ((i & 3) != 0)
          return SZ_ERROR_NO_ARCHIVE;
        pos += i;
        break;
      }
      if (pos < XZ_STREAM_FOOTER_SIZE || total > (1 << 16))
        return SZ_ERROR_NO_ARCHIVE;
    }
    
    if (pos < XZ_STREAM_FOOTER_SIZE)
      return SZ_ERROR_NO_ARCHIVE;
    pos -= XZ_STREAM_FOOTER_SIZE;
    RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE));
    if (!XZ_FOOTER_SIG_CHECK(buf + 10))
      return SZ_ERROR_NO_ARCHIVE;
  }
  
  p->flags = (CXzStreamFlags)GetBe16(buf + 8);

  if (!XzFlags_IsSupported(p->flags))
    return SZ_ERROR_UNSUPPORTED;

  if (GetUi32(buf) != CrcCalc(buf + 4, 6))
    return SZ_ERROR_ARCHIVE;

  indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2;

  if (pos < indexSize)
    return SZ_ERROR_ARCHIVE;

  pos -= indexSize;
  RINOK(LookInStream_SeekTo(stream, pos));
  RINOK(Xz_ReadIndex(p, stream, indexSize, alloc));

  {
    UInt64 totalSize = Xz_GetPackSize(p);
    if (totalSize == XZ_SIZE_OVERFLOW
        || totalSize >= ((UInt64)1 << 63)
        || pos < totalSize + XZ_STREAM_HEADER_SIZE)
      return SZ_ERROR_ARCHIVE;
    pos -= (totalSize + XZ_STREAM_HEADER_SIZE);
    RINOK(LookInStream_SeekTo(stream, pos));
    *startOffset = pos;
  }
  {
    CXzStreamFlags headerFlags;
    CSecToRead secToRead;
    SecToRead_CreateVTable(&secToRead);
    secToRead.realStream = stream;

    RINOK(Xz_ReadHeader(&headerFlags, &secToRead.vt));
    return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE;
  }
}
Пример #28
0
Файл: Aes.c Проект: Dabil/puNES
void AesCbc_Init(UInt32 *p, const Byte *iv)
{
  unsigned i;
  for (i = 0; i < 4; i++)
    p[i] = GetUi32(iv + i * 4);
}
Пример #29
0
static SRes SzArEx_Open2(
      CSzArEx *p,
      ILookInStream *inStream,
      ISzAlloc *allocMain,
      ISzAlloc *allocTemp)
{
   uint8_t header[k7zStartHeaderSize];
   int64_t startArcPos;
   uint64_t nextHeaderOffset, nextHeaderSize;
   size_t nextHeaderSizeT;
   uint32_t nextHeaderCRC;
   CBuf buffer;
   SRes res;

   startArcPos = 0;
   RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));

   RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));

   if (!TestSignatureCandidate(header))
      return SZ_ERROR_NO_ARCHIVE;
   if (header[6] != k7zMajorVersion)
      return SZ_ERROR_UNSUPPORTED;

   nextHeaderOffset = GetUi64(header + 12);
   nextHeaderSize = GetUi64(header + 20);
   nextHeaderCRC = GetUi32(header + 28);

   p->startPosAfterHeader = startArcPos + k7zStartHeaderSize;

   if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
      return SZ_ERROR_CRC;

   nextHeaderSizeT = (size_t)nextHeaderSize;
   if (nextHeaderSizeT != nextHeaderSize)
      return SZ_ERROR_MEM;
   if (nextHeaderSizeT == 0)
      return SZ_OK;
   if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize ||
         nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)
      return SZ_ERROR_NO_ARCHIVE;

   {
      int64_t pos = 0;
      RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
      if ((uint64_t)pos < startArcPos + nextHeaderOffset ||
            (uint64_t)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
            (uint64_t)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
         return SZ_ERROR_INPUT_EOF;
   }

   RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset));

   if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
      return SZ_ERROR_MEM;

   res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT);
   if (res == SZ_OK)
   {
      res = SZ_ERROR_ARCHIVE;
      if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC)
      {
         CSzData sd;
         uint64_t type;
         sd.Data = buffer.data;
         sd.Size = buffer.size;
         res = SzReadID(&sd, &type);
         if (res == SZ_OK)
         {
            if (type == k7zIdEncodedHeader)
            {
               CBuf outBuffer;
               Buf_Init(&outBuffer);
               res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp);
               if (res != SZ_OK)
                  Buf_Free(&outBuffer, allocTemp);
               else
               {
                  Buf_Free(&buffer, allocTemp);
                  buffer.data = outBuffer.data;
                  buffer.size = outBuffer.size;
                  sd.Data = buffer.data;
                  sd.Size = buffer.size;
                  res = SzReadID(&sd, &type);
               }
            }
         }
         if (res == SZ_OK)
         {
            if (type == k7zIdHeader)
               res = SzReadHeader(p, &sd, allocMain, allocTemp);
            else
               res = SZ_ERROR_UNSUPPORTED;
         }
      }
   }
   Buf_Free(&buffer, allocTemp);
   return res;
}
Пример #30
0
HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
{
  passwOK = false;
  if (_remSize < 16)
    return E_NOTIMPL;
  Byte *p = _bufAligned;
  UInt16 format = GetUi16(p);
  if (format != 3)
    return E_NOTIMPL;
  UInt16 algId = GetUi16(p + 2);
  if (algId < kAES128)
    return E_NOTIMPL;
  algId -= kAES128;
  if (algId > 2)
    return E_NOTIMPL;
  UInt16 bitLen = GetUi16(p + 4);
  UInt16 flags = GetUi16(p + 6);
  if (algId * 64 + 128 != bitLen)
    return E_NOTIMPL;
  _key.KeySize = 16 + algId * 8;
  bool cert = ((flags & 2) != 0);

  if ((flags & 0x4000) != 0)
  {
    // Use 3DES for rd data
    return E_NOTIMPL;
  }

  if (cert)
  {
    return E_NOTIMPL;
  }
  else
  {
    if ((flags & 1) == 0)
      return E_NOTIMPL;
  }

  UInt32 rdSize = GetUi16(p + 8);

  if (rdSize + 16 > _remSize)
    return E_NOTIMPL;

  const unsigned kPadSize = kAesPadAllign; // is equal to blockSize of cipher for rd

  /*
  if (cert)
  {
    if ((rdSize & 0x7) != 0)
      return E_NOTIMPL;
  }
  else
  */
  {
    // PKCS7 padding
    if (rdSize < kPadSize)
      return E_NOTIMPL;
    if ((rdSize & (kPadSize - 1)) != 0)
      return E_NOTIMPL;
  }

  memmove(p, p + 10, rdSize);
  const Byte *p2 = p + rdSize + 10;
  UInt32 reserved = GetUi32(p2);
  p2 += 4;
  
  /*
  if (cert)
  {
    UInt32 numRecipients = reserved;

    if (numRecipients == 0)
      return E_NOTIMPL;

    {
      UInt32 hashAlg = GetUi16(p2);
      hashAlg = hashAlg;
      UInt32 hashSize = GetUi16(p2 + 2);
      hashSize = hashSize;
      p2 += 4;

      reserved = reserved;
      // return E_NOTIMPL;

      for (unsigned r = 0; r < numRecipients; r++)
      {
        UInt32 specSize = GetUi16(p2);
        p2 += 2;
        p2 += specSize;
      }
    }
  }
  else
  */
  {
    if (reserved != 0)
      return E_NOTIMPL;
  }

  UInt32 validSize = GetUi16(p2);
  p2 += 2;
  const size_t validOffset = p2 - p;
  if ((validSize & 0xF) != 0 || validOffset + validSize != _remSize)
    return E_NOTIMPL;

  {
    RINOK(SetKey(_key.MasterKey, _key.KeySize));
    RINOK(SetInitVector(_iv, 16));
    RINOK(Init());
    Filter(p, rdSize);

    rdSize -= kPadSize;
    for (unsigned i = 0; i < kPadSize; i++)
      if (p[(size_t)rdSize + i] != kPadSize)
        return S_OK; // passwOK = false;
  }

  Byte fileKey[32];
  NSha1::CContext sha;
  sha.Init();
  sha.Update(_iv, _ivSize);
  sha.Update(p, rdSize);
  DeriveKey(sha, fileKey);
  
  RINOK(SetKey(fileKey, _key.KeySize));
  RINOK(SetInitVector(_iv, 16));
  Init();

  memmove(p, p + validOffset, validSize);
  Filter(p, validSize);

  if (validSize < 4)
    return E_NOTIMPL;
  validSize -= 4;
  if (GetUi32(p + validSize) != CrcCalc(p, validSize))
    return S_OK;
  passwOK = true;
  return S_OK;
}