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