Mercurial > vba-linux
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Crypto/ZipCrypto.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,131 @@ 1.4 +// Crypto/ZipCrypto.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +extern "C" 1.9 +{ 1.10 +#include "../../../C/7zCrc.h" 1.11 +} 1.12 + 1.13 +#include "../Common/StreamUtils.h" 1.14 + 1.15 +#include "RandGen.h" 1.16 +#include "ZipCrypto.h" 1.17 + 1.18 +namespace NCrypto { 1.19 +namespace NZip { 1.20 + 1.21 +void CCipher::UpdateKeys(Byte b) 1.22 +{ 1.23 + Keys[0] = CRC_UPDATE_BYTE(Keys[0], b); 1.24 + Keys[1] += Keys[0] & 0xff; 1.25 + Keys[1] = Keys[1] * 134775813L + 1; 1.26 + Keys[2] = CRC_UPDATE_BYTE(Keys[2], (Byte)(Keys[1] >> 24)); 1.27 +} 1.28 + 1.29 +void CCipher::SetPassword(const Byte *password, UInt32 passwordLen) 1.30 +{ 1.31 + Keys[0] = 305419896L; 1.32 + Keys[1] = 591751049L; 1.33 + Keys[2] = 878082192L; 1.34 + for (UInt32 i = 0; i < passwordLen; i++) 1.35 + UpdateKeys(password[i]); 1.36 +} 1.37 + 1.38 +Byte CCipher::DecryptByteSpec() 1.39 +{ 1.40 + UInt32 temp = Keys[2] | 2; 1.41 + return (Byte)((temp * (temp ^ 1)) >> 8); 1.42 +} 1.43 + 1.44 +Byte CCipher::DecryptByte(Byte b) 1.45 +{ 1.46 + Byte c = (Byte)(b ^ DecryptByteSpec()); 1.47 + UpdateKeys(c); 1.48 + return c; 1.49 +} 1.50 + 1.51 +Byte CCipher::EncryptByte(Byte b) 1.52 +{ 1.53 + Byte c = (Byte)(b ^ DecryptByteSpec()); 1.54 + UpdateKeys(b); 1.55 + return c; 1.56 +} 1.57 + 1.58 +void CCipher::DecryptHeader(Byte *buf) 1.59 +{ 1.60 + for (unsigned i = 0; i < kHeaderSize; i++) 1.61 + buf[i] = DecryptByte(buf[i]); 1.62 +} 1.63 + 1.64 +void CCipher::EncryptHeader(Byte *buf) 1.65 +{ 1.66 + for (unsigned i = 0; i < kHeaderSize; i++) 1.67 + buf[i] = EncryptByte(buf[i]); 1.68 +} 1.69 + 1.70 +STDMETHODIMP CEncoder::CryptoSetPassword(const Byte *data, UInt32 size) 1.71 +{ 1.72 + _cipher.SetPassword(data, size); 1.73 + return S_OK; 1.74 +} 1.75 + 1.76 +STDMETHODIMP CEncoder::CryptoSetCRC(UInt32 crc) 1.77 +{ 1.78 + _crc = crc; 1.79 + return S_OK; 1.80 +} 1.81 + 1.82 +STDMETHODIMP CEncoder::Init() 1.83 +{ 1.84 + return S_OK; 1.85 +} 1.86 + 1.87 +HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream) 1.88 +{ 1.89 + Byte header[kHeaderSize]; 1.90 + g_RandomGenerator.Generate(header, kHeaderSize - 2); 1.91 + 1.92 + header[kHeaderSize - 1] = Byte(_crc >> 24); 1.93 + header[kHeaderSize - 2] = Byte(_crc >> 16); 1.94 + 1.95 + _cipher.EncryptHeader(header); 1.96 + return WriteStream(outStream, header, kHeaderSize); 1.97 +} 1.98 + 1.99 +STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size) 1.100 +{ 1.101 + UInt32 i; 1.102 + for (i = 0; i < size; i++) 1.103 + data[i] = _cipher.EncryptByte(data[i]); 1.104 + return i; 1.105 +} 1.106 + 1.107 +STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size) 1.108 +{ 1.109 + _cipher.SetPassword(data, size); 1.110 + return S_OK; 1.111 +} 1.112 + 1.113 +HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream) 1.114 +{ 1.115 + Byte header[kHeaderSize]; 1.116 + RINOK(ReadStream_FAIL(inStream, header, kHeaderSize)); 1.117 + _cipher.DecryptHeader(header); 1.118 + return S_OK; 1.119 +} 1.120 + 1.121 +STDMETHODIMP CDecoder::Init() 1.122 +{ 1.123 + return S_OK; 1.124 +} 1.125 + 1.126 +STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) 1.127 +{ 1.128 + UInt32 i; 1.129 + for (i = 0; i < size; i++) 1.130 + data[i] = _cipher.DecryptByte(data[i]); 1.131 + return i; 1.132 +} 1.133 + 1.134 +}}