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); }
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; }
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; }
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); } } }
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); }
SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s) { Byte header[XZ_BLOCK_HEADER_SIZE_MAX]; unsigned pos = 1; int numFilters, i; header[pos++] = p->flags; if (XzBlock_HasPackSize(p)) pos += Xz_WriteVarInt(header + pos, p->packSize); if (XzBlock_HasUnpackSize(p)) pos += Xz_WriteVarInt(header + pos, p->unpackSize); numFilters = XzBlock_GetNumFilters(p); for (i = 0; i < numFilters; i++) { const CXzFilter *f = &p->filters[i]; pos += Xz_WriteVarInt(header + pos, f->id); pos += Xz_WriteVarInt(header + pos, f->propsSize); memcpy(header + pos, f->props, f->propsSize); pos += f->propsSize; } while((pos & 3) != 0) header[pos++] = 0; header[0] = (Byte)(pos >> 2); SetUi32(header + pos, CrcCalc(header, pos)); return WriteBytes(s, header, pos + 4); }
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); }
int XzCheck_Final(CXzCheck *p, Byte *digest) { switch (p->mode) { case XZ_CHECK_CRC32: SetUi32(digest, CRC_GET_DIGEST(p->crc)); break; case XZ_CHECK_CRC64: { int i; UInt64 v = CRC64_GET_DIGEST(p->crc64); for (i = 0; i < 8; i++, v >>= 8) digest[i] = (Byte)(v & 0xFF); break; } case XZ_CHECK_SHA256: if (!(p->sha)) return 0; cl_finish_hash(p->sha, digest); break; default: return 0; } return 1; }
STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) { const UInt32 kPropSize = 5; Byte props[kPropSize]; props[0] = (Byte)_props.Order; SetUi32(props + 1, _props.MemSize); return WriteStream(outStream, props, kPropSize); }
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]); } }
void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks) { for (; numBlocks != 0; numBlocks--) { UInt32 temp[4]; Byte buf[16]; int i; if (++p[0] == 0) p[1]++; Aes_Encode(p + 4, temp, p); SetUi32(buf, temp[0]); SetUi32(buf + 4, temp[1]); SetUi32(buf + 8, temp[2]); SetUi32(buf + 12, temp[3]); for (i = 0; i < 16; i++) *data++ ^= buf[i]; } }
SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s) { Byte buf[32]; UInt64 globalPos; { UInt32 crc = CRC_INIT_VAL; unsigned pos = 1 + Xz_WriteVarInt(buf + 1, p->numBlocks); size_t i; globalPos = pos; buf[0] = 0; RINOK(WriteBytesAndCrc(s, buf, pos, &crc)); for (i = 0; i < p->numBlocks; i++) { const CXzBlockSizes *block = &p->blocks[i]; pos = Xz_WriteVarInt(buf, block->totalSize); pos += Xz_WriteVarInt(buf + pos, block->unpackSize); globalPos += pos; RINOK(WriteBytesAndCrc(s, buf, pos, &crc)); } pos = ((unsigned)globalPos & 3); if (pos != 0) { buf[0] = buf[1] = buf[2] = 0; RINOK(WriteBytesAndCrc(s, buf, 4 - pos, &crc)); globalPos += 4 - pos; } { SetUi32(buf, CRC_GET_DIGEST(crc)); RINOK(WriteBytes(s, buf, 4)); globalPos += 4; } } { UInt32 indexSize = (UInt32)((globalPos >> 2) - 1); SetUi32(buf + 4, indexSize); buf[8] = (Byte)(p->flags >> 8); buf[9] = (Byte)(p->flags & 0xFF); SetUi32(buf, CrcCalc(buf + 4, 6)); memcpy(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE); return WriteBytes(s, buf, 12); } }
SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s) { UInt32 crc; Byte header[XZ_STREAM_HEADER_SIZE]; memcpy(header, XZ_SIG, XZ_SIG_SIZE); header[XZ_SIG_SIZE] = (Byte)(f >> 8); header[XZ_SIG_SIZE + 1] = (Byte)(f & 0xFF); crc = CrcCalc(header + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE); SetUi32(header + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE, crc); return WriteBytes(s, header, XZ_STREAM_HEADER_SIZE); }
UInt32 CDecoder::Hmac_Convert_Crc32(UInt32 crc) const { NSha256::CHmac ctx; ctx.SetKey(_hashKey, NSha256::kDigestSize); Byte v[4]; SetUi32(v, crc); ctx.Update(v, 4); Byte h[NSha256::kDigestSize]; ctx.Final(h); crc = 0; for (unsigned i = 0; i < NSha256::kDigestSize; i++) crc ^= (UInt32)h[i] << ((i & 3) * 8); return crc; };
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]; } }
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; }
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; }
static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf, ISeqOutStream *outStream, ISeqInStream *inStream, const CXzProps *props, ICompressProgress *progress) { xz->flags = (Byte)props->checkId; RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, props->lzma2Props)); RINOK(Xz_WriteHeader(xz->flags, outStream)); { CSeqCheckInStream checkInStream; CSeqSizeOutStream seqSizeOutStream; CXzBlock block; int filterIndex = 0; CXzFilter *filter = NULL; const CXzFilterProps *fp = props->filterProps; XzBlock_ClearFlags(&block); XzBlock_SetNumFilters(&block, 1 + (fp ? 1 : 0)); if (fp) { filter = &block.filters[filterIndex++]; filter->id = fp->id; filter->propsSize = 0; if (fp->id == XZ_ID_Delta) { filter->props[0] = (Byte)(fp->delta - 1); filter->propsSize = 1; } else if (fp->ipDefined) { SetUi32(filter->props, fp->ip); filter->propsSize = 4; } } { CXzFilter *f = &block.filters[filterIndex++]; f->id = XZ_ID_LZMA2; f->propsSize = 1; f->props[0] = Lzma2Enc_WriteProperties(lzmaf->lzma2); } seqSizeOutStream.p.Write = MyWrite; seqSizeOutStream.realStream = outStream; seqSizeOutStream.processed = 0; RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.p)); checkInStream.p.Read = SeqCheckInStream_Read; checkInStream.realStream = inStream; SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags)); if (fp) { #ifdef USE_SUBBLOCK if (fp->id == XZ_ID_Subblock) { lzmaf->sb.inStream = &checkInStream.p; RINOK(SbEncInStream_Init(&lzmaf->sb)); } else #endif { lzmaf->filter.realStream = &checkInStream.p; RINOK(SeqInFilter_Init(&lzmaf->filter, filter)); } } { UInt64 packPos = seqSizeOutStream.processed; SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p, fp ? #ifdef USE_SUBBLOCK (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p: #endif &lzmaf->filter.p: &checkInStream.p, progress); RINOK(res); block.unpackSize = checkInStream.processed; block.packSize = seqSizeOutStream.processed - packPos; } { unsigned padSize = 0; Byte buf[128]; while((((unsigned)block.packSize + padSize) & 3) != 0) buf[padSize++] = 0; SeqCheckInStream_GetDigest(&checkInStream, buf + padSize); RINOK(WriteBytes(&seqSizeOutStream.p, buf, padSize + XzFlags_GetCheckSize(xz->flags))); RINOK(Xz_AddIndexRecord(xz, block.unpackSize, seqSizeOutStream.processed - padSize, &g_Alloc)); } } return Xz_WriteFooter(xz, outStream); }
STDMETHODIMP_(void) CCrcHasher::Final(Byte *digest) { UInt32 val = CRC_GET_DIGEST(_crc); SetUi32(digest, val); }
SRes Bcj2Dec_Decode(CBcj2Dec *p) { if (p->range <= 5) { p->state = BCJ2_DEC_STATE_OK; for (; p->range != 5; p->range++) { if (p->range == 1 && p->code != 0) return SZ_ERROR_DATA; if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) { p->state = BCJ2_STREAM_RC; return SZ_OK; } p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; } if (p->code == 0xFFFFFFFF) return SZ_ERROR_DATA; p->range = 0xFFFFFFFF; } else if (p->state >= BCJ2_DEC_STATE_ORIG_0) { while (p->state <= BCJ2_DEC_STATE_ORIG_3) { Byte *dest = p->dest; if (dest == p->destLim) return SZ_OK; *dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0]; p->dest = dest + 1; } } /* if (BCJ2_IS_32BIT_STREAM(p->state)) { const Byte *cur = p->bufs[p->state]; if (cur == p->lims[p->state]) return SZ_OK; p->bufs[p->state] = cur + 4; { UInt32 val; Byte *dest; SizeT rem; p->ip += 4; val = GetBe32(cur) - p->ip; dest = p->dest; rem = p->destLim - dest; if (rem < 4) { SizeT i; SetUi32(p->temp, val); for (i = 0; i < rem; i++) dest[i] = p->temp[i]; p->dest = dest + rem; p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; return SZ_OK; } SetUi32(dest, val); p->temp[3] = (Byte)(val >> 24); p->dest = dest + 4; p->state = BCJ2_DEC_STATE_OK; } } */ for (;;) { if (BCJ2_IS_32BIT_STREAM(p->state)) p->state = BCJ2_DEC_STATE_OK; else { if (p->range < kTopValue) { if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) { p->state = BCJ2_STREAM_RC; return SZ_OK; } p->range <<= 8; p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; } { const Byte *src = p->bufs[BCJ2_STREAM_MAIN]; const Byte *srcLim; Byte *dest; SizeT num = p->lims[BCJ2_STREAM_MAIN] - src; if (num == 0) { p->state = BCJ2_STREAM_MAIN; return SZ_OK; } dest = p->dest; if (num > (SizeT)(p->destLim - dest)) { num = p->destLim - dest; if (num == 0) { p->state = BCJ2_DEC_STATE_ORIG; return SZ_OK; } } srcLim = src + num; if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80) *dest = src[0]; else for (;;) { Byte b = *src; *dest = b; if (b != 0x0F) { if ((b & 0xFE) == 0xE8) break; dest++; if (++src != srcLim) continue; break; } dest++; if (++src == srcLim) break; if ((*src & 0xF0) != 0x80) continue; *dest = *src; break; } num = src - p->bufs[BCJ2_STREAM_MAIN]; if (src == srcLim) { p->temp[3] = src[-1]; p->bufs[BCJ2_STREAM_MAIN] = src; p->ip += (UInt32)num; p->dest += num; p->state = p->bufs[BCJ2_STREAM_MAIN] == p->lims[BCJ2_STREAM_MAIN] ? (unsigned)BCJ2_STREAM_MAIN : (unsigned)BCJ2_DEC_STATE_ORIG; return SZ_OK; } { UInt32 bound, ttt; CProb *prob; Byte b = src[0]; Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]); p->temp[3] = b; p->bufs[BCJ2_STREAM_MAIN] = src + 1; num++; p->ip += (UInt32)num; p->dest += num; prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0)); _IF_BIT_0 { _UPDATE_0 continue; } _UPDATE_1 } } } { UInt32 val; unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; const Byte *cur = p->bufs[cj]; Byte *dest; SizeT rem; if (cur == p->lims[cj]) { p->state = cj; break; } val = GetBe32(cur); p->bufs[cj] = cur + 4; p->ip += 4; val -= p->ip; dest = p->dest; rem = p->destLim - dest; if (rem < 4) { SizeT i; SetUi32(p->temp, val); for (i = 0; i < rem; i++) dest[i] = p->temp[i]; p->dest = dest + rem; p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; break; } SetUi32(dest, val); p->temp[3] = (Byte)(val >> 24); p->dest = dest + 4; } } if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC]) { p->range <<= 8; p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; } return SZ_OK; }