1139790Simp/*
21543Srgrimes * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
31543Srgrimes * Copyright (c) 2017, Oracle and/or its affiliates.  All rights reserved.
41543Srgrimes *
51543Srgrimes * Licensed under the Apache License 2.0 (the "License").  You may not use
61543Srgrimes * this file except in compliance with the License.  You can obtain a copy
71543Srgrimes * in the file LICENSE in the source distribution or at
81543Srgrimes * https://www.openssl.org/source/license.html
91543Srgrimes */
101543Srgrimes
111543Srgrimes/*
121543Srgrimes * Copyright (C) 2017 National Security Research Institute. All Rights Reserved.
131543Srgrimes *
141543Srgrimes * Information for ARIA
151543Srgrimes *     http://210.104.33.10/ARIA/index-e.html (English)
161543Srgrimes *     http://seed.kisa.or.kr/ (Korean)
171543Srgrimes *
181543Srgrimes * Public domain version is distributed above.
191543Srgrimes */
201543Srgrimes
211543Srgrimes#include <openssl/e_os2.h>
221543Srgrimes#include "crypto/aria.h"
231543Srgrimes
241543Srgrimes#include <assert.h>
251543Srgrimes#include <string.h>
261543Srgrimes
271543Srgrimes#ifndef OPENSSL_SMALL_FOOTPRINT
281543Srgrimes
291543Srgrimes/* Begin macro */
3050477Speter
311543Srgrimes/* rotation */
321543Srgrimes#define rotl32(v, r) (((uint32_t)(v) << (r)) | ((uint32_t)(v) >> (32 - r)))
3313107Sbde#define rotr32(v, r) (((uint32_t)(v) >> (r)) | ((uint32_t)(v) << (32 - r)))
3413107Sbde
352166Spaul#define bswap32(v)                                          \
36143063Sjoerg    (((v) << 24) ^ ((v) >> 24) ^                            \
37143063Sjoerg    (((v) & 0x0000ff00) << 8) ^ (((v) & 0x00ff0000) >> 8))
38143063Sjoerg
39143063Sjoerg#define GET_U8_BE(X, Y) ((uint8_t)((X) >> ((3 - Y) * 8)))
4055205Speter#define GET_U32_BE(X, Y) (                                  \
4137542Sbde    ((uint32_t)((const uint8_t *)(X))[Y * 4    ] << 24) ^   \
4213157Sbde    ((uint32_t)((const uint8_t *)(X))[Y * 4 + 1] << 16) ^   \
4322639Sbde    ((uint32_t)((const uint8_t *)(X))[Y * 4 + 2] <<  8) ^   \
4422639Sbde    ((uint32_t)((const uint8_t *)(X))[Y * 4 + 3]      )     )
4522639Sbde
4622639Sbde#define PUT_U32_BE(DEST, IDX, VAL)                              \
4722639Sbde    do {                                                        \
4822639Sbde        ((uint8_t *)(DEST))[IDX * 4    ] = GET_U8_BE(VAL, 0);   \
4913157Sbde        ((uint8_t *)(DEST))[IDX * 4 + 1] = GET_U8_BE(VAL, 1);   \
5013157Sbde        ((uint8_t *)(DEST))[IDX * 4 + 2] = GET_U8_BE(VAL, 2);   \
5113157Sbde        ((uint8_t *)(DEST))[IDX * 4 + 3] = GET_U8_BE(VAL, 3);   \
5213157Sbde    } while(0)
5313157Sbde
5413157Sbde#define MAKE_U32(V0, V1, V2, V3) (      \
551543Srgrimes    ((uint32_t)((uint8_t)(V0)) << 24) | \
5617879Sbde    ((uint32_t)((uint8_t)(V1)) << 16) | \
5717879Sbde    ((uint32_t)((uint8_t)(V2)) <<  8) | \
5817879Sbde    ((uint32_t)((uint8_t)(V3))      )   )
5917879Sbde
60143063Sjoerg/* End Macro*/
61129498Sbde
62129498Sbde/* Key Constant
63129498Sbde * 128bit : 0, 1,    2
64163729Sbde * 192bit : 1, 2,    3(0)
65129498Sbde * 256bit : 2, 3(0), 4(1)
66129498Sbde */
67129498Sbdestatic const uint32_t Key_RC[5][4] = {
68129498Sbde    { 0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0 },
69129498Sbde    { 0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0 },
70129498Sbde    { 0xdb92371d, 0x2126e970, 0x03249775, 0x04e8c90e },
71129498Sbde    { 0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0 },
72129498Sbde    { 0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0 }
73129498Sbde};
74129498Sbde
75129498Sbde/* 32bit expanded s-box */
7617879Sbdestatic const uint32_t S1[256] = {
77129498Sbde    0x00636363, 0x007c7c7c, 0x00777777, 0x007b7b7b,
78143063Sjoerg    0x00f2f2f2, 0x006b6b6b, 0x006f6f6f, 0x00c5c5c5,
79129498Sbde    0x00303030, 0x00010101, 0x00676767, 0x002b2b2b,
80214346Sjhb    0x00fefefe, 0x00d7d7d7, 0x00ababab, 0x00767676,
8128921Sfsmp    0x00cacaca, 0x00828282, 0x00c9c9c9, 0x007d7d7d,
8290024Sbde    0x00fafafa, 0x00595959, 0x00474747, 0x00f0f0f0,
83214346Sjhb    0x00adadad, 0x00d4d4d4, 0x00a2a2a2, 0x00afafaf,
8479734Sjhb    0x009c9c9c, 0x00a4a4a4, 0x00727272, 0x00c0c0c0,
8578908Sjhb    0x00b7b7b7, 0x00fdfdfd, 0x00939393, 0x00262626,
8678908Sjhb    0x00363636, 0x003f3f3f, 0x00f7f7f7, 0x00cccccc,
87214346Sjhb    0x00343434, 0x00a5a5a5, 0x00e5e5e5, 0x00f1f1f1,
8828921Sfsmp    0x00717171, 0x00d8d8d8, 0x00313131, 0x00151515,
89214346Sjhb    0x00040404, 0x00c7c7c7, 0x00232323, 0x00c3c3c3,
90214346Sjhb    0x00181818, 0x00969696, 0x00050505, 0x009a9a9a,
9128921Sfsmp    0x00070707, 0x00121212, 0x00808080, 0x00e2e2e2,
9217879Sbde    0x00ebebeb, 0x00272727, 0x00b2b2b2, 0x00757575,
9317879Sbde    0x00090909, 0x00838383, 0x002c2c2c, 0x001a1a1a,
94134398Smarcel    0x001b1b1b, 0x006e6e6e, 0x005a5a5a, 0x00a0a0a0,
95134398Smarcel    0x00525252, 0x003b3b3b, 0x00d6d6d6, 0x00b3b3b3,
96134398Smarcel    0x00292929, 0x00e3e3e3, 0x002f2f2f, 0x00848484,
97134398Smarcel    0x00535353, 0x00d1d1d1, 0x00000000, 0x00ededed,
98134398Smarcel    0x00202020, 0x00fcfcfc, 0x00b1b1b1, 0x005b5b5b,
99134398Smarcel    0x006a6a6a, 0x00cbcbcb, 0x00bebebe, 0x00393939,
100134398Smarcel    0x004a4a4a, 0x004c4c4c, 0x00585858, 0x00cfcfcf,
101134398Smarcel    0x00d0d0d0, 0x00efefef, 0x00aaaaaa, 0x00fbfbfb,
102134398Smarcel    0x00434343, 0x004d4d4d, 0x00333333, 0x00858585,
103134398Smarcel    0x00454545, 0x00f9f9f9, 0x00020202, 0x007f7f7f,
104134398Smarcel    0x00505050, 0x003c3c3c, 0x009f9f9f, 0x00a8a8a8,
105134398Smarcel    0x00515151, 0x00a3a3a3, 0x00404040, 0x008f8f8f,
106134398Smarcel    0x00929292, 0x009d9d9d, 0x00383838, 0x00f5f5f5,
10755205Speter    0x00bcbcbc, 0x00b6b6b6, 0x00dadada, 0x00212121,
10813157Sbde    0x00101010, 0x00ffffff, 0x00f3f3f3, 0x00d2d2d2,
10922639Sbde    0x00cdcdcd, 0x000c0c0c, 0x00131313, 0x00ececec,
11022639Sbde    0x005f5f5f, 0x00979797, 0x00444444, 0x00171717,
11113157Sbde    0x00c4c4c4, 0x00a7a7a7, 0x007e7e7e, 0x003d3d3d,
11213157Sbde    0x00646464, 0x005d5d5d, 0x00191919, 0x00737373,
113143063Sjoerg    0x00606060, 0x00818181, 0x004f4f4f, 0x00dcdcdc,
11495195Smarkm    0x00222222, 0x002a2a2a, 0x00909090, 0x00888888,
11595195Smarkm    0x00464646, 0x00eeeeee, 0x00b8b8b8, 0x00141414,
11695195Smarkm    0x00dedede, 0x005e5e5e, 0x000b0b0b, 0x00dbdbdb,
11795195Smarkm    0x00e0e0e0, 0x00323232, 0x003a3a3a, 0x000a0a0a,
118180756Sluoqi    0x00494949, 0x00060606, 0x00242424, 0x005c5c5c,
11995195Smarkm    0x00c2c2c2, 0x00d3d3d3, 0x00acacac, 0x00626262,
120180756Sluoqi    0x00919191, 0x00959595, 0x00e4e4e4, 0x00797979,
121180756Sluoqi    0x00e7e7e7, 0x00c8c8c8, 0x00373737, 0x006d6d6d,
122180756Sluoqi    0x008d8d8d, 0x00d5d5d5, 0x004e4e4e, 0x00a9a9a9,
123180756Sluoqi    0x006c6c6c, 0x00565656, 0x00f4f4f4, 0x00eaeaea,
124180756Sluoqi    0x00656565, 0x007a7a7a, 0x00aeaeae, 0x00080808,
125180756Sluoqi    0x00bababa, 0x00787878, 0x00252525, 0x002e2e2e,
126180756Sluoqi    0x001c1c1c, 0x00a6a6a6, 0x00b4b4b4, 0x00c6c6c6,
127180756Sluoqi    0x00e8e8e8, 0x00dddddd, 0x00747474, 0x001f1f1f,
12895195Smarkm    0x004b4b4b, 0x00bdbdbd, 0x008b8b8b, 0x008a8a8a,
12995195Smarkm    0x00707070, 0x003e3e3e, 0x00b5b5b5, 0x00666666,
13095195Smarkm    0x00484848, 0x00030303, 0x00f6f6f6, 0x000e0e0e,
13195195Smarkm    0x00616161, 0x00353535, 0x00575757, 0x00b9b9b9,
13295195Smarkm    0x00868686, 0x00c1c1c1, 0x001d1d1d, 0x009e9e9e,
133115659Sobrien    0x00e1e1e1, 0x00f8f8f8, 0x00989898, 0x00111111,
13495195Smarkm    0x00696969, 0x00d9d9d9, 0x008e8e8e, 0x00949494,
13595195Smarkm    0x009b9b9b, 0x001e1e1e, 0x00878787, 0x00e9e9e9,
13695195Smarkm    0x00cecece, 0x00555555, 0x00282828, 0x00dfdfdf,
13795195Smarkm    0x008c8c8c, 0x00a1a1a1, 0x00898989, 0x000d0d0d,
13895195Smarkm    0x00bfbfbf, 0x00e6e6e6, 0x00424242, 0x00686868,
13995195Smarkm    0x00414141, 0x00999999, 0x002d2d2d, 0x000f0f0f,
140129445Sbde    0x00b0b0b0, 0x00545454, 0x00bbbbbb, 0x00161616
14195195Smarkm};
14295195Smarkm
143180756Sluoqistatic const uint32_t S2[256] = {
1441543Srgrimes    0xe200e2e2, 0x4e004e4e, 0x54005454, 0xfc00fcfc,
145143063Sjoerg    0x94009494, 0xc200c2c2, 0x4a004a4a, 0xcc00cccc,
146163735Sbde    0x62006262, 0x0d000d0d, 0x6a006a6a, 0x46004646,
147143063Sjoerg    0x3c003c3c, 0x4d004d4d, 0x8b008b8b, 0xd100d1d1,
14837542Sbde    0x5e005e5e, 0xfa00fafa, 0x64006464, 0xcb00cbcb,
149129445Sbde    0xb400b4b4, 0x97009797, 0xbe00bebe, 0x2b002b2b,
15037542Sbde    0xbc00bcbc, 0x77007777, 0x2e002e2e, 0x03000303,
15155205Speter    0xd300d3d3, 0x19001919, 0x59005959, 0xc100c1c1,
1522166Spaul    0x1d001d1d, 0x06000606, 0x41004141, 0x6b006b6b,
15313107Sbde    0x55005555, 0xf000f0f0, 0x99009999, 0x69006969,
15413107Sbde    0xea00eaea, 0x9c009c9c, 0x18001818, 0xae00aeae,
15513107Sbde    0x63006363, 0xdf00dfdf, 0xe700e7e7, 0xbb00bbbb,
15613107Sbde    0x00000000, 0x73007373, 0x66006666, 0xfb00fbfb,
15731723Stegge    0x96009696, 0x4c004c4c, 0x85008585, 0xe400e4e4,
15813107Sbde    0x3a003a3a, 0x09000909, 0x45004545, 0xaa00aaaa,
15955205Speter    0x0f000f0f, 0xee00eeee, 0x10001010, 0xeb00ebeb,
16019000Sbde    0x2d002d2d, 0x7f007f7f, 0xf400f4f4, 0x29002929,
16192761Salfred    0xac00acac, 0xcf00cfcf, 0xad00adad, 0x91009191,
16219000Sbde    0x8d008d8d, 0x78007878, 0xc800c8c8, 0x95009595,
16355205Speter    0xf900f9f9, 0x2f002f2f, 0xce00cece, 0xcd00cdcd,
16419000Sbde    0x08000808, 0x7a007a7a, 0x88008888, 0x38003838,
16519000Sbde    0x5c005c5c, 0x83008383, 0x2a002a2a, 0x28002828,
16619000Sbde    0x47004747, 0xdb00dbdb, 0xb800b8b8, 0xc700c7c7,
16719000Sbde    0x93009393, 0xa400a4a4, 0x12001212, 0x53005353,
168143063Sjoerg    0xff00ffff, 0x87008787, 0x0e000e0e, 0x31003131,
16992761Salfred    0x36003636, 0x21002121, 0x58005858, 0x48004848,
17033047Sbde    0x01000101, 0x8e008e8e, 0x37003737, 0x74007474,
17119000Sbde    0x32003232, 0xca00caca, 0xe900e9e9, 0xb100b1b1,
17213157Sbde    0xb700b7b7, 0xab00abab, 0x0c000c0c, 0xd700d7d7,
17355205Speter    0xc400c4c4, 0x56005656, 0x42004242, 0x26002626,
17419000Sbde    0x07000707, 0x98009898, 0x60006060, 0xd900d9d9,
17513157Sbde    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 ossl_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 ossl_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 ossl_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 = ossl_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 ossl_aria_encrypt(const unsigned char *in, unsigned char *out,
1110                       const ARIA_KEY *key)
1111{
1112    assert(in != NULL && out != NULL && key != NULL);
1113    do_encrypt(out, in, key->rounds, key->rd_key);
1114}
1115
1116
1117/*
1118 * Expand the cipher key into the encryption key schedule.
1119 * We short circuit execution of the last two
1120 * or four rotations based on the key size.
1121 */
1122int ossl_aria_set_encrypt_key(const unsigned char *userKey, const int bits,
1123                              ARIA_KEY *key)
1124{
1125    const ARIA_u128 *ck1, *ck2, *ck3;
1126    ARIA_u128 kr, w0, w1, w2, w3;
1127
1128    if (!userKey || !key)
1129        return -1;
1130    memcpy(w0.c, userKey, sizeof(w0));
1131    switch (bits) {
1132    default:
1133        return -2;
1134    case 128:
1135        key->rounds = 12;
1136        ck1 = &c1;
1137        ck2 = &c2;
1138        ck3 = &c3;
1139        memset(kr.c, 0, sizeof(kr));
1140        break;
1141
1142    case 192:
1143        key->rounds = 14;
1144        ck1 = &c2;
1145        ck2 = &c3;
1146        ck3 = &c1;
1147        memcpy(kr.c, userKey + ARIA_BLOCK_SIZE, sizeof(kr) / 2);
1148        memset(kr.c + ARIA_BLOCK_SIZE / 2, 0, sizeof(kr) / 2);
1149        break;
1150
1151    case 256:
1152        key->rounds = 16;
1153        ck1 = &c3;
1154        ck2 = &c1;
1155        ck3 = &c2;
1156        memcpy(kr.c, userKey + ARIA_BLOCK_SIZE, sizeof(kr));
1157        break;
1158    }
1159
1160    FO(&w3, &w0, ck1);    xor128(w1.c, w3.c, &kr);
1161    FE(&w3, &w1, ck2);    xor128(w2.c, w3.c, &w0);
1162    FO(&kr, &w2, ck3);    xor128(w3.c, kr.c, &w1);
1163
1164    rot19r(&key->rd_key[ 0], &w0, &w1);
1165    rot19r(&key->rd_key[ 1], &w1, &w2);
1166    rot19r(&key->rd_key[ 2], &w2, &w3);
1167    rot19r(&key->rd_key[ 3], &w3, &w0);
1168
1169    rot31r(&key->rd_key[ 4], &w0, &w1);
1170    rot31r(&key->rd_key[ 5], &w1, &w2);
1171    rot31r(&key->rd_key[ 6], &w2, &w3);
1172    rot31r(&key->rd_key[ 7], &w3, &w0);
1173
1174    rot61l(&key->rd_key[ 8], &w0, &w1);
1175    rot61l(&key->rd_key[ 9], &w1, &w2);
1176    rot61l(&key->rd_key[10], &w2, &w3);
1177    rot61l(&key->rd_key[11], &w3, &w0);
1178
1179    rot31l(&key->rd_key[12], &w0, &w1);
1180    if (key->rounds > 12) {
1181        rot31l(&key->rd_key[13], &w1, &w2);
1182        rot31l(&key->rd_key[14], &w2, &w3);
1183
1184        if (key->rounds > 14) {
1185            rot31l(&key->rd_key[15], &w3, &w0);
1186            rot19l(&key->rd_key[16], &w0, &w1);
1187        }
1188    }
1189    return 0;
1190}
1191
1192/*
1193 * Expand the cipher key into the decryption key schedule.
1194 */
1195int ossl_aria_set_decrypt_key(const unsigned char *userKey, const int bits,
1196                              ARIA_KEY *key)
1197{
1198    ARIA_KEY ek;
1199    const int r = ossl_aria_set_encrypt_key(userKey, bits, &ek);
1200    unsigned int i, rounds = ek.rounds;
1201
1202    if (r == 0) {
1203        key->rounds = rounds;
1204        memcpy(&key->rd_key[0], &ek.rd_key[rounds], sizeof(key->rd_key[0]));
1205        for (i = 1; i < rounds; i++)
1206            a(&key->rd_key[i], &ek.rd_key[rounds - i]);
1207        memcpy(&key->rd_key[rounds], &ek.rd_key[0], sizeof(key->rd_key[rounds]));
1208    }
1209    return r;
1210}
1211
1212#endif
1213