1162911Ssimon/* crypto/camellia/camellia.c -*- mode:C; c-file-style: "eay" -*- */ 2162911Ssimon/* ==================================================================== 3296341Sdelphij * 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 27296341Sdelphij * 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/* 69296341Sdelphij * Algorithm Specification 70296341Sdelphij * http://info.isl.llia/specicrypt/eng/camellia/specifications.html 71296341Sdelphij */ 72296341Sdelphij 73296341Sdelphij/* 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; }) 106296341Sdelphij# 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] = { 142296341Sdelphij {0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, 143296341Sdelphij 0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, 144296341Sdelphij 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00, 145296341Sdelphij 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, 146296341Sdelphij 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, 147296341Sdelphij 0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, 148296341Sdelphij 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000, 149296341Sdelphij 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, 150296341Sdelphij 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, 151296341Sdelphij 0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, 152296341Sdelphij 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00, 153296341Sdelphij 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, 154296341Sdelphij 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, 155296341Sdelphij 0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, 156296341Sdelphij 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700, 157296341Sdelphij 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, 158296341Sdelphij 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, 159296341Sdelphij 0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, 160296341Sdelphij 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400, 161296341Sdelphij 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, 162296341Sdelphij 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, 163296341Sdelphij 0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, 164296341Sdelphij 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00, 165296341Sdelphij 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, 166296341Sdelphij 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, 167296341Sdelphij 0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, 168296341Sdelphij 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00, 169296341Sdelphij 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, 170296341Sdelphij 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, 171296341Sdelphij 0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, 172296341Sdelphij 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600, 173296341Sdelphij 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, 174296341Sdelphij 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, 175296341Sdelphij 0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, 176296341Sdelphij 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800, 177296341Sdelphij 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, 178296341Sdelphij 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, 179296341Sdelphij 0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, 180296341Sdelphij 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900, 181296341Sdelphij 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, 182296341Sdelphij 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, 183296341Sdelphij 0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, 184296341Sdelphij 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00}, 185296341Sdelphij {0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, 186296341Sdelphij 0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, 187296341Sdelphij 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af, 188296341Sdelphij 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, 189296341Sdelphij 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, 190296341Sdelphij 0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, 191296341Sdelphij 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb, 192296341Sdelphij 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, 193296341Sdelphij 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, 194296341Sdelphij 0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, 195296341Sdelphij 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0, 196296341Sdelphij 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, 197296341Sdelphij 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, 198296341Sdelphij 0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, 199296341Sdelphij 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8, 200296341Sdelphij 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, 201296341Sdelphij 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, 202296341Sdelphij 0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, 203296341Sdelphij 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9, 204296341Sdelphij 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, 205296341Sdelphij 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, 206296341Sdelphij 0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, 207296341Sdelphij 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093, 208296341Sdelphij 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, 209296341Sdelphij 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, 210296341Sdelphij 0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, 211296341Sdelphij 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066, 212296341Sdelphij 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, 213296341Sdelphij 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, 214296341Sdelphij 0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, 215296341Sdelphij 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2, 216296341Sdelphij 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, 217296341Sdelphij 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, 218296341Sdelphij 0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, 219296341Sdelphij 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002, 220296341Sdelphij 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, 221296341Sdelphij 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, 222296341Sdelphij 0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, 223296341Sdelphij 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a, 224296341Sdelphij 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, 225296341Sdelphij 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, 226296341Sdelphij 0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, 227296341Sdelphij 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e}, 228296341Sdelphij {0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, 229296341Sdelphij 0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, 230296341Sdelphij 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf, 231296341Sdelphij 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, 232296341Sdelphij 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, 233296341Sdelphij 0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, 234296341Sdelphij 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060, 235296341Sdelphij 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, 236296341Sdelphij 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, 237296341Sdelphij 0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, 238296341Sdelphij 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a, 239296341Sdelphij 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, 240296341Sdelphij 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, 241296341Sdelphij 0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, 242296341Sdelphij 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f, 243296341Sdelphij 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, 244296341Sdelphij 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, 245296341Sdelphij 0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, 246296341Sdelphij 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888, 247296341Sdelphij 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, 248296341Sdelphij 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, 249296341Sdelphij 0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, 250296341Sdelphij 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6, 251296341Sdelphij 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, 252296341Sdelphij 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, 253296341Sdelphij 0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, 254296341Sdelphij 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8, 255296341Sdelphij 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, 256296341Sdelphij 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, 257296341Sdelphij 0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, 258296341Sdelphij 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d, 259296341Sdelphij 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, 260296341Sdelphij 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, 261296341Sdelphij 0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, 262296341Sdelphij 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131, 263296341Sdelphij 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, 264296341Sdelphij 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, 265296341Sdelphij 0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, 266296341Sdelphij 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292, 267296341Sdelphij 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, 268296341Sdelphij 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, 269296341Sdelphij 0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, 270296341Sdelphij 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d}, 271296341Sdelphij {0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, 272296341Sdelphij 0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, 273296341Sdelphij 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7, 274296341Sdelphij 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, 275296341Sdelphij 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, 276296341Sdelphij 0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, 277296341Sdelphij 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818, 278296341Sdelphij 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, 279296341Sdelphij 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, 280296341Sdelphij 0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, 281296341Sdelphij 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686, 282296341Sdelphij 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, 283296341Sdelphij 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, 284296341Sdelphij 0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, 285296341Sdelphij 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb, 286296341Sdelphij 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, 287296341Sdelphij 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, 288296341Sdelphij 0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, 289296341Sdelphij 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222, 290296341Sdelphij 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, 291296341Sdelphij 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, 292296341Sdelphij 0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, 293296341Sdelphij 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad, 294296341Sdelphij 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, 295296341Sdelphij 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, 296296341Sdelphij 0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, 297296341Sdelphij 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e, 298296341Sdelphij 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, 299296341Sdelphij 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, 300296341Sdelphij 0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, 301296341Sdelphij 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b, 302296341Sdelphij 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, 303296341Sdelphij 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, 304296341Sdelphij 0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, 305296341Sdelphij 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c, 306296341Sdelphij 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, 307296341Sdelphij 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, 308296341Sdelphij 0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, 309296341Sdelphij 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4, 310296341Sdelphij 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, 311296341Sdelphij 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, 312296341Sdelphij 0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, 313296341Sdelphij 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 {\ 331296341Sdelphij register u32 _t0,_t1,_t2,_t3;\ 332238405Sjkim\ 333296341Sdelphij _t0 = _s0 ^ (_key)[0];\ 334296341Sdelphij _t3 = SBOX4_4404[_t0&0xff];\ 335296341Sdelphij _t1 = _s1 ^ (_key)[1];\ 336296341Sdelphij _t3 ^= SBOX3_3033[(_t0 >> 8)&0xff];\ 337296341Sdelphij _t2 = SBOX1_1110[_t1&0xff];\ 338296341Sdelphij _t3 ^= SBOX2_0222[(_t0 >> 16)&0xff];\ 339296341Sdelphij _t2 ^= SBOX4_4404[(_t1 >> 8)&0xff];\ 340296341Sdelphij _t3 ^= SBOX1_1110[(_t0 >> 24)];\ 341296341Sdelphij _t2 ^= _t3;\ 342296341Sdelphij _t3 = RightRotate(_t3,8);\ 343296341Sdelphij _t2 ^= SBOX3_3033[(_t1 >> 16)&0xff];\ 344296341Sdelphij _s3 ^= _t3;\ 345296341Sdelphij _t2 ^= SBOX2_0222[(_t1 >> 24)];\ 346296341Sdelphij _s2 ^= _t2; \ 347296341Sdelphij _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 {\ 356296341Sdelphij u32 _t0=_s0>>(32-_n);\ 357296341Sdelphij _s0 = (_s0<<_n) | (_s1>>(32-_n));\ 358296341Sdelphij _s1 = (_s1<<_n) | (_s2>>(32-_n));\ 359296341Sdelphij _s2 = (_s2<<_n) | (_s3>>(32-_n));\ 360296341Sdelphij _s3 = (_s3<<_n) | _t0;\ 361238405Sjkim} while (0) 362162911Ssimon 363238405Sjkimint Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE k) 364296341Sdelphij{ 365296341Sdelphij register u32 s0, s1, s2, s3; 366162911Ssimon 367296341Sdelphij k[0] = s0 = GETU32(rawKey); 368296341Sdelphij k[1] = s1 = GETU32(rawKey + 4); 369296341Sdelphij k[2] = s2 = GETU32(rawKey + 8); 370296341Sdelphij k[3] = s3 = GETU32(rawKey + 12); 371162911Ssimon 372296341Sdelphij if (keyBitLength != 128) { 373296341Sdelphij k[8] = s0 = GETU32(rawKey + 16); 374296341Sdelphij k[9] = s1 = GETU32(rawKey + 20); 375296341Sdelphij if (keyBitLength == 192) { 376296341Sdelphij k[10] = s2 = ~s0; 377296341Sdelphij k[11] = s3 = ~s1; 378296341Sdelphij } else { 379296341Sdelphij k[10] = s2 = GETU32(rawKey + 24); 380296341Sdelphij k[11] = s3 = GETU32(rawKey + 28); 381296341Sdelphij } 382296341Sdelphij s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3]; 383296341Sdelphij } 384162911Ssimon 385296341Sdelphij /* Use the Feistel routine to scramble the key material */ 386296341Sdelphij Camellia_Feistel(s0, s1, s2, s3, SIGMA + 0); 387296341Sdelphij Camellia_Feistel(s2, s3, s0, s1, SIGMA + 2); 388162911Ssimon 389296341Sdelphij s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3]; 390296341Sdelphij Camellia_Feistel(s0, s1, s2, s3, SIGMA + 4); 391296341Sdelphij Camellia_Feistel(s2, s3, s0, s1, SIGMA + 6); 392162911Ssimon 393296341Sdelphij /* Fill the keyTable. Requires many block rotations. */ 394296341Sdelphij if (keyBitLength == 128) { 395296341Sdelphij k[4] = s0, k[5] = s1, k[6] = s2, k[7] = s3; 396296341Sdelphij RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 15 */ 397296341Sdelphij k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; 398296341Sdelphij RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 30 */ 399296341Sdelphij k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3; 400296341Sdelphij RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 45 */ 401296341Sdelphij k[24] = s0, k[25] = s1; 402296341Sdelphij RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 60 */ 403296341Sdelphij k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3; 404296341Sdelphij RotLeft128(s1, s2, s3, s0, 2); /* KA <<< 94 */ 405296341Sdelphij k[40] = s1, k[41] = s2, k[42] = s3, k[43] = s0; 406296341Sdelphij RotLeft128(s1, s2, s3, s0, 17); /* KA <<<111 */ 407296341Sdelphij k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0; 408162911Ssimon 409296341Sdelphij s0 = k[0], s1 = k[1], s2 = k[2], s3 = k[3]; 410296341Sdelphij RotLeft128(s0, s1, s2, s3, 15); /* KL <<< 15 */ 411296341Sdelphij k[8] = s0, k[9] = s1, k[10] = s2, k[11] = s3; 412296341Sdelphij RotLeft128(s0, s1, s2, s3, 30); /* KL <<< 45 */ 413296341Sdelphij k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3; 414296341Sdelphij RotLeft128(s0, s1, s2, s3, 15); /* KL <<< 60 */ 415296341Sdelphij k[26] = s2, k[27] = s3; 416296341Sdelphij RotLeft128(s0, s1, s2, s3, 17); /* KL <<< 77 */ 417296341Sdelphij k[32] = s0, k[33] = s1, k[34] = s2, k[35] = s3; 418296341Sdelphij RotLeft128(s0, s1, s2, s3, 17); /* KL <<< 94 */ 419296341Sdelphij k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3; 420296341Sdelphij RotLeft128(s0, s1, s2, s3, 17); /* KL <<<111 */ 421296341Sdelphij k[44] = s0, k[45] = s1, k[46] = s2, k[47] = s3; 422162911Ssimon 423296341Sdelphij return 3; /* grand rounds */ 424296341Sdelphij } else { 425296341Sdelphij k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; 426296341Sdelphij s0 ^= k[8], s1 ^= k[9], s2 ^= k[10], s3 ^= k[11]; 427296341Sdelphij Camellia_Feistel(s0, s1, s2, s3, (SIGMA + 8)); 428296341Sdelphij Camellia_Feistel(s2, s3, s0, s1, (SIGMA + 10)); 429162911Ssimon 430296341Sdelphij k[4] = s0, k[5] = s1, k[6] = s2, k[7] = s3; 431296341Sdelphij RotLeft128(s0, s1, s2, s3, 30); /* KB <<< 30 */ 432296341Sdelphij k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3; 433296341Sdelphij RotLeft128(s0, s1, s2, s3, 30); /* KB <<< 60 */ 434296341Sdelphij k[40] = s0, k[41] = s1, k[42] = s2, k[43] = s3; 435296341Sdelphij RotLeft128(s1, s2, s3, s0, 19); /* KB <<<111 */ 436296341Sdelphij k[64] = s1, k[65] = s2, k[66] = s3, k[67] = s0; 437162911Ssimon 438296341Sdelphij s0 = k[8], s1 = k[9], s2 = k[10], s3 = k[11]; 439296341Sdelphij RotLeft128(s0, s1, s2, s3, 15); /* KR <<< 15 */ 440296341Sdelphij k[8] = s0, k[9] = s1, k[10] = s2, k[11] = s3; 441296341Sdelphij RotLeft128(s0, s1, s2, s3, 15); /* KR <<< 30 */ 442296341Sdelphij k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3; 443296341Sdelphij RotLeft128(s0, s1, s2, s3, 30); /* KR <<< 60 */ 444296341Sdelphij k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3; 445296341Sdelphij RotLeft128(s1, s2, s3, s0, 2); /* KR <<< 94 */ 446296341Sdelphij k[52] = s1, k[53] = s2, k[54] = s3, k[55] = s0; 447162911Ssimon 448296341Sdelphij s0 = k[12], s1 = k[13], s2 = k[14], s3 = k[15]; 449296341Sdelphij RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 15 */ 450296341Sdelphij k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; 451296341Sdelphij RotLeft128(s0, s1, s2, s3, 30); /* KA <<< 45 */ 452296341Sdelphij k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3; 453296341Sdelphij /* KA <<< 77 */ 454296341Sdelphij k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0; 455296341Sdelphij RotLeft128(s1, s2, s3, s0, 17); /* KA <<< 94 */ 456296341Sdelphij k[56] = s1, k[57] = s2, k[58] = s3, k[59] = s0; 457162911Ssimon 458296341Sdelphij s0 = k[0], s1 = k[1], s2 = k[2], s3 = k[3]; 459296341Sdelphij RotLeft128(s1, s2, s3, s0, 13); /* KL <<< 45 */ 460296341Sdelphij k[24] = s1, k[25] = s2, k[26] = s3, k[27] = s0; 461296341Sdelphij RotLeft128(s1, s2, s3, s0, 15); /* KL <<< 60 */ 462296341Sdelphij k[32] = s1, k[33] = s2, k[34] = s3, k[35] = s0; 463296341Sdelphij RotLeft128(s1, s2, s3, s0, 17); /* KL <<< 77 */ 464296341Sdelphij k[44] = s1, k[45] = s2, k[46] = s3, k[47] = s0; 465296341Sdelphij RotLeft128(s2, s3, s0, s1, 2); /* KL <<<111 */ 466296341Sdelphij k[60] = s2, k[61] = s3, k[62] = s0, k[63] = s1; 467162911Ssimon 468296341Sdelphij return 4; /* grand rounds */ 469296341Sdelphij } 470296341Sdelphij /* 471296341Sdelphij * It is possible to perform certain precalculations, which 472296341Sdelphij * would spare few cycles in block procedure. It's not done, 473296341Sdelphij * because it upsets the performance balance between key 474296341Sdelphij * setup and block procedures, negatively affecting overall 475296341Sdelphij * throughput in applications operating on short messages 476296341Sdelphij * and volatile keys. 477296341Sdelphij */ 478296341Sdelphij} 479162911Ssimon 480296341Sdelphijvoid Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], 481296341Sdelphij const KEY_TABLE_TYPE keyTable, 482296341Sdelphij u8 ciphertext[]) 483296341Sdelphij{ 484296341Sdelphij register u32 s0, s1, s2, s3; 485296341Sdelphij const u32 *k = keyTable, *kend = keyTable + grandRounds * 16; 486162911Ssimon 487296341Sdelphij s0 = GETU32(plaintext) ^ k[0]; 488296341Sdelphij s1 = GETU32(plaintext + 4) ^ k[1]; 489296341Sdelphij s2 = GETU32(plaintext + 8) ^ k[2]; 490296341Sdelphij s3 = GETU32(plaintext + 12) ^ k[3]; 491296341Sdelphij k += 4; 492162911Ssimon 493296341Sdelphij while (1) { 494296341Sdelphij /* Camellia makes 6 Feistel rounds */ 495296341Sdelphij Camellia_Feistel(s0, s1, s2, s3, k + 0); 496296341Sdelphij Camellia_Feistel(s2, s3, s0, s1, k + 2); 497296341Sdelphij Camellia_Feistel(s0, s1, s2, s3, k + 4); 498296341Sdelphij Camellia_Feistel(s2, s3, s0, s1, k + 6); 499296341Sdelphij Camellia_Feistel(s0, s1, s2, s3, k + 8); 500296341Sdelphij Camellia_Feistel(s2, s3, s0, s1, k + 10); 501296341Sdelphij k += 12; 502162911Ssimon 503296341Sdelphij if (k == kend) 504296341Sdelphij break; 505162911Ssimon 506296341Sdelphij /* 507296341Sdelphij * This is the same function as the diffusion function D of the 508296341Sdelphij * accompanying documentation. See section 3.2 for properties of the 509296341Sdelphij * FLlayer function. 510296341Sdelphij */ 511296341Sdelphij s1 ^= LeftRotate(s0 & k[0], 1); 512296341Sdelphij s2 ^= s3 | k[3]; 513296341Sdelphij s0 ^= s1 | k[1]; 514296341Sdelphij s3 ^= LeftRotate(s2 & k[2], 1); 515296341Sdelphij k += 4; 516296341Sdelphij } 517162911Ssimon 518296341Sdelphij s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3]; 519162911Ssimon 520296341Sdelphij PUTU32(ciphertext, s2); 521296341Sdelphij PUTU32(ciphertext + 4, s3); 522296341Sdelphij PUTU32(ciphertext + 8, s0); 523296341Sdelphij PUTU32(ciphertext + 12, s1); 524296341Sdelphij} 525162911Ssimon 526296341Sdelphijvoid Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], 527296341Sdelphij const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) 528296341Sdelphij{ 529296341Sdelphij Camellia_EncryptBlock_Rounds(keyBitLength == 128 ? 3 : 4, 530296341Sdelphij plaintext, keyTable, ciphertext); 531296341Sdelphij} 532162911Ssimon 533296341Sdelphijvoid Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], 534296341Sdelphij const KEY_TABLE_TYPE keyTable, 535296341Sdelphij u8 plaintext[]) 536296341Sdelphij{ 537296341Sdelphij u32 s0, s1, s2, s3; 538296341Sdelphij const u32 *k = keyTable + grandRounds * 16, *kend = keyTable + 4; 539162911Ssimon 540296341Sdelphij s0 = GETU32(ciphertext) ^ k[0]; 541296341Sdelphij s1 = GETU32(ciphertext + 4) ^ k[1]; 542296341Sdelphij s2 = GETU32(ciphertext + 8) ^ k[2]; 543296341Sdelphij s3 = GETU32(ciphertext + 12) ^ k[3]; 544162911Ssimon 545296341Sdelphij while (1) { 546296341Sdelphij /* Camellia makes 6 Feistel rounds */ 547296341Sdelphij k -= 12; 548296341Sdelphij Camellia_Feistel(s0, s1, s2, s3, k + 10); 549296341Sdelphij Camellia_Feistel(s2, s3, s0, s1, k + 8); 550296341Sdelphij Camellia_Feistel(s0, s1, s2, s3, k + 6); 551296341Sdelphij Camellia_Feistel(s2, s3, s0, s1, k + 4); 552296341Sdelphij Camellia_Feistel(s0, s1, s2, s3, k + 2); 553296341Sdelphij Camellia_Feistel(s2, s3, s0, s1, k + 0); 554162911Ssimon 555296341Sdelphij if (k == kend) 556296341Sdelphij break; 557162911Ssimon 558296341Sdelphij /* 559296341Sdelphij * This is the same function as the diffusion function D of the 560296341Sdelphij * accompanying documentation. See section 3.2 for properties of the 561296341Sdelphij * FLlayer function. 562296341Sdelphij */ 563296341Sdelphij k -= 4; 564296341Sdelphij s1 ^= LeftRotate(s0 & k[2], 1); 565296341Sdelphij s2 ^= s3 | k[1]; 566296341Sdelphij s0 ^= s1 | k[3]; 567296341Sdelphij s3 ^= LeftRotate(s2 & k[0], 1); 568296341Sdelphij } 569162911Ssimon 570296341Sdelphij k -= 4; 571296341Sdelphij s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3]; 572296341Sdelphij 573296341Sdelphij PUTU32(plaintext, s2); 574296341Sdelphij PUTU32(plaintext + 4, s3); 575296341Sdelphij PUTU32(plaintext + 8, s0); 576296341Sdelphij PUTU32(plaintext + 12, s1); 577296341Sdelphij} 578296341Sdelphij 579296341Sdelphijvoid Camellia_DecryptBlock(int keyBitLength, const u8 plaintext[], 580296341Sdelphij const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) 581296341Sdelphij{ 582296341Sdelphij Camellia_DecryptBlock_Rounds(keyBitLength == 128 ? 3 : 4, 583296341Sdelphij plaintext, keyTable, ciphertext); 584296341Sdelphij} 585