xref: /aosp_15_r20/external/lzma/CPP/7zip/Crypto/ZipCrypto.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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