Coverage Report

Created: 2018-08-29 13:53

/src/openssl/crypto/aria/aria.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
3
 * Copyright (c) 2017, Oracle and/or its affiliates.  All rights reserved.
4
 *
5
 * Licensed under the OpenSSL license (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 "internal/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
0
#define rotr32(v, r) (((uint32_t)(v) >> (r)) | ((uint32_t)(v) << (32 - r)))
34
35
#define bswap32(v)                                          \
36
0
    (((v) << 24) ^ ((v) >> 24) ^                            \
37
0
    (((v) & 0x0000ff00) << 8) ^ (((v) & 0x00ff0000) >> 8))
38
39
0
#define GET_U8_BE(X, Y) ((uint8_t)((X) >> ((3 - Y) * 8)))
40
0
#define GET_U32_BE(X, Y) (                                  \
41
0
    ((uint32_t)((const uint8_t *)(X))[Y * 4    ] << 24) ^   \
42
0
    ((uint32_t)((const uint8_t *)(X))[Y * 4 + 1] << 16) ^   \
43
0
    ((uint32_t)((const uint8_t *)(X))[Y * 4 + 2] <<  8) ^   \
44
0
    ((uint32_t)((const uint8_t *)(X))[Y * 4 + 3]      )     )
45
46
#define PUT_U32_BE(DEST, IDX, VAL)                              \
47
0
    do {                                                        \
48
0
        ((uint8_t *)(DEST))[IDX * 4    ] = GET_U8_BE(VAL, 0);   \
49
0
        ((uint8_t *)(DEST))[IDX * 4 + 1] = GET_U8_BE(VAL, 1);   \
50
0
        ((uint8_t *)(DEST))[IDX * 4 + 2] = GET_U8_BE(VAL, 2);   \
51
0
        ((uint8_t *)(DEST))[IDX * 4 + 3] = GET_U8_BE(VAL, 3);   \
52
0
    } while(0)
53
54
0
#define MAKE_U32(V0, V1, V2, V3) (      \
55
0
    ((uint32_t)((uint8_t)(V0)) << 24) | \
56
0
    ((uint32_t)((uint8_t)(V1)) << 16) | \
57
0
    ((uint32_t)((uint8_t)(V2)) <<  8) | \
58
0
    ((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
0
    do {                                        \
347
0
        (T0) ^= (RK)->u[0];                     \
348
0
        (T1) ^= (RK)->u[1];                     \
349
0
        (T2) ^= (RK)->u[2];                     \
350
0
        (T3) ^= (RK)->u[3];                     \
351
0
    } while(0)
352
353
/* S-Box Layer 1 + M */
354
#define ARIA_SBOX_LAYER1_WITH_PRE_DIFF(T0, T1, T2, T3)  \
355
0
    do {                                                \
356
0
        (T0) =                                          \
357
0
            S1[GET_U8_BE(T0, 0)] ^                      \
358
0
            S2[GET_U8_BE(T0, 1)] ^                      \
359
0
            X1[GET_U8_BE(T0, 2)] ^                      \
360
0
            X2[GET_U8_BE(T0, 3)];                       \
361
0
        (T1) =                                          \
362
0
            S1[GET_U8_BE(T1, 0)] ^                      \
363
0
            S2[GET_U8_BE(T1, 1)] ^                      \
364
0
            X1[GET_U8_BE(T1, 2)] ^                      \
365
0
            X2[GET_U8_BE(T1, 3)];                       \
366
0
        (T2) =                                          \
367
0
            S1[GET_U8_BE(T2, 0)] ^                      \
368
0
            S2[GET_U8_BE(T2, 1)] ^                      \
369
0
            X1[GET_U8_BE(T2, 2)] ^                      \
370
0
            X2[GET_U8_BE(T2, 3)];                       \
371
0
        (T3) =                                          \
372
0
            S1[GET_U8_BE(T3, 0)] ^                      \
373
0
            S2[GET_U8_BE(T3, 1)] ^                      \
374
0
            X1[GET_U8_BE(T3, 2)] ^                      \
375
0
            X2[GET_U8_BE(T3, 3)];                       \
376
0
    } while(0)
377
378
/* S-Box Layer 2 + M */
379
#define ARIA_SBOX_LAYER2_WITH_PRE_DIFF(T0, T1, T2, T3)  \
380
0
    do {                                                \
381
0
        (T0) =                                          \
382
0
            X1[GET_U8_BE(T0, 0)] ^                      \
383
0
            X2[GET_U8_BE(T0, 1)] ^                      \
384
0
            S1[GET_U8_BE(T0, 2)] ^                      \
385
0
            S2[GET_U8_BE(T0, 3)];                       \
386
0
        (T1) =                                          \
387
0
            X1[GET_U8_BE(T1, 0)] ^                      \
388
0
            X2[GET_U8_BE(T1, 1)] ^                      \
389
0
            S1[GET_U8_BE(T1, 2)] ^                      \
390
0
            S2[GET_U8_BE(T1, 3)];                       \
391
0
        (T2) =                                          \
392
0
            X1[GET_U8_BE(T2, 0)] ^                      \
393
0
            X2[GET_U8_BE(T2, 1)] ^                      \
394
0
            S1[GET_U8_BE(T2, 2)] ^                      \
395
0
            S2[GET_U8_BE(T2, 3)];                       \
396
0
        (T3) =                                          \
397
0
            X1[GET_U8_BE(T3, 0)] ^                      \
398
0
            X2[GET_U8_BE(T3, 1)] ^                      \
399
0
            S1[GET_U8_BE(T3, 2)] ^                      \
400
0
            S2[GET_U8_BE(T3, 3)];                       \
401
0
    } while(0)
402
403
/* Word-level diffusion */
404
#define ARIA_DIFF_WORD(T0,T1,T2,T3) \
405
0
    do {                            \
406
0
        (T1) ^= (T2);               \
407
0
        (T2) ^= (T3);               \
408
0
        (T0) ^= (T1);               \
409
0
                                    \
410
0
        (T3) ^= (T1);               \
411
0
        (T2) ^= (T0);               \
412
0
        (T1) ^= (T2);               \
413
0
    } while(0)
414
415
/* Byte-level diffusion */
416
#define ARIA_DIFF_BYTE(T0, T1, T2, T3)                                  \
417
0
    do {                                                                \
418
0
        (T1) = (((T1) << 8) & 0xff00ff00) ^ (((T1) >> 8) & 0x00ff00ff); \
419
0
        (T2) = rotr32(T2, 16);                                          \
420
0
        (T3) = bswap32(T3);                                             \
421
0
    } while(0)
422
423
/* Odd round Substitution & Diffusion */
424
#define ARIA_SUBST_DIFF_ODD(T0, T1, T2, T3)             \
425
0
    do {                                                \
426
0
        ARIA_SBOX_LAYER1_WITH_PRE_DIFF(T0, T1, T2, T3); \
427
0
        ARIA_DIFF_WORD(T0, T1, T2, T3);                 \
428
0
        ARIA_DIFF_BYTE(T0, T1, T2, T3);                 \
429
0
        ARIA_DIFF_WORD(T0, T1, T2, T3);                 \
430
0
    } while(0)
431
432
/* Even round Substitution & Diffusion */
433
#define ARIA_SUBST_DIFF_EVEN(T0, T1, T2, T3)            \
434
0
    do {                                                \
435
0
        ARIA_SBOX_LAYER2_WITH_PRE_DIFF(T0, T1, T2, T3); \
436
0
        ARIA_DIFF_WORD(T0, T1, T2, T3);                 \
437
0
        ARIA_DIFF_BYTE(T2, T3, T0, T1);                 \
438
0
        ARIA_DIFF_WORD(T0, T1, T2, T3);                 \
439
0
    } while(0)
440
441
/* Q, R Macro expanded ARIA GSRK */
442
#define _ARIA_GSRK(RK, X, Y, Q, R)                  \
443
0
    do {                                            \
444
0
        (RK)->u[0] =                                \
445
0
            ((X)[0]) ^                              \
446
0
            (((Y)[((Q)    ) % 4]) >> (R)) ^         \
447
0
            (((Y)[((Q) + 3) % 4]) << (32 - (R)));   \
448
0
        (RK)->u[1] =                                \
449
0
            ((X)[1]) ^                              \
450
0
            (((Y)[((Q) + 1) % 4]) >> (R)) ^         \
451
0
            (((Y)[((Q)    ) % 4]) << (32 - (R)));   \
452
0
        (RK)->u[2] =                                \
453
0
            ((X)[2]) ^                              \
454
0
            (((Y)[((Q) + 2) % 4]) >> (R)) ^         \
455
0
            (((Y)[((Q) + 1) % 4]) << (32 - (R)));   \
456
0
        (RK)->u[3] =                                \
457
0
            ((X)[3]) ^                              \
458
0
            (((Y)[((Q) + 3) % 4]) >> (R)) ^         \
459
0
            (((Y)[((Q) + 2) % 4]) << (32 - (R)));   \
460
0
    } while(0)
461
462
0
#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 aria_encrypt(const unsigned char *in, unsigned char *out,
472
                  const ARIA_KEY *key)
473
0
{
474
0
    register uint32_t reg0, reg1, reg2, reg3;
475
0
    int Nr;
476
0
    const ARIA_u128 *rk;
477
0
478
0
    if (in == NULL || out == NULL || key == NULL) {
479
0
        return;
480
0
    }
481
0
482
0
    rk = key->rd_key;
483
0
    Nr = key->rounds;
484
0
485
0
    if (Nr != 12 && Nr != 14 && Nr != 16) {
486
0
        return;
487
0
    }
488
0
489
0
    reg0 = GET_U32_BE(in, 0);
490
0
    reg1 = GET_U32_BE(in, 1);
491
0
    reg2 = GET_U32_BE(in, 2);
492
0
    reg3 = GET_U32_BE(in, 3);
493
0
494
0
    ARIA_ADD_ROUND_KEY(rk, reg0, reg1, reg2, reg3);
495
0
    rk++;
496
0
497
0
    ARIA_SUBST_DIFF_ODD(reg0, reg1, reg2, reg3);
498
0
    ARIA_ADD_ROUND_KEY(rk, reg0, reg1, reg2, reg3);
499
0
    rk++;
500
0
501
0
    while(Nr -= 2){
502
0
        ARIA_SUBST_DIFF_EVEN(reg0, reg1, reg2, reg3);
503
0
        ARIA_ADD_ROUND_KEY(rk, reg0, reg1, reg2, reg3);
504
0
        rk++;
505
0
506
0
        ARIA_SUBST_DIFF_ODD(reg0, reg1, reg2, reg3);
507
0
        ARIA_ADD_ROUND_KEY(rk, reg0, reg1, reg2, reg3);
508
0
        rk++;
509
0
    }
510
0
511
0
    reg0 = rk->u[0] ^ MAKE_U32(
512
0
        (uint8_t)(X1[GET_U8_BE(reg0, 0)]     ),
513
0
        (uint8_t)(X2[GET_U8_BE(reg0, 1)] >> 8),
514
0
        (uint8_t)(S1[GET_U8_BE(reg0, 2)]     ),
515
0
        (uint8_t)(S2[GET_U8_BE(reg0, 3)]     ));
516
0
    reg1 = rk->u[1] ^ MAKE_U32(
517
0
        (uint8_t)(X1[GET_U8_BE(reg1, 0)]     ),
518
0
        (uint8_t)(X2[GET_U8_BE(reg1, 1)] >> 8),
519
0
        (uint8_t)(S1[GET_U8_BE(reg1, 2)]     ),
520
0
        (uint8_t)(S2[GET_U8_BE(reg1, 3)]     ));
521
0
    reg2 = rk->u[2] ^ MAKE_U32(
522
0
        (uint8_t)(X1[GET_U8_BE(reg2, 0)]     ),
523
0
        (uint8_t)(X2[GET_U8_BE(reg2, 1)] >> 8),
524
0
        (uint8_t)(S1[GET_U8_BE(reg2, 2)]     ),
525
0
        (uint8_t)(S2[GET_U8_BE(reg2, 3)]     ));
526
0
    reg3 = rk->u[3] ^ MAKE_U32(
527
0
        (uint8_t)(X1[GET_U8_BE(reg3, 0)]     ),
528
0
        (uint8_t)(X2[GET_U8_BE(reg3, 1)] >> 8),
529
0
        (uint8_t)(S1[GET_U8_BE(reg3, 2)]     ),
530
0
        (uint8_t)(S2[GET_U8_BE(reg3, 3)]     ));
531
0
532
0
    PUT_U32_BE(out, 0, reg0);
533
0
    PUT_U32_BE(out, 1, reg1);
534
0
    PUT_U32_BE(out, 2, reg2);
535
0
    PUT_U32_BE(out, 3, reg3);
536
0
}
537
538
int aria_set_encrypt_key(const unsigned char *userKey, const int bits,
539
                         ARIA_KEY *key)
540
0
{
541
0
    register uint32_t reg0, reg1, reg2, reg3;
542
0
    uint32_t w0[4], w1[4], w2[4], w3[4];
543
0
    const uint32_t *ck;
544
0
545
0
    ARIA_u128 *rk;
546
0
    int Nr = (bits + 256) / 32;
547
0
548
0
    if (userKey == NULL || key == NULL) {
549
0
        return -1;
550
0
    }
551
0
    if (bits != 128 && bits != 192 && bits != 256) {
552
0
        return -2;
553
0
    }
554
0
555
0
    rk = key->rd_key;
556
0
    key->rounds = Nr;
557
0
    ck = &Key_RC[(bits - 128) / 64][0];
558
0
559
0
    w0[0] = GET_U32_BE(userKey, 0);
560
0
    w0[1] = GET_U32_BE(userKey, 1);
561
0
    w0[2] = GET_U32_BE(userKey, 2);
562
0
    w0[3] = GET_U32_BE(userKey, 3);
563
0
564
0
    reg0 = w0[0] ^ ck[0];
565
0
    reg1 = w0[1] ^ ck[1];
566
0
    reg2 = w0[2] ^ ck[2];
567
0
    reg3 = w0[3] ^ ck[3];
568
0
569
0
    ARIA_SUBST_DIFF_ODD(reg0, reg1, reg2, reg3);
570
0
571
0
    if (bits > 128) {
572
0
        w1[0] = GET_U32_BE(userKey, 4);
573
0
        w1[1] = GET_U32_BE(userKey, 5);
574
0
        if (bits > 192) {
575
0
            w1[2] = GET_U32_BE(userKey, 6);
576
0
            w1[3] = GET_U32_BE(userKey, 7);
577
0
        }
578
0
        else {
579
0
            w1[2] = w1[3] = 0;
580
0
        }
581
0
    }
582
0
    else {
583
0
        w1[0] = w1[1] = w1[2] = w1[3] = 0;
584
0
    }
585
0
586
0
    w1[0] ^= reg0;
587
0
    w1[1] ^= reg1;
588
0
    w1[2] ^= reg2;
589
0
    w1[3] ^= reg3;
590
0
591
0
    reg0 = w1[0];
592
0
    reg1 = w1[1];
593
0
    reg2 = w1[2];
594
0
    reg3 = w1[3];
595
0
596
0
    reg0 ^= ck[4];
597
0
    reg1 ^= ck[5];
598
0
    reg2 ^= ck[6];
599
0
    reg3 ^= ck[7];
600
0
601
0
    ARIA_SUBST_DIFF_EVEN(reg0, reg1, reg2, reg3);
602
0
603
0
    reg0 ^= w0[0];
604
0
    reg1 ^= w0[1];
605
0
    reg2 ^= w0[2];
606
0
    reg3 ^= w0[3];
607
0
608
0
    w2[0] = reg0;
609
0
    w2[1] = reg1;
610
0
    w2[2] = reg2;
611
0
    w2[3] = reg3;
612
0
613
0
    reg0 ^= ck[8];
614
0
    reg1 ^= ck[9];
615
0
    reg2 ^= ck[10];
616
0
    reg3 ^= ck[11];
617
0
618
0
    ARIA_SUBST_DIFF_ODD(reg0, reg1, reg2, reg3);
619
0
620
0
    w3[0] = reg0 ^ w1[0];
621
0
    w3[1] = reg1 ^ w1[1];
622
0
    w3[2] = reg2 ^ w1[2];
623
0
    w3[3] = reg3 ^ w1[3];
624
0
625
0
    ARIA_GSRK(rk, w0, w1, 19);
626
0
    rk++;
627
0
    ARIA_GSRK(rk, w1, w2, 19);
628
0
    rk++;
629
0
    ARIA_GSRK(rk, w2, w3, 19);
630
0
    rk++;
631
0
    ARIA_GSRK(rk, w3, w0, 19);
632
0
633
0
    rk++;
634
0
    ARIA_GSRK(rk, w0, w1, 31);
635
0
    rk++;
636
0
    ARIA_GSRK(rk, w1, w2, 31);
637
0
    rk++;
638
0
    ARIA_GSRK(rk, w2, w3, 31);
639
0
    rk++;
640
0
    ARIA_GSRK(rk, w3, w0, 31);
641
0
642
0
    rk++;
643
0
    ARIA_GSRK(rk, w0, w1, 67);
644
0
    rk++;
645
0
    ARIA_GSRK(rk, w1, w2, 67);
646
0
    rk++;
647
0
    ARIA_GSRK(rk, w2, w3, 67);
648
0
    rk++;
649
0
    ARIA_GSRK(rk, w3, w0, 67);
650
0
651
0
    rk++;
652
0
    ARIA_GSRK(rk, w0, w1, 97);
653
0
    if (bits > 128) {
654
0
        rk++;
655
0
        ARIA_GSRK(rk, w1, w2, 97);
656
0
        rk++;
657
0
        ARIA_GSRK(rk, w2, w3, 97);
658
0
    }
659
0
    if (bits > 192) {
660
0
        rk++;
661
0
        ARIA_GSRK(rk, w3, w0, 97);
662
0
663
0
        rk++;
664
0
        ARIA_GSRK(rk, w0, w1, 109);
665
0
    }
666
0
667
0
    return 0;
668
0
}
669
670
int 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
0
679
0
    const int r = aria_set_encrypt_key(userKey, bits, key);
680
0
681
0
    if (r != 0) {
682
0
        return r;
683
0
    }
684
0
685
0
    rk_head = key->rd_key;
686
0
    rk_tail = rk_head + key->rounds;
687
0
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
0
693
0
    memcpy(rk_head, rk_tail, ARIA_BLOCK_SIZE);
694
0
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
0
700
0
    rk_head++;
701
0
    rk_tail--;
702
0
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
0
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
0
713
0
        s0 = reg0;
714
0
        s1 = reg1;
715
0
        s2 = reg2;
716
0
        s3 = reg3;
717
0
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
0
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
0
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
0
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
0
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
0
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
0
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 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 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 aria_set_decrypt_key(const unsigned char *userKey, const int bits,
1196
                         ARIA_KEY *key)
1197
{
1198
    ARIA_KEY ek;
1199
    const int r = 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