1162911Ssimon/* crypto/camellia/camellia.c -*- mode:C; c-file-style: "eay" -*- */
2162911Ssimon/* ====================================================================
3296465Sdelphij * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) .
4162911Ssimon * ALL RIGHTS RESERVED.
5162911Ssimon *
6162911Ssimon * Intellectual Property information for Camellia:
7162911Ssimon *     http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
8162911Ssimon *
9162911Ssimon * News Release for Announcement of Camellia open source:
10162911Ssimon *     http://www.ntt.co.jp/news/news06e/0604/060413a.html
11162911Ssimon *
12162911Ssimon * The Camellia Code included herein is developed by
13162911Ssimon * NTT (Nippon Telegraph and Telephone Corporation), and is contributed
14162911Ssimon * to the OpenSSL project.
15162911Ssimon *
16162911Ssimon * The Camellia Code is licensed pursuant to the OpenSSL open source
17162911Ssimon * license provided below.
18162911Ssimon */
19162911Ssimon/* ====================================================================
20162911Ssimon * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
21162911Ssimon *
22162911Ssimon * Redistribution and use in source and binary forms, with or without
23162911Ssimon * modification, are permitted provided that the following conditions
24162911Ssimon * are met:
25162911Ssimon *
26162911Ssimon * 1. Redistributions of source code must retain the above copyright
27296465Sdelphij *    notice, this list of conditions and the following disclaimer.
28162911Ssimon *
29162911Ssimon * 2. Redistributions in binary form must reproduce the above copyright
30162911Ssimon *    notice, this list of conditions and the following disclaimer in
31162911Ssimon *    the documentation and/or other materials provided with the
32162911Ssimon *    distribution.
33162911Ssimon *
34162911Ssimon * 3. All advertising materials mentioning features or use of this
35162911Ssimon *    software must display the following acknowledgment:
36162911Ssimon *    "This product includes software developed by the OpenSSL Project
37162911Ssimon *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
38162911Ssimon *
39162911Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
40162911Ssimon *    endorse or promote products derived from this software without
41162911Ssimon *    prior written permission. For written permission, please contact
42162911Ssimon *    openssl-core@openssl.org.
43162911Ssimon *
44162911Ssimon * 5. Products derived from this software may not be called "OpenSSL"
45162911Ssimon *    nor may "OpenSSL" appear in their names without prior written
46162911Ssimon *    permission of the OpenSSL Project.
47162911Ssimon *
48162911Ssimon * 6. Redistributions of any form whatsoever must retain the following
49162911Ssimon *    acknowledgment:
50162911Ssimon *    "This product includes software developed by the OpenSSL Project
51162911Ssimon *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
52162911Ssimon *
53162911Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
54162911Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55162911Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56162911Ssimon * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
57162911Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
58162911Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
59162911Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60162911Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61162911Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
62162911Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
63162911Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
64162911Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE.
65162911Ssimon * ====================================================================
66162911Ssimon */
67162911Ssimon
68296465Sdelphij/*
69296465Sdelphij * Algorithm Specification
70296465Sdelphij * http://info.isl.llia/specicrypt/eng/camellia/specifications.html
71296465Sdelphij */
72162911Ssimon
73162911Ssimon#include <string.h>
74162911Ssimon#include <stdlib.h>
75162911Ssimon
76162911Ssimon#include "camellia.h"
77162911Ssimon#include "cmll_locl.h"
78162911Ssimon
79162911Ssimon/* key constants */
80162911Ssimon#define CAMELLIA_SIGMA1L (0xA09E667FL)
81162911Ssimon#define CAMELLIA_SIGMA1R (0x3BCC908BL)
82162911Ssimon#define CAMELLIA_SIGMA2L (0xB67AE858L)
83162911Ssimon#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
84162911Ssimon#define CAMELLIA_SIGMA3L (0xC6EF372FL)
85162911Ssimon#define CAMELLIA_SIGMA3R (0xE94F82BEL)
86162911Ssimon#define CAMELLIA_SIGMA4L (0x54FF53A5L)
87162911Ssimon#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
88162911Ssimon#define CAMELLIA_SIGMA5L (0x10E527FAL)
89162911Ssimon#define CAMELLIA_SIGMA5R (0xDE682D1DL)
90162911Ssimon#define CAMELLIA_SIGMA6L (0xB05688C2L)
91162911Ssimon#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
92162911Ssimon
93162911Ssimon/*
94162911Ssimon *  macros
95162911Ssimon */
96162911Ssimon
97162911Ssimon/* e is pointer of subkey */
98162911Ssimon#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2])
99162911Ssimon#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1])
100162911Ssimon
101162911Ssimon/* rotation right shift 1byte */
102162911Ssimon#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
103162911Ssimon/* rotation left shift 1bit */
104162911Ssimon#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))
105162911Ssimon/* rotation left shift 1byte */
106162911Ssimon#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))
107162911Ssimon
108296465Sdelphij#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits)    \
109296465Sdelphijdo                                                      \
110296465Sdelphij        {                                               \
111296465Sdelphij        w0 = ll;                                        \
112296465Sdelphij        ll = (ll << bits) + (lr >> (32 - bits));        \
113296465Sdelphij        lr = (lr << bits) + (rl >> (32 - bits));        \
114296465Sdelphij        rl = (rl << bits) + (rr >> (32 - bits));        \
115296465Sdelphij        rr = (rr << bits) + (w0 >> (32 - bits));        \
116296465Sdelphij        } while(0)
117162911Ssimon
118296465Sdelphij#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \
119296465Sdelphijdo                                                      \
120296465Sdelphij        {                                               \
121296465Sdelphij        w0 = ll;                                        \
122296465Sdelphij        w1 = lr;                                        \
123296465Sdelphij        ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
124296465Sdelphij        lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
125296465Sdelphij        rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
126296465Sdelphij        rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
127296465Sdelphij        } while(0)
128162911Ssimon
129162911Ssimon#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
130162911Ssimon#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
131162911Ssimon#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
132162911Ssimon#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
133162911Ssimon
134296465Sdelphij#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)              \
135296465Sdelphijdo                                                                      \
136296465Sdelphij        {                                                               \
137296465Sdelphij        il = xl ^ kl;                                                   \
138296465Sdelphij        ir = xr ^ kr;                                                   \
139296465Sdelphij        t0 = il >> 16;                                                  \
140296465Sdelphij        t1 = ir >> 16;                                                  \
141296465Sdelphij        yl = CAMELLIA_SP1110(ir & 0xff)                                 \
142296465Sdelphij                ^ CAMELLIA_SP0222((t1 >> 8) & 0xff)                     \
143296465Sdelphij                ^ CAMELLIA_SP3033(t1 & 0xff)                            \
144296465Sdelphij                ^ CAMELLIA_SP4404((ir >> 8) & 0xff);                    \
145296465Sdelphij        yr = CAMELLIA_SP1110((t0 >> 8) & 0xff)                          \
146296465Sdelphij                ^ CAMELLIA_SP0222(t0 & 0xff)                            \
147296465Sdelphij                ^ CAMELLIA_SP3033((il >> 8) & 0xff)                     \
148296465Sdelphij                ^ CAMELLIA_SP4404(il & 0xff);                           \
149296465Sdelphij        yl ^= yr;                                                       \
150296465Sdelphij        yr = CAMELLIA_RR8(yr);                                          \
151296465Sdelphij        yr ^= yl;                                                       \
152296465Sdelphij        } while(0)
153162911Ssimon
154162911Ssimon/*
155162911Ssimon * for speed up
156162911Ssimon *
157162911Ssimon */
158162911Ssimon#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
159296465Sdelphijdo                                                                      \
160296465Sdelphij        {                                                               \
161296465Sdelphij        t0 = kll;                                                       \
162296465Sdelphij        t0 &= ll;                                                       \
163296465Sdelphij        lr ^= CAMELLIA_RL1(t0);                                         \
164296465Sdelphij        t1 = klr;                                                       \
165296465Sdelphij        t1 |= lr;                                                       \
166296465Sdelphij        ll ^= t1;                                                       \
167296465Sdelphij                                                                        \
168296465Sdelphij        t2 = krr;                                                       \
169296465Sdelphij        t2 |= rr;                                                       \
170296465Sdelphij        rl ^= t2;                                                       \
171296465Sdelphij        t3 = krl;                                                       \
172296465Sdelphij        t3 &= rl;                                                       \
173296465Sdelphij        rr ^= CAMELLIA_RL1(t3);                                         \
174296465Sdelphij        } while(0)
175162911Ssimon
176296465Sdelphij#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)        \
177296465Sdelphijdo                                                                      \
178296465Sdelphij        {                                                               \
179296465Sdelphij        il = xl;                                                        \
180296465Sdelphij        ir = xr;                                                        \
181296465Sdelphij        t0 = il >> 16;                                                  \
182296465Sdelphij        t1 = ir >> 16;                                                  \
183296465Sdelphij        ir = CAMELLIA_SP1110(ir & 0xff)                                 \
184296465Sdelphij                ^ CAMELLIA_SP0222((t1 >> 8) & 0xff)                     \
185296465Sdelphij                ^ CAMELLIA_SP3033(t1 & 0xff)                            \
186296465Sdelphij                ^ CAMELLIA_SP4404((ir >> 8) & 0xff);                    \
187296465Sdelphij        il = CAMELLIA_SP1110((t0 >> 8) & 0xff)                          \
188296465Sdelphij                ^ CAMELLIA_SP0222(t0 & 0xff)                            \
189296465Sdelphij                ^ CAMELLIA_SP3033((il >> 8) & 0xff)                     \
190296465Sdelphij                ^ CAMELLIA_SP4404(il & 0xff);                           \
191296465Sdelphij        il ^= kl;                                                       \
192296465Sdelphij        ir ^= kr;                                                       \
193296465Sdelphij        ir ^= il;                                                       \
194296465Sdelphij        il = CAMELLIA_RR8(il);                                          \
195296465Sdelphij        il ^= ir;                                                       \
196296465Sdelphij        yl ^= ir;                                                       \
197296465Sdelphij        yr ^= il;                                                       \
198296465Sdelphij        } while(0)
199162911Ssimon
200296465Sdelphijstatic const u32 camellia_sp1110[256] = {
201296465Sdelphij    0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00,
202296465Sdelphij    0xb3b3b300, 0x27272700, 0xc0c0c000, 0xe5e5e500,
203296465Sdelphij    0xe4e4e400, 0x85858500, 0x57575700, 0x35353500,
204296465Sdelphij    0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100,
205296465Sdelphij    0x23232300, 0xefefef00, 0x6b6b6b00, 0x93939300,
206296465Sdelphij    0x45454500, 0x19191900, 0xa5a5a500, 0x21212100,
207296465Sdelphij    0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00,
208296465Sdelphij    0x1d1d1d00, 0x65656500, 0x92929200, 0xbdbdbd00,
209296465Sdelphij    0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00,
210296465Sdelphij    0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00,
211296465Sdelphij    0x3e3e3e00, 0x30303000, 0xdcdcdc00, 0x5f5f5f00,
212296465Sdelphij    0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00,
213296465Sdelphij    0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00,
214296465Sdelphij    0xd5d5d500, 0x47474700, 0x5d5d5d00, 0x3d3d3d00,
215296465Sdelphij    0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600,
216296465Sdelphij    0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00,
217296465Sdelphij    0x8b8b8b00, 0x0d0d0d00, 0x9a9a9a00, 0x66666600,
218296465Sdelphij    0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00,
219296465Sdelphij    0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000,
220296465Sdelphij    0xf0f0f000, 0xb1b1b100, 0x84848400, 0x99999900,
221296465Sdelphij    0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200,
222296465Sdelphij    0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500,
223296465Sdelphij    0x6d6d6d00, 0xb7b7b700, 0xa9a9a900, 0x31313100,
224296465Sdelphij    0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700,
225296465Sdelphij    0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100,
226296465Sdelphij    0xdedede00, 0x1b1b1b00, 0x11111100, 0x1c1c1c00,
227296465Sdelphij    0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600,
228296465Sdelphij    0x53535300, 0x18181800, 0xf2f2f200, 0x22222200,
229296465Sdelphij    0xfefefe00, 0x44444400, 0xcfcfcf00, 0xb2b2b200,
230296465Sdelphij    0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100,
231296465Sdelphij    0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800,
232296465Sdelphij    0x60606000, 0xfcfcfc00, 0x69696900, 0x50505000,
233296465Sdelphij    0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00,
234296465Sdelphij    0xa1a1a100, 0x89898900, 0x62626200, 0x97979700,
235296465Sdelphij    0x54545400, 0x5b5b5b00, 0x1e1e1e00, 0x95959500,
236296465Sdelphij    0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200,
237296465Sdelphij    0x10101000, 0xc4c4c400, 0x00000000, 0x48484800,
238296465Sdelphij    0xa3a3a300, 0xf7f7f700, 0x75757500, 0xdbdbdb00,
239296465Sdelphij    0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00,
240296465Sdelphij    0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400,
241296465Sdelphij    0x87878700, 0x5c5c5c00, 0x83838300, 0x02020200,
242296465Sdelphij    0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300,
243296465Sdelphij    0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300,
244296465Sdelphij    0x9d9d9d00, 0x7f7f7f00, 0xbfbfbf00, 0xe2e2e200,
245296465Sdelphij    0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600,
246296465Sdelphij    0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00,
247296465Sdelphij    0x81818100, 0x96969600, 0x6f6f6f00, 0x4b4b4b00,
248296465Sdelphij    0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00,
249296465Sdelphij    0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00,
250296465Sdelphij    0x9f9f9f00, 0x6e6e6e00, 0xbcbcbc00, 0x8e8e8e00,
251296465Sdelphij    0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600,
252296465Sdelphij    0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900,
253296465Sdelphij    0x78787800, 0x98989800, 0x06060600, 0x6a6a6a00,
254296465Sdelphij    0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00,
255296465Sdelphij    0xd4d4d400, 0x25252500, 0xababab00, 0x42424200,
256296465Sdelphij    0x88888800, 0xa2a2a200, 0x8d8d8d00, 0xfafafa00,
257296465Sdelphij    0x72727200, 0x07070700, 0xb9b9b900, 0x55555500,
258296465Sdelphij    0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00,
259296465Sdelphij    0x36363600, 0x49494900, 0x2a2a2a00, 0x68686800,
260296465Sdelphij    0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400,
261296465Sdelphij    0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00,
262296465Sdelphij    0xbbbbbb00, 0xc9c9c900, 0x43434300, 0xc1c1c100,
263296465Sdelphij    0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400,
264296465Sdelphij    0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00,
265296465Sdelphij};
266162911Ssimon
267296465Sdelphijstatic const u32 camellia_sp0222[256] = {
268296465Sdelphij    0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9,
269296465Sdelphij    0x00676767, 0x004e4e4e, 0x00818181, 0x00cbcbcb,
270296465Sdelphij    0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a,
271296465Sdelphij    0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282,
272296465Sdelphij    0x00464646, 0x00dfdfdf, 0x00d6d6d6, 0x00272727,
273296465Sdelphij    0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242,
274296465Sdelphij    0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c,
275296465Sdelphij    0x003a3a3a, 0x00cacaca, 0x00252525, 0x007b7b7b,
276296465Sdelphij    0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f,
277296465Sdelphij    0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d,
278296465Sdelphij    0x007c7c7c, 0x00606060, 0x00b9b9b9, 0x00bebebe,
279296465Sdelphij    0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434,
280296465Sdelphij    0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595,
281296465Sdelphij    0x00ababab, 0x008e8e8e, 0x00bababa, 0x007a7a7a,
282296465Sdelphij    0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad,
283296465Sdelphij    0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a,
284296465Sdelphij    0x00171717, 0x001a1a1a, 0x00353535, 0x00cccccc,
285296465Sdelphij    0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a,
286296465Sdelphij    0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040,
287296465Sdelphij    0x00e1e1e1, 0x00636363, 0x00090909, 0x00333333,
288296465Sdelphij    0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585,
289296465Sdelphij    0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a,
290296465Sdelphij    0x00dadada, 0x006f6f6f, 0x00535353, 0x00626262,
291296465Sdelphij    0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf,
292296465Sdelphij    0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2,
293296465Sdelphij    0x00bdbdbd, 0x00363636, 0x00222222, 0x00383838,
294296465Sdelphij    0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c,
295296465Sdelphij    0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444,
296296465Sdelphij    0x00fdfdfd, 0x00888888, 0x009f9f9f, 0x00656565,
297296465Sdelphij    0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323,
298296465Sdelphij    0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151,
299296465Sdelphij    0x00c0c0c0, 0x00f9f9f9, 0x00d2d2d2, 0x00a0a0a0,
300296465Sdelphij    0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa,
301296465Sdelphij    0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f,
302296465Sdelphij    0x00a8a8a8, 0x00b6b6b6, 0x003c3c3c, 0x002b2b2b,
303296465Sdelphij    0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5,
304296465Sdelphij    0x00202020, 0x00898989, 0x00000000, 0x00909090,
305296465Sdelphij    0x00474747, 0x00efefef, 0x00eaeaea, 0x00b7b7b7,
306296465Sdelphij    0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5,
307296465Sdelphij    0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929,
308296465Sdelphij    0x000f0f0f, 0x00b8b8b8, 0x00070707, 0x00040404,
309296465Sdelphij    0x009b9b9b, 0x00949494, 0x00212121, 0x00666666,
310296465Sdelphij    0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7,
311296465Sdelphij    0x003b3b3b, 0x00fefefe, 0x007f7f7f, 0x00c5c5c5,
312296465Sdelphij    0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c,
313296465Sdelphij    0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676,
314296465Sdelphij    0x00030303, 0x002d2d2d, 0x00dedede, 0x00969696,
315296465Sdelphij    0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c,
316296465Sdelphij    0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919,
317296465Sdelphij    0x003f3f3f, 0x00dcdcdc, 0x00797979, 0x001d1d1d,
318296465Sdelphij    0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d,
319296465Sdelphij    0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2,
320296465Sdelphij    0x00f0f0f0, 0x00313131, 0x000c0c0c, 0x00d4d4d4,
321296465Sdelphij    0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575,
322296465Sdelphij    0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484,
323296465Sdelphij    0x00111111, 0x00454545, 0x001b1b1b, 0x00f5f5f5,
324296465Sdelphij    0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa,
325296465Sdelphij    0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414,
326296465Sdelphij    0x006c6c6c, 0x00929292, 0x00545454, 0x00d0d0d0,
327296465Sdelphij    0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949,
328296465Sdelphij    0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6,
329296465Sdelphij    0x00777777, 0x00939393, 0x00868686, 0x00838383,
330296465Sdelphij    0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9,
331296465Sdelphij    0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d,
332296465Sdelphij};
333162911Ssimon
334296465Sdelphijstatic const u32 camellia_sp3033[256] = {
335296465Sdelphij    0x38003838, 0x41004141, 0x16001616, 0x76007676,
336296465Sdelphij    0xd900d9d9, 0x93009393, 0x60006060, 0xf200f2f2,
337296465Sdelphij    0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a,
338296465Sdelphij    0x75007575, 0x06000606, 0x57005757, 0xa000a0a0,
339296465Sdelphij    0x91009191, 0xf700f7f7, 0xb500b5b5, 0xc900c9c9,
340296465Sdelphij    0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090,
341296465Sdelphij    0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727,
342296465Sdelphij    0x8e008e8e, 0xb200b2b2, 0x49004949, 0xde00dede,
343296465Sdelphij    0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7,
344296465Sdelphij    0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767,
345296465Sdelphij    0x1f001f1f, 0x18001818, 0x6e006e6e, 0xaf00afaf,
346296465Sdelphij    0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d,
347296465Sdelphij    0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565,
348296465Sdelphij    0xea00eaea, 0xa300a3a3, 0xae00aeae, 0x9e009e9e,
349296465Sdelphij    0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b,
350296465Sdelphij    0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6,
351296465Sdelphij    0xc500c5c5, 0x86008686, 0x4d004d4d, 0x33003333,
352296465Sdelphij    0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696,
353296465Sdelphij    0x3a003a3a, 0x09000909, 0x95009595, 0x10001010,
354296465Sdelphij    0x78007878, 0xd800d8d8, 0x42004242, 0xcc00cccc,
355296465Sdelphij    0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161,
356296465Sdelphij    0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282,
357296465Sdelphij    0xb600b6b6, 0xdb00dbdb, 0xd400d4d4, 0x98009898,
358296465Sdelphij    0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb,
359296465Sdelphij    0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0,
360296465Sdelphij    0x6f006f6f, 0x8d008d8d, 0x88008888, 0x0e000e0e,
361296465Sdelphij    0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b,
362296465Sdelphij    0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111,
363296465Sdelphij    0x7f007f7f, 0x22002222, 0xe700e7e7, 0x59005959,
364296465Sdelphij    0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8,
365296465Sdelphij    0x12001212, 0x04000404, 0x74007474, 0x54005454,
366296465Sdelphij    0x30003030, 0x7e007e7e, 0xb400b4b4, 0x28002828,
367296465Sdelphij    0x55005555, 0x68006868, 0x50005050, 0xbe00bebe,
368296465Sdelphij    0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb,
369296465Sdelphij    0x2a002a2a, 0xad00adad, 0x0f000f0f, 0xca00caca,
370296465Sdelphij    0x70007070, 0xff00ffff, 0x32003232, 0x69006969,
371296465Sdelphij    0x08000808, 0x62006262, 0x00000000, 0x24002424,
372296465Sdelphij    0xd100d1d1, 0xfb00fbfb, 0xba00baba, 0xed00eded,
373296465Sdelphij    0x45004545, 0x81008181, 0x73007373, 0x6d006d6d,
374296465Sdelphij    0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a,
375296465Sdelphij    0xc300c3c3, 0x2e002e2e, 0xc100c1c1, 0x01000101,
376296465Sdelphij    0xe600e6e6, 0x25002525, 0x48004848, 0x99009999,
377296465Sdelphij    0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9,
378296465Sdelphij    0xce00cece, 0xbf00bfbf, 0xdf00dfdf, 0x71007171,
379296465Sdelphij    0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313,
380296465Sdelphij    0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d,
381296465Sdelphij    0xc000c0c0, 0x4b004b4b, 0xb700b7b7, 0xa500a5a5,
382296465Sdelphij    0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717,
383296465Sdelphij    0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646,
384296465Sdelphij    0xcf00cfcf, 0x37003737, 0x5e005e5e, 0x47004747,
385296465Sdelphij    0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b,
386296465Sdelphij    0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac,
387296465Sdelphij    0x3c003c3c, 0x4c004c4c, 0x03000303, 0x35003535,
388296465Sdelphij    0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d,
389296465Sdelphij    0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121,
390296465Sdelphij    0x44004444, 0x51005151, 0xc600c6c6, 0x7d007d7d,
391296465Sdelphij    0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa,
392296465Sdelphij    0x7c007c7c, 0x77007777, 0x56005656, 0x05000505,
393296465Sdelphij    0x1b001b1b, 0xa400a4a4, 0x15001515, 0x34003434,
394296465Sdelphij    0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252,
395296465Sdelphij    0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd,
396296465Sdelphij    0xdd00dddd, 0xe400e4e4, 0xa100a1a1, 0xe000e0e0,
397296465Sdelphij    0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a,
398296465Sdelphij    0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f,
399296465Sdelphij};
400162911Ssimon
401296465Sdelphijstatic const u32 camellia_sp4404[256] = {
402296465Sdelphij    0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0,
403296465Sdelphij    0xe4e400e4, 0x57570057, 0xeaea00ea, 0xaeae00ae,
404296465Sdelphij    0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5,
405296465Sdelphij    0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092,
406296465Sdelphij    0x86860086, 0xafaf00af, 0x7c7c007c, 0x1f1f001f,
407296465Sdelphij    0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b,
408296465Sdelphij    0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d,
409296465Sdelphij    0xd9d900d9, 0x5a5a005a, 0x51510051, 0x6c6c006c,
410296465Sdelphij    0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0,
411296465Sdelphij    0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084,
412296465Sdelphij    0xdfdf00df, 0xcbcb00cb, 0x34340034, 0x76760076,
413296465Sdelphij    0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004,
414296465Sdelphij    0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011,
415296465Sdelphij    0x32320032, 0x9c9c009c, 0x53530053, 0xf2f200f2,
416296465Sdelphij    0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a,
417296465Sdelphij    0x24240024, 0xe8e800e8, 0x60600060, 0x69690069,
418296465Sdelphij    0xaaaa00aa, 0xa0a000a0, 0xa1a100a1, 0x62620062,
419296465Sdelphij    0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064,
420296465Sdelphij    0x10100010, 0x00000000, 0xa3a300a3, 0x75750075,
421296465Sdelphij    0x8a8a008a, 0xe6e600e6, 0x09090009, 0xdddd00dd,
422296465Sdelphij    0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090,
423296465Sdelphij    0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf,
424296465Sdelphij    0x52520052, 0xd8d800d8, 0xc8c800c8, 0xc6c600c6,
425296465Sdelphij    0x81810081, 0x6f6f006f, 0x13130013, 0x63630063,
426296465Sdelphij    0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc,
427296465Sdelphij    0x29290029, 0xf9f900f9, 0x2f2f002f, 0xb4b400b4,
428296465Sdelphij    0x78780078, 0x06060006, 0xe7e700e7, 0x71710071,
429296465Sdelphij    0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d,
430296465Sdelphij    0x72720072, 0xb9b900b9, 0xf8f800f8, 0xacac00ac,
431296465Sdelphij    0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1,
432296465Sdelphij    0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043,
433296465Sdelphij    0x15150015, 0xadad00ad, 0x77770077, 0x80800080,
434296465Sdelphij    0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5,
435296465Sdelphij    0x85850085, 0x35350035, 0x0c0c000c, 0x41410041,
436296465Sdelphij    0xefef00ef, 0x93930093, 0x19190019, 0x21210021,
437296465Sdelphij    0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd,
438296465Sdelphij    0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce,
439296465Sdelphij    0x30300030, 0x5f5f005f, 0xc5c500c5, 0x1a1a001a,
440296465Sdelphij    0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d,
441296465Sdelphij    0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d,
442296465Sdelphij    0x0d0d000d, 0x66660066, 0xcccc00cc, 0x2d2d002d,
443296465Sdelphij    0x12120012, 0x20200020, 0xb1b100b1, 0x99990099,
444296465Sdelphij    0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005,
445296465Sdelphij    0xb7b700b7, 0x31310031, 0x17170017, 0xd7d700d7,
446296465Sdelphij    0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c,
447296465Sdelphij    0x0f0f000f, 0x16160016, 0x18180018, 0x22220022,
448296465Sdelphij    0x44440044, 0xb2b200b2, 0xb5b500b5, 0x91910091,
449296465Sdelphij    0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050,
450296465Sdelphij    0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097,
451296465Sdelphij    0x5b5b005b, 0x95950095, 0xffff00ff, 0xd2d200d2,
452296465Sdelphij    0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db,
453296465Sdelphij    0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094,
454296465Sdelphij    0x5c5c005c, 0x02020002, 0x4a4a004a, 0x33330033,
455296465Sdelphij    0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2,
456296465Sdelphij    0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b,
457296465Sdelphij    0x96960096, 0x4b4b004b, 0xbebe00be, 0x2e2e002e,
458296465Sdelphij    0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e,
459296465Sdelphij    0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059,
460296465Sdelphij    0x98980098, 0x6a6a006a, 0x46460046, 0xbaba00ba,
461296465Sdelphij    0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa,
462296465Sdelphij    0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a,
463296465Sdelphij    0x49490049, 0x68680068, 0x38380038, 0xa4a400a4,
464296465Sdelphij    0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1,
465296465Sdelphij    0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e,
466296465Sdelphij};
467162911Ssimon
468162911Ssimon/**
469162911Ssimon * Stuff related to the Camellia key schedule
470162911Ssimon */
471162911Ssimon#define subl(x) subL[(x)]
472162911Ssimon#define subr(x) subR[(x)]
473162911Ssimon
474167612Ssimonvoid camellia_setup128(const u8 *key, u32 *subkey)
475296465Sdelphij{
476296465Sdelphij    u32 kll, klr, krl, krr;
477296465Sdelphij    u32 il, ir, t0, t1, w0, w1;
478296465Sdelphij    u32 kw4l, kw4r, dw, tl, tr;
479296465Sdelphij    u32 subL[26];
480296465Sdelphij    u32 subR[26];
481162911Ssimon
482296465Sdelphij        /**
483296465Sdelphij         *  k == kll || klr || krl || krr (|| is concatination)
484296465Sdelphij         */
485296465Sdelphij    kll = GETU32(key);
486296465Sdelphij    klr = GETU32(key + 4);
487296465Sdelphij    krl = GETU32(key + 8);
488296465Sdelphij    krr = GETU32(key + 12);
489296465Sdelphij        /**
490296465Sdelphij         * generate KL dependent subkeys
491296465Sdelphij         */
492296465Sdelphij    /* kw1 */
493296465Sdelphij    subl(0) = kll;
494296465Sdelphij    subr(0) = klr;
495296465Sdelphij    /* kw2 */
496296465Sdelphij    subl(1) = krl;
497296465Sdelphij    subr(1) = krr;
498296465Sdelphij    /* rotation left shift 15bit */
499296465Sdelphij    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
500296465Sdelphij    /* k3 */
501296465Sdelphij    subl(4) = kll;
502296465Sdelphij    subr(4) = klr;
503296465Sdelphij    /* k4 */
504296465Sdelphij    subl(5) = krl;
505296465Sdelphij    subr(5) = krr;
506296465Sdelphij    /* rotation left shift 15+30bit */
507296465Sdelphij    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
508296465Sdelphij    /* k7 */
509296465Sdelphij    subl(10) = kll;
510296465Sdelphij    subr(10) = klr;
511296465Sdelphij    /* k8 */
512296465Sdelphij    subl(11) = krl;
513296465Sdelphij    subr(11) = krr;
514296465Sdelphij    /* rotation left shift 15+30+15bit */
515296465Sdelphij    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
516296465Sdelphij    /* k10 */
517296465Sdelphij    subl(13) = krl;
518296465Sdelphij    subr(13) = krr;
519296465Sdelphij    /* rotation left shift 15+30+15+17 bit */
520296465Sdelphij    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
521296465Sdelphij    /* kl3 */
522296465Sdelphij    subl(16) = kll;
523296465Sdelphij    subr(16) = klr;
524296465Sdelphij    /* kl4 */
525296465Sdelphij    subl(17) = krl;
526296465Sdelphij    subr(17) = krr;
527296465Sdelphij    /* rotation left shift 15+30+15+17+17 bit */
528296465Sdelphij    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
529296465Sdelphij    /* k13 */
530296465Sdelphij    subl(18) = kll;
531296465Sdelphij    subr(18) = klr;
532296465Sdelphij    /* k14 */
533296465Sdelphij    subl(19) = krl;
534296465Sdelphij    subr(19) = krr;
535296465Sdelphij    /* rotation left shift 15+30+15+17+17+17 bit */
536296465Sdelphij    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
537296465Sdelphij    /* k17 */
538296465Sdelphij    subl(22) = kll;
539296465Sdelphij    subr(22) = klr;
540296465Sdelphij    /* k18 */
541296465Sdelphij    subl(23) = krl;
542296465Sdelphij    subr(23) = krr;
543162911Ssimon
544296465Sdelphij    /* generate KA */
545296465Sdelphij    kll = subl(0);
546296465Sdelphij    klr = subr(0);
547296465Sdelphij    krl = subl(1);
548296465Sdelphij    krr = subr(1);
549296465Sdelphij    CAMELLIA_F(kll, klr,
550296465Sdelphij               CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, w0, w1, il, ir, t0, t1);
551296465Sdelphij    krl ^= w0;
552296465Sdelphij    krr ^= w1;
553296465Sdelphij    CAMELLIA_F(krl, krr,
554296465Sdelphij               CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, kll, klr, il, ir, t0, t1);
555296465Sdelphij    /* current status == (kll, klr, w0, w1) */
556296465Sdelphij    CAMELLIA_F(kll, klr,
557296465Sdelphij               CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, krl, krr, il, ir, t0, t1);
558296465Sdelphij    krl ^= w0;
559296465Sdelphij    krr ^= w1;
560296465Sdelphij    CAMELLIA_F(krl, krr,
561296465Sdelphij               CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, w0, w1, il, ir, t0, t1);
562296465Sdelphij    kll ^= w0;
563296465Sdelphij    klr ^= w1;
564162911Ssimon
565296465Sdelphij    /* generate KA dependent subkeys */
566296465Sdelphij    /* k1, k2 */
567296465Sdelphij    subl(2) = kll;
568296465Sdelphij    subr(2) = klr;
569296465Sdelphij    subl(3) = krl;
570296465Sdelphij    subr(3) = krr;
571296465Sdelphij    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
572296465Sdelphij    /* k5,k6 */
573296465Sdelphij    subl(6) = kll;
574296465Sdelphij    subr(6) = klr;
575296465Sdelphij    subl(7) = krl;
576296465Sdelphij    subr(7) = krr;
577296465Sdelphij    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
578296465Sdelphij    /* kl1, kl2 */
579296465Sdelphij    subl(8) = kll;
580296465Sdelphij    subr(8) = klr;
581296465Sdelphij    subl(9) = krl;
582296465Sdelphij    subr(9) = krr;
583296465Sdelphij    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
584296465Sdelphij    /* k9 */
585296465Sdelphij    subl(12) = kll;
586296465Sdelphij    subr(12) = klr;
587296465Sdelphij    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
588296465Sdelphij    /* k11, k12 */
589296465Sdelphij    subl(14) = kll;
590296465Sdelphij    subr(14) = klr;
591296465Sdelphij    subl(15) = krl;
592296465Sdelphij    subr(15) = krr;
593296465Sdelphij    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
594296465Sdelphij    /* k15, k16 */
595296465Sdelphij    subl(20) = kll;
596296465Sdelphij    subr(20) = klr;
597296465Sdelphij    subl(21) = krl;
598296465Sdelphij    subr(21) = krr;
599296465Sdelphij    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
600296465Sdelphij    /* kw3, kw4 */
601296465Sdelphij    subl(24) = kll;
602296465Sdelphij    subr(24) = klr;
603296465Sdelphij    subl(25) = krl;
604296465Sdelphij    subr(25) = krr;
605162911Ssimon
606296465Sdelphij    /* absorb kw2 to other subkeys */
607162911Ssimon/* round 2 */
608296465Sdelphij    subl(3) ^= subl(1);
609296465Sdelphij    subr(3) ^= subr(1);
610162911Ssimon/* round 4 */
611296465Sdelphij    subl(5) ^= subl(1);
612296465Sdelphij    subr(5) ^= subr(1);
613162911Ssimon/* round 6 */
614296465Sdelphij    subl(7) ^= subl(1);
615296465Sdelphij    subr(7) ^= subr(1);
616296465Sdelphij    subl(1) ^= subr(1) & ~subr(9);
617296465Sdelphij    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw); /* modified for
618296465Sdelphij                                                          * FLinv(kl2) */
619162911Ssimon/* round 8 */
620296465Sdelphij    subl(11) ^= subl(1);
621296465Sdelphij    subr(11) ^= subr(1);
622162911Ssimon/* round 10 */
623296465Sdelphij    subl(13) ^= subl(1);
624296465Sdelphij    subr(13) ^= subr(1);
625162911Ssimon/* round 12 */
626296465Sdelphij    subl(15) ^= subl(1);
627296465Sdelphij    subr(15) ^= subr(1);
628296465Sdelphij    subl(1) ^= subr(1) & ~subr(17);
629296465Sdelphij    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw); /* modified for
630296465Sdelphij                                                           * FLinv(kl4) */
631162911Ssimon/* round 14 */
632296465Sdelphij    subl(19) ^= subl(1);
633296465Sdelphij    subr(19) ^= subr(1);
634162911Ssimon/* round 16 */
635296465Sdelphij    subl(21) ^= subl(1);
636296465Sdelphij    subr(21) ^= subr(1);
637162911Ssimon/* round 18 */
638296465Sdelphij    subl(23) ^= subl(1);
639296465Sdelphij    subr(23) ^= subr(1);
640162911Ssimon/* kw3 */
641296465Sdelphij    subl(24) ^= subl(1);
642296465Sdelphij    subr(24) ^= subr(1);
643162911Ssimon
644296465Sdelphij    /* absorb kw4 to other subkeys */
645296465Sdelphij    kw4l = subl(25);
646296465Sdelphij    kw4r = subr(25);
647162911Ssimon/* round 17 */
648296465Sdelphij    subl(22) ^= kw4l;
649296465Sdelphij    subr(22) ^= kw4r;
650162911Ssimon/* round 15 */
651296465Sdelphij    subl(20) ^= kw4l;
652296465Sdelphij    subr(20) ^= kw4r;
653162911Ssimon/* round 13 */
654296465Sdelphij    subl(18) ^= kw4l;
655296465Sdelphij    subr(18) ^= kw4r;
656296465Sdelphij    kw4l ^= kw4r & ~subr(16);
657296465Sdelphij    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */
658162911Ssimon/* round 11 */
659296465Sdelphij    subl(14) ^= kw4l;
660296465Sdelphij    subr(14) ^= kw4r;
661162911Ssimon/* round 9 */
662296465Sdelphij    subl(12) ^= kw4l;
663296465Sdelphij    subr(12) ^= kw4r;
664162911Ssimon/* round 7 */
665296465Sdelphij    subl(10) ^= kw4l;
666296465Sdelphij    subr(10) ^= kw4r;
667296465Sdelphij    kw4l ^= kw4r & ~subr(8);
668296465Sdelphij    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */
669162911Ssimon/* round 5 */
670296465Sdelphij    subl(6) ^= kw4l;
671296465Sdelphij    subr(6) ^= kw4r;
672162911Ssimon/* round 3 */
673296465Sdelphij    subl(4) ^= kw4l;
674296465Sdelphij    subr(4) ^= kw4r;
675162911Ssimon/* round 1 */
676296465Sdelphij    subl(2) ^= kw4l;
677296465Sdelphij    subr(2) ^= kw4r;
678162911Ssimon/* kw1 */
679296465Sdelphij    subl(0) ^= kw4l;
680296465Sdelphij    subr(0) ^= kw4r;
681162911Ssimon
682296465Sdelphij    /* key XOR is end of F-function */
683296465Sdelphij    CamelliaSubkeyL(0) = subl(0) ^ subl(2); /* kw1 */
684296465Sdelphij    CamelliaSubkeyR(0) = subr(0) ^ subr(2);
685296465Sdelphij    CamelliaSubkeyL(2) = subl(3); /* round 1 */
686296465Sdelphij    CamelliaSubkeyR(2) = subr(3);
687296465Sdelphij    CamelliaSubkeyL(3) = subl(2) ^ subl(4); /* round 2 */
688296465Sdelphij    CamelliaSubkeyR(3) = subr(2) ^ subr(4);
689296465Sdelphij    CamelliaSubkeyL(4) = subl(3) ^ subl(5); /* round 3 */
690296465Sdelphij    CamelliaSubkeyR(4) = subr(3) ^ subr(5);
691296465Sdelphij    CamelliaSubkeyL(5) = subl(4) ^ subl(6); /* round 4 */
692296465Sdelphij    CamelliaSubkeyR(5) = subr(4) ^ subr(6);
693296465Sdelphij    CamelliaSubkeyL(6) = subl(5) ^ subl(7); /* round 5 */
694296465Sdelphij    CamelliaSubkeyR(6) = subr(5) ^ subr(7);
695296465Sdelphij    tl = subl(10) ^ (subr(10) & ~subr(8));
696296465Sdelphij    dw = tl & subl(8),          /* FL(kl1) */
697296465Sdelphij        tr = subr(10) ^ CAMELLIA_RL1(dw);
698296465Sdelphij    CamelliaSubkeyL(7) = subl(6) ^ tl; /* round 6 */
699296465Sdelphij    CamelliaSubkeyR(7) = subr(6) ^ tr;
700296465Sdelphij    CamelliaSubkeyL(8) = subl(8); /* FL(kl1) */
701296465Sdelphij    CamelliaSubkeyR(8) = subr(8);
702296465Sdelphij    CamelliaSubkeyL(9) = subl(9); /* FLinv(kl2) */
703296465Sdelphij    CamelliaSubkeyR(9) = subr(9);
704296465Sdelphij    tl = subl(7) ^ (subr(7) & ~subr(9));
705296465Sdelphij    dw = tl & subl(9),          /* FLinv(kl2) */
706296465Sdelphij        tr = subr(7) ^ CAMELLIA_RL1(dw);
707296465Sdelphij    CamelliaSubkeyL(10) = tl ^ subl(11); /* round 7 */
708296465Sdelphij    CamelliaSubkeyR(10) = tr ^ subr(11);
709296465Sdelphij    CamelliaSubkeyL(11) = subl(10) ^ subl(12); /* round 8 */
710296465Sdelphij    CamelliaSubkeyR(11) = subr(10) ^ subr(12);
711296465Sdelphij    CamelliaSubkeyL(12) = subl(11) ^ subl(13); /* round 9 */
712296465Sdelphij    CamelliaSubkeyR(12) = subr(11) ^ subr(13);
713296465Sdelphij    CamelliaSubkeyL(13) = subl(12) ^ subl(14); /* round 10 */
714296465Sdelphij    CamelliaSubkeyR(13) = subr(12) ^ subr(14);
715296465Sdelphij    CamelliaSubkeyL(14) = subl(13) ^ subl(15); /* round 11 */
716296465Sdelphij    CamelliaSubkeyR(14) = subr(13) ^ subr(15);
717296465Sdelphij    tl = subl(18) ^ (subr(18) & ~subr(16));
718296465Sdelphij    dw = tl & subl(16),         /* FL(kl3) */
719296465Sdelphij        tr = subr(18) ^ CAMELLIA_RL1(dw);
720296465Sdelphij    CamelliaSubkeyL(15) = subl(14) ^ tl; /* round 12 */
721296465Sdelphij    CamelliaSubkeyR(15) = subr(14) ^ tr;
722296465Sdelphij    CamelliaSubkeyL(16) = subl(16); /* FL(kl3) */
723296465Sdelphij    CamelliaSubkeyR(16) = subr(16);
724296465Sdelphij    CamelliaSubkeyL(17) = subl(17); /* FLinv(kl4) */
725296465Sdelphij    CamelliaSubkeyR(17) = subr(17);
726296465Sdelphij    tl = subl(15) ^ (subr(15) & ~subr(17));
727296465Sdelphij    dw = tl & subl(17),         /* FLinv(kl4) */
728296465Sdelphij        tr = subr(15) ^ CAMELLIA_RL1(dw);
729296465Sdelphij    CamelliaSubkeyL(18) = tl ^ subl(19); /* round 13 */
730296465Sdelphij    CamelliaSubkeyR(18) = tr ^ subr(19);
731296465Sdelphij    CamelliaSubkeyL(19) = subl(18) ^ subl(20); /* round 14 */
732296465Sdelphij    CamelliaSubkeyR(19) = subr(18) ^ subr(20);
733296465Sdelphij    CamelliaSubkeyL(20) = subl(19) ^ subl(21); /* round 15 */
734296465Sdelphij    CamelliaSubkeyR(20) = subr(19) ^ subr(21);
735296465Sdelphij    CamelliaSubkeyL(21) = subl(20) ^ subl(22); /* round 16 */
736296465Sdelphij    CamelliaSubkeyR(21) = subr(20) ^ subr(22);
737296465Sdelphij    CamelliaSubkeyL(22) = subl(21) ^ subl(23); /* round 17 */
738296465Sdelphij    CamelliaSubkeyR(22) = subr(21) ^ subr(23);
739296465Sdelphij    CamelliaSubkeyL(23) = subl(22); /* round 18 */
740296465Sdelphij    CamelliaSubkeyR(23) = subr(22);
741296465Sdelphij    CamelliaSubkeyL(24) = subl(24) ^ subl(23); /* kw3 */
742296465Sdelphij    CamelliaSubkeyR(24) = subr(24) ^ subr(23);
743162911Ssimon
744296465Sdelphij    /* apply the inverse of the last half of P-function */
745296465Sdelphij    /* round 1 */
746296465Sdelphij    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
747296465Sdelphij    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
748296465Sdelphij    /* round 2 */
749296465Sdelphij    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
750296465Sdelphij    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
751296465Sdelphij    /* round 3 */
752296465Sdelphij    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
753296465Sdelphij    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
754296465Sdelphij    /* round 4 */
755296465Sdelphij    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
756296465Sdelphij    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
757296465Sdelphij    /* round 5 */
758296465Sdelphij    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
759296465Sdelphij    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
760296465Sdelphij    /* round 6 */
761296465Sdelphij    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
762296465Sdelphij    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
763296465Sdelphij    /* round 7 */
764296465Sdelphij    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
765296465Sdelphij    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
766296465Sdelphij    /* round 8 */
767296465Sdelphij    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
768296465Sdelphij    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
769296465Sdelphij    /* round 9 */
770296465Sdelphij    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
771296465Sdelphij    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
772296465Sdelphij    /* round 10 */
773296465Sdelphij    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
774296465Sdelphij    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
775296465Sdelphij    /* round 11 */
776296465Sdelphij    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
777296465Sdelphij    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
778296465Sdelphij    /* round 12 */
779296465Sdelphij    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
780296465Sdelphij    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
781296465Sdelphij    /* round 13 */
782296465Sdelphij    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
783296465Sdelphij    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
784296465Sdelphij    /* round 14 */
785296465Sdelphij    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
786296465Sdelphij    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
787296465Sdelphij    /* round 15 */
788296465Sdelphij    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
789296465Sdelphij    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
790296465Sdelphij    /* round 16 */
791296465Sdelphij    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
792296465Sdelphij    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
793296465Sdelphij    /* round 17 */
794296465Sdelphij    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
795296465Sdelphij    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
796296465Sdelphij    /* round 18 */
797296465Sdelphij    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
798296465Sdelphij    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
799162911Ssimon
800296465Sdelphij    return;
801296465Sdelphij}
802162911Ssimon
803167612Ssimonvoid camellia_setup256(const u8 *key, u32 *subkey)
804296465Sdelphij{
805296465Sdelphij    u32 kll, klr, krl, krr;     /* left half of key */
806296465Sdelphij    u32 krll, krlr, krrl, krrr; /* right half of key */
807296465Sdelphij    u32 il, ir, t0, t1, w0, w1; /* temporary variables */
808296465Sdelphij    u32 kw4l, kw4r, dw, tl, tr;
809296465Sdelphij    u32 subL[34];
810296465Sdelphij    u32 subR[34];
811162911Ssimon
812296465Sdelphij        /**
813296465Sdelphij         *  key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
814296465Sdelphij         *  (|| is concatination)
815296465Sdelphij         */
816162911Ssimon
817296465Sdelphij    kll = GETU32(key);
818296465Sdelphij    klr = GETU32(key + 4);
819296465Sdelphij    krl = GETU32(key + 8);
820296465Sdelphij    krr = GETU32(key + 12);
821296465Sdelphij    krll = GETU32(key + 16);
822296465Sdelphij    krlr = GETU32(key + 20);
823296465Sdelphij    krrl = GETU32(key + 24);
824296465Sdelphij    krrr = GETU32(key + 28);
825162911Ssimon
826296465Sdelphij    /* generate KL dependent subkeys */
827296465Sdelphij    /* kw1 */
828296465Sdelphij    subl(0) = kll;
829296465Sdelphij    subr(0) = klr;
830296465Sdelphij    /* kw2 */
831296465Sdelphij    subl(1) = krl;
832296465Sdelphij    subr(1) = krr;
833296465Sdelphij    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
834296465Sdelphij    /* k9 */
835296465Sdelphij    subl(12) = kll;
836296465Sdelphij    subr(12) = klr;
837296465Sdelphij    /* k10 */
838296465Sdelphij    subl(13) = krl;
839296465Sdelphij    subr(13) = krr;
840296465Sdelphij    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
841296465Sdelphij    /* kl3 */
842296465Sdelphij    subl(16) = kll;
843296465Sdelphij    subr(16) = klr;
844296465Sdelphij    /* kl4 */
845296465Sdelphij    subl(17) = krl;
846296465Sdelphij    subr(17) = krr;
847296465Sdelphij    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
848296465Sdelphij    /* k17 */
849296465Sdelphij    subl(22) = kll;
850296465Sdelphij    subr(22) = klr;
851296465Sdelphij    /* k18 */
852296465Sdelphij    subl(23) = krl;
853296465Sdelphij    subr(23) = krr;
854296465Sdelphij    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
855296465Sdelphij    /* k23 */
856296465Sdelphij    subl(30) = kll;
857296465Sdelphij    subr(30) = klr;
858296465Sdelphij    /* k24 */
859296465Sdelphij    subl(31) = krl;
860296465Sdelphij    subr(31) = krr;
861162911Ssimon
862296465Sdelphij    /* generate KR dependent subkeys */
863296465Sdelphij    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
864296465Sdelphij    /* k3 */
865296465Sdelphij    subl(4) = krll;
866296465Sdelphij    subr(4) = krlr;
867296465Sdelphij    /* k4 */
868296465Sdelphij    subl(5) = krrl;
869296465Sdelphij    subr(5) = krrr;
870296465Sdelphij    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
871296465Sdelphij    /* kl1 */
872296465Sdelphij    subl(8) = krll;
873296465Sdelphij    subr(8) = krlr;
874296465Sdelphij    /* kl2 */
875296465Sdelphij    subl(9) = krrl;
876296465Sdelphij    subr(9) = krrr;
877296465Sdelphij    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
878296465Sdelphij    /* k13 */
879296465Sdelphij    subl(18) = krll;
880296465Sdelphij    subr(18) = krlr;
881296465Sdelphij    /* k14 */
882296465Sdelphij    subl(19) = krrl;
883296465Sdelphij    subr(19) = krrr;
884296465Sdelphij    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
885296465Sdelphij    /* k19 */
886296465Sdelphij    subl(26) = krll;
887296465Sdelphij    subr(26) = krlr;
888296465Sdelphij    /* k20 */
889296465Sdelphij    subl(27) = krrl;
890296465Sdelphij    subr(27) = krrr;
891296465Sdelphij    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
892162911Ssimon
893296465Sdelphij    /* generate KA */
894296465Sdelphij    kll = subl(0) ^ krll;
895296465Sdelphij    klr = subr(0) ^ krlr;
896296465Sdelphij    krl = subl(1) ^ krrl;
897296465Sdelphij    krr = subr(1) ^ krrr;
898296465Sdelphij    CAMELLIA_F(kll, klr,
899296465Sdelphij               CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, w0, w1, il, ir, t0, t1);
900296465Sdelphij    krl ^= w0;
901296465Sdelphij    krr ^= w1;
902296465Sdelphij    CAMELLIA_F(krl, krr,
903296465Sdelphij               CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, kll, klr, il, ir, t0, t1);
904296465Sdelphij    kll ^= krll;
905296465Sdelphij    klr ^= krlr;
906296465Sdelphij    CAMELLIA_F(kll, klr,
907296465Sdelphij               CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, krl, krr, il, ir, t0, t1);
908296465Sdelphij    krl ^= w0 ^ krrl;
909296465Sdelphij    krr ^= w1 ^ krrr;
910296465Sdelphij    CAMELLIA_F(krl, krr,
911296465Sdelphij               CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, w0, w1, il, ir, t0, t1);
912296465Sdelphij    kll ^= w0;
913296465Sdelphij    klr ^= w1;
914162911Ssimon
915296465Sdelphij    /* generate KB */
916296465Sdelphij    krll ^= kll;
917296465Sdelphij    krlr ^= klr;
918296465Sdelphij    krrl ^= krl;
919296465Sdelphij    krrr ^= krr;
920296465Sdelphij    CAMELLIA_F(krll, krlr,
921296465Sdelphij               CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R, w0, w1, il, ir, t0, t1);
922296465Sdelphij    krrl ^= w0;
923296465Sdelphij    krrr ^= w1;
924296465Sdelphij    CAMELLIA_F(krrl, krrr,
925296465Sdelphij               CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R, w0, w1, il, ir, t0, t1);
926296465Sdelphij    krll ^= w0;
927296465Sdelphij    krlr ^= w1;
928162911Ssimon
929296465Sdelphij    /* generate KA dependent subkeys */
930296465Sdelphij    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
931296465Sdelphij    /* k5 */
932296465Sdelphij    subl(6) = kll;
933296465Sdelphij    subr(6) = klr;
934296465Sdelphij    /* k6 */
935296465Sdelphij    subl(7) = krl;
936296465Sdelphij    subr(7) = krr;
937296465Sdelphij    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
938296465Sdelphij    /* k11 */
939296465Sdelphij    subl(14) = kll;
940296465Sdelphij    subr(14) = klr;
941296465Sdelphij    /* k12 */
942296465Sdelphij    subl(15) = krl;
943296465Sdelphij    subr(15) = krr;
944296465Sdelphij    /* rotation left shift 32bit */
945296465Sdelphij    /* kl5 */
946296465Sdelphij    subl(24) = klr;
947296465Sdelphij    subr(24) = krl;
948296465Sdelphij    /* kl6 */
949296465Sdelphij    subl(25) = krr;
950296465Sdelphij    subr(25) = kll;
951296465Sdelphij    /* rotation left shift 49 from k11,k12 -> k21,k22 */
952296465Sdelphij    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
953296465Sdelphij    /* k21 */
954296465Sdelphij    subl(28) = kll;
955296465Sdelphij    subr(28) = klr;
956296465Sdelphij    /* k22 */
957296465Sdelphij    subl(29) = krl;
958296465Sdelphij    subr(29) = krr;
959162911Ssimon
960296465Sdelphij    /* generate KB dependent subkeys */
961296465Sdelphij    /* k1 */
962296465Sdelphij    subl(2) = krll;
963296465Sdelphij    subr(2) = krlr;
964296465Sdelphij    /* k2 */
965296465Sdelphij    subl(3) = krrl;
966296465Sdelphij    subr(3) = krrr;
967296465Sdelphij    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
968296465Sdelphij    /* k7 */
969296465Sdelphij    subl(10) = krll;
970296465Sdelphij    subr(10) = krlr;
971296465Sdelphij    /* k8 */
972296465Sdelphij    subl(11) = krrl;
973296465Sdelphij    subr(11) = krrr;
974296465Sdelphij    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
975296465Sdelphij    /* k15 */
976296465Sdelphij    subl(20) = krll;
977296465Sdelphij    subr(20) = krlr;
978296465Sdelphij    /* k16 */
979296465Sdelphij    subl(21) = krrl;
980296465Sdelphij    subr(21) = krrr;
981296465Sdelphij    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
982296465Sdelphij    /* kw3 */
983296465Sdelphij    subl(32) = krll;
984296465Sdelphij    subr(32) = krlr;
985296465Sdelphij    /* kw4 */
986296465Sdelphij    subl(33) = krrl;
987296465Sdelphij    subr(33) = krrr;
988162911Ssimon
989296465Sdelphij    /* absorb kw2 to other subkeys */
990162911Ssimon/* round 2 */
991296465Sdelphij    subl(3) ^= subl(1);
992296465Sdelphij    subr(3) ^= subr(1);
993162911Ssimon/* round 4 */
994296465Sdelphij    subl(5) ^= subl(1);
995296465Sdelphij    subr(5) ^= subr(1);
996162911Ssimon/* round 6 */
997296465Sdelphij    subl(7) ^= subl(1);
998296465Sdelphij    subr(7) ^= subr(1);
999296465Sdelphij    subl(1) ^= subr(1) & ~subr(9);
1000296465Sdelphij    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw); /* modified for
1001296465Sdelphij                                                          * FLinv(kl2) */
1002162911Ssimon/* round 8 */
1003296465Sdelphij    subl(11) ^= subl(1);
1004296465Sdelphij    subr(11) ^= subr(1);
1005162911Ssimon/* round 10 */
1006296465Sdelphij    subl(13) ^= subl(1);
1007296465Sdelphij    subr(13) ^= subr(1);
1008162911Ssimon/* round 12 */
1009296465Sdelphij    subl(15) ^= subl(1);
1010296465Sdelphij    subr(15) ^= subr(1);
1011296465Sdelphij    subl(1) ^= subr(1) & ~subr(17);
1012296465Sdelphij    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw); /* modified for
1013296465Sdelphij                                                           * FLinv(kl4) */
1014162911Ssimon/* round 14 */
1015296465Sdelphij    subl(19) ^= subl(1);
1016296465Sdelphij    subr(19) ^= subr(1);
1017162911Ssimon/* round 16 */
1018296465Sdelphij    subl(21) ^= subl(1);
1019296465Sdelphij    subr(21) ^= subr(1);
1020162911Ssimon/* round 18 */
1021296465Sdelphij    subl(23) ^= subl(1);
1022296465Sdelphij    subr(23) ^= subr(1);
1023296465Sdelphij    subl(1) ^= subr(1) & ~subr(25);
1024296465Sdelphij    dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw); /* modified for
1025296465Sdelphij                                                           * FLinv(kl6) */
1026162911Ssimon/* round 20 */
1027296465Sdelphij    subl(27) ^= subl(1);
1028296465Sdelphij    subr(27) ^= subr(1);
1029162911Ssimon/* round 22 */
1030296465Sdelphij    subl(29) ^= subl(1);
1031296465Sdelphij    subr(29) ^= subr(1);
1032162911Ssimon/* round 24 */
1033296465Sdelphij    subl(31) ^= subl(1);
1034296465Sdelphij    subr(31) ^= subr(1);
1035162911Ssimon/* kw3 */
1036296465Sdelphij    subl(32) ^= subl(1);
1037296465Sdelphij    subr(32) ^= subr(1);
1038162911Ssimon
1039296465Sdelphij    /* absorb kw4 to other subkeys */
1040296465Sdelphij    kw4l = subl(33);
1041296465Sdelphij    kw4r = subr(33);
1042162911Ssimon/* round 23 */
1043296465Sdelphij    subl(30) ^= kw4l;
1044296465Sdelphij    subr(30) ^= kw4r;
1045162911Ssimon/* round 21 */
1046296465Sdelphij    subl(28) ^= kw4l;
1047296465Sdelphij    subr(28) ^= kw4r;
1048162911Ssimon/* round 19 */
1049296465Sdelphij    subl(26) ^= kw4l;
1050296465Sdelphij    subr(26) ^= kw4r;
1051296465Sdelphij    kw4l ^= kw4r & ~subr(24);
1052296465Sdelphij    dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl5) */
1053162911Ssimon/* round 17 */
1054296465Sdelphij    subl(22) ^= kw4l;
1055296465Sdelphij    subr(22) ^= kw4r;
1056162911Ssimon/* round 15 */
1057296465Sdelphij    subl(20) ^= kw4l;
1058296465Sdelphij    subr(20) ^= kw4r;
1059162911Ssimon/* round 13 */
1060296465Sdelphij    subl(18) ^= kw4l;
1061296465Sdelphij    subr(18) ^= kw4r;
1062296465Sdelphij    kw4l ^= kw4r & ~subr(16);
1063296465Sdelphij    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */
1064162911Ssimon/* round 11 */
1065296465Sdelphij    subl(14) ^= kw4l;
1066296465Sdelphij    subr(14) ^= kw4r;
1067162911Ssimon/* round 9 */
1068296465Sdelphij    subl(12) ^= kw4l;
1069296465Sdelphij    subr(12) ^= kw4r;
1070162911Ssimon/* round 7 */
1071296465Sdelphij    subl(10) ^= kw4l;
1072296465Sdelphij    subr(10) ^= kw4r;
1073296465Sdelphij    kw4l ^= kw4r & ~subr(8);
1074296465Sdelphij    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */
1075162911Ssimon/* round 5 */
1076296465Sdelphij    subl(6) ^= kw4l;
1077296465Sdelphij    subr(6) ^= kw4r;
1078162911Ssimon/* round 3 */
1079296465Sdelphij    subl(4) ^= kw4l;
1080296465Sdelphij    subr(4) ^= kw4r;
1081162911Ssimon/* round 1 */
1082296465Sdelphij    subl(2) ^= kw4l;
1083296465Sdelphij    subr(2) ^= kw4r;
1084162911Ssimon/* kw1 */
1085296465Sdelphij    subl(0) ^= kw4l;
1086296465Sdelphij    subr(0) ^= kw4r;
1087162911Ssimon
1088296465Sdelphij    /* key XOR is end of F-function */
1089296465Sdelphij    CamelliaSubkeyL(0) = subl(0) ^ subl(2); /* kw1 */
1090296465Sdelphij    CamelliaSubkeyR(0) = subr(0) ^ subr(2);
1091296465Sdelphij    CamelliaSubkeyL(2) = subl(3); /* round 1 */
1092296465Sdelphij    CamelliaSubkeyR(2) = subr(3);
1093296465Sdelphij    CamelliaSubkeyL(3) = subl(2) ^ subl(4); /* round 2 */
1094296465Sdelphij    CamelliaSubkeyR(3) = subr(2) ^ subr(4);
1095296465Sdelphij    CamelliaSubkeyL(4) = subl(3) ^ subl(5); /* round 3 */
1096296465Sdelphij    CamelliaSubkeyR(4) = subr(3) ^ subr(5);
1097296465Sdelphij    CamelliaSubkeyL(5) = subl(4) ^ subl(6); /* round 4 */
1098296465Sdelphij    CamelliaSubkeyR(5) = subr(4) ^ subr(6);
1099296465Sdelphij    CamelliaSubkeyL(6) = subl(5) ^ subl(7); /* round 5 */
1100296465Sdelphij    CamelliaSubkeyR(6) = subr(5) ^ subr(7);
1101296465Sdelphij    tl = subl(10) ^ (subr(10) & ~subr(8));
1102296465Sdelphij    dw = tl & subl(8),          /* FL(kl1) */
1103296465Sdelphij        tr = subr(10) ^ CAMELLIA_RL1(dw);
1104296465Sdelphij    CamelliaSubkeyL(7) = subl(6) ^ tl; /* round 6 */
1105296465Sdelphij    CamelliaSubkeyR(7) = subr(6) ^ tr;
1106296465Sdelphij    CamelliaSubkeyL(8) = subl(8); /* FL(kl1) */
1107296465Sdelphij    CamelliaSubkeyR(8) = subr(8);
1108296465Sdelphij    CamelliaSubkeyL(9) = subl(9); /* FLinv(kl2) */
1109296465Sdelphij    CamelliaSubkeyR(9) = subr(9);
1110296465Sdelphij    tl = subl(7) ^ (subr(7) & ~subr(9));
1111296465Sdelphij    dw = tl & subl(9),          /* FLinv(kl2) */
1112296465Sdelphij        tr = subr(7) ^ CAMELLIA_RL1(dw);
1113296465Sdelphij    CamelliaSubkeyL(10) = tl ^ subl(11); /* round 7 */
1114296465Sdelphij    CamelliaSubkeyR(10) = tr ^ subr(11);
1115296465Sdelphij    CamelliaSubkeyL(11) = subl(10) ^ subl(12); /* round 8 */
1116296465Sdelphij    CamelliaSubkeyR(11) = subr(10) ^ subr(12);
1117296465Sdelphij    CamelliaSubkeyL(12) = subl(11) ^ subl(13); /* round 9 */
1118296465Sdelphij    CamelliaSubkeyR(12) = subr(11) ^ subr(13);
1119296465Sdelphij    CamelliaSubkeyL(13) = subl(12) ^ subl(14); /* round 10 */
1120296465Sdelphij    CamelliaSubkeyR(13) = subr(12) ^ subr(14);
1121296465Sdelphij    CamelliaSubkeyL(14) = subl(13) ^ subl(15); /* round 11 */
1122296465Sdelphij    CamelliaSubkeyR(14) = subr(13) ^ subr(15);
1123296465Sdelphij    tl = subl(18) ^ (subr(18) & ~subr(16));
1124296465Sdelphij    dw = tl & subl(16),         /* FL(kl3) */
1125296465Sdelphij        tr = subr(18) ^ CAMELLIA_RL1(dw);
1126296465Sdelphij    CamelliaSubkeyL(15) = subl(14) ^ tl; /* round 12 */
1127296465Sdelphij    CamelliaSubkeyR(15) = subr(14) ^ tr;
1128296465Sdelphij    CamelliaSubkeyL(16) = subl(16); /* FL(kl3) */
1129296465Sdelphij    CamelliaSubkeyR(16) = subr(16);
1130296465Sdelphij    CamelliaSubkeyL(17) = subl(17); /* FLinv(kl4) */
1131296465Sdelphij    CamelliaSubkeyR(17) = subr(17);
1132296465Sdelphij    tl = subl(15) ^ (subr(15) & ~subr(17));
1133296465Sdelphij    dw = tl & subl(17),         /* FLinv(kl4) */
1134296465Sdelphij        tr = subr(15) ^ CAMELLIA_RL1(dw);
1135296465Sdelphij    CamelliaSubkeyL(18) = tl ^ subl(19); /* round 13 */
1136296465Sdelphij    CamelliaSubkeyR(18) = tr ^ subr(19);
1137296465Sdelphij    CamelliaSubkeyL(19) = subl(18) ^ subl(20); /* round 14 */
1138296465Sdelphij    CamelliaSubkeyR(19) = subr(18) ^ subr(20);
1139296465Sdelphij    CamelliaSubkeyL(20) = subl(19) ^ subl(21); /* round 15 */
1140296465Sdelphij    CamelliaSubkeyR(20) = subr(19) ^ subr(21);
1141296465Sdelphij    CamelliaSubkeyL(21) = subl(20) ^ subl(22); /* round 16 */
1142296465Sdelphij    CamelliaSubkeyR(21) = subr(20) ^ subr(22);
1143296465Sdelphij    CamelliaSubkeyL(22) = subl(21) ^ subl(23); /* round 17 */
1144296465Sdelphij    CamelliaSubkeyR(22) = subr(21) ^ subr(23);
1145296465Sdelphij    tl = subl(26) ^ (subr(26)
1146296465Sdelphij                     & ~subr(24));
1147296465Sdelphij    dw = tl & subl(24),         /* FL(kl5) */
1148296465Sdelphij        tr = subr(26) ^ CAMELLIA_RL1(dw);
1149296465Sdelphij    CamelliaSubkeyL(23) = subl(22) ^ tl; /* round 18 */
1150296465Sdelphij    CamelliaSubkeyR(23) = subr(22) ^ tr;
1151296465Sdelphij    CamelliaSubkeyL(24) = subl(24); /* FL(kl5) */
1152296465Sdelphij    CamelliaSubkeyR(24) = subr(24);
1153296465Sdelphij    CamelliaSubkeyL(25) = subl(25); /* FLinv(kl6) */
1154296465Sdelphij    CamelliaSubkeyR(25) = subr(25);
1155296465Sdelphij    tl = subl(23) ^ (subr(23) & ~subr(25));
1156296465Sdelphij    dw = tl & subl(25),         /* FLinv(kl6) */
1157296465Sdelphij        tr = subr(23) ^ CAMELLIA_RL1(dw);
1158296465Sdelphij    CamelliaSubkeyL(26) = tl ^ subl(27); /* round 19 */
1159296465Sdelphij    CamelliaSubkeyR(26) = tr ^ subr(27);
1160296465Sdelphij    CamelliaSubkeyL(27) = subl(26) ^ subl(28); /* round 20 */
1161296465Sdelphij    CamelliaSubkeyR(27) = subr(26) ^ subr(28);
1162296465Sdelphij    CamelliaSubkeyL(28) = subl(27) ^ subl(29); /* round 21 */
1163296465Sdelphij    CamelliaSubkeyR(28) = subr(27) ^ subr(29);
1164296465Sdelphij    CamelliaSubkeyL(29) = subl(28) ^ subl(30); /* round 22 */
1165296465Sdelphij    CamelliaSubkeyR(29) = subr(28) ^ subr(30);
1166296465Sdelphij    CamelliaSubkeyL(30) = subl(29) ^ subl(31); /* round 23 */
1167296465Sdelphij    CamelliaSubkeyR(30) = subr(29) ^ subr(31);
1168296465Sdelphij    CamelliaSubkeyL(31) = subl(30); /* round 24 */
1169296465Sdelphij    CamelliaSubkeyR(31) = subr(30);
1170296465Sdelphij    CamelliaSubkeyL(32) = subl(32) ^ subl(31); /* kw3 */
1171296465Sdelphij    CamelliaSubkeyR(32) = subr(32) ^ subr(31);
1172162911Ssimon
1173296465Sdelphij    /* apply the inverse of the last half of P-function */
1174296465Sdelphij    /* round 1 */
1175296465Sdelphij    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
1176296465Sdelphij    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
1177296465Sdelphij    /* round 2 */
1178296465Sdelphij    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
1179296465Sdelphij    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
1180296465Sdelphij    /* round 3 */
1181296465Sdelphij    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
1182296465Sdelphij    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
1183296465Sdelphij    /* round 4 */
1184296465Sdelphij    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
1185296465Sdelphij    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
1186296465Sdelphij    /* round 5 */
1187296465Sdelphij    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
1188296465Sdelphij    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
1189296465Sdelphij    /* round 6 */
1190296465Sdelphij    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
1191296465Sdelphij    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
1192296465Sdelphij    /* round 7 */
1193296465Sdelphij    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
1194296465Sdelphij    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
1195296465Sdelphij    /* round 8 */
1196296465Sdelphij    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
1197296465Sdelphij    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
1198296465Sdelphij    /* round 9 */
1199296465Sdelphij    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
1200296465Sdelphij    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
1201296465Sdelphij    /* round 10 */
1202296465Sdelphij    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
1203296465Sdelphij    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
1204296465Sdelphij    /* round 11 */
1205296465Sdelphij    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
1206296465Sdelphij    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
1207296465Sdelphij    /* round 12 */
1208296465Sdelphij    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
1209296465Sdelphij    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
1210296465Sdelphij    /* round 13 */
1211296465Sdelphij    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
1212296465Sdelphij    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
1213296465Sdelphij    /* round 14 */
1214296465Sdelphij    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
1215296465Sdelphij    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
1216296465Sdelphij    /* round 15 */
1217296465Sdelphij    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
1218296465Sdelphij    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
1219296465Sdelphij    /* round 16 */
1220296465Sdelphij    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
1221296465Sdelphij    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
1222296465Sdelphij    /* round 17 */
1223296465Sdelphij    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
1224296465Sdelphij    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
1225296465Sdelphij    /* round 18 */
1226296465Sdelphij    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
1227296465Sdelphij    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
1228296465Sdelphij    /* round 19 */
1229296465Sdelphij    dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), dw = CAMELLIA_RL8(dw);
1230296465Sdelphij    CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, CamelliaSubkeyL(26) = dw;
1231296465Sdelphij    /* round 20 */
1232296465Sdelphij    dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), dw = CAMELLIA_RL8(dw);
1233296465Sdelphij    CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, CamelliaSubkeyL(27) = dw;
1234296465Sdelphij    /* round 21 */
1235296465Sdelphij    dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), dw = CAMELLIA_RL8(dw);
1236296465Sdelphij    CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, CamelliaSubkeyL(28) = dw;
1237296465Sdelphij    /* round 22 */
1238296465Sdelphij    dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), dw = CAMELLIA_RL8(dw);
1239296465Sdelphij    CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, CamelliaSubkeyL(29) = dw;
1240296465Sdelphij    /* round 23 */
1241296465Sdelphij    dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), dw = CAMELLIA_RL8(dw);
1242296465Sdelphij    CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw;
1243296465Sdelphij    /* round 24 */
1244296465Sdelphij    dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw);
1245296465Sdelphij    CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw, CamelliaSubkeyL(31) = dw;
1246162911Ssimon
1247296465Sdelphij    return;
1248296465Sdelphij}
1249162911Ssimon
1250167612Ssimonvoid camellia_setup192(const u8 *key, u32 *subkey)
1251296465Sdelphij{
1252296465Sdelphij    u8 kk[32];
1253296465Sdelphij    u32 krll, krlr, krrl, krrr;
1254162911Ssimon
1255296465Sdelphij    memcpy(kk, key, 24);
1256296465Sdelphij    memcpy((u8 *)&krll, key + 16, 4);
1257296465Sdelphij    memcpy((u8 *)&krlr, key + 20, 4);
1258296465Sdelphij    krrl = ~krll;
1259296465Sdelphij    krrr = ~krlr;
1260296465Sdelphij    memcpy(kk + 24, (u8 *)&krrl, 4);
1261296465Sdelphij    memcpy(kk + 28, (u8 *)&krrr, 4);
1262296465Sdelphij    camellia_setup256(kk, subkey);
1263296465Sdelphij    return;
1264296465Sdelphij}
1265162911Ssimon
1266162911Ssimon/**
1267162911Ssimon * Stuff related to camellia encryption/decryption
1268162911Ssimon */
1269167612Ssimonvoid camellia_encrypt128(const u32 *subkey, u32 *io)
1270296465Sdelphij{
1271296465Sdelphij    u32 il, ir, t0, t1;
1272162911Ssimon
1273296465Sdelphij    /* pre whitening but absorb kw2 */
1274296465Sdelphij    io[0] ^= CamelliaSubkeyL(0);
1275296465Sdelphij    io[1] ^= CamelliaSubkeyR(0);
1276296465Sdelphij    /* main iteration */
1277162911Ssimon
1278296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1279296465Sdelphij                     CamelliaSubkeyL(2), CamelliaSubkeyR(2),
1280296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1281296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1282296465Sdelphij                     CamelliaSubkeyL(3), CamelliaSubkeyR(3),
1283296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1284296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1285296465Sdelphij                     CamelliaSubkeyL(4), CamelliaSubkeyR(4),
1286296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1287296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1288296465Sdelphij                     CamelliaSubkeyL(5), CamelliaSubkeyR(5),
1289296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1290296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1291296465Sdelphij                     CamelliaSubkeyL(6), CamelliaSubkeyR(6),
1292296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1293296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1294296465Sdelphij                     CamelliaSubkeyL(7), CamelliaSubkeyR(7),
1295296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1296162911Ssimon
1297296465Sdelphij    CAMELLIA_FLS(io[0], io[1], io[2], io[3],
1298296465Sdelphij                 CamelliaSubkeyL(8), CamelliaSubkeyR(8),
1299296465Sdelphij                 CamelliaSubkeyL(9), CamelliaSubkeyR(9), t0, t1, il, ir);
1300162911Ssimon
1301296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1302296465Sdelphij                     CamelliaSubkeyL(10), CamelliaSubkeyR(10),
1303296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1304296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1305296465Sdelphij                     CamelliaSubkeyL(11), CamelliaSubkeyR(11),
1306296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1307296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1308296465Sdelphij                     CamelliaSubkeyL(12), CamelliaSubkeyR(12),
1309296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1310296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1311296465Sdelphij                     CamelliaSubkeyL(13), CamelliaSubkeyR(13),
1312296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1313296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1314296465Sdelphij                     CamelliaSubkeyL(14), CamelliaSubkeyR(14),
1315296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1316296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1317296465Sdelphij                     CamelliaSubkeyL(15), CamelliaSubkeyR(15),
1318296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1319162911Ssimon
1320296465Sdelphij    CAMELLIA_FLS(io[0], io[1], io[2], io[3],
1321296465Sdelphij                 CamelliaSubkeyL(16), CamelliaSubkeyR(16),
1322296465Sdelphij                 CamelliaSubkeyL(17), CamelliaSubkeyR(17), t0, t1, il, ir);
1323162911Ssimon
1324296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1325296465Sdelphij                     CamelliaSubkeyL(18), CamelliaSubkeyR(18),
1326296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1327296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1328296465Sdelphij                     CamelliaSubkeyL(19), CamelliaSubkeyR(19),
1329296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1330296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1331296465Sdelphij                     CamelliaSubkeyL(20), CamelliaSubkeyR(20),
1332296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1333296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1334296465Sdelphij                     CamelliaSubkeyL(21), CamelliaSubkeyR(21),
1335296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1336296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1337296465Sdelphij                     CamelliaSubkeyL(22), CamelliaSubkeyR(22),
1338296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1339296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1340296465Sdelphij                     CamelliaSubkeyL(23), CamelliaSubkeyR(23),
1341296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1342162911Ssimon
1343296465Sdelphij    /* post whitening but kw4 */
1344296465Sdelphij    io[2] ^= CamelliaSubkeyL(24);
1345296465Sdelphij    io[3] ^= CamelliaSubkeyR(24);
1346162911Ssimon
1347296465Sdelphij    t0 = io[0];
1348296465Sdelphij    t1 = io[1];
1349296465Sdelphij    io[0] = io[2];
1350296465Sdelphij    io[1] = io[3];
1351296465Sdelphij    io[2] = t0;
1352296465Sdelphij    io[3] = t1;
1353167612Ssimon
1354296465Sdelphij    return;
1355296465Sdelphij}
1356162911Ssimon
1357167612Ssimonvoid camellia_decrypt128(const u32 *subkey, u32 *io)
1358296465Sdelphij{
1359296465Sdelphij    u32 il, ir, t0, t1;         /* temporary valiables */
1360162911Ssimon
1361296465Sdelphij    /* pre whitening but absorb kw2 */
1362296465Sdelphij    io[0] ^= CamelliaSubkeyL(24);
1363296465Sdelphij    io[1] ^= CamelliaSubkeyR(24);
1364162911Ssimon
1365296465Sdelphij    /* main iteration */
1366296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1367296465Sdelphij                     CamelliaSubkeyL(23), CamelliaSubkeyR(23),
1368296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1369296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1370296465Sdelphij                     CamelliaSubkeyL(22), CamelliaSubkeyR(22),
1371296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1372296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1373296465Sdelphij                     CamelliaSubkeyL(21), CamelliaSubkeyR(21),
1374296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1375296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1376296465Sdelphij                     CamelliaSubkeyL(20), CamelliaSubkeyR(20),
1377296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1378296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1379296465Sdelphij                     CamelliaSubkeyL(19), CamelliaSubkeyR(19),
1380296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1381296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1382296465Sdelphij                     CamelliaSubkeyL(18), CamelliaSubkeyR(18),
1383296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1384162911Ssimon
1385296465Sdelphij    CAMELLIA_FLS(io[0], io[1], io[2], io[3],
1386296465Sdelphij                 CamelliaSubkeyL(17), CamelliaSubkeyR(17),
1387296465Sdelphij                 CamelliaSubkeyL(16), CamelliaSubkeyR(16), t0, t1, il, ir);
1388162911Ssimon
1389296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1390296465Sdelphij                     CamelliaSubkeyL(15), CamelliaSubkeyR(15),
1391296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1392296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1393296465Sdelphij                     CamelliaSubkeyL(14), CamelliaSubkeyR(14),
1394296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1395296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1396296465Sdelphij                     CamelliaSubkeyL(13), CamelliaSubkeyR(13),
1397296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1398296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1399296465Sdelphij                     CamelliaSubkeyL(12), CamelliaSubkeyR(12),
1400296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1401296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1402296465Sdelphij                     CamelliaSubkeyL(11), CamelliaSubkeyR(11),
1403296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1404296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1405296465Sdelphij                     CamelliaSubkeyL(10), CamelliaSubkeyR(10),
1406296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1407162911Ssimon
1408296465Sdelphij    CAMELLIA_FLS(io[0], io[1], io[2], io[3],
1409296465Sdelphij                 CamelliaSubkeyL(9), CamelliaSubkeyR(9),
1410296465Sdelphij                 CamelliaSubkeyL(8), CamelliaSubkeyR(8), t0, t1, il, ir);
1411162911Ssimon
1412296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1413296465Sdelphij                     CamelliaSubkeyL(7), CamelliaSubkeyR(7),
1414296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1415296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1416296465Sdelphij                     CamelliaSubkeyL(6), CamelliaSubkeyR(6),
1417296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1418296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1419296465Sdelphij                     CamelliaSubkeyL(5), CamelliaSubkeyR(5),
1420296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1421296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1422296465Sdelphij                     CamelliaSubkeyL(4), CamelliaSubkeyR(4),
1423296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1424296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1425296465Sdelphij                     CamelliaSubkeyL(3), CamelliaSubkeyR(3),
1426296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1427296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1428296465Sdelphij                     CamelliaSubkeyL(2), CamelliaSubkeyR(2),
1429296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1430162911Ssimon
1431296465Sdelphij    /* post whitening but kw4 */
1432296465Sdelphij    io[2] ^= CamelliaSubkeyL(0);
1433296465Sdelphij    io[3] ^= CamelliaSubkeyR(0);
1434162911Ssimon
1435296465Sdelphij    t0 = io[0];
1436296465Sdelphij    t1 = io[1];
1437296465Sdelphij    io[0] = io[2];
1438296465Sdelphij    io[1] = io[3];
1439296465Sdelphij    io[2] = t0;
1440296465Sdelphij    io[3] = t1;
1441162911Ssimon
1442296465Sdelphij    return;
1443296465Sdelphij}
1444162911Ssimon
1445162911Ssimon/**
1446162911Ssimon * stuff for 192 and 256bit encryption/decryption
1447162911Ssimon */
1448167612Ssimonvoid camellia_encrypt256(const u32 *subkey, u32 *io)
1449296465Sdelphij{
1450296465Sdelphij    u32 il, ir, t0, t1;         /* temporary valiables */
1451162911Ssimon
1452296465Sdelphij    /* pre whitening but absorb kw2 */
1453296465Sdelphij    io[0] ^= CamelliaSubkeyL(0);
1454296465Sdelphij    io[1] ^= CamelliaSubkeyR(0);
1455162911Ssimon
1456296465Sdelphij    /* main iteration */
1457296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1458296465Sdelphij                     CamelliaSubkeyL(2), CamelliaSubkeyR(2),
1459296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1460296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1461296465Sdelphij                     CamelliaSubkeyL(3), CamelliaSubkeyR(3),
1462296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1463296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1464296465Sdelphij                     CamelliaSubkeyL(4), CamelliaSubkeyR(4),
1465296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1466296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1467296465Sdelphij                     CamelliaSubkeyL(5), CamelliaSubkeyR(5),
1468296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1469296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1470296465Sdelphij                     CamelliaSubkeyL(6), CamelliaSubkeyR(6),
1471296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1472296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1473296465Sdelphij                     CamelliaSubkeyL(7), CamelliaSubkeyR(7),
1474296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1475162911Ssimon
1476296465Sdelphij    CAMELLIA_FLS(io[0], io[1], io[2], io[3],
1477296465Sdelphij                 CamelliaSubkeyL(8), CamelliaSubkeyR(8),
1478296465Sdelphij                 CamelliaSubkeyL(9), CamelliaSubkeyR(9), t0, t1, il, ir);
1479162911Ssimon
1480296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1481296465Sdelphij                     CamelliaSubkeyL(10), CamelliaSubkeyR(10),
1482296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1483296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1484296465Sdelphij                     CamelliaSubkeyL(11), CamelliaSubkeyR(11),
1485296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1486296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1487296465Sdelphij                     CamelliaSubkeyL(12), CamelliaSubkeyR(12),
1488296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1489296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1490296465Sdelphij                     CamelliaSubkeyL(13), CamelliaSubkeyR(13),
1491296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1492296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1493296465Sdelphij                     CamelliaSubkeyL(14), CamelliaSubkeyR(14),
1494296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1495296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1496296465Sdelphij                     CamelliaSubkeyL(15), CamelliaSubkeyR(15),
1497296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1498162911Ssimon
1499296465Sdelphij    CAMELLIA_FLS(io[0], io[1], io[2], io[3],
1500296465Sdelphij                 CamelliaSubkeyL(16), CamelliaSubkeyR(16),
1501296465Sdelphij                 CamelliaSubkeyL(17), CamelliaSubkeyR(17), t0, t1, il, ir);
1502162911Ssimon
1503296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1504296465Sdelphij                     CamelliaSubkeyL(18), CamelliaSubkeyR(18),
1505296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1506296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1507296465Sdelphij                     CamelliaSubkeyL(19), CamelliaSubkeyR(19),
1508296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1509296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1510296465Sdelphij                     CamelliaSubkeyL(20), CamelliaSubkeyR(20),
1511296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1512296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1513296465Sdelphij                     CamelliaSubkeyL(21), CamelliaSubkeyR(21),
1514296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1515296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1516296465Sdelphij                     CamelliaSubkeyL(22), CamelliaSubkeyR(22),
1517296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1518296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1519296465Sdelphij                     CamelliaSubkeyL(23), CamelliaSubkeyR(23),
1520296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1521162911Ssimon
1522296465Sdelphij    CAMELLIA_FLS(io[0], io[1], io[2], io[3],
1523296465Sdelphij                 CamelliaSubkeyL(24), CamelliaSubkeyR(24),
1524296465Sdelphij                 CamelliaSubkeyL(25), CamelliaSubkeyR(25), t0, t1, il, ir);
1525162911Ssimon
1526296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1527296465Sdelphij                     CamelliaSubkeyL(26), CamelliaSubkeyR(26),
1528296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1529296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1530296465Sdelphij                     CamelliaSubkeyL(27), CamelliaSubkeyR(27),
1531296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1532296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1533296465Sdelphij                     CamelliaSubkeyL(28), CamelliaSubkeyR(28),
1534296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1535296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1536296465Sdelphij                     CamelliaSubkeyL(29), CamelliaSubkeyR(29),
1537296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1538296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1539296465Sdelphij                     CamelliaSubkeyL(30), CamelliaSubkeyR(30),
1540296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1541296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1542296465Sdelphij                     CamelliaSubkeyL(31), CamelliaSubkeyR(31),
1543296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1544162911Ssimon
1545296465Sdelphij    /* post whitening but kw4 */
1546296465Sdelphij    io[2] ^= CamelliaSubkeyL(32);
1547296465Sdelphij    io[3] ^= CamelliaSubkeyR(32);
1548162911Ssimon
1549296465Sdelphij    t0 = io[0];
1550296465Sdelphij    t1 = io[1];
1551296465Sdelphij    io[0] = io[2];
1552296465Sdelphij    io[1] = io[3];
1553296465Sdelphij    io[2] = t0;
1554296465Sdelphij    io[3] = t1;
1555162911Ssimon
1556296465Sdelphij    return;
1557296465Sdelphij}
1558162911Ssimon
1559167612Ssimonvoid camellia_decrypt256(const u32 *subkey, u32 *io)
1560296465Sdelphij{
1561296465Sdelphij    u32 il, ir, t0, t1;         /* temporary valiables */
1562162911Ssimon
1563296465Sdelphij    /* pre whitening but absorb kw2 */
1564296465Sdelphij    io[0] ^= CamelliaSubkeyL(32);
1565296465Sdelphij    io[1] ^= CamelliaSubkeyR(32);
1566162911Ssimon
1567296465Sdelphij    /* main iteration */
1568296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1569296465Sdelphij                     CamelliaSubkeyL(31), CamelliaSubkeyR(31),
1570296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1571296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1572296465Sdelphij                     CamelliaSubkeyL(30), CamelliaSubkeyR(30),
1573296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1574296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1575296465Sdelphij                     CamelliaSubkeyL(29), CamelliaSubkeyR(29),
1576296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1577296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1578296465Sdelphij                     CamelliaSubkeyL(28), CamelliaSubkeyR(28),
1579296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1580296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1581296465Sdelphij                     CamelliaSubkeyL(27), CamelliaSubkeyR(27),
1582296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1583296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1584296465Sdelphij                     CamelliaSubkeyL(26), CamelliaSubkeyR(26),
1585296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1586162911Ssimon
1587296465Sdelphij    CAMELLIA_FLS(io[0], io[1], io[2], io[3],
1588296465Sdelphij                 CamelliaSubkeyL(25), CamelliaSubkeyR(25),
1589296465Sdelphij                 CamelliaSubkeyL(24), CamelliaSubkeyR(24), t0, t1, il, ir);
1590162911Ssimon
1591296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1592296465Sdelphij                     CamelliaSubkeyL(23), CamelliaSubkeyR(23),
1593296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1594296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1595296465Sdelphij                     CamelliaSubkeyL(22), CamelliaSubkeyR(22),
1596296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1597296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1598296465Sdelphij                     CamelliaSubkeyL(21), CamelliaSubkeyR(21),
1599296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1600296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1601296465Sdelphij                     CamelliaSubkeyL(20), CamelliaSubkeyR(20),
1602296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1603296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1604296465Sdelphij                     CamelliaSubkeyL(19), CamelliaSubkeyR(19),
1605296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1606296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1607296465Sdelphij                     CamelliaSubkeyL(18), CamelliaSubkeyR(18),
1608296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1609162911Ssimon
1610296465Sdelphij    CAMELLIA_FLS(io[0], io[1], io[2], io[3],
1611296465Sdelphij                 CamelliaSubkeyL(17), CamelliaSubkeyR(17),
1612296465Sdelphij                 CamelliaSubkeyL(16), CamelliaSubkeyR(16), t0, t1, il, ir);
1613162911Ssimon
1614296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1615296465Sdelphij                     CamelliaSubkeyL(15), CamelliaSubkeyR(15),
1616296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1617296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1618296465Sdelphij                     CamelliaSubkeyL(14), CamelliaSubkeyR(14),
1619296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1620296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1621296465Sdelphij                     CamelliaSubkeyL(13), CamelliaSubkeyR(13),
1622296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1623296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1624296465Sdelphij                     CamelliaSubkeyL(12), CamelliaSubkeyR(12),
1625296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1626296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1627296465Sdelphij                     CamelliaSubkeyL(11), CamelliaSubkeyR(11),
1628296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1629296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1630296465Sdelphij                     CamelliaSubkeyL(10), CamelliaSubkeyR(10),
1631296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1632162911Ssimon
1633296465Sdelphij    CAMELLIA_FLS(io[0], io[1], io[2], io[3],
1634296465Sdelphij                 CamelliaSubkeyL(9), CamelliaSubkeyR(9),
1635296465Sdelphij                 CamelliaSubkeyL(8), CamelliaSubkeyR(8), t0, t1, il, ir);
1636162911Ssimon
1637296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1638296465Sdelphij                     CamelliaSubkeyL(7), CamelliaSubkeyR(7),
1639296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1640296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1641296465Sdelphij                     CamelliaSubkeyL(6), CamelliaSubkeyR(6),
1642296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1643296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1644296465Sdelphij                     CamelliaSubkeyL(5), CamelliaSubkeyR(5),
1645296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1646296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1647296465Sdelphij                     CamelliaSubkeyL(4), CamelliaSubkeyR(4),
1648296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1649296465Sdelphij    CAMELLIA_ROUNDSM(io[0], io[1],
1650296465Sdelphij                     CamelliaSubkeyL(3), CamelliaSubkeyR(3),
1651296465Sdelphij                     io[2], io[3], il, ir, t0, t1);
1652296465Sdelphij    CAMELLIA_ROUNDSM(io[2], io[3],
1653296465Sdelphij                     CamelliaSubkeyL(2), CamelliaSubkeyR(2),
1654296465Sdelphij                     io[0], io[1], il, ir, t0, t1);
1655162911Ssimon
1656296465Sdelphij    /* post whitening but kw4 */
1657296465Sdelphij    io[2] ^= CamelliaSubkeyL(0);
1658296465Sdelphij    io[3] ^= CamelliaSubkeyR(0);
1659162911Ssimon
1660296465Sdelphij    t0 = io[0];
1661296465Sdelphij    t1 = io[1];
1662296465Sdelphij    io[0] = io[2];
1663296465Sdelphij    io[1] = io[3];
1664296465Sdelphij    io[2] = t0;
1665296465Sdelphij    io[3] = t1;
1666162911Ssimon
1667296465Sdelphij    return;
1668296465Sdelphij}
1669