1295016Sjkim/* crypto/camellia/camellia.c */
2162911Ssimon/* ====================================================================
3280304Sjkim * 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
27280304Sjkim *    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
68238405Sjkim/*
69280304Sjkim * Algorithm Specification
70295016Sjkim * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
71280304Sjkim */
72280304Sjkim
73280304Sjkim/*
74238405Sjkim * This release balances code size and performance. In particular key
75238405Sjkim * schedule setup is fully unrolled, because doing so *significantly*
76238405Sjkim * reduces amount of instructions per setup round and code increase is
77238405Sjkim * justifiable. In block functions on the other hand only inner loops
78238405Sjkim * are unrolled, as full unroll gives only nominal performance boost,
79238405Sjkim * while code size grows 4 or 7 times. Also, unlike previous versions
80238405Sjkim * this one "encourages" compiler to keep intermediate variables in
81238405Sjkim * registers, which should give better "all round" results, in other
82238405Sjkim * words reasonable performance even with not so modern compilers.
83238405Sjkim */
84162911Ssimon
85238405Sjkim#include "camellia.h"
86238405Sjkim#include "cmll_locl.h"
87162911Ssimon#include <string.h>
88162911Ssimon#include <stdlib.h>
89162911Ssimon
90238405Sjkim/* 32-bit rotations */
91238405Sjkim#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
92238405Sjkim# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
93238405Sjkim#  define RightRotate(x, s) _lrotr(x, s)
94238405Sjkim#  define LeftRotate(x, s)  _lrotl(x, s)
95238405Sjkim#  if _MSC_VER >= 1400
96238405Sjkim#   define SWAP(x) _byteswap_ulong(x)
97238405Sjkim#  else
98238405Sjkim#   define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
99238405Sjkim#  endif
100238405Sjkim#  define GETU32(p)   SWAP(*((u32 *)(p)))
101238405Sjkim#  define PUTU32(p,v) (*((u32 *)(p)) = SWAP((v)))
102238405Sjkim# elif defined(__GNUC__) && __GNUC__>=2
103238405Sjkim#  if defined(__i386) || defined(__x86_64)
104238405Sjkim#   define RightRotate(x,s) ({u32 ret; asm ("rorl %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; })
105238405Sjkim#   define LeftRotate(x,s)  ({u32 ret; asm ("roll %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; })
106280304Sjkim#   if defined(B_ENDIAN)        /* stratus.com does it */
107238405Sjkim#    define GETU32(p)   (*(u32 *)(p))
108238405Sjkim#    define PUTU32(p,v) (*(u32 *)(p)=(v))
109238405Sjkim#   else
110238405Sjkim#    define GETU32(p)   ({u32 r=*(const u32 *)(p); asm("bswapl %0":"=r"(r):"0"(r)); r; })
111238405Sjkim#    define PUTU32(p,v) ({u32 r=(v); asm("bswapl %0":"=r"(r):"0"(r)); *(u32 *)(p)=r; })
112238405Sjkim#   endif
113238405Sjkim#  elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
114238405Sjkim        defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
115238405Sjkim#   define LeftRotate(x,s)  ({u32 ret; asm ("rlwinm %0,%1,%2,0,31":"=r"(ret):"r"(x),"I"(s)); ret; })
116238405Sjkim#   define RightRotate(x,s) LeftRotate(x,(32-s))
117238405Sjkim#  elif defined(__s390x__)
118238405Sjkim#   define LeftRotate(x,s)  ({u32 ret; asm ("rll %0,%1,%2":"=r"(ret):"r"(x),"I"(s)); ret; })
119238405Sjkim#   define RightRotate(x,s) LeftRotate(x,(32-s))
120238405Sjkim#   define GETU32(p)   (*(u32 *)(p))
121238405Sjkim#   define PUTU32(p,v) (*(u32 *)(p)=(v))
122238405Sjkim#  endif
123238405Sjkim# endif
124238405Sjkim#endif
125162911Ssimon
126238405Sjkim#if !defined(RightRotate) && !defined(LeftRotate)
127238405Sjkim# define RightRotate(x, s) ( ((x) >> (s)) + ((x) << (32 - s)) )
128238405Sjkim# define LeftRotate(x, s)  ( ((x) << (s)) + ((x) >> (32 - s)) )
129238405Sjkim#endif
130162911Ssimon
131238405Sjkim#if !defined(GETU32) && !defined(PUTU32)
132238405Sjkim# define GETU32(p)   (((u32)(p)[0] << 24) ^ ((u32)(p)[1] << 16) ^ ((u32)(p)[2] <<  8) ^ ((u32)(p)[3]))
133238405Sjkim# define PUTU32(p,v) ((p)[0] = (u8)((v) >> 24), (p)[1] = (u8)((v) >> 16), (p)[2] = (u8)((v) >>  8), (p)[3] = (u8)(v))
134238405Sjkim#endif
135162911Ssimon
136238405Sjkim/* S-box data */
137238405Sjkim#define SBOX1_1110 Camellia_SBOX[0]
138238405Sjkim#define SBOX4_4404 Camellia_SBOX[1]
139238405Sjkim#define SBOX2_0222 Camellia_SBOX[2]
140238405Sjkim#define SBOX3_3033 Camellia_SBOX[3]
141238405Sjkimstatic const u32 Camellia_SBOX[][256] = {
142280304Sjkim    {0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700,
143280304Sjkim     0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500,
144280304Sjkim     0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00,
145280304Sjkim     0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100,
146280304Sjkim     0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500,
147280304Sjkim     0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00,
148280304Sjkim     0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000,
149280304Sjkim     0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00,
150280304Sjkim     0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700,
151280304Sjkim     0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600,
152280304Sjkim     0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00,
153280304Sjkim     0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00,
154280304Sjkim     0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100,
155280304Sjkim     0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200,
156280304Sjkim     0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700,
157280304Sjkim     0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700,
158280304Sjkim     0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00,
159280304Sjkim     0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600,
160280304Sjkim     0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400,
161280304Sjkim     0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100,
162280304Sjkim     0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00,
163280304Sjkim     0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00,
164280304Sjkim     0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00,
165280304Sjkim     0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200,
166280304Sjkim     0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700,
167280304Sjkim     0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00,
168280304Sjkim     0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00,
169280304Sjkim     0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300,
170280304Sjkim     0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00,
171280304Sjkim     0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600,
172280304Sjkim     0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600,
173280304Sjkim     0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00,
174280304Sjkim     0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00,
175280304Sjkim     0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600,
176280304Sjkim     0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800,
177280304Sjkim     0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00,
178280304Sjkim     0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200,
179280304Sjkim     0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500,
180280304Sjkim     0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900,
181280304Sjkim     0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400,
182280304Sjkim     0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900,
183280304Sjkim     0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400,
184280304Sjkim     0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00},
185280304Sjkim    {0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057,
186280304Sjkim     0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5,
187280304Sjkim     0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af,
188280304Sjkim     0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b,
189280304Sjkim     0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a,
190280304Sjkim     0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0,
191280304Sjkim     0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb,
192280304Sjkim     0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004,
193280304Sjkim     0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c,
194280304Sjkim     0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a,
195280304Sjkim     0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0,
196280304Sjkim     0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064,
197280304Sjkim     0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6,
198280304Sjkim     0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090,
199280304Sjkim     0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8,
200280304Sjkim     0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063,
201280304Sjkim     0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9,
202280304Sjkim     0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071,
203280304Sjkim     0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9,
204280304Sjkim     0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1,
205280304Sjkim     0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad,
206280304Sjkim     0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5,
207280304Sjkim     0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093,
208280304Sjkim     0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd,
209280304Sjkim     0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f,
210280304Sjkim     0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d,
211280304Sjkim     0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066,
212280304Sjkim     0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099,
213280304Sjkim     0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031,
214280304Sjkim     0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c,
215280304Sjkim     0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2,
216280304Sjkim     0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050,
217280304Sjkim     0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095,
218280304Sjkim     0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db,
219280304Sjkim     0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002,
220280304Sjkim     0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2,
221280304Sjkim     0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b,
222280304Sjkim     0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e,
223280304Sjkim     0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a,
224280304Sjkim     0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa,
225280304Sjkim     0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068,
226280304Sjkim     0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1,
227280304Sjkim     0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e},
228280304Sjkim    {0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e,
229280304Sjkim     0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a,
230280304Sjkim     0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf,
231280304Sjkim     0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242,
232280304Sjkim     0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca,
233280304Sjkim     0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f,
234280304Sjkim     0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060,
235280304Sjkim     0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434,
236280304Sjkim     0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e,
237280304Sjkim     0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad,
238280304Sjkim     0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a,
239280304Sjkim     0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a,
240280304Sjkim     0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363,
241280304Sjkim     0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585,
242280304Sjkim     0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f,
243280304Sjkim     0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf,
244280304Sjkim     0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636,
245280304Sjkim     0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c,
246280304Sjkim     0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888,
247280304Sjkim     0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323,
248280304Sjkim     0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9,
249280304Sjkim     0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa,
250280304Sjkim     0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6,
251280304Sjkim     0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5,
252280304Sjkim     0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef,
253280304Sjkim     0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5,
254280304Sjkim     0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8,
255280304Sjkim     0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666,
256280304Sjkim     0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe,
257280304Sjkim     0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c,
258280304Sjkim     0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d,
259280304Sjkim     0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c,
260280304Sjkim     0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc,
261280304Sjkim     0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d,
262280304Sjkim     0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131,
263280304Sjkim     0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575,
264280304Sjkim     0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545,
265280304Sjkim     0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa,
266280304Sjkim     0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292,
267280304Sjkim     0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949,
268280304Sjkim     0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393,
269280304Sjkim     0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9,
270280304Sjkim     0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d},
271280304Sjkim    {0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393,
272280304Sjkim     0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a,
273280304Sjkim     0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7,
274280304Sjkim     0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090,
275280304Sjkim     0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2,
276280304Sjkim     0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7,
277280304Sjkim     0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818,
278280304Sjkim     0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d,
279280304Sjkim     0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3,
280280304Sjkim     0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b,
281280304Sjkim     0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686,
282280304Sjkim     0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696,
283280304Sjkim     0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8,
284280304Sjkim     0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161,
285280304Sjkim     0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb,
286280304Sjkim     0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb,
287280304Sjkim     0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d,
288280304Sjkim     0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b,
289280304Sjkim     0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222,
290280304Sjkim     0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8,
291280304Sjkim     0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e,
292280304Sjkim     0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe,
293280304Sjkim     0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad,
294280304Sjkim     0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969,
295280304Sjkim     0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb,
296280304Sjkim     0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d,
297280304Sjkim     0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e,
298280304Sjkim     0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999,
299280304Sjkim     0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf,
300280304Sjkim     0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313,
301280304Sjkim     0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b,
302280304Sjkim     0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717,
303280304Sjkim     0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737,
304280304Sjkim     0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b,
305280304Sjkim     0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c,
306280304Sjkim     0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d,
307280304Sjkim     0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151,
308280304Sjkim     0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa,
309280304Sjkim     0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4,
310280304Sjkim     0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252,
311280304Sjkim     0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4,
312280304Sjkim     0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a,
313280304Sjkim     0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f}
314238405Sjkim};
315162911Ssimon
316238405Sjkim/* Key generation constants */
317238405Sjkimstatic const u32 SIGMA[] = {
318238405Sjkim    0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be,
319238405Sjkim    0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd
320238405Sjkim};
321162911Ssimon
322238405Sjkim/* The phi algorithm given in C.2.7 of the Camellia spec document. */
323162911Ssimon/*
324238405Sjkim * This version does not attempt to minimize amount of temporary
325238405Sjkim * variables, but instead explicitly exposes algorithm's parallelism.
326238405Sjkim * It is therefore most appropriate for platforms with not less than
327238405Sjkim * ~16 registers. For platforms with less registers [well, x86 to be
328238405Sjkim * specific] assembler version should be/is provided anyway...
329162911Ssimon */
330238405Sjkim#define Camellia_Feistel(_s0,_s1,_s2,_s3,_key) do {\
331280304Sjkim        register u32 _t0,_t1,_t2,_t3;\
332238405Sjkim\
333280304Sjkim        _t0  = _s0 ^ (_key)[0];\
334280304Sjkim        _t3  = SBOX4_4404[_t0&0xff];\
335280304Sjkim        _t1  = _s1 ^ (_key)[1];\
336280304Sjkim        _t3 ^= SBOX3_3033[(_t0 >> 8)&0xff];\
337280304Sjkim        _t2  = SBOX1_1110[_t1&0xff];\
338280304Sjkim        _t3 ^= SBOX2_0222[(_t0 >> 16)&0xff];\
339280304Sjkim        _t2 ^= SBOX4_4404[(_t1 >> 8)&0xff];\
340280304Sjkim        _t3 ^= SBOX1_1110[(_t0 >> 24)];\
341280304Sjkim        _t2 ^= _t3;\
342280304Sjkim        _t3  = RightRotate(_t3,8);\
343280304Sjkim        _t2 ^= SBOX3_3033[(_t1 >> 16)&0xff];\
344280304Sjkim        _s3 ^= _t3;\
345280304Sjkim        _t2 ^= SBOX2_0222[(_t1 >> 24)];\
346280304Sjkim        _s2 ^= _t2; \
347280304Sjkim        _s3 ^= _t2;\
348238405Sjkim} while(0)
349162911Ssimon
350238405Sjkim/*
351238405Sjkim * Note that n has to be less than 32. Rotations for larger amount
352238405Sjkim * of bits are achieved by "rotating" order of s-elements and
353238405Sjkim * adjusting n accordingly, e.g. RotLeft128(s1,s2,s3,s0,n-32).
354162911Ssimon */
355238405Sjkim#define RotLeft128(_s0,_s1,_s2,_s3,_n) do {\
356280304Sjkim        u32 _t0=_s0>>(32-_n);\
357280304Sjkim        _s0 = (_s0<<_n) | (_s1>>(32-_n));\
358280304Sjkim        _s1 = (_s1<<_n) | (_s2>>(32-_n));\
359280304Sjkim        _s2 = (_s2<<_n) | (_s3>>(32-_n));\
360280304Sjkim        _s3 = (_s3<<_n) | _t0;\
361238405Sjkim} while (0)
362162911Ssimon
363238405Sjkimint Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE k)
364280304Sjkim{
365280304Sjkim    register u32 s0, s1, s2, s3;
366162911Ssimon
367280304Sjkim    k[0] = s0 = GETU32(rawKey);
368280304Sjkim    k[1] = s1 = GETU32(rawKey + 4);
369280304Sjkim    k[2] = s2 = GETU32(rawKey + 8);
370280304Sjkim    k[3] = s3 = GETU32(rawKey + 12);
371162911Ssimon
372280304Sjkim    if (keyBitLength != 128) {
373280304Sjkim        k[8] = s0 = GETU32(rawKey + 16);
374280304Sjkim        k[9] = s1 = GETU32(rawKey + 20);
375280304Sjkim        if (keyBitLength == 192) {
376280304Sjkim            k[10] = s2 = ~s0;
377280304Sjkim            k[11] = s3 = ~s1;
378280304Sjkim        } else {
379280304Sjkim            k[10] = s2 = GETU32(rawKey + 24);
380280304Sjkim            k[11] = s3 = GETU32(rawKey + 28);
381280304Sjkim        }
382280304Sjkim        s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3];
383280304Sjkim    }
384162911Ssimon
385280304Sjkim    /* Use the Feistel routine to scramble the key material */
386280304Sjkim    Camellia_Feistel(s0, s1, s2, s3, SIGMA + 0);
387280304Sjkim    Camellia_Feistel(s2, s3, s0, s1, SIGMA + 2);
388162911Ssimon
389280304Sjkim    s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3];
390280304Sjkim    Camellia_Feistel(s0, s1, s2, s3, SIGMA + 4);
391280304Sjkim    Camellia_Feistel(s2, s3, s0, s1, SIGMA + 6);
392162911Ssimon
393280304Sjkim    /* Fill the keyTable. Requires many block rotations. */
394280304Sjkim    if (keyBitLength == 128) {
395280304Sjkim        k[4] = s0, k[5] = s1, k[6] = s2, k[7] = s3;
396280304Sjkim        RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 15 */
397280304Sjkim        k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
398280304Sjkim        RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 30 */
399280304Sjkim        k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3;
400280304Sjkim        RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 45 */
401280304Sjkim        k[24] = s0, k[25] = s1;
402280304Sjkim        RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 60 */
403280304Sjkim        k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3;
404280304Sjkim        RotLeft128(s1, s2, s3, s0, 2); /* KA <<< 94 */
405280304Sjkim        k[40] = s1, k[41] = s2, k[42] = s3, k[43] = s0;
406280304Sjkim        RotLeft128(s1, s2, s3, s0, 17); /* KA <<<111 */
407280304Sjkim        k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0;
408162911Ssimon
409280304Sjkim        s0 = k[0], s1 = k[1], s2 = k[2], s3 = k[3];
410280304Sjkim        RotLeft128(s0, s1, s2, s3, 15); /* KL <<< 15 */
411280304Sjkim        k[8] = s0, k[9] = s1, k[10] = s2, k[11] = s3;
412280304Sjkim        RotLeft128(s0, s1, s2, s3, 30); /* KL <<< 45 */
413280304Sjkim        k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3;
414280304Sjkim        RotLeft128(s0, s1, s2, s3, 15); /* KL <<< 60 */
415280304Sjkim        k[26] = s2, k[27] = s3;
416280304Sjkim        RotLeft128(s0, s1, s2, s3, 17); /* KL <<< 77 */
417280304Sjkim        k[32] = s0, k[33] = s1, k[34] = s2, k[35] = s3;
418280304Sjkim        RotLeft128(s0, s1, s2, s3, 17); /* KL <<< 94 */
419280304Sjkim        k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3;
420280304Sjkim        RotLeft128(s0, s1, s2, s3, 17); /* KL <<<111 */
421280304Sjkim        k[44] = s0, k[45] = s1, k[46] = s2, k[47] = s3;
422162911Ssimon
423280304Sjkim        return 3;               /* grand rounds */
424280304Sjkim    } else {
425280304Sjkim        k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
426280304Sjkim        s0 ^= k[8], s1 ^= k[9], s2 ^= k[10], s3 ^= k[11];
427280304Sjkim        Camellia_Feistel(s0, s1, s2, s3, (SIGMA + 8));
428280304Sjkim        Camellia_Feistel(s2, s3, s0, s1, (SIGMA + 10));
429162911Ssimon
430280304Sjkim        k[4] = s0, k[5] = s1, k[6] = s2, k[7] = s3;
431280304Sjkim        RotLeft128(s0, s1, s2, s3, 30); /* KB <<< 30 */
432280304Sjkim        k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3;
433280304Sjkim        RotLeft128(s0, s1, s2, s3, 30); /* KB <<< 60 */
434280304Sjkim        k[40] = s0, k[41] = s1, k[42] = s2, k[43] = s3;
435280304Sjkim        RotLeft128(s1, s2, s3, s0, 19); /* KB <<<111 */
436280304Sjkim        k[64] = s1, k[65] = s2, k[66] = s3, k[67] = s0;
437162911Ssimon
438280304Sjkim        s0 = k[8], s1 = k[9], s2 = k[10], s3 = k[11];
439280304Sjkim        RotLeft128(s0, s1, s2, s3, 15); /* KR <<< 15 */
440280304Sjkim        k[8] = s0, k[9] = s1, k[10] = s2, k[11] = s3;
441280304Sjkim        RotLeft128(s0, s1, s2, s3, 15); /* KR <<< 30 */
442280304Sjkim        k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3;
443280304Sjkim        RotLeft128(s0, s1, s2, s3, 30); /* KR <<< 60 */
444280304Sjkim        k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3;
445280304Sjkim        RotLeft128(s1, s2, s3, s0, 2); /* KR <<< 94 */
446280304Sjkim        k[52] = s1, k[53] = s2, k[54] = s3, k[55] = s0;
447162911Ssimon
448280304Sjkim        s0 = k[12], s1 = k[13], s2 = k[14], s3 = k[15];
449280304Sjkim        RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 15 */
450280304Sjkim        k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
451280304Sjkim        RotLeft128(s0, s1, s2, s3, 30); /* KA <<< 45 */
452280304Sjkim        k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3;
453280304Sjkim        /* KA <<< 77 */
454280304Sjkim        k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0;
455280304Sjkim        RotLeft128(s1, s2, s3, s0, 17); /* KA <<< 94 */
456280304Sjkim        k[56] = s1, k[57] = s2, k[58] = s3, k[59] = s0;
457162911Ssimon
458280304Sjkim        s0 = k[0], s1 = k[1], s2 = k[2], s3 = k[3];
459280304Sjkim        RotLeft128(s1, s2, s3, s0, 13); /* KL <<< 45 */
460280304Sjkim        k[24] = s1, k[25] = s2, k[26] = s3, k[27] = s0;
461280304Sjkim        RotLeft128(s1, s2, s3, s0, 15); /* KL <<< 60 */
462280304Sjkim        k[32] = s1, k[33] = s2, k[34] = s3, k[35] = s0;
463280304Sjkim        RotLeft128(s1, s2, s3, s0, 17); /* KL <<< 77 */
464280304Sjkim        k[44] = s1, k[45] = s2, k[46] = s3, k[47] = s0;
465280304Sjkim        RotLeft128(s2, s3, s0, s1, 2); /* KL <<<111 */
466280304Sjkim        k[60] = s2, k[61] = s3, k[62] = s0, k[63] = s1;
467162911Ssimon
468280304Sjkim        return 4;               /* grand rounds */
469280304Sjkim    }
470280304Sjkim    /*
471280304Sjkim     * It is possible to perform certain precalculations, which
472280304Sjkim     * would spare few cycles in block procedure. It's not done,
473280304Sjkim     * because it upsets the performance balance between key
474280304Sjkim     * setup and block procedures, negatively affecting overall
475280304Sjkim     * throughput in applications operating on short messages
476280304Sjkim     * and volatile keys.
477280304Sjkim     */
478280304Sjkim}
479162911Ssimon
480280304Sjkimvoid Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[],
481280304Sjkim                                  const KEY_TABLE_TYPE keyTable,
482280304Sjkim                                  u8 ciphertext[])
483280304Sjkim{
484280304Sjkim    register u32 s0, s1, s2, s3;
485280304Sjkim    const u32 *k = keyTable, *kend = keyTable + grandRounds * 16;
486162911Ssimon
487280304Sjkim    s0 = GETU32(plaintext) ^ k[0];
488280304Sjkim    s1 = GETU32(plaintext + 4) ^ k[1];
489280304Sjkim    s2 = GETU32(plaintext + 8) ^ k[2];
490280304Sjkim    s3 = GETU32(plaintext + 12) ^ k[3];
491280304Sjkim    k += 4;
492162911Ssimon
493280304Sjkim    while (1) {
494280304Sjkim        /* Camellia makes 6 Feistel rounds */
495280304Sjkim        Camellia_Feistel(s0, s1, s2, s3, k + 0);
496280304Sjkim        Camellia_Feistel(s2, s3, s0, s1, k + 2);
497280304Sjkim        Camellia_Feistel(s0, s1, s2, s3, k + 4);
498280304Sjkim        Camellia_Feistel(s2, s3, s0, s1, k + 6);
499280304Sjkim        Camellia_Feistel(s0, s1, s2, s3, k + 8);
500280304Sjkim        Camellia_Feistel(s2, s3, s0, s1, k + 10);
501280304Sjkim        k += 12;
502162911Ssimon
503280304Sjkim        if (k == kend)
504280304Sjkim            break;
505162911Ssimon
506280304Sjkim        /*
507280304Sjkim         * This is the same function as the diffusion function D of the
508280304Sjkim         * accompanying documentation. See section 3.2 for properties of the
509280304Sjkim         * FLlayer function.
510280304Sjkim         */
511280304Sjkim        s1 ^= LeftRotate(s0 & k[0], 1);
512280304Sjkim        s2 ^= s3 | k[3];
513280304Sjkim        s0 ^= s1 | k[1];
514280304Sjkim        s3 ^= LeftRotate(s2 & k[2], 1);
515280304Sjkim        k += 4;
516280304Sjkim    }
517162911Ssimon
518280304Sjkim    s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3];
519162911Ssimon
520280304Sjkim    PUTU32(ciphertext, s2);
521280304Sjkim    PUTU32(ciphertext + 4, s3);
522280304Sjkim    PUTU32(ciphertext + 8, s0);
523280304Sjkim    PUTU32(ciphertext + 12, s1);
524280304Sjkim}
525162911Ssimon
526280304Sjkimvoid Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[],
527280304Sjkim                           const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
528280304Sjkim{
529280304Sjkim    Camellia_EncryptBlock_Rounds(keyBitLength == 128 ? 3 : 4,
530280304Sjkim                                 plaintext, keyTable, ciphertext);
531280304Sjkim}
532162911Ssimon
533280304Sjkimvoid Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[],
534280304Sjkim                                  const KEY_TABLE_TYPE keyTable,
535280304Sjkim                                  u8 plaintext[])
536280304Sjkim{
537280304Sjkim    u32 s0, s1, s2, s3;
538280304Sjkim    const u32 *k = keyTable + grandRounds * 16, *kend = keyTable + 4;
539162911Ssimon
540280304Sjkim    s0 = GETU32(ciphertext) ^ k[0];
541280304Sjkim    s1 = GETU32(ciphertext + 4) ^ k[1];
542280304Sjkim    s2 = GETU32(ciphertext + 8) ^ k[2];
543280304Sjkim    s3 = GETU32(ciphertext + 12) ^ k[3];
544162911Ssimon
545280304Sjkim    while (1) {
546280304Sjkim        /* Camellia makes 6 Feistel rounds */
547280304Sjkim        k -= 12;
548280304Sjkim        Camellia_Feistel(s0, s1, s2, s3, k + 10);
549280304Sjkim        Camellia_Feistel(s2, s3, s0, s1, k + 8);
550280304Sjkim        Camellia_Feistel(s0, s1, s2, s3, k + 6);
551280304Sjkim        Camellia_Feistel(s2, s3, s0, s1, k + 4);
552280304Sjkim        Camellia_Feistel(s0, s1, s2, s3, k + 2);
553280304Sjkim        Camellia_Feistel(s2, s3, s0, s1, k + 0);
554162911Ssimon
555280304Sjkim        if (k == kend)
556280304Sjkim            break;
557162911Ssimon
558280304Sjkim        /*
559280304Sjkim         * This is the same function as the diffusion function D of the
560280304Sjkim         * accompanying documentation. See section 3.2 for properties of the
561280304Sjkim         * FLlayer function.
562280304Sjkim         */
563280304Sjkim        k -= 4;
564280304Sjkim        s1 ^= LeftRotate(s0 & k[2], 1);
565280304Sjkim        s2 ^= s3 | k[1];
566280304Sjkim        s0 ^= s1 | k[3];
567280304Sjkim        s3 ^= LeftRotate(s2 & k[0], 1);
568280304Sjkim    }
569162911Ssimon
570280304Sjkim    k -= 4;
571280304Sjkim    s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3];
572280304Sjkim
573280304Sjkim    PUTU32(plaintext, s2);
574280304Sjkim    PUTU32(plaintext + 4, s3);
575280304Sjkim    PUTU32(plaintext + 8, s0);
576280304Sjkim    PUTU32(plaintext + 12, s1);
577280304Sjkim}
578280304Sjkim
579280304Sjkimvoid Camellia_DecryptBlock(int keyBitLength, const u8 plaintext[],
580280304Sjkim                           const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
581280304Sjkim{
582280304Sjkim    Camellia_DecryptBlock_Rounds(keyBitLength == 128 ? 3 : 4,
583280304Sjkim                                 plaintext, keyTable, ciphertext);
584280304Sjkim}
585