Coverage Report

Created: 2023-09-25 06:33

/src/botan/src/lib/block/seed/seed.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* SEED
3
* (C) 1999-2007,2020 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/internal/seed.h>
9
10
#include <botan/internal/loadstor.h>
11
#include <botan/internal/prefetch.h>
12
13
namespace Botan {
14
15
namespace {
16
17
alignas(256) const uint8_t SEED_S0[256] = {
18
   0xA9, 0x85, 0xD6, 0xD3, 0x54, 0x1D, 0xAC, 0x25, 0x5D, 0x43, 0x18, 0x1E, 0x51, 0xFC, 0xCA, 0x63, 0x28, 0x44, 0x20,
19
   0x9D, 0xE0, 0xE2, 0xC8, 0x17, 0xA5, 0x8F, 0x03, 0x7B, 0xBB, 0x13, 0xD2, 0xEE, 0x70, 0x8C, 0x3F, 0xA8, 0x32, 0xDD,
20
   0xF6, 0x74, 0xEC, 0x95, 0x0B, 0x57, 0x5C, 0x5B, 0xBD, 0x01, 0x24, 0x1C, 0x73, 0x98, 0x10, 0xCC, 0xF2, 0xD9, 0x2C,
21
   0xE7, 0x72, 0x83, 0x9B, 0xD1, 0x86, 0xC9, 0x60, 0x50, 0xA3, 0xEB, 0x0D, 0xB6, 0x9E, 0x4F, 0xB7, 0x5A, 0xC6, 0x78,
22
   0xA6, 0x12, 0xAF, 0xD5, 0x61, 0xC3, 0xB4, 0x41, 0x52, 0x7D, 0x8D, 0x08, 0x1F, 0x99, 0x00, 0x19, 0x04, 0x53, 0xF7,
23
   0xE1, 0xFD, 0x76, 0x2F, 0x27, 0xB0, 0x8B, 0x0E, 0xAB, 0xA2, 0x6E, 0x93, 0x4D, 0x69, 0x7C, 0x09, 0x0A, 0xBF, 0xEF,
24
   0xF3, 0xC5, 0x87, 0x14, 0xFE, 0x64, 0xDE, 0x2E, 0x4B, 0x1A, 0x06, 0x21, 0x6B, 0x66, 0x02, 0xF5, 0x92, 0x8A, 0x0C,
25
   0xB3, 0x7E, 0xD0, 0x7A, 0x47, 0x96, 0xE5, 0x26, 0x80, 0xAD, 0xDF, 0xA1, 0x30, 0x37, 0xAE, 0x36, 0x15, 0x22, 0x38,
26
   0xF4, 0xA7, 0x45, 0x4C, 0x81, 0xE9, 0x84, 0x97, 0x35, 0xCB, 0xCE, 0x3C, 0x71, 0x11, 0xC7, 0x89, 0x75, 0xFB, 0xDA,
27
   0xF8, 0x94, 0x59, 0x82, 0xC4, 0xFF, 0x49, 0x39, 0x67, 0xC0, 0xCF, 0xD7, 0xB8, 0x0F, 0x8E, 0x42, 0x23, 0x91, 0x6C,
28
   0xDB, 0xA4, 0x34, 0xF1, 0x48, 0xC2, 0x6F, 0x3D, 0x2D, 0x40, 0xBE, 0x3E, 0xBC, 0xC1, 0xAA, 0xBA, 0x4E, 0x55, 0x3B,
29
   0xDC, 0x68, 0x7F, 0x9C, 0xD8, 0x4A, 0x56, 0x77, 0xA0, 0xED, 0x46, 0xB5, 0x2B, 0x65, 0xFA, 0xE3, 0xB9, 0xB1, 0x9F,
30
   0x5E, 0xF9, 0xE6, 0xB2, 0x31, 0xEA, 0x6D, 0x5F, 0xE4, 0xF0, 0xCD, 0x88, 0x16, 0x3A, 0x58, 0xD4, 0x62, 0x29, 0x07,
31
   0x33, 0xE8, 0x1B, 0x05, 0x79, 0x90, 0x6A, 0x2A, 0x9A,
32
};
33
34
alignas(256) const uint8_t SEED_S1[256] = {
35
   0x38, 0xE8, 0x2D, 0xA6, 0xCF, 0xDE, 0xB3, 0xB8, 0xAF, 0x60, 0x55, 0xC7, 0x44, 0x6F, 0x6B, 0x5B, 0xC3, 0x62, 0x33,
36
   0xB5, 0x29, 0xA0, 0xE2, 0xA7, 0xD3, 0x91, 0x11, 0x06, 0x1C, 0xBC, 0x36, 0x4B, 0xEF, 0x88, 0x6C, 0xA8, 0x17, 0xC4,
37
   0x16, 0xF4, 0xC2, 0x45, 0xE1, 0xD6, 0x3F, 0x3D, 0x8E, 0x98, 0x28, 0x4E, 0xF6, 0x3E, 0xA5, 0xF9, 0x0D, 0xDF, 0xD8,
38
   0x2B, 0x66, 0x7A, 0x27, 0x2F, 0xF1, 0x72, 0x42, 0xD4, 0x41, 0xC0, 0x73, 0x67, 0xAC, 0x8B, 0xF7, 0xAD, 0x80, 0x1F,
39
   0xCA, 0x2C, 0xAA, 0x34, 0xD2, 0x0B, 0xEE, 0xE9, 0x5D, 0x94, 0x18, 0xF8, 0x57, 0xAE, 0x08, 0xC5, 0x13, 0xCD, 0x86,
40
   0xB9, 0xFF, 0x7D, 0xC1, 0x31, 0xF5, 0x8A, 0x6A, 0xB1, 0xD1, 0x20, 0xD7, 0x02, 0x22, 0x04, 0x68, 0x71, 0x07, 0xDB,
41
   0x9D, 0x99, 0x61, 0xBE, 0xE6, 0x59, 0xDD, 0x51, 0x90, 0xDC, 0x9A, 0xA3, 0xAB, 0xD0, 0x81, 0x0F, 0x47, 0x1A, 0xE3,
42
   0xEC, 0x8D, 0xBF, 0x96, 0x7B, 0x5C, 0xA2, 0xA1, 0x63, 0x23, 0x4D, 0xC8, 0x9E, 0x9C, 0x3A, 0x0C, 0x2E, 0xBA, 0x6E,
43
   0x9F, 0x5A, 0xF2, 0x92, 0xF3, 0x49, 0x78, 0xCC, 0x15, 0xFB, 0x70, 0x75, 0x7F, 0x35, 0x10, 0x03, 0x64, 0x6D, 0xC6,
44
   0x74, 0xD5, 0xB4, 0xEA, 0x09, 0x76, 0x19, 0xFE, 0x40, 0x12, 0xE0, 0xBD, 0x05, 0xFA, 0x01, 0xF0, 0x2A, 0x5E, 0xA9,
45
   0x56, 0x43, 0x85, 0x14, 0x89, 0x9B, 0xB0, 0xE5, 0x48, 0x79, 0x97, 0xFC, 0x1E, 0x82, 0x21, 0x8C, 0x1B, 0x5F, 0x77,
46
   0x54, 0xB2, 0x1D, 0x25, 0x4F, 0x00, 0x46, 0xED, 0x58, 0x52, 0xEB, 0x7E, 0xDA, 0xC9, 0xFD, 0x30, 0x95, 0x65, 0x3C,
47
   0xB6, 0xE4, 0xBB, 0x7C, 0x0E, 0x50, 0x39, 0x26, 0x32, 0x84, 0x69, 0x93, 0x37, 0xE7, 0x24, 0xA4, 0xCB, 0x53, 0x0A,
48
   0x87, 0xD9, 0x4C, 0x83, 0x8F, 0xCE, 0x3B, 0x4A, 0xB7,
49
};
50
51
/*
52
* SEED G Function
53
*/
54
70.0k
inline uint32_t SEED_G(uint32_t X) {
55
70.0k
   const uint32_t M = 0x01010101;
56
70.0k
   const uint32_t s0 = M * SEED_S0[get_byte<3>(X)];
57
70.0k
   const uint32_t s1 = M * SEED_S1[get_byte<2>(X)];
58
70.0k
   const uint32_t s2 = M * SEED_S0[get_byte<1>(X)];
59
70.0k
   const uint32_t s3 = M * SEED_S1[get_byte<0>(X)];
60
61
70.0k
   const uint32_t M0 = 0x3FCFF3FC;
62
70.0k
   const uint32_t M1 = 0xFC3FCFF3;
63
70.0k
   const uint32_t M2 = 0xF3FC3FCF;
64
70.0k
   const uint32_t M3 = 0xCFF3FC3F;
65
66
70.0k
   return (s0 & M0) ^ (s1 & M1) ^ (s2 & M2) ^ (s3 & M3);
67
70.0k
}
68
69
}  // namespace
70
71
/*
72
* SEED Encryption
73
*/
74
1.44k
void SEED::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
75
1.44k
   assert_key_material_set();
76
77
1.44k
   prefetch_arrays(SEED_S0, SEED_S1);
78
79
2.89k
   for(size_t i = 0; i != blocks; ++i) {
80
1.44k
      uint32_t B0 = load_be<uint32_t>(in, 0);
81
1.44k
      uint32_t B1 = load_be<uint32_t>(in, 1);
82
1.44k
      uint32_t B2 = load_be<uint32_t>(in, 2);
83
1.44k
      uint32_t B3 = load_be<uint32_t>(in, 3);
84
85
13.0k
      for(size_t j = 0; j != 16; j += 2) {
86
11.5k
         uint32_t T0, T1;
87
88
11.5k
         T0 = B2 ^ m_K[2 * j];
89
11.5k
         T1 = SEED_G(B2 ^ B3 ^ m_K[2 * j + 1]);
90
11.5k
         T0 = SEED_G(T1 + T0);
91
11.5k
         T1 = SEED_G(T1 + T0);
92
11.5k
         B1 ^= T1;
93
11.5k
         B0 ^= T0 + T1;
94
95
11.5k
         T0 = B0 ^ m_K[2 * j + 2];
96
11.5k
         T1 = SEED_G(B0 ^ B1 ^ m_K[2 * j + 3]);
97
11.5k
         T0 = SEED_G(T1 + T0);
98
11.5k
         T1 = SEED_G(T1 + T0);
99
11.5k
         B3 ^= T1;
100
11.5k
         B2 ^= T0 + T1;
101
11.5k
      }
102
103
1.44k
      store_be(out, B2, B3, B0, B1);
104
105
1.44k
      in += BLOCK_SIZE;
106
1.44k
      out += BLOCK_SIZE;
107
1.44k
   }
108
1.44k
}
109
110
/*
111
* SEED Decryption
112
*/
113
0
void SEED::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
114
0
   assert_key_material_set();
115
116
0
   prefetch_arrays(SEED_S0, SEED_S1);
117
118
0
   for(size_t i = 0; i != blocks; ++i) {
119
0
      uint32_t B0 = load_be<uint32_t>(in, 0);
120
0
      uint32_t B1 = load_be<uint32_t>(in, 1);
121
0
      uint32_t B2 = load_be<uint32_t>(in, 2);
122
0
      uint32_t B3 = load_be<uint32_t>(in, 3);
123
124
0
      for(size_t j = 0; j != 16; j += 2) {
125
0
         uint32_t T0, T1;
126
127
0
         T0 = B2 ^ m_K[30 - 2 * j];
128
0
         T1 = SEED_G(B2 ^ B3 ^ m_K[31 - 2 * j]);
129
0
         T0 = SEED_G(T1 + T0);
130
0
         T1 = SEED_G(T1 + T0);
131
0
         B1 ^= T1;
132
0
         B0 ^= T0 + T1;
133
134
0
         T0 = B0 ^ m_K[28 - 2 * j];
135
0
         T1 = SEED_G(B0 ^ B1 ^ m_K[29 - 2 * j]);
136
0
         T0 = SEED_G(T1 + T0);
137
0
         T1 = SEED_G(T1 + T0);
138
0
         B3 ^= T1;
139
0
         B2 ^= T0 + T1;
140
0
      }
141
142
0
      store_be(out, B2, B3, B0, B1);
143
144
0
      in += BLOCK_SIZE;
145
0
      out += BLOCK_SIZE;
146
0
   }
147
0
}
148
149
1.44k
bool SEED::has_keying_material() const {
150
1.44k
   return !m_K.empty();
151
1.44k
}
152
153
/*
154
* SEED Key Schedule
155
*/
156
20
void SEED::key_schedule(std::span<const uint8_t> key) {
157
20
   const uint32_t RC[16] = {0x9E3779B9,
158
20
                            0x3C6EF373,
159
20
                            0x78DDE6E6,
160
20
                            0xF1BBCDCC,
161
20
                            0xE3779B99,
162
20
                            0xC6EF3733,
163
20
                            0x8DDE6E67,
164
20
                            0x1BBCDCCF,
165
20
                            0x3779B99E,
166
20
                            0x6EF3733C,
167
20
                            0xDDE6E678,
168
20
                            0xBBCDCCF1,
169
20
                            0x779B99E3,
170
20
                            0xEF3733C6,
171
20
                            0xDE6E678D,
172
20
                            0xBCDCCF1B};
173
174
20
   secure_vector<uint32_t> WK(4);
175
176
100
   for(size_t i = 0; i != 4; ++i) {
177
80
      WK[i] = load_be<uint32_t>(key.data(), i);
178
80
   }
179
180
20
   m_K.resize(32);
181
182
180
   for(size_t i = 0; i != 16; i += 2) {
183
160
      m_K[2 * i] = SEED_G(WK[0] + WK[2] - RC[i]);
184
160
      m_K[2 * i + 1] = SEED_G(WK[1] - WK[3] + RC[i]) ^ m_K[2 * i];
185
186
160
      uint32_t T = (WK[0] & 0xFF) << 24;
187
160
      WK[0] = (WK[0] >> 8) | (get_byte<3>(WK[1]) << 24);
188
160
      WK[1] = (WK[1] >> 8) | T;
189
190
160
      m_K[2 * i + 2] = SEED_G(WK[0] + WK[2] - RC[i + 1]);
191
160
      m_K[2 * i + 3] = SEED_G(WK[1] - WK[3] + RC[i + 1]) ^ m_K[2 * i + 2];
192
193
160
      T = get_byte<0>(WK[3]);
194
160
      WK[3] = (WK[3] << 8) | get_byte<0>(WK[2]);
195
160
      WK[2] = (WK[2] << 8) | T;
196
160
   }
197
20
}
198
199
20
void SEED::clear() {
200
20
   zap(m_K);
201
20
}
202
203
}  // namespace Botan