Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Crypto/Hash')
-rwxr-xr-xCPP/7zip/Crypto/Hash/HmacSha1.cpp109
-rwxr-xr-xCPP/7zip/Crypto/Hash/HmacSha1.h39
-rwxr-xr-xCPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp83
-rwxr-xr-xCPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h21
-rwxr-xr-xCPP/7zip/Crypto/Hash/RandGen.cpp78
-rwxr-xr-xCPP/7zip/Crypto/Hash/RandGen.h21
-rwxr-xr-xCPP/7zip/Crypto/Hash/RotateDefs.h19
-rwxr-xr-xCPP/7zip/Crypto/Hash/Sha1.cpp210
-rwxr-xr-xCPP/7zip/Crypto/Hash/Sha1.h68
-rwxr-xr-xCPP/7zip/Crypto/Hash/Sha256.cpp210
-rwxr-xr-xCPP/7zip/Crypto/Hash/Sha256.h30
-rwxr-xr-xCPP/7zip/Crypto/Hash/StdAfx.h8
12 files changed, 896 insertions, 0 deletions
diff --git a/CPP/7zip/Crypto/Hash/HmacSha1.cpp b/CPP/7zip/Crypto/Hash/HmacSha1.cpp
new file mode 100755
index 00000000..a5c20a75
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/HmacSha1.cpp
@@ -0,0 +1,109 @@
+// HmacSha1.cpp
+
+#include "StdAfx.h"
+
+#include "HmacSha1.h"
+
+namespace NCrypto {
+namespace NSha1 {
+
+void CHmac::SetKey(const Byte *key, size_t keySize)
+{
+ Byte keyTemp[kBlockSize];
+ size_t i;
+ for (i = 0; i < kBlockSize; i++)
+ keyTemp[i] = 0;
+ if(keySize > kBlockSize)
+ {
+ _sha.Init();
+ _sha.Update(key, keySize);
+ _sha.Final(keyTemp);
+ keySize = kDigestSize;
+ }
+ else
+ for (i = 0; i < keySize; i++)
+ keyTemp[i] = key[i];
+ for (i = 0; i < kBlockSize; i++)
+ keyTemp[i] ^= 0x36;
+ _sha.Init();
+ _sha.Update(keyTemp, kBlockSize);
+ for (i = 0; i < kBlockSize; i++)
+ keyTemp[i] ^= 0x36 ^ 0x5C;
+ _sha2.Init();
+ _sha2.Update(keyTemp, kBlockSize);
+}
+
+void CHmac::Final(Byte *mac, size_t macSize)
+{
+ Byte digest[kDigestSize];
+ _sha.Final(digest);
+ _sha2.Update(digest, kDigestSize);
+ _sha2.Final(digest);
+ for(size_t i = 0; i < macSize; i++)
+ mac[i] = digest[i];
+}
+
+
+void CHmac32::SetKey(const Byte *key, size_t keySize)
+{
+ UInt32 keyTemp[kBlockSizeInWords];
+ size_t i;
+ for (i = 0; i < kBlockSizeInWords; i++)
+ keyTemp[i] = 0;
+ if(keySize > kBlockSize)
+ {
+ CContext sha;
+ sha.Init();
+ sha.Update(key, keySize);
+ Byte digest[kDigestSize];
+ sha.Final(digest);
+
+ for (int i = 0 ; i < kDigestSizeInWords; i++)
+ keyTemp[i] =
+ ((UInt32)(digest[i * 4 + 0]) << 24) |
+ ((UInt32)(digest[i * 4 + 1]) << 16) |
+ ((UInt32)(digest[i * 4 + 2]) << 8) |
+ ((UInt32)(digest[i * 4 + 3]));
+ keySize = kDigestSizeInWords;
+ }
+ else
+ for (size_t i = 0; i < keySize; i++)
+ keyTemp[i / 4] |= (key[i] << (24 - 8 * (i & 3)));
+ for (i = 0; i < kBlockSizeInWords; i++)
+ keyTemp[i] ^= 0x36363636;
+ _sha.Init();
+ _sha.Update(keyTemp, kBlockSizeInWords);
+ for (i = 0; i < kBlockSizeInWords; i++)
+ keyTemp[i] ^= 0x36363636 ^ 0x5C5C5C5C;
+ _sha2.Init();
+ _sha2.Update(keyTemp, kBlockSizeInWords);
+}
+
+void CHmac32::Final(UInt32 *mac, size_t macSize)
+{
+ UInt32 digest[kDigestSizeInWords];
+ _sha.Final(digest);
+ _sha2.Update(digest, kDigestSizeInWords);
+ _sha2.Final(digest);
+ for(size_t i = 0; i < macSize; i++)
+ mac[i] = digest[i];
+}
+
+void CHmac32::GetLoopXorDigest(UInt32 *mac, UInt32 numIteration)
+{
+ UInt32 block[kBlockSizeInWords];
+ UInt32 block2[kBlockSizeInWords];
+ _sha.PrepareBlock(block, kDigestSizeInWords);
+ _sha2.PrepareBlock(block2, kDigestSizeInWords);
+ for(unsigned int s = 0; s < kDigestSizeInWords; s++)
+ block[s] = mac[s];
+ for(UInt32 i = 0; i < numIteration; i++)
+ {
+ _sha.GetBlockDigest(block, block2);
+ _sha2.GetBlockDigest(block2, block);
+ for (unsigned int s = 0; s < kDigestSizeInWords; s++)
+ mac[s] ^= block[s];
+ }
+}
+
+}}
diff --git a/CPP/7zip/Crypto/Hash/HmacSha1.h b/CPP/7zip/Crypto/Hash/HmacSha1.h
new file mode 100755
index 00000000..bca5bcf8
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/HmacSha1.h
@@ -0,0 +1,39 @@
+// HmacSha1.h
+// Implements HMAC-SHA-1 (RFC2104, FIPS-198)
+
+#ifndef _HMAC_H
+#define _HMAC_H
+
+#include "Sha1.h"
+
+namespace NCrypto {
+namespace NSha1 {
+
+// Use: SetKey(key, keySize); for () Update(data, size); Final(mac, macSize);
+
+class CHmac
+{
+ CContext _sha;
+ CContext _sha2;
+public:
+ void SetKey(const Byte *key, size_t keySize);
+ void Update(const Byte *data, size_t dataSize) { _sha.Update(data, dataSize); }
+ void Final(Byte *mac, size_t macSize = kDigestSize);
+};
+
+class CHmac32
+{
+ CContext32 _sha;
+ CContext32 _sha2;
+public:
+ void SetKey(const Byte *key, size_t keySize);
+ void Update(const UInt32 *data, size_t dataSize) { _sha.Update(data, dataSize); }
+ void Final(UInt32 *mac, size_t macSize = kDigestSizeInWords);
+
+ // It'sa for hmac function. in,out: mac[kDigestSizeInWords].
+ void GetLoopXorDigest(UInt32 *mac, UInt32 numIteration);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp b/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp
new file mode 100755
index 00000000..b11881b7
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.cpp
@@ -0,0 +1,83 @@
+// Pbkdf2HmacSha1.cpp
+
+#include "StdAfx.h"
+
+#include "HmacSha1.h"
+
+namespace NCrypto {
+namespace NSha1 {
+
+void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize, const Byte *salt, size_t saltSize,
+ UInt32 numIterations, Byte *key, size_t keySize)
+{
+ CHmac baseCtx;
+ baseCtx.SetKey(pwd, pwdSize);
+ for (UInt32 i = 1; keySize > 0; i++)
+ {
+ CHmac ctx = baseCtx;
+ ctx.Update(salt, saltSize);
+ Byte u[kDigestSize] = { (Byte)(i >> 24), (Byte)(i >> 16), (Byte)(i >> 8), (Byte)(i) };
+ const unsigned int curSize = (keySize < kDigestSize) ? (unsigned int)keySize : kDigestSize;
+ ctx.Update(u, 4);
+ ctx.Final(u, kDigestSize);
+
+ unsigned int s;
+ for (s = 0; s < curSize; s++)
+ key[s] = u[s];
+
+ for (UInt32 j = numIterations; j > 1; j--)
+ {
+ ctx = baseCtx;
+ ctx.Update(u, kDigestSize);
+ ctx.Final(u, kDigestSize);
+ for (s = 0; s < curSize; s++)
+ key[s] ^= u[s];
+ }
+
+ key += curSize;
+ keySize -= curSize;
+ }
+}
+
+void Pbkdf2Hmac32(const Byte *pwd, size_t pwdSize, const UInt32 *salt, size_t saltSize,
+ UInt32 numIterations, UInt32 *key, size_t keySize)
+{
+ CHmac32 baseCtx;
+ baseCtx.SetKey(pwd, pwdSize);
+ for (UInt32 i = 1; keySize > 0; i++)
+ {
+ CHmac32 ctx = baseCtx;
+ ctx.Update(salt, saltSize);
+ UInt32 u[kDigestSizeInWords] = { i };
+ const unsigned int curSize = (keySize < kDigestSizeInWords) ? (unsigned int)keySize : kDigestSizeInWords;
+ ctx.Update(u, 1);
+ ctx.Final(u, kDigestSizeInWords);
+
+ // Speed-optimized code start
+ ctx = baseCtx;
+ ctx.GetLoopXorDigest(u, numIterations - 1);
+ // Speed-optimized code end
+
+ unsigned int s;
+ for (s = 0; s < curSize; s++)
+ key[s] = u[s];
+
+ /*
+ // Default code start
+ for (UInt32 j = numIterations; j > 1; j--)
+ {
+ ctx = baseCtx;
+ ctx.Update(u, kDigestSizeInWords);
+ ctx.Final(u, kDigestSizeInWords);
+ for (s = 0; s < curSize; s++)
+ key[s] ^= u[s];
+ }
+ // Default code end
+ */
+
+ key += curSize;
+ keySize -= curSize;
+ }
+}
+
+}}
diff --git a/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h b/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h
new file mode 100755
index 00000000..00a5e009
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Pbkdf2HmacSha1.h
@@ -0,0 +1,21 @@
+// Pbkdf2HmacSha1.h
+// Password-Based Key Derivation Function (RFC 2898, PKCS #5) based on HMAC-SHA-1
+
+#ifndef __PBKDF2HMACSHA1_H
+#define __PBKDF2HMACSHA1_H
+
+#include <stddef.h>
+#include "../../../Common/Types.h"
+
+namespace NCrypto {
+namespace NSha1 {
+
+void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize, const Byte *salt, size_t saltSize,
+ UInt32 numIterations, Byte *key, size_t keySize);
+
+void Pbkdf2Hmac32(const Byte *pwd, size_t pwdSize, const UInt32 *salt, size_t saltSize,
+ UInt32 numIterations, UInt32 *key, size_t keySize);
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/RandGen.cpp b/CPP/7zip/Crypto/Hash/RandGen.cpp
new file mode 100755
index 00000000..480e04ca
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/RandGen.cpp
@@ -0,0 +1,78 @@
+// RandGen.cpp
+
+#include "StdAfx.h"
+
+#include <stdio.h>
+
+#include "Windows/Synchronization.h"
+
+#include "RandGen.h"
+
+// This is not very good random number generator.
+// Please use it only for salt.
+// First genrated data block depends from timer.
+// Other genrated data blocks depend from previous state
+// Maybe it's possible to restore original timer vaue from generated value.
+
+void CRandomGenerator::Init()
+{
+ NCrypto::NSha1::CContext hash;
+ hash.Init();
+
+ #ifdef _WIN32
+ DWORD w = ::GetCurrentProcessId();
+ hash.Update((const Byte *)&w, sizeof(w));
+ w = ::GetCurrentThreadId();
+ hash.Update((const Byte *)&w, sizeof(w));
+ #endif
+
+ for (int i = 0; i < 1000; i++)
+ {
+ #ifdef _WIN32
+ LARGE_INTEGER v;
+ if (::QueryPerformanceCounter(&v))
+ hash.Update((const Byte *)&v.QuadPart, sizeof(v.QuadPart));
+ #endif
+
+ DWORD tickCount = ::GetTickCount();
+ hash.Update((const Byte *)&tickCount, sizeof(tickCount));
+
+ for (int j = 0; j < 100; j++)
+ {
+ hash.Final(_buff);
+ hash.Init();
+ hash.Update(_buff, NCrypto::NSha1::kDigestSize);
+ }
+ }
+ hash.Final(_buff);
+ _needInit = false;
+}
+
+static NWindows::NSynchronization::CCriticalSection g_CriticalSection;
+
+void CRandomGenerator::Generate(Byte *data, unsigned int size)
+{
+ g_CriticalSection.Enter();
+ if (_needInit)
+ Init();
+ while (size > 0)
+ {
+ NCrypto::NSha1::CContext hash;
+
+ hash.Init();
+ hash.Update(_buff, NCrypto::NSha1::kDigestSize);
+ hash.Final(_buff);
+
+ hash.Init();
+ UInt32 salt = 0xF672ABD1;
+ hash.Update((const Byte *)&salt, sizeof(salt));
+ hash.Update(_buff, NCrypto::NSha1::kDigestSize);
+ Byte buff[NCrypto::NSha1::kDigestSize];
+ hash.Final(buff);
+ for (unsigned int i = 0; i < NCrypto::NSha1::kDigestSize && size > 0; i++, size--)
+ *data++ = buff[i];
+ }
+ g_CriticalSection.Leave();
+}
+
+CRandomGenerator g_RandomGenerator;
diff --git a/CPP/7zip/Crypto/Hash/RandGen.h b/CPP/7zip/Crypto/Hash/RandGen.h
new file mode 100755
index 00000000..3b58a032
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/RandGen.h
@@ -0,0 +1,21 @@
+// RandGen.h
+
+#ifndef __RANDGEN_H
+#define __RANDGEN_H
+
+#include "Sha1.h"
+
+class CRandomGenerator
+{
+ Byte _buff[NCrypto::NSha1::kDigestSize];
+ bool _needInit;
+
+ void Init();
+public:
+ CRandomGenerator(): _needInit(true) {};
+ void Generate(Byte *data, unsigned int size);
+};
+
+extern CRandomGenerator g_RandomGenerator;
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/RotateDefs.h b/CPP/7zip/Crypto/Hash/RotateDefs.h
new file mode 100755
index 00000000..832e7357
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/RotateDefs.h
@@ -0,0 +1,19 @@
+// RotateDefs.h
+
+#ifndef __ROTATEDEFS_H
+#define __ROTATEDEFS_H
+
+#ifdef _MSC_VER
+
+#include <stddef.h>
+#define rotlFixed(x, n) _rotl((x), (n))
+#define rotrFixed(x, n) _rotr((x), (n))
+
+#else
+
+#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
+
+#endif
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/Sha1.cpp b/CPP/7zip/Crypto/Hash/Sha1.cpp
new file mode 100755
index 00000000..0e1d2ecf
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Sha1.cpp
@@ -0,0 +1,210 @@
+// Sha1.cpp
+// This file is based on public domain
+// Steve Reid and Wei Dai's code from Crypto++
+
+#include "StdAfx.h"
+
+#include "Sha1.h"
+#include "RotateDefs.h"
+
+namespace NCrypto {
+namespace NSha1 {
+
+// define it for speed optimization
+// #define _SHA1_UNROLL
+
+static const unsigned int kNumW =
+ #ifdef _SHA1_UNROLL
+ 16;
+ #else
+ 80;
+ #endif
+
+
+#define w0(i) (W[(i)] = data[(i)])
+
+#ifdef _SHA1_UNROLL
+#define w1(i) (W[(i)&15] = rotlFixed(W[((i)-3)&15] ^ W[((i)-8)&15] ^ W[((i)-14)&15] ^ W[((i)-16)&15], 1))
+#else
+#define w1(i) (W[(i)] = rotlFixed(W[(i)-3] ^ W[(i)-8] ^ W[(i)-14] ^ W[(i)-16], 1))
+#endif
+
+#define f1(x,y,z) (z^(x&(y^z)))
+#define f2(x,y,z) (x^y^z)
+#define f3(x,y,z) ((x&y)|(z&(x|y)))
+#define f4(x,y,z) (x^y^z)
+
+#define RK1(a,b,c,d,e,i, f, w, k) e += f(b,c,d) + w(i) + k + rotlFixed(a,5); b = rotlFixed(b,30);
+
+#define R0(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f1, w0, 0x5A827999)
+#define R1(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f1, w1, 0x5A827999)
+#define R2(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f2, w1, 0x6ED9EBA1)
+#define R3(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f3, w1, 0x8F1BBCDC)
+#define R4(a,b,c,d,e,i) RK1(a,b,c,d,e,i, f4, w1, 0xCA62C1D6)
+
+#define RX_1_4(rx1, rx4, i) rx1(a,b,c,d,e,i); rx4(e,a,b,c,d,i+1); rx4(d,e,a,b,c,i+2); rx4(c,d,e,a,b,i+3); rx4(b,c,d,e,a,i+4);
+#define RX_5(rx, i) RX_1_4(rx, rx, i);
+
+void CContextBase::Init()
+{
+ _state[0] = 0x67452301;
+ _state[1] = 0xEFCDAB89;
+ _state[2] = 0x98BADCFE;
+ _state[3] = 0x10325476;
+ _state[4] = 0xC3D2E1F0;
+ _count = 0;
+}
+
+void CContextBase::GetBlockDigest(UInt32 *data, UInt32 *destDigest, bool returnRes)
+{
+ UInt32 a, b, c, d, e;
+ UInt32 W[kNumW];
+
+ a = _state[0];
+ b = _state[1];
+ c = _state[2];
+ d = _state[3];
+ e = _state[4];
+ #ifdef _SHA1_UNROLL
+ RX_5(R0, 0); RX_5(R0, 5); RX_5(R0, 10);
+ #else
+ int i;
+ for (i = 0; i < 15; i += 5) { RX_5(R0, i); }
+ #endif
+
+ RX_1_4(R0, R1, 15);
+
+
+ #ifdef _SHA1_UNROLL
+ RX_5(R2, 20); RX_5(R2, 25); RX_5(R2, 30); RX_5(R2, 35);
+ RX_5(R3, 40); RX_5(R3, 45); RX_5(R3, 50); RX_5(R3, 55);
+ RX_5(R4, 60); RX_5(R4, 65); RX_5(R4, 70); RX_5(R4, 75);
+ #else
+ i = 20;
+ for (; i < 40; i += 5) { RX_5(R2, i); }
+ for (; i < 60; i += 5) { RX_5(R3, i); }
+ for (; i < 80; i += 5) { RX_5(R4, i); }
+ #endif
+
+ destDigest[0] = _state[0] + a;
+ destDigest[1] = _state[1] + b;
+ destDigest[2] = _state[2] + c;
+ destDigest[3] = _state[3] + d;
+ destDigest[4] = _state[4] + e;
+
+ if (returnRes)
+ for (int i = 0 ; i < 16; i++)
+ data[i] = W[kNumW - 16 + i];
+
+ // Wipe variables
+ // a = b = c = d = e = 0;
+}
+
+void CContextBase::PrepareBlock(UInt32 *block, unsigned int size) const
+{
+ unsigned int curBufferPos = size & 0xF;
+ block[curBufferPos++] = 0x80000000;
+ while (curBufferPos != (16 - 2))
+ block[curBufferPos++] = 0;
+ const UInt64 lenInBits = (_count << 9) + ((UInt64)size << 5);
+ block[curBufferPos++] = (UInt32)(lenInBits >> 32);
+ block[curBufferPos++] = (UInt32)(lenInBits);
+}
+
+void CContext::Update(Byte *data, size_t size, bool rar350Mode)
+{
+ bool returnRes = false;
+ unsigned int curBufferPos = _count2;
+ while (size-- > 0)
+ {
+ int pos = (int)(curBufferPos & 3);
+ if (pos == 0)
+ _buffer[curBufferPos >> 2] = 0;
+ _buffer[curBufferPos >> 2] |= ((UInt32)*data++) << (8 * (3 - pos));
+ if (++curBufferPos == kBlockSize)
+ {
+ curBufferPos = 0;
+ CContextBase::UpdateBlock(_buffer, returnRes);
+ if (returnRes)
+ for (int i = 0; i < kBlockSizeInWords; i++)
+ {
+ UInt32 d = _buffer[i];
+ data[i * 4 + 0 - kBlockSize] = (Byte)(d);
+ data[i * 4 + 1 - kBlockSize] = (Byte)(d >> 8);
+ data[i * 4 + 2 - kBlockSize] = (Byte)(d >> 16);
+ data[i * 4 + 3 - kBlockSize] = (Byte)(d >> 24);
+ }
+ returnRes = rar350Mode;
+ }
+ }
+ _count2 = curBufferPos;
+}
+
+void CContext::Final(Byte *digest)
+{
+ const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 3);
+ unsigned int curBufferPos = _count2;
+ int pos = (int)(curBufferPos & 3);
+ curBufferPos >>= 2;
+ if (pos == 0)
+ _buffer[curBufferPos] = 0;
+ _buffer[curBufferPos++] |= ((UInt32)0x80) << (8 * (3 - pos));
+
+ while (curBufferPos != (16 - 2))
+ {
+ curBufferPos &= 0xF;
+ if (curBufferPos == 0)
+ UpdateBlock();
+ _buffer[curBufferPos++] = 0;
+ }
+ _buffer[curBufferPos++] = (UInt32)(lenInBits >> 32);
+ _buffer[curBufferPos++] = (UInt32)(lenInBits);
+ UpdateBlock();
+
+ int i;
+ for (i = 0; i < kDigestSizeInWords; i++)
+ {
+ UInt32 state = _state[i] & 0xFFFFFFFF;
+ *digest++ = (Byte)(state >> 24);
+ *digest++ = (Byte)(state >> 16);
+ *digest++ = (Byte)(state >> 8);
+ *digest++ = (Byte)(state);
+ }
+ Init();
+}
+
+///////////////////////////
+// Words version
+
+void CContext32::Update(const UInt32 *data, size_t size)
+{
+ while (size-- > 0)
+ {
+ _buffer[_count2++] = *data++;
+ if (_count2 == kBlockSizeInWords)
+ {
+ _count2 = 0;
+ UpdateBlock();
+ }
+ }
+}
+
+void CContext32::Final(UInt32 *digest)
+{
+ const UInt64 lenInBits = (_count << 9) + ((UInt64)_count2 << 5);
+ unsigned int curBufferPos = _count2;
+ _buffer[curBufferPos++] = 0x80000000;
+ while (curBufferPos != (16 - 2))
+ {
+ curBufferPos &= 0xF;
+ if (curBufferPos == 0)
+ UpdateBlock();
+ _buffer[curBufferPos++] = 0;
+ }
+ _buffer[curBufferPos++] = (UInt32)(lenInBits >> 32);
+ _buffer[curBufferPos++] = (UInt32)(lenInBits);
+ GetBlockDigest(_buffer, digest);
+ Init();
+}
+
+}}
diff --git a/CPP/7zip/Crypto/Hash/Sha1.h b/CPP/7zip/Crypto/Hash/Sha1.h
new file mode 100755
index 00000000..ebb11142
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Sha1.h
@@ -0,0 +1,68 @@
+// Sha1.h
+// This file is based on public domain
+// Steve Reid and Wei Dai's code from Crypto++
+
+#ifndef __SHA1_H
+#define __SHA1_H
+
+#include <stddef.h>
+#include "../../../Common/Types.h"
+
+// Sha1 implementation in RAR before version 3.60 has bug:
+// it changes data bytes in some cases.
+// So this class supports both versions: normal_SHA and rar3Mode
+
+namespace NCrypto {
+namespace NSha1 {
+
+const unsigned int kBlockSize = 64;
+const unsigned int kDigestSize = 20;
+
+const unsigned int kBlockSizeInWords = (kBlockSize >> 2);
+const unsigned int kDigestSizeInWords = (kDigestSize >> 2);
+
+class CContextBase
+{
+protected:
+ UInt32 _state[5];
+ UInt64 _count;
+ void UpdateBlock(UInt32 *data, bool returnRes = false)
+ {
+ GetBlockDigest(data, _state, returnRes);
+ _count++;
+ }
+public:
+ void Init();
+ void GetBlockDigest(UInt32 *blockData, UInt32 *destDigest, bool returnRes = false);
+ // PrepareBlock can be used only when size <= 13. size in Words
+ void PrepareBlock(UInt32 *block, unsigned int size) const;
+};
+
+class CContextBase2: public CContextBase
+{
+protected:
+ unsigned int _count2;
+ UInt32 _buffer[kBlockSizeInWords];
+ void UpdateBlock() { CContextBase::UpdateBlock(_buffer); }
+public:
+ void Init() { CContextBase::Init(); _count2 = 0; }
+};
+
+class CContext: public CContextBase2
+{
+public:
+ void Update(Byte *data, size_t size, bool rar350Mode = false);
+ void Update(const Byte *data, size_t size) { Update((Byte *)data, size, false); }
+ void Final(Byte *digest);
+};
+
+class CContext32: public CContextBase2
+{
+public:
+ void Update(const UInt32 *data, size_t size);
+ void Final(UInt32 *digest);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/Sha256.cpp b/CPP/7zip/Crypto/Hash/Sha256.cpp
new file mode 100755
index 00000000..db236058
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Sha256.cpp
@@ -0,0 +1,210 @@
+// Crypto/Sha256.cpp
+// This code is based on code from Wei Dai's Crypto++ library.
+
+#include "StdAfx.h"
+
+#include "Sha256.h"
+#include "RotateDefs.h"
+
+namespace NCrypto {
+namespace NSha256 {
+
+// define it for speed optimization
+// #define _SHA256_UNROLL
+// #define _SHA256_UNROLL2
+
+void CContext::Init()
+{
+ _state[0] = 0x6a09e667;
+ _state[1] = 0xbb67ae85;
+ _state[2] = 0x3c6ef372;
+ _state[3] = 0xa54ff53a;
+ _state[4] = 0x510e527f;
+ _state[5] = 0x9b05688c;
+ _state[6] = 0x1f83d9ab;
+ _state[7] = 0x5be0cd19;
+
+ _count = 0;
+}
+
+#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22))
+#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25))
+#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3))
+#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10))
+
+#define blk0(i) (W[i] = data[i])
+#define blk2(i) (W[i&15] += s1(W[(i-2)&15]) + W[(i-7)&15] + s0(W[(i-15)&15]))
+
+#define Ch(x,y,z) (z^(x&(y^z)))
+#define Maj(x,y,z) ((x&y)|(z&(x|y)))
+
+#define a(i) T[(0-(i))&7]
+#define b(i) T[(1-(i))&7]
+#define c(i) T[(2-(i))&7]
+#define d(i) T[(3-(i))&7]
+#define e(i) T[(4-(i))&7]
+#define f(i) T[(5-(i))&7]
+#define g(i) T[(6-(i))&7]
+#define h(i) T[(7-(i))&7]
+
+
+#ifdef _SHA256_UNROLL2
+
+#define R(a,b,c,d,e,f,g,h, i) h += S1(e) + Ch(e,f,g) + K[i+j] + (j?blk2(i):blk0(i));\
+ d += h; h += S0(a) + Maj(a, b, c)
+
+#define RX_8(i) \
+ R(a,b,c,d,e,f,g,h, i); \
+ R(h,a,b,c,d,e,f,g, i+1); \
+ R(g,h,a,b,c,d,e,f, i+2); \
+ R(f,g,h,a,b,c,d,e, i+3); \
+ R(e,f,g,h,a,b,c,d, i+4); \
+ R(d,e,f,g,h,a,b,c, i+5); \
+ R(c,d,e,f,g,h,a,b, i+6); \
+ R(b,c,d,e,f,g,h,a, i+7)
+
+#else
+
+#define R(i) h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j?blk2(i):blk0(i));\
+ d(i) += h(i); h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
+
+#ifdef _SHA256_UNROLL
+
+#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7);
+
+#endif
+
+#endif
+
+
+void CContext::Transform(UInt32 *state, const UInt32 *data)
+{
+ UInt32 W[16];
+
+ #ifdef _SHA256_UNROLL2
+ UInt32 a,b,c,d,e,f,g,h;
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ f = state[5];
+ g = state[6];
+ h = state[7];
+ #else
+ UInt32 T[8];
+ for (int s = 0; s < 8; s++)
+ T[s] = state[s];
+ #endif
+
+ for (unsigned int j = 0; j < 64; j += 16)
+ {
+ #if defined(_SHA256_UNROLL) || defined(_SHA256_UNROLL2)
+ RX_8(0); RX_8(8);
+ #else
+ for (unsigned int i = 0; i < 16; i++) { R(i); }
+ #endif
+ }
+
+ #ifdef _SHA256_UNROLL2
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ state[5] += f;
+ state[6] += g;
+ state[7] += h;
+ #else
+ for (int i = 0; i < 8; i++)
+ state[i] += T[i];
+ #endif
+
+ // Wipe variables
+ // memset(W, 0, sizeof(W));
+ // memset(T, 0, sizeof(T));
+}
+
+const UInt32 CContext::K[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+#undef S0
+#undef S1
+#undef s0
+#undef s1
+
+void CContext::WriteByteBlock()
+{
+ UInt32 data32[16];
+ for (int i = 0; i < 16; i++)
+ {
+ data32[i] = (UInt32(_buffer[i * 4]) << 24) +
+ (UInt32(_buffer[i * 4 + 1]) << 16) +
+ (UInt32(_buffer[i * 4 + 2]) << 8) +
+ UInt32(_buffer[i * 4 + 3]);
+ }
+ Transform(_state, data32);
+}
+
+void CContext::Update(const Byte *data, size_t size)
+{
+ UInt32 curBufferPos = (UInt32)_count & 0x3F;
+ while (size > 0)
+ {
+ _buffer[curBufferPos++] = *data++;
+ _count++;
+ size--;
+ if (curBufferPos == 64)
+ {
+ curBufferPos = 0;
+ WriteByteBlock();
+ }
+ }
+}
+
+void CContext::Final(Byte *digest)
+{
+ UInt64 lenInBits = (_count << 3);
+ UInt32 curBufferPos = (UInt32)_count & 0x3F;
+ _buffer[curBufferPos++] = 0x80;
+ while (curBufferPos != (64 - 8))
+ {
+ curBufferPos &= 0x3F;
+ if (curBufferPos == 0)
+ WriteByteBlock();
+ _buffer[curBufferPos++] = 0;
+ }
+ for (int i = 0; i < 8; i++)
+ {
+ _buffer[curBufferPos++] = (Byte)(lenInBits >> 56);
+ lenInBits <<= 8;
+ }
+ WriteByteBlock();
+
+ for (int j = 0; j < 8; j++)
+ {
+ *digest++ = (Byte)(_state[j] >> 24);
+ *digest++ = (Byte)(_state[j] >> 16);
+ *digest++ = (Byte)(_state[j] >> 8);
+ *digest++ = (Byte)(_state[j]);
+ }
+ Init();
+}
+
+}}
diff --git a/CPP/7zip/Crypto/Hash/Sha256.h b/CPP/7zip/Crypto/Hash/Sha256.h
new file mode 100755
index 00000000..e4788f41
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/Sha256.h
@@ -0,0 +1,30 @@
+// Crypto/Sha256.h
+
+#ifndef __CRYPTO_SHA256_H
+#define __CRYPTO_SHA256_H
+
+#include "Common/Types.h"
+
+namespace NCrypto {
+namespace NSha256 {
+
+class CContext
+{
+ static const UInt32 K[64];
+
+ UInt32 _state[8];
+ UInt64 _count;
+ Byte _buffer[64];
+ static void Transform(UInt32 *digest, const UInt32 *data);
+ void WriteByteBlock();
+public:
+ enum {DIGESTSIZE = 32};
+ CContext() { Init(); } ;
+ void Init();
+ void Update(const Byte *data, size_t size);
+ void Final(Byte *digest);
+};
+
+}}
+
+#endif
diff --git a/CPP/7zip/Crypto/Hash/StdAfx.h b/CPP/7zip/Crypto/Hash/StdAfx.h
new file mode 100755
index 00000000..e7fb6986
--- /dev/null
+++ b/CPP/7zip/Crypto/Hash/StdAfx.h
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif