aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--checks/algos.cpp1
-rw-r--r--checks/validate.dat70
-rw-r--r--doc/log.txt1
-rw-r--r--src/engine/def_engine/lookup_hash.cpp9
-rw-r--r--src/hash/gost_3411/gost_3411.cpp177
-rw-r--r--src/hash/gost_3411/gost_3411.h41
-rw-r--r--src/hash/gost_3411/info.txt10
7 files changed, 309 insertions, 0 deletions
diff --git a/checks/algos.cpp b/checks/algos.cpp
index faadfa5c3..79a609dda 100644
--- a/checks/algos.cpp
+++ b/checks/algos.cpp
@@ -72,6 +72,7 @@ std::vector<algorithm> get_algos()
algos.push_back(algorithm("Hash", "CRC24"));
algos.push_back(algorithm("Hash", "CRC32"));
algos.push_back(algorithm("Hash", "FORK-256"));
+ algos.push_back(algorithm("Hash", "GOST-34.11"));
algos.push_back(algorithm("Hash", "HAS-160"));
algos.push_back(algorithm("Hash", "HAS-V"));
algos.push_back(algorithm("Hash", "MD2"));
diff --git a/checks/validate.dat b/checks/validate.dat
index 31b1825fb..eaa288b15 100644
--- a/checks/validate.dat
+++ b/checks/validate.dat
@@ -29958,6 +29958,76 @@ A572D774628B4C35E06F0ED0DF055F27C054B4A556B1ABEEB076D5D502390E1C31E28555BE7F6A\
6ED4B49FD7CAB793E4BC:\
B97C3815ABA1958CB4A6F64B3DDA017236224597101DD822F24A6A594F255973
+[GOST-34.11]
+# Using the CryptoPro sboxes. Generated by OpenSSL's GOST code
+
+:981E5F3CA30C841487830F84FB433E13AC1101569B9C13584AC483234CD656C0
+616263:B285056DBF18D7392D7677369524DD14747459ED8143997E163B2986F92FD42C
+
+730B3A80E44DDB0AD9A04D990D22F84009A86E5E8A2E00164EB168CEB279:\
+DF252A7F37EBDCF4995B5419394A6D3D2C782D30AB5FAE89F3665F86A4BBF78F
+
+67C6697351FF4AEC29CDBAABF2FBE3467CC254F81BE8E78D765A2E63339F:\
+EF35DA69225241950EBA3F20E6EE2D86A6286707EBE04819A81F79AD71DB62E2
+
+C4852EB81C5EEE208BBDCAA019F49142FC132197EDAF0E02374187066A9E25:\
+CEA05A7CA858638868FB64A1BBC015296980A6096B4EB09B03F1C8B075FF25EC
+
+12FC7387466C9687EF618EB38BEE08D4F67564BC48DFDE8A477EBBBC425C2C54:\
+D1E138CD1DB357091037E6041E6BBC7F58E32C4294F938868A9FF5E66E174EA0
+
+A040EE298C760CD98EB6467BC03D839A31598922758D475AA389881F465A8BE79B:\
+6AE26456D06C682AB63DE2DE3D0A8A932370B12204BAC4B04F78472665A350D7
+
+3679B590CDB17A11BB39575C88F02BA1EC7FD72A454D3A30E702073A9451F7CA\
+CBAC5B985ED5AA190E017597F2A038DE1F0F08655D429544459C7ED9EE75A4B9\
+21FF517FD4FB98E2FD0D79EFADB1CDCD:\
+F2D03BA660317AB8AE88490C6B25B79D74B2C307AF0DF128E82E98204C3504E1
+
+B3980FFE5331EE30B407FC8EFA18FF6CE35C841C1622C405C93A51CBE8B2EC9B\
+4AFC999E2D87CEE18FCA7089E26FF5C5CC7AE1E29CA6E766E03831C8EA1D6335\
+19FCD34683A128126B989C4D079113D30BF4B6A89A9D0E7AD63F42C05CA5F576\
+A1C8BC2569E437D47CD3228465355770290D18C4AB263E81658141C2263738C8\
+FFF4ED69D9243D55F85FD95D9431CDBE3EE682E90CC06A7241AC3468E36C30E2\
+601D4B3941898F39E868967D99643BD84ABDC1567D2CC8BFD8FC27BB68579DC9\
+74E902B57291EF5AFA85D793E9126B33CF2D8A4D59520C314F33ECB78A8980FE\
+7283B3E414A23F0E2816A211290D45F83ACF45932151C47084B0:\
+D8A200CD03364E0FB2A396FAB05E67E0EB1195672316B0F54D1D05425E2005D0
+
+D658E6C4786E9CA4E60B8961514C406336F46691F29A9B2B1C07784E7EDC6C55\
+355219ADC0B551A6C0DA07112748745D3CDAEE2E748A599091D2DF0FAE4B64E3\
+9D7D915D33E204F3BD0B05E45379418F542FBDC8B917594AE9385A9783BE7B20\
+3C0C7D6FEE8162AB8D678FE0E1D07035002DFDB94456042D8E5EC5111C403158\
+4CAFC73A302AE6BD91759E72460EA7463BA5FF80FB03AD8A61729B7EB2CDD6FE\
+7C9E39ACC81F6A599408CCDA167320511820D114237F9E85F13903A406D9A282\
+77DB2F3FFA99998FA16569B7D88A08F1AADA05CD59A3524ADC55EEE32F9165A6\
+6C94E6672D7FF6CEE45F85BCE98EAD9368B261C155B30B3209FA15388B7ADEF7\
+0FC45E3C43540B27B490E49D1E913186449247994553CB4E4DE086D85B65CF6A\
+292EA66D82B194364278D4600A05E74E972EE7DC81B32BCE93B1A6EE16765840\
+A4FFAD26B0415DF2BA3153C4363A12CD68F9A9EAACD4B840865F2E9CD587DC79\
+86899F36CBFC29852D7C4963B65B301E54DA0801AEC14134206FD1F5F6AD6E7C\
+370DB3020ADC873758D09B0E2BCB2C7FA5358054F6C1881631590B270779A43E\
+8657409033C7C88B976399C22EC541D4FAC228F083B006B40A11DC118A804F11\
+D78FA10A566995EDCC2EAFFBF3F0CFEEB2F7DE36A7E5EAB1F6C6C2814611921D\
+A03327F69DBCE369EA9264DE8333CC352AAA6BD28F5683861C460763579980F8\
+CCA8EE6964D2D34F64372DE76BF91D95A3886733DEEBB9FB31C05E8859DE8025\
+866F8FEB41623AA599678D0460AA9A0332013611ECEF0C1DAF6AA60848262ECF\
+95BDBAD61FF47CB85B09BDBBB357BEE558F5F645E40262946C089CB52FCA84C4\
+873E9BA632175F8D201C48D37306B8CBFBAF10E0B173741E7B10D3AADB576F62\
+950A09C721685441849C14F7A2CCC29E7BD37E2D46F24BC1021E6CDD75DB400A\
+E549D106B1254735C15B2C6327EE01A3C17FD007711BC974393551AE1091B8F5\
+DA89FB8BAE42C06F9DECD2C4DBD4679C5337A4C5526D398BA28A39B21CF1A7F6\
+7AA28228E44297812F6A450A3EADA691E44A5637B78FC2591AFC0B36EDB22C68\
+54AE9038F128B92092FF2AD0ACD061901BB8C7D2478A2C6186379773EAC4DB3E\
+726C7763943083262FADF6DB7E576C990F336B57BD97B843CF50B7B91492F786\
+FE6EEA929F6DB8CE1BAEAA9906163215499D6C0735254A047501BD8994B40F92\
+23F925C267DD90828C3A1B92504DA79AEA14A11F39EB23AEEDE03781954613B8\
+40387AA7160A29A24544349591DB2F7BEFD09B28BCBED6A99F0D2A34543DEC94\
+76663B8C70642EB5A8624B393D7AB42D4B4F55070E2CB0AD39DAE18D17CD218D\
+335C19A3C0475968A9A4A1E71E561469A56970B3952060CFFA415C120E7E9F41\
+DAB9E59B003E03AAE2A59100FBA56AA00EDA54A4FBB473F5F6CF07044DA74628:\
+12DF46E869E72CB058629D3554917D7ABA7C6D9D432751F58600138DD5862BFD
+
# From TTA.IS-10118:
# "Hash Function Standard - Part 2 : Hash Function Algorithm (HAS-160)"
# Telecommunications Technology Association, Republic of Korea, Nov 1998
diff --git a/doc/log.txt b/doc/log.txt
index b85df4db0..f808e34ce 100644
--- a/doc/log.txt
+++ b/doc/log.txt
@@ -2,6 +2,7 @@
* 1.8.2-pre, 2009-??-??
- Make entropy polling more flexible and in most cases faster
- GOST 28147 now supports multiple sbox parameters
+ - Added the GOST 34.11 hash function
- Fix botan-config problems on MacOS X
* 1.8.1, 2009-01-20
diff --git a/src/engine/def_engine/lookup_hash.cpp b/src/engine/def_engine/lookup_hash.cpp
index 6a0d42dee..f59d4c7e1 100644
--- a/src/engine/def_engine/lookup_hash.cpp
+++ b/src/engine/def_engine/lookup_hash.cpp
@@ -26,6 +26,10 @@
#include <botan/fork256.h>
#endif
+#if defined(BOTAN_HAS_GOST_34_11)
+ #include <botan/gost_3411.h>
+#endif
+
#if defined(BOTAN_HAS_HAS_160)
#include <botan/has160.h>
#endif
@@ -100,6 +104,11 @@ Default_Engine::find_hash(const SCAN_Name& request,
return new FORK_256;
#endif
+#if defined(BOTAN_HAS_GOST_34_11)
+ if(request.algo_name() == "GOST-34.11")
+ return new GOST_34_11;
+#endif
+
#if defined(BOTAN_HAS_HAS_160)
if(request.algo_name() == "HAS-160")
return new HAS_160;
diff --git a/src/hash/gost_3411/gost_3411.cpp b/src/hash/gost_3411/gost_3411.cpp
new file mode 100644
index 000000000..25118752f
--- /dev/null
+++ b/src/hash/gost_3411/gost_3411.cpp
@@ -0,0 +1,177 @@
+/*
+* GOST 34.11
+* (C) 2009 Jack Lloyd
+*/
+
+#include <botan/gost_3411.h>
+#include <botan/loadstor.h>
+#include <botan/bit_ops.h>
+#include <botan/xor_buf.h>
+
+namespace Botan {
+
+/**
+* GOST 34.11 Constructor
+*/
+GOST_34_11::GOST_34_11() :
+ HashFunction(32, 32),
+ cipher(GOST_28147_89_Params("R3411_CryptoPro"))
+ {
+ count = 0;
+ position = 0;
+ }
+
+void GOST_34_11::clear() throw()
+ {
+ cipher.clear();
+ sum.clear();
+ hash.clear();
+ count = 0;
+ position = 0;
+ }
+
+/**
+* Hash additional inputs
+*/
+void GOST_34_11::add_data(const byte input[], u32bit length)
+ {
+ count += length;
+
+ if(position)
+ {
+ buffer.copy(position, input, length);
+
+ if(position + length >= HASH_BLOCK_SIZE)
+ {
+ compress_n(buffer.begin(), 1);
+ input += (HASH_BLOCK_SIZE - position);
+ length -= (HASH_BLOCK_SIZE - position);
+ position = 0;
+ }
+ }
+
+ const u32bit full_blocks = length / HASH_BLOCK_SIZE;
+ const u32bit remaining = length % HASH_BLOCK_SIZE;
+
+ if(full_blocks)
+ compress_n(input, full_blocks);
+
+ buffer.copy(position, input + full_blocks * HASH_BLOCK_SIZE, remaining);
+ position += remaining;
+ }
+
+namespace {
+
+void psi(byte data[32])
+ {
+ byte x = data[0] ^ data[2] ^ data[4] ^ data[6] ^ data[24] ^ data[30];
+ byte y = data[1] ^ data[3] ^ data[5] ^ data[7] ^ data[25] ^ data[31];
+
+ copy_mem(data, data+2, 30);
+ data[30] = x;
+ data[31] = y;
+ }
+
+}
+
+/**
+* The GOST 34.11 compression function
+*/
+void GOST_34_11::compress_n(const byte input[], u32bit blocks)
+ {
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ for(u32bit j = 0, carry = 0; j != 32; ++j)
+ {
+ u16bit s = sum[j] + input[32*i+j] + carry;
+ carry = get_byte(0, s);
+ sum[j] = get_byte(1, s);
+ }
+
+ byte S[32] = { 0 };
+
+ u64bit U[4], V[4];
+
+ for(u32bit j = 0; j != 4; ++j)
+ {
+ U[j] = load_be<u64bit>(hash, j);
+ V[j] = load_be<u64bit>(input + 32*i, j);
+ }
+
+ for(u32bit j = 0; j != 4; ++j)
+ {
+ byte key[32] = { 0 };
+
+ // P transformation
+ for(size_t k = 0; k != 4; ++k)
+ for(size_t l = 0; l != 8; ++l)
+ key[4*l+k] = get_byte(l, U[k]) ^ get_byte(l, V[k]);
+
+ cipher.set_key(key, 32);
+ cipher.encrypt(hash + 8*j, S + 8*j);
+
+ if(j == 3)
+ break;
+
+ // A(x)
+ u64bit A_U = U[0];
+ U[0] = U[1];
+ U[1] = U[2];
+ U[2] = U[3];
+ U[3] = U[0] ^ A_U;
+
+ if(j == 1) // C_3
+ {
+ U[0] ^= 0x00FF00FF00FF00FF;
+ U[1] ^= 0xFF00FF00FF00FF00;
+ U[2] ^= 0x00FFFF00FF0000FF;
+ U[3] ^= 0xFF000000FFFF00FF;
+ }
+
+ // A(A(x))
+ u64bit AA_V_1 = V[0] ^ V[1];
+ u64bit AA_V_2 = V[1] ^ V[2];
+ V[0] = V[2];
+ V[1] = V[3];
+ V[2] = AA_V_1;
+ V[3] = AA_V_2;
+ }
+
+ for(u32bit j = 0; j != 12; ++j)
+ psi(S);
+ xor_buf(S, input + 32*i, 32);
+ psi(S);
+ xor_buf(S, hash, 32);
+ for(u32bit j = 0; j != 61; ++j)
+ psi(S);
+
+ hash.copy(S, 32);
+ }
+ }
+
+/**
+* Produce the final GOST 34.11 output
+*/
+void GOST_34_11::final_result(byte out[])
+ {
+ if(position)
+ {
+ clear_mem(buffer.begin() + position, buffer.size() - position);
+ compress_n(buffer, 1);
+ }
+
+ SecureBuffer<byte, 32> length_buf;
+ const u64bit bit_count = count * 8;
+ store_le(bit_count, length_buf);
+
+ SecureBuffer<byte, 32> sum_buf(sum);
+
+ compress_n(length_buf, 1);
+ compress_n(sum_buf, 1);
+
+ copy_mem(out, hash.begin(), 32);
+
+ clear();
+ }
+
+}
diff --git a/src/hash/gost_3411/gost_3411.h b/src/hash/gost_3411/gost_3411.h
new file mode 100644
index 000000000..c69555052
--- /dev/null
+++ b/src/hash/gost_3411/gost_3411.h
@@ -0,0 +1,41 @@
+/**
+* GOST 34.11
+* (C) 2009 Jack Lloyd
+*/
+
+#ifndef BOTAN_GOST_3411_H__
+#define BOTAN_GOST_3411_H__
+
+#include <botan/hash.h>
+#include <botan/gost_28147.h>
+
+namespace Botan {
+
+/**
+* GOST 34.11
+*/
+class BOTAN_DLL GOST_34_11 : public HashFunction
+ {
+ public:
+ void clear() throw();
+ std::string name() const { return "GOST-R-34.11-94" ; }
+ HashFunction* clone() const { return new GOST_34_11; }
+
+ GOST_34_11();
+ protected:
+ void compress_n(const byte input[], u32bit blocks);
+
+ void add_data(const byte[], u32bit);
+ void final_result(byte[]);
+
+ GOST_28147_89 cipher;
+ SecureBuffer<byte, 32> buffer;
+ SecureBuffer<byte, 32> sum;
+ SecureBuffer<byte, 32> hash;
+ u64bit count;
+ u32bit position;
+ };
+
+}
+
+#endif
diff --git a/src/hash/gost_3411/info.txt b/src/hash/gost_3411/info.txt
new file mode 100644
index 000000000..ef2879823
--- /dev/null
+++ b/src/hash/gost_3411/info.txt
@@ -0,0 +1,10 @@
+realname "GOST 34.11"
+
+define GOST_34_11
+
+load_on auto
+
+<add>
+gost_3411.cpp
+gost_3411.h
+</add>