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