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 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#define rotr32(v, r) (((uint32_t)(v) >> (r)) | ((uint32_t)(v) << (32 - r)))
34
35#define bswap32(v) \
36 (((v) << 24) ^ ((v) >> 24) ^ \
37 (((v) & 0x0000ff00) << 8) ^ (((v) & 0x00ff0000) >> 8))
38
39#define GET_U8_BE(X, Y) ((uint8_t)((X) >> ((3 - Y) * 8)))
40#define GET_U32_BE(X, Y) ( \
41 ((uint32_t)((const uint8_t *)(X))[Y * 4 ] << 24) ^ \
42 ((uint32_t)((const uint8_t *)(X))[Y * 4 + 1] << 16) ^ \
43 ((uint32_t)((const uint8_t *)(X))[Y * 4 + 2] << 8) ^ \
44 ((uint32_t)((const uint8_t *)(X))[Y * 4 + 3] ) )
45
46#define PUT_U32_BE(DEST, IDX, VAL) \
47 do { \
48 ((uint8_t *)(DEST))[IDX * 4 ] = GET_U8_BE(VAL, 0); \
49 ((uint8_t *)(DEST))[IDX * 4 + 1] = GET_U8_BE(VAL, 1); \
50 ((uint8_t *)(DEST))[IDX * 4 + 2] = GET_U8_BE(VAL, 2); \
51 ((uint8_t *)(DEST))[IDX * 4 + 3] = GET_U8_BE(VAL, 3); \
52 } while(0)
53
54#define MAKE_U32(V0, V1, V2, V3) ( \
55 ((uint32_t)((uint8_t)(V0)) << 24) | \
56 ((uint32_t)((uint8_t)(V1)) << 16) | \
57 ((uint32_t)((uint8_t)(V2)) << 8) | \
58 ((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 */
67static 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 */
76static 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
143static 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
210static 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
277static 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 do { \
347 (T0) ^= (RK)->u[0]; \
348 (T1) ^= (RK)->u[1]; \
349 (T2) ^= (RK)->u[2]; \
350 (T3) ^= (RK)->u[3]; \
351 } while(0)
352
353/* S-Box Layer 1 + M */
354#define ARIA_SBOX_LAYER1_WITH_PRE_DIFF(T0, T1, T2, T3) \
355 do { \
356 (T0) = \
357 S1[GET_U8_BE(T0, 0)] ^ \
358 S2[GET_U8_BE(T0, 1)] ^ \
359 X1[GET_U8_BE(T0, 2)] ^ \
360 X2[GET_U8_BE(T0, 3)]; \
361 (T1) = \
362 S1[GET_U8_BE(T1, 0)] ^ \
363 S2[GET_U8_BE(T1, 1)] ^ \
364 X1[GET_U8_BE(T1, 2)] ^ \
365 X2[GET_U8_BE(T1, 3)]; \
366 (T2) = \
367 S1[GET_U8_BE(T2, 0)] ^ \
368 S2[GET_U8_BE(T2, 1)] ^ \
369 X1[GET_U8_BE(T2, 2)] ^ \
370 X2[GET_U8_BE(T2, 3)]; \
371 (T3) = \
372 S1[GET_U8_BE(T3, 0)] ^ \
373 S2[GET_U8_BE(T3, 1)] ^ \
374 X1[GET_U8_BE(T3, 2)] ^ \
375 X2[GET_U8_BE(T3, 3)]; \
376 } while(0)
377
378/* S-Box Layer 2 + M */
379#define ARIA_SBOX_LAYER2_WITH_PRE_DIFF(T0, T1, T2, T3) \
380 do { \
381 (T0) = \
382 X1[GET_U8_BE(T0, 0)] ^ \
383 X2[GET_U8_BE(T0, 1)] ^ \
384 S1[GET_U8_BE(T0, 2)] ^ \
385 S2[GET_U8_BE(T0, 3)]; \
386 (T1) = \
387 X1[GET_U8_BE(T1, 0)] ^ \
388 X2[GET_U8_BE(T1, 1)] ^ \
389 S1[GET_U8_BE(T1, 2)] ^ \
390 S2[GET_U8_BE(T1, 3)]; \
391 (T2) = \
392 X1[GET_U8_BE(T2, 0)] ^ \
393 X2[GET_U8_BE(T2, 1)] ^ \
394 S1[GET_U8_BE(T2, 2)] ^ \
395 S2[GET_U8_BE(T2, 3)]; \
396 (T3) = \
397 X1[GET_U8_BE(T3, 0)] ^ \
398 X2[GET_U8_BE(T3, 1)] ^ \
399 S1[GET_U8_BE(T3, 2)] ^ \
400 S2[GET_U8_BE(T3, 3)]; \
401 } while(0)
402
403/* Word-level diffusion */
404#define ARIA_DIFF_WORD(T0,T1,T2,T3) \
405 do { \
406 (T1) ^= (T2); \
407 (T2) ^= (T3); \
408 (T0) ^= (T1); \
409 \
410 (T3) ^= (T1); \
411 (T2) ^= (T0); \
412 (T1) ^= (T2); \
413 } while(0)
414
415/* Byte-level diffusion */
416#define ARIA_DIFF_BYTE(T0, T1, T2, T3) \
417 do { \
418 (T1) = (((T1) << 8) & 0xff00ff00) ^ (((T1) >> 8) & 0x00ff00ff); \
419 (T2) = rotr32(T2, 16); \
420 (T3) = bswap32(T3); \
421 } while(0)
422
423/* Odd round Substitution & Diffusion */
424#define ARIA_SUBST_DIFF_ODD(T0, T1, T2, T3) \
425 do { \
426 ARIA_SBOX_LAYER1_WITH_PRE_DIFF(T0, T1, T2, T3); \
427 ARIA_DIFF_WORD(T0, T1, T2, T3); \
428 ARIA_DIFF_BYTE(T0, T1, T2, T3); \
429 ARIA_DIFF_WORD(T0, T1, T2, T3); \
430 } while(0)
431
432/* Even round Substitution & Diffusion */
433#define ARIA_SUBST_DIFF_EVEN(T0, T1, T2, T3) \
434 do { \
435 ARIA_SBOX_LAYER2_WITH_PRE_DIFF(T0, T1, T2, T3); \
436 ARIA_DIFF_WORD(T0, T1, T2, T3); \
437 ARIA_DIFF_BYTE(T2, T3, T0, T1); \
438 ARIA_DIFF_WORD(T0, T1, T2, T3); \
439 } while(0)
440
441/* Q, R Macro expanded ARIA GSRK */
442#define _ARIA_GSRK(RK, X, Y, Q, R) \
443 do { \
444 (RK)->u[0] = \
445 ((X)[0]) ^ \
446 (((Y)[((Q) ) % 4]) >> (R)) ^ \
447 (((Y)[((Q) + 3) % 4]) << (32 - (R))); \
448 (RK)->u[1] = \
449 ((X)[1]) ^ \
450 (((Y)[((Q) + 1) % 4]) >> (R)) ^ \
451 (((Y)[((Q) ) % 4]) << (32 - (R))); \
452 (RK)->u[2] = \
453 ((X)[2]) ^ \
454 (((Y)[((Q) + 2) % 4]) >> (R)) ^ \
455 (((Y)[((Q) + 1) % 4]) << (32 - (R))); \
456 (RK)->u[3] = \
457 ((X)[3]) ^ \
458 (((Y)[((Q) + 3) % 4]) >> (R)) ^ \
459 (((Y)[((Q) + 2) % 4]) << (32 - (R))); \
460 } while(0)
461
462#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 do { \
466 (TMP) = (X); \
467 (TMP2) = rotr32((TMP), 8); \
468 (Y) = (TMP2) ^ rotr32((TMP) ^ (TMP2), 16); \
469 } while(0)
470
471void aria_encrypt(const unsigned char *in, unsigned char *out,
472 const ARIA_KEY *key)
473{
474 register uint32_t reg0, reg1, reg2, reg3;
475 int Nr;
476 const ARIA_u128 *rk;
477
478 if (in == NULL || out == NULL || key == NULL) {
479 return;
480 }
481
482 rk = key->rd_key;
483 Nr = key->rounds;
484
485 if (Nr != 12 && Nr != 14 && Nr != 16) {
486 return;
487 }
488
489 reg0 = GET_U32_BE(in, 0);
490 reg1 = GET_U32_BE(in, 1);
491 reg2 = GET_U32_BE(in, 2);
492 reg3 = GET_U32_BE(in, 3);
493
494 ARIA_ADD_ROUND_KEY(rk, reg0, reg1, reg2, reg3);
495 rk++;
496
497 ARIA_SUBST_DIFF_ODD(reg0, reg1, reg2, reg3);
498 ARIA_ADD_ROUND_KEY(rk, reg0, reg1, reg2, reg3);
499 rk++;
500
501 while(Nr -= 2){
502 ARIA_SUBST_DIFF_EVEN(reg0, reg1, reg2, reg3);
503 ARIA_ADD_ROUND_KEY(rk, reg0, reg1, reg2, reg3);
504 rk++;
505
506 ARIA_SUBST_DIFF_ODD(reg0, reg1, reg2, reg3);
507 ARIA_ADD_ROUND_KEY(rk, reg0, reg1, reg2, reg3);
508 rk++;
509 }
510
511 reg0 = rk->u[0] ^ MAKE_U32(
512 (uint8_t)(X1[GET_U8_BE(reg0, 0)] ),
513 (uint8_t)(X2[GET_U8_BE(reg0, 1)] >> 8),
514 (uint8_t)(S1[GET_U8_BE(reg0, 2)] ),
515 (uint8_t)(S2[GET_U8_BE(reg0, 3)] ));
516 reg1 = rk->u[1] ^ MAKE_U32(
517 (uint8_t)(X1[GET_U8_BE(reg1, 0)] ),
518 (uint8_t)(X2[GET_U8_BE(reg1, 1)] >> 8),
519 (uint8_t)(S1[GET_U8_BE(reg1, 2)] ),
520 (uint8_t)(S2[GET_U8_BE(reg1, 3)] ));
521 reg2 = rk->u[2] ^ MAKE_U32(
522 (uint8_t)(X1[GET_U8_BE(reg2, 0)] ),
523 (uint8_t)(X2[GET_U8_BE(reg2, 1)] >> 8),
524 (uint8_t)(S1[GET_U8_BE(reg2, 2)] ),
525 (uint8_t)(S2[GET_U8_BE(reg2, 3)] ));
526 reg3 = rk->u[3] ^ MAKE_U32(
527 (uint8_t)(X1[GET_U8_BE(reg3, 0)] ),
528 (uint8_t)(X2[GET_U8_BE(reg3, 1)] >> 8),
529 (uint8_t)(S1[GET_U8_BE(reg3, 2)] ),
530 (uint8_t)(S2[GET_U8_BE(reg3, 3)] ));
531
532 PUT_U32_BE(out, 0, reg0);
533 PUT_U32_BE(out, 1, reg1);
534 PUT_U32_BE(out, 2, reg2);
535 PUT_U32_BE(out, 3, reg3);
536}
537
538int aria_set_encrypt_key(const unsigned char *userKey, const int bits,
539 ARIA_KEY *key)
540{
541 register uint32_t reg0, reg1, reg2, reg3;
542 uint32_t w0[4], w1[4], w2[4], w3[4];
543 const uint32_t *ck;
544
545 ARIA_u128 *rk;
546 int Nr = (bits + 256) / 32;
547
548 if (userKey == NULL || key == NULL) {
549 return -1;
550 }
551 if (bits != 128 && bits != 192 && bits != 256) {
552 return -2;
553 }
554
555 rk = key->rd_key;
556 key->rounds = Nr;
557 ck = &Key_RC[(bits - 128) / 64][0];
558
559 w0[0] = GET_U32_BE(userKey, 0);
560 w0[1] = GET_U32_BE(userKey, 1);
561 w0[2] = GET_U32_BE(userKey, 2);
562 w0[3] = GET_U32_BE(userKey, 3);
563
564 reg0 = w0[0] ^ ck[0];
565 reg1 = w0[1] ^ ck[1];
566 reg2 = w0[2] ^ ck[2];
567 reg3 = w0[3] ^ ck[3];
568
569 ARIA_SUBST_DIFF_ODD(reg0, reg1, reg2, reg3);
570
571 if (bits > 128) {
572 w1[0] = GET_U32_BE(userKey, 4);
573 w1[1] = GET_U32_BE(userKey, 5);
574 if (bits > 192) {
575 w1[2] = GET_U32_BE(userKey, 6);
576 w1[3] = GET_U32_BE(userKey, 7);
577 }
578 else {
579 w1[2] = w1[3] = 0;
580 }
581 }
582 else {
583 w1[0] = w1[1] = w1[2] = w1[3] = 0;
584 }
585
586 w1[0] ^= reg0;
587 w1[1] ^= reg1;
588 w1[2] ^= reg2;
589 w1[3] ^= reg3;
590
591 reg0 = w1[0];
592 reg1 = w1[1];
593 reg2 = w1[2];
594 reg3 = w1[3];
595
596 reg0 ^= ck[4];
597 reg1 ^= ck[5];
598 reg2 ^= ck[6];
599 reg3 ^= ck[7];
600
601 ARIA_SUBST_DIFF_EVEN(reg0, reg1, reg2, reg3);
602
603 reg0 ^= w0[0];
604 reg1 ^= w0[1];
605 reg2 ^= w0[2];
606 reg3 ^= w0[3];
607
608 w2[0] = reg0;
609 w2[1] = reg1;
610 w2[2] = reg2;
611 w2[3] = reg3;
612
613 reg0 ^= ck[8];
614 reg1 ^= ck[9];
615 reg2 ^= ck[10];
616 reg3 ^= ck[11];
617
618 ARIA_SUBST_DIFF_ODD(reg0, reg1, reg2, reg3);
619
620 w3[0] = reg0 ^ w1[0];
621 w3[1] = reg1 ^ w1[1];
622 w3[2] = reg2 ^ w1[2];
623 w3[3] = reg3 ^ w1[3];
624
625 ARIA_GSRK(rk, w0, w1, 19);
626 rk++;
627 ARIA_GSRK(rk, w1, w2, 19);
628 rk++;
629 ARIA_GSRK(rk, w2, w3, 19);
630 rk++;
631 ARIA_GSRK(rk, w3, w0, 19);
632
633 rk++;
634 ARIA_GSRK(rk, w0, w1, 31);
635 rk++;
636 ARIA_GSRK(rk, w1, w2, 31);
637 rk++;
638 ARIA_GSRK(rk, w2, w3, 31);
639 rk++;
640 ARIA_GSRK(rk, w3, w0, 31);
641
642 rk++;
643 ARIA_GSRK(rk, w0, w1, 67);
644 rk++;
645 ARIA_GSRK(rk, w1, w2, 67);
646 rk++;
647 ARIA_GSRK(rk, w2, w3, 67);
648 rk++;
649 ARIA_GSRK(rk, w3, w0, 67);
650
651 rk++;
652 ARIA_GSRK(rk, w0, w1, 97);
653 if (bits > 128) {
654 rk++;
655 ARIA_GSRK(rk, w1, w2, 97);
656 rk++;
657 ARIA_GSRK(rk, w2, w3, 97);
658 }
659 if (bits > 192) {
660 rk++;
661 ARIA_GSRK(rk, w3, w0, 97);
662
663 rk++;
664 ARIA_GSRK(rk, w0, w1, 109);
665 }
666
667 return 0;
668}
669
670int aria_set_decrypt_key(const unsigned char *userKey, const int bits,
671 ARIA_KEY *key)
672{
673 ARIA_u128 *rk_head;
674 ARIA_u128 *rk_tail;
675 register uint32_t w1, w2;
676 register uint32_t reg0, reg1, reg2, reg3;
677 uint32_t s0, s1, s2, s3;
678
679 const int r = aria_set_encrypt_key(userKey, bits, key);
680
681 if (r != 0) {
682 return r;
683 }
684
685 rk_head = key->rd_key;
686 rk_tail = rk_head + key->rounds;
687
688 reg0 = rk_head->u[0];
689 reg1 = rk_head->u[1];
690 reg2 = rk_head->u[2];
691 reg3 = rk_head->u[3];
692
693 memcpy(rk_head, rk_tail, ARIA_BLOCK_SIZE);
694
695 rk_tail->u[0] = reg0;
696 rk_tail->u[1] = reg1;
697 rk_tail->u[2] = reg2;
698 rk_tail->u[3] = reg3;
699
700 rk_head++;
701 rk_tail--;
702
703 for (; rk_head < rk_tail; rk_head++, rk_tail--) {
704 ARIA_DEC_DIFF_BYTE(rk_head->u[0], reg0, w1, w2);
705 ARIA_DEC_DIFF_BYTE(rk_head->u[1], reg1, w1, w2);
706 ARIA_DEC_DIFF_BYTE(rk_head->u[2], reg2, w1, w2);
707 ARIA_DEC_DIFF_BYTE(rk_head->u[3], reg3, w1, w2);
708
709 ARIA_DIFF_WORD(reg0, reg1, reg2, reg3);
710 ARIA_DIFF_BYTE(reg0, reg1, reg2, reg3);
711 ARIA_DIFF_WORD(reg0, reg1, reg2, reg3);
712
713 s0 = reg0;
714 s1 = reg1;
715 s2 = reg2;
716 s3 = reg3;
717
718 ARIA_DEC_DIFF_BYTE(rk_tail->u[0], reg0, w1, w2);
719 ARIA_DEC_DIFF_BYTE(rk_tail->u[1], reg1, w1, w2);
720 ARIA_DEC_DIFF_BYTE(rk_tail->u[2], reg2, w1, w2);
721 ARIA_DEC_DIFF_BYTE(rk_tail->u[3], reg3, w1, w2);
722
723 ARIA_DIFF_WORD(reg0, reg1, reg2, reg3);
724 ARIA_DIFF_BYTE(reg0, reg1, reg2, reg3);
725 ARIA_DIFF_WORD(reg0, reg1, reg2, reg3);
726
727 rk_head->u[0] = reg0;
728 rk_head->u[1] = reg1;
729 rk_head->u[2] = reg2;
730 rk_head->u[3] = reg3;
731
732 rk_tail->u[0] = s0;
733 rk_tail->u[1] = s1;
734 rk_tail->u[2] = s2;
735 rk_tail->u[3] = s3;
736 }
737 ARIA_DEC_DIFF_BYTE(rk_head->u[0], reg0, w1, w2);
738 ARIA_DEC_DIFF_BYTE(rk_head->u[1], reg1, w1, w2);
739 ARIA_DEC_DIFF_BYTE(rk_head->u[2], reg2, w1, w2);
740 ARIA_DEC_DIFF_BYTE(rk_head->u[3], reg3, w1, w2);
741
742 ARIA_DIFF_WORD(reg0, reg1, reg2, reg3);
743 ARIA_DIFF_BYTE(reg0, reg1, reg2, reg3);
744 ARIA_DIFF_WORD(reg0, reg1, reg2, reg3);
745
746 rk_tail->u[0] = reg0;
747 rk_tail->u[1] = reg1;
748 rk_tail->u[2] = reg2;
749 rk_tail->u[3] = reg3;
750
751 return 0;
752}
753
754#else
755
756static 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
791static 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
826static 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
861static 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
896static const ARIA_u128 c1 = {{
897 0x51, 0x7c, 0xc1, 0xb7, 0x27, 0x22, 0x0a, 0x94,
898 0xfe, 0x13, 0xab, 0xe8, 0xfa, 0x9a, 0x6e, 0xe0
899}};
900
901static const ARIA_u128 c2 = {{
902 0x6d, 0xb1, 0x4a, 0xcc, 0x9e, 0x21, 0xc8, 0x20,
903 0xff, 0x28, 0xb1, 0xd5, 0xef, 0x5d, 0xe2, 0xb0
904}};
905
906static 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 */
915static 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 */
927static 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 */
946static 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 */
955static 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 */
964static 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 */
973static 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 */
982static 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 */
991static 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 */
1006static 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 */
1021static 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 */
1062static 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 */
1076static 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 */
1089static 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 */
1109void 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 */
1122int 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 */
1195int 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
1213