view 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
line wrap: on
line source
1 // Crypto/ZipCrypto.cpp
3 #include "StdAfx.h"
5 extern "C"
6 {
7 #include "../../../C/7zCrc.h"
8 }
10 #include "../Common/StreamUtils.h"
12 #include "RandGen.h"
13 #include "ZipCrypto.h"
15 namespace NCrypto {
16 namespace NZip {
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 }
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 }
35 Byte CCipher::DecryptByteSpec()
36 {
37 UInt32 temp = Keys[2] | 2;
38 return (Byte)((temp * (temp ^ 1)) >> 8);
39 }
41 Byte CCipher::DecryptByte(Byte b)
42 {
43 Byte c = (Byte)(b ^ DecryptByteSpec());
44 UpdateKeys(c);
45 return c;
46 }
48 Byte CCipher::EncryptByte(Byte b)
49 {
50 Byte c = (Byte)(b ^ DecryptByteSpec());
51 UpdateKeys(b);
52 return c;
53 }
55 void CCipher::DecryptHeader(Byte *buf)
56 {
57 for (unsigned i = 0; i < kHeaderSize; i++)
58 buf[i] = DecryptByte(buf[i]);
59 }
61 void CCipher::EncryptHeader(Byte *buf)
62 {
63 for (unsigned i = 0; i < kHeaderSize; i++)
64 buf[i] = EncryptByte(buf[i]);
65 }
67 STDMETHODIMP CEncoder::CryptoSetPassword(const Byte *data, UInt32 size)
68 {
69 _cipher.SetPassword(data, size);
70 return S_OK;
71 }
73 STDMETHODIMP CEncoder::CryptoSetCRC(UInt32 crc)
74 {
75 _crc = crc;
76 return S_OK;
77 }
79 STDMETHODIMP CEncoder::Init()
80 {
81 return S_OK;
82 }
84 HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream)
85 {
86 Byte header[kHeaderSize];
87 g_RandomGenerator.Generate(header, kHeaderSize - 2);
89 header[kHeaderSize - 1] = Byte(_crc >> 24);
90 header[kHeaderSize - 2] = Byte(_crc >> 16);
92 _cipher.EncryptHeader(header);
93 return WriteStream(outStream, header, kHeaderSize);
94 }
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 }
104 STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)
105 {
106 _cipher.SetPassword(data, size);
107 return S_OK;
108 }
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 }
118 STDMETHODIMP CDecoder::Init()
119 {
120 return S_OK;
121 }
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 }
131 }}