Coverage Report

Created: 2025-06-13 06:58

/src/openssl31/crypto/aria/aria.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
3
 * Copyright (c) 2017, Oracle and/or its affiliates.  All rights reserved.
4
 *
5
 * Licensed under the Apache License 2.0 (the "License").  You may not use
6
 * this file except in compliance with the License.  You can obtain a copy
7
 * in the file LICENSE in the source distribution or at
8
 * https://www.openssl.org/source/license.html
9
 */
10
11
/*
12
 * Copyright (C) 2017 National Security Research Institute. All Rights Reserved.
13
 *
14
 * Information for ARIA
15
 *     http://210.104.33.10/ARIA/index-e.html (English)
16
 *     http://seed.kisa.or.kr/ (Korean)
17
 *
18
 * Public domain version is distributed above.
19
 */
20
21
#include <openssl/e_os2.h>
22
#include "crypto/aria.h"
23
24
#include <assert.h>
25
#include <string.h>
26
27
#ifndef OPENSSL_SMALL_FOOTPRINT
28
29
/* Begin macro */
30
31
/* rotation */
32
#define rotl32(v, r) (((uint32_t)(v) << (r)) | ((uint32_t)(v) >> (32 - r)))
33
477k
#define rotr32(v, r) (((uint32_t)(v) >> (r)) | ((uint32_t)(v) << (32 - r)))
34
35
#define bswap32(v)                                          \
36
477k
    (((v) << 24) ^ ((v) >> 24) ^                            \
37
477k
    (((v) & 0x0000ff00) << 8) ^ (((v) & 0x00ff0000) >> 8))
38
39
8.22M
#define GET_U8_BE(X, Y) ((uint8_t)((X) >> ((3 - Y) * 8)))
40
151k
#define GET_U32_BE(X, Y) (                                  \
41
151k
    ((uint32_t)((const uint8_t *)(X))[Y * 4    ] << 24) ^   \
42
151k
    ((uint32_t)((const uint8_t *)(X))[Y * 4 + 1] << 16) ^   \
43
151k
    ((uint32_t)((const uint8_t *)(X))[Y * 4 + 2] <<  8) ^   \
44
151k
    ((uint32_t)((const uint8_t *)(X))[Y * 4 + 3]      )     )
45
46
#define PUT_U32_BE(DEST, IDX, VAL)                              \
47
146k
    do {                                                        \
48
146k
        ((uint8_t *)(DEST))[IDX * 4    ] = GET_U8_BE(VAL, 0);   \
49
146k
        ((uint8_t *)(DEST))[IDX * 4 + 1] = GET_U8_BE(VAL, 1);   \
50
146k
        ((uint8_t *)(DEST))[IDX * 4 + 2] = GET_U8_BE(VAL, 2);   \
51
146k
        ((uint8_t *)(DEST))[IDX * 4 + 3] = GET_U8_BE(VAL, 3);   \
52
146k
    } while(0)
53
54
146k
#define MAKE_U32(V0, V1, V2, V3) (      \
55
146k
    ((uint32_t)((uint8_t)(V0)) << 24) | \
56
146k
    ((uint32_t)((uint8_t)(V1)) << 16) | \
57
146k
    ((uint32_t)((uint8_t)(V2)) <<  8) | \
58
146k
    ((uint32_t)((uint8_t)(V3))      )   )
59
60
/* End Macro*/
61
62
/* Key Constant
63
 * 128bit : 0, 1,    2
64
 * 192bit : 1, 2,    3(0)
65
 * 256bit : 2, 3(0), 4(1)
66
 */
67
static const uint32_t Key_RC[5][4] = {
68
    { 0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0 },
69
    { 0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0 },
70
    { 0xdb92371d, 0x2126e970, 0x03249775, 0x04e8c90e },
71
    { 0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0 },
72
    { 0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0 }
73
};
74
75
/* 32bit expanded s-box */
76
static const uint32_t S1[256] = {
77
    0x00636363, 0x007c7c7c, 0x00777777, 0x007b7b7b,
78
    0x00f2f2f2, 0x006b6b6b, 0x006f6f6f, 0x00c5c5c5,
79
    0x00303030, 0x00010101, 0x00676767, 0x002b2b2b,
80
    0x00fefefe, 0x00d7d7d7, 0x00ababab, 0x00767676,
81
    0x00cacaca, 0x00828282, 0x00c9c9c9, 0x007d7d7d,
82
    0x00fafafa, 0x00595959, 0x00474747, 0x00f0f0f0,
83
    0x00adadad, 0x00d4d4d4, 0x00a2a2a2, 0x00afafaf,
84
    0x009c9c9c, 0x00a4a4a4, 0x00727272, 0x00c0c0c0,
85
    0x00b7b7b7, 0x00fdfdfd, 0x00939393, 0x00262626,
86
    0x00363636, 0x003f3f3f, 0x00f7f7f7, 0x00cccccc,
87
    0x00343434, 0x00a5a5a5, 0x00e5e5e5, 0x00f1f1f1,
88
    0x00717171, 0x00d8d8d8, 0x00313131, 0x00151515,
89
    0x00040404, 0x00c7c7c7, 0x00232323, 0x00c3c3c3,
90
    0x00181818, 0x00969696, 0x00050505, 0x009a9a9a,
91
    0x00070707, 0x00121212, 0x00808080, 0x00e2e2e2,
92
    0x00ebebeb, 0x00272727, 0x00b2b2b2, 0x00757575,
93
    0x00090909, 0x00838383, 0x002c2c2c, 0x001a1a1a,
94
    0x001b1b1b, 0x006e6e6e, 0x005a5a5a, 0x00a0a0a0,
95
    0x00525252, 0x003b3b3b, 0x00d6d6d6, 0x00b3b3b3,
96
    0x00292929, 0x00e3e3e3, 0x002f2f2f, 0x00848484,
97
    0x00535353, 0x00d1d1d1, 0x00000000, 0x00ededed,
98
    0x00202020, 0x00fcfcfc, 0x00b1b1b1, 0x005b5b5b,
99
    0x006a6a6a, 0x00cbcbcb, 0x00bebebe, 0x00393939,
100
    0x004a4a4a, 0x004c4c4c, 0x00585858, 0x00cfcfcf,
101
    0x00d0d0d0, 0x00efefef, 0x00aaaaaa, 0x00fbfbfb,
102
    0x00434343, 0x004d4d4d, 0x00333333, 0x00858585,
103
    0x00454545, 0x00f9f9f9, 0x00020202, 0x007f7f7f,
104
    0x00505050, 0x003c3c3c, 0x009f9f9f, 0x00a8a8a8,
105
    0x00515151, 0x00a3a3a3, 0x00404040, 0x008f8f8f,
106
    0x00929292, 0x009d9d9d, 0x00383838, 0x00f5f5f5,
107
    0x00bcbcbc, 0x00b6b6b6, 0x00dadada, 0x00212121,
108
    0x00101010, 0x00ffffff, 0x00f3f3f3, 0x00d2d2d2,
109
    0x00cdcdcd, 0x000c0c0c, 0x00131313, 0x00ececec,
110
    0x005f5f5f, 0x00979797, 0x00444444, 0x00171717,
111
    0x00c4c4c4, 0x00a7a7a7, 0x007e7e7e, 0x003d3d3d,
112
    0x00646464, 0x005d5d5d, 0x00191919, 0x00737373,
113
    0x00606060, 0x00818181, 0x004f4f4f, 0x00dcdcdc,
114
    0x00222222, 0x002a2a2a, 0x00909090, 0x00888888,
115
    0x00464646, 0x00eeeeee, 0x00b8b8b8, 0x00141414,
116
    0x00dedede, 0x005e5e5e, 0x000b0b0b, 0x00dbdbdb,
117
    0x00e0e0e0, 0x00323232, 0x003a3a3a, 0x000a0a0a,
118
    0x00494949, 0x00060606, 0x00242424, 0x005c5c5c,
119
    0x00c2c2c2, 0x00d3d3d3, 0x00acacac, 0x00626262,
120
    0x00919191, 0x00959595, 0x00e4e4e4, 0x00797979,
121
    0x00e7e7e7, 0x00c8c8c8, 0x00373737, 0x006d6d6d,
122
    0x008d8d8d, 0x00d5d5d5, 0x004e4e4e, 0x00a9a9a9,
123
    0x006c6c6c, 0x00565656, 0x00f4f4f4, 0x00eaeaea,
124
    0x00656565, 0x007a7a7a, 0x00aeaeae, 0x00080808,
125
    0x00bababa, 0x00787878, 0x00252525, 0x002e2e2e,
126
    0x001c1c1c, 0x00a6a6a6, 0x00b4b4b4, 0x00c6c6c6,
127
    0x00e8e8e8, 0x00dddddd, 0x00747474, 0x001f1f1f,
128
    0x004b4b4b, 0x00bdbdbd, 0x008b8b8b, 0x008a8a8a,
129
    0x00707070, 0x003e3e3e, 0x00b5b5b5, 0x00666666,
130
    0x00484848, 0x00030303, 0x00f6f6f6, 0x000e0e0e,
131
    0x00616161, 0x00353535, 0x00575757, 0x00b9b9b9,
132
    0x00868686, 0x00c1c1c1, 0x001d1d1d, 0x009e9e9e,
133
    0x00e1e1e1, 0x00f8f8f8, 0x00989898, 0x00111111,
134
    0x00696969, 0x00d9d9d9, 0x008e8e8e, 0x00949494,
135
    0x009b9b9b, 0x001e1e1e, 0x00878787, 0x00e9e9e9,
136
    0x00cecece, 0x00555555, 0x00282828, 0x00dfdfdf,
137
    0x008c8c8c, 0x00a1a1a1, 0x00898989, 0x000d0d0d,
138
    0x00bfbfbf, 0x00e6e6e6, 0x00424242, 0x00686868,
139
    0x00414141, 0x00999999, 0x002d2d2d, 0x000f0f0f,
140
    0x00b0b0b0, 0x00545454, 0x00bbbbbb, 0x00161616
141
};
142
143
static const uint32_t S2[256] = {
144
    0xe200e2e2, 0x4e004e4e, 0x54005454, 0xfc00fcfc,
145
    0x94009494, 0xc200c2c2, 0x4a004a4a, 0xcc00cccc,
146
    0x62006262, 0x0d000d0d, 0x6a006a6a, 0x46004646,
147
    0x3c003c3c, 0x4d004d4d, 0x8b008b8b, 0xd100d1d1,
148
    0x5e005e5e, 0xfa00fafa, 0x64006464, 0xcb00cbcb,
149
    0xb400b4b4, 0x97009797, 0xbe00bebe, 0x2b002b2b,
150
    0xbc00bcbc, 0x77007777, 0x2e002e2e, 0x03000303,
151
    0xd300d3d3, 0x19001919, 0x59005959, 0xc100c1c1,
152
    0x1d001d1d, 0x06000606, 0x41004141, 0x6b006b6b,
153
    0x55005555, 0xf000f0f0, 0x99009999, 0x69006969,
154
    0xea00eaea, 0x9c009c9c, 0x18001818, 0xae00aeae,
155
    0x63006363, 0xdf00dfdf, 0xe700e7e7, 0xbb00bbbb,
156
    0x00000000, 0x73007373, 0x66006666, 0xfb00fbfb,
157
    0x96009696, 0x4c004c4c, 0x85008585, 0xe400e4e4,
158
    0x3a003a3a, 0x09000909, 0x45004545, 0xaa00aaaa,
159
    0x0f000f0f, 0xee00eeee, 0x10001010, 0xeb00ebeb,
160
    0x2d002d2d, 0x7f007f7f, 0xf400f4f4, 0x29002929,
161
    0xac00acac, 0xcf00cfcf, 0xad00adad, 0x91009191,
162
    0x8d008d8d, 0x78007878, 0xc800c8c8, 0x95009595,
163
    0xf900f9f9, 0x2f002f2f, 0xce00cece, 0xcd00cdcd,
164
    0x08000808, 0x7a007a7a, 0x88008888, 0x38003838,
165
    0x5c005c5c, 0x83008383, 0x2a002a2a, 0x28002828,
166
    0x47004747, 0xdb00dbdb, 0xb800b8b8, 0xc700c7c7,
167
    0x93009393, 0xa400a4a4, 0x12001212, 0x53005353,
168
    0xff00ffff, 0x87008787, 0x0e000e0e, 0x31003131,
169
    0x36003636, 0x21002121, 0x58005858, 0x48004848,
170
    0x01000101, 0x8e008e8e, 0x37003737, 0x74007474,
171
    0x32003232, 0xca00caca, 0xe900e9e9, 0xb100b1b1,
172
    0xb700b7b7, 0xab00abab, 0x0c000c0c, 0xd700d7d7,
173
    0xc400c4c4, 0x56005656, 0x42004242, 0x26002626,
174
    0x07000707, 0x98009898, 0x60006060, 0xd900d9d9,
175
    0xb600b6b6, 0xb900b9b9, 0x11001111, 0x40004040,
176
    0xec00ecec, 0x20002020, 0x8c008c8c, 0xbd00bdbd,
177
    0xa000a0a0, 0xc900c9c9, 0x84008484, 0x04000404,
178
    0x49004949, 0x23002323, 0xf100f1f1, 0x4f004f4f,
179
    0x50005050, 0x1f001f1f, 0x13001313, 0xdc00dcdc,
180
    0xd800d8d8, 0xc000c0c0, 0x9e009e9e, 0x57005757,
181
    0xe300e3e3, 0xc300c3c3, 0x7b007b7b, 0x65006565,
182
    0x3b003b3b, 0x02000202, 0x8f008f8f, 0x3e003e3e,
183
    0xe800e8e8, 0x25002525, 0x92009292, 0xe500e5e5,
184
    0x15001515, 0xdd00dddd, 0xfd00fdfd, 0x17001717,
185
    0xa900a9a9, 0xbf00bfbf, 0xd400d4d4, 0x9a009a9a,
186
    0x7e007e7e, 0xc500c5c5, 0x39003939, 0x67006767,
187
    0xfe00fefe, 0x76007676, 0x9d009d9d, 0x43004343,
188
    0xa700a7a7, 0xe100e1e1, 0xd000d0d0, 0xf500f5f5,
189
    0x68006868, 0xf200f2f2, 0x1b001b1b, 0x34003434,
190
    0x70007070, 0x05000505, 0xa300a3a3, 0x8a008a8a,
191
    0xd500d5d5, 0x79007979, 0x86008686, 0xa800a8a8,
192
    0x30003030, 0xc600c6c6, 0x51005151, 0x4b004b4b,
193
    0x1e001e1e, 0xa600a6a6, 0x27002727, 0xf600f6f6,
194
    0x35003535, 0xd200d2d2, 0x6e006e6e, 0x24002424,
195
    0x16001616, 0x82008282, 0x5f005f5f, 0xda00dada,
196
    0xe600e6e6, 0x75007575, 0xa200a2a2, 0xef00efef,
197
    0x2c002c2c, 0xb200b2b2, 0x1c001c1c, 0x9f009f9f,
198
    0x5d005d5d, 0x6f006f6f, 0x80008080, 0x0a000a0a,
199
    0x72007272, 0x44004444, 0x9b009b9b, 0x6c006c6c,
200
    0x90009090, 0x0b000b0b, 0x5b005b5b, 0x33003333,
201
    0x7d007d7d, 0x5a005a5a, 0x52005252, 0xf300f3f3,
202
    0x61006161, 0xa100a1a1, 0xf700f7f7, 0xb000b0b0,
203
    0xd600d6d6, 0x3f003f3f, 0x7c007c7c, 0x6d006d6d,
204
    0xed00eded, 0x14001414, 0xe000e0e0, 0xa500a5a5,
205
    0x3d003d3d, 0x22002222, 0xb300b3b3, 0xf800f8f8,
206
    0x89008989, 0xde00dede, 0x71007171, 0x1a001a1a,
207
    0xaf00afaf, 0xba00baba, 0xb500b5b5, 0x81008181
208
};
209
210
static const uint32_t X1[256] = {
211
    0x52520052, 0x09090009, 0x6a6a006a, 0xd5d500d5,
212
    0x30300030, 0x36360036, 0xa5a500a5, 0x38380038,
213
    0xbfbf00bf, 0x40400040, 0xa3a300a3, 0x9e9e009e,
214
    0x81810081, 0xf3f300f3, 0xd7d700d7, 0xfbfb00fb,
215
    0x7c7c007c, 0xe3e300e3, 0x39390039, 0x82820082,
216
    0x9b9b009b, 0x2f2f002f, 0xffff00ff, 0x87870087,
217
    0x34340034, 0x8e8e008e, 0x43430043, 0x44440044,
218
    0xc4c400c4, 0xdede00de, 0xe9e900e9, 0xcbcb00cb,
219
    0x54540054, 0x7b7b007b, 0x94940094, 0x32320032,
220
    0xa6a600a6, 0xc2c200c2, 0x23230023, 0x3d3d003d,
221
    0xeeee00ee, 0x4c4c004c, 0x95950095, 0x0b0b000b,
222
    0x42420042, 0xfafa00fa, 0xc3c300c3, 0x4e4e004e,
223
    0x08080008, 0x2e2e002e, 0xa1a100a1, 0x66660066,
224
    0x28280028, 0xd9d900d9, 0x24240024, 0xb2b200b2,
225
    0x76760076, 0x5b5b005b, 0xa2a200a2, 0x49490049,
226
    0x6d6d006d, 0x8b8b008b, 0xd1d100d1, 0x25250025,
227
    0x72720072, 0xf8f800f8, 0xf6f600f6, 0x64640064,
228
    0x86860086, 0x68680068, 0x98980098, 0x16160016,
229
    0xd4d400d4, 0xa4a400a4, 0x5c5c005c, 0xcccc00cc,
230
    0x5d5d005d, 0x65650065, 0xb6b600b6, 0x92920092,
231
    0x6c6c006c, 0x70700070, 0x48480048, 0x50500050,
232
    0xfdfd00fd, 0xeded00ed, 0xb9b900b9, 0xdada00da,
233
    0x5e5e005e, 0x15150015, 0x46460046, 0x57570057,
234
    0xa7a700a7, 0x8d8d008d, 0x9d9d009d, 0x84840084,
235
    0x90900090, 0xd8d800d8, 0xabab00ab, 0x00000000,
236
    0x8c8c008c, 0xbcbc00bc, 0xd3d300d3, 0x0a0a000a,
237
    0xf7f700f7, 0xe4e400e4, 0x58580058, 0x05050005,
238
    0xb8b800b8, 0xb3b300b3, 0x45450045, 0x06060006,
239
    0xd0d000d0, 0x2c2c002c, 0x1e1e001e, 0x8f8f008f,
240
    0xcaca00ca, 0x3f3f003f, 0x0f0f000f, 0x02020002,
241
    0xc1c100c1, 0xafaf00af, 0xbdbd00bd, 0x03030003,
242
    0x01010001, 0x13130013, 0x8a8a008a, 0x6b6b006b,
243
    0x3a3a003a, 0x91910091, 0x11110011, 0x41410041,
244
    0x4f4f004f, 0x67670067, 0xdcdc00dc, 0xeaea00ea,
245
    0x97970097, 0xf2f200f2, 0xcfcf00cf, 0xcece00ce,
246
    0xf0f000f0, 0xb4b400b4, 0xe6e600e6, 0x73730073,
247
    0x96960096, 0xacac00ac, 0x74740074, 0x22220022,
248
    0xe7e700e7, 0xadad00ad, 0x35350035, 0x85850085,
249
    0xe2e200e2, 0xf9f900f9, 0x37370037, 0xe8e800e8,
250
    0x1c1c001c, 0x75750075, 0xdfdf00df, 0x6e6e006e,
251
    0x47470047, 0xf1f100f1, 0x1a1a001a, 0x71710071,
252
    0x1d1d001d, 0x29290029, 0xc5c500c5, 0x89890089,
253
    0x6f6f006f, 0xb7b700b7, 0x62620062, 0x0e0e000e,
254
    0xaaaa00aa, 0x18180018, 0xbebe00be, 0x1b1b001b,
255
    0xfcfc00fc, 0x56560056, 0x3e3e003e, 0x4b4b004b,
256
    0xc6c600c6, 0xd2d200d2, 0x79790079, 0x20200020,
257
    0x9a9a009a, 0xdbdb00db, 0xc0c000c0, 0xfefe00fe,
258
    0x78780078, 0xcdcd00cd, 0x5a5a005a, 0xf4f400f4,
259
    0x1f1f001f, 0xdddd00dd, 0xa8a800a8, 0x33330033,
260
    0x88880088, 0x07070007, 0xc7c700c7, 0x31310031,
261
    0xb1b100b1, 0x12120012, 0x10100010, 0x59590059,
262
    0x27270027, 0x80800080, 0xecec00ec, 0x5f5f005f,
263
    0x60600060, 0x51510051, 0x7f7f007f, 0xa9a900a9,
264
    0x19190019, 0xb5b500b5, 0x4a4a004a, 0x0d0d000d,
265
    0x2d2d002d, 0xe5e500e5, 0x7a7a007a, 0x9f9f009f,
266
    0x93930093, 0xc9c900c9, 0x9c9c009c, 0xefef00ef,
267
    0xa0a000a0, 0xe0e000e0, 0x3b3b003b, 0x4d4d004d,
268
    0xaeae00ae, 0x2a2a002a, 0xf5f500f5, 0xb0b000b0,
269
    0xc8c800c8, 0xebeb00eb, 0xbbbb00bb, 0x3c3c003c,
270
    0x83830083, 0x53530053, 0x99990099, 0x61610061,
271
    0x17170017, 0x2b2b002b, 0x04040004, 0x7e7e007e,
272
    0xbaba00ba, 0x77770077, 0xd6d600d6, 0x26260026,
273
    0xe1e100e1, 0x69690069, 0x14140014, 0x63630063,
274
    0x55550055, 0x21210021, 0x0c0c000c, 0x7d7d007d
275
};
276
277
static const uint32_t X2[256] = {
278
    0x30303000, 0x68686800, 0x99999900, 0x1b1b1b00,
279
    0x87878700, 0xb9b9b900, 0x21212100, 0x78787800,
280
    0x50505000, 0x39393900, 0xdbdbdb00, 0xe1e1e100,
281
    0x72727200, 0x09090900, 0x62626200, 0x3c3c3c00,
282
    0x3e3e3e00, 0x7e7e7e00, 0x5e5e5e00, 0x8e8e8e00,
283
    0xf1f1f100, 0xa0a0a000, 0xcccccc00, 0xa3a3a300,
284
    0x2a2a2a00, 0x1d1d1d00, 0xfbfbfb00, 0xb6b6b600,
285
    0xd6d6d600, 0x20202000, 0xc4c4c400, 0x8d8d8d00,
286
    0x81818100, 0x65656500, 0xf5f5f500, 0x89898900,
287
    0xcbcbcb00, 0x9d9d9d00, 0x77777700, 0xc6c6c600,
288
    0x57575700, 0x43434300, 0x56565600, 0x17171700,
289
    0xd4d4d400, 0x40404000, 0x1a1a1a00, 0x4d4d4d00,
290
    0xc0c0c000, 0x63636300, 0x6c6c6c00, 0xe3e3e300,
291
    0xb7b7b700, 0xc8c8c800, 0x64646400, 0x6a6a6a00,
292
    0x53535300, 0xaaaaaa00, 0x38383800, 0x98989800,
293
    0x0c0c0c00, 0xf4f4f400, 0x9b9b9b00, 0xededed00,
294
    0x7f7f7f00, 0x22222200, 0x76767600, 0xafafaf00,
295
    0xdddddd00, 0x3a3a3a00, 0x0b0b0b00, 0x58585800,
296
    0x67676700, 0x88888800, 0x06060600, 0xc3c3c300,
297
    0x35353500, 0x0d0d0d00, 0x01010100, 0x8b8b8b00,
298
    0x8c8c8c00, 0xc2c2c200, 0xe6e6e600, 0x5f5f5f00,
299
    0x02020200, 0x24242400, 0x75757500, 0x93939300,
300
    0x66666600, 0x1e1e1e00, 0xe5e5e500, 0xe2e2e200,
301
    0x54545400, 0xd8d8d800, 0x10101000, 0xcecece00,
302
    0x7a7a7a00, 0xe8e8e800, 0x08080800, 0x2c2c2c00,
303
    0x12121200, 0x97979700, 0x32323200, 0xababab00,
304
    0xb4b4b400, 0x27272700, 0x0a0a0a00, 0x23232300,
305
    0xdfdfdf00, 0xefefef00, 0xcacaca00, 0xd9d9d900,
306
    0xb8b8b800, 0xfafafa00, 0xdcdcdc00, 0x31313100,
307
    0x6b6b6b00, 0xd1d1d100, 0xadadad00, 0x19191900,
308
    0x49494900, 0xbdbdbd00, 0x51515100, 0x96969600,
309
    0xeeeeee00, 0xe4e4e400, 0xa8a8a800, 0x41414100,
310
    0xdadada00, 0xffffff00, 0xcdcdcd00, 0x55555500,
311
    0x86868600, 0x36363600, 0xbebebe00, 0x61616100,
312
    0x52525200, 0xf8f8f800, 0xbbbbbb00, 0x0e0e0e00,
313
    0x82828200, 0x48484800, 0x69696900, 0x9a9a9a00,
314
    0xe0e0e000, 0x47474700, 0x9e9e9e00, 0x5c5c5c00,
315
    0x04040400, 0x4b4b4b00, 0x34343400, 0x15151500,
316
    0x79797900, 0x26262600, 0xa7a7a700, 0xdedede00,
317
    0x29292900, 0xaeaeae00, 0x92929200, 0xd7d7d700,
318
    0x84848400, 0xe9e9e900, 0xd2d2d200, 0xbababa00,
319
    0x5d5d5d00, 0xf3f3f300, 0xc5c5c500, 0xb0b0b000,
320
    0xbfbfbf00, 0xa4a4a400, 0x3b3b3b00, 0x71717100,
321
    0x44444400, 0x46464600, 0x2b2b2b00, 0xfcfcfc00,
322
    0xebebeb00, 0x6f6f6f00, 0xd5d5d500, 0xf6f6f600,
323
    0x14141400, 0xfefefe00, 0x7c7c7c00, 0x70707000,
324
    0x5a5a5a00, 0x7d7d7d00, 0xfdfdfd00, 0x2f2f2f00,
325
    0x18181800, 0x83838300, 0x16161600, 0xa5a5a500,
326
    0x91919100, 0x1f1f1f00, 0x05050500, 0x95959500,
327
    0x74747400, 0xa9a9a900, 0xc1c1c100, 0x5b5b5b00,
328
    0x4a4a4a00, 0x85858500, 0x6d6d6d00, 0x13131300,
329
    0x07070700, 0x4f4f4f00, 0x4e4e4e00, 0x45454500,
330
    0xb2b2b200, 0x0f0f0f00, 0xc9c9c900, 0x1c1c1c00,
331
    0xa6a6a600, 0xbcbcbc00, 0xececec00, 0x73737300,
332
    0x90909000, 0x7b7b7b00, 0xcfcfcf00, 0x59595900,
333
    0x8f8f8f00, 0xa1a1a100, 0xf9f9f900, 0x2d2d2d00,
334
    0xf2f2f200, 0xb1b1b100, 0x00000000, 0x94949400,
335
    0x37373700, 0x9f9f9f00, 0xd0d0d000, 0x2e2e2e00,
336
    0x9c9c9c00, 0x6e6e6e00, 0x28282800, 0x3f3f3f00,
337
    0x80808000, 0xf0f0f000, 0x3d3d3d00, 0xd3d3d300,
338
    0x25252500, 0x8a8a8a00, 0xb5b5b500, 0xe7e7e700,
339
    0x42424200, 0xb3b3b300, 0xc7c7c700, 0xeaeaea00,
340
    0xf7f7f700, 0x4c4c4c00, 0x11111100, 0x33333300,
341
    0x03030300, 0xa2a2a200, 0xacacac00, 0x60606000
342
};
343
344
/* Key XOR Layer */
345
#define ARIA_ADD_ROUND_KEY(RK, T0, T1, T2, T3)  \
346
511k
    do {                                        \
347
511k
        (T0) ^= (RK)->u[0];                     \
348
511k
        (T1) ^= (RK)->u[1];                     \
349
511k
        (T2) ^= (RK)->u[2];                     \
350
511k
        (T3) ^= (RK)->u[3];                     \
351
511k
    } while(0)
352
353
/* S-Box Layer 1 + M */
354
#define ARIA_SBOX_LAYER1_WITH_PRE_DIFF(T0, T1, T2, T3)  \
355
257k
    do {                                                \
356
257k
        (T0) =                                          \
357
257k
            S1[GET_U8_BE(T0, 0)] ^                      \
358
257k
            S2[GET_U8_BE(T0, 1)] ^                      \
359
257k
            X1[GET_U8_BE(T0, 2)] ^                      \
360
257k
            X2[GET_U8_BE(T0, 3)];                       \
361
257k
        (T1) =                                          \
362
257k
            S1[GET_U8_BE(T1, 0)] ^                      \
363
257k
            S2[GET_U8_BE(T1, 1)] ^                      \
364
257k
            X1[GET_U8_BE(T1, 2)] ^                      \
365
257k
            X2[GET_U8_BE(T1, 3)];                       \
366
257k
        (T2) =                                          \
367
257k
            S1[GET_U8_BE(T2, 0)] ^                      \
368
257k
            S2[GET_U8_BE(T2, 1)] ^                      \
369
257k
            X1[GET_U8_BE(T2, 2)] ^                      \
370
257k
            X2[GET_U8_BE(T2, 3)];                       \
371
257k
        (T3) =                                          \
372
257k
            S1[GET_U8_BE(T3, 0)] ^                      \
373
257k
            S2[GET_U8_BE(T3, 1)] ^                      \
374
257k
            X1[GET_U8_BE(T3, 2)] ^                      \
375
257k
            X2[GET_U8_BE(T3, 3)];                       \
376
257k
    } while(0)
377
378
/* S-Box Layer 2 + M */
379
#define ARIA_SBOX_LAYER2_WITH_PRE_DIFF(T0, T1, T2, T3)  \
380
220k
    do {                                                \
381
220k
        (T0) =                                          \
382
220k
            X1[GET_U8_BE(T0, 0)] ^                      \
383
220k
            X2[GET_U8_BE(T0, 1)] ^                      \
384
220k
            S1[GET_U8_BE(T0, 2)] ^                      \
385
220k
            S2[GET_U8_BE(T0, 3)];                       \
386
220k
        (T1) =                                          \
387
220k
            X1[GET_U8_BE(T1, 0)] ^                      \
388
220k
            X2[GET_U8_BE(T1, 1)] ^                      \
389
220k
            S1[GET_U8_BE(T1, 2)] ^                      \
390
220k
            S2[GET_U8_BE(T1, 3)];                       \
391
220k
        (T2) =                                          \
392
220k
            X1[GET_U8_BE(T2, 0)] ^                      \
393
220k
            X2[GET_U8_BE(T2, 1)] ^                      \
394
220k
            S1[GET_U8_BE(T2, 2)] ^                      \
395
220k
            S2[GET_U8_BE(T2, 3)];                       \
396
220k
        (T3) =                                          \
397
220k
            X1[GET_U8_BE(T3, 0)] ^                      \
398
220k
            X2[GET_U8_BE(T3, 1)] ^                      \
399
220k
            S1[GET_U8_BE(T3, 2)] ^                      \
400
220k
            S2[GET_U8_BE(T3, 3)];                       \
401
220k
    } while(0)
402
403
/* Word-level diffusion */
404
#define ARIA_DIFF_WORD(T0,T1,T2,T3) \
405
955k
    do {                            \
406
955k
        (T1) ^= (T2);               \
407
955k
        (T2) ^= (T3);               \
408
955k
        (T0) ^= (T1);               \
409
955k
                                    \
410
955k
        (T3) ^= (T1);               \
411
955k
        (T2) ^= (T0);               \
412
955k
        (T1) ^= (T2);               \
413
955k
    } while(0)
414
415
/* Byte-level diffusion */
416
#define ARIA_DIFF_BYTE(T0, T1, T2, T3)                                  \
417
477k
    do {                                                                \
418
477k
        (T1) = (((T1) << 8) & 0xff00ff00) ^ (((T1) >> 8) & 0x00ff00ff); \
419
477k
        (T2) = rotr32(T2, 16);                                          \
420
477k
        (T3) = bswap32(T3);                                             \
421
477k
    } while(0)
422
423
/* Odd round Substitution & Diffusion */
424
#define ARIA_SUBST_DIFF_ODD(T0, T1, T2, T3)             \
425
257k
    do {                                                \
426
257k
        ARIA_SBOX_LAYER1_WITH_PRE_DIFF(T0, T1, T2, T3); \
427
257k
        ARIA_DIFF_WORD(T0, T1, T2, T3);                 \
428
257k
        ARIA_DIFF_BYTE(T0, T1, T2, T3);                 \
429
257k
        ARIA_DIFF_WORD(T0, T1, T2, T3);                 \
430
257k
    } while(0)
431
432
/* Even round Substitution & Diffusion */
433
#define ARIA_SUBST_DIFF_EVEN(T0, T1, T2, T3)            \
434
220k
    do {                                                \
435
220k
        ARIA_SBOX_LAYER2_WITH_PRE_DIFF(T0, T1, T2, T3); \
436
220k
        ARIA_DIFF_WORD(T0, T1, T2, T3);                 \
437
220k
        ARIA_DIFF_BYTE(T2, T3, T0, T1);                 \
438
220k
        ARIA_DIFF_WORD(T0, T1, T2, T3);                 \
439
220k
    } while(0)
440
441
/* Q, R Macro expanded ARIA GSRK */
442
#define _ARIA_GSRK(RK, X, Y, Q, R)                  \
443
13.5k
    do {                                            \
444
13.5k
        (RK)->u[0] =                                \
445
13.5k
            ((X)[0]) ^                              \
446
13.5k
            (((Y)[((Q)    ) % 4]) >> (R)) ^         \
447
13.5k
            (((Y)[((Q) + 3) % 4]) << (32 - (R)));   \
448
13.5k
        (RK)->u[1] =                                \
449
13.5k
            ((X)[1]) ^                              \
450
13.5k
            (((Y)[((Q) + 1) % 4]) >> (R)) ^         \
451
13.5k
            (((Y)[((Q)    ) % 4]) << (32 - (R)));   \
452
13.5k
        (RK)->u[2] =                                \
453
13.5k
            ((X)[2]) ^                              \
454
13.5k
            (((Y)[((Q) + 2) % 4]) >> (R)) ^         \
455
13.5k
            (((Y)[((Q) + 1) % 4]) << (32 - (R)));   \
456
13.5k
        (RK)->u[3] =                                \
457
13.5k
            ((X)[3]) ^                              \
458
13.5k
            (((Y)[((Q) + 3) % 4]) >> (R)) ^         \
459
13.5k
            (((Y)[((Q) + 2) % 4]) << (32 - (R)));   \
460
13.5k
    } while(0)
461
462
13.5k
#define ARIA_GSRK(RK, X, Y, N) _ARIA_GSRK(RK, X, Y, 4 - ((N) / 32), (N) % 32)
463
464
#define ARIA_DEC_DIFF_BYTE(X, Y, TMP, TMP2)         \
465
0
    do {                                            \
466
0
        (TMP) = (X);                                \
467
0
        (TMP2) = rotr32((TMP), 8);                  \
468
0
        (Y) = (TMP2) ^ rotr32((TMP) ^ (TMP2), 16);  \
469
0
    } while(0)
470
471
void ossl_aria_encrypt(const unsigned char *in, unsigned char *out,
472
                       const ARIA_KEY *key)
473
36.5k
{
474
36.5k
    register uint32_t reg0, reg1, reg2, reg3;
475
36.5k
    int Nr;
476
36.5k
    const ARIA_u128 *rk;
477
478
36.5k
    if (in == NULL || out == NULL || key == NULL) {
479
0
        return;
480
0
    }
481
482
36.5k
    rk = key->rd_key;
483
36.5k
    Nr = key->rounds;
484
485
36.5k
    if (Nr != 12 && Nr != 14 && Nr != 16) {
486
0
        return;
487
0
    }
488
489
36.5k
    reg0 = GET_U32_BE(in, 0);
490
36.5k
    reg1 = GET_U32_BE(in, 1);
491
36.5k
    reg2 = GET_U32_BE(in, 2);
492
36.5k
    reg3 = GET_U32_BE(in, 3);
493
494
36.5k
    ARIA_ADD_ROUND_KEY(rk, reg0, reg1, reg2, reg3);
495
36.5k
    rk++;
496
497
36.5k
    ARIA_SUBST_DIFF_ODD(reg0, reg1, reg2, reg3);
498
36.5k
    ARIA_ADD_ROUND_KEY(rk, reg0, reg1, reg2, reg3);
499
36.5k
    rk++;
500
501
255k
    while(Nr -= 2){
502
219k
        ARIA_SUBST_DIFF_EVEN(reg0, reg1, reg2, reg3);
503
219k
        ARIA_ADD_ROUND_KEY(rk, reg0, reg1, reg2, reg3);
504
219k
        rk++;
505
506
219k
        ARIA_SUBST_DIFF_ODD(reg0, reg1, reg2, reg3);
507
219k
        ARIA_ADD_ROUND_KEY(rk, reg0, reg1, reg2, reg3);
508
219k
        rk++;
509
219k
    }
510
511
36.5k
    reg0 = rk->u[0] ^ MAKE_U32(
512
36.5k
        (uint8_t)(X1[GET_U8_BE(reg0, 0)]     ),
513
36.5k
        (uint8_t)(X2[GET_U8_BE(reg0, 1)] >> 8),
514
36.5k
        (uint8_t)(S1[GET_U8_BE(reg0, 2)]     ),
515
36.5k
        (uint8_t)(S2[GET_U8_BE(reg0, 3)]     ));
516
36.5k
    reg1 = rk->u[1] ^ MAKE_U32(
517
36.5k
        (uint8_t)(X1[GET_U8_BE(reg1, 0)]     ),
518
36.5k
        (uint8_t)(X2[GET_U8_BE(reg1, 1)] >> 8),
519
36.5k
        (uint8_t)(S1[GET_U8_BE(reg1, 2)]     ),
520
36.5k
        (uint8_t)(S2[GET_U8_BE(reg1, 3)]     ));
521
36.5k
    reg2 = rk->u[2] ^ MAKE_U32(
522
36.5k
        (uint8_t)(X1[GET_U8_BE(reg2, 0)]     ),
523
36.5k
        (uint8_t)(X2[GET_U8_BE(reg2, 1)] >> 8),
524
36.5k
        (uint8_t)(S1[GET_U8_BE(reg2, 2)]     ),
525
36.5k
        (uint8_t)(S2[GET_U8_BE(reg2, 3)]     ));
526
36.5k
    reg3 = rk->u[3] ^ MAKE_U32(
527
36.5k
        (uint8_t)(X1[GET_U8_BE(reg3, 0)]     ),
528
36.5k
        (uint8_t)(X2[GET_U8_BE(reg3, 1)] >> 8),
529
36.5k
        (uint8_t)(S1[GET_U8_BE(reg3, 2)]     ),
530
36.5k
        (uint8_t)(S2[GET_U8_BE(reg3, 3)]     ));
531
532
36.5k
    PUT_U32_BE(out, 0, reg0);
533
36.5k
    PUT_U32_BE(out, 1, reg1);
534
36.5k
    PUT_U32_BE(out, 2, reg2);
535
36.5k
    PUT_U32_BE(out, 3, reg3);
536
36.5k
}
537
538
int ossl_aria_set_encrypt_key(const unsigned char *userKey, const int bits,
539
                              ARIA_KEY *key)
540
909
{
541
909
    register uint32_t reg0, reg1, reg2, reg3;
542
909
    uint32_t w0[4], w1[4], w2[4], w3[4];
543
909
    const uint32_t *ck;
544
545
909
    ARIA_u128 *rk;
546
909
    int Nr = (bits + 256) / 32;
547
548
909
    if (userKey == NULL || key == NULL) {
549
0
        return -1;
550
0
    }
551
909
    if (bits != 128 && bits != 192 && bits != 256) {
552
0
        return -2;
553
0
    }
554
555
909
    rk = key->rd_key;
556
909
    key->rounds = Nr;
557
909
    ck = &Key_RC[(bits - 128) / 64][0];
558
559
909
    w0[0] = GET_U32_BE(userKey, 0);
560
909
    w0[1] = GET_U32_BE(userKey, 1);
561
909
    w0[2] = GET_U32_BE(userKey, 2);
562
909
    w0[3] = GET_U32_BE(userKey, 3);
563
564
909
    reg0 = w0[0] ^ ck[0];
565
909
    reg1 = w0[1] ^ ck[1];
566
909
    reg2 = w0[2] ^ ck[2];
567
909
    reg3 = w0[3] ^ ck[3];
568
569
909
    ARIA_SUBST_DIFF_ODD(reg0, reg1, reg2, reg3);
570
571
909
    if (bits > 128) {
572
425
        w1[0] = GET_U32_BE(userKey, 4);
573
425
        w1[1] = GET_U32_BE(userKey, 5);
574
425
        if (bits > 192) {
575
424
            w1[2] = GET_U32_BE(userKey, 6);
576
424
            w1[3] = GET_U32_BE(userKey, 7);
577
424
        }
578
1
        else {
579
1
            w1[2] = w1[3] = 0;
580
1
        }
581
425
    }
582
484
    else {
583
484
        w1[0] = w1[1] = w1[2] = w1[3] = 0;
584
484
    }
585
586
909
    w1[0] ^= reg0;
587
909
    w1[1] ^= reg1;
588
909
    w1[2] ^= reg2;
589
909
    w1[3] ^= reg3;
590
591
909
    reg0 = w1[0];
592
909
    reg1 = w1[1];
593
909
    reg2 = w1[2];
594
909
    reg3 = w1[3];
595
596
909
    reg0 ^= ck[4];
597
909
    reg1 ^= ck[5];
598
909
    reg2 ^= ck[6];
599
909
    reg3 ^= ck[7];
600
601
909
    ARIA_SUBST_DIFF_EVEN(reg0, reg1, reg2, reg3);
602
603
909
    reg0 ^= w0[0];
604
909
    reg1 ^= w0[1];
605
909
    reg2 ^= w0[2];
606
909
    reg3 ^= w0[3];
607
608
909
    w2[0] = reg0;
609
909
    w2[1] = reg1;
610
909
    w2[2] = reg2;
611
909
    w2[3] = reg3;
612
613
909
    reg0 ^= ck[8];
614
909
    reg1 ^= ck[9];
615
909
    reg2 ^= ck[10];
616
909
    reg3 ^= ck[11];
617
618
909
    ARIA_SUBST_DIFF_ODD(reg0, reg1, reg2, reg3);
619
620
909
    w3[0] = reg0 ^ w1[0];
621
909
    w3[1] = reg1 ^ w1[1];
622
909
    w3[2] = reg2 ^ w1[2];
623
909
    w3[3] = reg3 ^ w1[3];
624
625
909
    ARIA_GSRK(rk, w0, w1, 19);
626
909
    rk++;
627
909
    ARIA_GSRK(rk, w1, w2, 19);
628
909
    rk++;
629
909
    ARIA_GSRK(rk, w2, w3, 19);
630
909
    rk++;
631
909
    ARIA_GSRK(rk, w3, w0, 19);
632
633
909
    rk++;
634
909
    ARIA_GSRK(rk, w0, w1, 31);
635
909
    rk++;
636
909
    ARIA_GSRK(rk, w1, w2, 31);
637
909
    rk++;
638
909
    ARIA_GSRK(rk, w2, w3, 31);
639
909
    rk++;
640
909
    ARIA_GSRK(rk, w3, w0, 31);
641
642
909
    rk++;
643
909
    ARIA_GSRK(rk, w0, w1, 67);
644
909
    rk++;
645
909
    ARIA_GSRK(rk, w1, w2, 67);
646
909
    rk++;
647
909
    ARIA_GSRK(rk, w2, w3, 67);
648
909
    rk++;
649
909
    ARIA_GSRK(rk, w3, w0, 67);
650
651
909
    rk++;
652
909
    ARIA_GSRK(rk, w0, w1, 97);
653
909
    if (bits > 128) {
654
425
        rk++;
655
425
        ARIA_GSRK(rk, w1, w2, 97);
656
425
        rk++;
657
425
        ARIA_GSRK(rk, w2, w3, 97);
658
425
    }
659
909
    if (bits > 192) {
660
424
        rk++;
661
424
        ARIA_GSRK(rk, w3, w0, 97);
662
663
424
        rk++;
664
424
        ARIA_GSRK(rk, w0, w1, 109);
665
424
    }
666
667
909
    return 0;
668
909
}
669
670
int ossl_aria_set_decrypt_key(const unsigned char *userKey, const int bits,
671
                              ARIA_KEY *key)
672
0
{
673
0
    ARIA_u128 *rk_head;
674
0
    ARIA_u128 *rk_tail;
675
0
    register uint32_t w1, w2;
676
0
    register uint32_t reg0, reg1, reg2, reg3;
677
0
    uint32_t s0, s1, s2, s3;
678
679
0
    const int r = ossl_aria_set_encrypt_key(userKey, bits, key);
680
681
0
    if (r != 0) {
682
0
        return r;
683
0
    }
684
685
0
    rk_head = key->rd_key;
686
0
    rk_tail = rk_head + key->rounds;
687
688
0
    reg0 = rk_head->u[0];
689
0
    reg1 = rk_head->u[1];
690
0
    reg2 = rk_head->u[2];
691
0
    reg3 = rk_head->u[3];
692
693
0
    memcpy(rk_head, rk_tail, ARIA_BLOCK_SIZE);
694
695
0
    rk_tail->u[0] = reg0;
696
0
    rk_tail->u[1] = reg1;
697
0
    rk_tail->u[2] = reg2;
698
0
    rk_tail->u[3] = reg3;
699
700
0
    rk_head++;
701
0
    rk_tail--;
702
703
0
    for (; rk_head < rk_tail; rk_head++, rk_tail--) {
704
0
        ARIA_DEC_DIFF_BYTE(rk_head->u[0], reg0, w1, w2);
705
0
        ARIA_DEC_DIFF_BYTE(rk_head->u[1], reg1, w1, w2);
706
0
        ARIA_DEC_DIFF_BYTE(rk_head->u[2], reg2, w1, w2);
707
0
        ARIA_DEC_DIFF_BYTE(rk_head->u[3], reg3, w1, w2);
708
709
0
        ARIA_DIFF_WORD(reg0, reg1, reg2, reg3);
710
0
        ARIA_DIFF_BYTE(reg0, reg1, reg2, reg3);
711
0
        ARIA_DIFF_WORD(reg0, reg1, reg2, reg3);
712
713
0
        s0 = reg0;
714
0
        s1 = reg1;
715
0
        s2 = reg2;
716
0
        s3 = reg3;
717
718
0
        ARIA_DEC_DIFF_BYTE(rk_tail->u[0], reg0, w1, w2);
719
0
        ARIA_DEC_DIFF_BYTE(rk_tail->u[1], reg1, w1, w2);
720
0
        ARIA_DEC_DIFF_BYTE(rk_tail->u[2], reg2, w1, w2);
721
0
        ARIA_DEC_DIFF_BYTE(rk_tail->u[3], reg3, w1, w2);
722
723
0
        ARIA_DIFF_WORD(reg0, reg1, reg2, reg3);
724
0
        ARIA_DIFF_BYTE(reg0, reg1, reg2, reg3);
725
0
        ARIA_DIFF_WORD(reg0, reg1, reg2, reg3);
726
727
0
        rk_head->u[0] = reg0;
728
0
        rk_head->u[1] = reg1;
729
0
        rk_head->u[2] = reg2;
730
0
        rk_head->u[3] = reg3;
731
732
0
        rk_tail->u[0] = s0;
733
0
        rk_tail->u[1] = s1;
734
0
        rk_tail->u[2] = s2;
735
0
        rk_tail->u[3] = s3;
736
0
    }
737
0
    ARIA_DEC_DIFF_BYTE(rk_head->u[0], reg0, w1, w2);
738
0
    ARIA_DEC_DIFF_BYTE(rk_head->u[1], reg1, w1, w2);
739
0
    ARIA_DEC_DIFF_BYTE(rk_head->u[2], reg2, w1, w2);
740
0
    ARIA_DEC_DIFF_BYTE(rk_head->u[3], reg3, w1, w2);
741
742
0
    ARIA_DIFF_WORD(reg0, reg1, reg2, reg3);
743
0
    ARIA_DIFF_BYTE(reg0, reg1, reg2, reg3);
744
0
    ARIA_DIFF_WORD(reg0, reg1, reg2, reg3);
745
746
0
    rk_tail->u[0] = reg0;
747
0
    rk_tail->u[1] = reg1;
748
0
    rk_tail->u[2] = reg2;
749
0
    rk_tail->u[3] = reg3;
750
751
0
    return 0;
752
0
}
753
754
#else
755
756
static const unsigned char sb1[256] = {
757
    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
758
    0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
759
    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
760
    0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
761
    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
762
    0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
763
    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
764
    0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
765
    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
766
    0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
767
    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
768
    0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
769
    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
770
    0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
771
    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
772
    0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
773
    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
774
    0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
775
    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
776
    0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
777
    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
778
    0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
779
    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
780
    0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
781
    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
782
    0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
783
    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
784
    0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
785
    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
786
    0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
787
    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
788
    0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
789
};
790
791
static const unsigned char sb2[256] = {
792
    0xe2, 0x4e, 0x54, 0xfc, 0x94, 0xc2, 0x4a, 0xcc,
793
    0x62, 0x0d, 0x6a, 0x46, 0x3c, 0x4d, 0x8b, 0xd1,
794
    0x5e, 0xfa, 0x64, 0xcb, 0xb4, 0x97, 0xbe, 0x2b,
795
    0xbc, 0x77, 0x2e, 0x03, 0xd3, 0x19, 0x59, 0xc1,
796
    0x1d, 0x06, 0x41, 0x6b, 0x55, 0xf0, 0x99, 0x69,
797
    0xea, 0x9c, 0x18, 0xae, 0x63, 0xdf, 0xe7, 0xbb,
798
    0x00, 0x73, 0x66, 0xfb, 0x96, 0x4c, 0x85, 0xe4,
799
    0x3a, 0x09, 0x45, 0xaa, 0x0f, 0xee, 0x10, 0xeb,
800
    0x2d, 0x7f, 0xf4, 0x29, 0xac, 0xcf, 0xad, 0x91,
801
    0x8d, 0x78, 0xc8, 0x95, 0xf9, 0x2f, 0xce, 0xcd,
802
    0x08, 0x7a, 0x88, 0x38, 0x5c, 0x83, 0x2a, 0x28,
803
    0x47, 0xdb, 0xb8, 0xc7, 0x93, 0xa4, 0x12, 0x53,
804
    0xff, 0x87, 0x0e, 0x31, 0x36, 0x21, 0x58, 0x48,
805
    0x01, 0x8e, 0x37, 0x74, 0x32, 0xca, 0xe9, 0xb1,
806
    0xb7, 0xab, 0x0c, 0xd7, 0xc4, 0x56, 0x42, 0x26,
807
    0x07, 0x98, 0x60, 0xd9, 0xb6, 0xb9, 0x11, 0x40,
808
    0xec, 0x20, 0x8c, 0xbd, 0xa0, 0xc9, 0x84, 0x04,
809
    0x49, 0x23, 0xf1, 0x4f, 0x50, 0x1f, 0x13, 0xdc,
810
    0xd8, 0xc0, 0x9e, 0x57, 0xe3, 0xc3, 0x7b, 0x65,
811
    0x3b, 0x02, 0x8f, 0x3e, 0xe8, 0x25, 0x92, 0xe5,
812
    0x15, 0xdd, 0xfd, 0x17, 0xa9, 0xbf, 0xd4, 0x9a,
813
    0x7e, 0xc5, 0x39, 0x67, 0xfe, 0x76, 0x9d, 0x43,
814
    0xa7, 0xe1, 0xd0, 0xf5, 0x68, 0xf2, 0x1b, 0x34,
815
    0x70, 0x05, 0xa3, 0x8a, 0xd5, 0x79, 0x86, 0xa8,
816
    0x30, 0xc6, 0x51, 0x4b, 0x1e, 0xa6, 0x27, 0xf6,
817
    0x35, 0xd2, 0x6e, 0x24, 0x16, 0x82, 0x5f, 0xda,
818
    0xe6, 0x75, 0xa2, 0xef, 0x2c, 0xb2, 0x1c, 0x9f,
819
    0x5d, 0x6f, 0x80, 0x0a, 0x72, 0x44, 0x9b, 0x6c,
820
    0x90, 0x0b, 0x5b, 0x33, 0x7d, 0x5a, 0x52, 0xf3,
821
    0x61, 0xa1, 0xf7, 0xb0, 0xd6, 0x3f, 0x7c, 0x6d,
822
    0xed, 0x14, 0xe0, 0xa5, 0x3d, 0x22, 0xb3, 0xf8,
823
    0x89, 0xde, 0x71, 0x1a, 0xaf, 0xba, 0xb5, 0x81
824
};
825
826
static const unsigned char sb3[256] = {
827
    0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
828
    0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
829
    0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
830
    0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
831
    0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
832
    0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
833
    0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
834
    0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
835
    0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
836
    0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
837
    0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
838
    0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
839
    0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
840
    0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
841
    0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
842
    0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
843
    0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
844
    0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
845
    0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
846
    0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
847
    0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
848
    0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
849
    0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
850
    0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
851
    0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
852
    0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
853
    0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
854
    0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
855
    0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
856
    0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
857
    0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
858
    0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
859
};
860
861
static const unsigned char sb4[256] = {
862
    0x30, 0x68, 0x99, 0x1b, 0x87, 0xb9, 0x21, 0x78,
863
    0x50, 0x39, 0xdb, 0xe1, 0x72, 0x09, 0x62, 0x3c,
864
    0x3e, 0x7e, 0x5e, 0x8e, 0xf1, 0xa0, 0xcc, 0xa3,
865
    0x2a, 0x1d, 0xfb, 0xb6, 0xd6, 0x20, 0xc4, 0x8d,
866
    0x81, 0x65, 0xf5, 0x89, 0xcb, 0x9d, 0x77, 0xc6,
867
    0x57, 0x43, 0x56, 0x17, 0xd4, 0x40, 0x1a, 0x4d,
868
    0xc0, 0x63, 0x6c, 0xe3, 0xb7, 0xc8, 0x64, 0x6a,
869
    0x53, 0xaa, 0x38, 0x98, 0x0c, 0xf4, 0x9b, 0xed,
870
    0x7f, 0x22, 0x76, 0xaf, 0xdd, 0x3a, 0x0b, 0x58,
871
    0x67, 0x88, 0x06, 0xc3, 0x35, 0x0d, 0x01, 0x8b,
872
    0x8c, 0xc2, 0xe6, 0x5f, 0x02, 0x24, 0x75, 0x93,
873
    0x66, 0x1e, 0xe5, 0xe2, 0x54, 0xd8, 0x10, 0xce,
874
    0x7a, 0xe8, 0x08, 0x2c, 0x12, 0x97, 0x32, 0xab,
875
    0xb4, 0x27, 0x0a, 0x23, 0xdf, 0xef, 0xca, 0xd9,
876
    0xb8, 0xfa, 0xdc, 0x31, 0x6b, 0xd1, 0xad, 0x19,
877
    0x49, 0xbd, 0x51, 0x96, 0xee, 0xe4, 0xa8, 0x41,
878
    0xda, 0xff, 0xcd, 0x55, 0x86, 0x36, 0xbe, 0x61,
879
    0x52, 0xf8, 0xbb, 0x0e, 0x82, 0x48, 0x69, 0x9a,
880
    0xe0, 0x47, 0x9e, 0x5c, 0x04, 0x4b, 0x34, 0x15,
881
    0x79, 0x26, 0xa7, 0xde, 0x29, 0xae, 0x92, 0xd7,
882
    0x84, 0xe9, 0xd2, 0xba, 0x5d, 0xf3, 0xc5, 0xb0,
883
    0xbf, 0xa4, 0x3b, 0x71, 0x44, 0x46, 0x2b, 0xfc,
884
    0xeb, 0x6f, 0xd5, 0xf6, 0x14, 0xfe, 0x7c, 0x70,
885
    0x5a, 0x7d, 0xfd, 0x2f, 0x18, 0x83, 0x16, 0xa5,
886
    0x91, 0x1f, 0x05, 0x95, 0x74, 0xa9, 0xc1, 0x5b,
887
    0x4a, 0x85, 0x6d, 0x13, 0x07, 0x4f, 0x4e, 0x45,
888
    0xb2, 0x0f, 0xc9, 0x1c, 0xa6, 0xbc, 0xec, 0x73,
889
    0x90, 0x7b, 0xcf, 0x59, 0x8f, 0xa1, 0xf9, 0x2d,
890
    0xf2, 0xb1, 0x00, 0x94, 0x37, 0x9f, 0xd0, 0x2e,
891
    0x9c, 0x6e, 0x28, 0x3f, 0x80, 0xf0, 0x3d, 0xd3,
892
    0x25, 0x8a, 0xb5, 0xe7, 0x42, 0xb3, 0xc7, 0xea,
893
    0xf7, 0x4c, 0x11, 0x33, 0x03, 0xa2, 0xac, 0x60
894
};
895
896
static const ARIA_u128 c1 = {{
897
    0x51, 0x7c, 0xc1, 0xb7, 0x27, 0x22, 0x0a, 0x94,
898
    0xfe, 0x13, 0xab, 0xe8, 0xfa, 0x9a, 0x6e, 0xe0
899
}};
900
901
static const ARIA_u128 c2 = {{
902
    0x6d, 0xb1, 0x4a, 0xcc, 0x9e, 0x21, 0xc8, 0x20,
903
    0xff, 0x28, 0xb1, 0xd5, 0xef, 0x5d, 0xe2, 0xb0
904
}};
905
906
static const ARIA_u128 c3 = {{
907
    0xdb, 0x92, 0x37, 0x1d, 0x21, 0x26, 0xe9, 0x70,
908
    0x03, 0x24, 0x97, 0x75, 0x04, 0xe8, 0xc9, 0x0e
909
}};
910
911
/*
912
 * Exclusive or two 128 bit values into the result.
913
 * It is safe for the result to be the same as the either input.
914
 */
915
static void xor128(ARIA_c128 o, const ARIA_c128 x, const ARIA_u128 *y)
916
{
917
    int i;
918
919
    for (i = 0; i < ARIA_BLOCK_SIZE; i++)
920
        o[i] = x[i] ^ y->c[i];
921
}
922
923
/*
924
 * Generalised circular rotate right and exclusive or function.
925
 * It is safe for the output to overlap either input.
926
 */
927
static ossl_inline void rotnr(unsigned int n, ARIA_u128 *o,
928
                              const ARIA_u128 *xor, const ARIA_u128 *z)
929
{
930
    const unsigned int bytes = n / 8, bits = n % 8;
931
    unsigned int i;
932
    ARIA_u128 t;
933
934
    for (i = 0; i < ARIA_BLOCK_SIZE; i++)
935
        t.c[(i + bytes) % ARIA_BLOCK_SIZE] = z->c[i];
936
    for (i = 0; i < ARIA_BLOCK_SIZE; i++)
937
        o->c[i] = ((t.c[i] >> bits) |
938
                (t.c[i ? i - 1 : ARIA_BLOCK_SIZE - 1] << (8 - bits))) ^
939
                xor->c[i];
940
}
941
942
/*
943
 * Circular rotate 19 bits right and xor.
944
 * It is safe for the output to overlap either input.
945
 */
946
static void rot19r(ARIA_u128 *o, const ARIA_u128 *xor, const ARIA_u128 *z)
947
{
948
    rotnr(19, o, xor, z);
949
}
950
951
/*
952
 * Circular rotate 31 bits right and xor.
953
 * It is safe for the output to overlap either input.
954
 */
955
static void rot31r(ARIA_u128 *o, const ARIA_u128 *xor, const ARIA_u128 *z)
956
{
957
    rotnr(31, o, xor, z);
958
}
959
960
/*
961
 * Circular rotate 61 bits left and xor.
962
 * It is safe for the output to overlap either input.
963
 */
964
static void rot61l(ARIA_u128 *o, const ARIA_u128 *xor, const ARIA_u128 *z)
965
{
966
    rotnr(8 * ARIA_BLOCK_SIZE - 61, o, xor, z);
967
}
968
969
/*
970
 * Circular rotate 31 bits left and xor.
971
 * It is safe for the output to overlap either input.
972
 */
973
static void rot31l(ARIA_u128 *o, const ARIA_u128 *xor, const ARIA_u128 *z)
974
{
975
    rotnr(8 * ARIA_BLOCK_SIZE - 31, o, xor, z);
976
}
977
978
/*
979
 * Circular rotate 19 bits left and xor.
980
 * It is safe for the output to overlap either input.
981
 */
982
static void rot19l(ARIA_u128 *o, const ARIA_u128 *xor, const ARIA_u128 *z)
983
{
984
    rotnr(8 * ARIA_BLOCK_SIZE - 19, o, xor, z);
985
}
986
987
/*
988
 * First substitution and xor layer, used for odd steps.
989
 * It is safe for the input and output to be the same.
990
 */
991
static void sl1(ARIA_u128 *o, const ARIA_u128 *x, const ARIA_u128 *y)
992
{
993
    unsigned int i;
994
    for (i = 0; i < ARIA_BLOCK_SIZE; i += 4) {
995
        o->c[i    ] = sb1[x->c[i    ] ^ y->c[i    ]];
996
        o->c[i + 1] = sb2[x->c[i + 1] ^ y->c[i + 1]];
997
        o->c[i + 2] = sb3[x->c[i + 2] ^ y->c[i + 2]];
998
        o->c[i + 3] = sb4[x->c[i + 3] ^ y->c[i + 3]];
999
    }
1000
}
1001
1002
/*
1003
 * Second substitution and xor layer, used for even steps.
1004
 * It is safe for the input and output to be the same.
1005
 */
1006
static void sl2(ARIA_c128 o, const ARIA_u128 *x, const ARIA_u128 *y)
1007
{
1008
    unsigned int i;
1009
    for (i = 0; i < ARIA_BLOCK_SIZE; i += 4) {
1010
        o[i    ] = sb3[x->c[i    ] ^ y->c[i    ]];
1011
        o[i + 1] = sb4[x->c[i + 1] ^ y->c[i + 1]];
1012
        o[i + 2] = sb1[x->c[i + 2] ^ y->c[i + 2]];
1013
        o[i + 3] = sb2[x->c[i + 3] ^ y->c[i + 3]];
1014
    }
1015
}
1016
1017
/*
1018
 * Diffusion layer step
1019
 * It is NOT safe for the input and output to overlap.
1020
 */
1021
static void a(ARIA_u128 *y, const ARIA_u128 *x)
1022
{
1023
    y->c[ 0] = x->c[ 3] ^ x->c[ 4] ^ x->c[ 6] ^ x->c[ 8] ^
1024
               x->c[ 9] ^ x->c[13] ^ x->c[14];
1025
    y->c[ 1] = x->c[ 2] ^ x->c[ 5] ^ x->c[ 7] ^ x->c[ 8] ^
1026
               x->c[ 9] ^ x->c[12] ^ x->c[15];
1027
    y->c[ 2] = x->c[ 1] ^ x->c[ 4] ^ x->c[ 6] ^ x->c[10] ^
1028
               x->c[11] ^ x->c[12] ^ x->c[15];
1029
    y->c[ 3] = x->c[ 0] ^ x->c[ 5] ^ x->c[ 7] ^ x->c[10] ^
1030
               x->c[11] ^ x->c[13] ^ x->c[14];
1031
    y->c[ 4] = x->c[ 0] ^ x->c[ 2] ^ x->c[ 5] ^ x->c[ 8] ^
1032
               x->c[11] ^ x->c[14] ^ x->c[15];
1033
    y->c[ 5] = x->c[ 1] ^ x->c[ 3] ^ x->c[ 4] ^ x->c[ 9] ^
1034
               x->c[10] ^ x->c[14] ^ x->c[15];
1035
    y->c[ 6] = x->c[ 0] ^ x->c[ 2] ^ x->c[ 7] ^ x->c[ 9] ^
1036
               x->c[10] ^ x->c[12] ^ x->c[13];
1037
    y->c[ 7] = x->c[ 1] ^ x->c[ 3] ^ x->c[ 6] ^ x->c[ 8] ^
1038
               x->c[11] ^ x->c[12] ^ x->c[13];
1039
    y->c[ 8] = x->c[ 0] ^ x->c[ 1] ^ x->c[ 4] ^ x->c[ 7] ^
1040
               x->c[10] ^ x->c[13] ^ x->c[15];
1041
    y->c[ 9] = x->c[ 0] ^ x->c[ 1] ^ x->c[ 5] ^ x->c[ 6] ^
1042
               x->c[11] ^ x->c[12] ^ x->c[14];
1043
    y->c[10] = x->c[ 2] ^ x->c[ 3] ^ x->c[ 5] ^ x->c[ 6] ^
1044
               x->c[ 8] ^ x->c[13] ^ x->c[15];
1045
    y->c[11] = x->c[ 2] ^ x->c[ 3] ^ x->c[ 4] ^ x->c[ 7] ^
1046
               x->c[ 9] ^ x->c[12] ^ x->c[14];
1047
    y->c[12] = x->c[ 1] ^ x->c[ 2] ^ x->c[ 6] ^ x->c[ 7] ^
1048
               x->c[ 9] ^ x->c[11] ^ x->c[12];
1049
    y->c[13] = x->c[ 0] ^ x->c[ 3] ^ x->c[ 6] ^ x->c[ 7] ^
1050
               x->c[ 8] ^ x->c[10] ^ x->c[13];
1051
    y->c[14] = x->c[ 0] ^ x->c[ 3] ^ x->c[ 4] ^ x->c[ 5] ^
1052
               x->c[ 9] ^ x->c[11] ^ x->c[14];
1053
    y->c[15] = x->c[ 1] ^ x->c[ 2] ^ x->c[ 4] ^ x->c[ 5] ^
1054
               x->c[ 8] ^ x->c[10] ^ x->c[15];
1055
}
1056
1057
/*
1058
 * Odd round function
1059
 * Apply the first substitution layer and then a diffusion step.
1060
 * It is safe for the input and output to overlap.
1061
 */
1062
static ossl_inline void FO(ARIA_u128 *o, const ARIA_u128 *d,
1063
                           const ARIA_u128 *rk)
1064
{
1065
    ARIA_u128 y;
1066
1067
    sl1(&y, d, rk);
1068
    a(o, &y);
1069
}
1070
1071
/*
1072
 * Even round function
1073
 * Apply the second substitution layer and then a diffusion step.
1074
 * It is safe for the input and output to overlap.
1075
 */
1076
static ossl_inline void FE(ARIA_u128 *o, const ARIA_u128 *d,
1077
                           const ARIA_u128 *rk)
1078
{
1079
    ARIA_u128 y;
1080
1081
    sl2(y.c, d, rk);
1082
    a(o, &y);
1083
}
1084
1085
/*
1086
 * Encrypt or decrypt a single block
1087
 * in and out can overlap
1088
 */
1089
static void do_encrypt(unsigned char *o, const unsigned char *pin,
1090
                       unsigned int rounds, const ARIA_u128 *keys)
1091
{
1092
    ARIA_u128 p;
1093
    unsigned int i;
1094
1095
    memcpy(&p, pin, sizeof(p));
1096
    for (i = 0; i < rounds - 2; i += 2) {
1097
        FO(&p, &p, &keys[i]);
1098
        FE(&p, &p, &keys[i + 1]);
1099
    }
1100
    FO(&p, &p, &keys[rounds - 2]);
1101
    sl2(o, &p, &keys[rounds - 1]);
1102
    xor128(o, o, &keys[rounds]);
1103
}
1104
1105
/*
1106
 * Encrypt a single block
1107
 * in and out can overlap
1108
 */
1109
void ossl_aria_encrypt(const unsigned char *in, unsigned char *out,
1110
                       const ARIA_KEY *key)
1111
{
1112
    assert(in != NULL && out != NULL && key != NULL);
1113
    do_encrypt(out, in, key->rounds, key->rd_key);
1114
}
1115
1116
1117
/*
1118
 * Expand the cipher key into the encryption key schedule.
1119
 * We short circuit execution of the last two
1120
 * or four rotations based on the key size.
1121
 */
1122
int ossl_aria_set_encrypt_key(const unsigned char *userKey, const int bits,
1123
                              ARIA_KEY *key)
1124
{
1125
    const ARIA_u128 *ck1, *ck2, *ck3;
1126
    ARIA_u128 kr, w0, w1, w2, w3;
1127
1128
    if (!userKey || !key)
1129
        return -1;
1130
    memcpy(w0.c, userKey, sizeof(w0));
1131
    switch (bits) {
1132
    default:
1133
        return -2;
1134
    case 128:
1135
        key->rounds = 12;
1136
        ck1 = &c1;
1137
        ck2 = &c2;
1138
        ck3 = &c3;
1139
        memset(kr.c, 0, sizeof(kr));
1140
        break;
1141
1142
    case 192:
1143
        key->rounds = 14;
1144
        ck1 = &c2;
1145
        ck2 = &c3;
1146
        ck3 = &c1;
1147
        memcpy(kr.c, userKey + ARIA_BLOCK_SIZE, sizeof(kr) / 2);
1148
        memset(kr.c + ARIA_BLOCK_SIZE / 2, 0, sizeof(kr) / 2);
1149
        break;
1150
1151
    case 256:
1152
        key->rounds = 16;
1153
        ck1 = &c3;
1154
        ck2 = &c1;
1155
        ck3 = &c2;
1156
        memcpy(kr.c, userKey + ARIA_BLOCK_SIZE, sizeof(kr));
1157
        break;
1158
    }
1159
1160
    FO(&w3, &w0, ck1);    xor128(w1.c, w3.c, &kr);
1161
    FE(&w3, &w1, ck2);    xor128(w2.c, w3.c, &w0);
1162
    FO(&kr, &w2, ck3);    xor128(w3.c, kr.c, &w1);
1163
1164
    rot19r(&key->rd_key[ 0], &w0, &w1);
1165
    rot19r(&key->rd_key[ 1], &w1, &w2);
1166
    rot19r(&key->rd_key[ 2], &w2, &w3);
1167
    rot19r(&key->rd_key[ 3], &w3, &w0);
1168
1169
    rot31r(&key->rd_key[ 4], &w0, &w1);
1170
    rot31r(&key->rd_key[ 5], &w1, &w2);
1171
    rot31r(&key->rd_key[ 6], &w2, &w3);
1172
    rot31r(&key->rd_key[ 7], &w3, &w0);
1173
1174
    rot61l(&key->rd_key[ 8], &w0, &w1);
1175
    rot61l(&key->rd_key[ 9], &w1, &w2);
1176
    rot61l(&key->rd_key[10], &w2, &w3);
1177
    rot61l(&key->rd_key[11], &w3, &w0);
1178
1179
    rot31l(&key->rd_key[12], &w0, &w1);
1180
    if (key->rounds > 12) {
1181
        rot31l(&key->rd_key[13], &w1, &w2);
1182
        rot31l(&key->rd_key[14], &w2, &w3);
1183
1184
        if (key->rounds > 14) {
1185
            rot31l(&key->rd_key[15], &w3, &w0);
1186
            rot19l(&key->rd_key[16], &w0, &w1);
1187
        }
1188
    }
1189
    return 0;
1190
}
1191
1192
/*
1193
 * Expand the cipher key into the decryption key schedule.
1194
 */
1195
int ossl_aria_set_decrypt_key(const unsigned char *userKey, const int bits,
1196
                              ARIA_KEY *key)
1197
{
1198
    ARIA_KEY ek;
1199
    const int r = ossl_aria_set_encrypt_key(userKey, bits, &ek);
1200
    unsigned int i, rounds = ek.rounds;
1201
1202
    if (r == 0) {
1203
        key->rounds = rounds;
1204
        memcpy(&key->rd_key[0], &ek.rd_key[rounds], sizeof(key->rd_key[0]));
1205
        for (i = 1; i < rounds; i++)
1206
            a(&key->rd_key[i], &ek.rd_key[rounds - i]);
1207
        memcpy(&key->rd_key[rounds], &ek.rd_key[0], sizeof(key->rd_key[rounds]));
1208
    }
1209
    return r;
1210
}
1211
1212
#endif