rlm@1
|
1 // Crypto/ZipCrypto.cpp
|
rlm@1
|
2
|
rlm@1
|
3 #include "StdAfx.h"
|
rlm@1
|
4
|
rlm@1
|
5 extern "C"
|
rlm@1
|
6 {
|
rlm@1
|
7 #include "../../../C/7zCrc.h"
|
rlm@1
|
8 }
|
rlm@1
|
9
|
rlm@1
|
10 #include "../Common/StreamUtils.h"
|
rlm@1
|
11
|
rlm@1
|
12 #include "RandGen.h"
|
rlm@1
|
13 #include "ZipCrypto.h"
|
rlm@1
|
14
|
rlm@1
|
15 namespace NCrypto {
|
rlm@1
|
16 namespace NZip {
|
rlm@1
|
17
|
rlm@1
|
18 void CCipher::UpdateKeys(Byte b)
|
rlm@1
|
19 {
|
rlm@1
|
20 Keys[0] = CRC_UPDATE_BYTE(Keys[0], b);
|
rlm@1
|
21 Keys[1] += Keys[0] & 0xff;
|
rlm@1
|
22 Keys[1] = Keys[1] * 134775813L + 1;
|
rlm@1
|
23 Keys[2] = CRC_UPDATE_BYTE(Keys[2], (Byte)(Keys[1] >> 24));
|
rlm@1
|
24 }
|
rlm@1
|
25
|
rlm@1
|
26 void CCipher::SetPassword(const Byte *password, UInt32 passwordLen)
|
rlm@1
|
27 {
|
rlm@1
|
28 Keys[0] = 305419896L;
|
rlm@1
|
29 Keys[1] = 591751049L;
|
rlm@1
|
30 Keys[2] = 878082192L;
|
rlm@1
|
31 for (UInt32 i = 0; i < passwordLen; i++)
|
rlm@1
|
32 UpdateKeys(password[i]);
|
rlm@1
|
33 }
|
rlm@1
|
34
|
rlm@1
|
35 Byte CCipher::DecryptByteSpec()
|
rlm@1
|
36 {
|
rlm@1
|
37 UInt32 temp = Keys[2] | 2;
|
rlm@1
|
38 return (Byte)((temp * (temp ^ 1)) >> 8);
|
rlm@1
|
39 }
|
rlm@1
|
40
|
rlm@1
|
41 Byte CCipher::DecryptByte(Byte b)
|
rlm@1
|
42 {
|
rlm@1
|
43 Byte c = (Byte)(b ^ DecryptByteSpec());
|
rlm@1
|
44 UpdateKeys(c);
|
rlm@1
|
45 return c;
|
rlm@1
|
46 }
|
rlm@1
|
47
|
rlm@1
|
48 Byte CCipher::EncryptByte(Byte b)
|
rlm@1
|
49 {
|
rlm@1
|
50 Byte c = (Byte)(b ^ DecryptByteSpec());
|
rlm@1
|
51 UpdateKeys(b);
|
rlm@1
|
52 return c;
|
rlm@1
|
53 }
|
rlm@1
|
54
|
rlm@1
|
55 void CCipher::DecryptHeader(Byte *buf)
|
rlm@1
|
56 {
|
rlm@1
|
57 for (unsigned i = 0; i < kHeaderSize; i++)
|
rlm@1
|
58 buf[i] = DecryptByte(buf[i]);
|
rlm@1
|
59 }
|
rlm@1
|
60
|
rlm@1
|
61 void CCipher::EncryptHeader(Byte *buf)
|
rlm@1
|
62 {
|
rlm@1
|
63 for (unsigned i = 0; i < kHeaderSize; i++)
|
rlm@1
|
64 buf[i] = EncryptByte(buf[i]);
|
rlm@1
|
65 }
|
rlm@1
|
66
|
rlm@1
|
67 STDMETHODIMP CEncoder::CryptoSetPassword(const Byte *data, UInt32 size)
|
rlm@1
|
68 {
|
rlm@1
|
69 _cipher.SetPassword(data, size);
|
rlm@1
|
70 return S_OK;
|
rlm@1
|
71 }
|
rlm@1
|
72
|
rlm@1
|
73 STDMETHODIMP CEncoder::CryptoSetCRC(UInt32 crc)
|
rlm@1
|
74 {
|
rlm@1
|
75 _crc = crc;
|
rlm@1
|
76 return S_OK;
|
rlm@1
|
77 }
|
rlm@1
|
78
|
rlm@1
|
79 STDMETHODIMP CEncoder::Init()
|
rlm@1
|
80 {
|
rlm@1
|
81 return S_OK;
|
rlm@1
|
82 }
|
rlm@1
|
83
|
rlm@1
|
84 HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream)
|
rlm@1
|
85 {
|
rlm@1
|
86 Byte header[kHeaderSize];
|
rlm@1
|
87 g_RandomGenerator.Generate(header, kHeaderSize - 2);
|
rlm@1
|
88
|
rlm@1
|
89 header[kHeaderSize - 1] = Byte(_crc >> 24);
|
rlm@1
|
90 header[kHeaderSize - 2] = Byte(_crc >> 16);
|
rlm@1
|
91
|
rlm@1
|
92 _cipher.EncryptHeader(header);
|
rlm@1
|
93 return WriteStream(outStream, header, kHeaderSize);
|
rlm@1
|
94 }
|
rlm@1
|
95
|
rlm@1
|
96 STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size)
|
rlm@1
|
97 {
|
rlm@1
|
98 UInt32 i;
|
rlm@1
|
99 for (i = 0; i < size; i++)
|
rlm@1
|
100 data[i] = _cipher.EncryptByte(data[i]);
|
rlm@1
|
101 return i;
|
rlm@1
|
102 }
|
rlm@1
|
103
|
rlm@1
|
104 STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)
|
rlm@1
|
105 {
|
rlm@1
|
106 _cipher.SetPassword(data, size);
|
rlm@1
|
107 return S_OK;
|
rlm@1
|
108 }
|
rlm@1
|
109
|
rlm@1
|
110 HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream)
|
rlm@1
|
111 {
|
rlm@1
|
112 Byte header[kHeaderSize];
|
rlm@1
|
113 RINOK(ReadStream_FAIL(inStream, header, kHeaderSize));
|
rlm@1
|
114 _cipher.DecryptHeader(header);
|
rlm@1
|
115 return S_OK;
|
rlm@1
|
116 }
|
rlm@1
|
117
|
rlm@1
|
118 STDMETHODIMP CDecoder::Init()
|
rlm@1
|
119 {
|
rlm@1
|
120 return S_OK;
|
rlm@1
|
121 }
|
rlm@1
|
122
|
rlm@1
|
123 STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
|
rlm@1
|
124 {
|
rlm@1
|
125 UInt32 i;
|
rlm@1
|
126 for (i = 0; i < size; i++)
|
rlm@1
|
127 data[i] = _cipher.DecryptByte(data[i]);
|
rlm@1
|
128 return i;
|
rlm@1
|
129 }
|
rlm@1
|
130
|
rlm@1
|
131 }}
|