annotate 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
rev   line source
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 }}