Coverage Report

Created: 2024-11-21 07:03

/src/libgcrypt/cipher/aria.c
Line
Count
Source (jump to first uncovered line)
1
/* aria.c  -  ARIA Cipher Algorithm
2
 *
3
 * Copyright (C) 2022-2023 Taehee Yoo <ap420073@gmail.com>
4
 * Copyright (C) 2023 Jussi Kivilinna <jussi.kivilinna@iki.fi>
5
 *
6
 * This file is part of Libgcrypt.
7
 *
8
 * Libgcrypt is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as
10
 * published by the Free Software Foundation; either version 2.1 of
11
 * the License, or (at your option) any later version.
12
 *
13
 * Libgcrypt is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
#include <config.h>
23
24
#include "types.h"
25
#include "g10lib.h"
26
#include "cipher.h"
27
#include "bufhelp.h"
28
#include "cipher-internal.h"
29
#include "bulkhelp.h"
30
31
/* Attribute macro to force alignment to 64 bytes.  */
32
#ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
33
# define ATTR_ALIGNED_64  __attribute__ ((aligned (64)))
34
#else
35
# define ATTR_ALIGNED_64
36
#endif
37
38
/* Attribute macro to force inlining of function. */
39
#if __GNUC__ >= 4
40
#  define ALWAYS_INLINE inline __attribute__ ((always_inline))
41
#else
42
#  define ALWAYS_INLINE inline
43
#endif
44
45
/* Attribute macro to prevent inlining of function. */
46
#if __GNUC__ >= 4
47
#  define NO_INLINE __attribute__ ((noinline))
48
#else
49
#  define NO_INLINE
50
#endif
51
52
53
/* USE_AESNI_AVX inidicates whether to compile with Intel AES-NI/AVX code. */
54
#undef USE_AESNI_AVX
55
#if defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT)
56
# if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
57
     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
58
#  define USE_AESNI_AVX 1
59
# endif
60
#endif
61
62
/* USE_GFNI_AVX inidicates whether to compile with Intel GFNI/AVX code. */
63
#undef USE_GFNI_AVX
64
#if defined(USE_AESNI_AVX) && defined(ENABLE_GFNI_SUPPORT)
65
# define USE_GFNI_AVX 1
66
#endif
67
68
/* USE_AESNI_AVX2 inidicates whether to compile with Intel AES-NI/AVX2 code. */
69
#undef USE_AESNI_AVX2
70
#if defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT)
71
# if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
72
     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
73
#  define USE_AESNI_AVX2 1
74
# endif
75
#endif
76
77
/* USE_VAES_AVX2 inidicates whether to compile with Intel VAES/AVX2 code. */
78
#undef USE_VAES_AVX2
79
#if defined(USE_AESNI_AVX2) && defined(HAVE_GCC_INLINE_ASM_VAES_VPCLMUL)
80
# define USE_VAES_AVX2 1
81
#endif
82
83
/* USE_GFNI_AVX2 inidicates whether to compile with Intel GFNI/AVX2 code. */
84
#undef USE_GFNI_AVX2
85
#if defined(USE_AESNI_AVX2) && defined(ENABLE_GFNI_SUPPORT)
86
# define USE_GFNI_AVX2 1
87
#endif
88
89
/* USE_GFNI_AVX512 inidicates whether to compile with Intel GFNI/AVX512 code. */
90
#undef USE_GFNI_AVX512
91
#if defined(ENABLE_GFNI_SUPPORT) && defined(ENABLE_AVX512_SUPPORT)
92
# if defined(__x86_64__) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
93
     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
94
#  define USE_GFNI_AVX512 1
95
# endif
96
#endif
97
98
/* How many parallel blocks to handle in bulk processing functions. */
99
#if defined(USE_GFNI_AVX512)
100
0
# define MAX_PARALLEL_BLKS 64
101
#elif defined(USE_AESNI_AVX2)
102
# define MAX_PARALLEL_BLKS 32
103
#elif defined(USE_AESNI_AVX)
104
# define MAX_PARALLEL_BLKS 16
105
#else
106
# define MAX_PARALLEL_BLKS 8
107
#endif
108
109
/* Assembly implementations use SystemV ABI, ABI conversion and additional
110
 * stack to store XMM6-XMM15 needed on Win64. */
111
#undef ASM_FUNC_ABI
112
#undef ASM_EXTRA_STACK
113
#if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2) || \
114
    defined(USE_GFNI_AVX512)
115
# ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
116
#  define ASM_FUNC_ABI __attribute__((sysv_abi))
117
#  define ASM_EXTRA_STACK (10 * 16)
118
# else
119
#  define ASM_FUNC_ABI
120
15
#  define ASM_EXTRA_STACK 0
121
# endif
122
#endif
123
124
125
static const char *aria_selftest (void);
126
127
128
#define ARIA_MIN_KEY_SIZE 16
129
#define ARIA_MAX_KEY_SIZE 32
130
12.3k
#define ARIA_BLOCK_SIZE   16
131
#define ARIA_MAX_RD_KEYS  17
132
#define ARIA_RD_KEY_WORDS (ARIA_BLOCK_SIZE / sizeof(u32))
133
134
135
typedef struct
136
{
137
  u32 enc_key[ARIA_MAX_RD_KEYS][ARIA_RD_KEY_WORDS];
138
  u32 dec_key[ARIA_MAX_RD_KEYS][ARIA_RD_KEY_WORDS];
139
  int rounds;
140
141
  unsigned int decryption_prepared:1; /* The decryption key is set up. */
142
  unsigned int bulk_prefetch_ready:1; /* Look-up table prefetch ready for
143
               * current bulk operation. */
144
145
#ifdef USE_AESNI_AVX
146
  unsigned int use_aesni_avx:1;
147
  unsigned int use_gfni_avx:1;
148
#endif
149
#ifdef USE_AESNI_AVX2
150
  unsigned int use_aesni_avx2:1;
151
  unsigned int use_vaes_avx2:1;
152
  unsigned int use_gfni_avx2:1;
153
#endif
154
#ifdef USE_GFNI_AVX512
155
  unsigned int use_gfni_avx512:1;
156
#endif
157
} ARIA_context;
158
159
160
static const u32 key_rc[20] =
161
  {
162
    0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0,
163
    0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0,
164
    0xdb92371d, 0x2126e970, 0x03249775, 0x04e8c90e,
165
    0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0,
166
    0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0
167
  };
168
169
170
static struct
171
{
172
  volatile u32 counter_head;
173
  u32 cacheline_align[64 / 4 - 1];
174
  u32 s1[256];
175
  u32 s2[256];
176
  u32 x1[256];
177
  u32 x2[256];
178
  volatile u32 counter_tail;
179
} sboxes ATTR_ALIGNED_64 =
180
  {
181
    0,
182
    { 0, },
183
184
    { /* s1 */
185
      0x00636363, 0x007c7c7c, 0x00777777, 0x007b7b7b,
186
      0x00f2f2f2, 0x006b6b6b, 0x006f6f6f, 0x00c5c5c5,
187
      0x00303030, 0x00010101, 0x00676767, 0x002b2b2b,
188
      0x00fefefe, 0x00d7d7d7, 0x00ababab, 0x00767676,
189
      0x00cacaca, 0x00828282, 0x00c9c9c9, 0x007d7d7d,
190
      0x00fafafa, 0x00595959, 0x00474747, 0x00f0f0f0,
191
      0x00adadad, 0x00d4d4d4, 0x00a2a2a2, 0x00afafaf,
192
      0x009c9c9c, 0x00a4a4a4, 0x00727272, 0x00c0c0c0,
193
      0x00b7b7b7, 0x00fdfdfd, 0x00939393, 0x00262626,
194
      0x00363636, 0x003f3f3f, 0x00f7f7f7, 0x00cccccc,
195
      0x00343434, 0x00a5a5a5, 0x00e5e5e5, 0x00f1f1f1,
196
      0x00717171, 0x00d8d8d8, 0x00313131, 0x00151515,
197
      0x00040404, 0x00c7c7c7, 0x00232323, 0x00c3c3c3,
198
      0x00181818, 0x00969696, 0x00050505, 0x009a9a9a,
199
      0x00070707, 0x00121212, 0x00808080, 0x00e2e2e2,
200
      0x00ebebeb, 0x00272727, 0x00b2b2b2, 0x00757575,
201
      0x00090909, 0x00838383, 0x002c2c2c, 0x001a1a1a,
202
      0x001b1b1b, 0x006e6e6e, 0x005a5a5a, 0x00a0a0a0,
203
      0x00525252, 0x003b3b3b, 0x00d6d6d6, 0x00b3b3b3,
204
      0x00292929, 0x00e3e3e3, 0x002f2f2f, 0x00848484,
205
      0x00535353, 0x00d1d1d1, 0x00000000, 0x00ededed,
206
      0x00202020, 0x00fcfcfc, 0x00b1b1b1, 0x005b5b5b,
207
      0x006a6a6a, 0x00cbcbcb, 0x00bebebe, 0x00393939,
208
      0x004a4a4a, 0x004c4c4c, 0x00585858, 0x00cfcfcf,
209
      0x00d0d0d0, 0x00efefef, 0x00aaaaaa, 0x00fbfbfb,
210
      0x00434343, 0x004d4d4d, 0x00333333, 0x00858585,
211
      0x00454545, 0x00f9f9f9, 0x00020202, 0x007f7f7f,
212
      0x00505050, 0x003c3c3c, 0x009f9f9f, 0x00a8a8a8,
213
      0x00515151, 0x00a3a3a3, 0x00404040, 0x008f8f8f,
214
      0x00929292, 0x009d9d9d, 0x00383838, 0x00f5f5f5,
215
      0x00bcbcbc, 0x00b6b6b6, 0x00dadada, 0x00212121,
216
      0x00101010, 0x00ffffff, 0x00f3f3f3, 0x00d2d2d2,
217
      0x00cdcdcd, 0x000c0c0c, 0x00131313, 0x00ececec,
218
      0x005f5f5f, 0x00979797, 0x00444444, 0x00171717,
219
      0x00c4c4c4, 0x00a7a7a7, 0x007e7e7e, 0x003d3d3d,
220
      0x00646464, 0x005d5d5d, 0x00191919, 0x00737373,
221
      0x00606060, 0x00818181, 0x004f4f4f, 0x00dcdcdc,
222
      0x00222222, 0x002a2a2a, 0x00909090, 0x00888888,
223
      0x00464646, 0x00eeeeee, 0x00b8b8b8, 0x00141414,
224
      0x00dedede, 0x005e5e5e, 0x000b0b0b, 0x00dbdbdb,
225
      0x00e0e0e0, 0x00323232, 0x003a3a3a, 0x000a0a0a,
226
      0x00494949, 0x00060606, 0x00242424, 0x005c5c5c,
227
      0x00c2c2c2, 0x00d3d3d3, 0x00acacac, 0x00626262,
228
      0x00919191, 0x00959595, 0x00e4e4e4, 0x00797979,
229
      0x00e7e7e7, 0x00c8c8c8, 0x00373737, 0x006d6d6d,
230
      0x008d8d8d, 0x00d5d5d5, 0x004e4e4e, 0x00a9a9a9,
231
      0x006c6c6c, 0x00565656, 0x00f4f4f4, 0x00eaeaea,
232
      0x00656565, 0x007a7a7a, 0x00aeaeae, 0x00080808,
233
      0x00bababa, 0x00787878, 0x00252525, 0x002e2e2e,
234
      0x001c1c1c, 0x00a6a6a6, 0x00b4b4b4, 0x00c6c6c6,
235
      0x00e8e8e8, 0x00dddddd, 0x00747474, 0x001f1f1f,
236
      0x004b4b4b, 0x00bdbdbd, 0x008b8b8b, 0x008a8a8a,
237
      0x00707070, 0x003e3e3e, 0x00b5b5b5, 0x00666666,
238
      0x00484848, 0x00030303, 0x00f6f6f6, 0x000e0e0e,
239
      0x00616161, 0x00353535, 0x00575757, 0x00b9b9b9,
240
      0x00868686, 0x00c1c1c1, 0x001d1d1d, 0x009e9e9e,
241
      0x00e1e1e1, 0x00f8f8f8, 0x00989898, 0x00111111,
242
      0x00696969, 0x00d9d9d9, 0x008e8e8e, 0x00949494,
243
      0x009b9b9b, 0x001e1e1e, 0x00878787, 0x00e9e9e9,
244
      0x00cecece, 0x00555555, 0x00282828, 0x00dfdfdf,
245
      0x008c8c8c, 0x00a1a1a1, 0x00898989, 0x000d0d0d,
246
      0x00bfbfbf, 0x00e6e6e6, 0x00424242, 0x00686868,
247
      0x00414141, 0x00999999, 0x002d2d2d, 0x000f0f0f,
248
      0x00b0b0b0, 0x00545454, 0x00bbbbbb, 0x00161616
249
    },
250
    { /* s2 */
251
      0xe200e2e2, 0x4e004e4e, 0x54005454, 0xfc00fcfc,
252
      0x94009494, 0xc200c2c2, 0x4a004a4a, 0xcc00cccc,
253
      0x62006262, 0x0d000d0d, 0x6a006a6a, 0x46004646,
254
      0x3c003c3c, 0x4d004d4d, 0x8b008b8b, 0xd100d1d1,
255
      0x5e005e5e, 0xfa00fafa, 0x64006464, 0xcb00cbcb,
256
      0xb400b4b4, 0x97009797, 0xbe00bebe, 0x2b002b2b,
257
      0xbc00bcbc, 0x77007777, 0x2e002e2e, 0x03000303,
258
      0xd300d3d3, 0x19001919, 0x59005959, 0xc100c1c1,
259
      0x1d001d1d, 0x06000606, 0x41004141, 0x6b006b6b,
260
      0x55005555, 0xf000f0f0, 0x99009999, 0x69006969,
261
      0xea00eaea, 0x9c009c9c, 0x18001818, 0xae00aeae,
262
      0x63006363, 0xdf00dfdf, 0xe700e7e7, 0xbb00bbbb,
263
      0x00000000, 0x73007373, 0x66006666, 0xfb00fbfb,
264
      0x96009696, 0x4c004c4c, 0x85008585, 0xe400e4e4,
265
      0x3a003a3a, 0x09000909, 0x45004545, 0xaa00aaaa,
266
      0x0f000f0f, 0xee00eeee, 0x10001010, 0xeb00ebeb,
267
      0x2d002d2d, 0x7f007f7f, 0xf400f4f4, 0x29002929,
268
      0xac00acac, 0xcf00cfcf, 0xad00adad, 0x91009191,
269
      0x8d008d8d, 0x78007878, 0xc800c8c8, 0x95009595,
270
      0xf900f9f9, 0x2f002f2f, 0xce00cece, 0xcd00cdcd,
271
      0x08000808, 0x7a007a7a, 0x88008888, 0x38003838,
272
      0x5c005c5c, 0x83008383, 0x2a002a2a, 0x28002828,
273
      0x47004747, 0xdb00dbdb, 0xb800b8b8, 0xc700c7c7,
274
      0x93009393, 0xa400a4a4, 0x12001212, 0x53005353,
275
      0xff00ffff, 0x87008787, 0x0e000e0e, 0x31003131,
276
      0x36003636, 0x21002121, 0x58005858, 0x48004848,
277
      0x01000101, 0x8e008e8e, 0x37003737, 0x74007474,
278
      0x32003232, 0xca00caca, 0xe900e9e9, 0xb100b1b1,
279
      0xb700b7b7, 0xab00abab, 0x0c000c0c, 0xd700d7d7,
280
      0xc400c4c4, 0x56005656, 0x42004242, 0x26002626,
281
      0x07000707, 0x98009898, 0x60006060, 0xd900d9d9,
282
      0xb600b6b6, 0xb900b9b9, 0x11001111, 0x40004040,
283
      0xec00ecec, 0x20002020, 0x8c008c8c, 0xbd00bdbd,
284
      0xa000a0a0, 0xc900c9c9, 0x84008484, 0x04000404,
285
      0x49004949, 0x23002323, 0xf100f1f1, 0x4f004f4f,
286
      0x50005050, 0x1f001f1f, 0x13001313, 0xdc00dcdc,
287
      0xd800d8d8, 0xc000c0c0, 0x9e009e9e, 0x57005757,
288
      0xe300e3e3, 0xc300c3c3, 0x7b007b7b, 0x65006565,
289
      0x3b003b3b, 0x02000202, 0x8f008f8f, 0x3e003e3e,
290
      0xe800e8e8, 0x25002525, 0x92009292, 0xe500e5e5,
291
      0x15001515, 0xdd00dddd, 0xfd00fdfd, 0x17001717,
292
      0xa900a9a9, 0xbf00bfbf, 0xd400d4d4, 0x9a009a9a,
293
      0x7e007e7e, 0xc500c5c5, 0x39003939, 0x67006767,
294
      0xfe00fefe, 0x76007676, 0x9d009d9d, 0x43004343,
295
      0xa700a7a7, 0xe100e1e1, 0xd000d0d0, 0xf500f5f5,
296
      0x68006868, 0xf200f2f2, 0x1b001b1b, 0x34003434,
297
      0x70007070, 0x05000505, 0xa300a3a3, 0x8a008a8a,
298
      0xd500d5d5, 0x79007979, 0x86008686, 0xa800a8a8,
299
      0x30003030, 0xc600c6c6, 0x51005151, 0x4b004b4b,
300
      0x1e001e1e, 0xa600a6a6, 0x27002727, 0xf600f6f6,
301
      0x35003535, 0xd200d2d2, 0x6e006e6e, 0x24002424,
302
      0x16001616, 0x82008282, 0x5f005f5f, 0xda00dada,
303
      0xe600e6e6, 0x75007575, 0xa200a2a2, 0xef00efef,
304
      0x2c002c2c, 0xb200b2b2, 0x1c001c1c, 0x9f009f9f,
305
      0x5d005d5d, 0x6f006f6f, 0x80008080, 0x0a000a0a,
306
      0x72007272, 0x44004444, 0x9b009b9b, 0x6c006c6c,
307
      0x90009090, 0x0b000b0b, 0x5b005b5b, 0x33003333,
308
      0x7d007d7d, 0x5a005a5a, 0x52005252, 0xf300f3f3,
309
      0x61006161, 0xa100a1a1, 0xf700f7f7, 0xb000b0b0,
310
      0xd600d6d6, 0x3f003f3f, 0x7c007c7c, 0x6d006d6d,
311
      0xed00eded, 0x14001414, 0xe000e0e0, 0xa500a5a5,
312
      0x3d003d3d, 0x22002222, 0xb300b3b3, 0xf800f8f8,
313
      0x89008989, 0xde00dede, 0x71007171, 0x1a001a1a,
314
      0xaf00afaf, 0xba00baba, 0xb500b5b5, 0x81008181
315
    },
316
    { /* x1 */
317
      0x52520052, 0x09090009, 0x6a6a006a, 0xd5d500d5,
318
      0x30300030, 0x36360036, 0xa5a500a5, 0x38380038,
319
      0xbfbf00bf, 0x40400040, 0xa3a300a3, 0x9e9e009e,
320
      0x81810081, 0xf3f300f3, 0xd7d700d7, 0xfbfb00fb,
321
      0x7c7c007c, 0xe3e300e3, 0x39390039, 0x82820082,
322
      0x9b9b009b, 0x2f2f002f, 0xffff00ff, 0x87870087,
323
      0x34340034, 0x8e8e008e, 0x43430043, 0x44440044,
324
      0xc4c400c4, 0xdede00de, 0xe9e900e9, 0xcbcb00cb,
325
      0x54540054, 0x7b7b007b, 0x94940094, 0x32320032,
326
      0xa6a600a6, 0xc2c200c2, 0x23230023, 0x3d3d003d,
327
      0xeeee00ee, 0x4c4c004c, 0x95950095, 0x0b0b000b,
328
      0x42420042, 0xfafa00fa, 0xc3c300c3, 0x4e4e004e,
329
      0x08080008, 0x2e2e002e, 0xa1a100a1, 0x66660066,
330
      0x28280028, 0xd9d900d9, 0x24240024, 0xb2b200b2,
331
      0x76760076, 0x5b5b005b, 0xa2a200a2, 0x49490049,
332
      0x6d6d006d, 0x8b8b008b, 0xd1d100d1, 0x25250025,
333
      0x72720072, 0xf8f800f8, 0xf6f600f6, 0x64640064,
334
      0x86860086, 0x68680068, 0x98980098, 0x16160016,
335
      0xd4d400d4, 0xa4a400a4, 0x5c5c005c, 0xcccc00cc,
336
      0x5d5d005d, 0x65650065, 0xb6b600b6, 0x92920092,
337
      0x6c6c006c, 0x70700070, 0x48480048, 0x50500050,
338
      0xfdfd00fd, 0xeded00ed, 0xb9b900b9, 0xdada00da,
339
      0x5e5e005e, 0x15150015, 0x46460046, 0x57570057,
340
      0xa7a700a7, 0x8d8d008d, 0x9d9d009d, 0x84840084,
341
      0x90900090, 0xd8d800d8, 0xabab00ab, 0x00000000,
342
      0x8c8c008c, 0xbcbc00bc, 0xd3d300d3, 0x0a0a000a,
343
      0xf7f700f7, 0xe4e400e4, 0x58580058, 0x05050005,
344
      0xb8b800b8, 0xb3b300b3, 0x45450045, 0x06060006,
345
      0xd0d000d0, 0x2c2c002c, 0x1e1e001e, 0x8f8f008f,
346
      0xcaca00ca, 0x3f3f003f, 0x0f0f000f, 0x02020002,
347
      0xc1c100c1, 0xafaf00af, 0xbdbd00bd, 0x03030003,
348
      0x01010001, 0x13130013, 0x8a8a008a, 0x6b6b006b,
349
      0x3a3a003a, 0x91910091, 0x11110011, 0x41410041,
350
      0x4f4f004f, 0x67670067, 0xdcdc00dc, 0xeaea00ea,
351
      0x97970097, 0xf2f200f2, 0xcfcf00cf, 0xcece00ce,
352
      0xf0f000f0, 0xb4b400b4, 0xe6e600e6, 0x73730073,
353
      0x96960096, 0xacac00ac, 0x74740074, 0x22220022,
354
      0xe7e700e7, 0xadad00ad, 0x35350035, 0x85850085,
355
      0xe2e200e2, 0xf9f900f9, 0x37370037, 0xe8e800e8,
356
      0x1c1c001c, 0x75750075, 0xdfdf00df, 0x6e6e006e,
357
      0x47470047, 0xf1f100f1, 0x1a1a001a, 0x71710071,
358
      0x1d1d001d, 0x29290029, 0xc5c500c5, 0x89890089,
359
      0x6f6f006f, 0xb7b700b7, 0x62620062, 0x0e0e000e,
360
      0xaaaa00aa, 0x18180018, 0xbebe00be, 0x1b1b001b,
361
      0xfcfc00fc, 0x56560056, 0x3e3e003e, 0x4b4b004b,
362
      0xc6c600c6, 0xd2d200d2, 0x79790079, 0x20200020,
363
      0x9a9a009a, 0xdbdb00db, 0xc0c000c0, 0xfefe00fe,
364
      0x78780078, 0xcdcd00cd, 0x5a5a005a, 0xf4f400f4,
365
      0x1f1f001f, 0xdddd00dd, 0xa8a800a8, 0x33330033,
366
      0x88880088, 0x07070007, 0xc7c700c7, 0x31310031,
367
      0xb1b100b1, 0x12120012, 0x10100010, 0x59590059,
368
      0x27270027, 0x80800080, 0xecec00ec, 0x5f5f005f,
369
      0x60600060, 0x51510051, 0x7f7f007f, 0xa9a900a9,
370
      0x19190019, 0xb5b500b5, 0x4a4a004a, 0x0d0d000d,
371
      0x2d2d002d, 0xe5e500e5, 0x7a7a007a, 0x9f9f009f,
372
      0x93930093, 0xc9c900c9, 0x9c9c009c, 0xefef00ef,
373
      0xa0a000a0, 0xe0e000e0, 0x3b3b003b, 0x4d4d004d,
374
      0xaeae00ae, 0x2a2a002a, 0xf5f500f5, 0xb0b000b0,
375
      0xc8c800c8, 0xebeb00eb, 0xbbbb00bb, 0x3c3c003c,
376
      0x83830083, 0x53530053, 0x99990099, 0x61610061,
377
      0x17170017, 0x2b2b002b, 0x04040004, 0x7e7e007e,
378
      0xbaba00ba, 0x77770077, 0xd6d600d6, 0x26260026,
379
      0xe1e100e1, 0x69690069, 0x14140014, 0x63630063,
380
      0x55550055, 0x21210021, 0x0c0c000c, 0x7d7d007d
381
    },
382
    { /* x2 */
383
      0x30303000, 0x68686800, 0x99999900, 0x1b1b1b00,
384
      0x87878700, 0xb9b9b900, 0x21212100, 0x78787800,
385
      0x50505000, 0x39393900, 0xdbdbdb00, 0xe1e1e100,
386
      0x72727200, 0x09090900, 0x62626200, 0x3c3c3c00,
387
      0x3e3e3e00, 0x7e7e7e00, 0x5e5e5e00, 0x8e8e8e00,
388
      0xf1f1f100, 0xa0a0a000, 0xcccccc00, 0xa3a3a300,
389
      0x2a2a2a00, 0x1d1d1d00, 0xfbfbfb00, 0xb6b6b600,
390
      0xd6d6d600, 0x20202000, 0xc4c4c400, 0x8d8d8d00,
391
      0x81818100, 0x65656500, 0xf5f5f500, 0x89898900,
392
      0xcbcbcb00, 0x9d9d9d00, 0x77777700, 0xc6c6c600,
393
      0x57575700, 0x43434300, 0x56565600, 0x17171700,
394
      0xd4d4d400, 0x40404000, 0x1a1a1a00, 0x4d4d4d00,
395
      0xc0c0c000, 0x63636300, 0x6c6c6c00, 0xe3e3e300,
396
      0xb7b7b700, 0xc8c8c800, 0x64646400, 0x6a6a6a00,
397
      0x53535300, 0xaaaaaa00, 0x38383800, 0x98989800,
398
      0x0c0c0c00, 0xf4f4f400, 0x9b9b9b00, 0xededed00,
399
      0x7f7f7f00, 0x22222200, 0x76767600, 0xafafaf00,
400
      0xdddddd00, 0x3a3a3a00, 0x0b0b0b00, 0x58585800,
401
      0x67676700, 0x88888800, 0x06060600, 0xc3c3c300,
402
      0x35353500, 0x0d0d0d00, 0x01010100, 0x8b8b8b00,
403
      0x8c8c8c00, 0xc2c2c200, 0xe6e6e600, 0x5f5f5f00,
404
      0x02020200, 0x24242400, 0x75757500, 0x93939300,
405
      0x66666600, 0x1e1e1e00, 0xe5e5e500, 0xe2e2e200,
406
      0x54545400, 0xd8d8d800, 0x10101000, 0xcecece00,
407
      0x7a7a7a00, 0xe8e8e800, 0x08080800, 0x2c2c2c00,
408
      0x12121200, 0x97979700, 0x32323200, 0xababab00,
409
      0xb4b4b400, 0x27272700, 0x0a0a0a00, 0x23232300,
410
      0xdfdfdf00, 0xefefef00, 0xcacaca00, 0xd9d9d900,
411
      0xb8b8b800, 0xfafafa00, 0xdcdcdc00, 0x31313100,
412
      0x6b6b6b00, 0xd1d1d100, 0xadadad00, 0x19191900,
413
      0x49494900, 0xbdbdbd00, 0x51515100, 0x96969600,
414
      0xeeeeee00, 0xe4e4e400, 0xa8a8a800, 0x41414100,
415
      0xdadada00, 0xffffff00, 0xcdcdcd00, 0x55555500,
416
      0x86868600, 0x36363600, 0xbebebe00, 0x61616100,
417
      0x52525200, 0xf8f8f800, 0xbbbbbb00, 0x0e0e0e00,
418
      0x82828200, 0x48484800, 0x69696900, 0x9a9a9a00,
419
      0xe0e0e000, 0x47474700, 0x9e9e9e00, 0x5c5c5c00,
420
      0x04040400, 0x4b4b4b00, 0x34343400, 0x15151500,
421
      0x79797900, 0x26262600, 0xa7a7a700, 0xdedede00,
422
      0x29292900, 0xaeaeae00, 0x92929200, 0xd7d7d700,
423
      0x84848400, 0xe9e9e900, 0xd2d2d200, 0xbababa00,
424
      0x5d5d5d00, 0xf3f3f300, 0xc5c5c500, 0xb0b0b000,
425
      0xbfbfbf00, 0xa4a4a400, 0x3b3b3b00, 0x71717100,
426
      0x44444400, 0x46464600, 0x2b2b2b00, 0xfcfcfc00,
427
      0xebebeb00, 0x6f6f6f00, 0xd5d5d500, 0xf6f6f600,
428
      0x14141400, 0xfefefe00, 0x7c7c7c00, 0x70707000,
429
      0x5a5a5a00, 0x7d7d7d00, 0xfdfdfd00, 0x2f2f2f00,
430
      0x18181800, 0x83838300, 0x16161600, 0xa5a5a500,
431
      0x91919100, 0x1f1f1f00, 0x05050500, 0x95959500,
432
      0x74747400, 0xa9a9a900, 0xc1c1c100, 0x5b5b5b00,
433
      0x4a4a4a00, 0x85858500, 0x6d6d6d00, 0x13131300,
434
      0x07070700, 0x4f4f4f00, 0x4e4e4e00, 0x45454500,
435
      0xb2b2b200, 0x0f0f0f00, 0xc9c9c900, 0x1c1c1c00,
436
      0xa6a6a600, 0xbcbcbc00, 0xececec00, 0x73737300,
437
      0x90909000, 0x7b7b7b00, 0xcfcfcf00, 0x59595900,
438
      0x8f8f8f00, 0xa1a1a100, 0xf9f9f900, 0x2d2d2d00,
439
      0xf2f2f200, 0xb1b1b100, 0x00000000, 0x94949400,
440
      0x37373700, 0x9f9f9f00, 0xd0d0d000, 0x2e2e2e00,
441
      0x9c9c9c00, 0x6e6e6e00, 0x28282800, 0x3f3f3f00,
442
      0x80808000, 0xf0f0f000, 0x3d3d3d00, 0xd3d3d300,
443
      0x25252500, 0x8a8a8a00, 0xb5b5b500, 0xe7e7e700,
444
      0x42424200, 0xb3b3b300, 0xc7c7c700, 0xeaeaea00,
445
      0xf7f7f700, 0x4c4c4c00, 0x11111100, 0x33333300,
446
      0x03030300, 0xa2a2a200, 0xacacac00, 0x60606000
447
    },
448
    0
449
  };
450
451
#ifdef USE_AESNI_AVX
452
extern unsigned int
453
_gcry_aria_aesni_avx_ecb_crypt_blk1_16(const void *ctx, byte *out,
454
               const byte *in, const void *key,
455
               u64 nblks) ASM_FUNC_ABI;
456
extern unsigned int
457
_gcry_aria_aesni_avx_ctr_crypt_blk16(const void *ctx, byte *out,
458
             const byte *in, byte *iv) ASM_FUNC_ABI;
459
460
#ifdef USE_GFNI_AVX
461
extern unsigned int
462
_gcry_aria_gfni_avx_ecb_crypt_blk1_16(const void *ctx, byte *out,
463
              const byte *in, const void *key,
464
              u64 nblks) ASM_FUNC_ABI;
465
extern unsigned int
466
_gcry_aria_gfni_avx_ctr_crypt_blk16(const void *ctx, byte *out,
467
            const byte *in, byte *iv) ASM_FUNC_ABI;
468
#endif /* USE_GFNI_AVX */
469
470
static inline unsigned int
471
aria_avx_ecb_crypt_blk1_16(const ARIA_context *ctx, byte *out, const byte *in,
472
         const u32 key[][ARIA_RD_KEY_WORDS], size_t nblks)
473
15
{
474
15
  if (0) { }
475
15
#ifdef USE_GFNI_AVX
476
15
  else if (ctx->use_gfni_avx)
477
0
    return _gcry_aria_gfni_avx_ecb_crypt_blk1_16(ctx, out, in, key, nblks)
478
0
    + ASM_EXTRA_STACK;
479
15
#endif /* USE_GFNI_AVX */
480
15
  else
481
15
    return _gcry_aria_aesni_avx_ecb_crypt_blk1_16(ctx, out, in, key, nblks)
482
15
    + ASM_EXTRA_STACK;
483
15
}
484
485
static inline unsigned int
486
aria_avx_ctr_crypt_blk16(const ARIA_context *ctx, byte *out, const byte *in,
487
       byte *iv)
488
0
{
489
0
  if (0) { }
490
0
#ifdef USE_GFNI_AVX
491
0
  else if (ctx->use_gfni_avx)
492
0
    return _gcry_aria_gfni_avx_ctr_crypt_blk16(ctx, out, in, iv)
493
0
    + ASM_EXTRA_STACK;
494
0
#endif /* USE_GFNI_AVX */
495
0
  else
496
0
    return _gcry_aria_aesni_avx_ctr_crypt_blk16(ctx, out, in, iv)
497
0
    + ASM_EXTRA_STACK;
498
0
}
499
#endif /* USE_AESNI_AVX */
500
501
#ifdef USE_AESNI_AVX2
502
extern unsigned int
503
_gcry_aria_aesni_avx2_ecb_crypt_blk32(const void *ctx, byte *out,
504
              const byte *in,
505
              const void *key) ASM_FUNC_ABI;
506
extern unsigned int
507
_gcry_aria_aesni_avx2_ctr_crypt_blk32(const void *ctx, byte *out,
508
              const byte *in, byte *iv) ASM_FUNC_ABI;
509
510
#ifdef USE_VAES_AVX2
511
extern unsigned int
512
_gcry_aria_vaes_avx2_ecb_crypt_blk32(const void *ctx, byte *out,
513
             const byte *in,
514
             const void *key) ASM_FUNC_ABI;
515
extern unsigned int
516
_gcry_aria_vaes_avx2_ctr_crypt_blk32(const void *ctx, byte *out,
517
             const byte *in, byte *iv) ASM_FUNC_ABI;
518
#endif /* USE_VAES_AVX2 */
519
520
#ifdef USE_GFNI_AVX2
521
extern unsigned int
522
_gcry_aria_gfni_avx2_ecb_crypt_blk32(const void *ctx, byte *out,
523
             const byte *in,
524
             const void *key) ASM_FUNC_ABI;
525
extern unsigned int
526
_gcry_aria_gfni_avx2_ctr_crypt_blk32(const void *ctx, byte *out,
527
             const byte *in, byte *iv) ASM_FUNC_ABI;
528
#endif /* USE_GFNI_AVX2 */
529
530
static inline unsigned int
531
aria_avx2_ecb_crypt_blk32(const ARIA_context *ctx, byte *out, const byte *in,
532
        const u32 key[][ARIA_RD_KEY_WORDS])
533
0
{
534
0
  if (0) { }
535
0
#ifdef USE_GFNI_AVX2
536
0
  else if (ctx->use_gfni_avx2)
537
0
    return _gcry_aria_gfni_avx2_ecb_crypt_blk32(ctx, out, in, key)
538
0
    + ASM_EXTRA_STACK;
539
0
#endif /* USE_GFNI_AVX2 */
540
0
#ifdef USE_VAES_AVX2
541
0
  else if (ctx->use_vaes_avx2)
542
0
    return _gcry_aria_vaes_avx2_ecb_crypt_blk32(ctx, out, in, key)
543
0
    + ASM_EXTRA_STACK;
544
0
#endif /* USE_VAES_AVX2 */
545
0
  else
546
0
    return _gcry_aria_aesni_avx2_ecb_crypt_blk32(ctx, out, in, key)
547
0
    + ASM_EXTRA_STACK;
548
0
}
549
550
static inline unsigned int
551
aria_avx2_ctr_crypt_blk32(const ARIA_context *ctx, byte *out, const byte *in,
552
        byte *iv)
553
0
{
554
0
  if (0) { }
555
0
#ifdef USE_GFNI_AVX2
556
0
  else if (ctx->use_gfni_avx2)
557
0
    return _gcry_aria_gfni_avx2_ctr_crypt_blk32(ctx, out, in, iv)
558
0
    + ASM_EXTRA_STACK;
559
0
#endif /* USE_GFNI_AVX2 */
560
0
#ifdef USE_VAES_AVX2
561
0
  else if (ctx->use_vaes_avx2)
562
0
    return _gcry_aria_vaes_avx2_ctr_crypt_blk32(ctx, out, in, iv)
563
0
    + ASM_EXTRA_STACK;
564
0
#endif /* USE_VAES_AVX2 */
565
0
  else
566
0
    return _gcry_aria_aesni_avx2_ctr_crypt_blk32(ctx, out, in, iv)
567
0
    + ASM_EXTRA_STACK;
568
0
}
569
#endif /* USE_AESNI_AVX2 */
570
571
#ifdef USE_GFNI_AVX512
572
extern unsigned int
573
_gcry_aria_gfni_avx512_ecb_crypt_blk64(const void *ctx, byte *out,
574
               const byte *in,
575
               const void *key) ASM_FUNC_ABI;
576
extern unsigned int
577
_gcry_aria_gfni_avx512_ctr_crypt_blk64(const void *ctx, byte *out,
578
               const byte *in, byte *iv) ASM_FUNC_ABI;
579
580
static inline unsigned int
581
aria_gfni_avx512_ecb_crypt_blk64(const ARIA_context *ctx, byte *out,
582
         const byte *in,
583
         const u32 key[][ARIA_RD_KEY_WORDS])
584
0
{
585
0
  return _gcry_aria_gfni_avx512_ecb_crypt_blk64(ctx, out, in, key)
586
0
    + ASM_EXTRA_STACK;
587
0
}
588
589
static inline unsigned int
590
aria_gfni_avx512_ctr_crypt_blk64(const ARIA_context *ctx, byte *out,
591
         const byte *in, byte *iv)
592
0
{
593
0
  return _gcry_aria_gfni_avx512_ctr_crypt_blk64(ctx, out, in, iv)
594
0
    + ASM_EXTRA_STACK;
595
0
}
596
#endif /* USE_AESNI_AVX2 */
597
598
/* Prefetching for sbox tables. */
599
static inline void
600
prefetch_table(const volatile byte *tab, size_t len)
601
269
{
602
269
  size_t i;
603
604
4.57k
  for (i = 0; len - i >= 8 * 32; i += 8 * 32)
605
4.30k
    {
606
4.30k
      (void)tab[i + 0 * 32];
607
4.30k
      (void)tab[i + 1 * 32];
608
4.30k
      (void)tab[i + 2 * 32];
609
4.30k
      (void)tab[i + 3 * 32];
610
4.30k
      (void)tab[i + 4 * 32];
611
4.30k
      (void)tab[i + 5 * 32];
612
4.30k
      (void)tab[i + 6 * 32];
613
4.30k
      (void)tab[i + 7 * 32];
614
4.30k
    }
615
1.07k
  for (; i < len; i += 32)
616
807
    {
617
807
      (void)tab[i];
618
807
    }
619
620
269
  (void)tab[len - 1];
621
269
}
622
623
static inline void
624
prefetch_sboxes(void)
625
269
{
626
  /* Modify counters to trigger copy-on-write and unsharing if physical pages
627
   * of look-up table are shared between processes.  Modifying counters also
628
   * causes checksums for pages to change and hint same-page merging algorithm
629
   * that these pages are frequently changing.  */
630
269
  sboxes.counter_head++;
631
269
  sboxes.counter_tail++;
632
633
  /* Prefetch look-up tables to cache.  */
634
269
  prefetch_table((const void *)&sboxes, sizeof(sboxes));
635
269
}
636
637
638
static ALWAYS_INLINE
639
u32 rotr32(u32 v, u32 r)
640
81.8k
{
641
81.8k
  return ror(v, r);
642
81.8k
}
643
644
static ALWAYS_INLINE
645
u32 bswap32(u32 v)
646
81.2k
{
647
81.2k
  return _gcry_bswap32(v);
648
81.2k
}
649
650
static ALWAYS_INLINE u32
651
get_u8(u32 x, u32 y)
652
1.39M
{
653
1.39M
  return (x >> ((3 - y) * 8)) & 0xFF;
654
1.39M
}
655
656
static ALWAYS_INLINE u32
657
make_u32(byte v0, byte v1, byte v2, byte v3)
658
25.1k
{
659
25.1k
  return ((u32)v0 << 24) | ((u32)v1 << 16) | ((u32)v2 <<  8) | ((u32)v3);
660
25.1k
}
661
662
static ALWAYS_INLINE u32
663
aria_m(u32 t0)
664
220
{
665
220
  return rotr32(t0, 8) ^ rotr32(t0 ^ rotr32(t0, 8), 16);
666
220
}
667
668
/* S-Box Layer 1 + M */
669
static ALWAYS_INLINE void
670
aria_sbox_layer1_with_pre_diff(u32 *t0, u32 *t1, u32 *t2, u32 *t3)
671
43.7k
{
672
43.7k
  *t0 = sboxes.s1[get_u8(*t0, 0)] ^
673
43.7k
  sboxes.s2[get_u8(*t0, 1)] ^
674
43.7k
  sboxes.x1[get_u8(*t0, 2)] ^
675
43.7k
  sboxes.x2[get_u8(*t0, 3)];
676
43.7k
  *t1 = sboxes.s1[get_u8(*t1, 0)] ^
677
43.7k
  sboxes.s2[get_u8(*t1, 1)] ^
678
43.7k
  sboxes.x1[get_u8(*t1, 2)] ^
679
43.7k
  sboxes.x2[get_u8(*t1, 3)];
680
43.7k
  *t2 = sboxes.s1[get_u8(*t2, 0)] ^
681
43.7k
  sboxes.s2[get_u8(*t2, 1)] ^
682
43.7k
  sboxes.x1[get_u8(*t2, 2)] ^
683
43.7k
  sboxes.x2[get_u8(*t2, 3)];
684
43.7k
  *t3 = sboxes.s1[get_u8(*t3, 0)] ^
685
43.7k
  sboxes.s2[get_u8(*t3, 1)] ^
686
43.7k
  sboxes.x1[get_u8(*t3, 2)] ^
687
43.7k
  sboxes.x2[get_u8(*t3, 3)];
688
43.7k
}
689
690
/* S-Box Layer 2 + M */
691
static ALWAYS_INLINE void
692
aria_sbox_layer2_with_pre_diff(u32 *t0, u32 *t1, u32 *t2, u32 *t3)
693
37.4k
{
694
37.4k
  *t0 = sboxes.x1[get_u8(*t0, 0)] ^
695
37.4k
  sboxes.x2[get_u8(*t0, 1)] ^
696
37.4k
  sboxes.s1[get_u8(*t0, 2)] ^
697
37.4k
  sboxes.s2[get_u8(*t0, 3)];
698
37.4k
  *t1 = sboxes.x1[get_u8(*t1, 0)] ^
699
37.4k
  sboxes.x2[get_u8(*t1, 1)] ^
700
37.4k
  sboxes.s1[get_u8(*t1, 2)] ^
701
37.4k
  sboxes.s2[get_u8(*t1, 3)];
702
37.4k
  *t2 = sboxes.x1[get_u8(*t2, 0)] ^
703
37.4k
  sboxes.x2[get_u8(*t2, 1)] ^
704
37.4k
  sboxes.s1[get_u8(*t2, 2)] ^
705
37.4k
  sboxes.s2[get_u8(*t2, 3)];
706
37.4k
  *t3 = sboxes.x1[get_u8(*t3, 0)] ^
707
37.4k
  sboxes.x2[get_u8(*t3, 1)] ^
708
37.4k
  sboxes.s1[get_u8(*t3, 2)] ^
709
37.4k
  sboxes.s2[get_u8(*t3, 3)];
710
37.4k
}
711
712
/* Word-level diffusion */
713
static ALWAYS_INLINE void
714
aria_diff_word(u32 *t0, u32 *t1, u32 *t2, u32 *t3)
715
162k
{
716
162k
  *t1 ^= *t2;
717
162k
  *t2 ^= *t3;
718
162k
  *t0 ^= *t1;
719
720
162k
  *t3 ^= *t1;
721
162k
  *t2 ^= *t0;
722
162k
  *t1 ^= *t2;
723
162k
}
724
725
/* Byte-level diffusion */
726
static inline void aria_diff_byte(u32 *t1, u32 *t2, u32 *t3)
727
81.2k
{
728
81.2k
  *t1 = ((*t1 << 8) & 0xff00ff00) ^ ((*t1 >> 8) & 0x00ff00ff);
729
81.2k
  *t2 = rotr32(*t2, 16);
730
81.2k
  *t3 = bswap32(*t3);
731
81.2k
}
732
733
/* Key XOR Layer */
734
static ALWAYS_INLINE void
735
aria_add_round_key(u32 *rk, u32 *t0, u32 *t1, u32 *t2, u32 *t3)
736
93.5k
{
737
93.5k
  *t0 ^= rk[0];
738
93.5k
  *t1 ^= rk[1];
739
93.5k
  *t2 ^= rk[2];
740
93.5k
  *t3 ^= rk[3];
741
93.5k
}
742
743
/* Odd round Substitution & Diffusion */
744
static ALWAYS_INLINE void
745
aria_subst_diff_odd(u32 *t0, u32 *t1, u32 *t2, u32 *t3)
746
43.7k
{
747
43.7k
  aria_sbox_layer1_with_pre_diff(t0, t1, t2, t3);
748
43.7k
  aria_diff_word(t0, t1, t2, t3);
749
43.7k
  aria_diff_byte(t1, t2, t3);
750
43.7k
  aria_diff_word(t0, t1, t2, t3);
751
43.7k
}
752
753
/* Even round Substitution & Diffusion */
754
static ALWAYS_INLINE void
755
aria_subst_diff_even(u32 *t0, u32 *t1, u32 *t2, u32 *t3)
756
37.4k
{
757
37.4k
  aria_sbox_layer2_with_pre_diff(t0, t1, t2, t3);
758
37.4k
  aria_diff_word(t0, t1, t2, t3);
759
37.4k
  aria_diff_byte(t3, t0, t1);
760
37.4k
  aria_diff_word(t0, t1, t2, t3);
761
37.4k
}
762
763
/* Last round */
764
static ALWAYS_INLINE void
765
aria_last_round(u32 *t0, u32 *t1, u32 *t2, u32 *t3)
766
6.28k
{
767
6.28k
  *t0 = make_u32((byte)(sboxes.x1[get_u8(*t0, 0)]),
768
6.28k
     (byte)(sboxes.x2[get_u8(*t0, 1)] >> 24),
769
6.28k
     (byte)(sboxes.s1[get_u8(*t0, 2)]),
770
6.28k
     (byte)(sboxes.s2[get_u8(*t0, 3)]));
771
6.28k
  *t1 = make_u32((byte)(sboxes.x1[get_u8(*t1, 0)]),
772
6.28k
     (byte)(sboxes.x2[get_u8(*t1, 1)] >> 24),
773
6.28k
     (byte)(sboxes.s1[get_u8(*t1, 2)]),
774
6.28k
     (byte)(sboxes.s2[get_u8(*t1, 3)]));
775
6.28k
  *t2 = make_u32((byte)(sboxes.x1[get_u8(*t2, 0)]),
776
6.28k
     (byte)(sboxes.x2[get_u8(*t2, 1)] >> 24),
777
6.28k
     (byte)(sboxes.s1[get_u8(*t2, 2)]),
778
6.28k
     (byte)(sboxes.s2[get_u8(*t2, 3)]));
779
6.28k
  *t3 = make_u32((byte)(sboxes.x1[get_u8(*t3, 0)]),
780
6.28k
     (byte)(sboxes.x2[get_u8(*t3, 1)] >> 24),
781
6.28k
     (byte)(sboxes.s1[get_u8(*t3, 2)]),
782
6.28k
     (byte)(sboxes.s2[get_u8(*t3, 3)]));
783
6.28k
}
784
785
/* Q, R Macro expanded ARIA GSRK */
786
static ALWAYS_INLINE void
787
aria_gsrk(u32 *rk, u32 *x, u32 *y, u32 n)
788
719
{
789
719
  int q = 4 - (n / 32);
790
719
  int r = n % 32;
791
792
719
  rk[0] = (x[0]) ^
793
719
    ((y[q % 4]) >> r) ^
794
719
    ((y[(q + 3) % 4]) << (32 - r));
795
719
  rk[1] = (x[1]) ^
796
719
    ((y[(q + 1) % 4]) >> r) ^
797
719
    ((y[q % 4]) << (32 - r));
798
719
  rk[2] = (x[2]) ^
799
719
    ((y[(q + 2) % 4]) >> r) ^
800
719
    ((y[(q + 1) % 4]) << (32 - r));
801
719
  rk[3] = (x[3]) ^
802
719
    ((y[(q + 3) % 4]) >> r) ^
803
719
    ((y[(q + 2) % 4]) << (32 - r));
804
719
}
805
806
807
static NO_INLINE void
808
aria_set_encrypt_key(ARIA_context *ctx, const byte *in_key, u32 key_len)
809
51
{
810
51
  u32 w0[4], w1[4], w2[4], w3[4];
811
51
  u32 reg0, reg1, reg2, reg3;
812
51
  const u32 *ck;
813
51
  int rkidx = 0;
814
815
51
  ctx->rounds = (key_len + 32) / 4;
816
51
  prefetch_sboxes();
817
818
51
  ck = &key_rc[(key_len - 16) / 2];
819
820
51
  w0[0] = buf_get_be32(in_key + 0);
821
51
  w0[1] = buf_get_be32(in_key + 4);
822
51
  w0[2] = buf_get_be32(in_key + 8);
823
51
  w0[3] = buf_get_be32(in_key + 12);
824
825
51
  reg0 = w0[0] ^ ck[0];
826
51
  reg1 = w0[1] ^ ck[1];
827
51
  reg2 = w0[2] ^ ck[2];
828
51
  reg3 = w0[3] ^ ck[3];
829
830
51
  aria_subst_diff_odd(&reg0, &reg1, &reg2, &reg3);
831
832
51
  if (key_len > 16)
833
21
    {
834
21
      w1[0] = buf_get_be32(in_key + 16);
835
21
      w1[1] = buf_get_be32(in_key + 20);
836
21
      if (key_len > 24)
837
7
  {
838
7
    w1[2] = buf_get_be32(in_key + 24);
839
7
    w1[3] = buf_get_be32(in_key + 28);
840
7
  }
841
14
      else
842
14
  {
843
14
    w1[2] = 0;
844
14
    w1[3] = 0;
845
14
  }
846
21
    }
847
30
  else
848
30
    {
849
30
      w1[0] = 0;
850
30
      w1[1] = 0;
851
30
      w1[2] = 0;
852
30
      w1[3] = 0;
853
30
    }
854
855
51
  w1[0] ^= reg0;
856
51
  w1[1] ^= reg1;
857
51
  w1[2] ^= reg2;
858
51
  w1[3] ^= reg3;
859
860
51
  reg0 = w1[0];
861
51
  reg1 = w1[1];
862
51
  reg2 = w1[2];
863
51
  reg3 = w1[3];
864
865
51
  reg0 ^= ck[4];
866
51
  reg1 ^= ck[5];
867
51
  reg2 ^= ck[6];
868
51
  reg3 ^= ck[7];
869
870
51
  aria_subst_diff_even(&reg0, &reg1, &reg2, &reg3);
871
872
51
  reg0 ^= w0[0];
873
51
  reg1 ^= w0[1];
874
51
  reg2 ^= w0[2];
875
51
  reg3 ^= w0[3];
876
877
51
  w2[0] = reg0;
878
51
  w2[1] = reg1;
879
51
  w2[2] = reg2;
880
51
  w2[3] = reg3;
881
882
51
  reg0 ^= ck[8];
883
51
  reg1 ^= ck[9];
884
51
  reg2 ^= ck[10];
885
51
  reg3 ^= ck[11];
886
887
51
  aria_subst_diff_odd(&reg0, &reg1, &reg2, &reg3);
888
889
51
  w3[0] = reg0 ^ w1[0];
890
51
  w3[1] = reg1 ^ w1[1];
891
51
  w3[2] = reg2 ^ w1[2];
892
51
  w3[3] = reg3 ^ w1[3];
893
894
51
  aria_gsrk(ctx->enc_key[rkidx], w0, w1, 19);
895
51
  rkidx++;
896
51
  aria_gsrk(ctx->enc_key[rkidx], w1, w2, 19);
897
51
  rkidx++;
898
51
  aria_gsrk(ctx->enc_key[rkidx], w2, w3, 19);
899
51
  rkidx++;
900
51
  aria_gsrk(ctx->enc_key[rkidx], w3, w0, 19);
901
902
51
  rkidx++;
903
51
  aria_gsrk(ctx->enc_key[rkidx], w0, w1, 31);
904
51
  rkidx++;
905
51
  aria_gsrk(ctx->enc_key[rkidx], w1, w2, 31);
906
51
  rkidx++;
907
51
  aria_gsrk(ctx->enc_key[rkidx], w2, w3, 31);
908
51
  rkidx++;
909
51
  aria_gsrk(ctx->enc_key[rkidx], w3, w0, 31);
910
911
51
  rkidx++;
912
51
  aria_gsrk(ctx->enc_key[rkidx], w0, w1, 67);
913
51
  rkidx++;
914
51
  aria_gsrk(ctx->enc_key[rkidx], w1, w2, 67);
915
51
  rkidx++;
916
51
  aria_gsrk(ctx->enc_key[rkidx], w2, w3, 67);
917
51
  rkidx++;
918
51
  aria_gsrk(ctx->enc_key[rkidx], w3, w0, 67);
919
920
51
  rkidx++;
921
51
  aria_gsrk(ctx->enc_key[rkidx], w0, w1, 97);
922
51
  if (key_len > 16)
923
21
    {
924
21
      rkidx++;
925
21
      aria_gsrk(ctx->enc_key[rkidx], w1, w2, 97);
926
21
      rkidx++;
927
21
      aria_gsrk(ctx->enc_key[rkidx], w2, w3, 97);
928
929
21
      if (key_len > 24)
930
7
  {
931
7
    rkidx++;
932
7
    aria_gsrk(ctx->enc_key[rkidx], w3, w0, 97);
933
934
7
    rkidx++;
935
7
    aria_gsrk(ctx->enc_key[rkidx], w0, w1, 109);
936
7
  }
937
21
    }
938
939
51
  wipememory(w0, sizeof(w0));
940
51
  wipememory(w1, sizeof(w1));
941
51
  wipememory(w2, sizeof(w2));
942
51
  wipememory(w3, sizeof(w3));
943
51
}
944
945
static void
946
aria_set_decrypt_key(ARIA_context *ctx)
947
5
{
948
5
  int i;
949
950
25
  for (i = 0; i < 4; i++)
951
20
    {
952
20
      ctx->dec_key[0][i] = ctx->enc_key[ctx->rounds][i];
953
20
      ctx->dec_key[ctx->rounds][i] = ctx->enc_key[0][i];
954
20
    }
955
956
60
  for (i = 1; i < ctx->rounds; i++)
957
55
    {
958
55
      ctx->dec_key[i][0] = aria_m(ctx->enc_key[ctx->rounds - i][0]);
959
55
      ctx->dec_key[i][1] = aria_m(ctx->enc_key[ctx->rounds - i][1]);
960
55
      ctx->dec_key[i][2] = aria_m(ctx->enc_key[ctx->rounds - i][2]);
961
55
      ctx->dec_key[i][3] = aria_m(ctx->enc_key[ctx->rounds - i][3]);
962
963
55
      aria_diff_word(&ctx->dec_key[i][0], &ctx->dec_key[i][1],
964
55
         &ctx->dec_key[i][2], &ctx->dec_key[i][3]);
965
55
      aria_diff_byte(&ctx->dec_key[i][1],
966
55
         &ctx->dec_key[i][2], &ctx->dec_key[i][3]);
967
55
      aria_diff_word(&ctx->dec_key[i][0], &ctx->dec_key[i][1],
968
55
         &ctx->dec_key[i][2], &ctx->dec_key[i][3]);
969
55
    }
970
5
}
971
972
static NO_INLINE unsigned int
973
aria_crypt(ARIA_context *ctx, byte *out, const byte *in,
974
     u32 key[][ARIA_RD_KEY_WORDS])
975
6.27k
{
976
6.27k
  u32 reg0, reg1, reg2, reg3;
977
6.27k
  int rounds = ctx->rounds;
978
6.27k
  int rkidx = 0;
979
980
6.27k
  reg0 = buf_get_be32(in + 0);
981
6.27k
  reg1 = buf_get_be32(in + 4);
982
6.27k
  reg2 = buf_get_be32(in + 8);
983
6.27k
  reg3 = buf_get_be32(in + 12);
984
985
6.27k
  aria_add_round_key(key[rkidx], &reg0, &reg1, &reg2, &reg3);
986
6.27k
  rkidx++;
987
988
43.6k
  while (1)
989
43.6k
    {
990
43.6k
      aria_subst_diff_odd(&reg0, &reg1, &reg2, &reg3);
991
43.6k
      aria_add_round_key(key[rkidx], &reg0, &reg1, &reg2, &reg3);
992
43.6k
      rkidx++;
993
994
43.6k
      if (rkidx >= rounds)
995
6.27k
  break;
996
997
37.3k
      aria_subst_diff_even(&reg0, &reg1, &reg2, &reg3);
998
37.3k
      aria_add_round_key(key[rkidx], &reg0, &reg1, &reg2, &reg3);
999
37.3k
      rkidx++;
1000
37.3k
    }
1001
1002
6.27k
  aria_last_round(&reg0, &reg1, &reg2, &reg3);
1003
6.27k
  aria_add_round_key(key[rkidx], &reg0, &reg1, &reg2, &reg3);
1004
1005
6.27k
  buf_put_be32(out + 0, reg0);
1006
6.27k
  buf_put_be32(out + 4, reg1);
1007
6.27k
  buf_put_be32(out + 8, reg2);
1008
6.27k
  buf_put_be32(out + 12, reg3);
1009
1010
6.27k
  return 4 * sizeof(void *) + 4 * sizeof(u32); /* stack burn depth */
1011
6.27k
}
1012
1013
unsigned int
1014
aria_encrypt(void *c, byte *outbuf, const byte *inbuf)
1015
166
{
1016
166
  ARIA_context *ctx = (ARIA_context *)c;
1017
1018
166
  prefetch_sboxes ();
1019
1020
166
  return aria_crypt (ctx, outbuf, inbuf, ctx->enc_key);
1021
166
}
1022
1023
unsigned int
1024
aria_decrypt(void *c, byte *outbuf, const byte *inbuf)
1025
5
{
1026
5
  ARIA_context *ctx = (ARIA_context *)c;
1027
1028
5
  if (!ctx->decryption_prepared)
1029
5
    {
1030
5
      aria_set_decrypt_key (ctx);
1031
5
      ctx->decryption_prepared = 1;
1032
5
    }
1033
1034
5
  prefetch_sboxes ();
1035
1036
5
  return aria_crypt (ctx, outbuf, inbuf, ctx->dec_key);
1037
5
}
1038
1039
1040
static unsigned int
1041
aria_crypt_2blks(ARIA_context *ctx, byte *out, const byte *in,
1042
     u32 key[][ARIA_RD_KEY_WORDS])
1043
2
{
1044
2
  u32 ra0, ra1, ra2, ra3;
1045
2
  u32 rb0, rb1, rb2, rb3;
1046
2
  int rounds = ctx->rounds;
1047
2
  int rkidx = 0;
1048
1049
2
  ra0 = buf_get_be32(in + 0);
1050
2
  ra1 = buf_get_be32(in + 4);
1051
2
  ra2 = buf_get_be32(in + 8);
1052
2
  ra3 = buf_get_be32(in + 12);
1053
2
  rb0 = buf_get_be32(in + 16);
1054
2
  rb1 = buf_get_be32(in + 20);
1055
2
  rb2 = buf_get_be32(in + 24);
1056
2
  rb3 = buf_get_be32(in + 28);
1057
1058
12
  while (1)
1059
12
    {
1060
12
      aria_add_round_key(key[rkidx], &ra0, &ra1, &ra2, &ra3);
1061
12
      aria_add_round_key(key[rkidx], &rb0, &rb1, &rb2, &rb3);
1062
12
      rkidx++;
1063
1064
12
      aria_subst_diff_odd(&ra0, &ra1, &ra2, &ra3);
1065
12
      aria_subst_diff_odd(&rb0, &rb1, &rb2, &rb3);
1066
12
      aria_add_round_key(key[rkidx], &ra0, &ra1, &ra2, &ra3);
1067
12
      aria_add_round_key(key[rkidx], &rb0, &rb1, &rb2, &rb3);
1068
12
      rkidx++;
1069
1070
12
      if (rkidx >= rounds)
1071
2
  break;
1072
1073
10
      aria_subst_diff_even(&ra0, &ra1, &ra2, &ra3);
1074
10
      aria_subst_diff_even(&rb0, &rb1, &rb2, &rb3);
1075
10
    }
1076
1077
2
  aria_last_round(&ra0, &ra1, &ra2, &ra3);
1078
2
  aria_last_round(&rb0, &rb1, &rb2, &rb3);
1079
2
  aria_add_round_key(key[rkidx], &ra0, &ra1, &ra2, &ra3);
1080
2
  aria_add_round_key(key[rkidx], &rb0, &rb1, &rb2, &rb3);
1081
1082
2
  buf_put_be32(out + 0, ra0);
1083
2
  buf_put_be32(out + 4, ra1);
1084
2
  buf_put_be32(out + 8, ra2);
1085
2
  buf_put_be32(out + 12, ra3);
1086
2
  buf_put_be32(out + 16, rb0);
1087
2
  buf_put_be32(out + 20, rb1);
1088
2
  buf_put_be32(out + 24, rb2);
1089
2
  buf_put_be32(out + 28, rb3);
1090
1091
2
  return 4 * sizeof(void *) + 8 * sizeof(u32); /* stack burn depth */
1092
2
}
1093
1094
static unsigned int
1095
aria_crypt_blocks (ARIA_context *ctx, byte *out, const byte *in,
1096
       size_t num_blks, u32 key[][ARIA_RD_KEY_WORDS])
1097
17
{
1098
17
  unsigned int burn_depth = 0;
1099
1100
17
#ifdef USE_GFNI_AVX512
1101
17
  if (ctx->use_gfni_avx512)
1102
0
    {
1103
0
      unsigned int nburn = 0;
1104
1105
0
      while (num_blks >= 64)
1106
0
  {
1107
0
    nburn = aria_gfni_avx512_ecb_crypt_blk64 (ctx, out, in, key);
1108
0
    in += 64 * ARIA_BLOCK_SIZE;
1109
0
    out += 64 * ARIA_BLOCK_SIZE;
1110
0
    num_blks -= 64;
1111
0
  }
1112
1113
0
      burn_depth = nburn > burn_depth ? nburn : burn_depth;
1114
1115
0
      if (num_blks == 0)
1116
0
  return burn_depth;
1117
0
    }
1118
17
#endif /* USE_AESNI_AVX2 */
1119
1120
17
#ifdef USE_AESNI_AVX2
1121
17
  if (ctx->use_aesni_avx2 || ctx->use_gfni_avx2)
1122
17
    {
1123
17
      unsigned int nburn = 0;
1124
1125
17
      while (num_blks >= 32)
1126
0
  {
1127
0
    nburn = aria_avx2_ecb_crypt_blk32 (ctx, out, in, key);
1128
0
    in += 32 * ARIA_BLOCK_SIZE;
1129
0
    out += 32 * ARIA_BLOCK_SIZE;
1130
0
    num_blks -= 32;
1131
0
  }
1132
1133
17
      burn_depth = nburn > burn_depth ? nburn : burn_depth;
1134
1135
17
      if (num_blks == 0)
1136
0
  return burn_depth;
1137
17
    }
1138
17
#endif /* USE_AESNI_AVX2 */
1139
1140
17
#ifdef USE_AESNI_AVX
1141
17
  if (ctx->use_aesni_avx || ctx->use_gfni_avx)
1142
17
    {
1143
17
      unsigned int nburn = 0;
1144
1145
32
      while (num_blks >= 3)
1146
15
  {
1147
15
    size_t curr_blks = num_blks < 16 ? num_blks : 16;
1148
15
    nburn = aria_avx_ecb_crypt_blk1_16 (ctx, out, in, key, curr_blks);
1149
15
    in += curr_blks * ARIA_BLOCK_SIZE;
1150
15
    out += curr_blks * ARIA_BLOCK_SIZE;
1151
15
    num_blks -= curr_blks;
1152
15
  }
1153
1154
17
      burn_depth = nburn > burn_depth ? nburn : burn_depth;
1155
1156
17
      if (num_blks == 0)
1157
15
  return burn_depth;
1158
17
    }
1159
2
#endif /* USE_AESNI_AVX */
1160
1161
2
  if (!ctx->bulk_prefetch_ready)
1162
2
    {
1163
2
      prefetch_sboxes();
1164
2
      ctx->bulk_prefetch_ready = 1;
1165
2
    }
1166
1167
4
  while (num_blks >= 2)
1168
2
    {
1169
2
      unsigned int nburn = aria_crypt_2blks (ctx, out, in, key);
1170
2
      burn_depth = nburn > burn_depth ? nburn : burn_depth;
1171
2
      out += 2 * ARIA_BLOCK_SIZE;
1172
2
      in += 2 * ARIA_BLOCK_SIZE;
1173
2
      num_blks -= 2;
1174
2
    }
1175
1176
2
  while (num_blks)
1177
0
    {
1178
0
      unsigned int nburn = aria_crypt (ctx, out, in, key);
1179
0
      burn_depth = nburn > burn_depth ? nburn : burn_depth;
1180
0
      out += ARIA_BLOCK_SIZE;
1181
0
      in += ARIA_BLOCK_SIZE;
1182
0
      num_blks--;
1183
0
    }
1184
1185
2
  if (burn_depth)
1186
2
    burn_depth += sizeof(void *) * 5;
1187
2
  return burn_depth;
1188
17
}
1189
1190
static unsigned int
1191
aria_enc_blocks (void *c, byte *out, const byte *in, size_t num_blks)
1192
17
{
1193
17
  ARIA_context *ctx = (ARIA_context *)c;
1194
1195
17
  return aria_crypt_blocks (ctx, out, in, num_blks, ctx->enc_key);
1196
17
}
1197
1198
static unsigned int
1199
aria_dec_blocks (void *c, byte *out, const byte *in, size_t num_blks)
1200
0
{
1201
0
  ARIA_context *ctx = (ARIA_context *)c;
1202
1203
0
  return aria_crypt_blocks (ctx, out, in, num_blks, ctx->dec_key);
1204
0
}
1205
1206
1207
/* Bulk encryption of complete blocks in CTR mode.  This function is only
1208
   intended for the bulk encryption feature of cipher.c.  CTR is expected to be
1209
   of size 16. */
1210
static void
1211
_gcry_aria_ctr_enc(void *context, unsigned char *ctr,
1212
       void *outbuf_arg, const void *inbuf_arg,
1213
       size_t nblocks)
1214
17
{
1215
17
  ARIA_context *ctx = context;
1216
17
  byte *outbuf = outbuf_arg;
1217
17
  const byte *inbuf = inbuf_arg;
1218
17
  int burn_stack_depth = 0;
1219
1220
17
#ifdef USE_GFNI_AVX512
1221
17
  if (ctx->use_gfni_avx512)
1222
0
    {
1223
0
      size_t nburn = 0;
1224
1225
0
      while (nblocks >= 64)
1226
0
  {
1227
0
    nburn = aria_gfni_avx512_ctr_crypt_blk64 (ctx, outbuf, inbuf, ctr);
1228
0
    inbuf += 64 * ARIA_BLOCK_SIZE;
1229
0
    outbuf += 64 * ARIA_BLOCK_SIZE;
1230
0
    nblocks -= 64;
1231
0
  }
1232
1233
0
      burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth;
1234
0
    }
1235
17
#endif /* USE_AESNI_AVX */
1236
1237
17
#ifdef USE_AESNI_AVX2
1238
17
  if (ctx->use_aesni_avx2 || ctx->use_gfni_avx2)
1239
17
    {
1240
17
      size_t nburn = 0;
1241
1242
17
      while (nblocks >= 32)
1243
0
  {
1244
0
    nburn = aria_avx2_ctr_crypt_blk32 (ctx, outbuf, inbuf, ctr);
1245
0
    inbuf += 32 * ARIA_BLOCK_SIZE;
1246
0
    outbuf += 32 * ARIA_BLOCK_SIZE;
1247
0
    nblocks -= 32;
1248
0
  }
1249
1250
17
      burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth;
1251
17
    }
1252
17
#endif /* USE_AESNI_AVX */
1253
1254
17
#ifdef USE_AESNI_AVX
1255
17
  if (ctx->use_aesni_avx || ctx->use_gfni_avx)
1256
17
    {
1257
17
      size_t nburn = 0;
1258
1259
17
      while (nblocks >= 16)
1260
0
  {
1261
0
    nburn = aria_avx_ctr_crypt_blk16 (ctx, outbuf, inbuf, ctr);
1262
0
    inbuf += 16 * ARIA_BLOCK_SIZE;
1263
0
    outbuf += 16 * ARIA_BLOCK_SIZE;
1264
0
    nblocks -= 16;
1265
0
  }
1266
1267
17
      burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth;
1268
17
    }
1269
17
#endif /* USE_AESNI_AVX */
1270
1271
  /* Process remaining blocks. */
1272
17
  if (nblocks)
1273
17
    {
1274
17
      byte tmpbuf[MAX_PARALLEL_BLKS * ARIA_BLOCK_SIZE];
1275
17
      unsigned int tmp_used = ARIA_BLOCK_SIZE;
1276
17
      size_t nburn = 0;
1277
1278
17
      ctx->bulk_prefetch_ready = 0;
1279
1280
17
      nburn = bulk_ctr_enc_128(ctx, aria_enc_blocks, outbuf, inbuf,
1281
17
             nblocks, ctr, tmpbuf,
1282
17
             sizeof(tmpbuf) / ARIA_BLOCK_SIZE, &tmp_used);
1283
17
      burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth;
1284
1285
17
      wipememory (tmpbuf, tmp_used);
1286
17
    }
1287
1288
17
  if (burn_stack_depth)
1289
17
    _gcry_burn_stack (burn_stack_depth);
1290
17
}
1291
1292
/* Bulk encryption of complete blocks in CBC mode. */
1293
static void
1294
_gcry_aria_cbc_enc (void *context, unsigned char *iv,
1295
        void *outbuf_arg, const void *inbuf_arg,
1296
        size_t nblocks, int cbc_mac)
1297
45
{
1298
45
  ARIA_context *ctx = context;
1299
45
  unsigned char *outbuf = outbuf_arg;
1300
45
  const unsigned char *inbuf = inbuf_arg;
1301
45
  unsigned char *last_iv;
1302
45
  unsigned int burn_depth = 0;
1303
1304
45
  prefetch_sboxes();
1305
1306
45
  last_iv = iv;
1307
1308
6.15k
  for (; nblocks; nblocks--)
1309
6.10k
    {
1310
6.10k
      cipher_block_xor (outbuf, inbuf, last_iv, ARIA_BLOCK_SIZE);
1311
1312
6.10k
      burn_depth = aria_crypt (ctx, outbuf, outbuf, ctx->enc_key);
1313
1314
6.10k
      last_iv = outbuf;
1315
6.10k
      inbuf += ARIA_BLOCK_SIZE;
1316
6.10k
      if (!cbc_mac)
1317
0
  outbuf += ARIA_BLOCK_SIZE;
1318
6.10k
    }
1319
1320
45
  if (last_iv != iv)
1321
45
    cipher_block_cpy (iv, last_iv, ARIA_BLOCK_SIZE);
1322
1323
45
  if (burn_depth)
1324
45
    _gcry_burn_stack (burn_depth + 4 * sizeof(void *));
1325
45
}
1326
1327
/* Bulk decryption of complete blocks in CBC mode.  This function is only
1328
   intended for the bulk encryption feature of cipher.c. */
1329
static void
1330
_gcry_aria_cbc_dec(void *context, unsigned char *iv,
1331
       void *outbuf_arg, const void *inbuf_arg,
1332
       size_t nblocks)
1333
0
{
1334
0
  ARIA_context *ctx = context;
1335
0
  unsigned char *outbuf = outbuf_arg;
1336
0
  const unsigned char *inbuf = inbuf_arg;
1337
0
  int burn_stack_depth = 0;
1338
1339
0
  if (!ctx->decryption_prepared)
1340
0
    {
1341
0
      aria_set_decrypt_key (ctx);
1342
0
      ctx->decryption_prepared = 1;
1343
0
    }
1344
1345
  /* Process remaining blocks. */
1346
0
  if (nblocks)
1347
0
    {
1348
0
      unsigned char tmpbuf[MAX_PARALLEL_BLKS * ARIA_BLOCK_SIZE];
1349
0
      unsigned int tmp_used = ARIA_BLOCK_SIZE;
1350
0
      size_t nburn;
1351
1352
0
      ctx->bulk_prefetch_ready = 0;
1353
1354
0
      nburn = bulk_cbc_dec_128(ctx, aria_dec_blocks, outbuf, inbuf,
1355
0
             nblocks, iv, tmpbuf,
1356
0
             sizeof(tmpbuf) / ARIA_BLOCK_SIZE, &tmp_used);
1357
0
      burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth;
1358
1359
0
      wipememory (tmpbuf, tmp_used);
1360
0
    }
1361
1362
0
  if (burn_stack_depth)
1363
0
    _gcry_burn_stack (burn_stack_depth);
1364
0
}
1365
1366
/* Bulk encryption of complete blocks in CFB mode. */
1367
static void
1368
_gcry_aria_cfb_enc (void *context, unsigned char *iv,
1369
        void *outbuf_arg, const void *inbuf_arg,
1370
        size_t nblocks)
1371
0
{
1372
0
  ARIA_context *ctx = context;
1373
0
  unsigned char *outbuf = outbuf_arg;
1374
0
  const unsigned char *inbuf = inbuf_arg;
1375
0
  unsigned int burn_depth = 0;
1376
1377
0
  prefetch_sboxes();
1378
1379
0
  for (; nblocks; nblocks--)
1380
0
    {
1381
      /* Encrypt the IV. */
1382
0
      burn_depth = aria_crypt (ctx, iv, iv, ctx->enc_key);
1383
      /* XOR the input with the IV and store input into IV.  */
1384
0
      cipher_block_xor_2dst(outbuf, iv, inbuf, ARIA_BLOCK_SIZE);
1385
0
      outbuf += ARIA_BLOCK_SIZE;
1386
0
      inbuf += ARIA_BLOCK_SIZE;
1387
0
    }
1388
1389
0
  if (burn_depth)
1390
0
    _gcry_burn_stack (burn_depth + 4 * sizeof(void *));
1391
0
}
1392
1393
/* Bulk decryption of complete blocks in CFB mode.  This function is only
1394
   intended for the bulk encryption feature of cipher.c. */
1395
static void
1396
_gcry_aria_cfb_dec(void *context, unsigned char *iv,
1397
       void *outbuf_arg, const void *inbuf_arg,
1398
       size_t nblocks)
1399
0
{
1400
0
  ARIA_context *ctx = context;
1401
0
  unsigned char *outbuf = outbuf_arg;
1402
0
  const unsigned char *inbuf = inbuf_arg;
1403
0
  int burn_stack_depth = 0;
1404
1405
  /* Process remaining blocks. */
1406
0
  if (nblocks)
1407
0
    {
1408
0
      unsigned char tmpbuf[MAX_PARALLEL_BLKS * ARIA_BLOCK_SIZE];
1409
0
      unsigned int tmp_used = ARIA_BLOCK_SIZE;
1410
0
      size_t nburn;
1411
1412
0
      ctx->bulk_prefetch_ready = 0;
1413
1414
0
      nburn = bulk_cfb_dec_128(ctx, aria_enc_blocks, outbuf, inbuf,
1415
0
             nblocks, iv, tmpbuf,
1416
0
             sizeof(tmpbuf) / ARIA_BLOCK_SIZE, &tmp_used);
1417
0
      burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth;
1418
1419
0
      wipememory (tmpbuf, tmp_used);
1420
0
    }
1421
1422
0
  if (burn_stack_depth)
1423
0
    _gcry_burn_stack (burn_stack_depth);
1424
0
}
1425
1426
/* Bulk encryption/decryption in ECB mode. */
1427
static void
1428
_gcry_aria_ecb_crypt (void *context, void *outbuf_arg,
1429
          const void *inbuf_arg, size_t nblocks, int encrypt)
1430
0
{
1431
0
  ARIA_context *ctx = context;
1432
0
  unsigned char *outbuf = outbuf_arg;
1433
0
  const unsigned char *inbuf = inbuf_arg;
1434
0
  int burn_stack_depth = 0;
1435
1436
0
  if (!encrypt && !ctx->decryption_prepared)
1437
0
    {
1438
0
      aria_set_decrypt_key (ctx);
1439
0
      ctx->decryption_prepared = 1;
1440
0
    }
1441
1442
  /* Process remaining blocks. */
1443
0
  if (nblocks)
1444
0
    {
1445
0
      bulk_crypt_fn_t crypt_blk1_n;
1446
0
      size_t nburn;
1447
1448
0
      ctx->bulk_prefetch_ready = 0;
1449
0
      crypt_blk1_n = encrypt ? aria_enc_blocks : aria_dec_blocks;
1450
1451
0
      nburn = bulk_ecb_crypt_128(ctx, crypt_blk1_n,
1452
0
         outbuf, inbuf, nblocks, MAX_PARALLEL_BLKS);
1453
0
      burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth;
1454
0
    }
1455
1456
0
  if (burn_stack_depth)
1457
0
    _gcry_burn_stack (burn_stack_depth);
1458
0
}
1459
1460
/* Bulk encryption/decryption of complete blocks in XTS mode. */
1461
static void
1462
_gcry_aria_xts_crypt (void *context, unsigned char *tweak, void *outbuf_arg,
1463
          const void *inbuf_arg, size_t nblocks, int encrypt)
1464
0
{
1465
0
  ARIA_context *ctx = context;
1466
0
  unsigned char *outbuf = outbuf_arg;
1467
0
  const unsigned char *inbuf = inbuf_arg;
1468
0
  int burn_stack_depth = 0;
1469
1470
0
  if (!encrypt && !ctx->decryption_prepared)
1471
0
    {
1472
0
      aria_set_decrypt_key (ctx);
1473
0
      ctx->decryption_prepared = 1;
1474
0
    }
1475
1476
  /* Process remaining blocks. */
1477
0
  if (nblocks)
1478
0
    {
1479
0
      unsigned char tmpbuf[MAX_PARALLEL_BLKS * ARIA_BLOCK_SIZE];
1480
0
      unsigned int tmp_used = ARIA_BLOCK_SIZE;
1481
0
      bulk_crypt_fn_t crypt_blk1_n;
1482
0
      size_t nburn;
1483
1484
0
      ctx->bulk_prefetch_ready = 0;
1485
0
      crypt_blk1_n = encrypt ? aria_enc_blocks : aria_dec_blocks;
1486
1487
0
      nburn = bulk_xts_crypt_128(ctx, crypt_blk1_n,
1488
0
         outbuf, inbuf, nblocks,
1489
0
         tweak, tmpbuf,
1490
0
         sizeof(tmpbuf) / ARIA_BLOCK_SIZE,
1491
0
         &tmp_used);
1492
0
      burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth;
1493
1494
0
      wipememory (tmpbuf, tmp_used);
1495
0
    }
1496
1497
0
  if (burn_stack_depth)
1498
0
    _gcry_burn_stack (burn_stack_depth);
1499
0
}
1500
1501
/* Bulk encryption of complete blocks in CTR32LE mode (for GCM-SIV). */
1502
static void
1503
_gcry_aria_ctr32le_enc(void *context, unsigned char *ctr,
1504
           void *outbuf_arg, const void *inbuf_arg,
1505
           size_t nblocks)
1506
0
{
1507
0
  ARIA_context *ctx = context;
1508
0
  byte *outbuf = outbuf_arg;
1509
0
  const byte *inbuf = inbuf_arg;
1510
0
  int burn_stack_depth = 0;
1511
1512
  /* Process remaining blocks. */
1513
0
  if (nblocks)
1514
0
    {
1515
0
      unsigned char tmpbuf[MAX_PARALLEL_BLKS * ARIA_BLOCK_SIZE];
1516
0
      unsigned int tmp_used = ARIA_BLOCK_SIZE;
1517
0
      size_t nburn;
1518
1519
0
      ctx->bulk_prefetch_ready = 0;
1520
1521
0
      nburn = bulk_ctr32le_enc_128 (ctx, aria_enc_blocks, outbuf, inbuf,
1522
0
            nblocks, ctr, tmpbuf,
1523
0
            sizeof(tmpbuf) / ARIA_BLOCK_SIZE,
1524
0
            &tmp_used);
1525
0
      burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth;
1526
1527
0
      wipememory (tmpbuf, tmp_used);
1528
0
    }
1529
1530
0
  if (burn_stack_depth)
1531
0
    _gcry_burn_stack (burn_stack_depth);
1532
0
}
1533
1534
/* Bulk encryption/decryption of complete blocks in OCB mode. */
1535
static size_t
1536
_gcry_aria_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
1537
          const void *inbuf_arg, size_t nblocks, int encrypt)
1538
0
{
1539
0
  ARIA_context *ctx = (void *)&c->context.c;
1540
0
  unsigned char *outbuf = outbuf_arg;
1541
0
  const unsigned char *inbuf = inbuf_arg;
1542
0
  u64 blkn = c->u_mode.ocb.data_nblocks;
1543
0
  int burn_stack_depth = 0;
1544
1545
0
  if (!encrypt && !ctx->decryption_prepared)
1546
0
    {
1547
0
      aria_set_decrypt_key (ctx);
1548
0
      ctx->decryption_prepared = 1;
1549
0
    }
1550
1551
  /* Process remaining blocks. */
1552
0
  if (nblocks)
1553
0
    {
1554
0
      unsigned char tmpbuf[MAX_PARALLEL_BLKS * ARIA_BLOCK_SIZE];
1555
0
      unsigned int tmp_used = ARIA_BLOCK_SIZE;
1556
0
      bulk_crypt_fn_t crypt_blk1_n;
1557
0
      size_t nburn;
1558
1559
0
      ctx->bulk_prefetch_ready = 0;
1560
0
      crypt_blk1_n = encrypt ? aria_enc_blocks : aria_dec_blocks;
1561
1562
0
      nburn = bulk_ocb_crypt_128 (c, ctx, crypt_blk1_n, outbuf, inbuf, nblocks,
1563
0
          &blkn, encrypt, tmpbuf,
1564
0
          sizeof(tmpbuf) / ARIA_BLOCK_SIZE,
1565
0
          &tmp_used);
1566
0
      burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth;
1567
1568
0
      wipememory (tmpbuf, tmp_used);
1569
0
    }
1570
1571
0
  c->u_mode.ocb.data_nblocks = blkn;
1572
1573
0
  if (burn_stack_depth)
1574
0
    _gcry_burn_stack (burn_stack_depth);
1575
1576
0
  return 0;
1577
0
}
1578
1579
/* Bulk authentication of complete blocks in OCB mode. */
1580
static size_t
1581
_gcry_aria_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks)
1582
0
{
1583
0
  ARIA_context *ctx = (void *)&c->context.c;
1584
0
  const unsigned char *abuf = abuf_arg;
1585
0
  u64 blkn = c->u_mode.ocb.aad_nblocks;
1586
0
  int burn_stack_depth = 0;
1587
1588
  /* Process remaining blocks. */
1589
0
  if (nblocks)
1590
0
    {
1591
0
      unsigned char tmpbuf[MAX_PARALLEL_BLKS * ARIA_BLOCK_SIZE];
1592
0
      unsigned int tmp_used = ARIA_BLOCK_SIZE;
1593
0
      size_t nburn;
1594
1595
0
      ctx->bulk_prefetch_ready = 0;
1596
1597
0
      nburn = bulk_ocb_auth_128 (c, ctx, aria_enc_blocks, abuf, nblocks,
1598
0
         &blkn, tmpbuf,
1599
0
         sizeof(tmpbuf) / ARIA_BLOCK_SIZE, &tmp_used);
1600
0
      burn_stack_depth = nburn > burn_stack_depth ? nburn : burn_stack_depth;
1601
1602
0
      wipememory (tmpbuf, tmp_used);
1603
0
    }
1604
1605
0
  c->u_mode.ocb.aad_nblocks = blkn;
1606
1607
0
  if (burn_stack_depth)
1608
0
    _gcry_burn_stack (burn_stack_depth);
1609
1610
0
  return 0;
1611
0
}
1612
1613
1614
static gcry_err_code_t
1615
aria_setkey(void *c, const byte *key, unsigned keylen,
1616
      cipher_bulk_ops_t *bulk_ops)
1617
64
{
1618
64
  ARIA_context *ctx = c;
1619
64
  static int initialized = 0;
1620
64
  static const char *selftest_failed = NULL;
1621
64
  unsigned int hwf = _gcry_get_hw_features ();
1622
1623
64
  (void)hwf;
1624
1625
64
  if (keylen != 16 && keylen != 24 && keylen != 32)
1626
18
    return GPG_ERR_INV_KEYLEN;
1627
1628
46
  if (!initialized)
1629
5
    {
1630
5
      initialized = 1;
1631
5
      selftest_failed = aria_selftest ();
1632
5
      if (selftest_failed)
1633
0
  log_error("%s\n", selftest_failed);
1634
5
    }
1635
1636
46
  if (selftest_failed)
1637
0
    return GPG_ERR_SELFTEST_FAILED;
1638
1639
46
#ifdef USE_GFNI_AVX512
1640
46
  ctx->use_gfni_avx512 = (hwf & HWF_INTEL_GFNI) && (hwf & HWF_INTEL_AVX512);
1641
46
#endif
1642
46
#ifdef USE_AESNI_AVX2
1643
46
  ctx->use_aesni_avx2 = (hwf & HWF_INTEL_AESNI) && (hwf & HWF_INTEL_AVX2);
1644
46
#endif
1645
46
#ifdef USE_GFNI_AVX2
1646
46
  ctx->use_gfni_avx2 = (hwf & HWF_INTEL_GFNI) && (hwf & HWF_INTEL_AVX2);
1647
46
#endif
1648
46
#ifdef USE_VAES_AVX2
1649
46
  ctx->use_vaes_avx2 = (hwf & HWF_INTEL_VAES_VPCLMUL) && (hwf & HWF_INTEL_AVX2);
1650
46
#endif
1651
46
#ifdef USE_AESNI_AVX
1652
46
  ctx->use_aesni_avx = (hwf & HWF_INTEL_AESNI) && (hwf & HWF_INTEL_AVX);
1653
46
#endif
1654
46
#ifdef USE_GFNI_AVX
1655
46
  ctx->use_gfni_avx = (hwf & HWF_INTEL_GFNI) && (hwf & HWF_INTEL_AVX);
1656
46
#endif
1657
1658
  /* Setup bulk encryption routines.  */
1659
46
  memset (bulk_ops, 0, sizeof(*bulk_ops));
1660
46
  bulk_ops->cbc_enc = _gcry_aria_cbc_enc;
1661
46
  bulk_ops->cbc_dec = _gcry_aria_cbc_dec;
1662
46
  bulk_ops->cfb_enc = _gcry_aria_cfb_enc;
1663
46
  bulk_ops->cfb_dec = _gcry_aria_cfb_dec;
1664
46
  bulk_ops->ctr_enc = _gcry_aria_ctr_enc;
1665
46
  bulk_ops->ctr32le_enc = _gcry_aria_ctr32le_enc;
1666
46
  bulk_ops->ecb_crypt = _gcry_aria_ecb_crypt;
1667
46
  bulk_ops->xts_crypt = _gcry_aria_xts_crypt;
1668
46
  bulk_ops->ocb_crypt = _gcry_aria_ocb_crypt;
1669
46
  bulk_ops->ocb_auth = _gcry_aria_ocb_auth;
1670
1671
  /* Setup context and encryption key. */
1672
46
  ctx->decryption_prepared = 0;
1673
46
  aria_set_encrypt_key (ctx, key, keylen);
1674
1675
46
  _gcry_burn_stack (3 * sizeof(void *) + 5 * 4 * sizeof(u32));
1676
46
  return 0;
1677
46
}
1678
1679
1680
static const char *
1681
aria_selftest (void)
1682
5
{
1683
5
  ARIA_context ctx;
1684
5
  byte scratch[16];
1685
1686
5
  static const byte key[16] = {
1687
5
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1688
5
    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
1689
5
  };
1690
5
  static const byte plaintext[16] = {
1691
5
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
1692
5
    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
1693
5
  };
1694
5
  static const byte ciphertext[16] = {
1695
5
    0xd7, 0x18, 0xfb, 0xd6, 0xab, 0x64, 0x4c, 0x73,
1696
5
    0x9d, 0xa9, 0x5f, 0x3b, 0xe6, 0x45, 0x17, 0x78
1697
5
  };
1698
1699
5
  memset (&ctx, 0, sizeof(ctx));
1700
1701
5
  aria_set_encrypt_key (&ctx, key, 16);
1702
5
  aria_encrypt (&ctx, scratch, plaintext);
1703
5
  if (memcmp (scratch, ciphertext, sizeof (ciphertext)))
1704
0
    return "ARIA test encryption failed.";
1705
5
  aria_decrypt (&ctx, scratch, scratch);
1706
5
  if (memcmp (scratch, plaintext, sizeof (plaintext)))
1707
0
    return "ARIA test decryption failed.";
1708
1709
5
  return NULL;
1710
5
}
1711
1712
1713
static const gcry_cipher_oid_spec_t aria128_oids[] =
1714
  {
1715
    { "1.2.410.200046.1.1.1", GCRY_CIPHER_MODE_ECB },
1716
    { "1.2.410.200046.1.1.2", GCRY_CIPHER_MODE_CBC },
1717
    { "1.2.410.200046.1.1.3", GCRY_CIPHER_MODE_CFB },
1718
    { "1.2.410.200046.1.1.4", GCRY_CIPHER_MODE_OFB },
1719
    { "1.2.410.200046.1.1.5", GCRY_CIPHER_MODE_CTR },
1720
    { "1.2.410.200046.1.1.34", GCRY_CIPHER_MODE_GCM },
1721
    { "1.2.410.200046.1.1.37", GCRY_CIPHER_MODE_CCM },
1722
    { NULL }
1723
  };
1724
1725
static const gcry_cipher_oid_spec_t aria192_oids[] =
1726
  {
1727
    { "1.2.410.200046.1.1.6", GCRY_CIPHER_MODE_ECB },
1728
    { "1.2.410.200046.1.1.7", GCRY_CIPHER_MODE_CBC },
1729
    { "1.2.410.200046.1.1.8", GCRY_CIPHER_MODE_CFB },
1730
    { "1.2.410.200046.1.1.9", GCRY_CIPHER_MODE_OFB },
1731
    { "1.2.410.200046.1.1.10", GCRY_CIPHER_MODE_CTR },
1732
    { "1.2.410.200046.1.1.35", GCRY_CIPHER_MODE_GCM },
1733
    { "1.2.410.200046.1.1.38", GCRY_CIPHER_MODE_CCM },
1734
    { NULL }
1735
  };
1736
1737
static const gcry_cipher_oid_spec_t aria256_oids[] =
1738
  {
1739
    { "1.2.410.200046.1.1.11", GCRY_CIPHER_MODE_ECB },
1740
    { "1.2.410.200046.1.1.12", GCRY_CIPHER_MODE_CBC },
1741
    { "1.2.410.200046.1.1.13", GCRY_CIPHER_MODE_CFB },
1742
    { "1.2.410.200046.1.1.14", GCRY_CIPHER_MODE_OFB },
1743
    { "1.2.410.200046.1.1.15", GCRY_CIPHER_MODE_CTR },
1744
    { "1.2.410.200046.1.1.36", GCRY_CIPHER_MODE_GCM },
1745
    { "1.2.410.200046.1.1.39", GCRY_CIPHER_MODE_CCM },
1746
    { NULL }
1747
  };
1748
1749
gcry_cipher_spec_t _gcry_cipher_spec_aria128 =
1750
  {
1751
    GCRY_CIPHER_ARIA128, { 0, 0 },
1752
    "ARIA128", NULL, aria128_oids, ARIA_BLOCK_SIZE, 128,
1753
    sizeof(ARIA_context), aria_setkey, aria_encrypt, aria_decrypt
1754
  };
1755
1756
gcry_cipher_spec_t _gcry_cipher_spec_aria192 =
1757
  {
1758
    GCRY_CIPHER_ARIA192, { 0, 0 },
1759
    "ARIA192",NULL,aria192_oids, ARIA_BLOCK_SIZE, 192,
1760
    sizeof(ARIA_context), aria_setkey, aria_encrypt, aria_decrypt
1761
  };
1762
1763
gcry_cipher_spec_t _gcry_cipher_spec_aria256 =
1764
  {
1765
    GCRY_CIPHER_ARIA256, { 0, 0 },
1766
    "ARIA256", NULL, aria256_oids, ARIA_BLOCK_SIZE, 256,
1767
    sizeof(ARIA_context), aria_setkey, aria_encrypt, aria_decrypt
1768
  };