Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gost_28147.cpp
Go to the documentation of this file.
1 /*
2 * GOST 28147-89
3 * (C) 1999-2009,2011 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/gost_28147.h>
9 #include <botan/loadstor.h>
10
11 namespace Botan {
12
13 uint8_t GOST_28147_89_Params::sbox_entry(size_t row, size_t col) const
14 {
15 uint8_t x = m_sboxes[4 * col + (row / 2)];
16
17 return (row % 2 == 0) ? (x >> 4) : (x & 0x0F);
18 }
19
20 GOST_28147_89_Params::GOST_28147_89_Params(const std::string& n) : m_name(n)
21 {
22 // Encoded in the packed fromat from RFC 4357
23
24 // GostR3411_94_TestParamSet (OID 1.2.643.2.2.31.0)
25 static const uint8_t GOST_R_3411_TEST_PARAMS[64] = {
26 0x4E, 0x57, 0x64, 0xD1, 0xAB, 0x8D, 0xCB, 0xBF, 0x94, 0x1A, 0x7A,
27 0x4D, 0x2C, 0xD1, 0x10, 0x10, 0xD6, 0xA0, 0x57, 0x35, 0x8D, 0x38,
28 0xF2, 0xF7, 0x0F, 0x49, 0xD1, 0x5A, 0xEA, 0x2F, 0x8D, 0x94, 0x62,
29 0xEE, 0x43, 0x09, 0xB3, 0xF4, 0xA6, 0xA2, 0x18, 0xC6, 0x98, 0xE3,
30 0xC1, 0x7C, 0xE5, 0x7E, 0x70, 0x6B, 0x09, 0x66, 0xF7, 0x02, 0x3C,
31 0x8B, 0x55, 0x95, 0xBF, 0x28, 0x39, 0xB3, 0x2E, 0xCC };
32
33 // GostR3411-94-CryptoProParamSet (OID 1.2.643.2.2.31.1)
34 static const uint8_t GOST_R_3411_CRYPTOPRO_PARAMS[64] = {
35 0xA5, 0x74, 0x77, 0xD1, 0x4F, 0xFA, 0x66, 0xE3, 0x54, 0xC7, 0x42,
36 0x4A, 0x60, 0xEC, 0xB4, 0x19, 0x82, 0x90, 0x9D, 0x75, 0x1D, 0x4F,
37 0xC9, 0x0B, 0x3B, 0x12, 0x2F, 0x54, 0x79, 0x08, 0xA0, 0xAF, 0xD1,
38 0x3E, 0x1A, 0x38, 0xC7, 0xB1, 0x81, 0xC6, 0xE6, 0x56, 0x05, 0x87,
39 0x03, 0x25, 0xEB, 0xFE, 0x9C, 0x6D, 0xF8, 0x6D, 0x2E, 0xAB, 0xDE,
40 0x20, 0xBA, 0x89, 0x3C, 0x92, 0xF8, 0xD3, 0x53, 0xBC };
41
42 if(m_name == "R3411_94_TestParam")
43 m_sboxes = GOST_R_3411_TEST_PARAMS;
44 else if(m_name == "R3411_CryptoPro")
45 m_sboxes = GOST_R_3411_CRYPTOPRO_PARAMS;
46 else
47 throw Invalid_Argument("GOST_28147_89_Params: Unknown " + m_name);
48 }
49
50 /*
51 * GOST Constructor
52 */
53 GOST_28147_89::GOST_28147_89(const GOST_28147_89_Params& param) : m_SBOX(1024)
54 {
55 // Convert the parallel 4x4 sboxes into larger word-based sboxes
56 for(size_t i = 0; i != 4; ++i)
57 for(size_t j = 0; j != 256; ++j)
58 {
59 const uint32_t T = (param.sbox_entry(2*i , j % 16)) |
60 (param.sbox_entry(2*i+1, j / 16) << 4);
61 m_SBOX[256*i+j] = rotate_left(T, (11+8*i) % 32);
62 }
63 }
64
65 std::string GOST_28147_89::name() const
66 {
67 /*
68 'Guess' the right name for the sbox on the basis of the values.
69 This would need to be updated if support for other sbox parameters
70 is added. Preferably, we would just store the string value in the
71 constructor, but can't break binary compat.
72 */
73 std::string sbox_name = "";
74 if(m_SBOX[0] == 0x00072000)
75 sbox_name = "R3411_94_TestParam";
76 else if(m_SBOX[0] == 0x0002D000)
77 sbox_name = "R3411_CryptoPro";
78 else
79 throw Internal_Error("GOST-28147 unrecognized sbox value");
80
81 return "GOST-28147-89(" + sbox_name + ")";
82 }
83
84 /*
85 * Two rounds of GOST
86 */
87 #define GOST_2ROUND(N1, N2, R1, R2) \
88 do { \
89 uint32_t T0 = N1 + m_EK[R1]; \
90 N2 ^= m_SBOX[get_byte(3, T0)] | \
91 m_SBOX[get_byte(2, T0)+256] | \
92 m_SBOX[get_byte(1, T0)+512] | \
93 m_SBOX[get_byte(0, T0)+768]; \
94 \
95 uint32_t T1 = N2 + m_EK[R2]; \
96 N1 ^= m_SBOX[get_byte(3, T1)] | \
97 m_SBOX[get_byte(2, T1)+256] | \
98 m_SBOX[get_byte(1, T1)+512] | \
99 m_SBOX[get_byte(0, T1)+768]; \
100 } while(0)
101
102 /*
103 * GOST Encryption
104 */
105 void GOST_28147_89::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
106 {
107 for(size_t i = 0; i != blocks; ++i)
108 {
109 uint32_t N1 = load_le<uint32_t>(in, 0);
110 uint32_t N2 = load_le<uint32_t>(in, 1);
111
112 for(size_t j = 0; j != 3; ++j)
113 {
114 GOST_2ROUND(N1, N2, 0, 1);
115 GOST_2ROUND(N1, N2, 2, 3);
116 GOST_2ROUND(N1, N2, 4, 5);
117 GOST_2ROUND(N1, N2, 6, 7);
118 }
119
120 GOST_2ROUND(N1, N2, 7, 6);
121 GOST_2ROUND(N1, N2, 5, 4);
122 GOST_2ROUND(N1, N2, 3, 2);
123 GOST_2ROUND(N1, N2, 1, 0);
124
125 store_le(out, N2, N1);
126
127 in += BLOCK_SIZE;
128 out += BLOCK_SIZE;
129 }
130 }
131
132 /*
133 * GOST Decryption
134 */
135 void GOST_28147_89::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
136 {
137 for(size_t i = 0; i != blocks; ++i)
138 {
139 uint32_t N1 = load_le<uint32_t>(in, 0);
140 uint32_t N2 = load_le<uint32_t>(in, 1);
141
142 GOST_2ROUND(N1, N2, 0, 1);
143 GOST_2ROUND(N1, N2, 2, 3);
144 GOST_2ROUND(N1, N2, 4, 5);
145 GOST_2ROUND(N1, N2, 6, 7);
146
147 for(size_t j = 0; j != 3; ++j)
148 {
149 GOST_2ROUND(N1, N2, 7, 6);
150 GOST_2ROUND(N1, N2, 5, 4);
151 GOST_2ROUND(N1, N2, 3, 2);
152 GOST_2ROUND(N1, N2, 1, 0);
153 }
154
155 store_le(out, N2, N1);
156 in += BLOCK_SIZE;
157 out += BLOCK_SIZE;
158 }
159 }
160
161 /*
162 * GOST Key Schedule
163 */
164 void GOST_28147_89::key_schedule(const uint8_t key[], size_t)
165 {
166 m_EK.resize(8);
167 for(size_t i = 0; i != 8; ++i)
168 m_EK[i] = load_le<uint32_t>(key, i);
169 }
170
171 void GOST_28147_89::clear()
172 {
173 zap(m_EK);
174 }
175
176 }
Botan::Invalid_Argument
Definition: exceptn.h:34
Botan::Block_Cipher_Fixed_Params< 8, 32 >::BLOCK_SIZE
Definition: block_cipher.h:186
m_name
std::string m_name
Definition: openssl_hash.cpp:69
Botan::zap
void zap(std::vector< T, Alloc > &vec)
Definition: secmem.h:221
Botan::GOST_28147_89_Params::GOST_28147_89_Params
GOST_28147_89_Params(const std::string &name="R3411_94_TestParam")
Definition: gost_28147.cpp:20
Botan::GOST_28147_89::decrypt_n
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: gost_28147.cpp:135
Botan::GOST_28147_89_Params
Definition: gost_28147.h:21
Botan::GOST_28147_89::name
std::string name() const override
Definition: gost_28147.cpp:65
Botan::Internal_Error
Definition: exceptn.h:88
Botan::load_le< uint32_t >
uint32_t load_le< uint32_t >(const uint8_t in[], size_t off)
Definition: loadstor.h:204
Botan::rotate_left
T rotate_left(T input, size_t rot)
Definition: rotate.h:21
Botan::GOST_28147_89::GOST_28147_89
GOST_28147_89(const GOST_28147_89_Params &params)
Definition: gost_28147.cpp:53
Botan::GOST_28147_89_Params::sbox_entry
uint8_t sbox_entry(size_t row, size_t col) const
Definition: gost_28147.cpp:13
Botan::GOST_28147_89::encrypt_n
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
Definition: gost_28147.cpp:105
Botan
Definition: alg_id.cpp:13
Botan::GOST_28147_89::clear
void clear() override
Definition: gost_28147.cpp:171
GOST_2ROUND
#define GOST_2ROUND(N1, N2, R1, R2)
Definition: gost_28147.cpp:87
Botan::store_le
void store_le(uint16_t in, uint8_t out[2])
Definition: loadstor.h:457