diff options
author | lloyd <[email protected]> | 2009-03-27 19:25:12 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2009-03-27 19:25:12 +0000 |
commit | fdc5fc1e78d584f6dd46d762ea524bcab20d56e3 (patch) | |
tree | a69c10cd9ee6bc75567fe5e3491c3f669f8577ff /src/block/gost_28147 | |
parent | 96a6948055bb0a497eab1a9a4a86cb2bb648a5b5 (diff) |
GOST was using a completely non-standard set of sboxes. Change it to use
GostR3411_94_TestParamSet, this is compatible with the implementations in
Crypto++ and OpenSSL. This is not backwards compatible, though once the
implementation supports multiple param sets (which is required, unfortunately,
for compatability with various standards by CryptoCom, who have defined not
one but at least 4 (!!!) different sboxes to use with GOST), I may offer
Botan's previous sbox set as an option.
Since adding the GOST hash function (34.11) and signing algorithm (34.10)
are on the long term agenda (request by Rickard Bondesson, as the Russian
authorities want to use their local standards for their DNSSEC use), I
renamed the block cipher class (which had been just 'GOST') to GOST_28147_89
to minimize future name clashes.
Diffstat (limited to 'src/block/gost_28147')
-rw-r--r-- | src/block/gost_28147/gost_28147.cpp | 106 | ||||
-rw-r--r-- | src/block/gost_28147/gost_28147.h | 36 | ||||
-rw-r--r-- | src/block/gost_28147/info.txt | 10 |
3 files changed, 152 insertions, 0 deletions
diff --git a/src/block/gost_28147/gost_28147.cpp b/src/block/gost_28147/gost_28147.cpp new file mode 100644 index 000000000..ad57a2ca7 --- /dev/null +++ b/src/block/gost_28147/gost_28147.cpp @@ -0,0 +1,106 @@ +/* +* GOST 28147-89 +* (C) 1999-2009 Jack Lloyd +*/ + +#include <botan/gost_28147.h> +#include <botan/loadstor.h> + +namespace Botan { + +/* +* GOST Constructor +*/ +GOST_28147_89::GOST_28147_89() : BlockCipher(8, 32) + { + + // GostR3411_94_TestParamSet (OID 1.2.643.2.2.31.0) + const byte sbox[8][16] = { + {0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3} + {0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9}, + {0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB}, + {0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3}, + {0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2}, + {0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE}, + {0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC}, + {0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC}, + }; + + for(size_t i = 0; i != 4; ++i) + for(size_t j = 0; j != 256; ++j) + { + u32bit T = sbox[2*i][j%16] | (sbox[2*i+1][j/16] << 4); + SBOX[256*i+j] = rotate_left(T, (11+8*i) % 32); + } + } + +/* +* GOST Encryption +*/ +void GOST_28147_89::enc(const byte in[], byte out[]) const + { + u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1); + + for(u32bit j = 0; j != 32; j += 2) + { + u32bit T0; + + T0 = N1 + EK[j]; + N2 ^= SBOX[get_byte(3, T0)] | + SBOX[get_byte(2, T0)+256] | + SBOX[get_byte(1, T0)+512] | + SBOX[get_byte(0, T0)+768]; + + T0 = N2 + EK[j+1]; + N1 ^= SBOX[get_byte(3, T0)] | + SBOX[get_byte(2, T0)+256] | + SBOX[get_byte(1, T0)+512] | + SBOX[get_byte(0, T0)+768]; + } + + store_le(out, N2, N1); + } + +/* +* GOST Decryption +*/ +void GOST_28147_89::dec(const byte in[], byte out[]) const + { + u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1); + + for(u32bit j = 0; j != 32; j += 2) + { + u32bit T0; + + T0 = N1 + EK[31-j]; + N2 ^= SBOX[get_byte(3, T0)] | + SBOX[get_byte(2, T0)+256] | + SBOX[get_byte(1, T0)+512] | + SBOX[get_byte(0, T0)+768]; + + T0 = N2 + EK[30-j]; + N1 ^= SBOX[get_byte(3, T0)] | + SBOX[get_byte(2, T0)+256] | + SBOX[get_byte(1, T0)+512] | + SBOX[get_byte(0, T0)+768]; + } + + store_le(out, N2, N1); + } + +/* +* GOST Key Schedule +*/ +void GOST_28147_89::key_schedule(const byte key[], u32bit) + { + for(u32bit j = 0; j != 8; ++j) + { + u32bit K = load_le<u32bit>(key, j); + EK[j] = EK[j+8] = EK[j+16] = K; + } + + for(u32bit j = 24; j != 32; ++j) + EK[j] = EK[7-(j-24)]; + } + +} diff --git a/src/block/gost_28147/gost_28147.h b/src/block/gost_28147/gost_28147.h new file mode 100644 index 000000000..d79bdb8d6 --- /dev/null +++ b/src/block/gost_28147/gost_28147.h @@ -0,0 +1,36 @@ +/* +* GOST 28147-89 +* (C) 1999-2009 Jack Lloyd +*/ + +#ifndef BOTAN_GOST_28147_89_H__ +#define BOTAN_GOST_28147_89_H__ + +#include <botan/block_cipher.h> + +namespace Botan { + +/** +* GOST 28147-89 +*/ +class BOTAN_DLL GOST_28147_89 : public BlockCipher + { + public: + void clear() throw() { EK.clear(); } + + std::string name() const { return "GOST-28147-89"; } + BlockCipher* clone() const { return new GOST_28147_89; } + + GOST_28147_89(); + private: + void enc(const byte[], byte[]) const; + void dec(const byte[], byte[]) const; + void key_schedule(const byte[], u32bit); + + SecureBuffer<u32bit, 1024> SBOX; + SecureBuffer<u32bit, 32> EK; + }; + +} + +#endif diff --git a/src/block/gost_28147/info.txt b/src/block/gost_28147/info.txt new file mode 100644 index 000000000..6e187fd48 --- /dev/null +++ b/src/block/gost_28147/info.txt @@ -0,0 +1,10 @@ +realname "GOST 28147-89" + +define GOST_28147_89 + +load_on auto + +<add> +gost_28147.cpp +gost_28147.h +</add> |