1*f6dc9357SAndroid Build Coastguard Worker // Crypto/ZipCrypto.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../C/7zCrc.h"
6*f6dc9357SAndroid Build Coastguard Worker
7*f6dc9357SAndroid Build Coastguard Worker #include "../Common/StreamUtils.h"
8*f6dc9357SAndroid Build Coastguard Worker
9*f6dc9357SAndroid Build Coastguard Worker #include "RandGen.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "ZipCrypto.h"
11*f6dc9357SAndroid Build Coastguard Worker
12*f6dc9357SAndroid Build Coastguard Worker namespace NCrypto {
13*f6dc9357SAndroid Build Coastguard Worker namespace NZip {
14*f6dc9357SAndroid Build Coastguard Worker
15*f6dc9357SAndroid Build Coastguard Worker #define UPDATE_KEYS(b) { \
16*f6dc9357SAndroid Build Coastguard Worker key0 = CRC_UPDATE_BYTE(key0, b); \
17*f6dc9357SAndroid Build Coastguard Worker key1 = (key1 + (key0 & 0xFF)) * 0x8088405 + 1; \
18*f6dc9357SAndroid Build Coastguard Worker key2 = CRC_UPDATE_BYTE(key2, (Byte)(key1 >> 24)); } \
19*f6dc9357SAndroid Build Coastguard Worker
20*f6dc9357SAndroid Build Coastguard Worker #define DECRYPT_BYTE_1 UInt32 temp = key2 | 2;
21*f6dc9357SAndroid Build Coastguard Worker #define DECRYPT_BYTE_2 ((Byte)((temp * (temp ^ 1)) >> 8))
22*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CCipher::CryptoSetPassword (const Byte * data,UInt32 size))23*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CCipher::CryptoSetPassword(const Byte *data, UInt32 size))
24*f6dc9357SAndroid Build Coastguard Worker {
25*f6dc9357SAndroid Build Coastguard Worker UInt32 key0 = 0x12345678;
26*f6dc9357SAndroid Build Coastguard Worker UInt32 key1 = 0x23456789;
27*f6dc9357SAndroid Build Coastguard Worker UInt32 key2 = 0x34567890;
28*f6dc9357SAndroid Build Coastguard Worker
29*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < size; i++)
30*f6dc9357SAndroid Build Coastguard Worker UPDATE_KEYS(data[i])
31*f6dc9357SAndroid Build Coastguard Worker
32*f6dc9357SAndroid Build Coastguard Worker KeyMem0 = key0;
33*f6dc9357SAndroid Build Coastguard Worker KeyMem1 = key1;
34*f6dc9357SAndroid Build Coastguard Worker KeyMem2 = key2;
35*f6dc9357SAndroid Build Coastguard Worker
36*f6dc9357SAndroid Build Coastguard Worker return S_OK;
37*f6dc9357SAndroid Build Coastguard Worker }
38*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(CCipher::Init ())39*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CCipher::Init())
40*f6dc9357SAndroid Build Coastguard Worker {
41*f6dc9357SAndroid Build Coastguard Worker return S_OK;
42*f6dc9357SAndroid Build Coastguard Worker }
43*f6dc9357SAndroid Build Coastguard Worker
WriteHeader_Check16(ISequentialOutStream * outStream,UInt16 crc)44*f6dc9357SAndroid Build Coastguard Worker HRESULT CEncoder::WriteHeader_Check16(ISequentialOutStream *outStream, UInt16 crc)
45*f6dc9357SAndroid Build Coastguard Worker {
46*f6dc9357SAndroid Build Coastguard Worker Byte h[kHeaderSize];
47*f6dc9357SAndroid Build Coastguard Worker
48*f6dc9357SAndroid Build Coastguard Worker /* PKZIP before 2.0 used 2 byte CRC check.
49*f6dc9357SAndroid Build Coastguard Worker PKZIP 2.0+ used 1 byte CRC check. It's more secure.
50*f6dc9357SAndroid Build Coastguard Worker We also use 1 byte CRC. */
51*f6dc9357SAndroid Build Coastguard Worker
52*f6dc9357SAndroid Build Coastguard Worker MY_RAND_GEN(h, kHeaderSize - 1);
53*f6dc9357SAndroid Build Coastguard Worker // h[kHeaderSize - 2] = (Byte)(crc);
54*f6dc9357SAndroid Build Coastguard Worker h[kHeaderSize - 1] = (Byte)(crc >> 8);
55*f6dc9357SAndroid Build Coastguard Worker
56*f6dc9357SAndroid Build Coastguard Worker RestoreKeys();
57*f6dc9357SAndroid Build Coastguard Worker Filter(h, kHeaderSize);
58*f6dc9357SAndroid Build Coastguard Worker return WriteStream(outStream, h, kHeaderSize);
59*f6dc9357SAndroid Build Coastguard Worker }
60*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF2(UInt32,CEncoder::Filter (Byte * data,UInt32 size))61*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF2(UInt32, CEncoder::Filter(Byte *data, UInt32 size))
62*f6dc9357SAndroid Build Coastguard Worker {
63*f6dc9357SAndroid Build Coastguard Worker UInt32 key0 = this->Key0;
64*f6dc9357SAndroid Build Coastguard Worker UInt32 key1 = this->Key1;
65*f6dc9357SAndroid Build Coastguard Worker UInt32 key2 = this->Key2;
66*f6dc9357SAndroid Build Coastguard Worker
67*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < size; i++)
68*f6dc9357SAndroid Build Coastguard Worker {
69*f6dc9357SAndroid Build Coastguard Worker Byte b = data[i];
70*f6dc9357SAndroid Build Coastguard Worker DECRYPT_BYTE_1
71*f6dc9357SAndroid Build Coastguard Worker data[i] = (Byte)(b ^ DECRYPT_BYTE_2);
72*f6dc9357SAndroid Build Coastguard Worker UPDATE_KEYS(b)
73*f6dc9357SAndroid Build Coastguard Worker }
74*f6dc9357SAndroid Build Coastguard Worker
75*f6dc9357SAndroid Build Coastguard Worker this->Key0 = key0;
76*f6dc9357SAndroid Build Coastguard Worker this->Key1 = key1;
77*f6dc9357SAndroid Build Coastguard Worker this->Key2 = key2;
78*f6dc9357SAndroid Build Coastguard Worker
79*f6dc9357SAndroid Build Coastguard Worker return size;
80*f6dc9357SAndroid Build Coastguard Worker }
81*f6dc9357SAndroid Build Coastguard Worker
ReadHeader(ISequentialInStream * inStream)82*f6dc9357SAndroid Build Coastguard Worker HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream)
83*f6dc9357SAndroid Build Coastguard Worker {
84*f6dc9357SAndroid Build Coastguard Worker return ReadStream_FAIL(inStream, _header, kHeaderSize);
85*f6dc9357SAndroid Build Coastguard Worker }
86*f6dc9357SAndroid Build Coastguard Worker
Init_BeforeDecode()87*f6dc9357SAndroid Build Coastguard Worker void CDecoder::Init_BeforeDecode()
88*f6dc9357SAndroid Build Coastguard Worker {
89*f6dc9357SAndroid Build Coastguard Worker RestoreKeys();
90*f6dc9357SAndroid Build Coastguard Worker Filter(_header, kHeaderSize);
91*f6dc9357SAndroid Build Coastguard Worker }
92*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF2(UInt32,CDecoder::Filter (Byte * data,UInt32 size))93*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF2(UInt32, CDecoder::Filter(Byte *data, UInt32 size))
94*f6dc9357SAndroid Build Coastguard Worker {
95*f6dc9357SAndroid Build Coastguard Worker UInt32 key0 = this->Key0;
96*f6dc9357SAndroid Build Coastguard Worker UInt32 key1 = this->Key1;
97*f6dc9357SAndroid Build Coastguard Worker UInt32 key2 = this->Key2;
98*f6dc9357SAndroid Build Coastguard Worker
99*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < size; i++)
100*f6dc9357SAndroid Build Coastguard Worker {
101*f6dc9357SAndroid Build Coastguard Worker DECRYPT_BYTE_1
102*f6dc9357SAndroid Build Coastguard Worker Byte b = (Byte)(data[i] ^ DECRYPT_BYTE_2);
103*f6dc9357SAndroid Build Coastguard Worker UPDATE_KEYS(b)
104*f6dc9357SAndroid Build Coastguard Worker data[i] = b;
105*f6dc9357SAndroid Build Coastguard Worker }
106*f6dc9357SAndroid Build Coastguard Worker
107*f6dc9357SAndroid Build Coastguard Worker this->Key0 = key0;
108*f6dc9357SAndroid Build Coastguard Worker this->Key1 = key1;
109*f6dc9357SAndroid Build Coastguard Worker this->Key2 = key2;
110*f6dc9357SAndroid Build Coastguard Worker
111*f6dc9357SAndroid Build Coastguard Worker return size;
112*f6dc9357SAndroid Build Coastguard Worker }
113*f6dc9357SAndroid Build Coastguard Worker
114*f6dc9357SAndroid Build Coastguard Worker }}
115