Coverage Report

Created: 2023-02-22 06:14

/src/botan/src/lib/block/aria/aria.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* ARIA
3
* Adapted for Botan by Jeffrey Walton, public domain
4
*
5
* Further changes
6
* (C) 2017,2020 Jack Lloyd
7
*
8
* Botan is released under the Simplified BSD License (see license.txt)
9
*
10
* This ARIA implementation is based on the 32-bit implementation by Aaram Yun from the
11
* National Security Research Institute, KOREA. Aaram Yun's implementation is based on
12
* the 8-bit implementation by Jin Hong. The source files are available in ARIA.zip from
13
* the Korea Internet & Security Agency website.
14
* <A HREF="https://tools.ietf.org/html/rfc5794">RFC 5794, A Description of the ARIA Encryption Algorithm</A>,
15
* <A HREF="http://seed.kisa.or.kr/iwt/ko/bbs/EgovReferenceList.do?bbsId=BBSMSTR_000000000002">Korea
16
* Internet & Security Agency homepage</A>
17
*/
18
19
#include <botan/internal/aria.h>
20
#include <botan/internal/loadstor.h>
21
#include <botan/internal/rotate.h>
22
#include <botan/internal/cpuid.h>
23
24
namespace Botan {
25
26
namespace {
27
28
namespace ARIA_F {
29
30
alignas(256) const uint8_t S1[256] = {
31
   0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67,
32
   0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59,
33
   0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7,
34
   0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1,
35
   0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05,
36
   0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83,
37
   0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29,
38
   0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
39
   0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA,
40
   0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C,
41
   0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC,
42
   0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC,
43
   0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19,
44
   0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE,
45
   0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49,
46
   0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
47
   0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4,
48
   0xEA, 0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6,
49
   0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70,
50
   0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9,
51
   0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E,
52
   0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 0x8C, 0xA1,
53
   0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0,
54
   0x54, 0xBB, 0x16 };
55
56
alignas(256) const uint8_t S2[256] = {
57
   0xE2, 0x4E, 0x54, 0xFC, 0x94, 0xC2, 0x4A, 0xCC, 0x62, 0x0D, 0x6A,
58
   0x46, 0x3C, 0x4D, 0x8B, 0xD1, 0x5E, 0xFA, 0x64, 0xCB, 0xB4, 0x97,
59
   0xBE, 0x2B, 0xBC, 0x77, 0x2E, 0x03, 0xD3, 0x19, 0x59, 0xC1, 0x1D,
60
   0x06, 0x41, 0x6B, 0x55, 0xF0, 0x99, 0x69, 0xEA, 0x9C, 0x18, 0xAE,
61
   0x63, 0xDF, 0xE7, 0xBB, 0x00, 0x73, 0x66, 0xFB, 0x96, 0x4C, 0x85,
62
   0xE4, 0x3A, 0x09, 0x45, 0xAA, 0x0F, 0xEE, 0x10, 0xEB, 0x2D, 0x7F,
63
   0xF4, 0x29, 0xAC, 0xCF, 0xAD, 0x91, 0x8D, 0x78, 0xC8, 0x95, 0xF9,
64
   0x2F, 0xCE, 0xCD, 0x08, 0x7A, 0x88, 0x38, 0x5C, 0x83, 0x2A, 0x28,
65
   0x47, 0xDB, 0xB8, 0xC7, 0x93, 0xA4, 0x12, 0x53, 0xFF, 0x87, 0x0E,
66
   0x31, 0x36, 0x21, 0x58, 0x48, 0x01, 0x8E, 0x37, 0x74, 0x32, 0xCA,
67
   0xE9, 0xB1, 0xB7, 0xAB, 0x0C, 0xD7, 0xC4, 0x56, 0x42, 0x26, 0x07,
68
   0x98, 0x60, 0xD9, 0xB6, 0xB9, 0x11, 0x40, 0xEC, 0x20, 0x8C, 0xBD,
69
   0xA0, 0xC9, 0x84, 0x04, 0x49, 0x23, 0xF1, 0x4F, 0x50, 0x1F, 0x13,
70
   0xDC, 0xD8, 0xC0, 0x9E, 0x57, 0xE3, 0xC3, 0x7B, 0x65, 0x3B, 0x02,
71
   0x8F, 0x3E, 0xE8, 0x25, 0x92, 0xE5, 0x15, 0xDD, 0xFD, 0x17, 0xA9,
72
   0xBF, 0xD4, 0x9A, 0x7E, 0xC5, 0x39, 0x67, 0xFE, 0x76, 0x9D, 0x43,
73
   0xA7, 0xE1, 0xD0, 0xF5, 0x68, 0xF2, 0x1B, 0x34, 0x70, 0x05, 0xA3,
74
   0x8A, 0xD5, 0x79, 0x86, 0xA8, 0x30, 0xC6, 0x51, 0x4B, 0x1E, 0xA6,
75
   0x27, 0xF6, 0x35, 0xD2, 0x6E, 0x24, 0x16, 0x82, 0x5F, 0xDA, 0xE6,
76
   0x75, 0xA2, 0xEF, 0x2C, 0xB2, 0x1C, 0x9F, 0x5D, 0x6F, 0x80, 0x0A,
77
   0x72, 0x44, 0x9B, 0x6C, 0x90, 0x0B, 0x5B, 0x33, 0x7D, 0x5A, 0x52,
78
   0xF3, 0x61, 0xA1, 0xF7, 0xB0, 0xD6, 0x3F, 0x7C, 0x6D, 0xED, 0x14,
79
   0xE0, 0xA5, 0x3D, 0x22, 0xB3, 0xF8, 0x89, 0xDE, 0x71, 0x1A, 0xAF,
80
   0xBA, 0xB5, 0x81 };
81
82
alignas(256) const uint8_t X1[256] = {
83
   0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3,
84
   0x9E, 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F,
85
   0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54,
86
   0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B,
87
   0x42, 0xFA, 0xC3, 0x4E, 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24,
88
   0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8,
89
   0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D,
90
   0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
91
   0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, 0x90, 0xD8, 0xAB,
92
   0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3,
93
   0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1,
94
   0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41,
95
   0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6,
96
   0x73, 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9,
97
   0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D,
98
   0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
99
   0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0,
100
   0xFE, 0x78, 0xCD, 0x5A, 0xF4, 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07,
101
   0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, 0x60,
102
   0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F,
103
   0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5,
104
   0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2B,
105
   0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55,
106
   0x21, 0x0C, 0x7D };
107
108
alignas(256) const uint8_t X2[256] = {
109
   0x30, 0x68, 0x99, 0x1B, 0x87, 0xB9, 0x21, 0x78, 0x50, 0x39, 0xDB,
110
   0xE1, 0x72, 0x09, 0x62, 0x3C, 0x3E, 0x7E, 0x5E, 0x8E, 0xF1, 0xA0,
111
   0xCC, 0xA3, 0x2A, 0x1D, 0xFB, 0xB6, 0xD6, 0x20, 0xC4, 0x8D, 0x81,
112
   0x65, 0xF5, 0x89, 0xCB, 0x9D, 0x77, 0xC6, 0x57, 0x43, 0x56, 0x17,
113
   0xD4, 0x40, 0x1A, 0x4D, 0xC0, 0x63, 0x6C, 0xE3, 0xB7, 0xC8, 0x64,
114
   0x6A, 0x53, 0xAA, 0x38, 0x98, 0x0C, 0xF4, 0x9B, 0xED, 0x7F, 0x22,
115
   0x76, 0xAF, 0xDD, 0x3A, 0x0B, 0x58, 0x67, 0x88, 0x06, 0xC3, 0x35,
116
   0x0D, 0x01, 0x8B, 0x8C, 0xC2, 0xE6, 0x5F, 0x02, 0x24, 0x75, 0x93,
117
   0x66, 0x1E, 0xE5, 0xE2, 0x54, 0xD8, 0x10, 0xCE, 0x7A, 0xE8, 0x08,
118
   0x2C, 0x12, 0x97, 0x32, 0xAB, 0xB4, 0x27, 0x0A, 0x23, 0xDF, 0xEF,
119
   0xCA, 0xD9, 0xB8, 0xFA, 0xDC, 0x31, 0x6B, 0xD1, 0xAD, 0x19, 0x49,
120
   0xBD, 0x51, 0x96, 0xEE, 0xE4, 0xA8, 0x41, 0xDA, 0xFF, 0xCD, 0x55,
121
   0x86, 0x36, 0xBE, 0x61, 0x52, 0xF8, 0xBB, 0x0E, 0x82, 0x48, 0x69,
122
   0x9A, 0xE0, 0x47, 0x9E, 0x5C, 0x04, 0x4B, 0x34, 0x15, 0x79, 0x26,
123
   0xA7, 0xDE, 0x29, 0xAE, 0x92, 0xD7, 0x84, 0xE9, 0xD2, 0xBA, 0x5D,
124
   0xF3, 0xC5, 0xB0, 0xBF, 0xA4, 0x3B, 0x71, 0x44, 0x46, 0x2B, 0xFC,
125
   0xEB, 0x6F, 0xD5, 0xF6, 0x14, 0xFE, 0x7C, 0x70, 0x5A, 0x7D, 0xFD,
126
   0x2F, 0x18, 0x83, 0x16, 0xA5, 0x91, 0x1F, 0x05, 0x95, 0x74, 0xA9,
127
   0xC1, 0x5B, 0x4A, 0x85, 0x6D, 0x13, 0x07, 0x4F, 0x4E, 0x45, 0xB2,
128
   0x0F, 0xC9, 0x1C, 0xA6, 0xBC, 0xEC, 0x73, 0x90, 0x7B, 0xCF, 0x59,
129
   0x8F, 0xA1, 0xF9, 0x2D, 0xF2, 0xB1, 0x00, 0x94, 0x37, 0x9F, 0xD0,
130
   0x2E, 0x9C, 0x6E, 0x28, 0x3F, 0x80, 0xF0, 0x3D, 0xD3, 0x25, 0x8A,
131
   0xB5, 0xE7, 0x42, 0xB3, 0xC7, 0xEA, 0xF7, 0x4C, 0x11, 0x33, 0x03,
132
   0xA2, 0xAC, 0x60 };
133
134
inline uint32_t ARIA_F1(uint32_t X)
135
41.3k
   {
136
41.3k
   const uint32_t M1 = 0x00010101;
137
41.3k
   const uint32_t M2 = 0x01000101;
138
41.3k
   const uint32_t M3 = 0x01010001;
139
41.3k
   const uint32_t M4 = 0x01010100;
140
141
41.3k
   return (S1[get_byte<0>(X)] * M1) ^
142
41.3k
          (S2[get_byte<1>(X)] * M2) ^
143
41.3k
          (X1[get_byte<2>(X)] * M3) ^
144
41.3k
          (X2[get_byte<3>(X)] * M4);
145
41.3k
   }
146
147
inline uint32_t ARIA_F2(uint32_t X)
148
34.9k
   {
149
34.9k
   const uint32_t M1 = 0x00010101;
150
34.9k
   const uint32_t M2 = 0x01000101;
151
34.9k
   const uint32_t M3 = 0x01010001;
152
34.9k
   const uint32_t M4 = 0x01010100;
153
154
34.9k
   return (X1[get_byte<0>(X)] * M3) ^
155
34.9k
          (X2[get_byte<1>(X)] * M4) ^
156
34.9k
          (S1[get_byte<2>(X)] * M1) ^
157
34.9k
          (S2[get_byte<3>(X)] * M2);
158
34.9k
   }
159
160
inline void ARIA_FO(uint32_t& T0, uint32_t& T1, uint32_t& T2, uint32_t& T3)
161
10.3k
   {
162
10.3k
   T0 = ARIA_F1(T0);
163
10.3k
   T1 = ARIA_F1(T1);
164
10.3k
   T2 = ARIA_F1(T2);
165
10.3k
   T3 = ARIA_F1(T3);
166
167
10.3k
   T1 ^= T2;
168
10.3k
   T2 ^= T3; T0 ^= T1;
169
10.3k
   T3 ^= T1; T2 ^= T0;
170
10.3k
   T1 ^= T2;
171
172
10.3k
   T1 = ((T1 << 8) & 0xFF00FF00) | ((T1 >> 8) & 0x00FF00FF);
173
10.3k
   T2 = rotr<16>(T2);
174
10.3k
   T3 = reverse_bytes(T3);
175
176
10.3k
   T1 ^= T2;
177
10.3k
   T2 ^= T3; T0 ^= T1;
178
10.3k
   T3 ^= T1; T2 ^= T0;
179
10.3k
   T1 ^= T2;
180
10.3k
   }
181
182
inline void ARIA_FE(uint32_t& T0, uint32_t& T1, uint32_t& T2, uint32_t& T3)
183
8.74k
   {
184
8.74k
   T0 = ARIA_F2(T0);
185
8.74k
   T1 = ARIA_F2(T1);
186
8.74k
   T2 = ARIA_F2(T2);
187
8.74k
   T3 = ARIA_F2(T3);
188
189
8.74k
   T1 ^= T2;
190
8.74k
   T2 ^= T3; T0 ^= T1;
191
8.74k
   T3 ^= T1; T2 ^= T0;
192
8.74k
   T1 ^= T2;
193
194
8.74k
   T3 = ((T3 << 8) & 0xFF00FF00) | ((T3 >> 8) & 0x00FF00FF);
195
8.74k
   T0 = rotr<16>(T0);
196
8.74k
   T1 = reverse_bytes(T1);
197
198
8.74k
   T1 ^= T2;
199
8.74k
   T2 ^= T3; T0 ^= T1;
200
8.74k
   T3 ^= T1; T2 ^= T0;
201
8.74k
   T1 ^= T2;
202
8.74k
   }
203
204
/*
205
* ARIA encryption and decryption
206
*/
207
void transform(const uint8_t in[], uint8_t out[], size_t blocks,
208
               const secure_vector<uint32_t>& KS)
209
1.39k
   {
210
   /*
211
   * Hit every cache line of S1, S2, X1, X2
212
   *
213
   * The initializer of Z ensures Z == 0xFFFFFFFF for any cache line size
214
   * size that is a power of 2 and <= 512
215
   */
216
1.39k
   const size_t cache_line_size = CPUID::cache_line_size();
217
218
1.39k
   volatile uint32_t Z = 0x9C1DADCF;
219
6.98k
   for(size_t i = 0; i < 256; i += cache_line_size)
220
5.58k
      {
221
5.58k
      Z = Z | make_uint32(S1[i], S2[i], X1[i], X2[i]);
222
5.58k
      }
223
224
1.39k
   const size_t ROUNDS = (KS.size() / 4) - 1;
225
226
2.79k
   for(size_t i = 0; i != blocks; ++i)
227
1.39k
      {
228
1.39k
      uint32_t t0, t1, t2, t3;
229
1.39k
      load_be(in + 16*i, t0, t1, t2, t3);
230
231
1.39k
      t0 &= Z;
232
233
11.3k
      for(size_t r = 0; r < ROUNDS; r += 2)
234
9.94k
         {
235
9.94k
         t0 ^= KS[4*r];
236
9.94k
         t1 ^= KS[4*r+1];
237
9.94k
         t2 ^= KS[4*r+2];
238
9.94k
         t3 ^= KS[4*r+3];
239
9.94k
         ARIA_FO(t0,t1,t2,t3);
240
241
9.94k
         t0 ^= KS[4*r+4];
242
9.94k
         t1 ^= KS[4*r+5];
243
9.94k
         t2 ^= KS[4*r+6];
244
9.94k
         t3 ^= KS[4*r+7];
245
246
9.94k
         if(r != ROUNDS-2)
247
8.55k
            ARIA_FE(t0,t1,t2,t3);
248
9.94k
         }
249
250
1.39k
      out[16*i+ 0] = X1[get_byte<0>(t0)] ^ get_byte<0>(KS[4*ROUNDS]);
251
1.39k
      out[16*i+ 1] = X2[get_byte<1>(t0)] ^ get_byte<1>(KS[4*ROUNDS]);
252
1.39k
      out[16*i+ 2] = S1[get_byte<2>(t0)] ^ get_byte<2>(KS[4*ROUNDS]);
253
1.39k
      out[16*i+ 3] = S2[get_byte<3>(t0)] ^ get_byte<3>(KS[4*ROUNDS]);
254
1.39k
      out[16*i+ 4] = X1[get_byte<0>(t1)] ^ get_byte<0>(KS[4*ROUNDS+1]);
255
1.39k
      out[16*i+ 5] = X2[get_byte<1>(t1)] ^ get_byte<1>(KS[4*ROUNDS+1]);
256
1.39k
      out[16*i+ 6] = S1[get_byte<2>(t1)] ^ get_byte<2>(KS[4*ROUNDS+1]);
257
1.39k
      out[16*i+ 7] = S2[get_byte<3>(t1)] ^ get_byte<3>(KS[4*ROUNDS+1]);
258
1.39k
      out[16*i+ 8] = X1[get_byte<0>(t2)] ^ get_byte<0>(KS[4*ROUNDS+2]);
259
1.39k
      out[16*i+ 9] = X2[get_byte<1>(t2)] ^ get_byte<1>(KS[4*ROUNDS+2]);
260
1.39k
      out[16*i+10] = S1[get_byte<2>(t2)] ^ get_byte<2>(KS[4*ROUNDS+2]);
261
1.39k
      out[16*i+11] = S2[get_byte<3>(t2)] ^ get_byte<3>(KS[4*ROUNDS+2]);
262
1.39k
      out[16*i+12] = X1[get_byte<0>(t3)] ^ get_byte<0>(KS[4*ROUNDS+3]);
263
1.39k
      out[16*i+13] = X2[get_byte<1>(t3)] ^ get_byte<1>(KS[4*ROUNDS+3]);
264
1.39k
      out[16*i+14] = S1[get_byte<2>(t3)] ^ get_byte<2>(KS[4*ROUNDS+3]);
265
1.39k
      out[16*i+15] = S2[get_byte<3>(t3)] ^ get_byte<3>(KS[4*ROUNDS+3]);
266
1.39k
      }
267
1.39k
   }
268
269
// n-bit right shift of Y XORed to X
270
template<size_t N>
271
inline void ARIA_ROL128(const uint32_t X[4], const uint32_t Y[4], uint32_t KS[4])
272
2.84k
   {
273
   // MSVC is not generating a "rotate immediate". Constify to help it along.
274
2.84k
   static const size_t Q = 4 - (N / 32);
275
2.84k
   static const size_t R = N % 32;
276
2.84k
   static_assert(R > 0 && R < 32, "Rotation in range for type");
277
2.84k
   KS[0] = (X[0]) ^ ((Y[(Q  )%4])>>R) ^ ((Y[(Q+3)%4])<<(32-R));
278
2.84k
   KS[1] = (X[1]) ^ ((Y[(Q+1)%4])>>R) ^ ((Y[(Q  )%4])<<(32-R));
279
2.84k
   KS[2] = (X[2]) ^ ((Y[(Q+2)%4])>>R) ^ ((Y[(Q+1)%4])<<(32-R));
280
2.84k
   KS[3] = (X[3]) ^ ((Y[(Q+3)%4])>>R) ^ ((Y[(Q+2)%4])<<(32-R));
281
2.84k
   }
aria.cpp:void Botan::(anonymous namespace)::ARIA_F::ARIA_ROL128<19ul>(unsigned int const*, unsigned int const*, unsigned int*)
Line
Count
Source
272
756
   {
273
   // MSVC is not generating a "rotate immediate". Constify to help it along.
274
756
   static const size_t Q = 4 - (N / 32);
275
756
   static const size_t R = N % 32;
276
756
   static_assert(R > 0 && R < 32, "Rotation in range for type");
277
756
   KS[0] = (X[0]) ^ ((Y[(Q  )%4])>>R) ^ ((Y[(Q+3)%4])<<(32-R));
278
756
   KS[1] = (X[1]) ^ ((Y[(Q+1)%4])>>R) ^ ((Y[(Q  )%4])<<(32-R));
279
756
   KS[2] = (X[2]) ^ ((Y[(Q+2)%4])>>R) ^ ((Y[(Q+1)%4])<<(32-R));
280
756
   KS[3] = (X[3]) ^ ((Y[(Q+3)%4])>>R) ^ ((Y[(Q+2)%4])<<(32-R));
281
756
   }
aria.cpp:void Botan::(anonymous namespace)::ARIA_F::ARIA_ROL128<31ul>(unsigned int const*, unsigned int const*, unsigned int*)
Line
Count
Source
272
756
   {
273
   // MSVC is not generating a "rotate immediate". Constify to help it along.
274
756
   static const size_t Q = 4 - (N / 32);
275
756
   static const size_t R = N % 32;
276
756
   static_assert(R > 0 && R < 32, "Rotation in range for type");
277
756
   KS[0] = (X[0]) ^ ((Y[(Q  )%4])>>R) ^ ((Y[(Q+3)%4])<<(32-R));
278
756
   KS[1] = (X[1]) ^ ((Y[(Q+1)%4])>>R) ^ ((Y[(Q  )%4])<<(32-R));
279
756
   KS[2] = (X[2]) ^ ((Y[(Q+2)%4])>>R) ^ ((Y[(Q+1)%4])<<(32-R));
280
756
   KS[3] = (X[3]) ^ ((Y[(Q+3)%4])>>R) ^ ((Y[(Q+2)%4])<<(32-R));
281
756
   }
aria.cpp:void Botan::(anonymous namespace)::ARIA_F::ARIA_ROL128<67ul>(unsigned int const*, unsigned int const*, unsigned int*)
Line
Count
Source
272
756
   {
273
   // MSVC is not generating a "rotate immediate". Constify to help it along.
274
756
   static const size_t Q = 4 - (N / 32);
275
756
   static const size_t R = N % 32;
276
756
   static_assert(R > 0 && R < 32, "Rotation in range for type");
277
756
   KS[0] = (X[0]) ^ ((Y[(Q  )%4])>>R) ^ ((Y[(Q+3)%4])<<(32-R));
278
756
   KS[1] = (X[1]) ^ ((Y[(Q+1)%4])>>R) ^ ((Y[(Q  )%4])<<(32-R));
279
756
   KS[2] = (X[2]) ^ ((Y[(Q+2)%4])>>R) ^ ((Y[(Q+1)%4])<<(32-R));
280
756
   KS[3] = (X[3]) ^ ((Y[(Q+3)%4])>>R) ^ ((Y[(Q+2)%4])<<(32-R));
281
756
   }
aria.cpp:void Botan::(anonymous namespace)::ARIA_F::ARIA_ROL128<97ul>(unsigned int const*, unsigned int const*, unsigned int*)
Line
Count
Source
272
505
   {
273
   // MSVC is not generating a "rotate immediate". Constify to help it along.
274
505
   static const size_t Q = 4 - (N / 32);
275
505
   static const size_t R = N % 32;
276
505
   static_assert(R > 0 && R < 32, "Rotation in range for type");
277
505
   KS[0] = (X[0]) ^ ((Y[(Q  )%4])>>R) ^ ((Y[(Q+3)%4])<<(32-R));
278
505
   KS[1] = (X[1]) ^ ((Y[(Q+1)%4])>>R) ^ ((Y[(Q  )%4])<<(32-R));
279
505
   KS[2] = (X[2]) ^ ((Y[(Q+2)%4])>>R) ^ ((Y[(Q+1)%4])<<(32-R));
280
505
   KS[3] = (X[3]) ^ ((Y[(Q+3)%4])>>R) ^ ((Y[(Q+2)%4])<<(32-R));
281
505
   }
aria.cpp:void Botan::(anonymous namespace)::ARIA_F::ARIA_ROL128<109ul>(unsigned int const*, unsigned int const*, unsigned int*)
Line
Count
Source
272
72
   {
273
   // MSVC is not generating a "rotate immediate". Constify to help it along.
274
72
   static const size_t Q = 4 - (N / 32);
275
72
   static const size_t R = N % 32;
276
72
   static_assert(R > 0 && R < 32, "Rotation in range for type");
277
72
   KS[0] = (X[0]) ^ ((Y[(Q  )%4])>>R) ^ ((Y[(Q+3)%4])<<(32-R));
278
72
   KS[1] = (X[1]) ^ ((Y[(Q+1)%4])>>R) ^ ((Y[(Q  )%4])<<(32-R));
279
72
   KS[2] = (X[2]) ^ ((Y[(Q+2)%4])>>R) ^ ((Y[(Q+1)%4])<<(32-R));
280
72
   KS[3] = (X[3]) ^ ((Y[(Q+3)%4])>>R) ^ ((Y[(Q+2)%4])<<(32-R));
281
72
   }
282
283
/*
284
* ARIA Key Schedule
285
*/
286
void key_schedule(secure_vector<uint32_t>& ERK,
287
                  secure_vector<uint32_t>& DRK,
288
                  const uint8_t key[], size_t length)
289
189
   {
290
189
   const uint32_t KRK[3][4] = {
291
189
      {0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0},
292
189
      {0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0},
293
189
      {0xdb92371d, 0x2126e970, 0x03249775, 0x04e8c90e}
294
189
   };
295
296
189
   const size_t CK0 = (length / 8) - 2;
297
189
   const size_t CK1 = (CK0 + 1) % 3;
298
189
   const size_t CK2 = (CK1 + 1) % 3;
299
300
189
   uint32_t w0[4];
301
189
   uint32_t w1[4];
302
189
   uint32_t w2[4];
303
189
   uint32_t w3[4];
304
305
189
   w0[0] = load_be<uint32_t>(key,0);
306
189
   w0[1] = load_be<uint32_t>(key,1);
307
189
   w0[2] = load_be<uint32_t>(key,2);
308
189
   w0[3] = load_be<uint32_t>(key,3);
309
310
189
   w1[0] = w0[0] ^ KRK[CK0][0];
311
189
   w1[1] = w0[1] ^ KRK[CK0][1];
312
189
   w1[2] = w0[2] ^ KRK[CK0][2];
313
189
   w1[3] = w0[3] ^ KRK[CK0][3];
314
315
189
   ARIA_FO(w1[0], w1[1], w1[2], w1[3]);
316
317
189
   if(length == 24 || length == 32)
318
122
      {
319
122
      w1[0] ^= load_be<uint32_t>(key,4);
320
122
      w1[1] ^= load_be<uint32_t>(key,5);
321
122
      }
322
189
   if(length == 32)
323
72
      {
324
72
      w1[2] ^= load_be<uint32_t>(key,6);
325
72
      w1[3] ^= load_be<uint32_t>(key,7);
326
72
      }
327
328
189
   w2[0] = w1[0] ^ KRK[CK1][0];
329
189
   w2[1] = w1[1] ^ KRK[CK1][1];
330
189
   w2[2] = w1[2] ^ KRK[CK1][2];
331
189
   w2[3] = w1[3] ^ KRK[CK1][3];
332
333
189
   ARIA_FE(w2[0], w2[1], w2[2], w2[3]);
334
335
189
   w2[0] ^= w0[0];
336
189
   w2[1] ^= w0[1];
337
189
   w2[2] ^= w0[2];
338
189
   w2[3] ^= w0[3];
339
340
189
   w3[0] = w2[0] ^ KRK[CK2][0];
341
189
   w3[1] = w2[1] ^ KRK[CK2][1];
342
189
   w3[2] = w2[2] ^ KRK[CK2][2];
343
189
   w3[3] = w2[3] ^ KRK[CK2][3];
344
345
189
   ARIA_FO(w3[0], w3[1], w3[2], w3[3]);
346
347
189
   w3[0] ^= w1[0];
348
189
   w3[1] ^= w1[1];
349
189
   w3[2] ^= w1[2];
350
189
   w3[3] ^= w1[3];
351
352
189
   if(length == 16)
353
67
      ERK.resize(4*13);
354
122
   else if(length == 24)
355
50
      ERK.resize(4*15);
356
72
   else if(length == 32)
357
72
      ERK.resize(4*17);
358
359
189
   ARIA_ROL128<19>(w0, w1, &ERK[ 0]);
360
189
   ARIA_ROL128<19>(w1, w2, &ERK[ 4]);
361
189
   ARIA_ROL128<19>(w2, w3, &ERK[ 8]);
362
189
   ARIA_ROL128<19>(w3, w0, &ERK[12]);
363
189
   ARIA_ROL128<31>(w0, w1, &ERK[16]);
364
189
   ARIA_ROL128<31>(w1, w2, &ERK[20]);
365
189
   ARIA_ROL128<31>(w2, w3, &ERK[24]);
366
189
   ARIA_ROL128<31>(w3, w0, &ERK[28]);
367
189
   ARIA_ROL128<67>(w0, w1, &ERK[32]);
368
189
   ARIA_ROL128<67>(w1, w2, &ERK[36]);
369
189
   ARIA_ROL128<67>(w2, w3, &ERK[40]);
370
189
   ARIA_ROL128<67>(w3, w0, &ERK[44]);
371
189
   ARIA_ROL128<97>(w0, w1, &ERK[48]);
372
373
189
   if(length == 24 || length == 32)
374
122
      {
375
122
      ARIA_ROL128<97>(w1, w2, &ERK[52]);
376
122
      ARIA_ROL128<97>(w2, w3, &ERK[56]);
377
378
122
      if(length == 32)
379
72
         {
380
72
         ARIA_ROL128< 97>(w3, w0, &ERK[60]);
381
72
         ARIA_ROL128<109>(w0, w1, &ERK[64]);
382
72
         }
383
122
      }
384
385
   // Now create the decryption key schedule
386
189
   DRK.resize(ERK.size());
387
388
3.03k
   for(size_t i = 0; i != DRK.size(); i += 4)
389
2.84k
      {
390
2.84k
      DRK[i  ] = ERK[ERK.size()-4-i];
391
2.84k
      DRK[i+1] = ERK[ERK.size()-3-i];
392
2.84k
      DRK[i+2] = ERK[ERK.size()-2-i];
393
2.84k
      DRK[i+3] = ERK[ERK.size()-1-i];
394
2.84k
      }
395
396
2.65k
   for(size_t i = 4; i != DRK.size() - 4; i += 4)
397
2.46k
      {
398
12.3k
      for(size_t j = 0; j != 4; ++j)
399
9.86k
         {
400
9.86k
         DRK[i+j] = rotr<8>(DRK[i+j]) ^
401
9.86k
                    rotr<16>(DRK[i+j]) ^
402
9.86k
                    rotr<24>(DRK[i+j]);
403
9.86k
         }
404
405
2.46k
      DRK[i+1] ^= DRK[i+2]; DRK[i+2] ^= DRK[i+3];
406
2.46k
      DRK[i+0] ^= DRK[i+1]; DRK[i+3] ^= DRK[i+1];
407
2.46k
      DRK[i+2] ^= DRK[i+0]; DRK[i+1] ^= DRK[i+2];
408
409
2.46k
      DRK[i+1] = ((DRK[i+1] << 8) & 0xFF00FF00) | ((DRK[i+1] >> 8) & 0x00FF00FF);
410
2.46k
      DRK[i+2] = rotr<16>(DRK[i+2]);
411
2.46k
      DRK[i+3] = reverse_bytes(DRK[i+3]);
412
413
2.46k
      DRK[i+1] ^= DRK[i+2]; DRK[i+2] ^= DRK[i+3];
414
2.46k
      DRK[i+0] ^= DRK[i+1]; DRK[i+3] ^= DRK[i+1];
415
2.46k
      DRK[i+2] ^= DRK[i+0]; DRK[i+1] ^= DRK[i+2];
416
2.46k
      }
417
189
   }
418
419
}
420
421
}
422
423
void ARIA_128::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
424
272
   {
425
272
   assert_key_material_set();
426
272
   ARIA_F::transform(in, out, blocks, m_ERK);
427
272
   }
428
429
void ARIA_192::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
430
676
   {
431
676
   assert_key_material_set();
432
676
   ARIA_F::transform(in, out, blocks, m_ERK);
433
676
   }
434
435
void ARIA_256::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
436
448
   {
437
448
   assert_key_material_set();
438
448
   ARIA_F::transform(in, out, blocks, m_ERK);
439
448
   }
440
441
void ARIA_128::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
442
0
   {
443
0
   assert_key_material_set();
444
0
   ARIA_F::transform(in, out, blocks, m_DRK);
445
0
   }
446
447
void ARIA_192::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
448
0
   {
449
0
   assert_key_material_set();
450
0
   ARIA_F::transform(in, out, blocks, m_DRK);
451
0
   }
452
453
void ARIA_256::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
454
0
   {
455
0
   assert_key_material_set();
456
0
   ARIA_F::transform(in, out, blocks, m_DRK);
457
0
   }
458
459
272
bool ARIA_128::has_keying_material() const { return !m_ERK.empty(); }
460
676
bool ARIA_192::has_keying_material() const { return !m_ERK.empty(); }
461
448
bool ARIA_256::has_keying_material() const { return !m_ERK.empty(); }
462
463
void ARIA_128::key_schedule(const uint8_t key[], size_t length)
464
67
   {
465
67
   ARIA_F::key_schedule(m_ERK, m_DRK, key, length);
466
67
   }
467
468
void ARIA_192::key_schedule(const uint8_t key[], size_t length)
469
50
   {
470
50
   ARIA_F::key_schedule(m_ERK, m_DRK, key, length);
471
50
   }
472
473
void ARIA_256::key_schedule(const uint8_t key[], size_t length)
474
72
   {
475
72
   ARIA_F::key_schedule(m_ERK, m_DRK, key, length);
476
72
   }
477
478
void ARIA_128::clear()
479
67
   {
480
67
   zap(m_ERK);
481
67
   zap(m_DRK);
482
67
   }
483
484
void ARIA_192::clear()
485
50
   {
486
50
   zap(m_ERK);
487
50
   zap(m_DRK);
488
50
   }
489
490
void ARIA_256::clear()
491
72
   {
492
72
   zap(m_ERK);
493
72
   zap(m_DRK);
494
72
   }
495
496
}